⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mp_graph.c

📁 LastWave
💻 C
📖 第 1 页 / 共 2 页
字号:
    AppendFloat2Listv(lv,o->rh);    return(YES);  }  return(NO);}/********************************************************************* * Functions to fill the display area with the Wigner distribution *********************************************************************//* * The Wigner-Ville distribution of a Gaussian atom is *  GWV(2*(u/2^o)) x GWV(2*(2*pi*\sigma^2* k*2^o/GABOR_MAX_FREQID)) * *  GWV(x) = e^{-x^2/4\sigma^2} */LWFLOAT *GaussianWignerVille(int sizeGWV){    LWFLOAT *GWV;    LWFLOAT c = 1/(4*theGaussianSigma2*sizeGWV*sizeGWV);    int i;            /* Allocation */    if ((GWV = FloatAlloc(sizeGWV)) == NULL)         Errorf("GaussianWignerVilleTime : Mem. Alloc. failed!");            /* Computation of e^{-x^2/\sigma^2}, x = i/sizeGWV*/    for (i = 0; i < sizeGWV; i++)     {        GWV[i] = exp(-c*i*i);    }    return(GWV);}/*  * The Wigner-Ville distribution of a FoF atom is *  FWV(2*(u/2^o)) x GWV(2*(2*pi*\sigma^2* k*2^o/GABOR_MAX_FREQID)) * *  FWV(x) = ??? */LWFLOAT *FoFWignerVille(int sizeFWV){    LWFLOAT *FWV;    LWFLOAT a,expon,beta,max;    int i;            /* Allocation */    if ((FWV = FloatAlloc(sizeFWV)) == NULL)         Errorf("FoFWignerVilleTime : Mem. Alloc. failed!");        /* Damping factor */    a = log(decayFoF);        /* scale */    expon = a/sizeFWV;     beta = betaFoF/sizeFWV;                max=0.0;    /* Computation of FoF window */    for (i = 0; i <= M_PI/beta; i++)     {        FWV[i] = 0.5*(1-cos(beta*i))*exp(-expon*i);	if (FWV[i] > max) max=FWV[i];    }    for (; i<sizeFWV; i++)    {	FWV[i] = exp(-expon*i);	if (FWV[i] > max) max=FWV[i];    }    /* Normalizing to the maximum */    for (i = 0; i <sizeFWV; i++)     {        FWV[i]=FWV[i]/max;    }    return(FWV);}/*  * Add the Wigner-Ville time-frequency distribution * of an atom to a time-frequency 'map' of nRow*nCol */void DisplayGaborAtom(GOBJECT obj,LWFLOAT *map,ATOM atom,int atomK,int mapx,int mapy,int nRow,int nCol){  GRAPHBOOK graph;  BOOK book;  /* The templates of the Wigner-Ville distributions */  static int sizeG = 256;  static LWFLOAT *GWV = NULL;  static LWFLOAT *FWV = NULL;  LWFLOAT timeMin,timeWidth,freqMin,freqWidth;  LWFLOAT nTimeIdPerCol,nFreqIdPerRow;    char flagAsym;  int x,y,xcenter,ycenter,dx,dy;  int xcurrent;  int xmin,xmax,ymin,ymax;    LWFLOAT iWV;  int  t,f,k;  LWFLOAT timeWV,freqWV;    /* Some inits */  graph = (GRAPHBOOK) obj;  book = graph->book;  if (book == NULL) return;  CheckBookNotEmpty(book);  flagAsym = GetFlagAsymWindowShape(atom->windowShape);  /* Is this atom to be displayed in this graph ? */  if(!IsVisible(graph,atom)) return;  /* Initialize the templates of Wigner-Ville distribution */  if(flagAsym) {    if(FWV == NULL) {      FWV = FoFWignerVille(sizeG);    }    if(GWV == NULL) {      GWV = GaussianWignerVille(sizeG);    }  }  else {    if(GWV == NULL) {      GWV = GaussianWignerVille(sizeG);    }  }   /*    * Get the pixel coordinates (xcenter,ycenter)   * of the 'center' of the atom, in map[] :   */  /* the coordinates in the gobject */  Local2Global(obj,TimeId2Time(book,atom->timeId),FreqId2Freq(book,atom->freqId),&xcenter,&ycenter);  /* change the origin to the corner of the map */  xcenter -=mapx;  ycenter -=mapy;  /*   * Get the pixel rectangle (xmin,xmax,ymin,ymax) corresponding to the atom   * as well as the conversion ratios between pixel and (time/freq)Id scales   */  /* (time/freq)(Min/Width) <=> size of the map in (time/freq) units */  Global2LocalRect(obj,mapx,mapy,nCol,nRow,		   &timeMin,&freqMin,&timeWidth,&freqWidth,NormalRect);  /* Conversion ratios */  nTimeIdPerCol = (Time2TimeId(book,timeMin+timeWidth)-Time2TimeId(book,timeMin))/nCol;  nFreqIdPerRow = (Freq2FreqId(book,freqMin+freqWidth)-Freq2FreqId(book,freqMin))/nRow;  /* The rectangle for a Gabor atom */  /* dx and dy are HALF the width and heighth of the box (in pixels) */  if (!flagAsym) {    dx = (int) (atom->windowSize/(2*nTimeIdPerCol));  }  // Except for asymmetric atoms !  else {    dx = (int) (atom->windowSize/nTimeIdPerCol);  }  dy = (int) ((GABOR_MAX_FREQID/(4*M_PI*theGaussianSigma2*atom->windowSize))/nFreqIdPerRow);  /* Now the box itself */  xmax = xcenter+dx;  if (!flagAsym) {    xmin = xcenter-dx;  }  else {    xmin = xcenter;  }  ymax = ycenter+dy;  ymin = ycenter-dy;    /* Is there anything to be displayed ?   * i.e. does the box intersect the pixmap ? */  if (xmax < 0 || ymax < 0 || xmin >= nCol || ymin >= nRow) return;  /* We do not print outside the pixmap */  xmin = MAX(0,xmin);  xmax = MIN(nCol-1,xmax);  ymin = MAX(0,ymin);  ymax = MIN(nRow-1,ymax);  /*    * Fill the pixmap   */  /* Case of a Gabor atom */  /* columns x = 'time' */  for (x = xmin; x <= xmax; x++) {    /*      * Compute the index in the template of Wigner-Ville distrib.      */    /* current distance in pixels from the 'time-center' of the atom */    iWV = abs(x-xcenter);    /* conversion in timeId units */    iWV *= nTimeIdPerCol;     /* conversion in percentage of the time-support of the template WV */    /* For symetric atoms, we have two equal sides of size 2^o/2 */    if (!flagAsym) {      iWV /= atom->windowSize/2;    }    /* For asymetric ones, only one side of size 2^o */    else {      iWV /= atom->windowSize;    }    /* conversion in index in the template WV */    t = (int) (sizeG*iWV);        /* indexes outside the tabulated template WV      * are expected to be be very small and are not displayed     */    if (t>=sizeG) continue;        /*      * It is time to use the template WV to get     * the amplitude of the time factor of the WV.     */    if(flagAsym) {      timeWV = FWV[t];    }    else {      timeWV = GWV[t];    }    /* Now, we take into account the CHIRP to compute     * (in pixel coordinates) the instantaneous frequency      * f = atomtime+atomchirp*(delta t)     * with the 'delta t' corresponding to the current value of 'x'     */    Local2Global(obj,                 TimeId2Time(book,atom->timeId+(x-xcenter)*nTimeIdPerCol),                 FreqId2Freq(book,atom->freqId+atom->chirpId*(x-xcenter)*nTimeIdPerCol),&xcurrent,&ycenter);     xcurrent -=mapx;    ycenter  -=mapy;          /* compute the local frequency box */    ymax = ycenter+dy;    ymin = ycenter-dy;    ymin = MAX(0,ymin);    ymax = MIN(nRow-1,ymax);            /* loop on frequency/row within the local box */    for (y = ymin; y <= ymax; y++) {      /*        * Compute the index in the template of Wigner-Ville distrib.        */      /* current distance in pixels from the 'frequency-center' of the atom */      iWV = abs(y-ycenter);      /* conversion in freqId units */      iWV *= nFreqIdPerRow;       /* conversion in percentage of the freq-support of the template WV */      iWV *= (4*M_PI*theGaussianSigma2*atom->windowSize)/(GABOR_MAX_FREQID);      /* conversion in index in the template WV */      f = (int) (sizeG*iWV);                  /* indexes outside the tabulated template WV        * are expected to be be very small and are not displayed       */      if (f>=sizeG) continue;                  /*        * It is time to use the template WV to get       * the amplitude of the freq factor of the WV.       */      freqWV = GWV[f];      /* Adding contribution at the right position in 'map' */      k = y*nCol+x;      map[k] += atom->coeff2*timeWV*freqWV;    }  }  return;}/* The drawing procedure */static void _DrawGraphBook (WINDOW win, GOBJECT obj, int x, int y,int w,int h){  GRAPHBOOK graph;  BOOK book;  unsigned short kMin,kMax;  int nColors;  int nRow,nCol;  int color;  static LWFLOAT *map         = NULL;  static int   mapAllocSize = 0;  LWFLOAT maxMap,maxPartialEnergy,moleculeEnergy;  unsigned long n;  MOLECULE molecule;    ATOM atom;  int i,j;  unsigned long k;  /* Some inits */  graph = (GRAPHBOOK) obj;  book  = graph->book;  if (book == NULL) return;  CheckBookNotEmpty(book);  /* Get the number of colors of the colormap */  nColors = ColorMapSize(graph->cm);  /* Allocation */  nCol = w;  nRow = h;  WInitPixMap(nRow,nCol);    /* Allocate a 'local map' of amplitudes and initialize with zeros */  if(map != NULL && mapAllocSize < nRow*nCol) {    Free(map);    map          = NULL;    mapAllocSize = 0;  }  if(map == NULL) {    if ((map = FloatAlloc(nRow*nCol)) == NULL)         Errorf("_DrawGraphBook : Mem. Alloc. failed!");    mapAllocSize = nRow*nCol;  }  for(k = 0; k < mapAllocSize; k++) map[k] = 0;  /*   * Do the plot in the local map   */  maxMap = -1;  /* Draw each molecule within the graph's limits */  for(n = graph->nMin; n <= MIN(book->size-1,graph->nMax); n++)  {    molecule = GetBookMolecule(book,n);    switch(graph->flagFund) {      /* Case when we display all partials within a certain range */    case FundAll :      kMin = 0;      kMax = molecule->dim-1;      break;      /* Case when we display only the most energetic partial */    case FundMax :    case FundSum :      maxPartialEnergy = -1;      moleculeEnergy       = 0;          /*       * We locate the most energetic partial and compute       * maxPartialEnergy    = the energy of this partial       * moleculeEnergy          = the total energy of the molecule       */      for(k = 0; k < molecule->dim; k++) {        atom = GetMoleculeAtom(molecule,0,k);        moleculeEnergy += atom->coeff2;        if (maxPartialEnergy < atom->coeff2) {          maxPartialEnergy = MAX(maxPartialEnergy,atom->coeff2);          kMin = kMax = k;        }      }      break;    }          /* Now we do display the desired partials */    for(k = kMin; k <= kMax; k++) {      atom = GetMoleculeAtom(molecule,0,k);      /*       * Case 'FundSum' :        * the most energetic with the total energy of the molecule        */      if (graph->flagFund == FundSum) {	/* We temporarily modify the coeff2 and memorize the right one           in maxPartialEnergy */        maxPartialEnergy = atom->coeff2;        atom->coeff2 = moleculeEnergy;      }                   maxMap = MAX (maxMap,atom->coeff2);                DisplayGaborAtom(obj,map,atom,k,x,y,nRow,nCol);            /* We restore atom->coeff2 if necessary */      if (graph->flagFund == FundSum) atom->coeff2 = maxPartialEnergy;    }  }    /* Normalize and replace the map by its log (dB) or power, pixel by pixel */  if(graph->flagDb) {    for(k = 0; k < nCol*nRow; k++) {      if(map[k] != 0.0) {	/* Normalize */	map[k] /= maxMap;	/* Take decibels */	map[k] = 10*log10(map[k]);	/* Scale the dynamics with 'exponent' */	map[k] /= graph->exponent;	map[k] += 1;	map[k] = MAX(map[k],0);      }    }  }      else {    for(k = 0; k < nCol*nRow; k++) {        if(map[k] != 0.0) {	/* Normalize */	map[k] /= maxMap;	map[k] = pow(map[k],graph->exponent);      }    }  }    /* Puts the 'local map' into the pixmap, using the color-code */  /* rows = 'freq' */  for(i = 0; i < nRow; i++) {    /* columns =  'time' */    for(j = 0; j < nCol; j++) {      k = i*nCol+j;      color = (int) (nColors * map[k]);      color = (color>=nColors ? nColors-1 : color);      color = (color<0 ? 0 : color);      color += graph->cm;                WSetPixelPixMap(i,j,color);    }  }  WDisplayPixMap(win,x,y);   }/* Defining the GraphBook gclass */  void DefineGraphBook(void){  theGraphBookClass          = NewGClass("GraphBook",theGObjectClass,"mp");   theGraphBookClass->nbBytes = sizeof(GraphBook);  theGraphBookClass->init    = _InitGraphBook;  theGraphBookClass->deleteContent = _DeleteContentGraphBook;  theGraphBookClass->set     = _SetGraphBook;  theGraphBookClass->draw    = _DrawGraphBook;     theGraphBookClass->varType = bookType;  theGraphBookClass->flags  &= ~(GClassMoveResize+GClassLocalCoor);  theGraphBookClass->info    = "Graphic Class that allows to display Book";}/* EOF */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -