From 5e25edb1b78f28bee09bd7513a80fb500bbd59c4 Mon Sep 17 00:00:00 2001 From: John Glover Date: Wed, 24 Nov 2010 23:26:43 +0000 Subject: Updated libsms to the latest version (1.15), includes some memory management improvements/simplifications but the basic API is the same. Also started updating the unit tests, which will now use the nose framework --- sms/spectrum.c | 403 +++++++++++++++++++++------------------------------------ 1 file changed, 149 insertions(+), 254 deletions(-) (limited to 'sms/spectrum.c') diff --git a/sms/spectrum.c b/sms/spectrum.c index c7d815a..356811f 100644 --- a/sms/spectrum.c +++ b/sms/spectrum.c @@ -25,58 +25,39 @@ /*! \brief compute a complex spectrum from a waveform * - * \param sizeWindow size of analysis window - * \param pWaveform pointer to input waveform - * \param pWindow pointer to input window - * \param sizeMag size of output magnitude and phase spectrums + * \param sizeWindow size of analysis window + * \param pWaveform pointer to input waveform + * \param pWindow pointer to input window + * \param sizeMag size of output magnitude and phase spectrums * \param pMag pointer to output magnitude spectrum * \param pPhase pointer to output phase spectrum * \return sizeFft, -1 on error \todo remove this return */ -int sms_spectrum (int sizeWindow, sfloat *pWaveform, sfloat *pWindow, int sizeMag, - sfloat *pMag, sfloat *pPhase) +int sms_spectrum(int sizeWindow, sfloat *pWaveform, sfloat *pWindow, int sizeMag, + sfloat *pMag, sfloat *pPhase, sfloat *pFftBuffer) { - int sizeFft = sizeMag << 1; - int i, it2; - int err = 0; - sfloat fReal, fImag; - - static sfloat *pFftBuffer; - static int sizeFftArray = 0; - /* if new size fft is larger than old, allocate more memory */ - if(sizeFftArray < sizeFft) - { - if(sizeFftArray != 0) free(pFftBuffer); - sizeFftArray = sms_power2(sizeFft); - if(sizeFftArray != sizeFft) - { - sms_error("bad fft size, incremented to power of 2"); - err = -1; - } - if ((pFftBuffer = (sfloat *) malloc(sizeFft * sizeof(sfloat))) == NULL) - { - sms_error("could not allocate memory for fft array"); - return(-1); - } - } - memset(pFftBuffer, 0, sizeFft * sizeof(sfloat)); - - /* apply window to waveform and center window around 0 (zero-phase windowing)*/ - sms_windowCentered(sizeWindow, pWaveform, pWindow, sizeFft, pFftBuffer); - - sms_fft(sizeFft, pFftBuffer); - - /* convert from rectangular to polar coordinates */ - for (i = 0; i < sizeMag; i++) - { - it2 = i << 1; //even numbers 0-N - fReal = pFftBuffer[it2]; /*odd numbers 1->N+1 */ - fImag = pFftBuffer[it2 + 1]; /*even numbers 2->N+2 */ - pMag[i] = sqrt (fReal * fReal + fImag * fImag); - pPhase[i] = atan2 (-fImag, fReal); /* \todo why is fImag negated? */ - } - - return (sizeFft); + int i, it2; + int err = 0; + sfloat fReal, fImag; + + int sizeFft = sizeMag << 1; + memset(pFftBuffer, 0, sizeFft * sizeof(sfloat)); + + /* apply window to waveform and center window around 0 (zero-phase windowing)*/ + sms_windowCentered(sizeWindow, pWaveform, pWindow, sizeFft, pFftBuffer); + sms_fft(sizeFft, pFftBuffer); + + /* convert from rectangular to polar coordinates */ + for (i = 0; i < sizeMag; i++) + { + it2 = i << 1; //even numbers 0-N + fReal = pFftBuffer[it2]; /*odd numbers 1->N+1 */ + fImag = pFftBuffer[it2 + 1]; /*even numbers 2->N+2 */ + pMag[i] = sqrt(fReal * fReal + fImag * fImag); + pPhase[i] = atan2(-fImag, fReal); /* \todo why is fImag negated? */ + } + + return sizeFft; } /*! \brief compute the spectrum Magnitude of a waveform @@ -85,63 +66,42 @@ int sms_spectrum (int sizeWindow, sfloat *pWaveform, sfloat *pWindow, int sizeMa * performs a zero-padded FFT (if sizeMag*2 > sizeWindow). * The spectra is then converted magnitude (RMS). * - * \param sizeWindow size of analysis window / input wavefrom - * \param pWaveform pointer to input waveform - * \param pWindow pointer to analysis window - * \param sizeMag size of output magnitude spectrum + * \param sizeWindow size of analysis window / input wavefrom + * \param pWaveform pointer to input waveform + * \param pWindow pointer to analysis window + * \param sizeMag size of output magnitude spectrum * \param pMag pointer to output magnitude spectrum * \return 0 on success, -1 on error */ -int sms_spectrumMag (int sizeWindow, sfloat *pWaveform, sfloat *pWindow, - int sizeMag, sfloat *pMag) +int sms_spectrumMag(int sizeWindow, sfloat *pWaveform, sfloat *pWindow, + int sizeMag, sfloat *pMag, sfloat *pFftBuffer) { - int i,it2; - int sizeFft = sizeMag << 1; - int err = 0; - sfloat fReal, fImag; - - static sfloat *pFftBuffer; - static int sizeFftArray = 0; - - if(sizeFftArray != sizeFft) - { - if(sizeFftArray != 0) free(pFftBuffer); - sizeFftArray = sms_power2(sizeFft); - if(sizeFftArray != sizeFft) - { - sms_error("bad fft size, incremented to power of 2"); - err = -1; - } - if ((pFftBuffer = (sfloat *) malloc(sizeFft * sizeof(sfloat))) == NULL) - { - sms_error("could not allocate memory for fft array"); - return(-1); - } - } - /* apply window to waveform, zero the rest of the array */ - //memset(pFftBuffer, 0, sizeFft * sizeof(sfloat)); - for (i = 0; i < sizeWindow; i++) - pFftBuffer[i] = pWindow[i] * pWaveform[i]; - for(i = sizeWindow; i < sizeFft; i++) - pFftBuffer[i] = 0.; - - /* compute real FFT */ - sms_fft(sizeFft, pFftBuffer); - - /* convert from rectangular to polar coordinates */ - for (i=0; i> 1, i, it2; - sfloat *pFBuffer, fPower; - - /* allocate buffer */ - if ((pFBuffer = (sfloat *) calloc(sizeFft, sizeof(sfloat))) == NULL) - return -1; - - /* convert from polar coordinates to rectangular */ - for (i = 0; i> 1, i, it2; + sfloat fPower; + + /* convert from polar coordinates to rectangular */ + for (i = 0; i> 1, i, it2; */ -/* sfloat *pFBuffer, fPower; */ - -/* /\* allocate buffer *\/ */ -/* if ((pFBuffer = (sfloat *) calloc(sizeFft+1, sizeof(sfloat))) == NULL) */ -/* return -1; */ - -/* /\* convert from polar coordinates to rectangular *\/ */ -/* for (i = 0; i < sizeMag; i++) */ -/* { */ -/* it2 = i << 1; */ -/* fPower = pFMagSpectrum[i]; */ -/* pFBuffer[it2] = fPower * cos (pFPhaseSpectrum[i]); */ -/* pFBuffer[it2+1] = fPower * sin (pFPhaseSpectrum[i]); */ -/* } */ -/* /\* compute IFFT *\/ */ -/* sms_ifft(sizeFft, pFBuffer); */ - -/* /\* assume the output array has been taken care off *\/ */ -/* for (i = 0; i < sizeWave; i++) */ -/* pFWaveform[i] += pFBuffer[i]; */ - -/* free(pFBuffer); */ - -/* return (sizeMag); */ -/* } */ -- cgit v1.2.3