summaryrefslogtreecommitdiff
path: root/sms/sms.c
diff options
context:
space:
mode:
authorJohn Glover <glover.john@gmail.com>2011-01-06 11:54:26 +0000
committerJohn Glover <glover.john@gmail.com>2011-01-06 11:54:26 +0000
commit0c141d4c9a03d4839e2a8626961bd6bbdd3e7f26 (patch)
tree33c6f276f0b9ace8d96535f4afb89926ec33e7bc /sms/sms.c
parent17c5625449888117208447dd4f86504281357013 (diff)
downloadsimpl-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/sms.c')
-rw-r--r--sms/sms.c72
1 files changed, 59 insertions, 13 deletions
diff --git a/sms/sms.c b/sms/sms.c
index 27b6724..8501d4d 100644
--- a/sms/sms.c
+++ b/sms/sms.c
@@ -319,7 +319,7 @@ int sms_initAnalysis(SMS_AnalParams *pAnalParams)
}
/* memory for residual */
- pAnalParams->residualParams.residualSize = pAnalParams->sizeHop * 2;
+ pAnalParams->residualParams.hopSize = pAnalParams->sizeHop;
sms_initResidual(&pAnalParams->residualParams);
/* memory for guide states */
@@ -467,15 +467,20 @@ int sms_initSynth(SMS_SynthParams *pSynthParams)
void sms_initResidualParams(SMS_ResidualParams *residualParams)
{
residualParams->samplingRate = 44100;
+ residualParams->hopSize = 256;
residualParams->residualSize = 0;
residualParams->residual = NULL;
- residualParams->residualWindow = NULL;
+ residualParams->fftWindow = NULL;
+ residualParams->ifftWindow = NULL;
+ residualParams->windowScale = 0.0;
residualParams->residualMag = 0.0;
residualParams->originalMag = 0.0;
residualParams->nCoeffs = 128;
residualParams->stocCoeffs = NULL;
residualParams->sizeStocMagSpectrum = 0;
residualParams->stocMagSpectrum = NULL;
+ residualParams->stocPhaseSpectrum = NULL;
+ residualParams->approx = NULL;
residualParams->approxEnvelope = NULL;
int i;
for(i = 0; i < SMS_MAX_SPEC; i++)
@@ -492,13 +497,14 @@ void sms_initResidualParams(SMS_ResidualParams *residualParams)
*/
int sms_initResidual(SMS_ResidualParams *residualParams)
{
- if(residualParams->residualSize <= 0)
+ if(residualParams->hopSize <= 0)
{
- sms_error("Residual size must be a positive integer");
+ sms_error("Residual hop size must be a positive integer");
return -1;
}
/* residual signal */
+ residualParams->residualSize = residualParams->hopSize * 2;
residualParams->residual = (sfloat *)calloc(residualParams->residualSize, sizeof(sfloat));
if(residualParams->residual == NULL)
{
@@ -506,15 +512,34 @@ int sms_initResidual(SMS_ResidualParams *residualParams)
return -1;
}
- /* residual window */
- residualParams->residualWindow = (sfloat *)calloc(residualParams->residualSize, sizeof(sfloat));
- if(residualParams->residualWindow == NULL)
+ /* residual fft/ifft windows */
+ residualParams->fftWindow = (sfloat *)calloc(residualParams->residualSize, sizeof(sfloat));
+ if(residualParams->fftWindow == NULL)
{
- sms_error("Could not allocate memory for residualWindow");
+ sms_error("Could not allocate memory for residual FFT window");
return -1;
}
- sms_getWindow(residualParams->residualSize, residualParams->residualWindow, SMS_WIN_HAMMING);
- sms_scaleWindow(residualParams->residualSize, residualParams->residualWindow);
+ sms_getWindow(residualParams->residualSize, residualParams->fftWindow, SMS_WIN_BH_70);
+ sms_scaleWindow(residualParams->residualSize, residualParams->fftWindow);
+
+ residualParams->ifftWindow = (sfloat *)calloc(residualParams->residualSize, sizeof(sfloat));
+ if(residualParams->ifftWindow == NULL)
+ {
+ sms_error("Could not allocate memory for residual IFFT window");
+ return -1;
+ }
+ sms_getWindow(residualParams->residualSize, residualParams->ifftWindow, SMS_WIN_HANNING);
+ /* compute IFFT window scaling:
+ * windows per hop = hop size / window size = 0.5
+ * overlap = 50% => 1 window total in each hop/frame
+ * => windowScale = window size / sum(window samples) = 1.85
+ * for a 1024 sized hamming window
+ */
+ int i;
+ sfloat sum = 0.0;
+ for(i = 0; i < residualParams->residualSize; i++)
+ sum += residualParams->ifftWindow[i];
+ residualParams->windowScale = (sfloat)residualParams->residualSize / sum;
/* stochastic analysis */
residualParams->stocCoeffs = (sfloat *)calloc(residualParams->nCoeffs, sizeof(sfloat));
@@ -531,7 +556,19 @@ int sms_initResidual(SMS_ResidualParams *residualParams)
sms_error("Could not allocate memory for stochastic magnitude spectrum");
return -1;
}
+ residualParams->stocPhaseSpectrum = (sfloat *)calloc(residualParams->sizeStocMagSpectrum, sizeof(sfloat));
+ if(residualParams->stocPhaseSpectrum == NULL)
+ {
+ sms_error("Could not allocate memory for stochastic magnitude spectrum");
+ return -1;
+ }
+ residualParams->approx = (sfloat *)calloc(residualParams->residualSize, sizeof(sfloat));
+ if(residualParams->approx == NULL)
+ {
+ sms_error("Could not allocate memory for spectral approximation");
+ return -1;
+ }
residualParams->approxEnvelope = (sfloat *)calloc(residualParams->nCoeffs, sizeof(sfloat));
if(residualParams->approxEnvelope == NULL)
{
@@ -553,19 +590,28 @@ void sms_freeResidual(SMS_ResidualParams *residualParams)
{
if(residualParams->residual)
free(residualParams->residual);
- if(residualParams->residualWindow)
- free(residualParams->residualWindow);
+ if(residualParams->fftWindow)
+ free(residualParams->fftWindow);
+ if(residualParams->ifftWindow)
+ free(residualParams->ifftWindow);
if(residualParams->stocCoeffs)
free(residualParams->stocCoeffs);
if(residualParams->stocMagSpectrum)
free(residualParams->stocMagSpectrum);
+ if(residualParams->stocPhaseSpectrum)
+ free(residualParams->stocPhaseSpectrum);
+ if(residualParams->approx)
+ free(residualParams->approx);
if(residualParams->approxEnvelope)
free(residualParams->approxEnvelope);
residualParams->residual = NULL;
- residualParams->residualWindow = NULL;
+ residualParams->fftWindow = NULL;
+ residualParams->ifftWindow = NULL;
residualParams->stocCoeffs = NULL;
residualParams->stocMagSpectrum = NULL;
+ residualParams->stocPhaseSpectrum = NULL;
+ residualParams->approx = NULL;
residualParams->approxEnvelope = NULL;
}