This is spectrum.c in view mode; [Download] [Up]
#include "../sms.h" /* * function to compute a complex spectrum from a waveform * returns the size of the complex spectrum * * float *pFWaveform; pointer to input waveform * int sizeWindow; size of analysis window * float *pFMagSpectrum; pointer to output magnitude spectrum * float *pFPhaseSpectrum; pointer to output phase spectrum */ int Spectrum (float *pFWaveform, int sizeWindow, float *pFMagSpectrum, float *pFPhaseSpectrum, ANAL_PARAMS analParams) { int sizeFft = (int) pow (2.0, (float)(1 + (floor (log ((float)(WINDOWS_IN_FFT * sizeWindow)) / LOG2)))); int i, it2, sizeMag = sizeFft >> 1, iMiddleWindow = (sizeWindow+1) >> 1, iOffset; float *pFBuffer, fReal, fImag; static int iOldSizeWindow = 0; /* allocate buffer */ if ((pFBuffer = (float *) calloc(sizeFft+1, sizeof(float))) == NULL) return -1; /* compute window when necessary */ if (iOldSizeWindow != sizeWindow) GetWindow (sizeWindow, pFWindowSpec, analParams.iWindowType); iOldSizeWindow = sizeWindow; /* apply window to waveform and center window around 0 */ iOffset = sizeFft - (iMiddleWindow - 1); for (i=0; i<iMiddleWindow-1; i++) pFBuffer[1+(iOffset + i)] = pFWindowSpec[i] * pFWaveform[i]; iOffset = iMiddleWindow - 1; for (i=0; i<iMiddleWindow; i++) pFBuffer[1+i] = pFWindowSpec[iOffset + i] * pFWaveform[iOffset + i]; /* compute real FFT */ realft (pFBuffer, sizeMag, 1); /* convert from rectangular to polar coordinates */ for (i = 0; i < sizeMag; i++) { it2 = i << 1; fReal = pFBuffer[it2+1]; fImag = pFBuffer[it2+2]; if (fReal != 0 || fImag != 0) { pFMagSpectrum[i] = TO_DB (sqrt (fReal * fReal + fImag * fImag)); pFPhaseSpectrum[i] = atan2 (-fImag, fReal); } } free (pFBuffer); return (sizeMag); } /* * function to compute a complex spectrum from a waveform * returns the size of the complex spectrum * * short *pIWaveform; pointer to input waveform * float pFWindow; pointer to analysis window * int sizeWindow; size of analysis window * float *pFMagSpectrum; pointer to output spectrum * float *pFPhaseSpectrum; pointer to output spectrum * int sizeFft; size of FFT */ int QuickSpectrum (short *pIWaveform, float *pFWindow, int sizeWindow, float *pFMagSpectrum, float *pFPhaseSpectrum, int sizeFft) { int sizeMag = sizeFft >> 1, i, it2; float *pFBuffer, fReal, fImag; /* allocate buffer */ if ((pFBuffer = (float *) calloc(sizeFft+1, sizeof(float))) == NULL) return -1; /* apply window to waveform */ for (i = 0; i < sizeWindow; i++) pFBuffer[i] = pFWindow[i] * pIWaveform[i]; /* compute real FFT */ realft (pFBuffer-1, sizeMag, 1); /* convert from rectangular to polar coordinates */ for (i = 0; i < sizeMag; i++) { it2 = i << 1; fReal = pFBuffer[it2]; fImag = pFBuffer[it2+1]; if (fReal != 0 || fImag != 0) { pFMagSpectrum[i] = sqrt(fReal * fReal + fImag * fImag); if (pFPhaseSpectrum) pFPhaseSpectrum[i] = atan2(fImag, fReal); } } free(pFBuffer); return (sizeMag); } /* * function to compute a complex spectrum from a waveform * returns the size of the complex spectrum * * float *pFWaveform; pointer to input waveform * float pFWindow; pointer to analysis window * int sizeWindow; size of analysis window * float *pFMagSpectrum; pointer to output spectrum * float *pFPhaseSpectrum; pointer to output spectrum * int sizeFft; size of FFT */ int QuickSpectrumF (float *pFWaveform, float *pFWindow, int sizeWindow, float *pFMagSpectrum, float *pFPhaseSpectrum, int sizeFft) { int sizeMag = sizeFft >> 1, i, it2; float *pFBuffer, fReal, fImag; /* allocate buffer */ if ((pFBuffer = (float *) calloc(sizeFft+1, sizeof(float))) == NULL) return -1; /* apply window to waveform */ for (i = 0; i < sizeWindow; i++) pFBuffer[i] = pFWindow[i] * pFWaveform[i]; /* compute real FFT */ realft (pFBuffer-1, sizeMag, 1); /* convert from rectangular to polar coordinates */ for (i=0; i<sizeMag; i++) { it2 = i << 1; fReal = pFBuffer[it2]; fImag = pFBuffer[it2+1]; if (fReal != 0 || fImag != 0) { pFMagSpectrum[i] = sqrt(fReal * fReal + fImag * fImag); if (pFPhaseSpectrum) pFPhaseSpectrum[i] = atan2(fImag, fReal); } } free(pFBuffer); return (sizeMag); } /* * function to perform the inverse FFT * float *pFMagSpectrum input magnitude spectrum * float *pFPhaseSpectrum input phase spectrum * int sizeFft size of FFT * float *pFWaveform output waveform * int sizeWave size of output waveform */ int InverseQuickSpectrum (float *pFMagSpectrum, float *pFPhaseSpectrum, int sizeFft, float *pFWaveform, int sizeWave) { int sizeMag = sizeFft >> 1, i, it2; float *pFBuffer, fPower; /* allocate buffer */ if ((pFBuffer = (float *) calloc(sizeFft+1, sizeof(float))) == 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 */ realft (pFBuffer-1, sizeMag, -1); /* assume the output array has been taken care off */ for (i = 0; i < sizeWave; i++) pFWaveform[i] += pFBuffer[i]; free(pFBuffer); return (sizeMag); } /* * function to perform the inverse FFT * float *pFMagSpectrum input magnitude spectrum * float *pFPhaseSpectrum input phase spectrum * int sizeFft size of FFT * float *pFWaveform output waveform * int sizeWave size of output waveform * float *pFWindow synthesis window */ int InverseQuickSpectrumW (float *pFMagSpectrum, float *pFPhaseSpectrum, int sizeFft, float *pFWaveform, int sizeWave, float *pFWindow) { int sizeMag = sizeFft >> 1, i, it2; float *pFBuffer, fPower; /* allocate buffer */ if ((pFBuffer = (float *) calloc(sizeFft, sizeof(float))) == 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 */ realft (pFBuffer-1, sizeMag, -1); /* assume the output array has been taken care off */ for (i = 0; i < sizeWave; i++) pFWaveform[i] += (pFBuffer[i] * pFWindow[i] * .5); free (pFBuffer); return (sizeMag); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.