diff options
author | John Glover <glover.john@gmail.com> | 2011-01-06 11:54:26 +0000 |
---|---|---|
committer | John Glover <glover.john@gmail.com> | 2011-01-06 11:54:26 +0000 |
commit | 0c141d4c9a03d4839e2a8626961bd6bbdd3e7f26 (patch) | |
tree | 33c6f276f0b9ace8d96535f4afb89926ec33e7bc /sms/spectrum.c | |
parent | 17c5625449888117208447dd4f86504281357013 (diff) | |
download | simpl-0c141d4c9a03d4839e2a8626961bd6bbdd3e7f26.tar.gz simpl-0c141d4c9a03d4839e2a8626961bd6bbdd3e7f26.tar.bz2 simpl-0c141d4c9a03d4839e2a8626961bd6bbdd3e7f26.zip |
Fixed SMSResidual. Also removed blank frames produced by sms at the beginning of analysis which was causing synthesised audio to be out of sync with the original.
Diffstat (limited to 'sms/spectrum.c')
-rw-r--r-- | sms/spectrum.c | 59 |
1 files changed, 43 insertions, 16 deletions
diff --git a/sms/spectrum.c b/sms/spectrum.c index 666b42d..1b8e053 100644 --- a/sms/spectrum.c +++ b/sms/spectrum.c @@ -37,7 +37,6 @@ int sms_spectrum(int sizeWindow, sfloat *pWaveform, sfloat *pWindow, int sizeMag sfloat *pMag, sfloat *pPhase, sfloat *pFftBuffer) { int i, it2; - int err = 0; sfloat fReal, fImag; int sizeFft = sizeMag << 1; @@ -55,6 +54,38 @@ int sms_spectrum(int sizeWindow, sfloat *pWaveform, sfloat *pWindow, int sizeMag 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? */ + /*pPhase[i] = atan2(fImag, fReal);*/ + } + + return sizeFft; +} + +/* sms_spectrum, but without zero-phase windowing, and with phase calculated + * according by arctan(imag/real) instead of arctan2(-imag/real) + */ +int sms_spectrumW(int sizeWindow, sfloat *pWaveform, sfloat *pWindow, int sizeMag, + sfloat *pMag, sfloat *pPhase, sfloat *pFftBuffer) +{ + int i, it2; + sfloat fReal, fImag; + + int sizeFft = sizeMag << 1; + memset(pFftBuffer, 0, sizeFft * sizeof(sfloat)); + + /* apply window to waveform */ + for(i = 0; i < sizeWindow; i++) + pFftBuffer[i] = pWaveform[i] * pWindow[i]; + + 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); } return sizeFft; @@ -81,8 +112,8 @@ int sms_spectrumMag(int sizeWindow, sfloat *pWaveform, sfloat *pWindow, 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 = 0; i < sizeWindow; i++) + pFftBuffer[i] = pWaveform[i] * pWindow[i]; for(i = sizeWindow; i < sizeFft; i++) pFftBuffer[i] = 0.; @@ -90,7 +121,7 @@ int sms_spectrumMag(int sizeWindow, sfloat *pWaveform, sfloat *pWindow, sms_fft(sizeFft, pFftBuffer); /* convert from rectangular to polar coordinates */ - for (i=0; i<sizeMag; i++) + for(i = 0; i < sizeMag; i++) { it2 = i << 1; fReal = pFftBuffer[it2]; @@ -123,7 +154,7 @@ int sms_invSpectrum(int sizeWaveform, sfloat *pWaveform, sfloat *pWindow, sms_PolarToRect(sizeMag, pFftBuffer, pMag, pPhase); sms_ifft(sizeFft, pFftBuffer); - /* assume the output array has been taken care off */ + /* assume that the output array does not need to be cleared */ /* before, this was multiplied by .5, why? */ for(i = 0; i < sizeWaveform; i++) //pWaveform[i] += pFftBuffer[i] * pWindow[i]; @@ -145,25 +176,21 @@ int sms_invQuickSpectrumW(sfloat *pFMagSpectrum, sfloat *pFPhaseSpectrum, int sizeFft, sfloat *pFWaveform, int sizeWave, sfloat *pFWindow, sfloat* pFftBuffer) { - int sizeMag = sizeFft >> 1, i, it2; - sfloat fPower; + int i, it2; + int sizeMag = sizeFft >> 1; - /* convert from polar coordinates to rectangular */ - for(i = 0; i<sizeMag; i++) + /* 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]); + pFftBuffer[it2] = pFMagSpectrum[i] * cos(pFPhaseSpectrum[i]); + pFftBuffer[it2+1] = pFMagSpectrum[i] * 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 */ + /* assume that the output array does not need to be cleared */ for(i = 0; i < sizeWave; i++) pFWaveform[i] += (pFftBuffer[i] * pFWindow[i] * .5); |