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

📄 stft.c

📁 LastWave
💻 C
📖 第 1 页 / 共 4 页
字号:
/*..........................................................................*//*                                                                          *//*      L a s t W a v e    P a c k a g e 'stft' 2.1                         *//*                                                                          *//*      Copyright (C) 1997-2002 R.Gribonval, E.Bacry                        *//*      email  : remi.gribonval@inria.fr                                    *//*               lastwave@cmapx.polytechnique.fr                            *//*                                                                          *//*..........................................................................*//*                                                                          *//*      This program is a free software, you can redistribute it and/or     *//*      modify it under the terms of the GNU General Public License as      *//*      published by the Free Software Foundation; either version 2 of the  *//*      License, or (at your option) any later version                      *//*                                                                          *//*      This program is distributed in the hope that it will be useful,     *//*      but WITHOUT ANY WARRANTY; without even the implied warranty of      *//*      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the       *//*      GNU General Public License for more details.                        *//*                                                                          *//*      You should have received a copy of the GNU General Public License   *//*      along with this program (in a file named COPYRIGHT);                *//*      if not, write to the Free Software Foundation, Inc.,                *//*      59 Temple Place, Suite 330, Boston, MA  02111-1307  USA             *//*                                                                          *//*..........................................................................*//****************************************************//* * 	The Short Time Fourier Transform : *		Parsing of variables *		Allocation and Desallocations of structures * *//****************************************************/#include "lastwave.h"#include "stft.h"/********************************//* *	STFT variables *//********************************/char *stftType = "&stft";extern TypeStruct tsStft;/* * Answers to the different print messages */ void ShortPrintStft(STFT stft){  //  if (stft->name == NULL)    Printf("<&stft[%d,%d];%p>\n",stft->nFrames,stft->nSubBands,stft);    //  else    //    Printf("<'%s';&stft[%d,%d];%p>\n",stft->name,stft->nFrames,stft->nSubBands,stft);}char *ToStrStft(STFT stft, char flagShort){  static char str[30];    sprintf(str,"<&stft;%p>",stft);  return(str);}void PrintInfoStft(STFT stft){  PrintStft(stft,NO);}/* * NumExtraction * * Vertical slices (<timeId>stft, ...) * Horizontal slices (<freqId>stft ...) */static char *numdoc = "The syntax <timeId>stft corresponds to vertical slices of the &stft. The syntax .<freqId>stft addresses horizontal slices. A slice is either a &listv {<real> <imag>} if the type of the &stft is complex, or just a &signal <real> which may contain either the energy, the phase, or the highres correlation.";static void *NumExtractStft(STFT stft,void **arg){  long n;  char flagDot;    int timeId,freqId;  SIGNAL signalR,signalI;  LWFLOAT *real,*imag;  LISTV lv = NULL;  /* doc */  if (stft == NULL) return(numdoc);  n = ARG_NE_GetN(arg);  flagDot = ARG_NE_GetFlagDot(arg);  /* Horizontal slice at as fixed frequency */  if(flagDot) {    CheckStftNotEmpty(stft);    freqId = n;    /* Checking */    if(freqId%stft->fRate != 0 ||        !INRANGE(0,freqId/stft->fRate,stft->nSubBands-1) ||       !INRANGE(stft->freqIdMin,freqId,stft->freqIdMax)) {	SetErrorf("Bad freqId %d : rate %d length %d min %d max %d",freqId,stft->fRate,stft->nSubBands,stft->freqIdMin,stft->freqIdMax);	return(NULL);    }      /* Checking */    switch(stft->type) {    case ComplexStft:      signalR = TNewSignal();      signalI = TNewSignal();      SizeSignal(signalR,stft->nFrames,YSIG);      SizeSignal(signalI,stft->nFrames,YSIG);      signalR->x0      =signalI->x0      =stft->x0;      signalR->dx      =signalI->dx      = TimeId2Time(stft,stft->tRate);      signalR->firstp  =signalI->firstp  = stft->firstp;      signalR->lastp   =signalI->lastp   = stft->lastp;      /* Getting the data */      for(timeId = 0;	  timeId < stft->tRate*stft->nFrames;	  timeId += stft->tRate) {	GetStftData(stft,timeId,&real,&imag);	signalR->Y[timeId/stft->tRate] = real[(freqId-stft->freqIdMin)/stft->fRate];	signalI->Y[timeId/stft->tRate] = imag[(freqId-stft->freqIdMin)/stft->fRate];      }      lv = TNewListv();      AppendValue2Listv(lv,(VALUE)signalR);      AppendValue2Listv(lv,(VALUE)signalI);      ARG_NE_SetResValue(arg,lv);      return(listvType);    case RealStft:     case PhaseStft:     case HighResStft:    case HarmoStft:      signalR = TNewSignal();      SizeSignal(signalR,stft->nFrames,YSIG);      signalR->x0 = stft->x0;      signalR->dx = TimeId2Time(stft,stft->tRate);      signalR->firstp  = stft->firstp;      signalR->lastp   = stft->lastp;      /* Getting the data */      for(timeId = 0; 	  timeId < stft->tRate*stft->nFrames; 	  timeId += stft->tRate) {	GetStftData(stft,timeId,&real,NULL);	signalR->Y[timeId/stft->tRate] = real[(freqId-stft->freqIdMin)/stft->fRate];      }      ARG_NE_SetResValue(arg,signalR);      return(signalType);    }  } else {    /* Vertical slice at as fixed time */    CheckStftNotEmpty(stft);    timeId = n;    switch(stft->type) {    case ComplexStft:      /* Getting the data */      GetStftData(stft,timeId,&real,&imag);      /* Allocation */      signalR = TNewSignal();      signalI = TNewSignal();      SizeSignal(signalR,stft->nSubBands,YSIG);      SizeSignal(signalI,stft->nSubBands,YSIG);      signalR->x0 = signalI->x0 = 0.0;      signalR->dx = signalI->dx = FreqId2Freq(stft,stft->fRate);      signalR->firstp  = signalI->firstp  = 0;      signalR->lastp   = signalI->lastp   = stft->nSubBands-1;      /* Copying */      memcpy(signalR->Y,real,stft->nSubBands*sizeof(LWFLOAT));      memcpy(signalI->Y,imag,stft->nSubBands*sizeof(LWFLOAT));      lv = TNewListv();      AppendValue2Listv(lv,(VALUE)signalR);      AppendValue2Listv(lv,(VALUE)signalI);      ARG_NE_SetResValue(arg,lv);      return(listvType);    case RealStft:    case PhaseStft:    case HighResStft:    case HarmoStft:      /* Getting the data */      GetStftData(stft,timeId,&real,NULL);      /* Allocation */      signalR = TNewSignal();      SizeSignal(signalR,((stft->freqIdMax-stft->freqIdMin)/stft->fRate)+1,YSIG);      signalR->x0      = FreqId2Freq(stft,stft->freqIdMin);      signalR->dx      = FreqId2Freq(stft,stft->fRate);      signalR->firstp  = 0;      signalR->lastp   = stft->nSubBands-1;      /* Copying */      memcpy(signalR->Y,real,(((stft->freqIdMax-stft->freqIdMin)/stft->fRate)+1)*sizeof(LWFLOAT));      ARG_NE_SetResValue(arg,signalR);      return(signalType);    }  }}STFT TNewStft(void){  STFT stft;    stft = NewStft();  TempValue(stft);  return(stft);}/* * Get the current stft * (generate an error if there is none) */STFT GetStftCur(void){  STFT stft;  if(!ParseTypedValLevel_(levelCur,"objCur",NULL,(VALUE *)&stft,stftType))     Errorf1("");    AddRefValue(stft);  TempValue(stft);    return(stft);}static void CheckSameStftStruct(const STFT stft1,const STFT stft2){  if(stft1==NULL||stft2==NULL)    Errorf("CheckSameStftStruct : NULL input");  CheckTFContentCompat(stft1,stft2);  if(stft1->tRate != stft2->tRate ||     stft1->nFrames != stft2->nFrames ||     stft1->fRate != stft2->fRate ||     stft1->nSubBands != stft2->nSubBands ||     stft1->borderType != stft2->borderType ||     stft1->firstp != stft2->firstp ||     stft1->lastp != stft2->lastp ||     stft1->freqIdMin != stft2->freqIdMin ||     stft1->freqIdMax != stft2->freqIdMax ||     stft1->windowShape != stft2->windowShape ||     stft1->windowSize != stft2->windowSize ||     stft1->dimHarmo != stft2->dimHarmo ||     stft1->iFMO != stft2->iFMO ||     stft1->type != stft2->type) {    PrintStft(stft1,NO);    PrintStft(stft2,NO);    Errorf("CheckSameStftStruct : struct is different!");  }}char* StftOper2Name(char oper){  switch(oper) {  case STFT_ADD:    return("+");  case STFT_SUBSTRACT:    return("-");  case STFT_MULTIPLY:    return("*");  case STFT_DIVIDE:    return("/");  case STFT_CONJUGATE:    return("conjugate");  case STFT_LN:    return("ln");  case STFT_LOG:    return("log");  case STFT_LOG2:    return("log2");  default :    Errorf("StftOper2Name : (Weird) unknown oper %s",oper);    return("");  }}char Name2StftOper(char *name){  if(name==NULL)    Errorf("Name2StftOper : NULL input");  if(!strcmp(name,"+"))    return(STFT_ADD);  if(!strcmp(name,"-"))    return(STFT_SUBSTRACT);  if(!strcmp(name,"*"))    return(STFT_MULTIPLY);  if(!strcmp(name,"/"))    return(STFT_DIVIDE);  if(!strcmp(name,"conjugate"))    return(STFT_CONJUGATE);  if(!strcmp(name,"ln"))    return(STFT_LN);  if(!strcmp(name,"log"))    return(STFT_LOG);  if(!strcmp(name,"log2"))    return(STFT_LOG2);  Errorf("Name2StftOper : unknown operation '%s'",name);  return(-1);}// Given a stft and a time range [timeIdMin,timeIdMax] where a// signal has changed, computes the time range where to update the stftvoid  ComputeUpdateLimits(STFT stft,int timeIdMin,int timeIdMax,			  int *pTimeIdMin,int *pTimeIdMax,			  char *pFlagTwoLoops,int *pTimeIdMin1,int *pTimeIdMax1){  int shiftMin,shiftMax;  // Check ...  CheckStftNotEmpty(stft);  switch(stft->borderType) {    // The simple border effects  case BorderPad0 :  case BorderPad :   case BorderMirror :    if((!INRANGE(0,timeIdMin,timeIdMax)) ||        (!INRANGE(timeIdMin,timeIdMax,stft->signalSize-1)))      Errorf("ComputeUpdateLimits : [%d %d] not in [0 %d]",	     timeIdMin,timeIdMax,stft->signalSize-1);    break;  case BorderPeriodic :    if((!INRANGE(0,timeIdMin,MIN(timeIdMax,stft->signalSize-1))) ||        (!INRANGE(timeIdMin,timeIdMax,2*stft->signalSize-1)))      Errorf("ComputeUpdateLimits : [%d %d] not in [0 %d]",	     timeIdMin,timeIdMax,stft->signalSize-1);    break;  default :     Errorf("ComputeUpdateLimits : border '%s' not treated yet",BorderType2Name(stft->borderType));  }  // By default there is only one loop  *pFlagTwoLoops = NO;  // The time support of the window centered at timeId is  // [timeId+shiftMin,timeId+shiftMax]  ComputeWindowSupport(stft->windowSize,stft->windowShape,0.0,		       &shiftMin,&shiftMax);  // The inner product has changed iff this support intersects   // the portion of the signal that has changed. This depends on the border type  switch(stft->borderType) {    // The simple border effects  case BorderPad0 :  case BorderPad :   case BorderMirror :    *pTimeIdMin     = timeIdMin-shiftMax;    *pTimeIdMax     = timeIdMax-shiftMin;    break;  case BorderPeriodic :    // Case when all changes are in the first 'copy' of the signal    if(timeIdMax <= stft->signalSize-1) {      *pTimeIdMin      = timeIdMin-shiftMax;      *pTimeIdMax      = timeIdMax-shiftMin;      break;    }    // Otherwise : the first part that need to be updated    *pFlagTwoLoops = YES;    *pTimeIdMin    = 0-shiftMax;    *pTimeIdMax    = (timeIdMax%stft->signalSize)-shiftMin;    *pTimeIdMin1   = timeIdMin-shiftMax;    *pTimeIdMax1   = stft->signalSize-1-shiftMin;    break;  default :      Errorf("ComputeUpdateLimits : border type %s not treated yet",BorderType2Name(stft->borderType));  }  /* We consider only the locations on the  time-freq grid */  QuantizeRangeLarge(*pTimeIdMin,*pTimeIdMax,stft->tRate,		     pTimeIdMin,pTimeIdMax);	  *pTimeIdMin     = MAX(0,*pTimeIdMin);  *pTimeIdMax     = MIN((stft->nFrames*stft->tRate)-stft->tRate,*pTimeIdMax);  if(*pFlagTwoLoops) {    QuantizeRangeLarge(*pTimeIdMin1,*pTimeIdMax1,stft->tRate,		       pTimeIdMin1,pTimeIdMax1);	    *pTimeIdMin1     = MAX(0,*pTimeIdMin1);    *pTimeIdMax1     = MIN((stft->nFrames*stft->tRate)-stft->tRate,*pTimeIdMax1);  }}void AddStft(STFT stftResult,STFT stftAdded,unsigned long timeIdMin,unsigned long timeIdMax){  int timeIdMinStft,timeIdMaxStft;  int timeIdMinStft2,timeIdMaxStft2;  char flagTwoLoops;  unsigned long timeId;  unsigned long f;  LWFLOAT *real1,*real2,*imag1=NULL,*imag2;  CheckStftNotEmpty(stftResult);  CheckStftNotEmpty(stftAdded);  CheckSameStftStruct(stftResult,stftAdded);  ComputeUpdateLimits(stftResult,timeIdMin,timeIdMax,		      &timeIdMinStft,&timeIdMaxStft,		      &flagTwoLoops,&timeIdMinStft2,&timeIdMaxStft2);  // First time Loop   for (timeId = timeIdMinStft;        timeId <= timeIdMaxStft;        timeId += stftResult->tRate) {    if(stftResult->type==ComplexStft) {      GetStftData(stftResult,timeId,&real1,&imag1);      GetStftData(stftAdded,timeId,&real2,&imag2);    } else {      GetStftData(stftResult,timeId,&real1,NULL);      GetStftData(stftAdded,timeId,&real2,NULL);    }    for(f = 0; f < stftResult->nSubBands; f++) real1[f]+=real2[f];    if(imag1) {      for(f = 0; f < stftResult->nSubBands; f++) imag1[f]+=imag2[f];    }  }  // Second loop if needed  if(flagTwoLoops) Errorf("????");} void ZeroStft(STFT stft,unsigned long timeIdMin,unsigned long timeIdMax){  int timeIdMinStft,timeIdMaxStft;  int timeIdMinStft2,timeIdMaxStft2;  char flagTwoLoops;  unsigned long timeId;  unsigned long f;  LWFLOAT *real1,*imag1=NULL;  CheckStftNotEmpty(stft);  ComputeUpdateLimits(stft,timeIdMin,timeIdMax,		      &timeIdMinStft,&timeIdMaxStft,		      &flagTwoLoops,&timeIdMinStft2,&timeIdMaxStft2);  // First time Loop   for (timeId = timeIdMinStft; timeId <= timeIdMaxStft; timeId += stft->tRate) {    if(stft->type==ComplexStft) {      GetStftData(stft,timeId,&real1,&imag1);    } else {      GetStftData(stft,timeId,&real1,NULL);    }    for(f = 0; f < stft->nSubBands; f++) real1[f]=0.0;    if(imag1!=NULL) {      for(f = 0; f < stft->nSubBands; f++) imag1[f]=0.0;    }  }  // Second loop if needed  if(flagTwoLoops) Errorf("????");} 

⌨️ 快捷键说明

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