locked
How to create class for creating .bmp files of plots as example of class using RRS feed

  • General discussion

  • How to create class for creating .bmp files of plots as example of class using  (example):

    #include <stdio.h>     //cstdio   /* printf, scanf, NULL */
    #include <stdlib.h>    // cstdlib
    #include <tchar.h>
    #include <iostream>    // iostream.h for  VS
     
     
     
     
    //typedef long WORD;
    typedef void *PVOID;
    typedef PVOID HANDLE;
    typedef unsigned long WORD;
    typedef unsigned long DWORD;
    typedef long LONG;
    typedef unsigned char BYTE;
    //typedef literal int BI_RGB;


    #define GENERIC_READ                     0x80000000
    #define GENERIC_WRITE                    0x40000000
    #define GENERIC_EXECUTE                  0x20000000
    #define GENERIC_ALL                      0x10000000
    #define FILE_SHARE_READ                  0x00000001
    #define FILE_SHARE_WRITE                 0x00000002
    #define FILE_SHARE_DELETE                0x00000004
    #define CREATE_NEW                       1
    #define CREATE_ALWAYS                    2
    #define OPEN_EXISTING                    3
    #define OPEN_ALWAYS                      4
    #define TRUNCATE_EXISTING                5

    #define FILE_ATTRIBUTE_READONLY          0x00000001 
    #define FILE_ATTRIBUTE_NORMAL            0x00000080 
    #define FILE_ATTRIBUTE_TEMPORARY         0x00000100 

     

    // 24/32 бит
    //DWORD rgb;


     typedef struct {
     
          int   R ;
          int   G ;
          int   B ;
          } RGBstruct;

     

     

     
    class DrawBMP
    {

    //protected:


    private:
     
     
            
     
        // int ***Pix;
       
        
        
     
    public:

       int ***create_array(int DIM1,  int DIM2,int DIM3)
                       {
                        int ***array;
                        
                         array=new int** [DIM1];         //
                        for(int i=0; i<DIM1; i++)
                        {
                             array[i] =new int * [DIM2];
                                               
                            for(int j=0; j<DIM2; j++)
          {
                             array[i][j]=new int [DIM3];   //  n
                          }}
                             return array;
                           }
                          
                        
                          
                     void delete_array(int ***ary, int DIM1, int DIM2 )
                     {
                     for (int i = 0; i < DIM1; i++) {
                          for (int j = 0; j < DIM2; j++) {
                          delete [] ary[i][j];
                                 }
                             delete [] ary[i];
                                }
                             delete [] ary;
                             return  ;
                     }

          DrawBMP();
          ~DrawBMP();
     
          
        
          int *** GetRandom(int ah ,   int ay      ); 
          int *** SetBackground( int c_h, int c_w  , RGBstruct Point  );
          void    SetPixel( int x, int y , RGBstruct Point , int ***bmp_arr  );
          void    SetBar( int x, int y ,int h, int w, RGBstruct BarColor, int ***bmp_arr  );
          //void    DrawLine();

            int   SaveArrFile(const TCHAR* filename,  int width, int height, int bpp,int  ***Pix);  
      void  SaveToFile(const TCHAR* filename, int h, int w,   int  ***bmp_arr   )  ;

    };

    DrawBMP::DrawBMP()
    {

    }
     
       int  ***DrawBMP::SetBackground( int c_h, int c_w  , RGBstruct Point  )
      {   
      int x,y;
      int ***bmp_arr;
     bmp_arr  =DrawBMP::create_array(3,c_w ,c_h );  
        for(  y = 0; y < c_h ; y++) {
             for(  x = 0; x < c_w ; x++) {
                         bmp_arr [0][x][y]=Point.R;
                         bmp_arr [1][x][y]=Point.G;
                         bmp_arr [2][x][y]=Point.B;
            }
        }

      return bmp_arr ;
      }
     
     
     
     
     
       void DrawBMP::SetPixel( int x, int y , RGBstruct Point, int ***bmp_arr  )
      {
       
                         bmp_arr [0][x][y]=Point.R;
                         bmp_arr [1][x][y]=Point.G;
                         bmp_arr [2][x][y]=Point.B;
             return;           
      }
      
          void DrawBMP::SetBar( int x, int y ,int h, int w, RGBstruct BarColor, int ***bmp_arr  )
      {
       
        for(int i=x;i<x+w;i++){
         for(int j=y;j<y+h;j++){
        DrawBMP::SetPixel( i,j ,BarColor, bmp_arr   );
       } }
             return;           
      }

     
     int *** DrawBMP::GetRandom( int c_h, int c_w     )
    {
     //массив пикселей    
         int x,y; 
        
      int ***  bmp_arr;
     bmp_arr  =DrawBMP::create_array(3,c_w ,c_h );  
        for(  y = 0; y < c_h ; y++) {
             for(  x = 0; x < c_w ; x++) {
     
                
                         bmp_arr [0][x][y]=200 ;//rand()%2*0xFF;
                         bmp_arr [1][x][y]=200;// rand()%2*0xFF;
                         bmp_arr [2][x][y]=0;//rand()%2*0xFF;
     
            }
        }
         //delete_array(Pix,3, c_h);
    return bmp_arr ;
    }

    /*

    Имя Длина Смещение Описание
    Заголовок файла (BitMapFileHeader)
    Type 2 0 Сигнатура "BM"
    Size 4 2 Размер файла
    Reserved 1 2 6 Зарезервировано
    Reserved 2 2 8 Зарезервировано
    OffsetBits 4 10 Смещение изображения от начала файла
    Информационный заголовок (BitMapInfoHeader)
    Size 4 14 Длина заголовка
    Width 4 18 Ширина изображения, точки
    Height 4 22 Высота изображения, точки
    Planes 2 26 Число плоскостей
    BitCount 2 28 Глубина цвета, бит на точку
    Compression 4 30 Тип компрессии (0 - несжатое изображение)
    SizeImage 4 34 Размер изображения, байт
    XpelsPerMeter 4 38 Горизонтальное разрешение, точки на метр
    YpelsPerMeter 4 42 Вертикальное разрешение, точки на метр
    ColorsUsed 4 46 Число используемых цветов (0 - максимально возможное для данной глубины цвета)
    ColorsImportant 4 50 Число основных цветов
    Таблица цветов (палитра) (ColorTable)
    ColorTable 1024 54 256 элементов по 4 байта
    Данные изображения (BitMap Array)
    Image Size 1078 Изображение, записанное по строкам слева направо и снизу вверх

       // hdr.bfType    = 0x4D42;   
       // hdr.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); 
       // hdr.bfSize    = hdr.bfOffBits + size;
     
     char hdr[]={ 
     
        'B','M',  // bfType/2/,  42 4D
        0,0,0,0,  // bfSize/4/   BA 03 00 00
            0,0,  // Reserved1/2/ 00 00
      0,0,  // Reserved2/2/ 00 00
     0,0,0,0   // OffsetBits/4/ 36 00 00 00
     
     } ;
     
      char dib[]={
       0,0,0,0,         //Size 4 14 Длина заголовка  ;sizeof(BITMAPINFOHEADER); 28 00 00 00
       0,0,0,0,         //Width 4 18 Ширина изображения,; точки (long)width;    14 00 00 00
       0,0,0,0,        //Height 4 22 Высота изображения,; точки (long)-height;  0F 00 00 00
        1,0,             //Planes 2 26 Число плоскостей  01 00
        0,0,             //BitCount 2 28 Глубина цвета, бит на точку ,; bpp; 18 00
       0,0,0,0,         //Compression 4 30 Тип компрессии (0 - несжатое изображение);=0; 00 00 00 00
       0,0,0,0,          //SizeImage 4 34 Размер изображения, байт ;=size ;
       0,0,0,0,         //XpelsPerMeter 4 38 Горизонтальное разрешение, точки на метр;   = 11811L
       0,0,0,0,         //YpelsPerMeter 4 42 Вертикальное разрешение, точки на метр ;    = 11811L
       0,0,0,0,         //ColorsUsed 4 46 Число используемых цветов (0 - максимально возможное для данной глубины цвета) ;=0
       0,0,0,0         //ColorsImportant 4 50 Число основных цветов ;=0, 40 bytes
     
       };
      
     
    //Таблица цветов (палитра) (ColorTable)
    //ColorTable 1024 54 256 элементов по 4 байта
    //Данные изображения (BitMap Array)
    //Image Size 1078 Изображение, записанное по строкам слева направо и снизу вверх


    */

     int  DrawBMP::SaveArrFile(const TCHAR* filename,  int width, int height, int bpp, int  ***Pix)
     {
        if((bpp < 24) || (bpp > 32))  {       return 0;}         // только 24/32 бит
     
           DWORD p_row = (DWORD)((width * bpp + 31) & ~31) / 8uL;
           DWORD size  = (DWORD)(height * p_row);
      // creating header
        // заголовок описателя растра
        // далее запись в файл
       
           FILE *fp;
           fp=fopen (filename,"wb"); // { return 0;};

        // writing headers
           DWORD  dwr = 0uL;
           DWORD dw ;
       
         // poke BITMAPFILEHEADER
         //bfType  , BM
           putc('B',fp);
           putc('M',fp);
        
      //poke size  bfSize, BA 03 00 00
           DWORD  bfSize=14*sizeof(char)  + 40*sizeof(char) + size;
           dw  = bfSize;
           char* buffer = (char*)(&dw );
           for(int i = 0; i < sizeof(DWORD); i++) fputc(buffer[i], fp);
     
     ///Reserved1 , 00 00
        putc(0,fp);
           putc(0,fp);
         //reserved 2, 00 00
           putc(0,fp);
           putc(0,fp);
        //poke OffsetBits  36 00 00 00
           DWORD OffsetBits=(DWORD) 14*sizeof(char)  +40*sizeof(char);//) sizeof(dib);
           dw  = OffsetBits;
           buffer = (char*)(&dw );
           for(int i = 0; i < sizeof(DWORD); i++) fputc(buffer[i], fp);
       //          poke  dib header
      
        //poke size  , 28 00 00 00
           DWORD biSize = (DWORD) 40*sizeof(char); //sizeof(dib);
           dw  = biSize;
           buffer = (char*)(&dw );
           for(int i = 0; i < sizeof(DWORD); i++) fputc(buffer[i], fp);    
         //sizeof(DWORD)=4
     
        //poke width,14 00 00 00
           DWORD biWidth   = (long)width;
           dw  = biWidth;
           buffer = (char*)(&dw );
           for(int i = 0; i < 4; i++) fputc(buffer[i], fp);
        
        //poke height,0F 00 00 00
           DWORD biHeight  = (DWORD) (long)height;  
           dw  =  biHeight;
           buffer = (char*)(&dw );
           for(int i = 0; i < 4; i++) fputc(buffer[i], fp);
     
        // biPlanes , 01 00
           WORD  biPlanes=1;
           dw  =  biPlanes;
           buffer = (char*)(&dw );
           for(int i = 0; i <2; i++) fputc(buffer[i], fp);
     
      //BitCount, 18 00
           WORD biBitCount  = bpp;
           dw  =  biBitCount;
           buffer = (char*)(&dw );
           for(int i = 0; i <2; i++) fputc(buffer[i], fp);
     
      //Compression 4 30 Тип компрессии (0 - несжатое изображение);=0; 00 00 00 00
      
       DWORD   biCompression  = 0x00000000;
           dw  = biCompression;
           buffer = (char*)(&dw );
         for(int i = 0; i < 4; i++) fputc(buffer[i], fp);
       
     //SizeImage 4 34 Размер изображения, байт ;=size ;   84 03 00 00    
         
       DWORD   SizeImage  =size;
           dw  = SizeImage;
           buffer = (char*)(&dw );
         for(int i = 0; i < 4; i++) fputc(buffer[i], fp);
       
     //XpelsPerMeter 4 38 Горизонтальное разрешение, точки на метр;   = 11811L
       
           DWORD   XpelsPerMeter =0;//11811L;
           dw  = XpelsPerMeter;
           buffer = (char*)(&dw );
           for(int i = 0; i < 4; i++) fputc(buffer[i], fp);
       
         
      //YpelsPerMeter 4 42 Вертикальное разрешение, точки на метр ;    = 11811L
       
           DWORD   YpelsPerMeter =0;//11811L;
           dw = XpelsPerMeter;
           buffer = (char*)(&dw );
           for(int i = 0; i < 4; i++) fputc(buffer[i], fp);
       
     //ColorsUsed 4 46 Число используемых цветов (0 - максимально возможное для данной глубины цвета) ;=0
             DWORD   ColorsUsed=0;
             dw  = ColorsUsed;
             buffer = (char*)(&dw );
             for(int i = 0; i < 4; i++) fputc(buffer[i], fp);
     //ColorsImportant 4 50 Число основных цветов ;=0 
         
               DWORD   ColorsImportant=0;
               dw  = ColorsImportant;
               buffer = (char*)(&dw );
               for(int i = 0; i < 4; i++) fputc(buffer[i], fp);
        
       
       // WriteFile(fp, (LPCVOID)&dib.bmiHeader, sizeof(BITMAPINFOHEADER), &dwr, NULL);


    //Таблица цветов (палитра) (ColorTable)
    //ColorTable 1024 54 256 элементов по 4 байта
       //  for(int i = 0; i < 256; i++) {
        //   dw  =0xFF;// Color[i];
       //    buffer = (char*)(&dw );
        //for(int i = 0; i < 4; i++) fputc(buffer[i], fp);
       
       // }

        // запись массива пикселей
        if(bpp == 32) // 32-бит
           for( int i = 0L  ; i <size ; i++ )
                 {        
                              //        putc(   Pix[2][x][y] , fp ) ;
                              //      putc(   Pix[1][x][y] , fp ) ;
                            //       putc(   Pix[0][x][y], fp ) ;            
                 }
      
            
            
            
          else if(bpp == 24) { // 24-бит с дополнением до 32-разрядной границы

              BYTE   nil = 0u;
              int   cb  = 4*sizeof(BYTE); //sizeof(RGBQUAD);
              int  align = ((cb - ((width*bpp + 7) / 8) % cb) % cb); 
              for(int y = 0; y < height; y++) {
                for(int x = 0; x < width; x++) {
                        putc(   Pix[2][x][y] , fp ) ;
                        putc(   Pix[1][x][y] , fp ) ;
                        putc(   Pix[0][x][y], fp ) ;
                      }
                        for(int i = 0; i < align; i++) // до границы DWORD
                              //WriteFile(fp, (LPCVOID)&nil, sizeof(BYTE), &dwr, NULL);
                              {
                                 for( int j = 0  ; j < sizeof(BYTE) ; j++ )
                                  {
                                  putc(  nil, fp ) ;
                                  }
                             }
                   }
       }

       fclose (fp);
       return 1;
    }

     

     

    void DrawBMP::SaveToFile(const TCHAR* filename, int h, int w ,    int  ***bmp_arr  )
    {
         
          DrawBMP::SaveArrFile(filename, w, h, 24, bmp_arr  );
          DrawBMP::delete_array(bmp_arr ,3, w);
    return  ;
    }

     

    DrawBMP::~DrawBMP()
    {

    }

      

    int  main(void) {

     RGBstruct point1, bgr,BarC;

      int  ***bmp_array ;
    DrawBMP *Pict1;

    int h1,w1;
    h1=768;
    w1=500;
     bgr.R=0;
     bgr.G=0;
     bgr.B=10;
     point1.R=255;
     point1.G=0;
     point1.B=0;
     BarC.R=0;
     BarC.G=250;
     BarC.B=0;
     // Pict1->DrawBMP::GetRandom(h1, w1 );
     bmp_array =Pict1->DrawBMP::SetBackground(h1, w1, bgr  );
     
       Pict1-> DrawBMP::SetBar( 100, 20 ,350,5,  BarC , bmp_array ) ;
       Pict1->DrawBMP::SetPixel( 100,450 , point1, bmp_array  );
     
        Pict1->DrawBMP::SaveToFile(_T("grid2.bmp"), h1, w1,   bmp_array  );

    }

    • Changed type USERPC01 Saturday, February 13, 2016 1:06 AM
    Saturday, February 13, 2016 12:41 AM

All replies

  • For  VS  C++ you  can use #include <windows.h>
    Saturday, February 13, 2016 12:42 AM
  • For using with classes and units , for example as  :

    //testclass1.cpp

    #include <iostream>
    #include <stdio.h>
    #include <math.h>
    #include <string.h>
    #include "spectr.h"
    using namespace std;


    int main()
    {

     FourierParser *SP= new  FourierParser;  //передаем конструктору параметры

      double fs;
      double f0;
      double Um;
      double x[1024];
      int i,n;
     
      char mode ;

    label1:


      cout << " Input fs   , Hz " ;
      cin >> fs;
      cout << " Input number of samples  " ;
      cin >> n;
     
      cout << " Input mode  \n  " ;
      cout << "  '1'- cos \n  " ;
      cout << "  '2'- meander with Um= U/2  \n  " ;
      cout << "  '3'- positive  pulse Q=2 \n  " ;
      cout << "  '4'- negative  pulse Q=2 \n  " ;
      cout << "  '5'- positive  pulse with programmed Q  \n  " ;
      cin >> mode;

      if ( mode=='1'   )
    {
      cout << " Input f0   , Hz " ;
      cin >> f0;

      cout << " Input Um   , V " ;
      cin >> Um;
     
      for (i=0;i<n;i++)
     {
     
      x[i]= Um*cos(2*M_PI*f0*i/fs   );

     }


    }


      if ( mode=='2'   )
    {
      cout << " Input U    , V " ;
      cin >> Um;
     
      for (i=0;i<n;i++)
     {
      x[i]= -Um/2;
      if (i>0.5*n-1) { x[i]= Um/2; }

     }

    }

      if ( mode=='3'   )
    {
      cout << " Input U    , V " ;
      cin >> Um;

      for (i=0;i<n;i++)
     {
      x[i]=Um;
      if (i>0.5*n-1) { x[i]=0; }

     }

    }

      if ( mode=='4'   )
    {
      cout << " Input U    , V " ;
      cin >> Um;

      for (i=0;i<n;i++)
     {
      x[i]=0;
      if (i>0.5*n-1) { x[i]=-Um; }

     }

    }


    double tau;
    double T;
    double Q; //Q= T/tau; tau=T/Q ;T =n*td=n/fs


    //T=n/fs
    //tau=T/Q

    // T-> n samples
    // tau= n samples /Q


      if ( mode=='5'   )
    {
      cout << " Input U    , V " ;
      cin >> Um;
       cout << " Input Q     " ;
      cin >> Q;

      for (i=0;i<n;i++)
     {
     // time=n*deltats =n/fs 
     //T/tau=2 - meander 
      
      x[i]=Um;
      if (
      i>(n /Q )-1   // 16/ 2
         ) 
       { x[i]=0; }

     }

    }

    //SP->FourierParser::printarray(x , n )  ;  

    double ti;
    for (i=0;i<n;i++)
    {
     
     
    cout<<i <<"   "  <<" x[i]=" << x[i]<< " t="   <<  SP->FourierParser::Gettassoc( fs  ,i) << " s " << endl ;
    }
      
    cout << "U RMS= " << SP->FourierParser::GetRms(x, n)  << endl ;
    cout << "U Average= " << SP->FourierParser::GetAverage(x, n)  << endl ;
    cout << "U Abs Average= " << SP->FourierParser::GetAbsAverage(x, n)  << endl ;
    cout << "U peak to peak= " << SP->FourierParser::GetPeakToPeak(x, n)  << endl ;
    cout << "U peak+= " << SP->FourierParser::GetPeak(x, n, 1)  << endl ;
    cout << "U peak-= " << SP->FourierParser::GetPeak(x, n, -1)  << endl ;
    cout << "U peak= " << SP->FourierParser::GetPeak(x, n, 2)  << endl ;
    cout << "PAR = " << SP->FourierParser::GetPAR(x, n, 2)  << endl ;   // x is power
    cout << "PAAR = " << SP->FourierParser::GetPAAR(x, n, 2)  << endl ; //
    cout << "Peak to RMS = " << SP->FourierParser::GetPeakToRMS(x, n, 2)  << endl ;

    system("pause");

      SP->FourierParser::printcomplexp(  (SP->FourierParser::GetSpectrum( x , n  , 1 )) ,     n );
      for (i=0;i<n;i++)
      {
       cout <<"i="<<i << " ; f="<<  SP->FourierParser::Getfassoc( fs  , n, i  ) <<" Hz " << endl;
      }

    system("pause");


    SP->~FourierParser();

    // delete  ;

    cout << " '1' - to return ; 0 to exit \n  " ;
    cin >> mode;

    if (mode=='1') goto label1 ;

    return 0;
     
    }

    //spectr.h

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <iostream>
    #include <math.h>

      //#define M_PI   3.14159265358979
      
      #define  NMAX   1024   //131072

    typedef struct
    {
    double re[NMAX];
    double im[NMAX];

    } complex_v;

    typedef struct
    {
    double mod[NMAX];
    double arg[NMAX];

    } complex_vp;

    class FourierParser

    {

    //protected:

    private:

           //double Arg(double x_re, double  x_im ) ;

    public:

    // constructor and destructor

          FourierParser();
         ~FourierParser();


    // do work
         
          double   GetRms(double *x, int Numb);
          double   GetAverage(double *x, int Numb);
          double   GetAbsAverage(double *x, int Numb);
          double   GetPeakToPeak(double *x, int Numb);
          double   GetPeak(double *x, int Numb, int mode);


          double   GetPAR(double *x, int Numb, int mode);
          double   GetPAAR(double *x, int Numb, int mode);
          double   GetPeakToRMS(double *x, int Numb, int mode);

          double Arg(double x_re, double  x_im ) ;
          double   Getfassoc(double fs  ,  int   Numb, int  n   );
          double   Gettassoc(double fs  , int n );
          complex_v   GetIQfromR_fi(int Num  , complex_vp Xk ,  int mode );
          complex_v   CDFT(double numdft  , complex_v dft_xn  );
          complex_v   ScaleDFT(int Num , complex_v  Xk );
          complex_v   ScaleIQidft(double Num  , complex_v  Xk );
          complex_v   CIDFT(int numidft  , complex_v idft_Xk  );
          complex_v   Hilbert(double *xre, int Numb);
          complex_v   GetAnalyticSignal(double *xnre , double Numb  );
          complex_v   getenvelope(double *xnre , double Numb );
          complex_v   GetSpectrumIQ(double *xn , double Num  );
          complex_vp  GetR_fi(double Numb , complex_v Xk,  int mode );
          complex_vp  GetSpectrum(double  *xn , double Num  , int  mode );
          complex_vp  GetSpectrumfromIQ(complex_v x, double Num , int mode );
          complex_v   SynthSignalfromIQ(int Num , complex_v Xk);
          complex_v   SynthSignalfromRFi(complex_vp  Xk ,   int Num  , int mode  );
          void        printcomplex(complex_v xn,double  Num );
          void        printcomplexp(complex_vp xn,double  Num );
          void        printarray(double *xn , double Num );
          //double    deltat(double *argF, double f0, double fs ,double N ) ;

    };


    //implementation


    FourierParser::FourierParser() //constructor
    {
    //cout << "constructor  passed" << endl;
    }

    double FourierParser::GetRms(double *x, int Numb)
    {
    int i;
    double res;
    res=0;
    for (i=0;i<Numb; i++)
    {
    res=res+(x[i]*x[i]);
    }
    res=res/Numb;
    res=pow(res,0.5);

    return res;
    }

    double  FourierParser::GetAverage(double *x, int Numb)
    {
    int i;
    double res;
    res=0;
    for (i=0;i<Numb;i++)
    {
    res=res+x[i] ;
    }
    res=res/Numb;

    return res;
    }

    double  FourierParser::GetAbsAverage(double *x, int Numb)
    {
    int i;
    double res;
    res=0;
    for (i=0;i<Numb;i++)
    {
    res= res+ fabs( x[i] ) ;  //fabs(x[i]);
    }
    res=res/Numb;

    return res;
    }


    double FourierParser::GetPeakToPeak(double *x, int Numb)
    {
    int i;

    double res1; //+   //+5  ; +5   ;  0
    double res2; //-   //-5  ; 0    ; -5
    res1=0;
    res2=0;
    for (i=0;i<Numb;i++)
    {
    if (res1<x[i]) {res1=x[i];  } //else {res1=res1;  }
    if (res2>x[i]) {res2=x[i];  } //else {res1=res1;  }
    }

    return res1-res2;


    }

    double FourierParser::GetPeak(double *x, int Numb, int mode)
    {
    int i;
     
    double res ; //+   //+5  ; +5   ;  0
     
     
    res =0;
    for (i=0;i<Numb;i++)
    {

    if (mode==1 )      { if (res<x[i]) { res=x[i];  } } //else {res=res;  } }  //+
    if (mode==-1)      { if (res>x[i]) { res=x[i];  } }//else {res=res;  } }  //-

    if (mode==2 )      { if ( fabs(res)< fabs( x[i] )   )           { res=fabs(x[i]); }  }

    }
     
     res=fabs(res);

    return res;


    }


    double FourierParser::GetPAR(double *x, int Numb, int mode)
    {
     
    return  fabs( FourierParser::GetPeak( x, Numb, mode)/   FourierParser::GetAverage( x, Numb));
    }

    double FourierParser::GetPAAR(double *x, int Numb, int mode)
    {
     
    return  fabs( FourierParser::GetPeak( x, Numb, mode)/   FourierParser::GetAbsAverage( x, Numb));
    }

    double FourierParser::GetPeakToRMS(double *x, int Numb, int mode)
    {
    //FourierParser FP1;
    return FourierParser::GetPeak( x, Numb, mode)/FourierParser::GetRms( x,  Numb);
    }

    //double FourierParser::Getfassoc(double fs  ,  int   Numb   )
    double FourierParser::Getfassoc(double fs  ,  int   Numb, int  n  )
    {
    //complex_v fvect ;
    //   int k ;
      //  for( k=0 ; k<Numb; k++)
     //  { 
     //   fvect.re[k]=fs*k/Numb;
      //  fvect.im[k]=0;
      // }
    //return fvect;
    return fs*n/Numb;
    }
       
    double  FourierParser::Gettassoc(double fs  ,   int n )
    {

      // n=0 ...Numb-1

    return n/fs;

    }


     double FourierParser::Arg(double x_re, double  x_im )
    {
      
       double arg ;
       char message[80];
      if (x_re > 0)
                 {
                 arg = atan(x_im / x_re);
                 }
      if ((x_re == 0) && (x_im > 0))
                 {
                 arg = M_PI / 2;
                 }
      if ((x_re == 0) && (x_im < 0))
                 {
                 arg = -M_PI / 2;
                 }
      if ((x_re < 0) &&(x_im >= 0))
                 {
                 arg = atan(x_im / x_re) + M_PI;
                 }
      if ((x_re < 0) && (x_im < 0))
                 {
                 arg = atan(x_im / x_re) - M_PI;
                 }
      if ((x_re == 0) &&(x_im == 0))
                 {
               //    cout << " Xre=0 and Xim=0, Invalid result" << endl;
                  arg = 0;
                 }
    return arg;
    }
    /*
     '36.  - 4. + 9.6568542i  - 4. + 4.i  - 4. + 1.6568542i  - 4.  - 4. - 1.6568542i
     
     '         column 7 to 8
     
      ' - 4. - 4.i  - 4. - 9.6568542i

    */


    complex_v   FourierParser::GetIQfromR_fi(int Num  , complex_vp Xk ,  int mode )
    {

    complex_v Xkr;


       int i ;
       double rad ;
      
        rad = 1;
         if (mode == 1) {
           rad = M_PI / 180;
        }
        
         for (i=0; i<Num; i++)
       {
          Xkr.re[i]=Xk.mod[i]*cos(rad * Xk.arg[i]);
          Xkr.im[i]=Xk.mod[i]*sin(rad * Xk.arg[i]);
      
       }

    return Xkr;
    }


    complex_v FourierParser::CDFT(double numdft  , complex_v dft_xn    )
     {
    complex_v dft_Xk;
    int i, k, N ;
     
     double angle ;

     for( k=0 ; k<=numdft-1; k++)
     {
      dft_Xk.re[k] = 0;
      dft_Xk.im[k] = 0;
       for (N=0 ; N<=numdft-1; N++)
        {
        angle=-2 * M_PI * k * N / numdft;
        dft_Xk.re[k]=dft_Xk.re[k]+dft_xn.re[N]* cos(angle)-dft_xn.im[N]*sin(angle);
        dft_Xk.im[k]=dft_Xk.im[k]+dft_xn.re[N]* sin(angle)+dft_xn.im[N]*cos(angle);
        }
     }

    return dft_Xk;
    }
     
    complex_v FourierParser::ScaleDFT(int Num , complex_v  Xk )
    {
    int i;
    complex_v ScXk;
      for (i= 0 ; i<Num; i++)
     {
         ScXk.re[i]=Xk.re[i]/Num;
         ScXk.im[i]=Xk.im[i]/Num;
     }

    return ScXk;
    }

    complex_v FourierParser::ScaleIQidft(double Num  , complex_v  Xk  )
    {
       int i ; 
       complex_v ScXk;

       for (i=0;i<Num; i++)
       {
        ScXk.re[i]=Xk.re[i]*Num;
        ScXk.im[i]=Xk.im[i]*Num;
      }

    return ScXk;
    }

    complex_v FourierParser::CIDFT(int numidft  , complex_v idft_Xk    )
    {
     int k, N;
     double angle;
     complex_v idft_xn;
      for( N=0 ; N<=numidft-1 ; N++)
      {
       //idft_item(n) = numidft - 1
       idft_xn.re[N]=0;
       idft_xn.im[N]=0;
        for( k=0 ; k<= numidft-1; k++)
        {
        angle=2*M_PI*k*N/numidft;
        idft_xn.re[N]=idft_xn.re[N]+idft_Xk.re[k]*cos(angle)-idft_Xk.im[k]*sin(angle);
        idft_xn.im[N]=idft_xn.im[N]+idft_Xk.re[k]*sin(angle)+idft_Xk.im[k]*cos(angle);
        }
     
       idft_xn.re[N] = idft_xn.re[N]/numidft;
       idft_xn.im[N] = idft_xn.im[N]/numidft;

      }
     
     
    return idft_xn;
    }

    complex_v  FourierParser::Hilbert(double *xre, int Numb)
    {
    complex_v Hilb;
    //MATLAB algorithm

       int k, i, no2 ;
       double h[NMAX];
     
     
       complex_v dft_xn  ;
       complex_v dft_Xk  ;
       complex_v idft_Xk;  
       complex_v idft_xn;


     if (Numb == 0) {
         Hilb.re[0]=0;
         Hilb.im[0]=0;
      // cout<< " Hilbert() :   Parsing error " << endl ;
       
       }


      no2=int(Numb / 2);
     
      
      
      
       for(i= 0; i< Numb; i++)
       {
       dft_xn.re[i]=xre[i];
       dft_xn.im[i] = 0;
       }

         dft_Xk=FourierParser::CDFT(Numb,  dft_xn);

         i = 0;
           while (i <= Numb)
        {

            h[i] = 0;
            i = i + 1;
        }

      //if  N is even
     
        if ((Numb>0)&&((2*no2)==Numb))
     {
            h[0]=1;    // zero
            h[no2]=1;  // Nyquist
            for ( k=1; k<no2; k++)
           {
               h[k] = 2;
           }
        }
       //if N is odd
        else {
             if(Numb > 0)
               {
               h[0]=1;
               for(k= 2 ; k<= (0.5 * (Numb + 1))  ; k++ )
                {
                h[k-1]=2;
                }
             
               }
             }


         for (i=0 ; i<Numb; i++)
         {
          idft_Xk.re[i]= dft_Xk.re[i]*h[i];
          idft_Xk.im[i]= dft_Xk.im[i]*h[i];
         }
     
        
           idft_xn=FourierParser::CIDFT(Numb, idft_Xk  );
       
       for (i = 0; i<  Numb; i++)
       {
       Hilb.re[i] = idft_xn.re[i];
       Hilb.im[i] = idft_xn.im[i];
       }
    return Hilb;
     
     }

     complex_v FourierParser::GetAnalyticSignal(double *xnre , double Numb  )

    {

     
      //'I=x(t)
      // 'Q=jHilb(t)
      // 'Hilb=Hilbert()
      complex_v x, Hilb;
      int i ;
       Hilb= FourierParser::Hilbert(xnre, Numb);
       for (i=0;i<Numb;i++)
       {
        x.re[i] = xnre[i];
        x.im[i] = Hilb.im[i];
       }

    return x;
    }

      complex_v FourierParser::getenvelope(double *xnre , double Numb )
     {
      int i;
      complex_v Hilb, res;
      
       Hilb=FourierParser::Hilbert(xnre, Numb );
       for( i = 0 ;i< Numb;i++)
       {
       res.re[i] = pow((Hilb.re[i]*Hilb.re[i])+(Hilb.im[i]*Hilb.im[i]) , 0.5);
       }

    return res;
     }


    complex_v FourierParser::GetSpectrumIQ(double *xn , double Num  )
    {
      
    complex_v x , Xk;
      x= FourierParser::GetAnalyticSignal(xn, Num );
      Xk= FourierParser::CDFT(Num, x  );
      Xk= FourierParser::ScaleDFT(Num, Xk);

    return Xk;
    }

    complex_vp FourierParser::GetR_fi(double Numb , complex_v Xk,  int mode )
    {
    complex_vp Xkrfi;
       int i ;
       for( i = 0 ; i< Numb;i++)
       {
        Xkrfi.mod[i] =  pow( ((Xk.re[i]*Xk.re[i])+(Xk.im[i] *Xk.im[i])) , 0.5);
        Xkrfi.arg[i] = FourierParser::Arg(Xk.re[i], Xk.im[i]);
       if (mode == 1)
         {
        Xkrfi.arg[i] = Xkrfi.arg[i]*180/M_PI;
         }

       }
    return Xkrfi;
    }


    complex_vp FourierParser::GetSpectrum(double  *xn , double Num  , int  mode )
    {
    complex_v x, Xk;
    complex_vp res;

        x=FourierParser::GetAnalyticSignal(xn, Num);
        Xk=FourierParser::CDFT(Num,x);
        Xk=FourierParser::ScaleDFT(Num,Xk);
         res=FourierParser::GetR_fi(Num, Xk, mode);
    return res;
     }
     
     
    complex_vp FourierParser::GetSpectrumfromIQ(complex_v x, double Num , int mode )
     { 
    complex_v  Xk;
    complex_vp res;  

          
          Xk= FourierParser::CDFT(Num, x );
          Xk= FourierParser::ScaleDFT(Num, Xk );
          res=FourierParser::GetR_fi(Num, Xk, mode);
    return res;
     
    }


    complex_v FourierParser::SynthSignalfromIQ(int Num , complex_v Xk)
     {  
     complex_v idft_xn;
              idft_xn= FourierParser::CIDFT(Num, Xk);
              idft_xn=FourierParser::ScaleIQidft(Num, idft_xn);
    return idft_xn;
     }

    complex_v FourierParser::SynthSignalfromRFi(complex_vp  Xk ,   int Num  , int mode  )
    {

    complex_v xn,Xkd;

         Xkd= FourierParser::GetIQfromR_fi(Num,Xk , mode);
         xn= FourierParser::SynthSignalfromIQ(Num, Xkd );

    return xn;
    }

    void FourierParser::printcomplex(complex_v xn,double  Num )
    {
    int i;
         for (i=0; i<Num;i++)
         {
              //cout<< i <<"  " << xnre[i] <<" +j *  " << xnim[i]<< endl;     
         }
    //cout << endl;
    return;
    }

    void FourierParser::printcomplexp(complex_vp xn, double  Num )
    {
    int i;
         for (i=0; i<Num;i++)
         {
               printf(" i= %d ; |X|= %le  ; arg(x) =%le \n ", i  ,  xn.mod[i] , xn.arg[i]);     
         }
     
    return;
    }


    void FourierParser::printarray(double *xn , double Num )
    {
     int i;
         for (i=0; i<Num; i++)
        {
          printf("  x[ %d ] = %le \n", i, xn[i]  );
         
            
        }
    return;
    }

    /*
    double FourierParser::deltat(double *argF, double f0, double fs ,double N )
      double fv[ NMAX +1];
      double delta;
      double N0 ;
      double i ;
      fv= Getfassoc(fs,  N);
      N0 = 0;
     For (i = 0;i<  N;i++)
      {
      If ((fv[i] >= f0) && (fv[i + 1] <= f0) )
       {
       N0 = i;
       }
      }
     
     delta= -(argF[N0]-argF[0])/(2*M_PI*fv[N0]-2*M_PI*fv[0]);
    return delta;
     }
    */


    // Define the destructor.


    FourierParser::~FourierParser()
     {
      
     //printf(" destructor  passed\n " );
     }

    Saturday, February 13, 2016 1:08 AM
  • // and   file from Internet for poke .wav file:

    #include <cmath>
    #include <fstream>
    #include <iostream>
    using namespace std;

    namespace little_endian_io
    {
      template <typename Word>
      std::ostream& write_word( std::ostream& outs, Word value, unsigned size = sizeof( Word ) )
      {
        for (; size; --size, value >>= 8)
          outs.put( static_cast <char> (value & 0xFF) );
        return outs;
      }
    }
    using namespace little_endian_io;

    int main()
    {
      ofstream f( "example.wav", ios::binary );

      // Write the file headers
      f << "RIFF----WAVEfmt ";     // (chunk size to be filled in later)
      write_word( f,     16, 4 );  // no extension data
      write_word( f,      1, 2 );  // PCM - integer samples
      write_word( f,      2, 2 );  // two channels (stereo file)
      write_word( f,  44100, 4 );  // samples per second (Hz)
      write_word( f, 176400, 4 );  // (Sample Rate * BitsPerSample * Channels) / 8
      write_word( f,      4, 2 );  // data block size (size of two integer samples, one for each channel, in bytes)
      write_word( f,     16, 2 );  // number of bits per sample (use a multiple of 8)

      // Write the data chunk header
      size_t data_chunk_pos = f.tellp();
      f << "data----";  // (chunk size to be filled in later)
     
      // Write the audio samples
      // (We'll generate a single C4 note with a sine wave, fading from left to right)
     // constexpr
      double two_pi = 6.283185307179586476925286766559;
     // constexpr
     double max_amplitude = 32760;  // "volume"

      double hz        = 44100;    // samples per second
      double frequency =1000;// 261.626;  // middle C
      double seconds   = 2.5;      // time

      int N = hz * seconds;  // total number of samples
      for (int n = 0; n < N; n++)
      {
        double amplitude = (double)n / N * max_amplitude;
        double value     = sin( (two_pi * n * frequency) / hz );
        write_word( f, (int)(                 amplitude  * value), 2 );
        write_word( f, (int)((max_amplitude - amplitude) * value), 2 );
      }
     
      // (We'll need the final file size to fix the chunk sizes above)
      size_t file_length = f.tellp();

      // Fix the data chunk header to contain the data size
      f.seekp( data_chunk_pos + 4 );
      write_word( f, file_length - data_chunk_pos + 8 );

      // Fix the file header to contain the proper RIFF chunk size, which is (file size - 8) bytes
      f.seekp( 0 + 4 );
      write_word( f, file_length - 8, 4 );
    }

    //read header of .wav


    #include <iostream>
    #include <string>
    #include <fstream>

    using namespace std;
    using std::string;
    using std::fstream;

    typedef struct  WAV_HEADER{
        char                RIFF[4];        // RIFF Header      Magic header
        unsigned long       ChunkSize;      // RIFF Chunk Size 
        char                WAVE[4];        // WAVE Header     
        char                fmt[4];         // FMT header      
        unsigned long       Subchunk1Size;  // Size of the fmt chunk                               
        unsigned short      AudioFormat;    // Audio format 1=PCM,6=mulaw,7=alaw, 257=IBM Mu-Law, 258=IBM A-Law, 259=ADPCM
        unsigned short      NumOfChan;      // Number of channels 1=Mono 2=Sterio                  
        unsigned long       SamplesPerSec;  // Sampling Frequency in Hz                            
        unsigned long       bytesPerSec;    // bytes per second
        unsigned short      blockAlign;     // 2=16-bit mono, 4=16-bit stereo
        unsigned short      bitsPerSample;  // Number of bits per sample     
        char                Subchunk2ID[4]; // "data"  string  
        unsigned long       Subchunk2Size;  // Sampled data length   

    }wav_hdr;

    // Function prototypes
    int getFileSize(FILE *inFile);

    int main(int argc,char *argv[]){
        wav_hdr wavHeader;
        FILE *wavFile;
        int headerSize = sizeof(wav_hdr),filelength = 0;

        string answer;

        do{
            string input;
            string answer;

            const char* filePath;

            cout << "Pick wav file from the Windows Media File: ";
            cin >> input;
            cin.get();

            cout << endl;

           // path = "C:\\Windows\\Media\\" + input + ".wav";
          // char   *path = "file.wav";
          
         //   filePath = path.c_str();
    filePath="file.wav";
            wavFile = fopen( filePath , "r" );

            if(wavFile == NULL){
                printf("Can not able to open wave file\n");
                //exit(EXIT_FAILURE);
            }

            fread(&wavHeader,headerSize,1,wavFile);
            filelength = getFileSize(wavFile);
            fclose(wavFile);

            cout << "File is                    :" << filelength << " bytes." << endl;

            cout << "RIFF header                :" << wavHeader.RIFF[0]
                                                    << wavHeader.RIFF[1]
                                                    << wavHeader.RIFF[2]
                                                    << wavHeader.RIFF[3] << endl;

            cout << "WAVE header                :" << wavHeader.WAVE[0]
                                                    << wavHeader.WAVE[1]
                                                    << wavHeader.WAVE[2]
                                                    << wavHeader.WAVE[3]
                                                    << endl;

            cout << "FMT                        :" << wavHeader.fmt[0]
                                                    << wavHeader.fmt[1]
                                                    << wavHeader.fmt[2]
                                                    << wavHeader.fmt[3]
                                                    << endl;

            cout << "Data size                  :" << wavHeader.ChunkSize << endl;

            // Display the sampling Rate form the header
            cout << "Sampling Rate              :" << wavHeader.SamplesPerSec << endl;
            cout << "Number of bits used        :" << wavHeader.bitsPerSample << endl;
            cout << "Number of channels         :" << wavHeader.NumOfChan << endl;
            cout << "Number of bytes per second :" << wavHeader.bytesPerSec << endl;
            cout << "Data length                :" << wavHeader.Subchunk2Size << endl;
            cout << "Audio Format               :" << wavHeader.AudioFormat << endl;
            // Audio format 1=PCM,6=mulaw,7=alaw, 257=IBM Mu-Law, 258=IBM A-Law, 259=ADPCM


            cout << "Block align                :" << wavHeader.blockAlign << endl;

            cout << "Data string                :" << wavHeader.Subchunk2ID[0]
                                                    << wavHeader.Subchunk2ID[1]
                                                    << wavHeader.Subchunk2ID[2]
                                                    << wavHeader.Subchunk2ID[3]
                                                    << endl;

            cout << endl << endl << "Try something else? (y/n)";
            cin >> answer;
            //cin.get();
            cout << endl << endl;

        }while( answer == "y" );


        getchar();
        return 0;
    }
    // find the file size
    int getFileSize(FILE *inFile){
        int fileSize = 0;
        fseek(inFile,0,SEEK_END);

        fileSize=ftell(inFile);

        fseek(inFile,0,SEEK_SET);
        return fileSize;
    }

     
    • Edited by USERPC01 Saturday, February 13, 2016 1:14 AM
    Saturday, February 13, 2016 1:12 AM