This is smsSynthesis.c in view mode; [Download] [Up]
#include "../sms.h" /* synthesis of one frame of the deterministic component using the IFFT */ static int SineSynthIFFT (SMS_DATA *pSmsData, float *pFBuffer, SYNTH_PARAMS *pSynthParams) { long sizeFft = pSynthParams->sizeHop * 2, sizeMag = pSynthParams->sizeHop, nBins = 8, iFirstBin, k, i, l, b, nTraj = pSmsData->nTraj; float fMag=0, fFreq=0, fPhase=0, fLoc, fSin, fCos, fBinRemainder, fTmp, fNewMag, *pFFftBuffer, fIndex; pFFftBuffer = (float *) calloc(sizeFft+1, sizeof(float)); for (i = 0; i < nTraj; i++) { if (((fMag = pSmsData->pFMagTraj[i]) > 0) && ((fFreq = pSmsData->pFFreqTraj[i]) < FHalfSamplingRate)) { if (pSynthParams->previousFrame.pFMagTraj[i] <= 0) pSynthParams->previousFrame.pFPhaTraj[i] = TWO_PI * ((random() - HALF_MAX) / HALF_MAX); fMag = TO_MAG (fMag); fTmp = pSynthParams->previousFrame.pFPhaTraj[i] + (TWO_PI * fFreq / pSynthParams->fSamplingRate) * sizeMag; fPhase = fTmp - floor(fTmp / TWO_PI) * TWO_PI; fLoc = sizeFft * fFreq / pSynthParams->fSamplingRate; iFirstBin = (int) fLoc - 3; fBinRemainder = fLoc - floor (fLoc); fSin = SinTab (fPhase); fCos = SinTab (fPhase + PI_2); for (k = 1, l = iFirstBin; k <= nBins; k++, l++) { fIndex = (k - fBinRemainder); if (fIndex > 7.999) fIndex = 0; fNewMag = fMag * SincTab (fIndex); if (l > 0 && l < sizeMag) { pFFftBuffer[l*2+1] += fNewMag * fCos; pFFftBuffer[l*2] += fNewMag * fSin; } else if (l == 0) { pFFftBuffer[0] += 2 * fNewMag * fSin; } else if (l < 0) { b = abs(l); pFFftBuffer[b*2+1] -= fNewMag * fCos; pFFftBuffer[b*2] += fNewMag * fSin; } else if (l > sizeMag) { b = sizeMag - (l - sizeMag); pFFftBuffer[b*2+1] -= fNewMag * fCos; pFFftBuffer[b*2] += fNewMag * fSin; } else if (l == sizeMag) { pFFftBuffer[1] += 2 * fNewMag * fSin; } } } pSynthParams->previousFrame.pFMagTraj[i] = fMag; pSynthParams->previousFrame.pFPhaTraj[i] = fPhase; pSynthParams->previousFrame.pFFreqTraj[i] = fFreq; } realft (pFFftBuffer-1, sizeMag, -1); for(i = 0, k = sizeMag; i < sizeMag; i++, k++) pFBuffer[i] += pFFftBuffer[k] * pSynthParams->pFDetWindow[i]; for(i= sizeMag, k = 0; i < sizeFft; i++, k++) pFBuffer[i] += pFFftBuffer[k] * pSynthParams->pFDetWindow[i]; free (pFFftBuffer); return (1); } /* synthesis of one frame of the stochastic component using spectral envelopes */ static int StocSynthIFFT (SMS_DATA *pSmsData, float *pFBuffer, SYNTH_PARAMS *pSynthParams) { float *pFMagSpectrum, *pFPhaseSpectrum; int i, nSegments = pSmsData->nCoeff, nSegmentsUsed; int sizeFft = pSynthParams->sizeHop << 1, sizeMag = pSynthParams->sizeHop; /* if no gain or no coefficients return */ if (*(pSmsData->pFStocGain) <= 0) return 0; if ((pFMagSpectrum = (float *) calloc(sizeMag, sizeof(float))) == NULL) return -1; if ((pFPhaseSpectrum = (float *) calloc(sizeMag, sizeof(float))) == NULL) return -1; *(pSmsData->pFStocGain) = TO_MAG(*(pSmsData->pFStocGain)); /* scale the coefficients to normal amplitude */ for (i = 0; i < nSegments; i++) pSmsData->pFStocCoeff[i] *= 2 * *(pSmsData->pFStocGain); nSegmentsUsed = nSegments * pSynthParams->fSamplingRate / pSynthParams->fOriginalSRate; SpectralApprox (pSmsData->pFStocCoeff, nSegments, nSegmentsUsed, pFMagSpectrum, sizeMag, nSegmentsUsed); /* generate random phases */ for (i = 0; i < sizeMag; i++) pFPhaseSpectrum[i] = TWO_PI * ((random() - HALF_MAX) / HALF_MAX); InverseQuickSpectrumW (pFMagSpectrum, pFPhaseSpectrum, sizeFft, pFBuffer, sizeFft, pSynthParams->pFStocWindow); free (pFMagSpectrum); free (pFPhaseSpectrum); return 1; } /* synthesizes one frame of SMS data * * SMS_DATA *pSmsData; input SMS data * short *pSSynthesis; output sound buffer * SYNTH_PARAMS *pSynthParams; synthesis parameters */ int SmsSynthesis (SMS_DATA *pSmsData, short *pSSynthesis, SYNTH_PARAMS *pSynthParams) { static float *pFBuffer = NULL; int i, sizeHop = pSynthParams->sizeHop; if (pFBuffer == NULL) { if((pFBuffer = (float *) calloc(sizeHop*2, sizeof(float))) == NULL) return -1; } memcpy ((char *) pFBuffer, (char *)(pFBuffer+sizeHop), sizeof(float) * sizeHop); memset ((char *)(pFBuffer+sizeHop), 0, sizeof(float) * sizeHop); /* synthesize stochastic component */ if (pSmsData->nCoeff > 0 && pSynthParams->iSynthesisType != 1) StocSynthIFFT (pSmsData, pFBuffer, pSynthParams); /* synthesize deterministic component */ if (pSynthParams->iSynthesisType != 2) SineSynthIFFT (pSmsData, pFBuffer, pSynthParams); /* de-emphasize the sound */ for(i = 0; i < sizeHop; i++) pSSynthesis[i] = (short) DeEmphasis(pFBuffer[i]); return (1); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.