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

📄 stft_complex.c

📁 LastWave
💻 C
📖 第 1 页 / 共 2 页
字号:
/*..........................................................................*//*                                                                          *//*      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 COMPLEX Short Time Fourier Transform : * *		COMPUTATION and UPDATE *//****************************************************/#include "lastwave.h"#include "stft.h"/* * FFT : To get rid of (use a library!) */  #define SWAP(a,b) tempr=(a);(a)=(b);(b)=tempr#define FD LWFLOATstatic void FourierTransform(FD *data,int nn,int fftSign){	int n,mmax,m,j,istep,i;	double wtemp,wr,wpr,wpi,wi,theta;	LWFLOAT tempr,tempi;	n=nn << 1;	j=1;	for (i=1;i<n;i+=2) {		if (j > i) {			SWAP(data[j],data[i]);			SWAP(data[j+1],data[i+1]);		}		m=n >> 1;		while (m >= 2 && j > m) {			j -= m;			m >>= 1;		}		j += m;	}	mmax=2;	while (n > mmax) {		istep=2*mmax;		theta=6.28318530717959/(fftSign*mmax);		wtemp=sin(0.5*theta);		wpr = -2.0*wtemp*wtemp;		wpi=sin(theta);		wr=1.0;		wi=0.0;		for (m=1;m<mmax;m+=2) {			for (i=m;i<=n;i+=istep) {				j=i+mmax;				tempr=wr*data[j]-wi*data[j+1];				tempi=wr*data[j+1]+wi*data[j];				data[j]=data[i]-tempr;				data[j+1]=data[i+1]-tempi;				data[i] += tempr;				data[i+1] += tempi;			}			wr=(wtemp=wr)*wpr-wi*wpi+wr;			wi=wi*wpr+wtemp*wpi+wi;		}		mmax=istep;	}}#undef SWAP/* Get the real part of the fftData and put it in the signal 'out' */static void GetRealPart(FD *fftData,int size,SIGNAL out){   int i;   SizeSignal(out,size,YSIG);   for (i=0;i<size;i++)	   out->Y[i] = fftData[2*i+1];}/* Get the imaginary part of the fftData and put it in the signal 'out' */static void GetImagPart(FD *fftData,int size,SIGNAL out){   int i;      SizeSignal(out,size,YSIG);   for (i=0;i<size;i++)	  out->Y[i] = fftData[2*i+2];}/***********************************************************************//* Make FFT-form signal from realPart and imagPart                     *//* Add zeros if the size != newSize (newSize must be a power of 2      *//* If imagPart == NULL then it is considered to be made of zero        *//***********************************************************************/static void MakeFFTData(FD *fftData,LWFLOAT *realPart,LWFLOAT *imagPart,int size,int newSize){   int   i;   if (imagPart != NULL) {        	for (i=0;i<newSize;i++)       	 if (i>=size)          	fftData[2*i+1] = fftData[2*i+2] = 0.0;         else {           	fftData[2*i+1] = realPart[i];           	fftData[2*i+2] = imagPart[i];         }     }    else {      for (i=0;i<newSize;i++)       	 if (i>=size)          	fftData[2*i+1] = fftData[2*i+2] = 0.0;         else {           	fftData[2*i+1] = realPart[i];           	fftData[2*i+2] = 0.0;         }     }  }/***********************************************************//*                                                         *//*         Compute the fft transform of a SIGNAL           *//*             (inImag can be NULL)                        *//*                                                         *//***********************************************************//* fft :  SIGNAL --> float *          *//* fftOut must be of size 2*newSize+2 */static void Fft1_(SIGNAL inReal,SIGNAL inImag,FD *fftOut, int newSize, int fftSign){  if (inImag == NULL)    	  MakeFFTData(fftOut,inReal->Y,NULL,inReal->size,newSize);  else      MakeFFTData(fftOut,inReal->Y,inImag->Y,inReal->size,newSize);    	    FourierTransform(fftOut,newSize,fftSign);}   /* fft :  SIGNAL --> SIGNAL          */static void Fft1(SIGNAL inReal,SIGNAL inImag,SIGNAL outReal,SIGNAL outImag,int fftSign,char flagShift){   int size2, newSize,size;   FD *fftData,val;   int i;      size2 = (int) (0.5+(log((double) inReal->size)/log(2.)));   newSize = 1 << size2;      /* allocation of the result */   fftData = (FD *) Malloc(sizeof(FD)*(2*newSize+2));      Fft1_(inReal,inImag,fftData,newSize,fftSign);        GetRealPart(fftData,newSize,outReal);   GetImagPart(fftData,newSize,outImag);      if (fftSign == -1)    	for(i=0;i<outReal->size;i++) {   		outReal->Y[i] /= newSize;   		outImag->Y[i] /= newSize;   	}      if (!flagShift) {     outImag->dx = outReal->dx = 2*M_PI/outImag->size;      outImag->x0 = outReal->x0 = 0;   }    else {     size = outImag->size;     for (i=0;i<size/2;i++ ) {       val = outImag->Y[i];       outImag->Y[i] = outImag->Y[size/2+i];       outImag->Y[size/2+i] = val;       val = outReal->Y[i];       outReal->Y[i] = outReal->Y[size/2+i];       outReal->Y[size/2+i] = val;     }     outImag->dx = outReal->dx = 1/(outImag->size*inReal->dx);      outImag->x0 = outReal->x0 = -1/(2*inReal->dx);   }         Free(fftData);}/************************************************************************ * *    Multiply signal with the window and FFT *   (Sum_n  signal(n+shift) * window(n) * exp(2*i*PI*k*fRate*n/GABOR_MAX_FREQID) *     * ************************************************************************/void FilterMultiplyFft(SIGNAL signal,char borderType,SIGNAL window,char windowShape,unsigned long timeId, unsigned long fRate,		       SIGNAL resultR,SIGNAL resultI){  unsigned long maxWindowShape;  unsigned long paddFftSize;  unsigned long i;  static SIGNAL timeSignal = NULL;    /* Checking arguments */  if(signal == NULL) Errorf("FilterMultiplyFft : NULL signal");  if(window == NULL) Errorf("FilterMultiplyFft : NULL window");  if(window->size%2 != 0) Errorf("FilterMultiplyFft   : window size %d should be even",window->size);  if(GABOR_MAX_FREQID%fRate != 0) Errorf("FilterMultiplyFft   : bad fRate %d does not divide GABOR_MAX_FREQID",fRate,GABOR_MAX_FREQID);    /* Allocation if necessary */  if (timeSignal == NULL) timeSignal = NewSignal();    /*    * Compute the size of the (possibly zero padded)    * signal I want to perform the FFT on :   * I need at least 'GABOR_MAX_FREQID/fRate' bins.   */  paddFftSize = MAX(window->size,GABOR_MAX_FREQID/fRate);    /*    * Extract just the piece of the signal that we need,   * with treatment of the border effects.   *    * Checked correct on the 21/02/2001 by R.Gribonval   *   * timeId-maxWindowShape is the index of the first    * point of the window (which value is set to zero)   * This is also the first point of the signal to extract.   */  maxWindowShape = GetMaxWindowShape(windowShape,window->size);   ExtractSig(signal,timeSignal,borderType,timeId-maxWindowShape,paddFftSize);    /* Multiplication by window */  for(i=0; i < window->size; i++) timeSignal->Y[i] *= window->Y[i];      /* Zero padding if necessary */  for(; i < paddFftSize; i++) timeSignal->Y[i]  = 0.0;    /* Rotation to take into account the maxWindowShape :    * the window must be 'centered' at maxWindowShape */  SizeSignal(resultR,paddFftSize,YSIG);  ZeroSig(resultR);  for(i=0; i<resultR->size; i++)     resultR->Y[i] = timeSignal->Y[(i+maxWindowShape)%timeSignal->size];		    /* Fft */  SizeSignal(resultI,paddFftSize,YSIG);  ZeroSig(resultI);  Fft1(resultR,NULL,resultR,resultI,1,NO);    /* Taking the conjugate value : Why ???? */  for(i=0; i<resultR->size; i++) resultI->Y[i] *= -1;    /* Properly setting the 'dx' field */  resultR->dx = GABOR_MAX_FREQID/paddFftSize;  resultI->dx = GABOR_MAX_FREQID/paddFftSize;}void C_FilterMultiplyFft(char **argv){  SIGNAL signal;  char borderType = STFT_DEFAULT_BORDERTYPE;  unsigned long fRate;  char windowShape = STFT_DEFAULT_WINDOWSHAPE;  SIGNAL window ;  unsigned long timeId;  SIGNAL resultR,resultI;  char opt;  char *name;  argv = ParseArgv(argv,tSIGNALI,&signal,tSIGNALI,&window,tINT,&timeId,tINT,&fRate,tSIGNAL,&resultR,tSIGNAL,&resultI,-1);    while((opt = ParseOption(&argv))) {    switch(opt) {    case 'b' :      argv = ParseArgv(argv,tSTR,&name,-1);      borderType = Name2BorderType(name);      break;    default :      ErrorOption(opt);    }  }  NoMoreArgs(argv);  FilterMultiplyFft(signal,borderType,window,windowShape,timeId,fRate,resultR,resultI);}#ifdef TODOvoid C_OverlapAdd(char **argv){

⌨️ 快捷键说明

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