summaryrefslogtreecommitdiff
path: root/sms/spectrum.c
diff options
context:
space:
mode:
Diffstat (limited to 'sms/spectrum.c')
-rw-r--r--sms/spectrum.c403
1 files changed, 149 insertions, 254 deletions
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<sizeMag; i++)
- {
- it2 = i << 1;
- fReal = pFftBuffer[it2];
- fImag = pFftBuffer[it2+1];
- pMag[i] = sqrtf(fReal * fReal + fImag * fImag);
- }
-
- //return (err);
- return (sizeFft);
+ int i,it2;
+ int sizeFft = sizeMag << 1;
+ sfloat fReal, fImag;
+
+ /* apply window to waveform, zero the rest of the array */
+ 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<sizeMag; i++)
+ {
+ it2 = i << 1;
+ fReal = pFftBuffer[it2];
+ fImag = pFftBuffer[it2+1];
+ pMag[i] = sqrtf(fReal * fReal + fImag * fImag);
+ }
+
+ return sizeFft;
}
-
+
/*! \brief function for a quick inverse spectrum, windowed
*
* Not done yet, but this will be a function that is the inverse of
@@ -150,194 +110,129 @@ int sms_spectrumMag (int sizeWindow, sfloat *pWaveform, sfloat *pWindow,
* function to perform the inverse FFT, windowing the output
* sfloat *pFMagSpectrum input magnitude spectrum
* sfloat *pFPhaseSpectrum input phase spectrum
- * int sizeFft size of FFT
- * sfloat *pFWaveform output waveform
+ * int sizeFft size of FFT
+ * sfloat *pFWaveform output waveform
* int sizeWave size of output waveform
- * sfloat *pFWindow synthesis window
+ * sfloat *pFWindow synthesis window
*/
-int sms_invSpectrum (int sizeWaveform, sfloat *pWaveform, sfloat *pWindow ,
- int sizeMag, sfloat *pMag, sfloat *pPhase)
+int sms_invSpectrum(int sizeWaveform, sfloat *pWaveform, sfloat *pWindow,
+ int sizeMag, sfloat *pMag, sfloat *pPhase, sfloat *pFftBuffer)
{
- int i;
- int sizeFft = sizeMag << 1;
- int err = 0;
- static sfloat *pFftBuffer;
- static int sizeFftArray = 0;
+ int i;
+ int sizeFft = sizeMag << 1;
- 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);
- }
- }
+ sms_PolarToRect(sizeMag, pFftBuffer, pMag, pPhase);
+ sms_ifft(sizeFft, pFftBuffer);
- sms_PolarToRect(sizeMag, pFftBuffer, pMag, pPhase);
- /* compute IFFT */
- sms_ifft(sizeFft, pFftBuffer);
+ /* assume the output array has been taken care off */
+ /* before, this was multiplied by .5, why? */
+ for (i = 0; i < sizeWaveform; i++)
+ //pWaveform[i] += pFftBuffer[i] * pWindow[i];
+ pWaveform[i] = pFftBuffer[i];
- /* assume the output array has been taken care off */
- /* before, this was multiplied by .5, why? */
- for (i = 0; i < sizeWaveform; i++)
- //pWaveform[i] += pFftBuffer[i] * pWindow[i];
- pWaveform[i] = pFftBuffer[i];
-
- return (sizeFft);
-// return (err);
+ return sizeFft;
}
+
/*! \brief function for a quick inverse spectrum, windowed
* function to perform the inverse FFT, windowing the output
* sfloat *pFMagSpectrum input magnitude spectrum
* sfloat *pFPhaseSpectrum input phase spectrum
- * int sizeFft size of FFT
- * sfloat *pFWaveform output waveform
+ * int sizeFft size of FFT
+ * sfloat *pFWaveform output waveform
* int sizeWave size of output waveform
- * sfloat *pFWindow synthesis window
+ * sfloat *pFWindow synthesis window
*/
-int sms_invQuickSpectrumW (sfloat *pFMagSpectrum, sfloat *pFPhaseSpectrum,
- int sizeFft, sfloat *pFWaveform, int sizeWave,
- sfloat *pFWindow)
+int sms_invQuickSpectrumW(sfloat *pFMagSpectrum, sfloat *pFPhaseSpectrum,
+ int sizeFft, sfloat *pFWaveform, int sizeWave,
+ sfloat *pFWindow, sfloat* pFftBuffer)
{
- int sizeMag = sizeFft >> 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<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 */
- /* \todo is a seperate pFBuffer necessary here?
- it seems like multiplying the window into the waveform
- would be fine, without pFBuffer */
- for (i = 0; i < sizeWave; i++)
- pFWaveform[i] += (pFBuffer[i] * pFWindow[i] * .5);
-
- free (pFBuffer);
-
- return (sizeMag);
+ int sizeMag = sizeFft >> 1, i, it2;
+ sfloat fPower;
+
+ /* convert from polar coordinates to rectangular */
+ for (i = 0; i<sizeMag; i++)
+ {
+ it2 = i << 1;
+ fPower = pFMagSpectrum[i];
+ pFftBuffer[it2] = fPower * cos (pFPhaseSpectrum[i]);
+ pFftBuffer[it2+1] = fPower * sin (pFPhaseSpectrum[i]);
+ }
+
+ /* compute IFFT */
+ sms_ifft(sizeFft, pFftBuffer);
+
+ /* assume the output array has been taken care off */
+ /* \todo is a seperate pFftBuffer necessary here?
+ it seems like multiplying the window into the waveform
+ would be fine, without pFftBuffer */
+ for (i = 0; i < sizeWave; i++)
+ pFWaveform[i] += (pFftBuffer[i] * pFWindow[i] * .5);
+
+ return sizeMag;
}
/*! \brief convert spectrum from Rectangular to Polar form
*
- * \param sizeMag size of spectrum (pMag and pPhase arrays)
- * \param pRect pointer output spectrum in rectangular form (2x sizeSpec)
- * \param pMag pointer to sfloat array of magnitude spectrum
- * \param pPhase pointer to sfloat array of phase spectrum
+ * \param sizeMag size of spectrum (pMag and pPhase arrays)
+ * \param pRect pointer output spectrum in rectangular form (2x sizeSpec)
+ * \param pMag pointer to sfloat array of magnitude spectrum
+ * \param pPhase pointer to sfloat array of phase spectrum
*/
void sms_RectToPolar( int sizeMag, sfloat *pRect, sfloat *pMag, sfloat *pPhase)
{
- int i, it2;
- sfloat fReal, fImag;
-
- for (i=0; i<sizeMag; i++)
- {
- it2 = i << 1;
- fReal = pRect[it2];
- fImag = pRect[it2+1];
-
- pMag[i] = sqrtf(fReal * fReal + fImag * fImag);
- if (pPhase)
- pPhase[i] = atan2f(fImag, fReal);
- }
-
-
+ int i, it2;
+ sfloat fReal, fImag;
+
+ for (i=0; i<sizeMag; i++)
+ {
+ it2 = i << 1;
+ fReal = pRect[it2];
+ fImag = pRect[it2+1];
+
+ pMag[i] = sqrtf(fReal * fReal + fImag * fImag);
+ if (pPhase)
+ pPhase[i] = atan2f(fImag, fReal);
+ }
}
/*! \brief convert spectrum from Rectangular to Polar form
*
- * \param sizeSpec size of spectrum (pMag and pPhase arrays)
- * \param pRect pointer output spectrum in rectangular form (2x sizeSpec)
- * \param pMag pointer to sfloat array of magnitude spectrum
- * \param pPhase pointer to sfloat array of phase spectrum
+ * \param sizeSpec size of spectrum (pMag and pPhase arrays)
+ * \param pRect pointer output spectrum in rectangular form (2x sizeSpec)
+ * \param pMag pointer to sfloat array of magnitude spectrum
+ * \param pPhase pointer to sfloat array of phase spectrum
*/
-void sms_PolarToRect( int sizeSpec, sfloat *pRect, sfloat *pMag, sfloat *pPhase)
+void sms_PolarToRect(int sizeSpec, sfloat *pRect, sfloat *pMag, sfloat *pPhase)
{
- int i, it2;
- sfloat fMag;
-
- for (i = 0; i<sizeSpec; i++)
- {
- it2 = i << 1;
- fMag = pMag[i];
- pRect[it2] = fMag * cos (pPhase[i]);
- pRect[it2+1] = fMag * sin (pPhase[i]);
- }
+ int i, it2;
+ sfloat fMag;
+
+ for(i = 0; i<sizeSpec; i++)
+ {
+ it2 = i << 1;
+ fMag = pMag[i];
+ pRect[it2] = fMag * cos (pPhase[i]);
+ pRect[it2+1] = fMag * sin (pPhase[i]);
+ }
}
/*! \brief compute magnitude spectrum of a DFT in rectangular coordinates
*
- * \param sizeMag size of output Magnitude (half of input real FFT)
- * \param pInRect pointer to input DFT array (real/imag sfloats)
- * \param pOutMag pointer to of magnitude spectrum array
+ * \param sizeMag size of output Magnitude (half of input real FFT)
+ * \param pInRect pointer to input DFT array (real/imag sfloats)
+ * \param pOutMag pointer to of magnitude spectrum array
*/
-void sms_spectrumRMS( int sizeMag, sfloat *pInRect, sfloat *pOutMag)
+void sms_spectrumRMS(int sizeMag, sfloat *pInRect, sfloat *pOutMag)
{
- int i, it2;
- sfloat fReal, fImag;
-
- for (i=0; i<sizeMag; i++)
- {
- it2 = i << 1;
- fReal = pInRect[it2];
- fImag = pInRect[it2+1];
- pOutMag[i] = sqrtf(fReal * fReal + fImag * fImag);
- }
+ int i, it2;
+ sfloat fReal, fImag;
+
+ for(i=0; i<sizeMag; i++)
+ {
+ it2 = i << 1;
+ fReal = pInRect[it2];
+ fImag = pInRect[it2+1];
+ pOutMag[i] = sqrtf(fReal * fReal + fImag * fImag);
+ }
}
-
-/*! \brief convert from Polar spectrum to waveform
- * function to perform the inverse FFT
- * sfloat *pFMagSpectrum input magnitude spectrum
- * sfloat *pFPhaseSpectrum input phase spectrum
- * int sizeFft size of FFT
- * sfloat *pFWaveform output waveform
- * int sizeWave size of output waveform
- */
-/* int sms_invSpectrum (sfloat *pFMagSpectrum, sfloat *pFPhaseSpectrum, */
-/* int sizeFft, sfloat *pFWaveform, int sizeWave) */
-/* { */
-/* int sizeMag = sizeFft >> 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); */
-/* } */