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

📄 stft.c

📁 LastWave
💻 C
📖 第 1 页 / 共 4 页
字号:
    /*     *                  Orthogonality condition :      *     *  Given the freq0Id range [freq0IdMin,freq0IdMax], and the <windowSize>,     *  what is the region of allowed indexes ON THE GRID i_f0=freq0Id/fRate,     *  knowing that there is a LOWER BOUND i_f0 >= iFMO (iF0Min"Ortho")     *  for these indexes in order to keep the partials at frequencies      *  k*freq0Id and (k+1)*freq0Id QUASI ORTHOGONAL.     *  -> i_f0Min and i_f0Max depend on <windowSize>      */    /* ***************************************************************/        /* the f0 range */    QuantizeRangeLarge(freq0IdMin,freq0IdMax,stft->fRate,		       &f0IdMin,&f0IdMax);          i_f0Min = f0IdMin/stft->fRate;    i_f0Max = f0IdMax/stft->fRate;        i_f0Min = MAX(iFMO,i_f0Min);    if(i_f0Min*stft->fRate < freq0IdMin) {      i_f0Min++;    }    i_f0Max = MIN(stft->nSubBands-1,i_f0Max);        /* This is now the freq0Id-range */    stft->freqIdMin = i_f0Min*stft->fRate;    stft->freqIdMax = i_f0Max*stft->fRate;    stft->iFMO      = iFMO;    stft->dimHarmo  = dimHarmo;        /* If the range is not empty we allocate the data accordingly */    if(stft->freqIdMin <= stft->freqIdMax) {      stft->real = NewSignal();      size = stft->nFrames*(((stft->freqIdMax-stft->freqIdMin)/stft->fRate)+1);      SizeSignal(stft->real,size,YSIG);       ZeroSig(stft->real);      stft->real->x0 = stft->freqIdMin;      stft->real->dx = stft->fRate;    }    else {      stft->real = NULL;      Warningf("SizeStft : empty 'harmo' stft at windowSize=%d",windowSize);    }        break;  default :     Errorf("SizeStft : unknown stftType %d",stftType);  }}   /****************************************** * *  Functions to access the real and imaginary *  inner product of a STFT structure *  corresponding to a given timeId (for all frequencies) * ******************************************/void GetStftData(STFT stft,LWFLOAT timeId,LWFLOAT* *pReal,LWFLOAT* *pImag){  int tId;    /* Checking argument */  CheckStft(stft);  if(stft->real == NULL)    Errorf("GetStftData : empty stft->real");  if(pReal == NULL)    Errorf("GetStftData : NULL output");  if(pImag != NULL && stft->imag == NULL)     Errorf("GetStftData : trying to get imag in real stft");  /* Some tests */  if(timeId != (int) timeId)     Errorf("GetStftData : Bad timeId %g not integer",timeId);  tId = (int) timeId;    if (tId % stft->tRate != 0 || tId < 0 || tId/stft->tRate >= stft->nFrames)     Errorf("GetStftData : Bad timeId %d : rate %d range [0 %d]\n",	   tId,stft->tRate,stft->nFrames);    /* Getting the data */  *pReal = stft->real->Y+(tId/stft->tRate)*(((stft->freqIdMax-stft->freqIdMin)/stft->fRate)+1);  if(pImag != NULL)    *pImag = stft->imag->Y+(tId/stft->tRate)*stft->nSubBands;} /* * The GENERAL command for computing a stft */ void C_Stftd(char **argv){  // The signal to be analyzed  SIGNAL signal;  struct aTFContent tfContent;  // The output stft   STFT stft = NULL;  // Some intermediate STFT variables  STFT stftTmp        = NULL;  STFT stftComplex    = NULL;  STFT stftReal       = NULL;  STFT stftPhase      = NULL;  // Parameters for the grid  int timeRedund,freqRedund;  // The window  char windowShape;  int  windowSize;  // Border effects  char borderType;  // The limits of the update  int  timeIdMin,timeIdMax;    char *name;  char opt;  char stftType;    // Read the main arguments  argv = ParseArgv(argv,tSTFT_,NULL,&stft,tSIGNALI,&signal,-1);  if(stft == NULL)     stft = GetStftCur();  // The signal size  tfContent.signalSize = signal->size;  tfContent.x0 = signal->x0;  tfContent.dx = signal->dx;  // The minimum and maximum timeId  timeIdMin = 0;  timeIdMax = tfContent.signalSize-1;    // Default Option values  windowShape = STFT_DEFAULT_WINDOWSHAPE;  stftType    = STFT_DEFAULT_STFTTYPE;  timeRedund  = STFT_DEFAULT_TIMEREDUND;  freqRedund  = STFT_DEFAULT_FREQREDUND;  borderType  = STFT_DEFAULT_BORDERTYPE;  // Try to read the windowShape  ParseArgv(argv,tSTR_,NULL,&name,-1);  if(name != NULL) {    windowShape = Name2WindowShape(name);    argv++;  }  // The windowSize  argv = ParseArgv(argv,tINT,&windowSize,-1);  // Try to read the type  ParseArgv(argv,tSTR_,NULL,&name,-1);  if(name != NULL) {    if(!strcmp(name,"complex") || !strcmp(name,"real")    || !strcmp(name,"phase")) {      stftType = Name2StftType(name);      argv++;    }  }  // Reading additional options  while(( opt = ParseOption(&argv))) {    switch(opt) {      // Border type    case 'b' :      argv = ParseArgv(argv,tSTR,&name,-1);      borderType = Name2BorderType(name);      break;      // Time redundancy factor    case 'T' :      argv = ParseArgv(argv,tINT,&timeRedund,-1);      if(timeRedund<=0) Errorf("Bad timeRedund %d",timeRedund);      break;      // Frequency redundancy factor    case 'F' :      argv = ParseArgv(argv,tINT,&freqRedund,-1);      if(freqRedund<=0) Errorf("Bad freqRedund %d",freqRedund);      break;    default : ErrorOption(opt);    }  }  NoMoreArgs(argv);  //  // Computation of a Complex spectrogram   //    // -If we are computing a complex spectrogram   // we don't need any temporary stft structure  if(stftType == ComplexStft)     stftTmp = stft;  // -Otherwise we need one to store the (main) complex spectrogram.  else    stftTmp = NewStft();  CopyFieldsTFContent(&tfContent,stftTmp);  SizeStft(stftTmp,windowShape,windowSize,timeRedund,freqRedund,	   borderType,ComplexStft,0,0,0,0);  // Computing the complex spectrogram  UpdateStftComplex(stftTmp,signal,timeIdMin,timeIdMax);  // Are we done ?  if(stftType == ComplexStft) {    return;  } else    stftComplex = stftTmp;    //  // Computation of a Real spectrogram   //    // -If we are computing a real or phase spectrogram  // we don't need any temporary stft structure  if(stftType == RealStft || stftType == PhaseStft)     stftTmp = stft;  // -Otherwise we need one to store the real spectrogram.  else    stftTmp = NewStft();  CopyFieldsTFContent(&tfContent,stftTmp);  // If we compute ONLY the phase  if(stftType == PhaseStft)    SizeStft(stftTmp,windowShape,windowSize,timeRedund,freqRedund,borderType,	     PhaseStft,0,0,0,0);  // Else we need the RealStft in any case  else    SizeStft(stftTmp,windowShape,windowSize,timeRedund,freqRedund,borderType,	     RealStft,0,0,0,0);  // Compute the real or phase stft  UpdateStftRealOrPhase(stftTmp,stftComplex,timeIdMin,timeIdMax);   // Are we done ?  if (stftType == RealStft || stftType == PhaseStft) {    // We delete the stftComplex     stftComplex = DeleteStft(stftComplex);    return;  }  else    stftReal = stftTmp;}/* * The TFContent fields : x0,dx,signalSize,freqIdNyquist */static char *dxDoc = "{[= <dx>]} {Sets/Gets the abscissa step of the signal which has been analyzed.}";void *GetDxTFContentV(ATFCONTENT val, void **arg){  /* Documentation */  if (val == NULL) return(dxDoc);    return(GetFloatField(val->dx,arg));}void *SetDxTFContentV(ATFCONTENT val, void **arg){  /* Documentation */  if (val == NULL) return(dxDoc);  return(SetFloatField(&(val->dx),arg,FieldSPositive));}static char *x0Doc = "{[= <x0>]} {Sets/Gets the first abscissa of the signal which has been analyzed.}";void *GetX0TFContentV(ATFCONTENT val, void **arg){  /* Documentation */  if (val == NULL) return(x0Doc);  return(GetFloatField(val->x0,arg));}void *SetX0TFContentV(ATFCONTENT val, void **arg){  /* Documentation */  if (val == NULL) return(x0Doc);  return(SetFloatField(&(val->x0),arg,0));}static char *signalSizeDoc = "{} {Gets the size of the original signal of the time-frequency transform.}";void *GetSignalSizeTFContentV(ATFCONTENT val, void **arg){  /* Documentation */  if (val == NULL) return(signalSizeDoc);  return(GetIntField(val->signalSize,arg));}static char *freqIdNyquistDoc = "{} {Gets the Nyquist frequency in sample coordinates.}";/*  * This is a bit special ... val is not used : 'freqIdNyquist' is a builtin constant  * that is useful for index<->real frequency conversions*/void *GetFreqIdNyquistTFContentV(VALUE val, void **arg){  char *field = ARG_G_GetField(arg);  /* Documentation */  if (val == NULL)  return(freqIdNyquistDoc);  return(GetIntField(GABOR_NYQUIST_FREQID,arg));}/* * The window fields : windowShape,windowSize */static char *windowShapeDoc = "{} {Gets the windowShape of a Short Time Fourier Transform. "WindowShapeHelpString". To see the shape of a window, you can build it using the 'stft window ...' command.}";static char *windowSizeDoc = "{} {Gets the windowSize of a Short Time Fourier Transform, i.e. the number of samples of its window. So far only powers of 2 are allowed.  To see the shape of a window, you can build it using the 'stft window ...' command.}";void *GetWindowShapeStftV(STFT val, void **arg){  /* Documentation */  if (val == NULL) return(windowShapeDoc);  return(GetStrField(WindowShape2Name(val->windowShape),arg));}void *GetWindowSizeStftV(STFT val, void **arg){  /* Documentation */  if (val == NULL) return(windowSizeDoc);  return(GetIntField(val->windowSize,arg));}static char *gridDoc = "{} {Gets stft 'grid' i.e. returns a &listv {timeRate timeLength freqRate freqLength}.}";void *GetGridStftV(STFT stft,void **arg){  LISTV lv;  if(stft == NULL) return(gridDoc);  lv = TNewListv();  AppendInt2Listv(lv,stft->tRate);  AppendInt2Listv(lv,stft->nFrames);  AppendInt2Listv(lv,stft->fRate);  AppendInt2Listv(lv,stft->nSubBands);  return(GetValueField(lv,arg));}static char *typeDoc = "{} {Gets stft type (it is either 'complex' for short time fourier transform, 'real', 'phase' or 'highres'}";void *GetTypeStftV(STFT val,void **arg){  if(val == NULL) return(typeDoc);  return(GetStrField(StftType2Name(val->type),arg));}static char *borderDoc = "{} {Returns stft <border type>"BorderTypeHelpString".}";static char *firstpDoc = "{} {Gets stft <firstp>}";static char *lastpDoc = "{} {Gets stft <lastp>}";void *GetBorderStftV(STFT stft,void **arg){  if(stft == NULL) return(borderDoc);  return(GetStrField(BorderType2Name(stft->borderType),arg));}void *GetFirstpStftV(STFT stft,void **arg){  if(stft == NULL) return(firstpDoc);  return(GetIntField(stft->firstp,arg));}void *GetLastpStftV(STFT stft,void **arg){  if(stft == NULL) return(lastpDoc);  return(GetIntField(stft->lastp,arg));}  static char *dataDoc = "{} {Returns a signal containing the stft real data or a listv {real imag} containing its complex data}";void *GetDataStftV(STFT stft,void **arg){  SIGNAL signalR = NULL,signalI = NULL;  LISTV lv = NULL;  /* Documentation */  if(stft == NULL) return(dataDoc);    /* Case of an empty stft */  if(stft->real==NULL) {    return(GetValueField(nullValue,arg));  }  switch(stft->type) {  case ComplexStft :    lv = TNewListv();    signalR = TNewSignal();    signalI = TNewSignal();    CopySig(stft->real,signalR);    CopySig(stft->imag,signalI);    signalR->x0 = FreqId2Freq(stft,stft->freqIdMin);    signalR->dx = FreqId2Freq(stft,stft->fRate);    signalI->x0 = FreqId2Freq(stft,stft->freqIdMin);    signalI->dx = FreqId2Freq(stft,stft->fRate);    AppendValue2Listv(lv,(VALUE)signalR);    AppendValue2Listv(lv,(VALUE)signalI);    return(GetValueField(lv,arg));  case RealStft:   case PhaseStft:   case HighResStft:  case HarmoStft:    signalR = TNewSignal();    CopySig(stft->real,signalR);    signalR->x0 = FreqId2Freq(stft,stft->freqIdMin);    signalR->dx = FreqId2Freq(stft,stft->fRate);    return(GetValueField(signalR,arg));  }}/* * The field list */struct field fieldsStft[] = {  "dx",GetDxTFContentV,SetDxTFContentV,NULL,NULL,  "x0",GetX0TFContentV,SetX0TFContentV,NULL,NULL,  "signalSize",GetSignalSizeTFContentV,NULL,NULL,NULL,  "freqIdNyquist",GetFreqIdNyquistTFContentV,NULL,NULL,NULL,  "windowShape",GetWindowShapeStftV,NULL,NULL,NULL,  "windowSize",GetWindowSizeStftV,NULL,NULL,NULL,  "grid",GetGridStftV,NULL,NULL,NULL,  "border",GetBorderStftV,NULL,NULL,NULL,  "firstp",GetFirstpStftV,NULL,NULL,NULL,  "lastp",GetLastpStftV,NULL,NULL,NULL,  "type",GetTypeStftV,NULL,NULL,NULL,  "sig",GetDataStftV,NULL,NULL,NULL,  NULL, NULL, NULL, NULL, NULL};/* * The type structure for STFT */TypeStruct tsStft = {  "{{{&stft} {This type is the basic type for Short Time Fourier transforms and related time-frequency transforms.}}}",  /* Documentation */  &stftType,       /* The basic (unique) type name */  NULL,     /* The GetType function */                           DeleteStft,     /* The Delete function */  NewStft,     /* The New function */    NULL,       /* The copy function */  ClearStft,       /* The clear function */    ToStrStft,       /* String conversion */  ShortPrintStft,   /* The Print function : print the object when 'print' is called */  PrintInfoStft,   /* The PrintInfo function : called by 'info' */  NumExtractStft,              /* The NumExtract function : used to deal with syntax like 10a */     fieldsStft,      /* The list of fields */};/* EOF */

⌨️ 快捷键说明

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