summaryrefslogtreecommitdiff
path: root/sms/synthesis.c
diff options
context:
space:
mode:
Diffstat (limited to 'sms/synthesis.c')
-rw-r--r--sms/synthesis.c113
1 files changed, 58 insertions, 55 deletions
diff --git a/sms/synthesis.c b/sms/synthesis.c
index 9523ee6..bc739d0 100644
--- a/sms/synthesis.c
+++ b/sms/synthesis.c
@@ -120,14 +120,12 @@ static int StocSynthApprox(SMS_Data *pSmsData, SMS_SynthParams *pSynthParams)
int sizeSpec1 = pSmsData->nCoeff;
int sizeSpec2 = pSynthParams->sizeHop;
int sizeFft = pSynthParams->sizeHop << 1; /* 50% overlap, so sizeFft is 2x sizeHop */
- sfloat fStocGain;
/* if no gain or no coefficients return */
- if (*(pSmsData->pFStocGain) <= 0)
+ if(*(pSmsData->pFStocGain) <= 0)
return 0;
- sizeSpec1Used = sizeSpec1 * pSynthParams->iSamplingRate /
- pSynthParams->iOriginalSRate;
+ sizeSpec1Used = sizeSpec1 * pSynthParams->iSamplingRate / pSynthParams->iOriginalSRate;
/* sizeSpec1Used cannot be more than what is available \todo check by graph */
if(sizeSpec1Used > sizeSpec1) sizeSpec1Used = sizeSpec1;
@@ -150,74 +148,79 @@ static int StocSynthApprox(SMS_Data *pSmsData, SMS_SynthParams *pSynthParams)
*
* \param residualParams Parameters and memory for residual synthesis
*/
-void sms_approxResidual(SMS_ResidualParams *residualParams)
+void sms_approxResidual(int sizeResidual, sfloat* residual,
+ int sizeApprox, sfloat* approx,
+ SMS_ResidualParams *residualParams)
{
- /* filter residual with a high pass filter */
- sms_filterHighPass(residualParams->residualSize,
- residualParams->residual,
- residualParams->samplingRate);
-
- sms_spectrumMag(residualParams->residualSize,
- residualParams->residual,
- residualParams->residualWindow,
- residualParams->sizeStocMagSpectrum,
- residualParams->stocMagSpectrum,
- residualParams->fftBuffer);
-
- sms_spectralApprox(residualParams->stocMagSpectrum,
- residualParams->sizeStocMagSpectrum,
- residualParams->sizeStocMagSpectrum,
- residualParams->stocCoeffs,
- residualParams->nCoeffs,
- residualParams->nCoeffs,
- residualParams->approxEnvelope);
-
- /* get energy of spectrum */
int i;
- sfloat fMag = 0.0;
- for(i = 0; i < residualParams->sizeStocMagSpectrum; i++)
- fMag += (residualParams->stocMagSpectrum[i] * pAnalParams->stocMagSpectrum[i]);
- /* if no gain or no coefficients return */
- sfloat stocGain = fMag / residualParams->sizeStocMagSpectrum;
- if(stocGain <= 0)
- return;
+ /* shift buffers */
+ memcpy(residualParams->residual,
+ residualParams->residual + residualParams->hopSize,
+ sizeof(sfloat) * residualParams->hopSize);
+ memcpy(residualParams->residual + residualParams->hopSize, residual,
+ sizeof(sfloat) * residualParams->hopSize);
- int i, sizeSpec1Used;
- int sizeSpec1 = residualParams->nCoeffs;
- /*int sizeSpec2 = pSynthParams->sizeHop;*/
- int sizeSpec2 = residualParams->residualSize;
- int sizeFft = sizeSpec2 << 1; /* 50% overlap, so sizeFft is 2x sizeHop */
+ memcpy(residualParams->approx,
+ residualParams->approx + residualParams->hopSize,
+ sizeof(sfloat) * residualParams->hopSize);
+ memset(residualParams->approx + residualParams->hopSize, 0,
+ sizeof(sfloat) * residualParams->hopSize);
- /*sizeSpec1Used = sizeSpec1 * pSynthParams->iSamplingRate / pSynthParams->iOriginalSRate;*/
+ sms_spectrumMag(residualParams->residualSize,
+ residualParams->residual,
+ residualParams->fftWindow,
+ residualParams->sizeStocMagSpectrum,
+ residualParams->stocMagSpectrum,
+ residualParams->fftBuffer);
+
+ if(residualParams->sizeStocMagSpectrum != residualParams->nCoeffs)
+ {
+ sms_spectralApprox(residualParams->stocMagSpectrum,
+ residualParams->sizeStocMagSpectrum,
+ residualParams->sizeStocMagSpectrum,
+ residualParams->stocCoeffs,
+ residualParams->nCoeffs,
+ residualParams->nCoeffs,
+ residualParams->approxEnvelope);
- /*[> sizeSpec1Used cannot be more than what is available \todo check by graph <]*/
- /*if(sizeSpec1Used > sizeSpec1) sizeSpec1Used = sizeSpec1;*/
+ sms_spectralApprox(residualParams->stocCoeffs,
+ residualParams->nCoeffs,
+ residualParams->nCoeffs,
+ residualParams->stocMagSpectrum,
+ residualParams->sizeStocMagSpectrum,
+ residualParams->sizeStocMagSpectrum,
+ residualParams->approxEnvelope);
+ }
- /*sms_spectralApprox(pSmsData->pFStocCoeff, sizeSpec1, sizeSpec1Used,*/
- /* pSynthParams->pMagBuff, sizeSpec2, sizeSpec1Used,*/
- /* pSynthParams->approxEnvelope);*/
+ /* generate random phases */
+ for(i = 0; i < residualParams->sizeStocMagSpectrum; i++)
+ residualParams->stocPhaseSpectrum[i] = TWO_PI * sms_random();
- /*[> generate random phases <]*/
- /*for(i = 0; i < sizeSpec2; i++)*/
- /* pSynthParams->pPhaseBuff[i] = TWO_PI * sms_random();*/
+ /* IFFT with 50% overlap */
+ sms_invQuickSpectrumW(residualParams->stocMagSpectrum,
+ residualParams->stocPhaseSpectrum,
+ residualParams->sizeStocMagSpectrum*2,
+ residualParams->approx,
+ residualParams->residualSize,
+ residualParams->ifftWindow,
+ residualParams->fftBuffer);
- /*sms_invQuickSpectrumW(pSynthParams->pMagBuff, pSynthParams->pPhaseBuff,*/
- /* sizeFft, pSynthParams->pSynthBuff, sizeFft,*/
- /* pSynthParams->pFStocWindow, pSynthParams->pSpectra);*/
+ /* output */
+ for(i = 0; i < sizeApprox; i++)
+ approx[i] = residualParams->approx[i] * residualParams->windowScale;
}
/*! \brief synthesizes one frame of SMS data
*
- * \param pSmsData input SMS data
- * \param pFSynthesis output sound buffer
- * \param pSynthParams synthesis parameters
+ * \param pSmsData input SMS data
+ * \param pFSynthesis output sound buffer
+ * \param pSynthParams synthesis parameters
*/
void sms_synthesize(SMS_Data *pSmsData, sfloat *pFSynthesis, SMS_SynthParams *pSynthParams)
{
- int i, k;
+ int i;
int sizeHop = pSynthParams->sizeHop;
- int sizeFft = sizeHop << 1;
memcpy(pSynthParams->pSynthBuff, (sfloat *)(pSynthParams->pSynthBuff+sizeHop),
sizeof(sfloat) * sizeHop);