summaryrefslogtreecommitdiff
path: root/sms
diff options
context:
space:
mode:
authorJohn Glover <glover.john@gmail.com>2010-11-24 23:26:43 +0000
committerJohn Glover <glover.john@gmail.com>2010-11-24 23:26:43 +0000
commit5e25edb1b78f28bee09bd7513a80fb500bbd59c4 (patch)
tree9290c3757abdecf2525c68cd5e5082fa9604ca61 /sms
parent580dd2e019e9666dc5f4771dedeb0720aa8d1d07 (diff)
downloadsimpl-5e25edb1b78f28bee09bd7513a80fb500bbd59c4.tar.gz
simpl-5e25edb1b78f28bee09bd7513a80fb500bbd59c4.tar.bz2
simpl-5e25edb1b78f28bee09bd7513a80fb500bbd59c4.zip
Updated libsms to the latest version (1.15), includes some memory management improvements/simplifications but the basic API is the same. Also started updating the unit tests, which will now use the nose framework
Diffstat (limited to 'sms')
-rw-r--r--sms/analysis.c1081
-rw-r--r--sms/fileIO.c418
-rw-r--r--sms/filters.c73
-rw-r--r--sms/fixTracks.c149
-rw-r--r--sms/peakContinuation.c250
-rw-r--r--sms/peakDetection.c27
-rw-r--r--sms/residual.c126
-rw-r--r--sms/sineSynth.c268
-rw-r--r--sms/sms.c464
-rw-r--r--sms/sms.h654
-rw-r--r--sms/sms.i702
-rw-r--r--sms/soundIO.c3
-rw-r--r--sms/spectralApprox.c213
-rw-r--r--sms/spectrum.c403
-rw-r--r--sms/stocAnalysis.c66
-rw-r--r--sms/synthesis.c410
-rw-r--r--sms/tables.c135
17 files changed, 2539 insertions, 2903 deletions
diff --git a/sms/analysis.c b/sms/analysis.c
index 84eb28c..55c955f 100644
--- a/sms/analysis.c
+++ b/sms/analysis.c
@@ -33,19 +33,19 @@
void printAnalysisParams(SMS_AnalParams* params)
{
- printf("fLowestFreq: %f\n"
- "fHighestFreq: %f\n"
- "fMinPeakMag: %f\n"
- "iSamplingRate: %d\n"
- "iMaxPeaks: %d\n"
- "fHighestFundamental: %f\n"
- "iRefHarmonic: %d\n"
- "fMinRefHarmMag: %f\n"
- "fRefHarmMagDiffFromMax: %f\n"
- "iSoundType: %d\n",
- params->fLowestFreq, params->fHighestFreq, params->fMinPeakMag, params->iSamplingRate,
- params->maxPeaks, params->fHighestFundamental, params->iRefHarmonic,
- params->fMinRefHarmMag, params->fRefHarmMagDiffFromMax, params->iSoundType);
+ printf("fLowestFreq: %f\n"
+ "fHighestFreq: %f\n"
+ "fMinPeakMag: %f\n"
+ "iSamplingRate: %d\n"
+ "iMaxPeaks: %d\n"
+ "fHighestFundamental: %f\n"
+ "iRefHarmonic: %d\n"
+ "fMinRefHarmMag: %f\n"
+ "fRefHarmMagDiffFromMax: %f\n"
+ "iSoundType: %d\n",
+ params->fLowestFreq, params->fHighestFreq, params->fMinPeakMag, params->iSamplingRate,
+ params->maxPeaks, params->fHighestFundamental, params->iRefHarmonic,
+ params->fMinRefHarmMag, params->fRefHarmMagDiffFromMax, params->iSoundType);
}
/*! \brief compute spectrum, find peaks, and fundamental of one frame
@@ -58,49 +58,40 @@ void printAnalysisParams(SMS_AnalParams* params)
*/
void sms_analyzeFrame(int iCurrentFrame, SMS_AnalParams *pAnalParams, sfloat fRefFundamental)
{
- int i, iFrame;
- static int sizeWindowStatic = 0;
- static int sizeMag = 0;
- static sfloat pFMagSpectrum[SMS_MAX_SPEC];
- static sfloat pFPhaSpectrum[SMS_MAX_SPEC];
- static sfloat pFSpectrumWindow[SMS_MAX_SPEC];
+ int i, iFrame;
SMS_AnalFrame *pCurrentFrame = pAnalParams->ppFrames[iCurrentFrame];
- int sizeWindow = pCurrentFrame->iFrameSize;
int iSoundLoc = pCurrentFrame->iFrameSample -((pCurrentFrame->iFrameSize + 1) >> 1) + 1;
- sfloat *pFData = &(pAnalParams->soundBuffer.pFBuffer[iSoundLoc - pAnalParams->soundBuffer.iMarker]);
-
- /*if window size has changed, update the window and sizemag*/
- if (sizeWindowStatic != sizeWindow)
- {
- sizeMag = sms_power2(sizeWindow);
- sms_getWindow(sizeWindow, pFSpectrumWindow, pAnalParams->iWindowType);
- sms_scaleWindow(sizeWindow, pFSpectrumWindow);
- sizeWindowStatic = sizeWindow;
- }
-
- /* compute the magnitude and (zero-windowed) phase spectra */
- sms_spectrum(sizeWindow, pFData, pFSpectrumWindow, sizeMag,
- pFMagSpectrum, pFPhaSpectrum);
-
- /* convert magnitude spectra to dB */
- sms_arrayMagToDB(sizeMag, pFMagSpectrum);
-
- /* find the prominent peaks */
- pCurrentFrame->nPeaks = sms_detectPeaks(sizeMag,
- pFMagSpectrum,
- pFPhaSpectrum,
+ sfloat *pFData = &(pAnalParams->soundBuffer.pFBuffer[iSoundLoc - pAnalParams->soundBuffer.iMarker]);
+
+ /* TODO: this doesn't have to be done every time */
+ int sizeWindow = pCurrentFrame->iFrameSize;
+ int sizeMag = sms_power2(sizeWindow);
+ sms_getWindow(sizeWindow, pAnalParams->spectrumWindow, pAnalParams->iWindowType);
+ sms_scaleWindow(sizeWindow, pAnalParams->spectrumWindow);
+
+ /* compute the magnitude and (zero-windowed) phase spectra */
+ sms_spectrum(sizeWindow, pFData, pAnalParams->spectrumWindow, sizeMag,
+ pAnalParams->magSpectrum, pAnalParams->phaseSpectrum,
+ pAnalParams->fftBuffer);
+
+ /* convert magnitude spectra to dB */
+ sms_arrayMagToDB(sizeMag, pAnalParams->magSpectrum);
+
+ /* find the prominent peaks */
+ pCurrentFrame->nPeaks = sms_detectPeaks(sizeMag,
+ pAnalParams->magSpectrum,
+ pAnalParams->phaseSpectrum,
pCurrentFrame->pSpectralPeaks,
pAnalParams);
- /* find a reference harmonic */
- if (pCurrentFrame->nPeaks > 0 &&
- (pAnalParams->iFormat == SMS_FORMAT_H ||
- pAnalParams->iFormat == SMS_FORMAT_HP))
- pCurrentFrame->fFundamental = sms_harmDetection(pAnalParams->nTracks, pCurrentFrame->pSpectralPeaks,
- fRefFundamental, pAnalParams->iRefHarmonic,
- pAnalParams->fLowestFundamental, pAnalParams->fHighestFundamental,
- pAnalParams->iSoundType, pAnalParams->fMinRefHarmMag,
- pAnalParams->fRefHarmMagDiffFromMax);
+ /* find a reference harmonic */
+ if (pCurrentFrame->nPeaks > 0 &&
+ (pAnalParams->iFormat == SMS_FORMAT_H || pAnalParams->iFormat == SMS_FORMAT_HP))
+ pCurrentFrame->fFundamental = sms_harmDetection(pAnalParams->nTracks, pCurrentFrame->pSpectralPeaks,
+ fRefFundamental, pAnalParams->iRefHarmonic,
+ pAnalParams->fLowestFundamental, pAnalParams->fHighestFundamental,
+ pAnalParams->iSoundType, pAnalParams->fMinRefHarmMag,
+ pAnalParams->fRefHarmMagDiffFromMax);
}
/*! \brief re-analyze the previous frames if necessary
@@ -115,545 +106,545 @@ void sms_analyzeFrame(int iCurrentFrame, SMS_AnalParams *pAnalParams, sfloat fRe
static int ReAnalyzeFrame(int iCurrentFrame, SMS_AnalParams *pAnalParams)
{
sfloat fFund, fLastFund, fDev;
- int iNewFrameSize, i;
- sfloat fAvgDeviation = sms_fundDeviation(pAnalParams, iCurrentFrame);
+ int iNewFrameSize, i;
+ sfloat fAvgDeviation = sms_fundDeviation(pAnalParams, iCurrentFrame);
int iFirstFrame = iCurrentFrame - pAnalParams->minGoodFrames;
- /*! \todo mae this a < 0 check, but first make sure sms_fundDeviation does not
- return values below zero */
- if (fAvgDeviation == -1)
- return (-1);
-
- /* if the last pAnalParams->minGoodFrames are stable look before them */
- /* and recompute the frames that are not stable */
- if (fAvgDeviation <= pAnalParams->maxDeviation)
- for (i = 0; i < pAnalParams->analDelay; i++)
- {
- if (pAnalParams->ppFrames[iFirstFrame - i]->iFrameNum <= 0 ||
- pAnalParams->ppFrames[iFirstFrame - i]->iStatus == SMS_FRAME_RECOMPUTED)
- return(-1);
- fFund = pAnalParams->ppFrames[iFirstFrame - i]->fFundamental;
- fLastFund = pAnalParams->ppFrames[iFirstFrame - i + 1]->fFundamental;
- fDev = fabs (fFund - fLastFund) / fLastFund;
- iNewFrameSize = ((pAnalParams->iSamplingRate / fLastFund) *
- pAnalParams->fSizeWindow/2) * 2 + 1;
-
- if (fFund <= 0 || fDev > .2 ||
- fabs ((double)(pAnalParams->ppFrames[iFirstFrame - i]->iFrameSize -
- iNewFrameSize)) /
- iNewFrameSize >= .2)
- {
- pAnalParams->ppFrames[iFirstFrame - i]->iFrameSize = iNewFrameSize;
- pAnalParams->ppFrames[iFirstFrame - i]->iStatus = SMS_FRAME_READY;
-
- /* recompute frame */
- sms_analyzeFrame(iFirstFrame - i, pAnalParams, fLastFund);
- pAnalParams->ppFrames[iFirstFrame - i]->iStatus = SMS_FRAME_RECOMPUTED;
-
- if (fabs(pAnalParams->ppFrames[iFirstFrame - i]->fFundamental - fLastFund) /
- fLastFund >= .2)
- return(-1);
- }
- }
- return (1);
+ /*! \todo make this a < 0 check, but first make sure sms_fundDeviation does not
+ return values below zero */
+ if(fAvgDeviation == -1)
+ return -1;
+
+ /* if the last SMS_MIN_GOOD_FRAMES are stable look before them */
+ /* and recompute the frames that are not stable */
+ if (fAvgDeviation <= pAnalParams->maxDeviation)
+ {
+ for(i = 0; i < pAnalParams->analDelay; i++)
+ {
+ if(pAnalParams->ppFrames[iFirstFrame - i]->iFrameNum <= 0 ||
+ pAnalParams->ppFrames[iFirstFrame - i]->iStatus == SMS_FRAME_RECOMPUTED)
+ return -1;
+ fFund = pAnalParams->ppFrames[iFirstFrame - i]->fFundamental;
+ fLastFund = pAnalParams->ppFrames[iFirstFrame - i + 1]->fFundamental;
+ fDev = fabs (fFund - fLastFund) / fLastFund;
+ iNewFrameSize = ((pAnalParams->iSamplingRate / fLastFund) *
+ pAnalParams->fSizeWindow/2) * 2 + 1;
+
+ if(fFund <= 0 || fDev > .2 ||
+ fabs((double)(pAnalParams->ppFrames[iFirstFrame - i]->iFrameSize -
+ iNewFrameSize)) / iNewFrameSize >= .2)
+ {
+ pAnalParams->ppFrames[iFirstFrame - i]->iFrameSize = iNewFrameSize;
+ pAnalParams->ppFrames[iFirstFrame - i]->iStatus = SMS_FRAME_READY;
+
+ /* recompute frame */
+ sms_analyzeFrame(iFirstFrame - i, pAnalParams, fLastFund);
+ pAnalParams->ppFrames[iFirstFrame - i]->iStatus = SMS_FRAME_RECOMPUTED;
+
+ if(fabs(pAnalParams->ppFrames[iFirstFrame - i]->fFundamental - fLastFund) /
+ fLastFund >= .2)
+ return -1;
+ }
+ }
+ }
+ return 1;
}
int sms_findPeaks(int sizeWaveform, sfloat *pWaveform, SMS_AnalParams *pAnalParams, SMS_SpectralPeaks *pSpectralPeaks)
{
- int iCurrentFrame = pAnalParams->iMaxDelayFrames - 1; /* frame # of current frame */
- sfloat fRefFundamental = 0; /* reference fundamental for current frame */
- int i, iError, iExtraSamples; /* samples used for next analysis frame */
+ int iCurrentFrame = pAnalParams->iMaxDelayFrames - 1; /* frame # of current frame */
+ sfloat fRefFundamental = 0; /* reference fundamental for current frame */
+ int i, iError, iExtraSamples; /* samples used for next analysis frame */
SMS_AnalFrame *pTmpAnalFrame;
/* set initial analysis-window size */
- if(pAnalParams->windowSize == 0)
- pAnalParams->windowSize = pAnalParams->iDefaultSizeWindow;
-
- /* fill sound buffer and perform pre-emphasis */
- if (sizeWaveform > 0)
- sms_fillSoundBuffer(sizeWaveform, pWaveform, pAnalParams);
-
- /* move analysis data one frame back */
- pTmpAnalFrame = pAnalParams->ppFrames[0];
- for(i = 1; i < pAnalParams->iMaxDelayFrames; i++)
- pAnalParams->ppFrames[i-1] = pAnalParams->ppFrames[i];
- pAnalParams->ppFrames[pAnalParams->iMaxDelayFrames-1] = pTmpAnalFrame;
-
- /* initialize the current frame */
- sms_initFrame(iCurrentFrame, pAnalParams, pAnalParams->windowSize);
- if(sms_errorCheck())
- {
- printf("Error in init frame: %s \n", sms_errorString());
- return(0);
- }
-
- if(pAnalParams->ppFrames[iCurrentFrame]->iStatus == SMS_FRAME_READY)
- {
- sfloat fAvgDev = sms_fundDeviation(pAnalParams, iCurrentFrame - 1);
-
- /* if single note use the default fundamental as reference */
- if(pAnalParams->iSoundType == SMS_SOUND_TYPE_NOTE)
- fRefFundamental = pAnalParams->fDefaultFundamental;
- /* if sound is stable use the last fundamental as a reference */
- else if(fAvgDev != -1 && fAvgDev <= pAnalParams->maxDeviation)
- fRefFundamental = pAnalParams->ppFrames[iCurrentFrame - 1]->fFundamental;
- else
- fRefFundamental = 0;
-
- /* compute spectrum, find peaks, and find fundamental of frame */
- sms_analyzeFrame(iCurrentFrame, pAnalParams, fRefFundamental);
-
- /* set the size of the next analysis window */
- if(pAnalParams->ppFrames[iCurrentFrame]->fFundamental > 0 &&
- pAnalParams->iSoundType != SMS_SOUND_TYPE_NOTE)
- pAnalParams->windowSize = sms_sizeNextWindow(iCurrentFrame, pAnalParams);
-
- /* figure out how much needs to be read next time */
- // how many processed - sample no. of end of next frame
- // = no. samples that we haven't processed yet from whenever, if sizeNextRead was 0
- iExtraSamples = (pAnalParams->soundBuffer.iMarker + pAnalParams->soundBuffer.sizeBuffer) -
- (pAnalParams->ppFrames[iCurrentFrame]->iFrameSample + pAnalParams->sizeHop);
-
- pAnalParams->sizeNextRead = MAX(0, (pAnalParams->windowSize+1)/2 - iExtraSamples);
- ReAnalyzeFrame(iCurrentFrame, pAnalParams);
-
- /* save peaks */
- pSpectralPeaks->nPeaksFound = pAnalParams->ppFrames[iCurrentFrame]->nPeaks;
- pSpectralPeaks->nPeaks = pAnalParams->maxPeaks;
- pSpectralPeaks->pSpectralPeaks = pAnalParams->ppFrames[iCurrentFrame]->pSpectralPeaks;
+ if(pAnalParams->windowSize == 0)
+ pAnalParams->windowSize = pAnalParams->iDefaultSizeWindow;
+
+ /* fill sound buffer and perform pre-emphasis */
+ if (sizeWaveform > 0)
+ sms_fillSoundBuffer(sizeWaveform, pWaveform, pAnalParams);
+
+ /* move analysis data one frame back */
+ pTmpAnalFrame = pAnalParams->ppFrames[0];
+ for(i = 1; i < pAnalParams->iMaxDelayFrames; i++)
+ pAnalParams->ppFrames[i-1] = pAnalParams->ppFrames[i];
+ pAnalParams->ppFrames[pAnalParams->iMaxDelayFrames-1] = pTmpAnalFrame;
+
+ /* initialize the current frame */
+ sms_initFrame(iCurrentFrame, pAnalParams, pAnalParams->windowSize);
+ if(sms_errorCheck())
+ {
+ printf("Error in init frame: %s \n", sms_errorString());
+ return(0);
+ }
+
+ if(pAnalParams->ppFrames[iCurrentFrame]->iStatus == SMS_FRAME_READY)
+ {
+ sfloat fAvgDev = sms_fundDeviation(pAnalParams, iCurrentFrame - 1);
+
+ /* if single note use the default fundamental as reference */
+ if(pAnalParams->iSoundType == SMS_SOUND_TYPE_NOTE)
+ fRefFundamental = pAnalParams->fDefaultFundamental;
+ /* if sound is stable use the last fundamental as a reference */
+ else if(fAvgDev != -1 && fAvgDev <= pAnalParams->maxDeviation)
+ fRefFundamental = pAnalParams->ppFrames[iCurrentFrame - 1]->fFundamental;
+ else
+ fRefFundamental = 0;
+
+ /* compute spectrum, find peaks, and find fundamental of frame */
+ sms_analyzeFrame(iCurrentFrame, pAnalParams, fRefFundamental);
+
+ /* set the size of the next analysis window */
+ if(pAnalParams->ppFrames[iCurrentFrame]->fFundamental > 0 &&
+ pAnalParams->iSoundType != SMS_SOUND_TYPE_NOTE)
+ pAnalParams->windowSize = sms_sizeNextWindow(iCurrentFrame, pAnalParams);
+
+ /* figure out how much needs to be read next time */
+ // how many processed - sample no. of end of next frame
+ // = no. samples that we haven't processed yet from whenever, if sizeNextRead was 0
+ iExtraSamples = (pAnalParams->soundBuffer.iMarker + pAnalParams->soundBuffer.sizeBuffer) -
+ (pAnalParams->ppFrames[iCurrentFrame]->iFrameSample + pAnalParams->sizeHop);
+
+ pAnalParams->sizeNextRead = MAX(0, (pAnalParams->windowSize+1)/2 - iExtraSamples);
+ ReAnalyzeFrame(iCurrentFrame, pAnalParams);
+
+ /* save peaks */
+ pSpectralPeaks->nPeaksFound = pAnalParams->ppFrames[iCurrentFrame]->nPeaks;
+ pSpectralPeaks->nPeaks = pAnalParams->maxPeaks;
+ pSpectralPeaks->pSpectralPeaks = pAnalParams->ppFrames[iCurrentFrame]->pSpectralPeaks;
/* convert peak amps to linear */
for(i = 0; i < pSpectralPeaks->nPeaksFound; i++)
{
pSpectralPeaks->pSpectralPeaks[i].fMag = pow(10.0, 0.05*(pSpectralPeaks->pSpectralPeaks[i].fMag));
}
- return pSpectralPeaks->nPeaks;
- }
- else
- {
- return 0;
- }
+ return pSpectralPeaks->nPeaks;
+ }
+ else
+ {
+ return 0;
+ }
}
void sms_setPeaks(SMS_AnalParams *pAnalParams, int numamps, sfloat* amps,
- int numfreqs, sfloat* freqs, int numphases, sfloat* phases)
+ int numfreqs, sfloat* freqs, int numphases, sfloat* phases)
{
- int i;
- SMS_AnalFrame *tempFrame;
-
- /* move analysis data one frame back */
- tempFrame = pAnalParams->ppFrames[0];
- for(i = 1; i < pAnalParams->iMaxDelayFrames; i++)
- pAnalParams->ppFrames[i-1] = pAnalParams->ppFrames[i];
- pAnalParams->ppFrames[pAnalParams->iMaxDelayFrames-1] = tempFrame;
-
- /* initialize the current frame */
- SMS_AnalFrame *currentFrame = pAnalParams->ppFrames[2];
- sms_initFrame(2, pAnalParams, 0);
- if(sms_errorCheck())
- {
- printf("Error in init frame: %s \n", sms_errorString());
- return;
- }
-
- for(i = 0; i < numamps; i++)
- {
- /* copy current peaks data */
- currentFrame->pSpectralPeaks[i].fMag = sms_magToDB(amps[i]);
- currentFrame->pSpectralPeaks[i].fFreq = freqs[i];
- currentFrame->pSpectralPeaks[i].fPhase = phases[i];
- }
- currentFrame->nPeaks = numamps;
- currentFrame->iStatus = SMS_FRAME_READY;
-
- /* harmonic detection */
- if (currentFrame->nPeaks > 0 &&
- (pAnalParams->iFormat == SMS_FORMAT_H || pAnalParams->iFormat == SMS_FORMAT_HP))
- {
- /* get a reference fundamental */
- sfloat refFundamental = 0;
- sfloat avgDeviation = sms_fundDeviation(pAnalParams, 1);
- if(pAnalParams->iSoundType == SMS_SOUND_TYPE_NOTE)
- refFundamental = pAnalParams->fDefaultFundamental;
- /* if sound is stable use the last fundamental as a reference */
- else if(avgDeviation != -1 && avgDeviation <= pAnalParams->maxDeviation)
- refFundamental = pAnalParams->ppFrames[1]->fFundamental;
- else
- refFundamental = 0;
-
- currentFrame->fFundamental = sms_harmDetection(pAnalParams->nTracks, currentFrame->pSpectralPeaks,
- refFundamental, pAnalParams->iRefHarmonic,
- pAnalParams->fLowestFundamental, pAnalParams->fHighestFundamental,
- pAnalParams->iSoundType, pAnalParams->fMinRefHarmMag,
- pAnalParams->fRefHarmMagDiffFromMax);
- }
+ int i;
+ SMS_AnalFrame *tempFrame;
+
+ /* move analysis data one frame back */
+ tempFrame = pAnalParams->ppFrames[0];
+ for(i = 1; i < pAnalParams->iMaxDelayFrames; i++)
+ pAnalParams->ppFrames[i-1] = pAnalParams->ppFrames[i];
+ pAnalParams->ppFrames[pAnalParams->iMaxDelayFrames-1] = tempFrame;
+
+ /* initialize the current frame */
+ SMS_AnalFrame *currentFrame = pAnalParams->ppFrames[2];
+ sms_initFrame(2, pAnalParams, 0);
+ if(sms_errorCheck())
+ {
+ printf("Error in init frame: %s \n", sms_errorString());
+ return;
+ }
+
+ for(i = 0; i < numamps; i++)
+ {
+ /* copy current peaks data */
+ currentFrame->pSpectralPeaks[i].fMag = sms_magToDB(amps[i]);
+ currentFrame->pSpectralPeaks[i].fFreq = freqs[i];
+ currentFrame->pSpectralPeaks[i].fPhase = phases[i];
+ }
+ currentFrame->nPeaks = numamps;
+ currentFrame->iStatus = SMS_FRAME_READY;
+
+ /* harmonic detection */
+ if (currentFrame->nPeaks > 0 &&
+ (pAnalParams->iFormat == SMS_FORMAT_H || pAnalParams->iFormat == SMS_FORMAT_HP))
+ {
+ /* get a reference fundamental */
+ sfloat refFundamental = 0;
+ sfloat avgDeviation = sms_fundDeviation(pAnalParams, 1);
+ if(pAnalParams->iSoundType == SMS_SOUND_TYPE_NOTE)
+ refFundamental = pAnalParams->fDefaultFundamental;
+ /* if sound is stable use the last fundamental as a reference */
+ else if(avgDeviation != -1 && avgDeviation <= pAnalParams->maxDeviation)
+ refFundamental = pAnalParams->ppFrames[1]->fFundamental;
+ else
+ refFundamental = 0;
+
+ currentFrame->fFundamental = sms_harmDetection(pAnalParams->nTracks, currentFrame->pSpectralPeaks,
+ refFundamental, pAnalParams->iRefHarmonic,
+ pAnalParams->fLowestFundamental, pAnalParams->fHighestFundamental,
+ pAnalParams->iSoundType, pAnalParams->fMinRefHarmMag,
+ pAnalParams->fRefHarmMagDiffFromMax);
+ }
}
int sms_findPartials(SMS_Data *pSmsData, SMS_AnalParams *pAnalParams)
{
- /* clear SMS output */
- sms_clearFrame(pSmsData);
-
- /* incorporate the peaks into the corresponding tracks */
- /* todo: allow for longer analysis delays */
- if(pAnalParams->ppFrames[1]->fFundamental > 0 ||
- ((pAnalParams->iFormat == SMS_FORMAT_IH || pAnalParams->iFormat == SMS_FORMAT_IHP) &&
- pAnalParams->ppFrames[1]->nPeaks > 0))
- {
- sms_peakContinuation(1, pAnalParams);
- }
-
- /* fill gaps and delete short tracks */
- /* todo: allow for longer analysis delays */
- if(pAnalParams->iCleanTracks > 0)
- {
- sms_cleanTracks(1, pAnalParams);
- }
-
- /* output data */
- sms_allocFrame(pSmsData, pAnalParams->nTracks, pAnalParams->nStochasticCoeff,
- 1, pAnalParams->iStochasticType, pAnalParams->specEnvParams.nCoeff);
-
- int length = sizeof(sfloat) * pSmsData->nTracks;
- memcpy((char *) pSmsData->pFSinFreq, (char *)
- pAnalParams->ppFrames[0]->deterministic.pFSinFreq, length);
- memcpy((char *) pSmsData->pFSinAmp, (char *)
- pAnalParams->ppFrames[0]->deterministic.pFSinAmp, length);
-
- /* convert mags back to linear */
- sms_arrayDBToMag(pSmsData->nTracks, pSmsData->pFSinAmp);
-
- if(pAnalParams->iFormat == SMS_FORMAT_HP ||
- pAnalParams->iFormat == SMS_FORMAT_IHP)
- memcpy((char *) pSmsData->pFSinPha, (char *)
- pAnalParams->ppFrames[0]->deterministic.pFSinPha, length);
-
- /* do post-processing (for now, spectral envelope calculation and storage) */
- if(pAnalParams->specEnvParams.iType != SMS_ENV_NONE)
- {
- sms_spectralEnvelope(pSmsData, &pAnalParams->specEnvParams);
- }
-
- return 1;
+ /* clear SMS output */
+ sms_clearFrame(pSmsData);
+
+ /* incorporate the peaks into the corresponding tracks */
+ /* todo: allow for longer analysis delays */
+ if(pAnalParams->ppFrames[1]->fFundamental > 0 ||
+ ((pAnalParams->iFormat == SMS_FORMAT_IH || pAnalParams->iFormat == SMS_FORMAT_IHP) &&
+ pAnalParams->ppFrames[1]->nPeaks > 0))
+ {
+ sms_peakContinuation(1, pAnalParams);
+ }
+
+ /* fill gaps and delete short tracks */
+ /* todo: allow for longer analysis delays */
+ if(pAnalParams->iCleanTracks > 0)
+ {
+ sms_cleanTracks(1, pAnalParams);
+ }
+
+ /* output data */
+ sms_allocFrame(pSmsData, pAnalParams->nTracks, pAnalParams->nStochasticCoeff,
+ 1, pAnalParams->iStochasticType, pAnalParams->specEnvParams.nCoeff);
+
+ int length = sizeof(sfloat) * pSmsData->nTracks;
+ memcpy((char *) pSmsData->pFSinFreq, (char *)
+ pAnalParams->ppFrames[0]->deterministic.pFSinFreq, length);
+ memcpy((char *) pSmsData->pFSinAmp, (char *)
+ pAnalParams->ppFrames[0]->deterministic.pFSinAmp, length);
+
+ /* convert mags back to linear */
+ sms_arrayDBToMag(pSmsData->nTracks, pSmsData->pFSinAmp);
+
+ if(pAnalParams->iFormat == SMS_FORMAT_HP ||
+ pAnalParams->iFormat == SMS_FORMAT_IHP)
+ memcpy((char *) pSmsData->pFSinPha, (char *)
+ pAnalParams->ppFrames[0]->deterministic.pFSinPha, length);
+
+ /* do post-processing (for now, spectral envelope calculation and storage) */
+ if(pAnalParams->specEnvParams.iType != SMS_ENV_NONE)
+ {
+ sms_spectralEnvelope(pSmsData, &pAnalParams->specEnvParams);
+ }
+
+ return 1;
}
int sms_findResidual(int sizeSynthesis, sfloat* pSynthesis,
- int sizeOriginal, sfloat* pOriginal,
- int sizeResidual, sfloat* pResidual,
- SMS_AnalParams *analParams)
+ int sizeOriginal, sfloat* pOriginal,
+ int sizeResidual, sfloat* pResidual,
+ SMS_AnalParams *analParams)
{
- if(sizeSynthesis != sizeOriginal || sizeOriginal != sizeResidual)
- {
- return -1;
- }
-
- /* perform preemphasis */
- int i;
- for(i = 0; i < sizeSynthesis; i++)
- {
- pOriginal[i] = sms_preEmphasis(pOriginal[i], analParams);
- }
-
- sms_residual(sizeResidual, pSynthesis, pOriginal, pResidual);
- return 0;
+ if(sizeSynthesis != sizeOriginal || sizeOriginal != sizeResidual)
+ {
+ return -1;
+ }
+
+ /* perform preemphasis */
+ int i;
+ for(i = 0; i < sizeSynthesis; i++)
+ {
+ pOriginal[i] = sms_preEmphasis(pOriginal[i], analParams);
+ }
+
+ /*sms_residual(sizeResidual, pSynthesis, pOriginal, pResidual);*/
+ return 0;
}
void sms_approxResidual(int sizeResidual, sfloat* pResidual,
- SMS_Data* pSmsData, SMS_SynthParams* pSynthParams)
+ SMS_Data* pSmsData, SMS_SynthParams* pSynthParams)
{
- /* perform stochastic analysis after 1 frame of the */
- /* deterministic synthesis because it needs two frames */
-// if (pAnalParams->ppFrames[0]->iStatus != SMS_FRAME_EMPTY &&
-// pAnalParams->ppFrames[0]->iStatus != SMS_FRAME_END)
-// {
-// int sizeResidual = pAnalParams->sizeHop * 2;
-// int iSoundLoc = pAnalParams->ppFrames[0]->iFrameSample - pAnalParams->sizeHop;
-// // sfloat *pOriginal = &(pAnalParams->soundBuffer.pFBuffer[iSoundLoc - pAnalParams->soundBuffer.iMarker]);
-// sfloat *pOriginal;
-// sfloat *pFResidual;
+ /* perform stochastic analysis after 1 frame of the */
+ /* deterministic synthesis because it needs two frames */
+// if (pAnalParams->ppFrames[0]->iStatus != SMS_FRAME_EMPTY &&
+// pAnalParams->ppFrames[0]->iStatus != SMS_FRAME_END)
+// {
+// int sizeResidual = pAnalParams->sizeHop * 2;
+// int iSoundLoc = pAnalParams->ppFrames[0]->iFrameSample - pAnalParams->sizeHop;
+// // sfloat *pOriginal = &(pAnalParams->soundBuffer.pFBuffer[iSoundLoc - pAnalParams->soundBuffer.iMarker]);
+// sfloat *pOriginal;
+// sfloat *pFResidual;
//
-// static sfloat *pWindow;
-// static int sizeWindowArray = 0;
+// static sfloat *pWindow;
+// static int sizeWindowArray = 0;
//
-// // int sizeData = MIN(pAnalParams->soundBuffer.sizeBuffer -
-// // (iSoundLoc - pAnalParams->soundBuffer.iMarker),
-// // sizeResidual);
-// int sizeData = sizeResidual;
-// if ((pFResidual = (sfloat *) calloc (sizeResidual, sizeof(sfloat))) == NULL)
-// {
-// sms_error("sms_analyze: error allocating memory for pFResidual");
-// return -1;
-// }
-// if (sizeWindowArray != sizeData)
-// {
-// if(sizeWindowArray != 0) free(pWindow);
-// if((pWindow = (sfloat *) calloc(sizeData, sizeof(sfloat))) == NULL)
-// {
-// sms_error("sms_analyze: error allocating memory for pWindow");
-// return -1;
-// }
-// sms_getWindow( sizeData, pWindow, SMS_WIN_HAMMING);
-// sms_scaleWindow( sizeData, pWindow);
-// sizeWindowArray = sizeData;
-// }
+// // int sizeData = MIN(pAnalParams->soundBuffer.sizeBuffer -
+// // (iSoundLoc - pAnalParams->soundBuffer.iMarker),
+// // sizeResidual);
+// int sizeData = sizeResidual;
+// if ((pFResidual = (sfloat *) calloc (sizeResidual, sizeof(sfloat))) == NULL)
+// {
+// sms_error("sms_analyze: error allocating memory for pFResidual");
+// return -1;
+// }
+// if (sizeWindowArray != sizeData)
+// {
+// if(sizeWindowArray != 0) free(pWindow);
+// if((pWindow = (sfloat *) calloc(sizeData, sizeof(sfloat))) == NULL)
+// {
+// sms_error("sms_analyze: error allocating memory for pWindow");
+// return -1;
+// }
+// sms_getWindow( sizeData, pWindow, SMS_WIN_HAMMING);
+// sms_scaleWindow( sizeData, pWindow);
+// sizeWindowArray = sizeData;
+// }
//
-// /* obtain residual sound from original and synthesized sounds. accumulate the residual percentage.*/
-// pAnalParams->fResidualAccumPerc += sms_residual(sizeData,
-// pAnalParams->synthBuffer.pFBuffer,
-// pOriginal,
-// pFResidual,
-// pWindow);
+// /* obtain residual sound from original and synthesized sounds. accumulate the residual percentage.*/
+// pAnalParams->fResidualAccumPerc += sms_residual(sizeData,
+// pAnalParams->synthBuffer.pFBuffer,
+// pOriginal,
+// pFResidual,
+// pWindow);
//
-// if (pAnalParams->iStochasticType == SMS_STOC_APPROX)
-// {
-// /* filter residual with a high pass filter (it solves some problems) */
-// sms_filterHighPass (sizeData, pFResidual, pAnalParams->iSamplingRate);
+// if (pAnalParams->iStochasticType == SMS_STOC_APPROX)
+// {
+// /* filter residual with a high pass filter (it solves some problems) */
+// sms_filterHighPass (sizeData, pFResidual, pAnalParams->iSamplingRate);
//
-// /* approximate residual */
-// sms_stocAnalysis (sizeData, pFResidual, pWindow, pSmsData);
-// }
-// else if (pAnalParams->iStochasticType == SMS_STOC_IFFT)
-// {
-// int sizeMag = sms_power2(sizeData >> 1);
-// sms_spectrum (sizeData, pFResidual, pWindow, sizeMag, pSmsData->pFStocCoeff,
-// pSmsData->pResPhase);
-// }
+// /* approximate residual */
+// sms_stocAnalysis (sizeData, pFResidual, pWindow, pSmsData);
+// }
+// else if (pAnalParams->iStochasticType == SMS_STOC_IFFT)
+// {
+// int sizeMag = sms_power2(sizeData >> 1);
+// sms_spectrum (sizeData, pFResidual, pWindow, sizeMag, pSmsData->pFStocCoeff,
+// pSmsData->pResPhase);
+// }
//
-// /* get sharper transitions in deterministic representation */
-// // sms_scaleDet (pAnalParams->synthBuffer.pFBuffer, pOriginal,
-// // pAnalParams->ppFrames[0]->deterministic.pFSinAmp,
-// // pAnalParams, pSmsData->nTracks);
+// /* get sharper transitions in deterministic representation */
+// // sms_scaleDet (pAnalParams->synthBuffer.pFBuffer, pOriginal,
+// // pAnalParams->ppFrames[0]->deterministic.pFSinAmp,
+// // pAnalParams, pSmsData->nTracks);
//
-// pAnalParams->ppFrames[0]->iStatus = SMS_FRAME_DONE;
+// pAnalParams->ppFrames[0]->iStatus = SMS_FRAME_DONE;
//
-// free ((char *) pFResidual); /* \todo get rid of this free, manage memory the same as spectrum functions */
-// }
+// free ((char *) pFResidual); /* \todo get rid of this free, manage memory the same as spectrum functions */
+// }
}
-int sms_analyze (int sizeWaveform, sfloat *pWaveform, SMS_Data *pSmsData, SMS_AnalParams *pAnalParams)
+int sms_analyze(int sizeWaveform, sfloat *pWaveform, SMS_Data *pSmsData, SMS_AnalParams *pAnalParams)
{
- static int sizeWindow = 0; /* size of current analysis window */ //RTE ?: shouldn't this just be initilalized outside?
-
- int iCurrentFrame = pAnalParams->iMaxDelayFrames - 1; /* frame # of current frame */
- int delayFrames = pAnalParams->minGoodFrames + pAnalParams->analDelay;
- int i, iError, iExtraSamples; /* samples used for next analysis frame */
- sfloat fRefFundamental = 0; /* reference fundamental for current frame */
+ int iCurrentFrame = pAnalParams->iMaxDelayFrames - 1; /* frame # of current frame */
+ int delayFrames;
+ int i, iError, iExtraSamples; /* samples used for next analysis frame */
+ sfloat fRefFundamental = 0; /* reference fundamental for current frame */
SMS_AnalFrame *pTmpAnalFrame;
- /* clear SMS output */
- sms_clearFrame (pSmsData);
-
- /* set initial analysis-window size */
- if (sizeWindow == 0)
- sizeWindow = pAnalParams->iDefaultSizeWindow;
-
- /* fill the input sound buffer and perform pre-emphasis */
- if (sizeWaveform > 0)
- sms_fillSoundBuffer (sizeWaveform, pWaveform, pAnalParams);
-
- /* move analysis data one frame back */
- pTmpAnalFrame = pAnalParams->ppFrames[0];
- for(i = 1; i < pAnalParams->iMaxDelayFrames; i++)
- pAnalParams->ppFrames[i-1] = pAnalParams->ppFrames[i];
- pAnalParams->ppFrames[pAnalParams->iMaxDelayFrames-1] = pTmpAnalFrame;
-
- /* initialize the current frame */
- sms_initFrame (iCurrentFrame, pAnalParams, sizeWindow);
- if(sms_errorCheck())
- {
- printf("error in init frame: %s \n", sms_errorString());
- return(-1);
- }
-
- /* if right data in the sound buffer do analysis */
- if (pAnalParams->ppFrames[iCurrentFrame]->iStatus == SMS_FRAME_READY)
- {
- sfloat fAvgDev = sms_fundDeviation( pAnalParams, iCurrentFrame - 1);
-
- /* if single note use the default fundamental as reference */
- if (pAnalParams->iSoundType == SMS_SOUND_TYPE_NOTE)
- fRefFundamental = pAnalParams->fDefaultFundamental;
- /* if sound is stable use the last fundamental as a reference */
- else if (fAvgDev != -1 && fAvgDev <= pAnalParams->maxDeviation)
- fRefFundamental = pAnalParams->ppFrames[iCurrentFrame - 1]->fFundamental;
- else
- fRefFundamental = 0;
-
- /* compute spectrum, find peaks, and find fundamental of frame */
- sms_analyzeFrame (iCurrentFrame, pAnalParams, fRefFundamental);
-
- /* set the size of the next analysis window */
- if (pAnalParams->ppFrames[iCurrentFrame]->fFundamental > 0 &&
- pAnalParams->iSoundType != SMS_SOUND_TYPE_NOTE)
- sizeWindow = sms_sizeNextWindow (iCurrentFrame, pAnalParams);
-
- /* figure out how much needs to be read next time */
- iExtraSamples =
- (pAnalParams->soundBuffer.iMarker + pAnalParams->soundBuffer.sizeBuffer) -
- (pAnalParams->ppFrames[iCurrentFrame]->iFrameSample + pAnalParams->sizeHop);
-
- pAnalParams->sizeNextRead = MAX (0, (sizeWindow+1)/2 - iExtraSamples);
-
- /* check again the previous frames and recompute if necessary */
- ReAnalyzeFrame (iCurrentFrame, pAnalParams);
- }
-
- /* incorporate the peaks into the corresponding tracks */
- /* This is done after a pAnalParams->iMaxDelayFrames delay */
- if (pAnalParams->ppFrames[iCurrentFrame - delayFrames]->fFundamental > 0 ||
- ((pAnalParams->iFormat == SMS_FORMAT_IH ||
- pAnalParams->iFormat == SMS_FORMAT_IHP) &&
- pAnalParams->ppFrames[iCurrentFrame - delayFrames]->nPeaks > 0))
- sms_peakContinuation (iCurrentFrame - delayFrames, pAnalParams);
-
- /* fill gaps and delete short tracks */
- if (pAnalParams->iCleanTracks > 0 &&
- pAnalParams->ppFrames[iCurrentFrame - delayFrames]->iStatus != SMS_FRAME_EMPTY)
- sms_cleanTracks (iCurrentFrame - delayFrames, pAnalParams);
-
- /* do stochastic analysis */
- if (pAnalParams->iStochasticType != SMS_STOC_NONE)
- {
- /* synthesize deterministic signal */
- if (pAnalParams->ppFrames[1]->iStatus != SMS_FRAME_EMPTY &&
- pAnalParams->ppFrames[1]->iStatus != SMS_FRAME_END)
- {
- /* shift synthesis buffer */
- memcpy(pAnalParams->synthBuffer.pFBuffer,
+ /* set the frame delay, checking that it does not exceed the given maximum
+ *
+ * TODO: check for good values of pAnalParams->minGoodFrames and
+ * pAnalParams->analDelay here too? Or figure out why sms_crashes if
+ * pAnalParamx->iMaxDelayFrames is changed without changing the other
+ * two variables.
+ */
+ delayFrames = pAnalParams->minGoodFrames + pAnalParams->analDelay;
+ if(delayFrames > (pAnalParams->iMaxDelayFrames - 1))
+ delayFrames = pAnalParams->iMaxDelayFrames - 1;
+
+ /* clear SMS output */
+ sms_clearFrame(pSmsData);
+
+ /* set initial analysis-window size */
+ if(pAnalParams->windowSize == 0)
+ pAnalParams->windowSize = pAnalParams->iDefaultSizeWindow;
+
+ /* fill the input sound buffer and perform pre-emphasis */
+ if(sizeWaveform > 0)
+ sms_fillSoundBuffer(sizeWaveform, pWaveform, pAnalParams);
+
+ /* move analysis data one frame back */
+ pTmpAnalFrame = pAnalParams->ppFrames[0];
+ for(i = 1; i < pAnalParams->iMaxDelayFrames; i++)
+ pAnalParams->ppFrames[i-1] = pAnalParams->ppFrames[i];
+ pAnalParams->ppFrames[pAnalParams->iMaxDelayFrames-1] = pTmpAnalFrame;
+
+ /* initialize the current frame */
+ sms_initFrame(iCurrentFrame, pAnalParams, pAnalParams->windowSize);
+ if(sms_errorCheck())
+ {
+ printf("error in init frame: %s \n", sms_errorString());
+ return -1;
+ }
+
+ /* if right data in the sound buffer do analysis */
+ if(pAnalParams->ppFrames[iCurrentFrame]->iStatus == SMS_FRAME_READY)
+ {
+ sfloat fAvgDev = sms_fundDeviation(pAnalParams, iCurrentFrame - 1);
+
+ /* if single note use the default fundamental as reference */
+ if(pAnalParams->iSoundType == SMS_SOUND_TYPE_NOTE)
+ fRefFundamental = pAnalParams->fDefaultFundamental;
+ /* if sound is stable use the last fundamental as a reference */
+ else if(fAvgDev != -1 && fAvgDev <= pAnalParams->maxDeviation)
+ fRefFundamental = pAnalParams->ppFrames[iCurrentFrame - 1]->fFundamental;
+ else
+ fRefFundamental = 0;
+
+ /* compute spectrum, find peaks, and find fundamental of frame */
+ sms_analyzeFrame(iCurrentFrame, pAnalParams, fRefFundamental);
+
+ /* set the size of the next analysis window */
+ if(pAnalParams->ppFrames[iCurrentFrame]->fFundamental > 0 &&
+ pAnalParams->iSoundType != SMS_SOUND_TYPE_NOTE)
+ pAnalParams->windowSize = sms_sizeNextWindow (iCurrentFrame, pAnalParams);
+
+ /* figure out how much needs to be read next time */
+ iExtraSamples =
+ (pAnalParams->soundBuffer.iMarker + pAnalParams->soundBuffer.sizeBuffer) -
+ (pAnalParams->ppFrames[iCurrentFrame]->iFrameSample + pAnalParams->sizeHop);
+
+ pAnalParams->sizeNextRead = MAX(0, (pAnalParams->windowSize+1)/2 - iExtraSamples);
+
+ /* check again the previous frames and recompute if necessary */
+ ReAnalyzeFrame(iCurrentFrame, pAnalParams);
+ }
+
+ /* incorporate the peaks into the corresponding tracks */
+ /* This is done after a pAnalParams->iMaxDelayFrames delay */
+ if(pAnalParams->ppFrames[iCurrentFrame - delayFrames]->fFundamental > 0 ||
+ ((pAnalParams->iFormat == SMS_FORMAT_IH || pAnalParams->iFormat == SMS_FORMAT_IHP) &&
+ pAnalParams->ppFrames[iCurrentFrame - delayFrames]->nPeaks > 0))
+ sms_peakContinuation(iCurrentFrame - delayFrames, pAnalParams);
+
+ /* fill gaps and delete short tracks */
+ if(pAnalParams->iCleanTracks > 0 &&
+ pAnalParams->ppFrames[iCurrentFrame - delayFrames]->iStatus != SMS_FRAME_EMPTY)
+ sms_cleanTracks(iCurrentFrame - delayFrames, pAnalParams);
+
+ /* do stochastic analysis */
+ if(pAnalParams->iStochasticType != SMS_STOC_NONE)
+ {
+ /* synthesize deterministic signal */
+ if(pAnalParams->ppFrames[1]->iStatus != SMS_FRAME_EMPTY &&
+ pAnalParams->ppFrames[1]->iStatus != SMS_FRAME_END)
+ {
+ /* shift synthesis buffer */
+ memcpy(pAnalParams->synthBuffer.pFBuffer,
pAnalParams->synthBuffer.pFBuffer+pAnalParams->sizeHop,
- sizeof(sfloat) * pAnalParams->sizeHop);
- memset(pAnalParams->synthBuffer.pFBuffer+pAnalParams->sizeHop,
+ sizeof(sfloat) * pAnalParams->sizeHop);
+ memset(pAnalParams->synthBuffer.pFBuffer+pAnalParams->sizeHop,
0, sizeof(sfloat) * pAnalParams->sizeHop);
- /* get deterministic signal with phase */
- sms_sineSynthFrame(&pAnalParams->ppFrames[1]->deterministic,
- pAnalParams->synthBuffer.pFBuffer+pAnalParams->sizeHop,
- pAnalParams->sizeHop, &pAnalParams->prevFrame,
- pAnalParams->iSamplingRate);
- }
-
- /* perform stochastic analysis after 1 frame of the */
- /* deterministic synthesis because it needs two frames */
- if (pAnalParams->ppFrames[0]->iStatus != SMS_FRAME_EMPTY &&
- pAnalParams->ppFrames[0]->iStatus != SMS_FRAME_END)
-
- {
- int sizeResidual = pAnalParams->sizeHop * 2;
- int iSoundLoc = pAnalParams->ppFrames[0]->iFrameSample - pAnalParams->sizeHop;
- sfloat *pOriginal = &(pAnalParams->soundBuffer.pFBuffer[iSoundLoc -
- pAnalParams->soundBuffer.iMarker]);
- sfloat *pFResidual;
-
- static sfloat *pWindow;
- static int sizeWindowArray = 0;
-
- int sizeData = MIN(pAnalParams->soundBuffer.sizeBuffer -
- (iSoundLoc - pAnalParams->soundBuffer.iMarker),
- sizeResidual);
- if ((pFResidual = (sfloat *) calloc (sizeResidual, sizeof(sfloat))) == NULL)
- {
- sms_error("sms_analyze: error allocating memory for pFResidual");
- return -1;
- }
- if (sizeWindowArray != sizeData)
- {
- if(sizeWindowArray != 0) free(pWindow);
- if((pWindow = (sfloat *) calloc(sizeData, sizeof(sfloat))) == NULL)
- {
- sms_error("sms_analyze: error allocating memory for pWindow");
- return -1;
- }
- sms_getWindow( sizeData, pWindow, SMS_WIN_HAMMING);
- sms_scaleWindow( sizeData, pWindow);
- sizeWindowArray = sizeData;
- }
-
- /* obtain residual sound from original and synthesized sounds. accumulate the residual percentage.*/
- pAnalParams->fResidualAccumPerc += sms_residual(sizeData,
- pAnalParams->synthBuffer.pFBuffer,
- pOriginal,
- pFResidual);
-
- if(pAnalParams->iStochasticType == SMS_STOC_APPROX)
- {
- /* filter residual with a high pass filter (it solves some problems) */
- sms_filterHighPass (sizeData, pFResidual, pAnalParams->iSamplingRate);
-
- /* approximate residual */
- sms_stocAnalysis (sizeData, pFResidual, pWindow, pSmsData);
- }
- else if(pAnalParams->iStochasticType == SMS_STOC_IFFT)
- {
- int sizeMag = sms_power2(sizeData >> 1);
- sms_spectrum (sizeData, pFResidual, pWindow, sizeMag, pSmsData->pFStocCoeff,
- pSmsData->pResPhase);
- }
-
- /* get sharper transitions in deterministic representation */
- sms_scaleDet(pAnalParams->synthBuffer.pFBuffer, pOriginal,
- pAnalParams->ppFrames[0]->deterministic.pFSinAmp,
- pAnalParams, pSmsData->nTracks);
-
- pAnalParams->ppFrames[0]->iStatus = SMS_FRAME_DONE;
-
- free ((char *) pFResidual); /* \todo get rid of this free, manage memory the same as spectrum functions */
- }
- }
- else if (pAnalParams->ppFrames[0]->iStatus != SMS_FRAME_EMPTY &&
- pAnalParams->ppFrames[0]->iStatus != SMS_FRAME_END)
- pAnalParams->ppFrames[0]->iStatus = SMS_FRAME_DONE;
-
- /* get the result */
- if (pAnalParams->ppFrames[0]->iStatus == SMS_FRAME_EMPTY)
- {
- /* no partials yet, so output the current peaks for testing */
- int numPeaks = pAnalParams->ppFrames[iCurrentFrame]->nPeaks;
- int numTracks = pSmsData->nTracks;
- numTracks = MIN(numPeaks, numTracks);
- for(i = 0; i < numTracks; i++)
- {
- pSmsData->pFSinFreq[i] = pAnalParams->ppFrames[iCurrentFrame]->pSpectralPeaks[i].fFreq;
- pSmsData->pFSinAmp[i] = pAnalParams->ppFrames[iCurrentFrame]->pSpectralPeaks[i].fMag;
- if(pAnalParams->iFormat == SMS_FORMAT_HP ||
- pAnalParams->iFormat == SMS_FORMAT_IHP)
- {
- pSmsData->pFSinPha[i] = pAnalParams->ppFrames[iCurrentFrame]->pSpectralPeaks[i].fPhase;
- }
- }
- pSmsData->nTracks = numTracks;
- return 0;
- }
- /* return analysis data */
- else if (pAnalParams->ppFrames[0]->iStatus == SMS_FRAME_DONE)
- {
- /* put data into output */
- int length = sizeof(sfloat) * pSmsData->nTracks;
- memcpy ((char *) pSmsData->pFSinFreq, (char *)
- pAnalParams->ppFrames[0]->deterministic.pFSinFreq, length);
- memcpy ((char *) pSmsData->pFSinAmp, (char *)
- pAnalParams->ppFrames[0]->deterministic.pFSinAmp, length);
-
- /* convert mags back to linear */
- sms_arrayDBToMag(pSmsData->nTracks, pSmsData->pFSinAmp);
- if (pAnalParams->iFormat == SMS_FORMAT_HP ||
- pAnalParams->iFormat == SMS_FORMAT_IHP)
- memcpy ((char *) pSmsData->pFSinPha, (char *)
- pAnalParams->ppFrames[0]->deterministic.pFSinPha, length);
-
- /* do post-processing (for now, spectral envelope calculation and storage) */
- if(pAnalParams->specEnvParams.iType != SMS_ENV_NONE)
- {
- sms_spectralEnvelope( pSmsData, &pAnalParams->specEnvParams);
- }
- return (1);
- }
- /* done, end of sound */
- else if (pAnalParams->ppFrames[0]->iStatus == SMS_FRAME_END)
- return (-1);
- else
- {
- sms_error ("sms_analyze error: wrong status of frame.");
- return(-1);
- }
- return (1);
+ /* get deterministic signal with phase */
+ sms_sineSynthFrame(&pAnalParams->ppFrames[1]->deterministic,
+ pAnalParams->synthBuffer.pFBuffer+pAnalParams->sizeHop,
+ pAnalParams->sizeHop, &pAnalParams->prevFrame,
+ pAnalParams->iSamplingRate);
+ }
+
+ /* perform stochastic analysis after 1 frame of the */
+ /* deterministic synthesis because it needs two frames */
+ if(pAnalParams->ppFrames[0]->iStatus != SMS_FRAME_EMPTY &&
+ pAnalParams->ppFrames[0]->iStatus != SMS_FRAME_END)
+ {
+ int sizeResidual = pAnalParams->sizeHop * 2;
+ int iSoundLoc = pAnalParams->ppFrames[0]->iFrameSample - pAnalParams->sizeHop;
+ sfloat *pOriginal = &(pAnalParams->soundBuffer.pFBuffer[iSoundLoc -
+ pAnalParams->soundBuffer.iMarker]);
+
+ int sizeData = MIN(pAnalParams->soundBuffer.sizeBuffer -
+ (iSoundLoc - pAnalParams->soundBuffer.iMarker),
+ pAnalParams->sizeResidual);
+
+ if(sizeData > pAnalParams->sizeResidual)
+ {
+ sms_error("Residual size larger than expected.");
+ return -1;
+ }
+ else if(sizeData < pAnalParams->sizeResidual)
+ {
+ /* should only happen if we're at the end of a sound, unless hop size changes */
+ sms_getWindow(sizeData, pAnalParams->residualWindow, SMS_WIN_HAMMING);
+ sms_scaleWindow(sizeData, pAnalParams->residualWindow);
+ }
+
+ /* obtain residual sound from original and synthesized sounds. accumulate the residual percentage.*/
+ pAnalParams->fResidualAccumPerc += sms_residual(sizeData,
+ pAnalParams->synthBuffer.pFBuffer,
+ pOriginal,
+ pAnalParams->residual,
+ pAnalParams->residualWindow);
+
+ if(pAnalParams->iStochasticType == SMS_STOC_APPROX)
+ {
+ /* filter residual with a high pass filter (it solves some problems) */
+ sms_filterHighPass(sizeData, pAnalParams->residual, pAnalParams->iSamplingRate);
+
+ /* approximate residual */
+ sms_stocAnalysis(sizeData, pAnalParams->residual, pAnalParams->residualWindow,
+ pSmsData, pAnalParams);
+ }
+ else if(pAnalParams->iStochasticType == SMS_STOC_IFFT)
+ {
+ int sizeMag = sms_power2(sizeData >> 1);
+ sms_spectrum(sizeData, pAnalParams->residual, pAnalParams->residualWindow,
+ sizeMag, pSmsData->pFStocCoeff, pSmsData->pResPhase,
+ pAnalParams->fftBuffer);
+ }
+
+ /* get sharper transitions in deterministic representation */
+ sms_scaleDet(pAnalParams->synthBuffer.pFBuffer, pOriginal,
+ pAnalParams->ppFrames[0]->deterministic.pFSinAmp,
+ pAnalParams, pSmsData->nTracks);
+
+ pAnalParams->ppFrames[0]->iStatus = SMS_FRAME_DONE;
+ }
+ }
+ else if(pAnalParams->ppFrames[0]->iStatus != SMS_FRAME_EMPTY &&
+ pAnalParams->ppFrames[0]->iStatus != SMS_FRAME_END)
+ pAnalParams->ppFrames[0]->iStatus = SMS_FRAME_DONE;
+
+ /* get the result */
+ if(pAnalParams->ppFrames[0]->iStatus == SMS_FRAME_EMPTY)
+ {
+ /* no partials yet, so output the current peaks for testing */
+ int numPeaks = pAnalParams->ppFrames[iCurrentFrame]->nPeaks;
+ int numTracks = pSmsData->nTracks;
+ numTracks = MIN(numPeaks, numTracks);
+ for(i = 0; i < numTracks; i++)
+ {
+ pSmsData->pFSinFreq[i] = pAnalParams->ppFrames[iCurrentFrame]->pSpectralPeaks[i].fFreq;
+ pSmsData->pFSinAmp[i] = pAnalParams->ppFrames[iCurrentFrame]->pSpectralPeaks[i].fMag;
+ if(pAnalParams->iFormat == SMS_FORMAT_HP ||
+ pAnalParams->iFormat == SMS_FORMAT_IHP)
+ {
+ pSmsData->pFSinPha[i] = pAnalParams->ppFrames[iCurrentFrame]->pSpectralPeaks[i].fPhase;
+ }
+ }
+ pSmsData->nTracks = numTracks;
+ return 0;
+ }
+ /* return analysis data */
+ else if(pAnalParams->ppFrames[0]->iStatus == SMS_FRAME_DONE)
+ {
+ /* put data into output */
+ int length = sizeof(sfloat) * pSmsData->nTracks;
+ memcpy((char *) pSmsData->pFSinFreq, (char *)
+ pAnalParams->ppFrames[0]->deterministic.pFSinFreq, length);
+ memcpy((char *) pSmsData->pFSinAmp, (char *)
+ pAnalParams->ppFrames[0]->deterministic.pFSinAmp, length);
+
+ /* convert mags back to linear */
+ sms_arrayDBToMag(pSmsData->nTracks, pSmsData->pFSinAmp);
+ if(pAnalParams->iFormat == SMS_FORMAT_HP ||
+ pAnalParams->iFormat == SMS_FORMAT_IHP)
+ memcpy((char *) pSmsData->pFSinPha, (char *)
+ pAnalParams->ppFrames[0]->deterministic.pFSinPha, length);
+
+ /* do post-processing (for now, spectral envelope calculation and storage) */
+ if(pAnalParams->specEnvParams.iType != SMS_ENV_NONE)
+ {
+ sms_spectralEnvelope(pSmsData, &pAnalParams->specEnvParams);
+ }
+ return 1;
+ }
+ /* done, end of sound */
+ else if(pAnalParams->ppFrames[0]->iStatus == SMS_FRAME_END)
+ return -1;
+ else
+ {
+ sms_error("sms_analyze error: wrong status of frame.");
+ return -1;
+ }
+ return 1;
}
diff --git a/sms/fileIO.c b/sms/fileIO.c
index 8fbfa5b..e870c5a 100644
--- a/sms/fileIO.c
+++ b/sms/fileIO.c
@@ -37,7 +37,7 @@ static char pChTextString[1000]; /*!< string to store analysis parameters in sms
*
* \param pSmsHeader header for SMS file
*/
-void sms_initHeader (SMS_Header *pSmsHeader)
+void sms_initHeader(SMS_Header *pSmsHeader)
{
pSmsHeader->iSmsMagic = SMS_MAGIC;
pSmsHeader->iHeadBSize = sizeof(SMS_Header);
@@ -51,8 +51,6 @@ void sms_initHeader (SMS_Header *pSmsHeader)
pSmsHeader->nEnvCoeff = 0;
pSmsHeader->iMaxFreq = 0;
pSmsHeader->fResidualPerc = 0;
- pSmsHeader->nTextCharacters = 0;
- pSmsHeader->pChTextCharacters = NULL;
}
/*! \brief fill an SMS header with necessary information for storage
@@ -67,10 +65,9 @@ void sms_initHeader (SMS_Header *pSmsHeader)
* \param pAnalParams structure of analysis parameters
* \param pProgramString pointer to a string containing the name of the program that made the analysis data
*/
-void sms_fillHeader (SMS_Header *pSmsHeader, SMS_AnalParams *pAnalParams,
- char *pProgramString)
+void sms_fillHeader(SMS_Header *pSmsHeader, SMS_AnalParams *pAnalParams, char *pProgramString)
{
- sms_initHeader (pSmsHeader);
+ sms_initHeader(pSmsHeader);
pSmsHeader->nFrames = pAnalParams->nFrames;
pSmsHeader->iFormat = pAnalParams->iFormat;
pSmsHeader->iFrameRate = pAnalParams->iFrameRate;
@@ -83,35 +80,8 @@ void sms_fillHeader (SMS_Header *pSmsHeader, SMS_AnalParams *pAnalParams,
pSmsHeader->nStochasticCoeff = pAnalParams->nStochasticCoeff;
pSmsHeader->iEnvType = pAnalParams->specEnvParams.iType;
pSmsHeader->nEnvCoeff = pAnalParams->specEnvParams.nCoeff;
- pSmsHeader->iMaxFreq = (int) pAnalParams->fHighestFreq;
+ pSmsHeader->iMaxFreq = (int)pAnalParams->fHighestFreq;
pSmsHeader->iFrameBSize = sms_frameSizeB(pSmsHeader);
- sprintf (pChTextString,
- "created by %s with parameters: format %d, soundType %d, "
- "analysisDirection %d, windowSize %.2f,"
- " windowType %d, frameRate %d, highestFreq %.2f, minPeakMag %.2f,"
- " refHarmonic %d, minRefHarmMag %.2f, refHarmMagDiffFromMax %.2f,"
- " defaultFund %.2f, lowestFund %.2f, highestFund %.2f, nGuides %d,"
- " nTracks %d, freqDeviation %.2f, peakContToGuide %.2f,"
- " fundContToGuide %.2f, cleanTracks %d, iMinTrackLength %d,"
- "iMaxSleepingTime %d, stochasticType %d, nStocCoeff %d\n"
- "iEnvType: %d, nEnvCoeff: %d",
- pProgramString,
- pAnalParams->iFormat, pAnalParams->iSoundType,
- pAnalParams->iAnalysisDirection, pAnalParams->fSizeWindow,
- pAnalParams->iWindowType, pAnalParams->iFrameRate,
- pAnalParams->fHighestFreq, pAnalParams->fMinPeakMag,
- pAnalParams->iRefHarmonic, pAnalParams->fMinRefHarmMag,
- pAnalParams->fRefHarmMagDiffFromMax,
- pAnalParams->fDefaultFundamental, pAnalParams->fLowestFundamental,
- pAnalParams->fHighestFundamental, pAnalParams->nGuides,
- pAnalParams->nTracks, pAnalParams->fFreqDeviation,
- pAnalParams->fPeakContToGuide, pAnalParams->fFundContToGuide,
- pAnalParams->iCleanTracks, pAnalParams->iMinTrackLength,
- pAnalParams->iMaxSleepingTime, pAnalParams->iStochasticType,
- pAnalParams->nStochasticCoeff, pSmsHeader->iEnvType, pSmsHeader->nEnvCoeff);
-
- pSmsHeader->nTextCharacters = strlen (pChTextString) + 1;
- pSmsHeader->pChTextCharacters = (char *) pChTextString;
}
/*! \brief write SMS header to file
@@ -121,50 +91,31 @@ void sms_fillHeader (SMS_Header *pSmsHeader, SMS_AnalParams *pAnalParams,
* \param ppSmsFile (double pointer to) file to be created
* \return error code \see SMS_WRERR in SMS_ERRORS
*/
-int sms_writeHeader (char *pChFileName, SMS_Header *pSmsHeader,
- FILE **ppSmsFile)
+int sms_writeHeader(char *pChFileName, SMS_Header *pSmsHeader, FILE **ppSmsFile)
{
int iVariableSize = 0;
- if (pSmsHeader->iSmsMagic != SMS_MAGIC)
+ if(pSmsHeader->iSmsMagic != SMS_MAGIC)
{
sms_error("not an SMS file");
- return(-1);
+ return -1;
}
- if ((*ppSmsFile = fopen (pChFileName, "w+")) == NULL)
+ if((*ppSmsFile = fopen (pChFileName, "w+")) == NULL)
{
sms_error("cannot open file for writing");
- return(-1);
+ return -1;
}
- /* check variable size of header */
- /* iVariableSize = sizeof (int) * pSmsHeader->nLoopRecords + */
- /* sizeof (sfloat) * pSmsHeader->nSpecEnvelopePoints + */
- /* sizeof(char) * pSmsHeader->nTextCharacters; */
- iVariableSize = sizeof(char) * pSmsHeader->nTextCharacters;
- pSmsHeader->iHeadBSize = sizeof(SMS_Header) + iVariableSize;
+ pSmsHeader->iHeadBSize = sizeof(SMS_Header);
/* write header */
- if (fwrite((void *)pSmsHeader, (size_t)1, (size_t)sizeof(SMS_Header),
- *ppSmsFile) < (size_t)sizeof(SMS_Header))
+ if(fwrite((void *)pSmsHeader, (size_t)1, (size_t)sizeof(SMS_Header),
+ *ppSmsFile) < (size_t)sizeof(SMS_Header))
{
sms_error("cannot write output file");
return(-1);
}
- /* write variable part of header */
- if (pSmsHeader->nTextCharacters > 0)
- {
- char *pChStart = (char *) pSmsHeader->pChTextCharacters;
- int iSize = sizeof(char) * pSmsHeader->nTextCharacters;
-
- if (fwrite ((void *)pChStart, (size_t)1, (size_t)iSize, *ppSmsFile) <
- (size_t)iSize)
- {
- sms_error("cannot write output file (nTextCharacters)");
- return(-1);
- }
- }
- return (0);
+ return 0;
}
/*! \brief rewrite SMS header and close file
@@ -173,40 +124,23 @@ int sms_writeHeader (char *pChFileName, SMS_Header *pSmsHeader,
* \param pSmsHeader pointer to header for SMS file
* \return error code \see SMS_WRERR in SMS_ERRORS
*/
-int sms_writeFile (FILE *pSmsFile, SMS_Header *pSmsHeader)
+int sms_writeFile(FILE *pSmsFile, SMS_Header *pSmsHeader)
{
int iVariableSize;
-
rewind(pSmsFile);
- /* check variable size of header */
- iVariableSize = sizeof(char) * pSmsHeader->nTextCharacters;
-
- pSmsHeader->iHeadBSize = sizeof(SMS_Header) + iVariableSize;
+ pSmsHeader->iHeadBSize = sizeof(SMS_Header);
/* write header */
- if (fwrite((void *)pSmsHeader, (size_t)1, (size_t)sizeof(SMS_Header),
+ if(fwrite((void *)pSmsHeader, (size_t)1, (size_t)sizeof(SMS_Header),
pSmsFile) < (size_t)sizeof(SMS_Header))
{
sms_error("cannot write output file (header)");
- return(-1);
+ return -1;
}
- if (pSmsHeader->nTextCharacters > 0)
- {
- char *pChStart = (char *) pSmsHeader->pChTextCharacters;
- int iSize = sizeof(char) * pSmsHeader->nTextCharacters;
-
- if (fwrite ((void *)pChStart, (size_t)1, (size_t)iSize, pSmsFile) <
- (size_t)iSize)
- {
- sms_error("cannot write output file (nTextCharacters)");
- return(-1);
- }
- }
-
fclose(pSmsFile);
- return (0);
+ return 0;
}
/*! \brief write SMS frame
@@ -216,32 +150,31 @@ int sms_writeFile (FILE *pSmsFile, SMS_Header *pSmsHeader)
* \param pSmsFrame pointer to SMS data frame
* \return 0 on success, -1 on failure
*/
-int sms_writeFrame (FILE *pSmsFile, SMS_Header *pSmsHeader,
- SMS_Data *pSmsFrame)
+int sms_writeFrame(FILE *pSmsFile, SMS_Header *pSmsHeader, SMS_Data *pSmsFrame)
{
- if (fwrite ((void *)pSmsFrame->pSmsData, 1, pSmsHeader->iFrameBSize,
- pSmsFile) < (unsigned int) pSmsHeader->iFrameBSize)
+ if (fwrite((void *)pSmsFrame->pSmsData, 1, pSmsHeader->iFrameBSize,
+ pSmsFile) < (unsigned int) pSmsHeader->iFrameBSize)
{
sms_error("cannot write frame to output file");
- return(-1);
+ return -1;
}
- else return (0);
+ return 0;
}
-
/*! \brief get the size in bytes of the frame in a SMS file
*
* \param pSmsHeader pointer to SMS header
* \return the size in bytes of the frame
*/
-int sms_frameSizeB (SMS_Header *pSmsHeader)
+int sms_frameSizeB(SMS_Header *pSmsHeader)
{
int iSize, nDet;
- if (pSmsHeader->iFormat == SMS_FORMAT_H ||
- pSmsHeader->iFormat == SMS_FORMAT_IH)
+ if(pSmsHeader->iFormat == SMS_FORMAT_H ||
+ pSmsHeader->iFormat == SMS_FORMAT_IH)
nDet = 2;/* freq, mag */
- else nDet = 3; /* freq, mag, phase */
+ else
+ nDet = 3; /* freq, mag, phase */
iSize = sizeof (sfloat) * (nDet * pSmsHeader->nTracks);
@@ -255,10 +188,9 @@ int sms_frameSizeB (SMS_Header *pSmsHeader)
iSize += sizeof(sfloat) * (pSmsHeader->nStochasticCoeff * 2 + 1);
}
iSize += sizeof(sfloat) * pSmsHeader->nEnvCoeff;
- return(iSize);
+ return iSize;
}
-
/*! \brief function to read SMS header
*
* \param pChFileName file name for SMS file
@@ -266,108 +198,89 @@ int sms_frameSizeB (SMS_Header *pSmsHeader)
* \param ppSmsFile (double pointer to) inputfile
* \return error code \see SMS_ERRORS
*/
-int sms_getHeader (char *pChFileName, SMS_Header **ppSmsHeader,
- FILE **ppSmsFile)
+int sms_getHeader(char *pChFileName, SMS_Header **ppSmsHeader, FILE **ppSmsFile)
{
int iHeadBSize, iFrameBSize, nFrames;
int iMagicNumber;
/* open file for reading */
- if ((*ppSmsFile = fopen (pChFileName, "r")) == NULL)
+ if((*ppSmsFile = fopen (pChFileName, "r")) == NULL)
{
sms_error("could not open SMS header");
- return (-1);
+ return -1;
}
/* read magic number */
- if (fread ((void *) &iMagicNumber, (size_t) sizeof(int), (size_t)1,
- *ppSmsFile) < (size_t)1)
+ if(fread((void *) &iMagicNumber, (size_t) sizeof(int), (size_t)1,
+ *ppSmsFile) < (size_t)1)
{
sms_error("could not read SMS header");
- return (-1);
+ return -1;
}
- if (iMagicNumber != SMS_MAGIC)
+ if(iMagicNumber != SMS_MAGIC)
{
sms_error("not an SMS file");
- return (-1);
+ return -1;
}
/* read size of of header */
- if (fread ((void *) &iHeadBSize, (size_t) sizeof(int), (size_t)1,
- *ppSmsFile) < (size_t)1)
+ if(fread((void *) &iHeadBSize, (size_t) sizeof(int), (size_t)1,
+ *ppSmsFile) < (size_t)1)
{
sms_error("could not read SMS header (iHeadBSize)");
- return (-1);
+ return -1;
}
- if (iHeadBSize <= 0)
+ if(iHeadBSize <= 0)
{
sms_error("bad SMS header size");
- return (-1);
+ return -1;
}
/* read number of data Frames */
- if (fread ((void *) &nFrames, (size_t) sizeof(int), (size_t)1,
- *ppSmsFile) < (size_t)1)
+ if(fread((void *) &nFrames, (size_t) sizeof(int), (size_t)1,
+ *ppSmsFile) < (size_t)1)
{
sms_error("could not read SMS number of frames");
- return (-1);
+ return -1;
}
- if (nFrames <= 0)
+ if(nFrames <= 0)
{
sms_error("number of frames <= 0");
- return (-1);
+ return -1;
}
/* read size of data Frames */
- if (fread ((void *) &iFrameBSize, (size_t) sizeof(int), (size_t)1,
- *ppSmsFile) < (size_t)1)
+ if(fread((void *) &iFrameBSize, (size_t) sizeof(int), (size_t)1,
+ *ppSmsFile) < (size_t)1)
{
sms_error("could not read size of SMS data");
- return (-1);
+ return -1;
}
- if (iFrameBSize <= 0)
+ if(iFrameBSize <= 0)
{
sms_error("size bytes of frames <= 0");
- return (-1);
+ return -1;
}
/* allocate memory for header */
- if (((*ppSmsHeader) = (SMS_Header *)malloc (iHeadBSize)) == NULL)
+ if(((*ppSmsHeader) = (SMS_Header *)malloc (iHeadBSize)) == NULL)
{
sms_error("cannot allocate memory for header");
- return (-1);
+ return -1;
}
/* read header */
- rewind (*ppSmsFile);
- if (fread ((void *) (*ppSmsHeader), 1, iHeadBSize, *ppSmsFile) < (unsigned int) iHeadBSize)
+ rewind(*ppSmsFile);
+ if(fread ((void *) (*ppSmsHeader), 1, iHeadBSize, *ppSmsFile) < (unsigned int) iHeadBSize)
{
sms_error("cannot read header of SMS file");
- return (-1);
+ return -1;
}
- /* set pointers to variable part of header */
- /* if ((*ppSmsHeader)->nLoopRecords > 0) */
- /* (*ppSmsHeader)->pILoopRecords = (int *) ((char *)(*ppSmsHeader) + */
- /* sizeof(SMS_Header)); */
-
- /* if ((*ppSmsHeader)->nSpecEnvelopePoints > 0) */
- /* (*ppSmsHeader)->pFSpectralEnvelope = */
- /* (sfloat *) ((char *)(*ppSmsHeader) + sizeof(SMS_Header) + */
- /* sizeof(int) * (*ppSmsHeader)->nLoopRecords); */
-
- /* if ((*ppSmsHeader)->nTextCharacters > 0) */
- /* (*ppSmsHeader)->pChTextCharacters = */
- /* (char *) ((char *)(*ppSmsHeader) + sizeof(SMS_Header) + */
- /* sizeof(int) * (*ppSmsHeader)->nLoopRecords + */
- /* sizeof(sfloat) * (*ppSmsHeader)->nSpecEnvelopePoints); */
- if ((*ppSmsHeader)->nTextCharacters > 0)
- (*ppSmsHeader)->pChTextCharacters = (char *)(*ppSmsHeader) + sizeof(SMS_Header);
-
- return (0);
+ return 0;
}
/*! \brief read an SMS data frame
@@ -378,24 +291,23 @@ int sms_getHeader (char *pChFileName, SMS_Header **ppSmsHeader,
* \param pSmsFrame pointer to SMS frame
* \return 0 on sucess, -1 on error
*/
-int sms_getFrame (FILE *pSmsFile, SMS_Header *pSmsHeader, int iFrame,
- SMS_Data *pSmsFrame)
+int sms_getFrame(FILE *pSmsFile, SMS_Header *pSmsHeader, int iFrame, SMS_Data *pSmsFrame)
{
- if (fseek (pSmsFile, pSmsHeader->iHeadBSize + iFrame *
- pSmsHeader->iFrameBSize, SEEK_SET) < 0)
+ if(fseek(pSmsFile, pSmsHeader->iHeadBSize + iFrame *
+ pSmsHeader->iFrameBSize, SEEK_SET) < 0)
{
- sms_error ("cannot seek to the SMS frame");
- return (-1);
+ sms_error("cannot seek to the SMS frame");
+ return -1;
}
- if ((pSmsHeader->iFrameBSize =
- fread ((void *)pSmsFrame->pSmsData, (size_t)1,
- (size_t)pSmsHeader->iFrameBSize, pSmsFile))
- != pSmsHeader->iFrameBSize)
+ if((pSmsHeader->iFrameBSize =
+ fread((void *)pSmsFrame->pSmsData, (size_t)1,
+ (size_t)pSmsHeader->iFrameBSize, pSmsFile))
+ != pSmsHeader->iFrameBSize)
{
- sms_error ("cannot read SMS frame");
- return (-1);
+ sms_error("cannot read SMS frame");
+ return -1;
}
- return (0);
+ return 0;
}
/*! \brief allocate memory for a frame of SMS data
@@ -409,25 +321,34 @@ int sms_getFrame (FILE *pSmsFile, SMS_Header *pSmsHeader, int iFrame,
* \param nEnvCoeff number of envelope coefficients in frame
* \return 0 on success, -1 on error
*/
-int sms_allocFrame (SMS_Data *pSmsFrame, int nTracks, int nStochCoeff, int iPhase,
- int stochType, int nEnvCoeff)
+int sms_allocFrame(SMS_Data *pSmsFrame, int nTracks, int nStochCoeff, int iPhase,
+ int stochType, int nEnvCoeff)
{
sfloat *dataPos; /* a marker to locate specific data witin smsData */
+
/* calculate size of frame */
- int sizeData = 2 * nTracks * sizeof(sfloat);
- sizeData += 1 * sizeof(sfloat); //adding one for nSamples
- if (iPhase > 0) sizeData += nTracks * sizeof(sfloat);
- if (stochType == SMS_STOC_APPROX)
+ int sizeData = sizeof(sfloat); /* nSamples */
+ /* frequencies and magnitudes */
+ sizeData += 2 * nTracks * sizeof(sfloat);
+ /* phases */
+ if(iPhase > 0)
+ sizeData += nTracks * sizeof(sfloat);
+ /* stochastic coefficients */
+ if(stochType == SMS_STOC_APPROX)
sizeData += (nStochCoeff + 1) * sizeof(sfloat);
- else if (stochType == SMS_STOC_IFFT)
- sizeData += (2*nStochCoeff + 1) * sizeof(sfloat);
+ else if(stochType == SMS_STOC_IFFT)
+ sizeData += ((2*nStochCoeff) + 1) * sizeof(sfloat);
+ /* spectral envelope */
sizeData += nEnvCoeff * sizeof(sfloat); /* add in number of envelope coefficients (cep or fbins) if any */
+
/* allocate memory for data */
- if ((pSmsFrame->pSmsData = (sfloat *) malloc (sizeData)) == NULL)
+ pSmsFrame->pSmsData = (sfloat *)malloc(sizeData);
+ if(pSmsFrame->pSmsData == NULL)
{
sms_error("cannot allocate memory for SMS frame data");
- return (-1);
+ return -1;
}
+ memset(pSmsFrame->pSmsData, 0, sizeData);
/* set the variables in the structure */
/* \todo why not set these in init functions, then allocate with them?? */
@@ -435,40 +356,38 @@ int sms_allocFrame (SMS_Data *pSmsFrame, int nTracks, int nStochCoeff, int iPhas
pSmsFrame->nTracks = nTracks;
pSmsFrame->nCoeff = nStochCoeff;
pSmsFrame->nEnvCoeff = nEnvCoeff;
+
/* set pointers to data types within smsData array */
pSmsFrame->pFSinFreq = pSmsFrame->pSmsData;
- dataPos = (sfloat *)(pSmsFrame->pFSinFreq + nTracks);
- memset(pSmsFrame->pFSinFreq, 0, sizeof(sfloat) * nTracks);
+ dataPos = (sfloat *)(pSmsFrame->pFSinFreq + nTracks);
pSmsFrame->pFSinAmp = dataPos;
dataPos = (sfloat *)(pSmsFrame->pFSinAmp + nTracks);
- memset(pSmsFrame->pFSinAmp, 0, sizeof(sfloat) * nTracks);
- if (iPhase > 0)
+ if(iPhase > 0)
{
pSmsFrame->pFSinPha = dataPos;
- dataPos = (sfloat *) (pSmsFrame->pFSinPha + nTracks);
- memset(pSmsFrame->pFSinPha, 0, sizeof(sfloat) * nTracks);
+ dataPos = (sfloat *)(pSmsFrame->pFSinPha + nTracks);
}
- else pSmsFrame->pFSinPha = NULL;
+ else
+ pSmsFrame->pFSinPha = NULL;
- if (stochType == SMS_STOC_APPROX)
+ if(stochType == SMS_STOC_APPROX)
{
pSmsFrame->pFStocCoeff = dataPos;
- dataPos = (sfloat *) (pSmsFrame->pFStocCoeff + nStochCoeff);
- memset(pSmsFrame->pFStocCoeff, 0, sizeof(sfloat) * nStochCoeff);
+ dataPos = (sfloat *)(pSmsFrame->pFStocCoeff + nStochCoeff);
pSmsFrame->pFStocGain = dataPos;
- dataPos = (sfloat *) (pSmsFrame->pFStocGain + 1);
+ dataPos = (sfloat *)(pSmsFrame->pFStocGain + 1);
}
- else if (stochType == SMS_STOC_IFFT)
+ else if(stochType == SMS_STOC_IFFT)
{
pSmsFrame->pFStocCoeff = dataPos;
- dataPos = (sfloat *) (pSmsFrame->pFStocCoeff + nStochCoeff);
+ dataPos = (sfloat *)(pSmsFrame->pFStocCoeff + nStochCoeff);
pSmsFrame->pResPhase = dataPos;
- dataPos = (sfloat *) (pSmsFrame->pResPhase + nStochCoeff);
+ dataPos = (sfloat *)(pSmsFrame->pResPhase + nStochCoeff);
pSmsFrame->pFStocGain = dataPos;
- dataPos = (sfloat *) (pSmsFrame->pFStocGain + 1);
+ dataPos = (sfloat *)(pSmsFrame->pFStocGain + 1);
}
else
{
@@ -476,11 +395,13 @@ int sms_allocFrame (SMS_Data *pSmsFrame, int nTracks, int nStochCoeff, int iPhas
pSmsFrame->pResPhase = NULL;
pSmsFrame->pFStocGain = NULL;
}
- if (nEnvCoeff > 0)
+
+ if(nEnvCoeff > 0)
pSmsFrame->pSpecEnv = dataPos;
else
pSmsFrame->pSpecEnv = NULL;
- return (0);
+
+ return 0;
}
/*! \brief function to allocate an SMS data frame using an SMS_Header
@@ -492,40 +413,45 @@ int sms_allocFrame (SMS_Data *pSmsFrame, int nTracks, int nStochCoeff, int iPhas
* \param pSmsFrame pointer to SMS frame
* \return 0 on success, -1 on error
*/
-int sms_allocFrameH (SMS_Header *pSmsHeader, SMS_Data *pSmsFrame)
+int sms_allocFrameH(SMS_Header *pSmsHeader, SMS_Data *pSmsFrame)
{
int iPhase = (pSmsHeader->iFormat == SMS_FORMAT_HP ||
- pSmsHeader->iFormat == SMS_FORMAT_IHP) ? 1 : 0;
- return (sms_allocFrame (pSmsFrame, pSmsHeader->nTracks,
- pSmsHeader->nStochasticCoeff, iPhase,
- pSmsHeader->iStochasticType, pSmsHeader->nEnvCoeff));
+ pSmsHeader->iFormat == SMS_FORMAT_IHP) ? 1 : 0;
+ return sms_allocFrame(pSmsFrame, pSmsHeader->nTracks,
+ pSmsHeader->nStochasticCoeff, iPhase,
+ pSmsHeader->iStochasticType,
+ pSmsHeader->nEnvCoeff);
}
-
/*! \brief free the SMS data structure
*
* \param pSmsFrame pointer to frame of SMS data
*/
-void sms_freeFrame (SMS_Data *pSmsFrame)
+void sms_freeFrame(SMS_Data *pSmsFrame)
{
- free(pSmsFrame->pSmsData);
- pSmsFrame->nTracks = 0;
- pSmsFrame->nCoeff = 0;
- pSmsFrame->sizeData = 0;
- pSmsFrame->pFSinFreq = NULL;
- pSmsFrame->pFSinAmp = NULL;
- pSmsFrame->pFStocCoeff = NULL;
- pSmsFrame->pResPhase = NULL;
- pSmsFrame->pFStocGain = NULL;
+ if(!pSmsFrame)
+ return;
+
+ if(pSmsFrame->pSmsData)
+ free(pSmsFrame->pSmsData);
+
+ pSmsFrame->nTracks = 0;
+ pSmsFrame->nCoeff = 0;
+ pSmsFrame->sizeData = 0;
+ pSmsFrame->pFSinFreq = NULL;
+ pSmsFrame->pFSinAmp = NULL;
+ pSmsFrame->pFStocCoeff = NULL;
+ pSmsFrame->pResPhase = NULL;
+ pSmsFrame->pFStocGain = NULL;
}
/*! \brief clear the SMS data structure
*
* \param pSmsFrame pointer to frame of SMS data
*/
-void sms_clearFrame (SMS_Data *pSmsFrame)
+void sms_clearFrame(SMS_Data *pSmsFrame)
{
- memset ((char *) pSmsFrame->pSmsData, 0, pSmsFrame->sizeData);
+ memset(pSmsFrame->pSmsData, 0, pSmsFrame->sizeData);
}
/*! \brief copy a frame of SMS_Data
@@ -534,49 +460,49 @@ void sms_clearFrame (SMS_Data *pSmsFrame)
* \param pOriginalSmsData original frame
*
*/
-void sms_copyFrame (SMS_Data *pCopySmsData, SMS_Data *pOriginalSmsData)
+void sms_copyFrame(SMS_Data *pCopySmsData, SMS_Data *pOriginalSmsData)
{
/* if the two frames are the same size just copy data */
- if (pCopySmsData->sizeData == pOriginalSmsData->sizeData &&
- pCopySmsData->nTracks == pOriginalSmsData->nTracks)
+ if(pCopySmsData->sizeData == pOriginalSmsData->sizeData &&
+ pCopySmsData->nTracks == pOriginalSmsData->nTracks)
{
- memcpy ((char *)pCopySmsData->pSmsData,
- (char *)pOriginalSmsData->pSmsData,
- pCopySmsData->sizeData);
+ memcpy((char *)pCopySmsData->pSmsData,
+ (char *)pOriginalSmsData->pSmsData,
+ pCopySmsData->sizeData);
}
/* if frames is different size copy the smallest */
else
{
- int nTracks = MIN (pCopySmsData->nTracks, pOriginalSmsData->nTracks);
- int nCoeff = MIN (pCopySmsData->nCoeff, pOriginalSmsData->nCoeff);
+ int nTracks = MIN(pCopySmsData->nTracks, pOriginalSmsData->nTracks);
+ int nCoeff = MIN(pCopySmsData->nCoeff, pOriginalSmsData->nCoeff);
pCopySmsData->nTracks = nTracks;
pCopySmsData->nCoeff = nCoeff;
- memcpy ((char *)pCopySmsData->pFSinFreq,
- (char *)pOriginalSmsData->pFSinFreq,
- sizeof(sfloat) * nTracks);
- memcpy ((char *)pCopySmsData->pFSinAmp,
- (char *)pOriginalSmsData->pFSinAmp,
- sizeof(sfloat) * nTracks);
- if (pOriginalSmsData->pFSinPha != NULL &&
- pCopySmsData->pFSinPha != NULL)
- memcpy ((char *)pCopySmsData->pFSinPha,
- (char *)pOriginalSmsData->pFSinPha,
- sizeof(sfloat) * nTracks);
- if (pOriginalSmsData->pFStocCoeff != NULL &&
- pCopySmsData->pFStocCoeff != NULL)
+ memcpy((char *)pCopySmsData->pFSinFreq,
+ (char *)pOriginalSmsData->pFSinFreq,
+ sizeof(sfloat) * nTracks);
+ memcpy((char *)pCopySmsData->pFSinAmp,
+ (char *)pOriginalSmsData->pFSinAmp,
+ sizeof(sfloat) * nTracks);
+ if(pOriginalSmsData->pFSinPha != NULL &&
+ pCopySmsData->pFSinPha != NULL)
+ memcpy((char *)pCopySmsData->pFSinPha,
+ (char *)pOriginalSmsData->pFSinPha,
+ sizeof(sfloat) * nTracks);
+ if(pOriginalSmsData->pFStocCoeff != NULL &&
+ pCopySmsData->pFStocCoeff != NULL)
{
- if (pOriginalSmsData->pResPhase != NULL &&
- pCopySmsData->pResPhase != NULL)
- memcpy ((char *)pCopySmsData->pResPhase,
- (char *)pOriginalSmsData->pResPhase,
- sizeof(sfloat) * nCoeff);
+ if(pOriginalSmsData->pResPhase != NULL &&
+ pCopySmsData->pResPhase != NULL)
+ memcpy((char *)pCopySmsData->pResPhase,
+ (char *)pOriginalSmsData->pResPhase,
+ sizeof(sfloat) * nCoeff);
}
- if (pOriginalSmsData->pFStocGain != NULL &&
- pCopySmsData->pFStocGain != NULL)
- memcpy ((char *)pCopySmsData->pFStocGain,
- (char *)pOriginalSmsData->pFStocGain,
- sizeof(sfloat));
+ if(pOriginalSmsData->pFStocGain != NULL &&
+ pCopySmsData->pFStocGain != NULL)
+ memcpy((char *)pCopySmsData->pFStocGain,
+ (char *)pOriginalSmsData->pFStocGain,
+ sizeof(sfloat));
}
}
@@ -589,21 +515,22 @@ void sms_copyFrame (SMS_Data *pCopySmsData, SMS_Data *pOriginalSmsData)
* \param pSmsFrameOut sms output frame
* \param fInterpFactor interpolation factor
*/
-void sms_interpolateFrames (SMS_Data *pSmsFrame1, SMS_Data *pSmsFrame2,
- SMS_Data *pSmsFrameOut, sfloat fInterpFactor)
+void sms_interpolateFrames(SMS_Data *pSmsFrame1, SMS_Data *pSmsFrame2,
+ SMS_Data *pSmsFrameOut, sfloat fInterpFactor)
{
int i;
sfloat fFreq1, fFreq2;
/* interpolate the deterministic part */
- for (i = 0; i < pSmsFrame1->nTracks; i++)
+ for(i = 0; i < pSmsFrame1->nTracks; i++)
{
fFreq1 = pSmsFrame1->pFSinFreq[i];
fFreq2 = pSmsFrame2->pFSinFreq[i];
- if (fFreq1 == 0) fFreq1 = fFreq2;
- if (fFreq2 == 0) fFreq2 = fFreq1;
- pSmsFrameOut->pFSinFreq[i] =
- fFreq1 + fInterpFactor * (fFreq2 - fFreq1);
+ if(fFreq1 == 0)
+ fFreq1 = fFreq2;
+ if(fFreq2 == 0)
+ fFreq2 = fFreq1;
+ pSmsFrameOut->pFSinFreq[i] = fFreq1 + fInterpFactor * (fFreq2 - fFreq1);
pSmsFrameOut->pFSinAmp[i] =
pSmsFrame1->pFSinAmp[i] + fInterpFactor *
(pSmsFrame2->pFSinAmp[i] - pSmsFrame1->pFSinAmp[i]);
@@ -611,23 +538,22 @@ void sms_interpolateFrames (SMS_Data *pSmsFrame1, SMS_Data *pSmsFrame2,
/* interpolate the stochastic part. The pointer is non-null when the frame contains
stochastic coefficients */
- if (pSmsFrameOut->pFStocGain)
+ if(pSmsFrameOut->pFStocGain)
{
*(pSmsFrameOut->pFStocGain) =
*(pSmsFrame1->pFStocGain) + fInterpFactor *
(*(pSmsFrame2->pFStocGain) - *(pSmsFrame1->pFStocGain));
}
/*! \todo how to interpolate residual phase spectrum */
- for (i = 0; i < pSmsFrame1->nCoeff; i++)
+ for(i = 0; i < pSmsFrame1->nCoeff; i++)
pSmsFrameOut->pFStocCoeff[i] =
pSmsFrame1->pFStocCoeff[i] + fInterpFactor *
(pSmsFrame2->pFStocCoeff[i] - pSmsFrame1->pFStocCoeff[i]);
/* DO NEXT: interpolate spec env here if fbins */
- for (i = 0; i < pSmsFrame1->nEnvCoeff; i++)
+ for(i = 0; i < pSmsFrame1->nEnvCoeff; i++)
pSmsFrameOut->pSpecEnv[i] =
pSmsFrame1->pSpecEnv[i] + fInterpFactor *
(pSmsFrame2->pSpecEnv[i] - pSmsFrame1->pSpecEnv[i]);
-
-
}
+
diff --git a/sms/filters.c b/sms/filters.c
index b1ca9fc..9c13ad5 100644
--- a/sms/filters.c
+++ b/sms/filters.c
@@ -31,13 +31,11 @@
*
* sfloat fInput; sound sample
*/
-sfloat sms_preEmphasis (sfloat fInput, SMS_AnalParams *pAnalParams)
+sfloat sms_preEmphasis(sfloat fInput, SMS_AnalParams *pAnalParams)
{
- sfloat fOutput = 0;
- fOutput = fInput - SMS_EMPH_COEF * pAnalParams->preEmphasisLastValue;
- pAnalParams->preEmphasisLastValue = fOutput;
-
- return (fOutput);
+ sfloat fOutput = fInput - SMS_EMPH_COEF * pAnalParams->preEmphasisLastValue;
+ pAnalParams->preEmphasisLastValue = fOutput;
+ return fOutput;
}
/* de-emphasis filter function, it returns the filtered value
@@ -46,11 +44,9 @@ sfloat sms_preEmphasis (sfloat fInput, SMS_AnalParams *pAnalParams)
*/
sfloat sms_deEmphasis(sfloat fInput, SMS_SynthParams *pSynthParams)
{
- sfloat fOutput = 0;
- fOutput = fInput + SMS_EMPH_COEF * pSynthParams->deemphasisLastValue;
- pSynthParams->deemphasisLastValue = fInput;
-
- return(fOutput);
+ sfloat fOutput = fInput + SMS_EMPH_COEF * pSynthParams->deEmphasisLastValue;
+ pSynthParams->deEmphasisLastValue = fInput;
+ return fOutput;
}
/*! \brief function to implement a zero-pole filter
@@ -65,15 +61,11 @@ sfloat sms_deEmphasis(sfloat fInput, SMS_SynthParams *pSynthParams)
* \param fInput input sample
* \return value is the filtered sample
*/
-static sfloat ZeroPoleFilter (sfloat *pFa, sfloat *pFb, int nCoeff, sfloat fInput )
+static sfloat ZeroPoleFilter(sfloat *pFa, sfloat *pFb, int nCoeff, sfloat fInput )
{
double fOut = 0;
int iSection;
-
-/* static sfloat *pD = NULL; */
-/* if (pD == NULL) */
-/* pD = (sfloat *) calloc(5, sizeof(sfloat)); */
- static sfloat pD[5] = {0, 0, 0, 0, 0};
+ static sfloat pD[5] = {0, 0, 0, 0, 0};
pD[0] = fInput;
for (iSection = nCoeff-1; iSection > 0; iSection--)
@@ -83,23 +75,9 @@ static sfloat ZeroPoleFilter (sfloat *pFa, sfloat *pFb, int nCoeff, sfloat fInpu
pD[iSection] = pD [iSection-1];
}
fOut = fOut + pFa[0] * pD[0];
- return((sfloat) fOut);
+ return (sfloat) fOut;
}
- /* cutoff 1500 Hz */
-/* static sfloat pFCoeff32k[10] = {0.679459, -2.71784, 4.07676, -2.71784,
- 0.679459, 1, -3.23168, 3.97664, -2.20137, 0.461665};
- static sfloat pFCoeff36k[10] = {0.709489, -2.83796, 4.25694, -2.83796,
- 0.709489, 1, -3.31681, 4.17425, -2.3574, 0.503375};
- static sfloat pFCoeff40k[10] = {0.734408, -2.93763, 4.40645, -2.93763,
- 0.734408, 1, -3.38497, 4.33706, -2.48914, 0.539355};
- static sfloat pFCoeff441k[10] = {0.755893, -3.02357, 4.53536, -3.02357,
- 0.755893, 1, -3.44205, 4.47657, -2.6043, 0.571374};
- static sfloat pFCoeff48k[10] = {0.773347, -3.09339, 4.64008, -3.09339,
- 0.773347, 1, -3.48731, 4.58929, -2.69888, 0.598065};
-*/
-
-
/*! \brief function to filter a waveform with a high-pass filter
*
* cutoff =1500 Hz
@@ -110,10 +88,8 @@ static sfloat ZeroPoleFilter (sfloat *pFa, sfloat *pFb, int nCoeff, sfloat fInpu
* \param pResidual pointer to residual signal
* \param iSamplingRate sampling rate of signal
*/
-void sms_filterHighPass ( int sizeResidual, sfloat *pResidual, int iSamplingRate)
+void sms_filterHighPass(int sizeResidual, sfloat *pResidual, int iSamplingRate)
{
-
-
/* cutoff 800Hz */
static sfloat pFCoeff32k[10] = {0.814255, -3.25702, 4.88553, -3.25702,
0.814255, 1, -3.58973, 4.85128, -2.92405, 0.66301};
@@ -128,13 +104,13 @@ void sms_filterHighPass ( int sizeResidual, sfloat *pResidual, int iSamplingRate
sfloat *pFCoeff, fSample = 0;
int i;
- if (iSamplingRate <= 32000)
+ if(iSamplingRate <= 32000)
pFCoeff = pFCoeff32k;
- else if (iSamplingRate <= 36000)
+ else if(iSamplingRate <= 36000)
pFCoeff = pFCoeff36k;
- else if (iSamplingRate <= 40000)
+ else if(iSamplingRate <= 40000)
pFCoeff = pFCoeff40k;
- else if (iSamplingRate <= 44100)
+ else if(iSamplingRate <= 44100)
pFCoeff = pFCoeff441k;
else
pFCoeff = pFCoeff48k;
@@ -142,12 +118,11 @@ void sms_filterHighPass ( int sizeResidual, sfloat *pResidual, int iSamplingRate
for(i = 0; i < sizeResidual; i++)
{
/* try to avoid underflow when there is nothing to filter */
- if (i > 0 && fSample == 0 && pResidual[i] == 0)
+ if(i > 0 && fSample == 0 && pResidual[i] == 0)
return;
fSample = pResidual[i];
- pResidual[i] =
- ZeroPoleFilter (&pFCoeff[0], &pFCoeff[5], 5, fSample);
+ pResidual[i] = ZeroPoleFilter (&pFCoeff[0], &pFCoeff[5], 5, fSample);
}
}
@@ -161,32 +136,32 @@ void sms_filterHighPass ( int sizeResidual, sfloat *pResidual, int iSamplingRate
* \param size2 horizontal size of pFArray
* \param pFOutArray output array of size size1
*/
-void sms_filterArray (sfloat *pFArray, int size1, int size2, sfloat *pFOutArray)
+void sms_filterArray(sfloat *pFArray, int size1, int size2, sfloat *pFOutArray)
{
int i, j, iPoint, iFrame, size2_2 = size2-2, size2_1 = size2-1;
sfloat *pFCurrentArray = pFArray + (size2_1) * size1;
- sfloat fVal, fWeighting, fTotalWeighting, fTmpVal;
+ sfloat fVal, fWeighting, fTotalWeighting, fTmpVal;
/* find the filtered envelope */
- for (i = 0; i < size1; i++)
+ for(i = 0; i < size1; i++)
{
fVal = pFCurrentArray[i];
fTotalWeighting = 1;
/* filter by the surrounding points */
- for (j = 1; j < (size2_2); j++)
+ for(j = 1; j < (size2_2); j++)
{
fWeighting = (sfloat) size2 / (1+ j);
/* filter on the vertical dimension */
/* consider the lower points */
iPoint = i - (size2_1) + j;
- if (iPoint >= 0)
+ if(iPoint >= 0)
{
fVal += pFCurrentArray[iPoint] * fWeighting;
fTotalWeighting += fWeighting;
}
/* consider the higher points */
iPoint = i + (size2_1) - j;
- if (iPoint < size1)
+ if(iPoint < size1)
{
fVal += pFCurrentArray[iPoint] * fWeighting;
fTotalWeighting += fWeighting;
@@ -195,7 +170,7 @@ void sms_filterArray (sfloat *pFArray, int size1, int size2, sfloat *pFOutArray)
/* consider the previous points */
iFrame = j;
fTmpVal = pFArray[iFrame*size1 + i];
- if (fTmpVal)
+ if(fTmpVal)
{
fVal += fTmpVal * fWeighting;
fTotalWeighting += fWeighting;
diff --git a/sms/fixTracks.c b/sms/fixTracks.c
index dc507f8..81e24ee 100644
--- a/sms/fixTracks.c
+++ b/sms/fixTracks.c
@@ -153,79 +153,70 @@ static void DeleteShortTrack (int iCurrentFrame, int iTrack, int *pIState,
*/
void sms_cleanTracks(int iCurrentFrame, SMS_AnalParams *pAnalParams)
{
- int iTrack, iLength, iFrame;
- static int *pIState = NULL;
- static int nStates = 0;
+ int iTrack, iLength, iFrame;
- if (pIState == NULL || nStates != pAnalParams->nGuides || pAnalParams->resetGuideStates == 1)
- {
- /* \todo shouldn't this memory allocation be checked? */
- pIState = (int *) calloc (pAnalParams->nGuides, sizeof(int));
- nStates = pAnalParams->nGuides;
- pAnalParams->resetGuideStates = 0;
- }
-
- /* if fundamental and first partial are short, delete everything */
- if ((pAnalParams->iFormat == SMS_FORMAT_H ||
- pAnalParams->iFormat == SMS_FORMAT_HP) &&
- pAnalParams->ppFrames[iCurrentFrame]->deterministic.pFSinAmp[0] == 0 &&
- pIState[0] > 0 &&
- pIState[0] < pAnalParams->iMinTrackLength &&
- pAnalParams->ppFrames[iCurrentFrame]->deterministic.pFSinAmp[1] == 0 &&
- pIState[1] > 0 &&
- pIState[1] < pAnalParams->iMinTrackLength)
- {
- iLength = pIState[0];
- for (iTrack = 0; iTrack < pAnalParams->nGuides; iTrack++)
- {
- for (iFrame = 1; iFrame <= iLength; iFrame++)
- {
- if((iCurrentFrame - iFrame) >= 0)
- {
- pAnalParams->ppFrames[iCurrentFrame -
- iFrame]->deterministic.pFSinAmp[iTrack] = 0;
- pAnalParams->ppFrames[iCurrentFrame -
- iFrame]->deterministic.pFSinFreq[iTrack] = 0;
- pAnalParams->ppFrames[iCurrentFrame -
- iFrame]->deterministic.pFSinPha[iTrack] = 0;
- }
- }
- pIState[iTrack] = -pAnalParams->iMaxSleepingTime;
- }
- if (pAnalParams->iDebugMode == SMS_DBG_CLEAN_TRAJ ||
- pAnalParams->iDebugMode == SMS_DBG_ALL)
+ /* if fundamental and first partial are short, delete everything */
+ if((pAnalParams->iFormat == SMS_FORMAT_H || pAnalParams->iFormat == SMS_FORMAT_HP) &&
+ pAnalParams->ppFrames[iCurrentFrame]->deterministic.pFSinAmp[0] == 0 &&
+ pAnalParams->guideStates[0] > 0 &&
+ pAnalParams->guideStates[0] < pAnalParams->iMinTrackLength &&
+ pAnalParams->ppFrames[iCurrentFrame]->deterministic.pFSinAmp[1] == 0 &&
+ pAnalParams->guideStates[1] > 0 &&
+ pAnalParams->guideStates[1] < pAnalParams->iMinTrackLength)
+ {
+ iLength = pAnalParams->guideStates[0];
+ for(iTrack = 0; iTrack < pAnalParams->nGuides; iTrack++)
+ {
+ for(iFrame = 1; iFrame <= iLength; iFrame++)
+ {
+ if((iCurrentFrame - iFrame) >= 0)
{
- fprintf(stdout, "cleanTrack: frame %d to frame %d deleted\n",
- pAnalParams->ppFrames[iCurrentFrame-iLength]->iFrameNum,
- pAnalParams->ppFrames[iCurrentFrame-1]->iFrameNum);
+ pAnalParams->ppFrames[iCurrentFrame -
+ iFrame]->deterministic.pFSinAmp[iTrack] = 0;
+ pAnalParams->ppFrames[iCurrentFrame -
+ iFrame]->deterministic.pFSinFreq[iTrack] = 0;
+ pAnalParams->ppFrames[iCurrentFrame -
+ iFrame]->deterministic.pFSinPha[iTrack] = 0;
}
+ }
+ pAnalParams->guideStates[iTrack] = -pAnalParams->iMaxSleepingTime;
+ }
+ if(pAnalParams->iDebugMode == SMS_DBG_CLEAN_TRAJ ||
+ pAnalParams->iDebugMode == SMS_DBG_ALL)
+ {
+ fprintf(stdout, "cleanTrack: frame %d to frame %d deleted\n",
+ pAnalParams->ppFrames[iCurrentFrame-iLength]->iFrameNum,
+ pAnalParams->ppFrames[iCurrentFrame-1]->iFrameNum);
+ }
- return;
- }
-
- /* check every partial individually */
- for (iTrack = 0; iTrack < pAnalParams->nGuides; iTrack++)
- {
- /* track after gap */
- if(pAnalParams->ppFrames[iCurrentFrame]->deterministic.pFSinAmp[iTrack] != 0)
- {
- if(pIState[iTrack] < 0 &&
- pIState[iTrack] > -pAnalParams->iMaxSleepingTime)
- FillGap (iCurrentFrame, iTrack, pIState, pAnalParams);
- else
- pIState[iTrack] = (pIState[iTrack]<0) ? 1 : pIState[iTrack]+1;
- }
- /* gap after track */
- else
- {
- if(pIState[iTrack] > 0 &&
- pIState[iTrack] < pAnalParams->iMinTrackLength)
- DeleteShortTrack (iCurrentFrame, iTrack, pIState, pAnalParams);
- else
- pIState[iTrack] = (pIState[iTrack]>0) ? -1 : pIState[iTrack]-1;
- }
- }
- return;
+ return;
+ }
+
+ /* check every partial individually */
+ for(iTrack = 0; iTrack < pAnalParams->nGuides; iTrack++)
+ {
+ /* track after gap */
+ if(pAnalParams->ppFrames[iCurrentFrame]->deterministic.pFSinAmp[iTrack] != 0)
+ {
+ if(pAnalParams->guideStates[iTrack] < 0 &&
+ pAnalParams->guideStates[iTrack] > -pAnalParams->iMaxSleepingTime)
+ FillGap (iCurrentFrame, iTrack, pAnalParams->guideStates, pAnalParams);
+ else
+ pAnalParams->guideStates[iTrack] =
+ (pAnalParams->guideStates[iTrack]<0) ? 1 : pAnalParams->guideStates[iTrack]+1;
+ }
+ /* gap after track */
+ else
+ {
+ if(pAnalParams->guideStates[iTrack] > 0 &&
+ pAnalParams->guideStates[iTrack] < pAnalParams->iMinTrackLength)
+ DeleteShortTrack (iCurrentFrame, iTrack, pAnalParams->guideStates, pAnalParams);
+ else
+ pAnalParams->guideStates[iTrack] =
+ (pAnalParams->guideStates[iTrack]>0) ? -1 : pAnalParams->guideStates[iTrack]-1;
+ }
+ }
+ return;
}
/*! \brief scale deterministic magnitude if synthesis is larger than original
@@ -236,15 +227,15 @@ void sms_cleanTracks(int iCurrentFrame, SMS_AnalParams *pAnalParams)
* \param pAnalParams pointer to analysis parameters
* \param nTrack number of tracks
*/
-void sms_scaleDet (sfloat *pFSynthBuffer, sfloat *pFOriginalBuffer,
- sfloat *pFSinAmp, SMS_AnalParams *pAnalParams, int nTrack)
+void sms_scaleDet(sfloat *pFSynthBuffer, sfloat *pFOriginalBuffer,
+ sfloat *pFSinAmp, SMS_AnalParams *pAnalParams, int nTrack)
{
sfloat fOriginalMag = 0, fSynthesisMag = 0;
sfloat fCosScaleFactor;
int iTrack, i;
/* get sound energy */
- for (i = 0; i < pAnalParams->sizeHop; i++)
+ for(i = 0; i < pAnalParams->sizeHop; i++)
{
fOriginalMag += fabs((double) pFOriginalBuffer[i]);
fSynthesisMag += fabs((double) pFSynthBuffer[i]);
@@ -252,18 +243,18 @@ void sms_scaleDet (sfloat *pFSynthBuffer, sfloat *pFOriginalBuffer,
/* if total energy of deterministic sound is larger than original,
scale deterministic representation */
- if (fSynthesisMag > (1.5 * fOriginalMag))
+ if(fSynthesisMag > (1.5 * fOriginalMag))
{
fCosScaleFactor = fOriginalMag / fSynthesisMag;
if(pAnalParams->iDebugMode == SMS_DBG_CLEAN_TRAJ ||
pAnalParams->iDebugMode == SMS_DBG_ALL)
- fprintf (stdout, "Frame %d: magnitude scaled by %f\n",
- pAnalParams->ppFrames[0]->iFrameNum, fCosScaleFactor);
+ fprintf(stdout, "Frame %d: magnitude scaled by %f\n",
+ pAnalParams->ppFrames[0]->iFrameNum, fCosScaleFactor);
- for (iTrack = 0; iTrack < nTrack; iTrack++)
- if (pFSinAmp[iTrack] > 0)
- pFSinAmp[iTrack] =
- sms_magToDB (sms_dBToMag (pFSinAmp[iTrack]) * fCosScaleFactor);
+ for(iTrack = 0; iTrack < nTrack; iTrack++)
+ if(pFSinAmp[iTrack] > 0)
+ pFSinAmp[iTrack] = sms_magToDB (sms_dBToMag (pFSinAmp[iTrack]) * fCosScaleFactor);
}
}
+
diff --git a/sms/peakContinuation.c b/sms/peakContinuation.c
index 571772f..b514266 100644
--- a/sms/peakContinuation.c
+++ b/sms/peakContinuation.c
@@ -362,140 +362,120 @@ static int GetStartingPeak(int iGuide, SMS_Guide *pGuides, int nGuides,
*/
int sms_peakContinuation(int iFrame, SMS_AnalParams *pAnalParams)
{
- int iGuide, iCurrentPeak = -1, iGoodPeak = -1;
- sfloat fFund = pAnalParams->ppFrames[iFrame]->fFundamental;
- sfloat fFreqDev = fFund * pAnalParams->fFreqDeviation, fCurrentMax = 1000;
- static SMS_Guide *pGuides = NULL;
- static int nGuides = 0;
-
- if(pGuides == NULL || nGuides != pAnalParams->nGuides || pAnalParams->resetGuides == 1)
- {
- if((pGuides = (SMS_Guide *) calloc(pAnalParams->nGuides, sizeof(SMS_Guide)))
- == NULL)
- return SMS_MALLOC;
- if (pAnalParams->iFormat == SMS_FORMAT_H ||
- pAnalParams->iFormat == SMS_FORMAT_HP)
- for (iGuide = 0; iGuide < pAnalParams->nGuides; iGuide++)
- pGuides[iGuide].fFreq = pAnalParams->fDefaultFundamental * (iGuide + 1);
- nGuides = pAnalParams->nGuides;
- pAnalParams->resetGuides = 0;
- }
-
- /* update guides with fundamental contribution */
- if(fFund > 0 &&
- (pAnalParams->iFormat == SMS_FORMAT_H ||
- pAnalParams->iFormat == SMS_FORMAT_HP))
- for(iGuide = 0; iGuide < pAnalParams->nGuides; iGuide++)
- pGuides[iGuide].fFreq =
- (1 - pAnalParams->fFundContToGuide) * pGuides[iGuide].fFreq +
- pAnalParams->fFundContToGuide * fFund * (iGuide + 1);
-
- if (pAnalParams->iDebugMode == SMS_DBG_PEAK_CONT ||
- pAnalParams->iDebugMode == SMS_DBG_ALL)
- fprintf(stdout,
- "Frame %d Peak Continuation: \n",
- pAnalParams->ppFrames[iFrame]->iFrameNum);
-
- /* continue all guides */
- for(iGuide = 0; iGuide < pAnalParams->nGuides; iGuide++)
- {
- sfloat fPreviousFreq =
- pAnalParams->ppFrames[iFrame-1]->deterministic.pFSinFreq[iGuide];
-
- /* get the guide value by upgrading the previous guide */
- if(fPreviousFreq > 0)
- pGuides[iGuide].fFreq =
- (1 - pAnalParams->fPeakContToGuide) * pGuides[iGuide].fFreq +
- pAnalParams->fPeakContToGuide * fPreviousFreq;
-
- if(pAnalParams->iDebugMode == SMS_DBG_PEAK_CONT ||
- pAnalParams->iDebugMode == SMS_DBG_ALL)
- fprintf(stdout, "Guide %d: freq %f, mag %f\n",
- iGuide, pGuides[iGuide].fFreq, pGuides[iGuide].fMag);
-
- if(pGuides[iGuide].fFreq <= 0.0 ||
- pGuides[iGuide].fFreq > pAnalParams->fHighestFreq)
- {
- pGuides[iGuide].iStatus = GUIDE_DEAD;
- pGuides[iGuide].fFreq = 0;
- continue;
- }
-
- pGuides[iGuide].iPeakChosen = -1;
-
- if(pAnalParams->iFormat == SMS_FORMAT_IH ||
- pAnalParams->iFormat == SMS_FORMAT_IHP)
- fFreqDev = pGuides[iGuide].fFreq * pAnalParams->fFreqDeviation;
-
- /* get the best peak for the guide */
- GetBestPeak(pGuides, iGuide, pAnalParams->ppFrames[iFrame]->pSpectralPeaks,
- pAnalParams, fFreqDev);
- }
-
- /* try to find good peaks for the GUIDE_DEAD guides */
- if(pAnalParams->iFormat == SMS_FORMAT_IH ||
- pAnalParams->iFormat == SMS_FORMAT_IHP)
- {
- for(iGuide = 0; iGuide < pAnalParams->nGuides; iGuide++)
- {
- if(pGuides[iGuide].iStatus != GUIDE_DEAD)
- continue;
-
- /* TODO: make this function use pAnalParams->maxPeaks instead
- * of SMS_MAX_NPEAKS */
- if(GetStartingPeak (iGuide, pGuides, pAnalParams->nGuides,
- pAnalParams->ppFrames[iFrame]->pSpectralPeaks,
- &fCurrentMax) == -1)
- break;
- }
- }
-
- /* save all the continuation values,
- * assume output tracks are already clear */
- for(iGuide = 0; iGuide < pAnalParams->nGuides; iGuide++)
- {
- if(pGuides[iGuide].iStatus == GUIDE_DEAD)
- continue;
-
- if(pAnalParams->iFormat == SMS_FORMAT_IH ||
- pAnalParams->iFormat == SMS_FORMAT_IHP)
- {
- if(pGuides[iGuide].iStatus > 0 &&
- pGuides[iGuide].iPeakChosen == -1)
- {
- if(pGuides[iGuide].iStatus++ > pAnalParams->iMaxSleepingTime)
- {
- pGuides[iGuide].iStatus = GUIDE_DEAD;
- pGuides[iGuide].fFreq = 0;
- pGuides[iGuide].fMag = 0;
- pGuides[iGuide].iPeakChosen = -1;
- }
- else
- pGuides[iGuide].iStatus++;
- continue;
- }
-
- if(pGuides[iGuide].iStatus == GUIDE_ACTIVE &&
- pGuides[iGuide].iPeakChosen == -1)
- {
- pGuides[iGuide].iStatus = 1;
- continue;
- }
- }
-
- /* if good continuation peak found, save it */
- if((iCurrentPeak = pGuides[iGuide].iPeakChosen) >= 0)
- {
- pAnalParams->ppFrames[iFrame]->deterministic.pFSinFreq[iGuide] =
- pAnalParams->ppFrames[iFrame]->pSpectralPeaks[iCurrentPeak].fFreq;
- pAnalParams->ppFrames[iFrame]->deterministic.pFSinAmp[iGuide] =
- pAnalParams->ppFrames[iFrame]->pSpectralPeaks[iCurrentPeak].fMag;
- pAnalParams->ppFrames[iFrame]->deterministic.pFSinPha[iGuide] =
- pAnalParams->ppFrames[iFrame]->pSpectralPeaks[iCurrentPeak].fPhase;
-
- pGuides[iGuide].iStatus = GUIDE_ACTIVE;
- pGuides[iGuide].iPeakChosen = -1;
- }
- }
+ int iGuide, iCurrentPeak = -1, iGoodPeak = -1;
+ sfloat fFund = pAnalParams->ppFrames[iFrame]->fFundamental,
+ fFreqDev = fFund * pAnalParams->fFreqDeviation, fCurrentMax = 1000;
+
+ /* update guides with fundamental contribution */
+ if(fFund > 0 && (pAnalParams->iFormat == SMS_FORMAT_H ||
+ pAnalParams->iFormat == SMS_FORMAT_HP))
+ for(iGuide = 0; iGuide < pAnalParams->nGuides; iGuide++)
+ pAnalParams->guides[iGuide].fFreq =
+ (1 - pAnalParams->fFundContToGuide) * pAnalParams->guides[iGuide].fFreq +
+ pAnalParams->fFundContToGuide * fFund * (iGuide + 1);
+
+ if(pAnalParams->iDebugMode == SMS_DBG_PEAK_CONT ||
+ pAnalParams->iDebugMode == SMS_DBG_ALL)
+ fprintf(stdout, "Frame %d Peak Continuation: \n",
+ pAnalParams->ppFrames[iFrame]->iFrameNum);
+
+ /* continue all guides */
+ for(iGuide = 0; iGuide < pAnalParams->nGuides; iGuide++)
+ {
+ sfloat fPreviousFreq = pAnalParams->ppFrames[iFrame-1]->deterministic.pFSinFreq[iGuide];
+
+ /* get the guide value by upgrading the previous guide */
+ if(fPreviousFreq > 0)
+ pAnalParams->guides[iGuide].fFreq =
+ (1 - pAnalParams->fPeakContToGuide) * pAnalParams->guides[iGuide].fFreq +
+ pAnalParams->fPeakContToGuide * fPreviousFreq;
+
+ if(pAnalParams->iDebugMode == SMS_DBG_PEAK_CONT ||
+ pAnalParams->iDebugMode == SMS_DBG_ALL)
+ fprintf(stdout, "Guide %d: freq %f, mag %f\n",
+ iGuide, pAnalParams->guides[iGuide].fFreq, pAnalParams->guides[iGuide].fMag);
+
+ if(pAnalParams->guides[iGuide].fFreq <= 0.0 ||
+ pAnalParams->guides[iGuide].fFreq > pAnalParams->fHighestFreq)
+ {
+ pAnalParams->guides[iGuide].iStatus = GUIDE_DEAD;
+ pAnalParams->guides[iGuide].fFreq = 0;
+ continue;
+ }
+
+ pAnalParams->guides[iGuide].iPeakChosen = -1;
+
+ if(pAnalParams->iFormat == SMS_FORMAT_IH ||
+ pAnalParams->iFormat == SMS_FORMAT_IHP)
+ fFreqDev = pAnalParams->guides[iGuide].fFreq * pAnalParams->fFreqDeviation;
+
+ /* get the best peak for the guide */
+ iGoodPeak =
+ GetBestPeak(pAnalParams->guides, iGuide, pAnalParams->ppFrames[iFrame]->pSpectralPeaks,
+ pAnalParams, fFreqDev);
+ }
+
+ /* try to find good peaks for the GUIDE_DEAD guides */
+ if(pAnalParams->iFormat == SMS_FORMAT_IH ||
+ pAnalParams->iFormat == SMS_FORMAT_IHP)
+ for(iGuide = 0; iGuide < pAnalParams->nGuides; iGuide++)
+ {
+ if(pAnalParams->guides[iGuide].iStatus != GUIDE_DEAD)
+ continue;
+
+ if(GetStartingPeak(iGuide, pAnalParams->guides, pAnalParams->nGuides,
+ pAnalParams->ppFrames[iFrame]->pSpectralPeaks,
+ &fCurrentMax) == -1)
+ break;
+ }
+
+ /* save all the continuation values,
+ * assume output tracks are already clear */
+ for(iGuide = 0; iGuide < pAnalParams->nGuides; iGuide++)
+ {
+ if(pAnalParams->guides[iGuide].iStatus == GUIDE_DEAD)
+ continue;
+
+ if(pAnalParams->iFormat == SMS_FORMAT_IH ||
+ pAnalParams->iFormat == SMS_FORMAT_IHP)
+ {
+ if(pAnalParams->guides[iGuide].iStatus > 0 &&
+ pAnalParams->guides[iGuide].iPeakChosen == -1)
+ {
+ if(pAnalParams->guides[iGuide].iStatus++ > pAnalParams->iMaxSleepingTime)
+ {
+ pAnalParams->guides[iGuide].iStatus = GUIDE_DEAD;
+ pAnalParams->guides[iGuide].fFreq = 0;
+ pAnalParams->guides[iGuide].fMag = 0;
+ pAnalParams->guides[iGuide].iPeakChosen = -1;
+ }
+ else
+ pAnalParams->guides[iGuide].iStatus++;
+ continue;
+ }
+
+ if(pAnalParams->guides[iGuide].iStatus == GUIDE_ACTIVE &&
+ pAnalParams->guides[iGuide].iPeakChosen == -1)
+ {
+ pAnalParams->guides[iGuide].iStatus = 1;
+ continue;
+ }
+ }
+
+ /* if good continuation peak found, save it */
+ if((iCurrentPeak = pAnalParams->guides[iGuide].iPeakChosen) >= 0)
+ {
+ pAnalParams->ppFrames[iFrame]->deterministic.pFSinFreq[iGuide] =
+ pAnalParams->ppFrames[iFrame]->pSpectralPeaks[iCurrentPeak].fFreq;
+ pAnalParams->ppFrames[iFrame]->deterministic.pFSinAmp[iGuide] =
+ pAnalParams->ppFrames[iFrame]->pSpectralPeaks[iCurrentPeak].fMag;
+ pAnalParams->ppFrames[iFrame]->deterministic.pFSinPha[iGuide] =
+ pAnalParams->ppFrames[iFrame]->pSpectralPeaks[iCurrentPeak].fPhase;
+
+ pAnalParams->guides[iGuide].iStatus = GUIDE_ACTIVE;
+ pAnalParams->guides[iGuide].iPeakChosen = -1;
+ }
+ }
return SMS_OK;
}
+
diff --git a/sms/peakDetection.c b/sms/peakDetection.c
index 1bbe713..fc40e69 100644
--- a/sms/peakDetection.c
+++ b/sms/peakDetection.c
@@ -165,31 +165,20 @@ static sfloat GetPhaseVal (sfloat *pPhaseSpectrum, sfloat fPeakLoc)
int sms_detectPeaks(int sizeSpec, sfloat *pMag, sfloat *pPhase,
SMS_Peak *pSpectralPeaks, SMS_AnalParams *pAnalParams)
{
- static int iFirstBin, iHighestBin, sizeFft;
- static sfloat fInvSizeFft;
- static int sizeSpecStatic = 0;
-
- /* allocate memory if sizeSpec has changed or this is the first run */
- if(sizeSpecStatic != sizeSpec)
- {
- sizeSpecStatic = sizeSpec;
- sizeFft = sizeSpec << 1;
- fInvSizeFft = 1.0 / sizeFft;
- /* make sure to start on the 2nd bin so interpolation is possible QUESTION: why not allow a peak in bin 1 or 0? */
- /* rte: changed the first argument of MAX from 2 to 1 */
- iFirstBin = MAX(1, sizeFft * pAnalParams->fLowestFreq / pAnalParams->iSamplingRate);
- iHighestBin = MIN(sizeSpec-1, sizeFft * pAnalParams->fHighestFreq / pAnalParams->iSamplingRate);
- }
+ int sizeFft = sizeSpec << 1;
+ sfloat fInvSizeFft = 1.0 / sizeFft;
+ int iFirstBin = MAX(1, sizeFft * pAnalParams->fLowestFreq / pAnalParams->iSamplingRate);
+ int iHighestBin = MIN(sizeSpec-1, sizeFft * pAnalParams->fHighestFreq / pAnalParams->iSamplingRate);
/* clear peak structure */
memset(pSpectralPeaks, 0, pAnalParams->maxPeaks * sizeof(SMS_Peak));
/* set starting search values */
int iCurrentLoc = iFirstBin;
- int iPeak = 0; /* index for spectral search */
- sfloat fPeakMag = 0.0; /* magnitude of peak */
- sfloat fPeakLoc = 0.0; /* location of peak */
-
+ int iPeak = 0; /* index for spectral search */
+ sfloat fPeakMag = 0.0; /* magnitude of peak */
+ sfloat fPeakLoc = 0.0; /* location of peak */
+
/* find peaks */
while((iPeak < pAnalParams->maxPeaks) &&
(FindNextPeak(pMag, iHighestBin, &iCurrentLoc, &fPeakMag,
diff --git a/sms/residual.c b/sms/residual.c
index a9237dc..b69a28f 100644
--- a/sms/residual.c
+++ b/sms/residual.c
@@ -32,109 +32,45 @@
* \param pResidual pointer to output residual waveform
* \param pWindow pointer to windowing array
* \return residual percentage (0 if residual was not large enough)
- \todo why is residual energy percentage computed this way? should be optional and in a seperate function
+ \todo why is residual energy percentage computed this way? should be optional and in a seperate function
*/
-int sms_residual (int sizeWindow, sfloat *pSynthesis, sfloat *pOriginal, sfloat *pResidual)
+int sms_residual(int sizeWindow, sfloat *pSynthesis, sfloat *pOriginal, sfloat *pResidual, sfloat *pWindow)
{
- static sfloat fResidualMag = 0.;
+ static sfloat fResidualMag = 0.;
static sfloat fOriginalMag = 0.;
- sfloat fScale = 1.;
- sfloat fCurrentResidualMag = 0.;
- sfloat fCurrentOriginalMag = 0.;
- int i;
-
- /* get residual */
- for (i=0; i<sizeWindow; i++)
- {
- pResidual[i] = pOriginal[i] - pSynthesis[i];
- }
+ sfloat fScale = 1.;
+ sfloat fCurrentResidualMag = 0.;
+ sfloat fCurrentOriginalMag = 0.;
+ int i;
- /* get energy of residual */
- for (i=0; i<sizeWindow; i++)
- {
- fCurrentResidualMag += (pResidual[i] * pResidual[i]);
- }
+ /* get residual */
+ for (i=0; i<sizeWindow; i++)
+ pResidual[i] = pOriginal[i] - pSynthesis[i];
- /* if residual is big enough compute coefficients */
- if (fCurrentResidualMag) //always compute
- {
- /* get energy of original */
- for (i=0; i<sizeWindow; i++)
- {
- fCurrentOriginalMag += (pOriginal[i] * pOriginal[i]);
- }
- fOriginalMag = .5 * (fCurrentOriginalMag/sizeWindow + fOriginalMag);
- fResidualMag = .5 * (fCurrentResidualMag/sizeWindow + fResidualMag);
+ /* get energy of residual */
+ for (i=0; i<sizeWindow; i++)
+ fCurrentResidualMag += (pResidual[i] * pResidual[i]);
- /* scale residual if need to be */
- if (fResidualMag > fOriginalMag)
- {
- fScale = fOriginalMag / fResidualMag;
- for (i=0; i<sizeWindow; i++)
- {
- pResidual[i] *= fScale;
- }
- }
+ /* if residual is big enough compute coefficients */
+ if (fCurrentResidualMag)
+ {
+ /* get energy of original */
+ for (i=0; i<sizeWindow; i++)
+ fCurrentOriginalMag += (pOriginal[i] * pOriginal[i]);
- return fCurrentResidualMag / fCurrentOriginalMag;
- }
- return 0;
-}
-
-/*! \brief get the residual waveform
- *
- * \param sizeWindow size of buffers
- * \param pSynthesis pointer to deterministic component
- * \param pOriginal pointer to original waveform
- * \param pResidual pointer to output residual waveform
- * \param pWindow pointer to windowing array
- * \return residual percentage
- \todo why is residual energy percentage computed this way? should be optional and in a seperate function
- */
-int sms_residualOLD ( int sizeWindow, sfloat *pSynthesis, sfloat *pOriginal, sfloat *pResidual, sfloat *pWindow)
-{
- static sfloat fResidualMag = 0, fOriginalMag = 0, *pFWindow = NULL;
- sfloat fScale = 1, fCurrentResidualMag = 0, fCurrentOriginalMag = 0;
- int i;
-
- /* get residual */
- for (i=0; i<sizeWindow; i++)
- pResidual[i] = pOriginal[i] - pSynthesis[i];
+ fOriginalMag = .5 * (fCurrentOriginalMag/sizeWindow + fOriginalMag);
+ fResidualMag = .5 * (fCurrentResidualMag/sizeWindow + fResidualMag);
- /* get energy of residual */
- for (i=0; i<sizeWindow; i++)
- fCurrentResidualMag += fabsf( pResidual[i] * pWindow[i]);
+ /* scale residual if need to be */
+ if (fResidualMag > fOriginalMag)
+ {
+ fScale = fOriginalMag / fResidualMag;
+ for (i=0; i<sizeWindow; i++)
+ pResidual[i] *= fScale;
+ }
- /* if residual is big enough compute coefficients */
-// if (fCurrentResidualMag/sizeWindow > .01)
- if (fCurrentResidualMag) //always compute
- {
-/* printf(" fCurrentResidualMag: %f, sizeWindow: %d, ratio: %f\n", */
-/* fCurrentResidualMag, sizeWindow, fCurrentResidualMag/sizeWindow ); */
-
- /* get energy of original */
- for (i=0; i<sizeWindow; i++)
- fCurrentOriginalMag += fabs( pOriginal[i] * pWindow[i]);
-
- fOriginalMag =
- .5 * (fCurrentOriginalMag/sizeWindow + fOriginalMag);
- fResidualMag =
- .5 * (fCurrentResidualMag/sizeWindow + fResidualMag);
-
- /* scale residual if need to be */
- if (fResidualMag > fOriginalMag)
- {
- fScale = fOriginalMag / fResidualMag;
- for (i=0; i<sizeWindow; i++)
- pResidual[i] *= fScale;
- }
-
- printf("risidual mag: %f, original mag: %f \n", fCurrentResidualMag , fCurrentOriginalMag);
- return (fCurrentResidualMag / fCurrentOriginalMag);
- }
- else printf("whaaaat not big enough: fCurrentResidualMag: %f, sizeWindow: %d, ratio: %f\n",
- fCurrentResidualMag, sizeWindow, fCurrentResidualMag/sizeWindow );
-
- return (0);
+ return fCurrentResidualMag / fCurrentOriginalMag;
+ }
+ return 0;
}
diff --git a/sms/sineSynth.c b/sms/sineSynth.c
index 58768bd..f2110af 100644
--- a/sms/sineSynth.c
+++ b/sms/sineSynth.c
@@ -32,163 +32,165 @@
* \param fMag current magnitude
* \param fPhase current phase
* \param pLastFrame stucture with values from last frame
- * \param pFWaveform pointer to output waveform
- * \param sizeBuffer size of the synthesis buffer
+ * \param pFWaveform pointer to output waveform
+ * \param sizeBuffer size of the synthesis buffer
* \param iTrack current track
*/
-static void SinePhaSynth (sfloat fFreq, sfloat fMag, sfloat fPhase,
- SMS_Data *pLastFrame, sfloat *pFWaveform,
- int sizeBuffer, int iTrack)
+static void SinePhaSynth(sfloat fFreq, sfloat fMag, sfloat fPhase,
+ SMS_Data *pLastFrame, sfloat *pFWaveform,
+ int sizeBuffer, int iTrack)
{
- sfloat fMagIncr, fInstMag, fInstPhase, fTmp;
- int iM, i;
- sfloat fAlpha, fBeta, fTmp1, fTmp2;
+ sfloat fMagIncr, fInstMag, fInstPhase, fTmp;
+ int iM, i;
+ sfloat fAlpha, fBeta, fTmp1, fTmp2;
- /* if no mag in last frame copy freq from current and make phase */
- if (pLastFrame->pFSinAmp[iTrack] <= 0)
- {
- pLastFrame->pFSinFreq[iTrack] = fFreq;
- fTmp = fPhase - (fFreq * sizeBuffer);
- pLastFrame->pFSinPha[iTrack] = fTmp - floor(fTmp / TWO_PI) * TWO_PI;
- }
- /* and the other way */
- else if (fMag <= 0)
- {
- fFreq = pLastFrame->pFSinFreq[iTrack];
- fTmp = pLastFrame->pFSinPha[iTrack] +
+ /* if no mag in last frame copy freq from current and make phase */
+ if (pLastFrame->pFSinAmp[iTrack] <= 0)
+ {
+ pLastFrame->pFSinFreq[iTrack] = fFreq;
+ fTmp = fPhase - (fFreq * sizeBuffer);
+ pLastFrame->pFSinPha[iTrack] = fTmp - floor(fTmp / TWO_PI) * TWO_PI;
+ }
+ /* and the other way */
+ else if (fMag <= 0)
+ {
+ fFreq = pLastFrame->pFSinFreq[iTrack];
+ fTmp = pLastFrame->pFSinPha[iTrack] +
(pLastFrame->pFSinFreq[iTrack] * sizeBuffer);
- fPhase = fTmp - floor(fTmp / TWO_PI) * TWO_PI;
- }
-
- /* caculate the instantaneous amplitude */
- fMagIncr = (fMag - pLastFrame->pFSinAmp[iTrack]) / sizeBuffer;
- fInstMag = pLastFrame->pFSinAmp[iTrack];
-
- /* create instantaneous phase from freq. and phase values */
- fTmp1 = fFreq - pLastFrame->pFSinFreq[iTrack];
- fTmp2 = ((pLastFrame->pFSinPha[iTrack] +
- pLastFrame->pFSinFreq[iTrack] * sizeBuffer - fPhase) +
- fTmp1 * sizeBuffer / 2.0) / TWO_PI;
- iM = (int) (fTmp2 + .5);
- fTmp2 = fPhase - pLastFrame->pFSinPha[iTrack] -
- pLastFrame->pFSinFreq[iTrack] * sizeBuffer +
- TWO_PI * iM;
- fAlpha = (3.0 / (sfloat)(sizeBuffer * sizeBuffer)) *
- fTmp2 - fTmp1 / sizeBuffer;
- fBeta = (-2.0 / ((sfloat) (sizeBuffer * sizeBuffer * sizeBuffer))) *
- fTmp2 + fTmp1 / ((sfloat) (sizeBuffer * sizeBuffer));
-
- for(i=0; i<sizeBuffer; i++)
- {
- fInstMag += fMagIncr;
- fInstPhase = pLastFrame->pFSinPha[iTrack] +
- pLastFrame->pFSinFreq[iTrack] * i +
- fAlpha * i * i + fBeta * i * i * i;
-
-/* pFWaveform[i] += sms_dBToMag(fInstMag) * sms_sine(fInstPhase + PI_2); */
- pFWaveform[i] += sms_dBToMag(fInstMag) * sinf(fInstPhase + PI_2);
- }
- /* save current values into buffer */
- pLastFrame->pFSinFreq[iTrack] = fFreq;
- pLastFrame->pFSinAmp[iTrack] = fMag;
- pLastFrame->pFSinPha[iTrack] = fPhase;
+ fPhase = fTmp - floor(fTmp / TWO_PI) * TWO_PI;
+ }
+
+ /* caculate the instantaneous amplitude */
+ fMagIncr = (fMag - pLastFrame->pFSinAmp[iTrack]) / sizeBuffer;
+ fInstMag = pLastFrame->pFSinAmp[iTrack];
+
+ /* create instantaneous phase from freq. and phase values */
+ fTmp1 = fFreq - pLastFrame->pFSinFreq[iTrack];
+ fTmp2 = ((pLastFrame->pFSinPha[iTrack] +
+ pLastFrame->pFSinFreq[iTrack] * sizeBuffer - fPhase) +
+ fTmp1 * sizeBuffer / 2.0) / TWO_PI;
+ iM = (int) (fTmp2 + .5);
+ fTmp2 = fPhase - pLastFrame->pFSinPha[iTrack] -
+ pLastFrame->pFSinFreq[iTrack] * sizeBuffer +
+ TWO_PI * iM;
+ fAlpha = (3.0 / (sfloat)(sizeBuffer * sizeBuffer)) *
+ fTmp2 - fTmp1 / sizeBuffer;
+ fBeta = (-2.0 / ((sfloat) (sizeBuffer * sizeBuffer * sizeBuffer))) *
+ fTmp2 + fTmp1 / ((sfloat) (sizeBuffer * sizeBuffer));
+
+ for(i=0; i<sizeBuffer; i++)
+ {
+ fInstMag += fMagIncr;
+ fInstPhase = pLastFrame->pFSinPha[iTrack] +
+ pLastFrame->pFSinFreq[iTrack] * i +
+ fAlpha * i * i + fBeta * i * i * i;
+
+ /* pFWaveform[i] += sms_dBToMag(fInstMag) * sms_sine(fInstPhase + PI_2); */
+ pFWaveform[i] += sms_dBToMag(fInstMag) * sinf(fInstPhase + PI_2);
+ }
+ /* save current values into buffer */
+ pLastFrame->pFSinFreq[iTrack] = fFreq;
+ pLastFrame->pFSinAmp[iTrack] = fMag;
+ pLastFrame->pFSinPha[iTrack] = fPhase;
}
/*! \brief generate a sinusoid given two frames, current and last
*
- * \param fFreq current frequency
+ * \param fFreq current frequency
* \param fMag current magnitude
* \param pLastFrame stucture with values from last frame
- * \param pFBuffer pointer to output waveform
- * \param sizeBuffer size of the synthesis buffer
+ * \param pFBuffer pointer to output waveform
+ * \param sizeBuffer size of the synthesis buffer
* \param iTrack current track
*/
-static void SineSynth (sfloat fFreq, sfloat fMag, SMS_Data *pLastFrame,
- sfloat *pFBuffer, int sizeBuffer, int iTrack)
+static void SineSynth(sfloat fFreq, sfloat fMag, SMS_Data *pLastFrame,
+ sfloat *pFBuffer, int sizeBuffer, int iTrack)
{
- sfloat fMagIncr, fInstMag, fFreqIncr, fInstPhase, fInstFreq;
- int i;
-
- /* if no mag in last frame copy freq from current */
- if (pLastFrame->pFSinAmp[iTrack] <= 0)
- {
+ sfloat fMagIncr, fInstMag, fFreqIncr, fInstPhase, fInstFreq;
+ int i;
+
+ /* if no mag in last frame copy freq from current */
+ if (pLastFrame->pFSinAmp[iTrack] <= 0)
+ {
+ pLastFrame->pFSinFreq[iTrack] = fFreq;
+ pLastFrame->pFSinPha[iTrack] =
+ TWO_PI * sms_random();
+ }
+ /* and the other way */
+ else if (fMag <= 0)
+ fFreq = pLastFrame->pFSinFreq[iTrack];
+
+ /* calculate the instantaneous amplitude */
+ fMagIncr = (fMag - pLastFrame->pFSinAmp[iTrack]) / sizeBuffer;
+ fInstMag = pLastFrame->pFSinAmp[iTrack];
+ /* calculate instantaneous frequency */
+ fFreqIncr = (fFreq - pLastFrame->pFSinFreq[iTrack]) / sizeBuffer;
+ fInstFreq = pLastFrame->pFSinFreq[iTrack];
+ fInstPhase = pLastFrame->pFSinPha[iTrack];
+
+ /* generate all the samples */
+ for (i = 0; i < sizeBuffer; i++)
+ {
+ fInstMag += fMagIncr;
+ fInstFreq += fFreqIncr;
+ fInstPhase += fInstFreq;
+
+ pFBuffer[i] += sms_dBToMag(fInstMag) * sms_sine(fInstPhase);
+ }
+
+ /* save current values into last values */
pLastFrame->pFSinFreq[iTrack] = fFreq;
- pLastFrame->pFSinPha[iTrack] =
- TWO_PI * sms_random();
- }
- /* and the other way */
- else if (fMag <= 0)
- fFreq = pLastFrame->pFSinFreq[iTrack];
-
- /* calculate the instantaneous amplitude */
- fMagIncr = (fMag - pLastFrame->pFSinAmp[iTrack]) / sizeBuffer;
- fInstMag = pLastFrame->pFSinAmp[iTrack];
- /* calculate instantaneous frequency */
- fFreqIncr = (fFreq - pLastFrame->pFSinFreq[iTrack]) / sizeBuffer;
- fInstFreq = pLastFrame->pFSinFreq[iTrack];
- fInstPhase = pLastFrame->pFSinPha[iTrack];
-
- /* generate all the samples */
- for (i = 0; i < sizeBuffer; i++)
- {
- fInstMag += fMagIncr;
- fInstFreq += fFreqIncr;
- fInstPhase += fInstFreq;
-
- pFBuffer[i] += sms_dBToMag (fInstMag) * sms_sine (fInstPhase);
- }
-
- /* save current values into last values */
- pLastFrame->pFSinFreq[iTrack] = fFreq;
- pLastFrame->pFSinAmp[iTrack] = fMag;
- pLastFrame->pFSinPha[iTrack] = fInstPhase -
- floor(fInstPhase / TWO_PI) * TWO_PI;
+ pLastFrame->pFSinAmp[iTrack] = fMag;
+ pLastFrame->pFSinPha[iTrack] = fInstPhase -
+ floor(fInstPhase / TWO_PI) * TWO_PI;
}
/*! \brief generate all the sinusoids for a given frame
*
* \param pSmsData SMS data for current frame
- * \param pFBuffer pointer to output waveform
+ * \param pFBuffer pointer to output waveform
* \param sizeBuffer size of the synthesis buffer
* \param pLastFrame SMS data from last frame
* \param iSamplingRate sampling rate to synthesize for
*/
-void sms_sineSynthFrame (SMS_Data *pSmsData, sfloat *pFBuffer,
- int sizeBuffer, SMS_Data *pLastFrame, int iSamplingRate)
+void sms_sineSynthFrame(SMS_Data *pSmsData, sfloat *pFBuffer,
+ int sizeBuffer, SMS_Data *pLastFrame,
+ int iSamplingRate)
{
- sfloat fMag, fFreq;
- int i;
- int nTracks = pSmsData->nTracks;
- int iHalfSamplingRate = iSamplingRate >> 1;
-
- /* go through all the tracks */
- for (i = 0; i < nTracks; i++)
- {
- /* get magnitude */
- fMag = pSmsData->pFSinAmp[i];
-
- fFreq = pSmsData->pFSinFreq[i];
-
- /* gaurd so transposed frequencies don't alias */
- if (fFreq > iHalfSamplingRate || fFreq < 0)
- fMag = 0;
-
- /* generate sines if there are magnitude values */
- if ((fMag > 0) || (pLastFrame->pFSinAmp[i] > 0))
- {
- /* frequency from Hz to radians */
- fFreq = (fFreq == 0) ? 0 : TWO_PI * fFreq / iSamplingRate;
-
- /* \todo make seperate function for SineSynth /wo phase */
- if (pSmsData->pFSinPha == NULL)
- {
- SineSynth(fFreq, fMag, pLastFrame, pFBuffer, sizeBuffer, i);
- }
- else
- {
- SinePhaSynth(fFreq, fMag, pSmsData->pFSinPha[i], pLastFrame,
- pFBuffer, sizeBuffer, i);
- }
- }
+ sfloat fMag, fFreq;
+ int i;
+ int nTracks = pSmsData->nTracks;
+ int iHalfSamplingRate = iSamplingRate >> 1;
+
+ /* go through all the tracks */
+ for (i = 0; i < nTracks; i++)
+ {
+ /* get magnitude */
+ fMag = pSmsData->pFSinAmp[i];
+
+ fFreq = pSmsData->pFSinFreq[i];
+
+ /* gaurd so transposed frequencies don't alias */
+ if (fFreq > iHalfSamplingRate || fFreq < 0)
+ fMag = 0;
+
+ /* generate sines if there are magnitude values */
+ if ((fMag > 0) || (pLastFrame->pFSinAmp[i] > 0))
+ {
+ /* frequency from Hz to radians */
+ fFreq = (fFreq == 0) ? 0 : TWO_PI * fFreq / iSamplingRate;
+
+ /* \todo make seperate function for SineSynth /wo phase */
+ if (pSmsData->pFSinPha == NULL)
+ {
+ SineSynth(fFreq, fMag, pLastFrame, pFBuffer, sizeBuffer, i);
+ }
+ else
+ {
+ SinePhaSynth(fFreq, fMag, pSmsData->pFSinPha[i], pLastFrame,
+ pFBuffer, sizeBuffer, i);
+ }
}
+ }
}
+
diff --git a/sms/sms.c b/sms/sms.c
index 6d29e53..f9e2e95 100644
--- a/sms/sms.c
+++ b/sms/sms.c
@@ -35,7 +35,6 @@ static sfloat inv_mag_thresh = 100000.; /*!< inv(.00001) */
static int initIsDone = 0; /* \todo is this variable necessary? */
#define SIZE_TABLES 4096
-
#define HALF_MAX 1073741823.5 /*!< half the max of a 32-bit word */
#define INV_HALF_MAX (1.0 / HALF_MAX)
#define TWENTY_OVER_LOG10 (20. / LOG10)
@@ -50,36 +49,35 @@ static int initIsDone = 0; /* \todo is this variable necessary? */
*
* \return error code \see SMS_MALLOC or SMS_OK in SMS_ERRORS
*/
-int sms_init( void )
+int sms_init(void)
{
- int iError;
if (!initIsDone)
{
initIsDone = 1;
- if(sms_prepSine (SIZE_TABLES))
+ if(sms_prepSine(SIZE_TABLES))
{
sms_error("cannot allocate memory for sine table");
- return (-1);
+ return -1;
}
- if(sms_prepSinc (SIZE_TABLES))
+ if(sms_prepSinc(SIZE_TABLES))
{
sms_error("cannot allocate memory for sinc table");
- return (-1);
+ return -1;
}
- }
#ifdef MERSENNE_TWISTER
- init_gen_rand(1234);
+ init_gen_rand(1234);
#endif
+ }
- return (0);
+ return 0;
}
/*! \brief free global data
*
* deallocates memory allocated to global arrays (windows and tables)
*/
-void sms_free( void )
+void sms_free()
{
initIsDone = 0;
sms_clearSine();
@@ -101,6 +99,7 @@ void sms_free( void )
*/
void sms_initAnalParams(SMS_AnalParams *pAnalParams)
{
+ int i;
pAnalParams->iDebugMode = 0;
pAnalParams->iFormat = SMS_FORMAT_H;
pAnalParams->iSoundType = SMS_SOUND_TYPE_MELODY;
@@ -141,8 +140,6 @@ void sms_initAnalParams(SMS_AnalParams *pAnalParams)
(pAnalParams->minGoodFrames + pAnalParams->analDelay);
pAnalParams->fResidualAccumPerc = 0.;
pAnalParams->preEmphasisLastValue = 0.;
- pAnalParams->resetGuides = 1;
- pAnalParams->resetGuideStates = 1;
/* spectral envelope params */
pAnalParams->specEnvParams.iType = SMS_ENV_NONE; /* turn off enveloping */
pAnalParams->specEnvParams.iOrder = 25; /* ... but set default params anyway */
@@ -150,6 +147,33 @@ void sms_initAnalParams(SMS_AnalParams *pAnalParams)
pAnalParams->specEnvParams.iMaxFreq = 0;
pAnalParams->specEnvParams.nCoeff = 0;
pAnalParams->specEnvParams.iAnchor = 0; /* not yet implemented */
+ pAnalParams->pFrames = NULL;
+ /* fft */
+ for(i = 0; i < SMS_MAX_SPEC; i++)
+ {
+ pAnalParams->magSpectrum[i] = 0.0;
+ pAnalParams->phaseSpectrum[i] = 0.0;
+ pAnalParams->spectrumWindow[i] = 0.0;
+ pAnalParams->fftBuffer[i] = 0.0;
+ pAnalParams->fftBuffer[i+SMS_MAX_SPEC] = 0.0;
+ }
+ /* analysis frames */
+ pAnalParams->pFrames = NULL;
+ pAnalParams->ppFrames = NULL;
+ /* residual */
+ pAnalParams->sizeResidual = pAnalParams->sizeHop * 2;
+ pAnalParams->residual = NULL;
+ pAnalParams->residualWindow = NULL;
+ /* peak continuation */
+ pAnalParams->guideStates = NULL;
+ pAnalParams->guides = NULL;
+ /* audio input frame */
+ for(i = 0; i < SMS_MAX_FRAME_SIZE; i++)
+ pAnalParams->inputBuffer[i] = 0.0;
+ /* stochastic analysis */
+ pAnalParams->stocMagSpectrum = NULL;
+ pAnalParams->approxEnvelope = NULL;
+ pAnalParams->ppFrames = NULL;
}
/*! \brief initialize analysis data structure's arrays
@@ -170,16 +194,12 @@ int sms_initAnalysis(SMS_AnalParams *pAnalParams)
/* define the hopsize for each record */
pAnalParams->sizeHop = (int)(pAnalParams->iSamplingRate /
- (sfloat) pAnalParams->iFrameRate);
-
- /* define the number of frames and number of samples */
- // pAnalParams->nFrames = pSoundHeader->nSamples / (sfloat) pAnalParams->sizeHop;
- // pAnalParams->iSizeSound = pSoundHeader->nSamples;
+ (sfloat) pAnalParams->iFrameRate);
/* set the default size window to an odd length */
pAnalParams->iDefaultSizeWindow =
(int)((pAnalParams->iSamplingRate / pAnalParams->fDefaultFundamental) *
- pAnalParams->fSizeWindow / 2) * 2 + 1;
+ pAnalParams->fSizeWindow / 2) * 2 + 1;
int sizeBuffer = (pAnalParams->iMaxDelayFrames * pAnalParams->sizeHop) + SMS_MAX_WINDOW;
@@ -197,16 +217,16 @@ int sms_initAnalysis(SMS_AnalParams *pAnalParams)
pAnalParams->specEnvParams.iMaxFreq = pAnalParams->fHighestFreq;
/*\todo this probably doesn't need env coefficients - they aren't getting used */
- sms_allocFrame (&pAnalParams->prevFrame, pAnalParams->nGuides,
- pAnalParams->nStochasticCoeff, 1, pAnalParams->iStochasticType, 0);
+ sms_allocFrame(&pAnalParams->prevFrame, pAnalParams->nGuides,
+ pAnalParams->nStochasticCoeff, 1, pAnalParams->iStochasticType, 0);
- pAnalParams->sizeNextRead = (pAnalParams->iDefaultSizeWindow + 1) * 0.5; /* \todo REMOVE THIS from other files first */
+ pAnalParams->sizeNextRead = (pAnalParams->iDefaultSizeWindow + 1) * 0.5;
/* sound buffer */
if ((pSoundBuf->pFBuffer = (sfloat *) calloc(sizeBuffer, sizeof(sfloat))) == NULL)
{
sms_error("could not allocate memory");
- return(-1);
+ return -1;
}
pSoundBuf->iMarker = -sizeBuffer;
pSoundBuf->iFirstGood = sizeBuffer;
@@ -222,74 +242,179 @@ int sms_initAnalysis(SMS_AnalParams *pAnalParams)
pAnalParams->fDefaultFundamental = pAnalParams->fHighestFundamental;
}
- /* initialize peak detection/continuation parameters */
- /*pAnalParams->peakParams.fLowestFreq = pAnalParams->fLowestFundamental;*/
- /*pAnalParams->peakParams.fHighestFreq = pAnalParams->fHighestFreq;*/
- /*pAnalParams->peakParams.fMinPeakMag = pAnalParams->fMinPeakMag;*/
- /*pAnalParams->peakParams.iSamplingRate = pAnalParams->iSamplingRate;*/
- /*pAnalParams->peakParams.iMaxPeaks = SMS_MAX_NPEAKS;*/
- /*pAnalParams->peakParams.fHighestFundamental = pAnalParams->fHighestFundamental;*/
- /*pAnalParams->peakParams.iRefHarmonic = pAnalParams->iRefHarmonic;*/
- /*pAnalParams->peakParams.fMinRefHarmMag = pAnalParams->fMinRefHarmMag;*/
- /*pAnalParams->peakParams.fRefHarmMagDiffFromMax = pAnalParams->fRefHarmMagDiffFromMax;*/
- /*pAnalParams->peakParams.iSoundType = pAnalParams->iSoundType;*/
-
/* deterministic synthesis buffer */
pSynthBuf->sizeBuffer = pAnalParams->sizeHop << 1;
- if((pSynthBuf->pFBuffer = (sfloat *)calloc(pSynthBuf->sizeBuffer, sizeof(sfloat))) == NULL)
+ pSynthBuf->pFBuffer = calloc(pSynthBuf->sizeBuffer, sizeof(sfloat));
+ if(pSynthBuf->pFBuffer == NULL)
{
sms_error("could not allocate memory");
- return(-1);
+ return -1;
}
- pSynthBuf->iMarker = -sizeBuffer;
pSynthBuf->iMarker = pSynthBuf->sizeBuffer;
-
/* buffer of analysis frames */
- if ((pAnalParams->pFrames = (SMS_AnalFrame *) calloc(pAnalParams->iMaxDelayFrames, sizeof(SMS_AnalFrame))) == NULL)
+ pAnalParams->pFrames = (SMS_AnalFrame *)malloc(pAnalParams->iMaxDelayFrames * sizeof(SMS_AnalFrame));
+ if(pAnalParams->pFrames == NULL)
{
sms_error("could not allocate memory for delay frames");
- return(-1);
+ return -1;
}
- if ((pAnalParams->ppFrames =
- (SMS_AnalFrame **) calloc(pAnalParams->iMaxDelayFrames, sizeof(SMS_AnalFrame *))) == NULL)
+ pAnalParams->ppFrames = (SMS_AnalFrame **)malloc(pAnalParams->iMaxDelayFrames * sizeof(SMS_AnalFrame *));
+ if(pAnalParams->ppFrames == NULL)
{
sms_error("could not allocate memory for pointers to delay frames");
- return(-1);
+ return -1;
}
/* initialize the frame pointers and allocate memory */
- for (i = 0; i < pAnalParams->iMaxDelayFrames; i++)
+ for(i = 0; i < pAnalParams->iMaxDelayFrames; i++)
{
pAnalParams->pFrames[i].iStatus = SMS_FRAME_EMPTY;
- if (((pAnalParams->pFrames[i]).pSpectralPeaks =
- (SMS_Peak *)calloc (pAnalParams->maxPeaks, sizeof(SMS_Peak))) == NULL)
+ pAnalParams->pFrames[i].iFrameSample = 0;
+ pAnalParams->pFrames[i].iFrameSize = 0;
+ pAnalParams->pFrames[i].iFrameNum = 0;
+ pAnalParams->pFrames[i].pSpectralPeaks =
+ (SMS_Peak *)malloc(pAnalParams->maxPeaks * sizeof(SMS_Peak));
+ if((pAnalParams->pFrames[i]).pSpectralPeaks == NULL)
{
sms_error("could not allocate memory for spectral peaks");
- return(-1);
+ return -1;
}
(pAnalParams->pFrames[i].deterministic).nTracks = pAnalParams->nGuides;
- if (((pAnalParams->pFrames[i].deterministic).pFSinFreq =
- (sfloat *)calloc (pAnalParams->nGuides, sizeof(sfloat))) == NULL)
+
+ (pAnalParams->pFrames[i].deterministic).pFSinFreq =
+ (sfloat *)calloc(pAnalParams->nGuides, sizeof(sfloat));
+ if((pAnalParams->pFrames[i].deterministic).pFSinFreq == NULL)
{
sms_error("could not allocate memory");
- return(-1);
+ return -1;
}
- if (((pAnalParams->pFrames[i].deterministic).pFSinAmp =
- (sfloat *)calloc (pAnalParams->nGuides, sizeof(sfloat))) == NULL)
+
+ (pAnalParams->pFrames[i].deterministic).pFSinAmp =
+ (sfloat *)calloc(pAnalParams->nGuides, sizeof(sfloat));
+ if((pAnalParams->pFrames[i].deterministic).pFSinAmp == NULL)
{
sms_error("could not allocate memory");
- return(-1);
+ return -1;
}
- if (((pAnalParams->pFrames[i].deterministic).pFSinPha =
- (sfloat *) calloc (pAnalParams->nGuides, sizeof(sfloat))) == NULL)
+
+ (pAnalParams->pFrames[i].deterministic).pFSinPha =
+ (sfloat *)calloc(pAnalParams->nGuides, sizeof(sfloat));
+ if((pAnalParams->pFrames[i].deterministic).pFSinPha == NULL)
{
sms_error("could not allocate memory");
- return(-1);
+ return -1;
}
pAnalParams->ppFrames[i] = &pAnalParams->pFrames[i];
}
+ /* memory for residual */
+ pAnalParams->sizeResidual = pAnalParams->sizeHop * 2;
+ pAnalParams->residual = (sfloat *)calloc(pAnalParams->sizeResidual, sizeof(sfloat));
+ if(pAnalParams->residual == NULL)
+ {
+ sms_error("Could not allocate memory for residual");
+ return -1;
+ }
+ pAnalParams->residualWindow = (sfloat *)calloc(pAnalParams->sizeResidual, sizeof(sfloat));
+ if(pAnalParams->residualWindow == NULL)
+ {
+ sms_error("Could not allocate memory for residualWindow");
+ return -1;
+ }
+ sms_getWindow(pAnalParams->sizeResidual, pAnalParams->residualWindow, SMS_WIN_HAMMING);
+ sms_scaleWindow(pAnalParams->sizeResidual, pAnalParams->residualWindow);
+
+ /* memory for guide states */
+ pAnalParams->guideStates = (int *)calloc(pAnalParams->nGuides, sizeof(int));
+ if(pAnalParams->guideStates == NULL)
+ {
+ sms_error("Could not allocate memory for guide states");
+ return -1;
+ }
+
+ /* memory for guides */
+ pAnalParams->guides = (SMS_Guide *)malloc(pAnalParams->nGuides * sizeof(SMS_Guide));
+ if(pAnalParams->guides == NULL)
+ {
+ sms_error("Could not allocate memory for guides");
+ return -1;
+ }
+ /* initial guide values */
+ if(pAnalParams->iFormat == SMS_FORMAT_H ||
+ pAnalParams->iFormat == SMS_FORMAT_HP)
+ {
+ for (i = 0; i < pAnalParams->nGuides; i++)
+ {
+ pAnalParams->guides[i].fFreq = pAnalParams->fDefaultFundamental * (i + 1);
+ }
+ }
+
+ /* stochastic analysis */
+ pAnalParams->sizeStocMagSpectrum = sms_power2(pAnalParams->sizeResidual) >> 1;
+ pAnalParams->stocMagSpectrum = (sfloat *)calloc(pAnalParams->sizeStocMagSpectrum, sizeof(sfloat));
+ if(pAnalParams->stocMagSpectrum == NULL)
+ {
+ sms_error("Could not allocate memory for stochastic magnitude spectrum");
+ return -1;
+ }
+ pAnalParams->approxEnvelope = (sfloat *)calloc(pAnalParams->nStochasticCoeff, sizeof(sfloat));
+ if(pAnalParams->approxEnvelope == NULL)
+ {
+ sms_error("Could not allocate memory for spectral approximation envelope");
+ return -1;
+ }
+
return 0;
+
+ /*[> buffer of analysis frames <]*/
+ /*pAnalParams->pFrames = (SMS_AnalFrame *) malloc(pAnalParams->iMaxDelayFrames * sizeof(SMS_AnalFrame)); */
+ /*if(pAnalParams->pFrames == NULL)*/
+ /*{*/
+ /* sms_error("could not allocate memory for delay frames");*/
+ /* return -1;*/
+ /*}*/
+
+ /*pAnalParams->ppFrames = (SMS_AnalFrame **) malloc(pAnalParams->iMaxDelayFrames * sizeof(SMS_AnalFrame *));*/
+ /*if(pAnalParams->ppFrames == NULL)*/
+ /*{*/
+ /* sms_error("could not allocate memory for pointers to delay frames");*/
+ /* return -1;*/
+ /*}*/
+
+ /*[> initialize the frame pointers and allocate memory <]*/
+ /*for (i = 0; i < pAnalParams->iMaxDelayFrames; i++)*/
+ /*{*/
+ /* pAnalParams->pFrames[i].iStatus = SMS_FRAME_EMPTY;*/
+ /* pAnalParams->pFrames[i].pSpectralPeaks =*/
+ /* (SMS_Peak *)malloc(pAnalParams->maxPeaks * sizeof(SMS_Peak));*/
+ /* if (pAnalParams->pFrames[i].pSpectralPeaks == NULL)*/
+ /* {*/
+ /* sms_error("could not allocate memory for spectral peaks");*/
+ /* return -1;*/
+ /* }*/
+ /* (pAnalParams->pFrames[i].deterministic).nTracks = pAnalParams->nGuides;*/
+ /* if (((pAnalParams->pFrames[i].deterministic).pFSinFreq =*/
+ /* (sfloat *)calloc (pAnalParams->nGuides, sizeof(sfloat))) == NULL)*/
+ /* {*/
+ /* sms_error("could not allocate memory");*/
+ /* return -1;*/
+ /* }*/
+ /* if (((pAnalParams->pFrames[i].deterministic).pFSinAmp =*/
+ /* (sfloat *)calloc (pAnalParams->nGuides, sizeof(sfloat))) == NULL)*/
+ /* {*/
+ /* sms_error("could not allocate memory");*/
+ /* return -1;*/
+ /* }*/
+ /* if (((pAnalParams->pFrames[i].deterministic).pFSinPha =*/
+ /* (sfloat *) calloc (pAnalParams->nGuides, sizeof(sfloat))) == NULL)*/
+ /* {*/
+ /* sms_error("could not allocate memory");*/
+ /* return -1;*/
+ /* }*/
+ /* pAnalParams->ppFrames[i] = &pAnalParams->pFrames[i];*/
+ /*}*/
+
+ /*return 0;*/
}
void sms_changeHopSize(int hopSize, SMS_AnalParams *pAnalParams)
@@ -297,15 +422,17 @@ void sms_changeHopSize(int hopSize, SMS_AnalParams *pAnalParams)
pAnalParams->sizeHop = hopSize;
pAnalParams->iFrameRate = pAnalParams->iSamplingRate / hopSize;
int sizeBuffer = (pAnalParams->iMaxDelayFrames * pAnalParams->sizeHop) + SMS_MAX_WINDOW;
- SMS_SndBuffer *pSynthBuf = &pAnalParams->synthBuffer;
- SMS_SndBuffer *pSoundBuf = &pAnalParams->soundBuffer;
/* if storing residual phases, restrict number of stochastic coefficients to the size of the spectrum (sizeHop = 1/2 sizeFft)*/
if(pAnalParams->iStochasticType == SMS_STOC_IFFT)
pAnalParams->nStochasticCoeff = sms_power2(pAnalParams->sizeHop);
/* sound buffer */
- if ((pSoundBuf->pFBuffer = (sfloat *) calloc(sizeBuffer, sizeof(sfloat))) == NULL)
+ SMS_SndBuffer *pSoundBuf = &pAnalParams->soundBuffer;
+
+ free(pSoundBuf->pFBuffer);
+ pSoundBuf->pFBuffer = calloc(sizeBuffer, sizeof(sfloat));
+ if(pSoundBuf->pFBuffer == NULL)
{
sms_error("could not allocate memory");
return;
@@ -315,13 +442,16 @@ void sms_changeHopSize(int hopSize, SMS_AnalParams *pAnalParams)
pSoundBuf->sizeBuffer = sizeBuffer;
/* deterministic synthesis buffer */
+ SMS_SndBuffer *pSynthBuf = &pAnalParams->synthBuffer;
pSynthBuf->sizeBuffer = pAnalParams->sizeHop << 1;
- if((pSynthBuf->pFBuffer = (sfloat *)calloc(pSynthBuf->sizeBuffer, sizeof(sfloat))) == NULL)
+
+ free(pSynthBuf->pFBuffer);
+ pSynthBuf->pFBuffer = calloc(sizeBuffer, sizeof(sfloat));
+ if(pSynthBuf->pFBuffer == NULL)
{
sms_error("could not allocate memory");
return;
}
- pSynthBuf->iMarker = -sizeBuffer;
pSynthBuf->iMarker = pSynthBuf->sizeBuffer;
}
@@ -344,7 +474,14 @@ void sms_initSynthParams(SMS_SynthParams *synthParams)
synthParams->nTracks = 60;
synthParams->iStochasticType = SMS_STOC_APPROX;
synthParams->nStochasticCoeff = 128;
- synthParams->deemphasisLastValue = 0;
+ synthParams->pFDetWindow = NULL;
+ synthParams->pFStocWindow = NULL;
+ synthParams->pSynthBuff = NULL;
+ synthParams->pMagBuff = NULL;
+ synthParams->pPhaseBuff = NULL;
+ synthParams->pSpectra = NULL;
+ synthParams->approxEnvelope = NULL;
+ synthParams->deEmphasisLastValue = 0;
}
/*! \brief initialize synthesis data structure's arrays
@@ -364,12 +501,6 @@ void sms_initSynthParams(SMS_SynthParams *synthParams)
int sms_initSynth(SMS_SynthParams *pSynthParams)
{
int sizeHop, sizeFft, err;
- /* set synthesis parameters from arguments and header */
- // pSynthParams->iOriginalSRate = pSmsHeader->iSamplingRate;
- // pSynthParams->origSizeHop = pSynthParams->iOriginalSRate / pSmsHeader->iFrameRate;
- // pSynthParams->iStochasticType = pSmsHeader->iStochasticType;
- // if(pSynthParams->iSamplingRate <= 0)
- // pSynthParams->iSamplingRate = pSynthParams->iOriginalSRate;
/* make sure sizeHop is something to the power of 2 */
sizeHop = sms_power2(pSynthParams->sizeHop);
@@ -382,29 +513,34 @@ int sms_initSynth(SMS_SynthParams *pSynthParams)
sizeFft = sizeHop * 2;
pSynthParams->pFStocWindow =(sfloat *) calloc(sizeFft, sizeof(sfloat));
- sms_getWindow( sizeFft, pSynthParams->pFStocWindow, SMS_WIN_HANNING );
+ sms_getWindow(sizeFft, pSynthParams->pFStocWindow, SMS_WIN_HANNING);
pSynthParams->pFDetWindow = (sfloat *) calloc(sizeFft, sizeof(sfloat));
- sms_getWindow( sizeFft, pSynthParams->pFDetWindow, SMS_WIN_IFFT );
+ sms_getWindow(sizeFft, pSynthParams->pFDetWindow, SMS_WIN_IFFT);
/* allocate memory for analysis data - size of original hopsize */
/* previous frame to interpolate from */
/* \todo why is stoch coeff + 1? */
sms_allocFrame(&pSynthParams->prevFrame, pSynthParams->nTracks,
- pSynthParams->nStochasticCoeff + 1, 1,
- pSynthParams->iStochasticType, 0);
+ pSynthParams->nStochasticCoeff + 1, 1,
+ pSynthParams->iStochasticType, 0);
pSynthParams->pSynthBuff = (sfloat *) calloc(sizeFft, sizeof(sfloat));
pSynthParams->pMagBuff = (sfloat *) calloc(sizeHop, sizeof(sfloat));
pSynthParams->pPhaseBuff = (sfloat *) calloc(sizeHop, sizeof(sfloat));
pSynthParams->pSpectra = (sfloat *) calloc(sizeFft, sizeof(sfloat));
- /* set/check modification parameters */
- // pSynthParams->modParams.maxFreq = pSmsHeader->iMaxFreq;
+ /* approximation envelope */
+ pSynthParams->approxEnvelope = (sfloat *)calloc(pSynthParams->nStochasticCoeff, sizeof(sfloat));
+ if(pSynthParams->approxEnvelope == NULL)
+ {
+ sms_error("Could not allocate memory for spectral approximation envelope");
+ return -1;
+ }
return SMS_OK;
}
-int sms_changeSynthHop( SMS_SynthParams *pSynthParams, int sizeHop)
+int sms_changeSynthHop(SMS_SynthParams *pSynthParams, int sizeHop)
{
int sizeFft = sizeHop * 2;
@@ -417,7 +553,7 @@ int sms_changeSynthHop( SMS_SynthParams *pSynthParams, int sizeHop)
sms_getWindow( sizeFft, pSynthParams->pFStocWindow, SMS_WIN_HANNING );
pSynthParams->pFDetWindow =
(sfloat *) realloc(pSynthParams->pFDetWindow, sizeFft * sizeof(sfloat));
- sms_getWindow( sizeFft, pSynthParams->pFDetWindow, SMS_WIN_IFFT );
+ sms_getWindow(sizeFft, pSynthParams->pFDetWindow, SMS_WIN_IFFT);
pSynthParams->sizeHop = sizeHop;
@@ -431,24 +567,44 @@ int sms_changeSynthHop( SMS_SynthParams *pSynthParams, int sizeHop)
*
* \param pAnalParams pointer to analysis data structure
*/
-void sms_freeAnalysis( SMS_AnalParams *pAnalParams )
+void sms_freeAnalysis(SMS_AnalParams *pAnalParams)
{
- int i;
- for (i = 0; i < pAnalParams->iMaxDelayFrames; i++)
+ if(pAnalParams->pFrames)
{
- free((pAnalParams->pFrames[i]).pSpectralPeaks);
- free((pAnalParams->pFrames[i].deterministic).pFSinFreq);
- free((pAnalParams->pFrames[i].deterministic).pFSinAmp);
- free((pAnalParams->pFrames[i].deterministic).pFSinPha);
+ int i;
+ for(i = 0; i < pAnalParams->iMaxDelayFrames; i++)
+ {
+ if((pAnalParams->pFrames[i]).pSpectralPeaks)
+ free((pAnalParams->pFrames[i]).pSpectralPeaks);
+ if((pAnalParams->pFrames[i].deterministic).pFSinFreq)
+ free((pAnalParams->pFrames[i].deterministic).pFSinFreq);
+ if((pAnalParams->pFrames[i].deterministic).pFSinAmp)
+ free((pAnalParams->pFrames[i].deterministic).pFSinAmp);
+ if((pAnalParams->pFrames[i].deterministic).pFSinPha)
+ free((pAnalParams->pFrames[i].deterministic).pFSinPha);
+ }
+ free(pAnalParams->pFrames);
}
sms_freeFrame(&pAnalParams->prevFrame);
- // free(pAnalParams->soundBuffer.pFBuffer);
- free(pAnalParams->synthBuffer.pFBuffer);
- free(pAnalParams->pFrames);
- free(pAnalParams->ppFrames);
- // free(pAnalParams->pFSpectrumWindow);
-
+ if(pAnalParams->soundBuffer.pFBuffer)
+ free(pAnalParams->soundBuffer.pFBuffer);
+ if((pAnalParams->synthBuffer).pFBuffer)
+ free((pAnalParams->synthBuffer).pFBuffer);
+ if(pAnalParams->ppFrames)
+ free(pAnalParams->ppFrames);
+ if(pAnalParams->residual)
+ free(pAnalParams->residual);
+ if(pAnalParams->residualWindow)
+ free(pAnalParams->residualWindow);
+ if(pAnalParams->guideStates)
+ free(pAnalParams->guideStates);
+ if(pAnalParams->guides)
+ free(pAnalParams->guides);
+ if(pAnalParams->stocMagSpectrum)
+ free(pAnalParams->stocMagSpectrum);
+ if(pAnalParams->approxEnvelope)
+ free(pAnalParams->approxEnvelope);
}
/*! \brief free analysis data
@@ -460,16 +616,24 @@ void sms_freeAnalysis( SMS_AnalParams *pAnalParams )
* already? as it is, it crashes if this is called without one
* \param pSynthParams pointer to synthesis data structure
*/
-void sms_freeSynth( SMS_SynthParams *pSynthParams )
+void sms_freeSynth(SMS_SynthParams *pSynthParams)
{
- free(pSynthParams->pFStocWindow);
- free(pSynthParams->pFDetWindow);
- free (pSynthParams->pSynthBuff);
- free (pSynthParams->pSpectra);
- free (pSynthParams->pMagBuff);
- free (pSynthParams->pPhaseBuff);
- sms_freeFrame(&pSynthParams->prevFrame);
+ if(pSynthParams->pFStocWindow)
+ free(pSynthParams->pFStocWindow);
+ if(pSynthParams->pFDetWindow)
+ free(pSynthParams->pFDetWindow);
+ if(pSynthParams->pSynthBuff)
+ free(pSynthParams->pSynthBuff);
+ if(pSynthParams->pSpectra)
+ free(pSynthParams->pSpectra);
+ if(pSynthParams->pMagBuff)
+ free(pSynthParams->pMagBuff);
+ if(pSynthParams->pPhaseBuff)
+ free(pSynthParams->pPhaseBuff);
+ if(pSynthParams->approxEnvelope)
+ free(pSynthParams->approxEnvelope);
+ sms_freeFrame(&pSynthParams->prevFrame);
}
/*! \brief set window size for next frame
@@ -481,23 +645,23 @@ void sms_freeSynth( SMS_SynthParams *pSynthParams )
* \param pAnalParams analysis parameters
* \return the size of the next window in samples
*/
-int sms_sizeNextWindow (int iCurrentFrame, SMS_AnalParams *pAnalParams)
+int sms_sizeNextWindow(int iCurrentFrame, SMS_AnalParams *pAnalParams)
{
sfloat fFund = pAnalParams->ppFrames[iCurrentFrame]->fFundamental;
sfloat fPrevFund = pAnalParams->ppFrames[iCurrentFrame-1]->fFundamental;
int sizeWindow;
/* if the previous fundamental was stable use it to set the window size */
- if (fPrevFund > 0 && fabs(fPrevFund - fFund) / fFund <= .2)
- sizeWindow = (int) ((pAnalParams->iSamplingRate / fFund) *
- pAnalParams->fSizeWindow * .5) * 2 + 1;
+ if(fPrevFund > 0 && fabs(fPrevFund - fFund) / fFund <= .2)
+ sizeWindow = (int)((pAnalParams->iSamplingRate / fFund) *
+ pAnalParams->fSizeWindow * .5) * 2 + 1;
/* otherwise use the default size window */
else
sizeWindow = pAnalParams->iDefaultSizeWindow;
- if (sizeWindow > SMS_MAX_WINDOW)
+ if(sizeWindow > SMS_MAX_WINDOW)
{
- fprintf (stderr, "sms_sizeNextWindow error: sizeWindow (%d) too big, set to %d\n", sizeWindow,
+ fprintf(stderr, "sms_sizeNextWindow error: sizeWindow (%d) too big, set to %d\n", sizeWindow,
SMS_MAX_WINDOW);
sizeWindow = SMS_MAX_WINDOW;
}
@@ -519,22 +683,22 @@ int sms_sizeNextWindow (int iCurrentFrame, SMS_AnalParams *pAnalParams)
int sms_initFrame(int iCurrentFrame, SMS_AnalParams *pAnalParams, int sizeWindow)
{
/* clear deterministic data */
- memset ((sfloat *) pAnalParams->ppFrames[iCurrentFrame]->deterministic.pFSinFreq, 0,
- sizeof(sfloat) * pAnalParams->nGuides);
- memset ((sfloat *) pAnalParams->ppFrames[iCurrentFrame]->deterministic.pFSinAmp, 0,
- sizeof(sfloat) * pAnalParams->nGuides);
- memset ((sfloat *) pAnalParams->ppFrames[iCurrentFrame]->deterministic.pFSinPha, 0,
- sizeof(sfloat) * pAnalParams->nGuides);
+ memset((sfloat *) pAnalParams->ppFrames[iCurrentFrame]->deterministic.pFSinFreq, 0,
+ sizeof(sfloat) * pAnalParams->nGuides);
+ memset((sfloat *) pAnalParams->ppFrames[iCurrentFrame]->deterministic.pFSinAmp, 0,
+ sizeof(sfloat) * pAnalParams->nGuides);
+ memset((sfloat *) pAnalParams->ppFrames[iCurrentFrame]->deterministic.pFSinPha, 0,
+ sizeof(sfloat) * pAnalParams->nGuides);
/* clear peaks */
- memset ((void *) pAnalParams->ppFrames[iCurrentFrame]->pSpectralPeaks, 0,
- sizeof (SMS_Peak) * pAnalParams->maxPeaks);
+ memset((void *) pAnalParams->ppFrames[iCurrentFrame]->pSpectralPeaks, 0,
+ sizeof (SMS_Peak) * pAnalParams->maxPeaks);
pAnalParams->ppFrames[iCurrentFrame]->nPeaks = 0;
pAnalParams->ppFrames[iCurrentFrame]->fFundamental = 0;
pAnalParams->ppFrames[iCurrentFrame]->iFrameNum =
- pAnalParams->ppFrames[iCurrentFrame - 1]->iFrameNum + 1;
+ pAnalParams->ppFrames[iCurrentFrame - 1]->iFrameNum + 1;
pAnalParams->ppFrames[iCurrentFrame]->iFrameSize = sizeWindow;
/* if first frame set center of data around 0 */
@@ -548,7 +712,7 @@ int sms_initFrame(int iCurrentFrame, SMS_AnalParams *pAnalParams, int sizeWindow
/* check for end of sound */
if ((pAnalParams->ppFrames[iCurrentFrame]->iFrameSample + (sizeWindow+1)/2) >= pAnalParams->iSizeSound
- && pAnalParams->iSizeSound > 0)
+ && pAnalParams->iSizeSound > 0)
{
pAnalParams->ppFrames[iCurrentFrame]->iFrameNum = -1;
pAnalParams->ppFrames[iCurrentFrame]->iFrameSize = 0;
@@ -574,11 +738,11 @@ sfloat sms_fundDeviation(SMS_AnalParams *pAnalParams, int iCurrentFrame)
int i;
/* get the sum of the past few fundamentals */
- for (i = 0; i < pAnalParams->minGoodFrames; i++)
+ for(i = 0; i < pAnalParams->minGoodFrames; i++)
{
fFund = pAnalParams->ppFrames[iCurrentFrame-i]->fFundamental;
if(fFund <= 0)
- return(-1);
+ return -1;
else
fSum += fFund;
}
@@ -587,11 +751,11 @@ sfloat sms_fundDeviation(SMS_AnalParams *pAnalParams, int iCurrentFrame)
fAverage = fSum / pAnalParams->minGoodFrames;
/* get the deviation from the average */
- for (i = 0; i < pAnalParams->minGoodFrames; i++)
+ for(i = 0; i < pAnalParams->minGoodFrames; i++)
fDeviation += fabs(pAnalParams->ppFrames[iCurrentFrame-i]->fFundamental - fAverage);
/* return the deviation from the average */
- return (fDeviation / (pAnalParams->minGoodFrames * fAverage));
+ return fDeviation / (pAnalParams->minGoodFrames * fAverage);
}
@@ -600,14 +764,14 @@ sfloat sms_fundDeviation(SMS_AnalParams *pAnalParams, int iCurrentFrame)
* \param pAnalParams pointer to analysis params
* \return error value \see SMS_ERRORS
*/
-int sms_createDebugFile (SMS_AnalParams *pAnalParams)
+int sms_createDebugFile(SMS_AnalParams *pAnalParams)
{
- if ((pDebug = fopen(pChDebugFile, "w+")) == NULL)
+ if((pDebug = fopen(pChDebugFile, "w+")) == NULL)
{
fprintf(stderr, "Cannot open debugfile: %s\n", pChDebugFile);
- return(SMS_WRERR);
+ return SMS_WRERR;
}
- else return(SMS_OK);
+ return SMS_OK;
}
/*! \brief function to write to the debug file
@@ -621,16 +785,15 @@ int sms_createDebugFile (SMS_AnalParams *pAnalParams)
* \param pFBuffer3 pointer to array 3
* \param sizeBuffer the size of the buffers
*/
-void sms_writeDebugData (sfloat *pFBuffer1, sfloat *pFBuffer2,
- sfloat *pFBuffer3, int sizeBuffer)
+void sms_writeDebugData(sfloat *pFBuffer1, sfloat *pFBuffer2,
+ sfloat *pFBuffer3, int sizeBuffer)
{
int i;
static int counter = 0;
- for (i = 0; i < sizeBuffer; i++)
- fprintf (pDebug, "%d %d %d %d\n", counter++, (int)pFBuffer1[i],
- (int)pFBuffer2[i], (int)pFBuffer3[i]);
-
+ for(i = 0; i < sizeBuffer; i++)
+ fprintf(pDebug, "%d %d %d %d\n", counter++, (int)pFBuffer1[i],
+ (int)pFBuffer2[i], (int)pFBuffer3[i]);
}
/*! \brief function to write the residual sound file to disk
@@ -639,7 +802,7 @@ void sms_writeDebugData (sfloat *pFBuffer1, sfloat *pFBuffer2,
*/
void sms_writeDebugFile ()
{
- fclose (pDebug);
+ fclose(pDebug);
}
/*! \brief convert from magnitude to decibel
@@ -647,7 +810,7 @@ void sms_writeDebugFile ()
* \param x magnitude (0:1)
* \return decibel (0: -100)
*/
-sfloat sms_magToDB( sfloat x)
+sfloat sms_magToDB(sfloat x)
{
if(x < mag_thresh)
return 0.0;
@@ -662,7 +825,7 @@ sfloat sms_magToDB( sfloat x)
* \param x decibel (0-100)
* \return magnitude (0-1)
*/
-sfloat sms_dBToMag( sfloat x)
+sfloat sms_dBToMag(sfloat x)
{
if(x < 0.00001)
return 0.0;
@@ -680,10 +843,10 @@ sfloat sms_dBToMag( sfloat x)
* \param sizeArray size of array
* \param pArray pointer to array
*/
-void sms_arrayMagToDB( int sizeArray, sfloat *pArray)
+void sms_arrayMagToDB(int sizeArray, sfloat *pArray)
{
int i;
- for( i = 0; i < sizeArray; i++)
+ for(i = 0; i < sizeArray; i++)
pArray[i] = sms_magToDB(pArray[i]);
}
@@ -695,10 +858,10 @@ void sms_arrayMagToDB( int sizeArray, sfloat *pArray)
* \param sizeArray size of array
* \param pArray pointer to array
*/
-void sms_arrayDBToMag( int sizeArray, sfloat *pArray)
+void sms_arrayDBToMag(int sizeArray, sfloat *pArray)
{
int i;
- for( i = 0; i < sizeArray; i++)
+ for(i = 0; i < sizeArray; i++)
pArray[i] = sms_dBToMag(pArray[i]);
}
/*! \brief set the linear magnitude threshold
@@ -708,7 +871,7 @@ void sms_arrayDBToMag( int sizeArray, sfloat *pArray)
*
* \param x threshold value
*/
-void sms_setMagThresh( sfloat x)
+void sms_setMagThresh(sfloat x)
{
/* limit threshold to -100db */
if(x < 0.00001)
@@ -722,7 +885,8 @@ void sms_setMagThresh( sfloat x)
*
* \param pErrorMessage pointer to error message string
*/
-void sms_error(char *pErrorMessage) {
+void sms_error(char *pErrorMessage)
+{
strncpy(error_message, pErrorMessage, 256);
error_status = -1;
}
@@ -733,7 +897,7 @@ void sms_error(char *pErrorMessage) {
*/
int sms_errorCheck()
{
- return(error_status);
+ return error_status;
}
/*! \brief get a string containing information about the last error
@@ -747,7 +911,7 @@ char* sms_errorString()
error_status = 0;
return error_message;
}
- else return NULL;
+ return NULL;
}
/*! \brief random number genorator
@@ -757,9 +921,9 @@ char* sms_errorString()
sfloat sms_random()
{
#ifdef MERSENNE_TWISTER
- return(genrand_real1());
+ return genrand_real1();
#else
- return((sfloat)(random() * 2 * INV_HALF_MAX));
+ return (sfloat)(random() * 2 * INV_HALF_MAX);
#endif
}
@@ -771,17 +935,17 @@ sfloat sms_rms(int sizeArray, sfloat *pArray)
{
int i;
sfloat mean_squared = 0.;
- for( i = 0; i < sizeArray; i++)
+ for(i = 0; i < sizeArray; i++)
mean_squared += pArray[i] * pArray[i];
- return(sqrtf(mean_squared / sizeArray));
+ return sqrtf(mean_squared / sizeArray);
}
/*! \brief make sure a number is a power of 2
*
* \return a power of two integer >= input value
*/
-int sms_power2( int n)
+int sms_power2(int n)
{
int p = -1;
int N = n;
@@ -793,12 +957,12 @@ int sms_power2( int n)
if(1<<p == N) /* n was a power of 2 */
{
- return(N);
+ return N;
}
else /* make the new value larger than n */
{
p++;
- return(1<<p);
+ return 1<<p;
}
}
@@ -807,9 +971,9 @@ int sms_power2( int n)
* \param x linear frequency value
* \return (1.059...)^x, where 1.059 is the 12th root of 2 precomputed
*/
-sfloat sms_scalarTempered( sfloat x)
+sfloat sms_scalarTempered(sfloat x)
{
- return(powf(1.0594630943592953, x));
+ return powf(1.0594630943592953, x);
}
/*! \brief scale an array of linear frequencies to the well-tempered scale
@@ -817,9 +981,9 @@ sfloat sms_scalarTempered( sfloat x)
* \param sizeArray size of the array
* \param pArray pointer to array of frequencies
*/
-void sms_arrayScalarTempered( int sizeArray, sfloat *pArray)
+void sms_arrayScalarTempered(int sizeArray, sfloat *pArray)
{
int i;
- for( i = 0; i < sizeArray; i++)
+ for(i = 0; i < sizeArray; i++)
pArray[i] = sms_scalarTempered(pArray[i]);
}
diff --git a/sms/sms.h b/sms/sms.h
index bedc7d3..96898db 100644
--- a/sms/sms.h
+++ b/sms/sms.h
@@ -30,12 +30,13 @@
#include <memory.h>
#include <strings.h>
-#define SMS_VERSION 1.1 /*!< \brief version control number */
+#define SMS_VERSION 1.15 /*!< \brief version control number */
-#define SMS_MAX_NPEAKS 400 /*!< \brief maximum number of peaks */
+#define SMS_MAX_NPEAKS 400 /*!< \brief maximum number of peaks */
+#define SMS_MAX_FRAME_SIZE 10000 /* maximum size of input frame in samples */
+#define SMS_MAX_SPEC 8192 /*! \brief maximum size for magnitude spectrum */
#define sfloat double
-/*#define sfloat float*/
/*! \struct SMS_Header
* \brief structure for the header of an SMS file
@@ -61,24 +62,18 @@ typedef struct
{
int iSmsMagic; /*!< identification constant */
int iHeadBSize; /*!< size in bytes of header */
- int nFrames; /*!< number of data frames */
- int iFrameBSize; /*!< size in bytes of each data frame */
+ int nFrames; /*!< number of data frames */
+ int iFrameBSize; /*!< size in bytes of each data frame */
int iSamplingRate; /*!< samplerate of analysis signal (necessary to recreate residual spectrum */
int iFormat; /*!< type of data format \see SMS_Format */
- int nTracks; /*!< number of sinusoidal tracks per frame */
+ int nTracks; /*!< number of sinusoidal tracks per frame */
int iFrameRate; /*!< rate in Hz of data frames */
int iStochasticType; /*!< type stochastic representation */
int nStochasticCoeff; /*!< number of stochastic coefficients per frame */
- int iEnvType; /*!< type of envelope representation */
- int nEnvCoeff; /*!< number of cepstral coefficents per frame */
- int iMaxFreq; /*!< maximum frequency of peaks (also corresponds to the last bin of the specEnv */
- /* sfloat fAmplitude; /\*!< average amplitude of represented sound. *\/ */
- /* sfloat fFrequency; /\*!< average fundamental frequency *\/ */
- /* int iBegSteadyState; /\*!< record number of begining of steady state. *\/ */
- /* int iEndSteadyState; /\*!< record number of end of steady state. *\/ */
- sfloat fResidualPerc; /*!< percentage of the residual to original */
- int nTextCharacters; /*!< number of text characters */
- char *pChTextCharacters; /*!< Text string relating to the sound */
+ int iEnvType; /*!< type of envelope representation */
+ int nEnvCoeff; /*!< number of cepstral coefficents per frame */
+ int iMaxFreq; /*!< maximum frequency of peaks (also corresponds to the last bin of the specEnv */
+ sfloat fResidualPerc; /*!< percentage of the residual to original */
} SMS_Header;
/*! \struct SMS_Data
@@ -95,17 +90,17 @@ typedef struct
*/
typedef struct
{
- sfloat *pSmsData; /*!< pointer to all SMS data */
- int sizeData; /*!< size of all the data */
- sfloat *pFSinFreq; /*!< frequency of sinusoids */
- sfloat *pFSinAmp; /*!< magnitude of sinusoids (stored in dB) */
- sfloat *pFSinPha; /*!< phase of sinusoids */
- int nTracks; /*!< number of sinusoidal tracks in frame */
- sfloat *pFStocGain; /*!< gain of stochastic component */
- int nCoeff; /*!< number of filter coefficients */
- sfloat *pFStocCoeff; /*!< filter coefficients for stochastic component */
- sfloat *pResPhase; /*!< residual phase spectrum */
- int nEnvCoeff; /*!< number of spectral envelope coefficients */
+ sfloat *pSmsData; /*!< pointer to all SMS data */
+ int sizeData; /*!< size of all the data */
+ sfloat *pFSinFreq; /*!< frequency of sinusoids */
+ sfloat *pFSinAmp; /*!< magnitude of sinusoids (stored in dB) */
+ sfloat *pFSinPha; /*!< phase of sinusoids */
+ int nTracks; /*!< number of sinusoidal tracks in frame */
+ sfloat *pFStocGain; /*!< gain of stochastic component */
+ int nCoeff; /*!< number of filter coefficients */
+ sfloat *pFStocCoeff; /*!< filter coefficients for stochastic component */
+ sfloat *pResPhase; /*!< residual phase spectrum */
+ int nEnvCoeff; /*!< number of spectral envelope coefficients */
sfloat *pSpecEnv;
} SMS_Data;
@@ -120,22 +115,20 @@ typedef struct
*/
typedef struct
{
- sfloat *pFBuffer; /*!< buffer for sound data*/
- int sizeBuffer; /*!< size of buffer */
- int iMarker; /*!< sample marker relating to sound source */
- int iFirstGood; /*!< first sample in buffer that is a good one */
+ sfloat *pFBuffer; /*!< buffer for sound data*/
+ int sizeBuffer; /*!< size of buffer */
+ int iMarker; /*!< sample marker relating to sound source */
+ int iFirstGood; /*!< first sample in buffer that is a good one */
} SMS_SndBuffer;
/*! \struct SMS_Peak
* \brief structure for sinusodial peak
*/
-
-/* information attached to a spectral peak */
typedef struct
{
- sfloat fFreq; /*!< frequency of peak */
- sfloat fMag; /*!< magnitude of peak */
- sfloat fPhase; /*!< phase of peak */
+ sfloat fFreq; /*!< frequency of peak */
+ sfloat fMag; /*!< magnitude of peak */
+ sfloat fPhase; /*!< phase of peak */
} SMS_Peak;
/* a collection of spectral peaks */
@@ -157,48 +150,42 @@ typedef struct
int iFrameSample; /*!< sample number of the middle of the frame */
int iFrameSize; /*!< number of samples used in the frame */
int iFrameNum; /*!< frame number */
- SMS_Peak *pSpectralPeaks; /*!< spectral peaks found in frame */
+ SMS_Peak *pSpectralPeaks; /*!< spectral peaks found in frame */
int nPeaks; /*!< number of peaks found */
- sfloat fFundamental; /*!< fundamental frequency in frame */
+ sfloat fFundamental; /*!< fundamental frequency in frame */
SMS_Data deterministic; /*!< deterministic data */
- int iStatus; /*!< status of frame enumerated by SMS_FRAME_STATUS
- \see SMS_FRAME_STATUS */
+ int iStatus; /*!< status of frame enumerated by SMS_FRAME_STATUS \see SMS_FRAME_STATUS */
} SMS_AnalFrame;
-/*! \struct SMS_PeakParams
- * \brief structure with useful information for peak detection and continuation
- *
- */
-//typedef struct
-//{
-// sfloat fLowestFreq; [>!< the first bin to look for a peak <]
-// sfloat fHighestFreq; [>!< the last bin to look for a peak <]
-// sfloat fMinPeakMag; [>!< mininum magnitude to consider as a peak <]
-// int iSamplingRate; [>!< sampling rate of analysis signal <]
-// int iMaxPeaks; [>!< maximum number of spectral peaks to look for <]
-// int nPeaksFound; [>!< the number of peaks found in each analysis <]
-// sfloat fHighestFundamental;[>!< highest fundamental frequency in Hz <]
-// int iRefHarmonic; [>!< reference harmonic to use in the fundamental detection <]
-// sfloat fMinRefHarmMag; [>!< minimum magnitude in dB for reference peak <]
-// sfloat fRefHarmMagDiffFromMax; [>!< maximum magnitude difference from reference peak to highest peak <]
-// int iSoundType; [>!< type of sound to be analyzed \see SMS_SOUND_TYPE <]
-//} SMS_PeakParams;
-
/*! \struct SMS_SEnvParams;
* \brief structure information and data for spectral enveloping
*
*/
typedef struct
{
- int iType; /*!< envelope type \see SMS_SpecEnvType */
- int iOrder; /*!< ceptrum order */
- int iMaxFreq; /*!< maximum frequency covered by the envelope */
+ int iType; /*!< envelope type \see SMS_SpecEnvType */
+ int iOrder; /*!< ceptrum order */
+ int iMaxFreq; /*!< maximum frequency covered by the envelope */
sfloat fLambda; /*!< regularization factor */
- int nCoeff; /*!< number of coefficients (bins) in the envelope */
- int iAnchor; /*!< whether to make anchor points at DC / Nyquist or not */
+ int nCoeff; /*!< number of coefficients (bins) in the envelope */
+ int iAnchor; /*!< whether to make anchor points at DC / Nyquist or not */
} SMS_SEnvParams;
-
+/*! \struct SMS_Guide
+ * \brief information attached to a guide
+ *
+ * This structure is used to organize the detected peaks into time-varying
+ * trajectories, or sinusoidal tracks. As the analysis progresses, previous
+ * guides may be updated according to new information in the peak continuation
+ * of new frames (two-way mismatch).
+ */
+typedef struct
+{
+ sfloat fFreq; /*!< frequency of guide */
+ sfloat fMag; /*!< magnitude of guide */
+ int iStatus; /*!< status of guide: DEAD, SLEEPING, ACTIVE */
+ int iPeakChosen; /*!< peak number chosen by the guide */
+} SMS_Guide;
/*! \struct SMS_AnalParams
* \brief structure with useful information for analysis functions
@@ -216,56 +203,112 @@ typedef struct
*/
typedef struct
{
- int iDebugMode; /*!< debug codes enumerated by SMS_DBG \see SMS_DBG */
- int iFormat; /*!< analysis format code defined by SMS_Format \see SMS_Format */
- int iSoundType; /*!< type of sound to be analyzed \see SMS_SOUND_TYPE */
- int iStochasticType; /*!< type of stochastic model defined by SMS_StocSynthType \see SMS_StocSynthType */
- int iFrameRate; /*!< rate in Hz of data frames */
- int nStochasticCoeff; /*!< number of stochastic coefficients per frame */
- sfloat fLowestFundamental; /*!< lowest fundamental frequency in Hz */
- sfloat fHighestFundamental;/*!< highest fundamental frequency in Hz */
- sfloat fDefaultFundamental;/*!< default fundamental in Hz */
- sfloat fPeakContToGuide; /*!< contribution of previous peak to current guide (between 0 and 1) */
- sfloat fFundContToGuide; /*!< contribution of current fundamental to current guide (between 0 and 1) */
- sfloat fFreqDeviation; /*!< maximum deviation from peak to peak */
- int iSamplingRate; /*! sampling rate of sound to be analyzed */
- int iDefaultSizeWindow; /*!< default size of analysis window in samples */
- int windowSize; /*!< the current window size */
- int sizeHop; /*!< hop size of analysis window in samples */
- sfloat fSizeWindow; /*!< size of analysis window in number of periods */
- int nTracks; /*!< number of sinusoidal tracks in frame */
- int maxPeaks; /*!< maximum number of peaks in a frame */
- int nGuides; /*!< number of guides used for peak detection and continuation \see SMS_Guide */
- int iCleanTracks; /*!< whether or not to clean sinusoidal tracks */
- //int iEnvelope; /*!< whether or not to compute spectral envelope */
- sfloat fMinRefHarmMag; /*!< minimum magnitude in dB for reference peak */
- sfloat fRefHarmMagDiffFromMax; /*!< maximum magnitude difference from reference peak to highest peak */
- int iRefHarmonic; /*!< reference harmonic to use in the fundamental detection */
- int iMinTrackLength; /*!< minimum length in samples of a given track */
- int iMaxSleepingTime; /*!< maximum sleeping time for a track */
- sfloat fLowestFreq; /*!< lowest frequency to be searched */
- sfloat fHighestFreq; /*!< highest frequency to be searched */
- sfloat fMinPeakMag; /*!< minimum magnitude in dB for a good peak */
- int iAnalysisDirection; /*!< analysis direction, direct or reverse */
- int iSizeSound; /*!< total size of sound to be analyzed in samples */
- int nFrames; /*!< total number of frames that will be analyzed */
- int iWindowType; /*!< type of FFT analysis window \see SMS_WINDOWS */
- int iMaxDelayFrames; /*!< maximum number of frames to delay before peak continuation */
- int minGoodFrames; /*!< minimum number of stable frames for backward search */
- sfloat maxDeviation; /*!< maximum deviation allowed */
- int analDelay; /*! number of frames in the past to be looked in possible re-analyze */
- sfloat fResidualAccumPerc; /*!< accumalitive residual percentage */
- int sizeNextRead; /*!< size of samples to read from sound file next analysis */
+ int iDebugMode; /*!< debug codes enumerated by SMS_DBG \see SMS_DBG */
+ int iFormat; /*!< analysis format code defined by SMS_Format \see SMS_Format */
+ int iSoundType; /*!< type of sound to be analyzed \see SMS_SOUND_TYPE */
+ int iStochasticType; /*!< type of stochastic model defined by SMS_StocSynthType \see SMS_StocSynthType */
+ int iFrameRate; /*!< rate in Hz of data frames */
+ int nStochasticCoeff; /*!< number of stochastic coefficients per frame */
+ sfloat fLowestFundamental; /*!< lowest fundamental frequency in Hz */
+ sfloat fHighestFundamental; /*!< highest fundamental frequency in Hz */
+ sfloat fDefaultFundamental; /*!< default fundamental in Hz */
+ sfloat fPeakContToGuide; /*!< contribution of previous peak to current guide (between 0 and 1) */
+ sfloat fFundContToGuide; /*!< contribution of current fundamental to current guide (between 0 and 1) */
+ sfloat fFreqDeviation; /*!< maximum deviation from peak to peak */
+ int iSamplingRate; /*! sampling rate of sound to be analyzed */
+ int iDefaultSizeWindow; /*!< default size of analysis window in samples */
+ int windowSize; /*!< the current window size */
+ int sizeHop; /*!< hop size of analysis window in samples */
+ sfloat fSizeWindow; /*!< size of analysis window in number of periods */
+ int nTracks; /*!< number of sinusoidal tracks in frame */
+ int maxPeaks; /*!< maximum number of peaks in a frame */
+ int nGuides; /*!< number of guides used for peak detection and continuation \see SMS_Guide */
+ int iCleanTracks; /*!< whether or not to clean sinusoidal tracks */
+ sfloat fMinRefHarmMag; /*!< minimum magnitude in dB for reference peak */
+ sfloat fRefHarmMagDiffFromMax; /*!< maximum magnitude difference from reference peak to highest peak */
+ int iRefHarmonic; /*!< reference harmonic to use in the fundamental detection */
+ int iMinTrackLength; /*!< minimum length in samples of a given track */
+ int iMaxSleepingTime; /*!< maximum sleeping time for a track */
+ sfloat fLowestFreq; /*!< lowest frequency to be searched */
+ sfloat fHighestFreq; /*!< highest frequency to be searched */
+ sfloat fMinPeakMag; /*!< minimum magnitude in dB for a good peak */
+ int iAnalysisDirection; /*!< analysis direction, direct or reverse */
+ int iSizeSound; /*!< total size of sound to be analyzed in samples */
+ int nFrames; /*!< total number of frames that will be analyzed */
+ int iWindowType; /*!< type of FFT analysis window \see SMS_WINDOWS */
+ int iMaxDelayFrames; /*!< maximum number of frames to delay before peak continuation */
+ int minGoodFrames; /*!< minimum number of stable frames for backward search */
+ sfloat maxDeviation; /*!< maximum deviation allowed */
+ int analDelay; /*! number of frames in the past to be looked in possible re-analyze */
+ sfloat fResidualAccumPerc; /*!< accumalitive residual percentage */
+ int sizeNextRead; /*!< size of samples to read from sound file next analysis */
sfloat preEmphasisLastValue;
- int resetGuides;
- int resetGuideStates;
- //SMS_PeakParams peakParams; [>!< structure with parameters for spectral peaks <]
- SMS_Data prevFrame; /*!< the previous analysis frame */
- SMS_SEnvParams specEnvParams; /*!< all data for spectral enveloping */
- SMS_SndBuffer soundBuffer; /*!< signal to be analyzed */
- SMS_SndBuffer synthBuffer; /*!< resynthesized signal used to create the residual */
- SMS_AnalFrame *pFrames; /*!< an array of frames that have already been analyzed */
- SMS_AnalFrame **ppFrames; /*!< pointers to the frames analyzed (it is circular-shifted once the array is full */
+ SMS_Data prevFrame; /*!< the previous analysis frame */
+ SMS_SEnvParams specEnvParams; /*!< all data for spectral enveloping */
+ SMS_SndBuffer soundBuffer; /*!< signal to be analyzed */
+ SMS_SndBuffer synthBuffer; /*!< resynthesized signal used to create the residual */
+ SMS_AnalFrame *pFrames; /*!< an array of frames that have already been analyzed */
+ sfloat magSpectrum[SMS_MAX_SPEC];
+ sfloat phaseSpectrum[SMS_MAX_SPEC];
+ sfloat spectrumWindow[SMS_MAX_SPEC];
+ sfloat fftBuffer[SMS_MAX_SPEC * 2];
+ int sizeResidual;
+ sfloat *residual;
+ sfloat *residualWindow;
+ int *guideStates;
+ SMS_Guide* guides;
+ sfloat inputBuffer[SMS_MAX_FRAME_SIZE];
+ int sizeStocMagSpectrum;
+ sfloat *stocMagSpectrum;
+ sfloat *approxEnvelope; /*!< spectral approximation envelope */
+ SMS_AnalFrame **ppFrames; /*!< pointers to the frames analyzed (it is circular-shifted once the array is full */
+
+ //int iDebugMode; [>!< debug codes enumerated by SMS_DBG \see SMS_DBG <]
+ //int iFormat; [>!< analysis format code defined by SMS_Format \see SMS_Format <]
+ //int iSoundType; [>!< type of sound to be analyzed \see SMS_SOUND_TYPE <]
+ //int iStochasticType; [>!< type of stochastic model defined by SMS_StocSynthType \see SMS_StocSynthType <]
+ //int iFrameRate; [>!< rate in Hz of data frames <]
+ //int nStochasticCoeff; [>!< number of stochastic coefficients per frame <]
+ //sfloat fLowestFundamental; [>!< lowest fundamental frequency in Hz <]
+ //sfloat fHighestFundamental;[>!< highest fundamental frequency in Hz <]
+ //sfloat fDefaultFundamental;[>!< default fundamental in Hz <]
+ //sfloat fPeakContToGuide; [>!< contribution of previous peak to current guide (between 0 and 1) <]
+ //sfloat fFundContToGuide; [>!< contribution of current fundamental to current guide (between 0 and 1) <]
+ //sfloat fFreqDeviation; [>!< maximum deviation from peak to peak <]
+ //int iSamplingRate; [>! sampling rate of sound to be analyzed <]
+ //int iDefaultSizeWindow; [>!< default size of analysis window in samples <]
+ //int windowSize; [>!< the current window size <]
+ //int sizeHop; [>!< hop size of analysis window in samples <]
+ //sfloat fSizeWindow; [>!< size of analysis window in number of periods <]
+ //int nTracks; [>!< number of sinusoidal tracks in frame <]
+ //int maxPeaks; [>!< maximum number of peaks in a frame <]
+ //int nGuides; [>!< number of guides used for peak detection and continuation \see SMS_Guide <]
+ //int iCleanTracks; [>!< whether or not to clean sinusoidal tracks <]
+ //sfloat fMinRefHarmMag; [>!< minimum magnitude in dB for reference peak <]
+ //sfloat fRefHarmMagDiffFromMax; [>!< maximum magnitude difference from reference peak to highest peak <]
+ //int iRefHarmonic; [>!< reference harmonic to use in the fundamental detection <]
+ //int iMinTrackLength; [>!< minimum length in samples of a given track <]
+ //int iMaxSleepingTime; [>!< maximum sleeping time for a track <]
+ //sfloat fLowestFreq; [>!< lowest frequency to be searched <]
+ //sfloat fHighestFreq; [>!< highest frequency to be searched <]
+ //sfloat fMinPeakMag; [>!< minimum magnitude in dB for a good peak <]
+ //int iAnalysisDirection; [>!< analysis direction, direct or reverse <]
+ //int iSizeSound; [>!< total size of sound to be analyzed in samples <]
+ //int nFrames; [>!< total number of frames that will be analyzed <]
+ //int iWindowType; [>!< type of FFT analysis window \see SMS_WINDOWS <]
+ //int iMaxDelayFrames; [>!< maximum number of frames to delay before peak continuation <]
+ //int minGoodFrames; [>!< minimum number of stable frames for backward search <]
+ //sfloat maxDeviation; [>!< maximum deviation allowed <]
+ //int analDelay; [>! number of frames in the past to be looked in possible re-analyze <]
+ //sfloat fResidualAccumPerc; [>!< accumalitive residual percentage <]
+ //int sizeNextRead; [>!< size of samples to read from sound file next analysis <]
+ //sfloat preEmphasisLastValue;
+ //SMS_Data prevFrame; [>!< the previous analysis frame <]
+ //SMS_SEnvParams specEnvParams; [>!< all data for spectral enveloping <]
+ //SMS_SndBuffer soundBuffer; [>!< signal to be analyzed <]
+ //SMS_SndBuffer synthBuffer; [>!< resynthesized signal used to create the residual <]
+ //SMS_AnalFrame *pFrames; [>!< an array of frames that have already been analyzed <]
+ //SMS_AnalFrame **ppFrames; [>!< pointers to the frames analyzed (it is circular-shifted once the array is full <]
} SMS_AnalParams;
/*! \struct SMS_ModifyParams
@@ -274,20 +317,20 @@ typedef struct
*/
typedef struct
{
- int ready; /*!< a flag to know if the struct has been initialized) */
- int maxFreq; /*!< maximum frequency component */
- int doResGain; /*!< whether or not to scale residual gain */
- sfloat resGain; /*!< residual scale factor */
- int doTranspose; /*!< whether or not to transpose */
- sfloat transpose; /*!< transposition factor */
- int doSinEnv; /*!< whether or not to apply a new spectral envelope to the sin component */
- sfloat sinEnvInterp; /*!< value between 0 (use frame's env) and 1 (use *env). Interpolates inbetween values*/
- int sizeSinEnv; /*!< size of the envelope pointed to by env */
- sfloat *sinEnv; /*!< sinusoidal spectral envelope */
- int doResEnv; /*!< whether or not to apply a new spectral envelope to the residual component */
- sfloat resEnvInterp; /*!< value between 0 (use frame's env) and 1 (use *env). Interpolates inbetween values*/
- int sizeResEnv; /*!< size of the envelope pointed to by resEnv */
- sfloat *resEnv; /*!< residual spectral envelope */
+ int ready; /*!< a flag to know if the struct has been initialized) */
+ int maxFreq; /*!< maximum frequency component */
+ int doResGain; /*!< whether or not to scale residual gain */
+ sfloat resGain; /*!< residual scale factor */
+ int doTranspose; /*!< whether or not to transpose */
+ sfloat transpose; /*!< transposition factor */
+ int doSinEnv; /*!< whether or not to apply a new spectral envelope to the sin component */
+ sfloat sinEnvInterp; /*!< value between 0 (use frame's env) and 1 (use *env). Interpolates inbetween values*/
+ int sizeSinEnv; /*!< size of the envelope pointed to by env */
+ sfloat *sinEnv; /*!< sinusoidal spectral envelope */
+ int doResEnv; /*!< whether or not to apply a new spectral envelope to the residual component */
+ sfloat resEnvInterp; /*!< value between 0 (use frame's env) and 1 (use *env). Interpolates inbetween values*/
+ int sizeResEnv; /*!< size of the envelope pointed to by resEnv */
+ sfloat *resEnv; /*!< residual spectral envelope */
} SMS_ModifyParams;
/*! \struct SMS_SynthParams
@@ -300,7 +343,8 @@ typedef struct
*/
typedef struct
{
- int iStochasticType; /*!< type of stochastic model defined by SMS_StocSynthType \see SMS_StocSynthType */
+ int iStochasticType; /*!< type of stochastic model defined by SMS_StocSynthType
+ \see SMS_StocSynthType */
int iSynthesisType; /*!< type of synthesis to perform \see SMS_SynthType */
int iDetSynthType; /*!< method for synthesizing deterministic component \see SMS_DetSynthType */
int iOriginalSRate; /*!< samplerate of the sound model source (for stochastic synthesis approximation) */
@@ -309,7 +353,7 @@ typedef struct
int origSizeHop; /*!< original number of samples used to create each analysis frame */
int nTracks;
int nStochasticCoeff;
- sfloat deemphasisLastValue;
+ sfloat deEmphasisLastValue;
sfloat *pFDetWindow; /*!< array to hold the window used for deterministic synthesis \see SMS_WIN_IFFT */
sfloat *pFStocWindow; /*!< array to hold the window used for stochastic synthesis (Hanning) */
sfloat *pSynthBuff; /*!< an array for keeping samples during overlap-add (2x sizeHop) */
@@ -318,7 +362,29 @@ typedef struct
sfloat *pSpectra; /*!< array for in-place FFT transform */
SMS_Data prevFrame; /*!< previous data frame, for interpolation between frames */
SMS_ModifyParams modParams; /*!< modification parameters */
+ sfloat *approxEnvelope; /*!< spectral approximation envelope */
} SMS_SynthParams;
+//typedef struct
+//{
+// int iStochasticType; [>!< type of stochastic model defined by SMS_StocSynthType \see SMS_StocSynthType <]
+// int iSynthesisType; [>!< type of synthesis to perform \see SMS_SynthType <]
+// int iDetSynthType; [>!< method for synthesizing deterministic component \see SMS_DetSynthType <]
+// int iOriginalSRate; [>!< samplerate of the sound model source (for stochastic synthesis approximation) <]
+// int iSamplingRate; [>!< synthesis samplerate <]
+// int sizeHop; [>!< number of samples to synthesis for each frame <]
+// int origSizeHop; [>!< original number of samples used to create each analysis frame <]
+// int nTracks;
+// int nStochasticCoeff;
+// sfloat deemphasisLastValue;
+// sfloat *pFDetWindow; [>!< array to hold the window used for deterministic synthesis \see SMS_WIN_IFFT <]
+// sfloat *pFStocWindow; [>!< array to hold the window used for stochastic synthesis (Hanning) <]
+// sfloat *pSynthBuff; [>!< an array for keeping samples during overlap-add (2x sizeHop) <]
+// sfloat *pMagBuff; [>!< an array for keeping magnitude spectrum for stochastic synthesis <]
+// sfloat *pPhaseBuff; [>!< an array for keeping phase spectrum for stochastic synthesis <]
+// sfloat *pSpectra; [>!< array for in-place FFT transform <]
+// SMS_Data prevFrame; [>!< previous data frame, for interpolation between frames <]
+// SMS_ModifyParams modParams; [>!< modification parameters <]
+//} SMS_SynthParams;
/*! \struct SMS_HarmCandidate
* \brief structure to hold information about a harmonic candidate
@@ -329,11 +395,11 @@ typedef struct
*/
typedef struct
{
- sfloat fFreq; /*!< frequency of harmonic */
- sfloat fMag; /*!< magnitude of harmonic */
- sfloat fMagPerc; /*!< percentage of magnitude */
- sfloat fFreqDev; /*!< deviation from perfect harmonic */
- sfloat fHarmRatio; /*!< percentage of harmonics found */
+ sfloat fFreq; /*!< frequency of harmonic */
+ sfloat fMag; /*!< magnitude of harmonic */
+ sfloat fMagPerc; /*!< percentage of magnitude */
+ sfloat fFreqDev; /*!< deviation from perfect harmonic */
+ sfloat fHarmRatio; /*!< percentage of harmonics found */
} SMS_HarmCandidate;
/*! \struct SMS_ContCandidate
@@ -344,27 +410,11 @@ typedef struct
*/
typedef struct
{
- sfloat fFreqDev; /*!< frequency deviation from guide */
- sfloat fMagDev; /*!< magnitude deviation from guide */
- int iPeak; /*!< peak number (organized according to frequency)*/
+ sfloat fFreqDev; /*!< frequency deviation from guide */
+ sfloat fMagDev; /*!< magnitude deviation from guide */
+ int iPeak; /*!< peak number (organized according to frequency)*/
} SMS_ContCandidate;
-/*! \struct SMS_Guide
- * \brief information attached to a guide
- *
- * This structure is used to organize the detected peaks into time-varying
- * trajectories, or sinusoidal tracks. As the analysis progresses, previous
- * guides may be updated according to new information in the peak continuation
- * of new frames (two-way mismatch).
- */
-typedef struct
-{
- sfloat fFreq; /*!< frequency of guide */
- sfloat fMag; /*!< magnitude of guide */
- int iStatus; /*!< status of guide: DEAD, SLEEPING, ACTIVE */
- int iPeakChosen; /*!< peak number chosen by the guide */
-} SMS_Guide;
-
/*! \brief analysis format
*
* Is the signal is known to be harmonic, using format harmonic (with out without
@@ -375,10 +425,10 @@ typedef struct
*/
enum SMS_Format
{
- SMS_FORMAT_H, /*!< 0, format harmonic */
- SMS_FORMAT_IH, /*!< 1, format inharmonic */
- SMS_FORMAT_HP, /*!< 2, format harmonic with phase */
- SMS_FORMAT_IHP /*!< 3, format inharmonic with phase */
+ SMS_FORMAT_H, /*!< 0, format harmonic */
+ SMS_FORMAT_IH, /*!< 1, format inharmonic */
+ SMS_FORMAT_HP, /*!< 2, format harmonic with phase */
+ SMS_FORMAT_IHP /*!< 3, format inharmonic with phase */
};
/*! \brief synthesis types
@@ -390,9 +440,9 @@ enum SMS_Format
*/
enum SMS_SynthType
{
- SMS_STYPE_ALL, /*!< both components combined */
- SMS_STYPE_DET, /*!< deterministic component alone */
- SMS_STYPE_STOC /*!< stochastic component alone */
+ SMS_STYPE_ALL, /*!< both components combined */
+ SMS_STYPE_DET, /*!< deterministic component alone */
+ SMS_STYPE_STOC /*!< stochastic component alone */
};
/*! \brief synthesis method for deterministic component
@@ -406,8 +456,8 @@ enum SMS_SynthType
*/
enum SMS_DetSynthType
{
- SMS_DET_IFFT, /*!< Inverse Fast Fourier Transform (IFFT) */
- SMS_DET_SIN /*!< Sinusoidal Table Lookup (SIN) */
+ SMS_DET_IFFT, /*!< Inverse Fast Fourier Transform (IFFT) */
+ SMS_DET_SIN /*!< Sinusoidal Table Lookup (SIN) */
};
/*! \brief synthesis method for stochastic component
@@ -433,9 +483,9 @@ enum SMS_DetSynthType
*/
enum SMS_StocSynthType
{
- SMS_STOC_NONE, /*!< 0, no stochastistic component */
- SMS_STOC_APPROX, /*!< 1, Inverse FFT, magnitude approximation and generated phases */
- SMS_STOC_IFFT /*!< 2, inverse FFT, interpolated spectrum (not used) */
+ SMS_STOC_NONE, /*!< 0, no stochastistic component */
+ SMS_STOC_APPROX, /*!< 1, Inverse FFT, magnitude approximation and generated phases */
+ SMS_STOC_IFFT /*!< 2, inverse FFT, interpolated spectrum (not used) */
};
/*! \brief synthesis method for deterministic component
@@ -449,23 +499,22 @@ enum SMS_StocSynthType
*/
enum SMS_SpecEnvType
{
- SMS_ENV_NONE, /*!< none */
- SMS_ENV_CEP, /*!< cepstral coefficients */
- SMS_ENV_FBINS /*!< frequency bins */
+ SMS_ENV_NONE, /*!< none */
+ SMS_ENV_CEP, /*!< cepstral coefficients */
+ SMS_ENV_FBINS /*!< frequency bins */
};
-
/*! \brief Error codes returned by SMS file functions */
/* \todo remove me */
enum SMS_ERRORS
{
- SMS_OK, /*!< 0, no error*/
- SMS_NOPEN, /*!< 1, couldn't open file */
- SMS_NSMS , /*!< 2, not a SMS file */
- SMS_MALLOC, /*!< 3, couldn't allocate memory */
- SMS_RDERR, /*!< 4, read error */
- SMS_WRERR, /*!< 5, write error */
- SMS_SNDERR /*!< 7, sound IO error */
+ SMS_OK, /*!< 0, no error*/
+ SMS_NOPEN, /*!< 1, couldn't open file */
+ SMS_NSMS , /*!< 2, not a SMS file */
+ SMS_MALLOC, /*!< 3, couldn't allocate memory */
+ SMS_RDERR, /*!< 4, read error */
+ SMS_WRERR, /*!< 5, write error */
+ SMS_SNDERR /*!< 6, sound IO error */
};
/*! \brief debug modes
@@ -474,20 +523,19 @@ enum SMS_ERRORS
*/
enum SMS_DBG
{
- SMS_DBG_NONE, /*!< 0, no debugging */
- SMS_DBG_DET, /*!< 1, not yet implemented \todo make this show main information to look at for discovering the correct deterministic parameters*/
- SMS_DBG_PEAK_DET, /*!< 2, peak detection function */
- SMS_DBG_HARM_DET, /*!< 3, harmonic detection function */
- SMS_DBG_PEAK_CONT, /*!< 4, peak continuation function */
- SMS_DBG_CLEAN_TRAJ, /*!< 5, clean tracks function */
- SMS_DBG_SINE_SYNTH, /*!< 6, sine synthesis function */
- SMS_DBG_STOC_ANAL, /*!< 7, stochastic analysis function */
- SMS_DBG_STOC_SYNTH, /*!< 8, stochastic synthesis function */
- SMS_DBG_SMS_ANAL, /*!< 9, top level analysis function */
- SMS_DBG_ALL, /*!< 10, everything */
- SMS_DBG_RESIDUAL, /*!< 11, write residual to file */
- SMS_DBG_SYNC, /*!< 12, write original, synthesis and residual
- to a text file */
+ SMS_DBG_NONE, /*!< 0, no debugging */
+ SMS_DBG_DET, /*!< 1, not yet implemented \todo make this show main information to look at for discovering the correct deterministic parameters*/
+ SMS_DBG_PEAK_DET, /*!< 2, peak detection function */
+ SMS_DBG_HARM_DET, /*!< 3, harmonic detection function */
+ SMS_DBG_PEAK_CONT, /*!< 4, peak continuation function */
+ SMS_DBG_CLEAN_TRAJ, /*!< 5, clean tracks function */
+ SMS_DBG_SINE_SYNTH, /*!< 6, sine synthesis function */
+ SMS_DBG_STOC_ANAL, /*!< 7, stochastic analysis function */
+ SMS_DBG_STOC_SYNTH, /*!< 8, stochastic synthesis function */
+ SMS_DBG_SMS_ANAL, /*!< 9, top level analysis function */
+ SMS_DBG_ALL, /*!< 10, everything */
+ SMS_DBG_RESIDUAL, /*!< 11, write residual to file */
+ SMS_DBG_SYNC, /*!< 12, write original, synthesis and residual to a text file */
};
#define SMS_MAX_WINDOW 8190 /*!< \brief maximum size for analysis window */
@@ -498,8 +546,8 @@ enum SMS_DBG
*/
enum SMS_SOUND_TYPE
{
- SMS_SOUND_TYPE_MELODY, /*!< 0, sound composed of several notes */
- SMS_SOUND_TYPE_NOTE /*!< 1, sound composed of a single note */
+ SMS_SOUND_TYPE_MELODY, /*!< 0, sound composed of several notes */
+ SMS_SOUND_TYPE_NOTE /*!< 1, sound composed of a single note */
};
/* \brief direction of analysis
@@ -510,22 +558,22 @@ enum SMS_SOUND_TYPE
*/
enum SMS_DIRECTION
{
- SMS_DIR_FWD, /*!< analysis from left to right */
- SMS_DIR_REV /*!< analysis from right to left */
+ SMS_DIR_FWD, /*!< analysis from left to right */
+ SMS_DIR_REV /*!< analysis from right to left */
};
/* \brief window selection
*/
enum SMS_WINDOWS
{
- SMS_WIN_HAMMING, /*!< 0: hamming */
- SMS_WIN_BH_62, /*!< 1: blackman-harris, 62dB cutoff */
- SMS_WIN_BH_70, /*!< 2: blackman-harris, 70dB cutoff */
- SMS_WIN_BH_74, /*!< 3: blackman-harris, 74dB cutoff */
- SMS_WIN_BH_92, /*!< 4: blackman-harris, 92dB cutoff */
- SMS_WIN_HANNING, /*!< 5: hanning */
- SMS_WIN_IFFT /*!< 6: window for deterministic synthesis based on the Inverse-FFT algorithm.
- This is a combination of an inverse Blackman-Harris 92dB and a triangular window. */
+ SMS_WIN_HAMMING, /*!< 0: hamming */
+ SMS_WIN_BH_62, /*!< 1: blackman-harris, 62dB cutoff */
+ SMS_WIN_BH_70, /*!< 2: blackman-harris, 70dB cutoff */
+ SMS_WIN_BH_74, /*!< 3: blackman-harris, 74dB cutoff */
+ SMS_WIN_BH_92, /*!< 4: blackman-harris, 92dB cutoff */
+ SMS_WIN_HANNING, /*!< 5: hanning */
+ SMS_WIN_IFFT /*!< 6: window for deterministic synthesis based on the Inverse-FFT algorithm.
+ This is a combination of an inverse Blackman-Harris 92dB and a triangular window. */
};
/*!
@@ -546,7 +594,6 @@ enum SMS_FRAME_STATUS
SMS_FRAME_END
};
-
#define SMS_MIN_SIZE_FRAME 128 /* size of synthesis frame */
/*! \defgroup math_macros Math Macros
@@ -554,13 +601,13 @@ enum SMS_FRAME_STATUS
* this library
* \{
*/
-#define PI 3.141592653589793238462643 /*!< pi */
+#define PI 3.141592653589793238462643 /*!< pi */
#define TWO_PI 6.28318530717958647692 /*!< pi * 2 */
-#define INV_TWO_PI (1 / TWO_PI) /*!< 1 / ( pi * 2) */
-#define PI_2 1.57079632679489661923 /*!< pi / 2 */
-#define LOG2 0.69314718055994529 /*!< natural logarithm of 2 */
-#define LOG10 2.3025850929940459 /*!< natural logarithm of 10 */
-#define EXP 2.7182818284590451 /*!< Eurler's number */
+#define INV_TWO_PI (1 / TWO_PI) /*!< 1 / ( pi * 2) */
+#define PI_2 1.57079632679489661923 /*!< pi / 2 */
+#define LOG2 0.69314718055994529 /*!< natural logarithm of 2 */
+#define LOG10 2.3025850929940459 /*!< natural logarithm of 10 */
+#define EXP 2.7182818284590451 /*!< Eurler's number */
sfloat sms_magToDB(sfloat x);
sfloat sms_dBToMag(sfloat x);
@@ -588,187 +635,120 @@ void sms_arrayScalarTempered( int sizeArray, sfloat *pArray);
/* function declarations */
void sms_setPeaks(SMS_AnalParams *pAnalParams, int numamps, sfloat* amps,
int numfreqs, sfloat* freqs, int numphases, sfloat* phases);
-
int sms_findPeaks(int sizeWaveform, sfloat *pWaveform, SMS_AnalParams *pAnalParams, SMS_SpectralPeaks *pSpectralPeaks);
-
int sms_findPartials(SMS_Data *pSmsFrame, SMS_AnalParams *pAnalParams);
-
int sms_findResidual(int sizeSynthesis, sfloat* pSynthesis,
int sizeOriginal, sfloat* pOriginal,
int sizeResidual, sfloat* pResidual,
SMS_AnalParams *analParams);
-
int sms_analyze(int sizeWaveform, sfloat *pWaveform, SMS_Data *pSmsData, SMS_AnalParams *pAnalParams);
-
void sms_analyzeFrame(int iCurrentFrame, SMS_AnalParams *pAnalParams, sfloat fRefFundamental);
-int sms_init(void);
-
-void sms_free(void);
-
+int sms_init();
+void sms_free();
int sms_initAnalysis(SMS_AnalParams *pAnalParams);
-
void sms_initAnalParams(SMS_AnalParams *pAnalParams);
-
void sms_changeHopSize(int hopSize, SMS_AnalParams *pAnalParams);
-
void sms_initSynthParams(SMS_SynthParams *synthParams);
-
int sms_initSynth(SMS_SynthParams *pSynthParams);
-
int sms_changeSynthHop(SMS_SynthParams *pSynthParams, int sizeHop);
-
void sms_freeAnalysis(SMS_AnalParams *pAnalParams);
-
void sms_freeSynth(SMS_SynthParams *pSynthParams );
void sms_fillSoundBuffer(int sizeWaveform, sfloat *pWaveform, SMS_AnalParams *pAnalParams);
-
void sms_windowCentered(int sizeWindow, sfloat *pWaveform, sfloat *pWindow, int sizeFft, sfloat *pFftBuffer);
-
void sms_getWindow(int sizeWindow, sfloat *pWindow, int iWindowType);
-
void sms_scaleWindow(int sizeWindow, sfloat *pWindow);
-
int sms_spectrum(int sizeWindow, sfloat *pWaveform, sfloat *pWindow, int sizeMag,
- sfloat *pMag, sfloat *pPhase);
-
+ sfloat *pMag, sfloat *pPhase, sfloat *pFftBuffer);
int sms_invSpectrum(int sizeWaveform, sfloat *pWaveform, sfloat *pWindow ,
- int sizeMag, sfloat *pMag, sfloat *pPhase);
-
+ int sizeMag, sfloat *pMag, sfloat *pPhase, sfloat *pFftBuffer);
/* \todo remove this once invSpectrum is completely implemented */
int sms_invQuickSpectrumW(sfloat *pFMagSpectrum, sfloat *pFPhaseSpectrum,
int sizeFft, sfloat *pFWaveform, int sizeWave,
- sfloat *pFWindow);
-
+ sfloat *pFWindow, sfloat *pFftBuffer);
int sms_spectralApprox(sfloat *pSpec1, int sizeSpec1, int sizeSpec1Used,
- sfloat *pSpec2, int sizeSpec2, int nCoefficients);
-
+ sfloat *pSpec2, int sizeSpec2, int nCoefficients,
+ sfloat *envelope);
int sms_spectrumMag(int sizeWindow, sfloat *pWaveform, sfloat *pWindow,
- int sizeMag, sfloat *pMag);
+ int sizeMag, sfloat *pMag, sfloat *pFftBuffer);
void sms_dCepstrum(int sizeCepstrum, sfloat *pCepstrum, int sizeFreq, sfloat *pFreq, sfloat *pMag,
sfloat fLambda, int iSamplingRate);
-
void sms_dCepstrumEnvelope(int sizeCepstrum, sfloat *pCepstrum, int sizeEnv, sfloat *pEnv);
-
void sms_spectralEnvelope(SMS_Data *pSmsData, SMS_SEnvParams *pSpecEnvParams);
int sms_sizeNextWindow(int iCurrentFrame, SMS_AnalParams *pAnalParams);
-
sfloat sms_fundDeviation(SMS_AnalParams *pAnalParams, int iCurrentFrame);
-
int sms_detectPeaks(int sizeSpec, sfloat *pFMag, sfloat *pPhase,
SMS_Peak *pSpectralPeaks, SMS_AnalParams *pAnalParams);
-
sfloat sms_harmDetection(int numPeaks, SMS_Peak* spectralPeaks, sfloat refFundamental,
- sfloat refHarmonic, sfloat lowestFreq, sfloat highestFreq,
- int soundType, sfloat minRefHarmMag, sfloat refHarmMagDiffFromMax);
-
-int sms_peakContinuation (int iFrame, SMS_AnalParams *pAnalParams);
-
-sfloat sms_preEmphasis (sfloat fInput, SMS_AnalParams *pAnalParams);
+ sfloat refHarmonic, sfloat lowestFreq, sfloat highestFreq,
+ int soundType, sfloat minRefHarmMag, sfloat refHarmMagDiffFromMax);
+int sms_peakContinuation(int iFrame, SMS_AnalParams *pAnalParams);
+sfloat sms_preEmphasis(sfloat fInput, SMS_AnalParams *pAnalParams);
sfloat sms_deEmphasis(sfloat fInput, SMS_SynthParams *pSynthParams);
-void sms_cleanTracks (int iCurrentFrame, SMS_AnalParams *pAnalParams);
-
-void sms_scaleDet (sfloat *pSynthBuffer, sfloat *pOriginalBuffer,
- sfloat *pSinAmp, SMS_AnalParams *pAnalParams, int nTracks);
-
-int sms_prepSine (int nTableSize);
-
-int sms_prepSinc (int nTableSize);
-
-void sms_clearSine( void );
-
-void sms_clearSinc( void );
-
-void sms_synthesize (SMS_Data *pSmsFrame, sfloat*pSynthesis,
- SMS_SynthParams *pSynthParams);
-
-void sms_sineSynthFrame (SMS_Data *pSmsFrame, sfloat *pBuffer,
- int sizeBuffer, SMS_Data *pLastFrame,
- int iSamplingRate);
-
-void sms_initHeader (SMS_Header *pSmsHeader);
-
-int sms_getHeader (char *pChFileName, SMS_Header **ppSmsHeader,
- FILE **ppInputFile);
-
-void sms_fillHeader (SMS_Header *pSmsHeader, SMS_AnalParams *pAnalParams,
- char *pProgramString);
-
-int sms_writeHeader (char *pFileName, SMS_Header *pSmsHeader,
- FILE **ppOutSmsFile);
-
-int sms_writeFile (FILE *pSmsFile, SMS_Header *pSmsHeader);
-
-int sms_initFrame (int iCurrentFrame, SMS_AnalParams *pAnalParams,
- int sizeWindow);
-
-int sms_allocFrame (SMS_Data *pSmsFrame, int nTracks, int nCoeff,
- int iPhase, int stochType, int nEnvCoeff);
-
-int sms_allocFrameH (SMS_Header *pSmsHeader, SMS_Data *pSmsFrame);
-
-int sms_getFrame (FILE *pInputFile, SMS_Header *pSmsHeader, int iFrame,
- SMS_Data *pSmsFrame);
-
-int sms_writeFrame (FILE *pSmsFile, SMS_Header *pSmsHeader,
- SMS_Data *pSmsFrame);
-
-void sms_freeFrame (SMS_Data *pSmsFrame);
-
-void sms_clearFrame (SMS_Data *pSmsFrame);
-
-void sms_copyFrame (SMS_Data *pCopySmsFrame, SMS_Data *pOriginalSmsFrame);
-
-int sms_frameSizeB (SMS_Header *pSmsHeader);
-
-int sms_residual (int sizeWindow, sfloat *pSynthesis, sfloat *pOriginal, sfloat *pResidual);
-
-void sms_filterHighPass ( int sizeResidual, sfloat *pResidual, int iSamplingRate);
-
-int sms_stocAnalysis ( int sizeWindow, sfloat *pResidual, sfloat *pWindow,
- SMS_Data *pSmsFrame);
-
-void sms_interpolateFrames (SMS_Data *pSmsFrame1, SMS_Data *pSmsFrame2,
- SMS_Data *pSmsFrameOut, sfloat fInterpFactor);
-
+void sms_cleanTracks(int iCurrentFrame, SMS_AnalParams *pAnalParams);
+void sms_scaleDet(sfloat *pSynthBuffer, sfloat *pOriginalBuffer,
+ sfloat *pSinAmp, SMS_AnalParams *pAnalParams, int nTracks);
+
+int sms_prepSine(int nTableSize);
+int sms_prepSinc(int nTableSize);
+void sms_clearSine();
+void sms_clearSinc();
+
+void sms_synthesize(SMS_Data *pSmsFrame, sfloat*pSynthesis, SMS_SynthParams *pSynthParams);
+void sms_sineSynthFrame(SMS_Data *pSmsFrame, sfloat *pBuffer,
+ int sizeBuffer, SMS_Data *pLastFrame,
+ int iSamplingRate);
+
+void sms_initHeader(SMS_Header *pSmsHeader);
+int sms_getHeader(char *pChFileName, SMS_Header **ppSmsHeader, FILE **ppInputFile);
+void sms_fillHeader(SMS_Header *pSmsHeader, SMS_AnalParams *pAnalParams, char *pProgramString);
+int sms_writeHeader(char *pFileName, SMS_Header *pSmsHeader, FILE **ppOutSmsFile);
+int sms_writeFile(FILE *pSmsFile, SMS_Header *pSmsHeader);
+int sms_initFrame(int iCurrentFrame, SMS_AnalParams *pAnalParams, int sizeWindow);
+int sms_allocFrame(SMS_Data *pSmsFrame, int nTracks, int nCoeff,
+ int iPhase, int stochType, int nEnvCoeff);
+int sms_allocFrameH(SMS_Header *pSmsHeader, SMS_Data *pSmsFrame);
+int sms_getFrame(FILE *pInputFile, SMS_Header *pSmsHeader, int iFrame, SMS_Data *pSmsFrame);
+int sms_writeFrame(FILE *pSmsFile, SMS_Header *pSmsHeader, SMS_Data *pSmsFrame);
+void sms_freeFrame(SMS_Data *pSmsFrame);
+void sms_clearFrame(SMS_Data *pSmsFrame);
+void sms_copyFrame(SMS_Data *pCopySmsFrame, SMS_Data *pOriginalSmsFrame);
+int sms_frameSizeB(SMS_Header *pSmsHeader);
+
+int sms_residual(int sizeWindow, sfloat *pSynthesis, sfloat *pOriginal,
+ sfloat *pResidual, sfloat *pWindow);
+void sms_filterHighPass(int sizeResidual, sfloat *pResidual, int iSamplingRate);
+int sms_stocAnalysis(int sizeWindow, sfloat *pResidual, sfloat *pWindow,
+ SMS_Data *pSmsFrame, SMS_AnalParams *pAnalParams);
+
+void sms_interpolateFrames(SMS_Data *pSmsFrame1, SMS_Data *pSmsFrame2,
+ SMS_Data *pSmsFrameOut, sfloat fInterpFactor);
void sms_fft(int sizeFft, sfloat *pArray);
-
void sms_ifft(int sizeFft, sfloat *pArray);
-
-void sms_RectToPolar( int sizeSpec, sfloat *pReal, sfloat *pMag, sfloat *pPhase);
-
-void sms_PolarToRect( int sizeSpec, sfloat *pReal, sfloat *pMag, sfloat *pPhase);
-
-void sms_spectrumRMS( int sizeMag, sfloat *pReal, sfloat *pMag);
+void sms_RectToPolar(int sizeSpec, sfloat *pReal, sfloat *pMag, sfloat *pPhase);
+void sms_PolarToRect(int sizeSpec, sfloat *pReal, sfloat *pMag, sfloat *pPhase);
+void sms_spectrumRMS(int sizeMag, sfloat *pReal, sfloat *pMag);
void sms_initModify(SMS_Header *header, SMS_ModifyParams *params);
-
void sms_initModifyParams(SMS_ModifyParams *params);
-
void sms_freeModify(SMS_ModifyParams *params);
-
void sms_modify(SMS_Data *frame, SMS_ModifyParams *params);
/***********************************************************************************/
/************* debug functions: ******************************************************/
-int sms_createDebugFile (SMS_AnalParams *pAnalParams);
-
-void sms_writeDebugData (sfloat *pBuffer1, sfloat *pBuffer2,
- sfloat *pBuffer3, int sizeBuffer);
-
-void sms_writeDebugFile ( void );
-
-void sms_error( char *pErrorMessage );
-
-int sms_errorCheck( void );
-
-char* sms_errorString( void );
+int sms_createDebugFile(SMS_AnalParams *pAnalParams);
+void sms_writeDebugData(sfloat *pBuffer1, sfloat *pBuffer2,
+ sfloat *pBuffer3, int sizeBuffer);
+void sms_writeDebugFile();
+void sms_error(char *pErrorMessage );
+int sms_errorCheck();
+char* sms_errorString();
#endif /* _SMS_H */
diff --git a/sms/sms.i b/sms/sms.i
index e091312..d33c280 100644
--- a/sms/sms.i
+++ b/sms/sms.i
@@ -1,4 +1,4 @@
-%module pysms
+%module simplsms
%{
#include "sms.h"
#define SWIG_FILE_WITH_INIT
@@ -9,7 +9,6 @@
%init
%{
import_array();
- sms_init(); /* initialize the library (makes some tables, seeds the random number generator, etc */
%}
%exception
@@ -23,24 +22,24 @@
}
/* apply all numpy typemaps to various names in sms.h */
-%apply (int DIM1, double* INPLACE_ARRAY1) {(int sizeWindow, double* pWindow)};
-%apply (int DIM1, double* INPLACE_ARRAY1) {(int sizeWaveform, double* pWaveform)};
-%apply (int DIM1, double* INPLACE_ARRAY1) {(long sizeSound, double* pSound)};
-%apply (int DIM1, double* INPLACE_ARRAY1) {(int sizeFft, double* pArray)};
-%apply (int DIM1, double* INPLACE_ARRAY1) {(int sizeFft, double* pFftBuffer)};
-%apply (int DIM1, double* INPLACE_ARRAY1) {(int sizeFreq, double* pFreq)};
-%apply (int DIM1, double* INPLACE_ARRAY1) {(int sizeAmp, double* pAmp)};
-%apply (int DIM1, double* INPLACE_ARRAY1) {(int sizeMag, double* pMag)};
-%apply (int DIM1, double* INPLACE_ARRAY1) {(int sizePhase, double* pPhase)};
-%apply (int DIM1, double* INPLACE_ARRAY1) {(int sizeRes, double* pRes)};
-%apply (int DIM1, double* INPLACE_ARRAY1) {(int sizeCepstrum, double* pCepstrum)};
-%apply (int DIM1, double* INPLACE_ARRAY1) {(int sizeEnv, double* pEnv)};
-%apply (int DIM1, double* INPLACE_ARRAY1) {(int sizeTrack, double* pTrack)};
-%apply (int DIM1, double* INPLACE_ARRAY1) {(int sizeArray, double* pArray)};
-%apply (int DIM1, double* IN_ARRAY1) {(int sizeInArray, double* pInArray)};
-%apply (int DIM1, double* INPLACE_ARRAY1) {(int sizeOutArray, double* pOutArray)};
-%apply (int DIM1, double* INPLACE_ARRAY1) {(int sizeHop, double* pSynthesis)};
-%apply (int DIM1, double* IN_ARRAY1)
+%apply(int DIM1, double* INPLACE_ARRAY1) {(int sizeWindow, double* pWindow)};
+%apply(int DIM1, double* INPLACE_ARRAY1) {(int sizeWaveform, double* pWaveform)};
+%apply(int DIM1, double* INPLACE_ARRAY1) {(long sizeSound, double* pSound)};
+%apply(int DIM1, double* INPLACE_ARRAY1) {(int sizeFft, double* pArray)};
+%apply(int DIM1, double* INPLACE_ARRAY1) {(int sizeFft, double* pFftBuffer)};
+%apply(int DIM1, double* INPLACE_ARRAY1) {(int sizeFreq, double* pFreq)};
+%apply(int DIM1, double* INPLACE_ARRAY1) {(int sizeAmp, double* pAmp)};
+%apply(int DIM1, double* INPLACE_ARRAY1) {(int sizeMag, double* pMag)};
+%apply(int DIM1, double* INPLACE_ARRAY1) {(int sizePhase, double* pPhase)};
+%apply(int DIM1, double* INPLACE_ARRAY1) {(int sizeRes, double* pRes)};
+%apply(int DIM1, double* INPLACE_ARRAY1) {(int sizeCepstrum, double* pCepstrum)};
+%apply(int DIM1, double* INPLACE_ARRAY1) {(int sizeEnv, double* pEnv)};
+%apply(int DIM1, double* INPLACE_ARRAY1) {(int sizeTrack, double* pTrack)};
+%apply(int DIM1, double* INPLACE_ARRAY1) {(int sizeArray, double* pArray)};
+%apply(int DIM1, double* IN_ARRAY1) {(int sizeInArray, double* pInArray)};
+%apply(int DIM1, double* INPLACE_ARRAY1) {(int sizeOutArray, double* pOutArray)};
+%apply(int DIM1, double* INPLACE_ARRAY1) {(int sizeHop, double* pSynthesis)};
+%apply(int DIM1, double* IN_ARRAY1)
{
(int numamps, double* amps),
(int numfreqs, double* freqs),
@@ -55,17 +54,16 @@
%include "sms.h"
-
/* overload the functions that will be wrapped to fit numpy typmaps (defined below)
* by renaming the wrapped names back to originals
*/
-%rename (sms_detectPeaks) simplsms_detectPeaks;
-%rename (sms_spectrum) simplsms_spectrum;
-%rename (sms_spectrumMag) simplsms_spectrumMag;
-%rename (sms_windowCentered) simplsms_windowCentered;
-%rename (sms_invSpectrum) simplsms_invSpectrum;
-%rename (sms_dCepstrum) simplsms_dCepstrum;
-%rename (sms_synthesize) simplsms_synthesize_wrapper;
+%rename(sms_detectPeaks) simplsms_detectPeaks;
+%rename(sms_spectrum) simplsms_spectrum;
+%rename(sms_spectrumMag) simplsms_spectrumMag;
+%rename(sms_windowCentered) simplsms_windowCentered;
+%rename(sms_invSpectrum) simplsms_invSpectrum;
+%rename(sms_dCepstrum) simplsms_dCepstrum;
+%rename(sms_synthesize) simplsms_synthesize_wrapper;
%inline
%{
@@ -76,8 +74,8 @@
int allocated;
} SMS_File;
- void simplsms_dCepstrum( int sizeCepstrum, sfloat *pCepstrum, int sizeFreq, sfloat *pFreq, int sizeMag, sfloat *pMag,
- sfloat fLambda, int iSamplingRate)
+ void simplsms_dCepstrum(int sizeCepstrum, sfloat *pCepstrum, int sizeFreq, sfloat *pFreq, int sizeMag, sfloat *pMag,
+ sfloat fLambda, int iSamplingRate)
{
sms_dCepstrum(sizeCepstrum,pCepstrum, sizeFreq, pFreq, pMag,
fLambda, iSamplingRate);
@@ -98,23 +96,23 @@
pPeakStruct->nPeaksFound = sms_detectPeaks(sizeMag, pMag, pPhase, pPeakStruct->pSpectralPeaks, pAnalParams);
return pPeakStruct->nPeaksFound;
}
- int simplsms_spectrum( int sizeWaveform, sfloat *pWaveform, int sizeWindow, sfloat *pWindow,
- int sizeMag, sfloat *pMag, int sizePhase, sfloat *pPhase)
+ int simplsms_spectrum(int sizeWaveform, sfloat *pWaveform, int sizeWindow, sfloat *pWindow,
+ int sizeMag, sfloat *pMag, int sizePhase, sfloat *pPhase, sfloat *pFftBuffer)
{
- return(sms_spectrum(sizeWindow, pWaveform, pWindow, sizeMag, pMag, pPhase));
+ return sms_spectrum(sizeWindow, pWaveform, pWindow, sizeMag, pMag, pPhase, pFftBuffer);
}
- int simplsms_spectrumMag( int sizeWaveform, sfloat *pWaveform, int sizeWindow, sfloat *pWindow,
- int sizeMag, sfloat *pMag)
+ int simplsms_spectrumMag(int sizeWaveform, sfloat *pWaveform, int sizeWindow, sfloat *pWindow,
+ int sizeMag, sfloat *pMag, sfloat *pFftBuffer)
{
- return(sms_spectrumMag(sizeWindow, pWaveform, pWindow, sizeMag, pMag));
+ return sms_spectrumMag(sizeWindow, pWaveform, pWindow, sizeMag, pMag, pFftBuffer);
}
- int simplsms_invSpectrum( int sizeWaveform, sfloat *pWaveform, int sizeWindow, sfloat *pWindow,
- int sizeMag, sfloat *pMag, int sizePhase, sfloat *pPhase)
+ int simplsms_invSpectrum(int sizeWaveform, sfloat *pWaveform, int sizeWindow, sfloat *pWindow,
+ int sizeMag, sfloat *pMag, int sizePhase, sfloat *pPhase, sfloat *pFftBuffer)
{
- return(sms_invSpectrum(sizeWaveform, pWaveform, pWindow, sizeMag, pMag, pPhase));
+ return sms_invSpectrum(sizeWaveform, pWaveform, pWindow, sizeMag, pMag, pPhase, pFftBuffer);
}
void simplsms_windowCentered(int sizeWaveform, sfloat *pWaveform, int sizeWindow,
- sfloat *pWindow, int sizeFft, sfloat *pFftBuffer)
+ sfloat *pWindow, int sizeFft, sfloat *pFftBuffer)
{
if (sizeWaveform != sizeWindow)
{
@@ -132,405 +130,389 @@
}
sms_synthesize(pSmsData, pSynthesis, pSynthParams);
}
-
%}
%extend SMS_File
{
/* load an entire file to an internal numpy array */
- void load( char *pFilename )
+ void load(char *pFilename)
{
- int i;
- FILE *pSmsFile;
- $self->allocated = 0;
- sms_getHeader (pFilename, &$self->header, &pSmsFile);
- if(sms_errorCheck()) return;
-
- $self->smsData = calloc($self->header->nFrames, sizeof(SMS_Data));
- for( i = 0; i < $self->header->nFrames; i++ )
- {
- sms_allocFrameH ($self->header, &$self->smsData[i]);
- if(sms_errorCheck()) return;
- sms_getFrame (pSmsFile, $self->header, i, &$self->smsData[i]);
- if(sms_errorCheck()) return;
- }
- $self->allocated = 1;
- return;
+ int i;
+ FILE *pSmsFile;
+ $self->allocated = 0;
+ sms_getHeader (pFilename, &$self->header, &pSmsFile);
+ if(sms_errorCheck()) return;
+
+ $self->smsData = calloc($self->header->nFrames, sizeof(SMS_Data));
+ for(i = 0; i < $self->header->nFrames; i++)
+ {
+ sms_allocFrameH ($self->header, &$self->smsData[i]);
+ if(sms_errorCheck())
+ return;
+ sms_getFrame (pSmsFile, $self->header, i, &$self->smsData[i]);
+ if(sms_errorCheck())
+ return;
+ }
+ $self->allocated = 1;
}
- void close(void) /* todo: this should be in the destructor, no? */
+ void close() /* todo: this should be in the destructor, no? */
{
- int i;
- if(!$self->allocated)
- {
- sms_error("file not yet alloceted");
- return;
- }
- $self->allocated = 0;
- for( i = 0; i < $self->header->nFrames; i++)
- sms_freeFrame(&$self->smsData[i]);
- free($self->smsData);
+ int i;
+ if(!$self->allocated)
+ {
+ sms_error("file not yet alloceted");
return;
+ }
+ $self->allocated = 0;
+ for(i = 0; i < $self->header->nFrames; i++)
+ sms_freeFrame(&$self->smsData[i]);
+ free($self->smsData);
}
/* return a pointer to a frame, which can be passed around to other libsms functions */
void getFrame(int i, SMS_Data *frame)
{
- if(i < 0 || i >= $self->header->nFrames)
- {
- sms_error("index is out of file boundaries");
- return;
- }
- frame = &$self->smsData[i];
+ if(i < 0 || i >= $self->header->nFrames)
+ {
+ sms_error("index is out of file boundaries");
+ return;
+ }
+ frame = &$self->smsData[i];
}
- void getTrack(int track, int sizeFreq, sfloat *pFreq, int sizeAmp,
- sfloat *pAmp)
+ void getTrack(int track, int sizeFreq, sfloat *pFreq, int sizeAmp, sfloat *pAmp)
{
- /* fatal error protection first */
- if(!$self->allocated)
- {
- sms_error("file not yet alloceted");
- return ;
- }
- if(track >= $self->header->nTracks)
- {
- sms_error("desired track is greater than number of tracks in file");
- return;
- }
- if(sizeFreq != sizeAmp)
- {
- sms_error("freq and amp arrays are different in size");
- return;
- }
- /* make sure arrays are big enough, or return less data */
- int nFrames = MIN (sizeFreq, $self->header->nFrames);
- int i;
- for( i=0; i < nFrames; i++)
- {
- pFreq[i] = $self->smsData[i].pFSinFreq[track];
- pAmp[i] = $self->smsData[i].pFSinAmp[track];
- }
+ /* fatal error protection first */
+ if(!$self->allocated)
+ {
+ sms_error("file not yet alloceted");
+ return;
+ }
+ if(track >= $self->header->nTracks)
+ {
+ sms_error("desired track is greater than number of tracks in file");
+ return;
+ }
+ if(sizeFreq != sizeAmp)
+ {
+ sms_error("freq and amp arrays are different in size");
+ return;
+ }
+ /* make sure arrays are big enough, or return less data */
+ int nFrames = MIN(sizeFreq, $self->header->nFrames);
+ int i;
+ for(i=0; i < nFrames; i++)
+ {
+ pFreq[i] = $self->smsData[i].pFSinFreq[track];
+ pAmp[i] = $self->smsData[i].pFSinAmp[track];
+ }
}
// TODO turn into getTrackP - and check if phase exists
void getTrack(int track, int sizeFreq, sfloat *pFreq, int sizeAmp,
- sfloat *pAmp, int sizePhase, sfloat *pPhase)
+ sfloat *pAmp, int sizePhase, sfloat *pPhase)
{
- /* fatal error protection first */
- if(!$self->allocated)
- {
- sms_error("file not yet alloceted");
- return ;
- }
- if(track >= $self->header->nTracks)
- {
- sms_error("desired track is greater than number of tracks in file");
- return;
- }
- if(sizeFreq != sizeAmp)
- {
- sms_error("freq and amp arrays are different in size");
- return;
- }
- /* make sure arrays are big enough, or return less data */
- int nFrames = MIN (sizeFreq, $self->header->nFrames);
- int i;
- for( i=0; i < nFrames; i++)
- {
- pFreq[i] = $self->smsData[i].pFSinFreq[track];
- pAmp[i] = $self->smsData[i].pFSinFreq[track];
- }
- if($self->header->iFormat < SMS_FORMAT_HP) return;
-
- if(sizePhase != sizeFreq || sizePhase != sizeAmp)
- {
- sms_error("phase array and freq/amp arrays are different in size");
- return;
- }
- for( i=0; i < nFrames; i++)
- pPhase[i] = $self->smsData[i].pFSinPha[track];
-
+ /* fatal error protection first */
+ if(!$self->allocated)
+ {
+ sms_error("file not yet alloceted");
return;
+ }
+ if(track >= $self->header->nTracks)
+ {
+ sms_error("desired track is greater than number of tracks in file");
+ return;
+ }
+ if(sizeFreq != sizeAmp)
+ {
+ sms_error("freq and amp arrays are different in size");
+ return;
+ }
+ /* make sure arrays are big enough, or return less data */
+ int nFrames = MIN (sizeFreq, $self->header->nFrames);
+ int i;
+ for(i=0; i < nFrames; i++)
+ {
+ pFreq[i] = $self->smsData[i].pFSinFreq[track];
+ pAmp[i] = $self->smsData[i].pFSinFreq[track];
+ }
+ if($self->header->iFormat < SMS_FORMAT_HP)
+ return;
+
+ if(sizePhase != sizeFreq || sizePhase != sizeAmp)
+ {
+ sms_error("phase array and freq/amp arrays are different in size");
+ return;
+ }
+ for(i=0; i < nFrames; i++)
+ pPhase[i] = $self->smsData[i].pFSinPha[track];
}
void getFrameDet(int i, int sizeFreq, sfloat *pFreq, int sizeAmp, sfloat *pAmp)
{
- if(!$self->allocated)
- {
- sms_error("file not yet alloceted");
- return ;
- }
- if(i >= $self->header->nFrames)
- {
- sms_error("index is greater than number of frames in file");
- return;
- }
- int nTracks = $self->smsData[i].nTracks;
- if(sizeFreq > nTracks)
- {
- sms_error("index is greater than number of frames in file");
- return;
- }
- if(sizeFreq != sizeAmp)
- {
- sms_error("freq and amp arrays are different in size");
- return;
- }
- memcpy(pFreq, $self->smsData[i].pFSinFreq, sizeof(sfloat) * nTracks);
- memcpy(pAmp, $self->smsData[i].pFSinAmp, sizeof(sfloat) * nTracks);
-
- if($self->header->iFormat < SMS_FORMAT_HP) return;
-
+ if(!$self->allocated)
+ {
+ sms_error("file not yet alloceted");
+ return;
+ }
+ if(i >= $self->header->nFrames)
+ {
+ sms_error("index is greater than number of frames in file");
+ return;
+ }
+ int nTracks = $self->smsData[i].nTracks;
+ if(sizeFreq > nTracks)
+ {
+ sms_error("index is greater than number of frames in file");
return;
+ }
+ if(sizeFreq != sizeAmp)
+ {
+ sms_error("freq and amp arrays are different in size");
+ return;
+ }
+ memcpy(pFreq, $self->smsData[i].pFSinFreq, sizeof(sfloat) * nTracks);
+ memcpy(pAmp, $self->smsData[i].pFSinAmp, sizeof(sfloat) * nTracks);
}
void getFrameDetP(int i, int sizeFreq, sfloat *pFreq, int sizeAmp,
- sfloat *pAmp, int sizePhase, sfloat *pPhase)
+ sfloat *pAmp, int sizePhase, sfloat *pPhase)
{
- if(!$self->allocated)
- {
- sms_error("file not yet alloceted");
- return ;
- }
- if($self->header->iFormat < SMS_FORMAT_HP)
- {
- sms_error("file does not contain a phase component in Deterministic (iFormat < SMS_FORMAT_HP)");
- return;
- }
- if(i >= $self->header->nFrames)
- {
- sms_error("index is greater than number of frames in file");
- return;
- }
- int nTracks = $self->smsData[i].nTracks;
- if(sizeFreq > nTracks)
- {
- sms_error("index is greater than number of frames in file");
- return;
- }
- if(sizeFreq != sizeAmp)
- {
- sms_error("freq and amp arrays are different in size");
- return;
- }
- memcpy(pFreq, $self->smsData[i].pFSinFreq, sizeof(sfloat) * nTracks);
- memcpy(pAmp, $self->smsData[i].pFSinAmp, sizeof(sfloat) * nTracks);
-
- if(sizePhase != sizeFreq || sizePhase != sizeAmp)
- {
- sms_error("phase array and freq/amp arrays are different in size");
- return;
- }
- memcpy(pPhase, $self->smsData[i].pFSinPha, sizeof(sfloat) * nTracks);
-
+ if(!$self->allocated)
+ {
+ sms_error("file not yet alloceted");
+ return;
+ }
+ if($self->header->iFormat < SMS_FORMAT_HP)
+ {
+ sms_error("file does not contain a phase component in Deterministic (iFormat < SMS_FORMAT_HP)");
+ return;
+ }
+ if(i >= $self->header->nFrames)
+ {
+ sms_error("index is greater than number of frames in file");
+ return;
+ }
+ int nTracks = $self->smsData[i].nTracks;
+ if(sizeFreq > nTracks)
+ {
+ sms_error("index is greater than number of frames in file");
return;
+ }
+ if(sizeFreq != sizeAmp)
+ {
+ sms_error("freq and amp arrays are different in size");
+ return;
+ }
+ memcpy(pFreq, $self->smsData[i].pFSinFreq, sizeof(sfloat) * nTracks);
+ memcpy(pAmp, $self->smsData[i].pFSinAmp, sizeof(sfloat) * nTracks);
+
+ if(sizePhase != sizeFreq || sizePhase != sizeAmp)
+ {
+ sms_error("phase array and freq/amp arrays are different in size");
+ return;
+ }
+ memcpy(pPhase, $self->smsData[i].pFSinPha, sizeof(sfloat) * nTracks);
}
void getFrameRes(int i, int sizeRes, sfloat *pRes)
{
-
- if(!$self->allocated)
- {
- sms_error("file not yet alloceted");
- return ;
- }
- if($self->header->iStochasticType < 1)
- {
- sms_error("file does not contain a stochastic component");
- return ;
- }
- int nCoeff = sizeRes;
- if($self->header->nStochasticCoeff > sizeRes)
- nCoeff = $self->header->nStochasticCoeff; // return what you can
-
- memcpy(pRes, $self->smsData[i].pFStocCoeff, sizeof(sfloat) * nCoeff);
+ if(!$self->allocated)
+ {
+ sms_error("file not yet alloceted");
return;
+ }
+ if($self->header->iStochasticType < 1)
+ {
+ sms_error("file does not contain a stochastic component");
+ return;
+ }
+ int nCoeff = sizeRes;
+ if($self->header->nStochasticCoeff > sizeRes)
+ nCoeff = $self->header->nStochasticCoeff; // return what you can
+
+ memcpy(pRes, $self->smsData[i].pFStocCoeff, sizeof(sfloat) * nCoeff);
}
void getFrameEnv(int i, int sizeEnv, sfloat *pEnv)
{
-
- if(!$self->allocated)
- {
- sms_error("file not yet alloceted");
- return ;
- }
- if($self->header->iEnvType < 1)
- {
- sms_error("file does not contain a spectral envelope");
- return ;
- }
- int nCoeff = sizeEnv;
- if($self->header->nStochasticCoeff > sizeEnv)
- nCoeff = $self->header->nEnvCoeff; // return what you can
-
- memcpy(pEnv, $self->smsData[i].pSpecEnv, sizeof(sfloat) * nCoeff);
+ if(!$self->allocated)
+ {
+ sms_error("file not yet alloceted");
return;
+ }
+ if($self->header->iEnvType < 1)
+ {
+ sms_error("file does not contain a spectral envelope");
+ return;
+ }
+ int nCoeff = sizeEnv;
+ if($self->header->nStochasticCoeff > sizeEnv)
+ nCoeff = $self->header->nEnvCoeff; // return what you can
+
+ memcpy(pEnv, $self->smsData[i].pSpecEnv, sizeof(sfloat) * nCoeff);
}
}
%extend SMS_AnalParams
{
- SMS_AnalParams()
- {
- SMS_AnalParams *s = (SMS_AnalParams *)malloc(sizeof(SMS_AnalParams));
- sms_initAnalParams(s);
- return s;
- }
+ SMS_AnalParams()
+ {
+ SMS_AnalParams *s = (SMS_AnalParams *)malloc(sizeof(SMS_AnalParams));
+ sms_initAnalParams(s);
+ return s;
+ }
}
%extend SMS_SynthParams
{
- SMS_SynthParams()
- {
- SMS_SynthParams *s = (SMS_SynthParams *)malloc(sizeof(SMS_SynthParams));
- sms_initSynthParams(s);
- return s;
- }
+ SMS_SynthParams()
+ {
+ SMS_SynthParams *s = (SMS_SynthParams *)malloc(sizeof(SMS_SynthParams));
+ sms_initSynthParams(s);
+ return s;
+ }
}
%extend SMS_SpectralPeaks
{
- SMS_SpectralPeaks(int n)
+ SMS_SpectralPeaks(int n)
+ {
+ SMS_SpectralPeaks *s = (SMS_SpectralPeaks *)malloc(sizeof(SMS_SpectralPeaks));
+ s->nPeaks = n;
+ if((s->pSpectralPeaks = (SMS_Peak *)calloc (s->nPeaks, sizeof(SMS_Peak))) == NULL)
{
- SMS_SpectralPeaks *s = (SMS_SpectralPeaks *)malloc(sizeof(SMS_SpectralPeaks));
- s->nPeaks = n;
- if ((s->pSpectralPeaks =
- (SMS_Peak *)calloc (s->nPeaks, sizeof(SMS_Peak))) == NULL)
- {
- sms_error("could not allocate memory for spectral peaks");
- return(NULL);
- }
- s->nPeaksFound = 0;
- return s;
+ sms_error("could not allocate memory for spectral peaks");
+ return NULL;
}
- void getFreq( int sizeArray, sfloat *pArray )
+ s->nPeaksFound = 0;
+ return s;
+ }
+ void getFreq(int sizeArray, sfloat *pArray )
+ {
+ if(sizeArray < $self->nPeaksFound)
{
- if(sizeArray < $self->nPeaksFound)
- {
- sms_error("numpy array not big enough");
- return;
- }
- int i;
- for (i = 0; i < $self->nPeaksFound; i++)
- pArray[i] = $self->pSpectralPeaks[i].fFreq;
-
+ sms_error("numpy array not big enough");
+ return;
}
- void getMag( int sizeArray, sfloat *pArray )
+ int i;
+ for(i = 0; i < $self->nPeaksFound; i++)
+ pArray[i] = $self->pSpectralPeaks[i].fFreq;
+ }
+ void getMag( int sizeArray, sfloat *pArray )
+ {
+ if(sizeArray < $self->nPeaksFound)
{
- if(sizeArray < $self->nPeaksFound)
- {
- sms_error("numpy array not big enough");
- return;
- }
- int i;
- for (i = 0; i < $self->nPeaksFound; i++)
- pArray[i] = $self->pSpectralPeaks[i].fMag;
+ sms_error("numpy array not big enough");
+ return;
}
- void getPhase( int sizeArray, sfloat *pArray )
+ int i;
+ for(i = 0; i < $self->nPeaksFound; i++)
+ pArray[i] = $self->pSpectralPeaks[i].fMag;
+ }
+ void getPhase( int sizeArray, sfloat *pArray )
+ {
+ if(sizeArray < $self->nPeaksFound)
{
- if(sizeArray < $self->nPeaksFound)
- {
- sms_error("numpy array not big enough");
- return;
- }
- int i;
- for (i = 0; i < $self->nPeaksFound; i++)
- pArray[i] = $self->pSpectralPeaks[i].fPhase;
-
+ sms_error("numpy array not big enough");
+ return;
}
+ int i;
+ for(i = 0; i < $self->nPeaksFound; i++)
+ pArray[i] = $self->pSpectralPeaks[i].fPhase;
+ }
}
%extend SMS_Data
{
- void getSinAmp(int sizeArray, sfloat *pArray)
+ void getSinAmp(int sizeArray, sfloat *pArray)
+ {
+ if(sizeArray < $self->nTracks)
{
- if(sizeArray < $self->nTracks)
- {
- sms_error("numpy array not big enough");
- return;
- }
- int i;
- for (i = 0; i < $self->nTracks; i++)
- pArray[i] = $self->pFSinAmp[i];
+ sms_error("numpy array not big enough");
+ return;
}
- void getSinFreq(int sizeArray, sfloat *pArray)
+ int i;
+ for(i = 0; i < $self->nTracks; i++)
+ pArray[i] = $self->pFSinAmp[i];
+ }
+ void getSinFreq(int sizeArray, sfloat *pArray)
+ {
+ if(sizeArray < $self->nTracks)
{
- if(sizeArray < $self->nTracks)
- {
- sms_error("numpy array not big enough");
- return;
- }
- int i;
- for (i = 0; i < $self->nTracks; i++)
- pArray[i] = $self->pFSinFreq[i];
+ sms_error("numpy array not big enough");
+ return;
}
- void getSinPhase(int sizeArray, sfloat *pArray)
+ int i;
+ for(i = 0; i < $self->nTracks; i++)
+ pArray[i] = $self->pFSinFreq[i];
+ }
+ void getSinPhase(int sizeArray, sfloat *pArray)
+ {
+ if(sizeArray < $self->nTracks)
{
- if(sizeArray < $self->nTracks)
- {
- sms_error("numpy array not big enough");
- return;
- }
- int i;
- for (i = 0; i < $self->nTracks; i++)
- pArray[i] = $self->pFSinPha[i];
+ sms_error("numpy array not big enough");
+ return;
}
- void getSinEnv(int sizeArray, sfloat *pArray)
+ int i;
+ for(i = 0; i < $self->nTracks; i++)
+ pArray[i] = $self->pFSinPha[i];
+ }
+ void getSinEnv(int sizeArray, sfloat *pArray)
+ {
+ if(sizeArray < $self->nEnvCoeff)
{
- if(sizeArray < $self->nEnvCoeff)
- {
- sms_error("numpy array not big enough");
- return;
- }
- int i;
- for (i = 0; i < $self->nEnvCoeff; i++)
- pArray[i] = $self->pSpecEnv[i];
+ sms_error("numpy array not big enough");
+ return;
}
- void setSinAmp(int sizeArray, sfloat *pArray)
+ int i;
+ for(i = 0; i < $self->nEnvCoeff; i++)
+ pArray[i] = $self->pSpecEnv[i];
+ }
+ void setSinAmp(int sizeArray, sfloat *pArray)
+ {
+ if(sizeArray < $self->nTracks)
{
- if(sizeArray < $self->nTracks)
- {
- sms_error("numpy array not big enough");
- return;
- }
- int i;
- for (i = 0; i < $self->nTracks; i++)
- $self->pFSinAmp[i] = pArray[i];
-
+ sms_error("numpy array not big enough");
+ return;
}
- void setSinFreq(int sizeArray, sfloat *pArray)
+ int i;
+ for (i = 0; i < $self->nTracks; i++)
+ $self->pFSinAmp[i] = pArray[i];
+ }
+ void setSinFreq(int sizeArray, sfloat *pArray)
+ {
+ if(sizeArray < $self->nTracks)
{
- if(sizeArray < $self->nTracks)
- {
- sms_error("numpy array not big enough");
- return;
- }
- int i;
- for (i = 0; i < $self->nTracks; i++)
- $self->pFSinFreq[i] = pArray[i];
+ sms_error("numpy array not big enough");
+ return;
}
- void setSinPha(int sizeArray, sfloat *pArray)
+ int i;
+ for(i = 0; i < $self->nTracks; i++)
+ $self->pFSinFreq[i] = pArray[i];
+ }
+ void setSinPha(int sizeArray, sfloat *pArray)
+ {
+ if(sizeArray < $self->nTracks)
{
- if(sizeArray < $self->nTracks)
- {
- sms_error("numpy array not big enough");
- return;
- }
- int i;
- for (i = 0; i < $self->nTracks; i++)
- $self->pFSinPha[i] = pArray[i];
+ sms_error("numpy array not big enough");
+ return;
}
+ int i;
+ for(i = 0; i < $self->nTracks; i++)
+ $self->pFSinPha[i] = pArray[i];
+ }
}
%extend SMS_ModifyParams
{
- /* no need to return an error code, if sms_error is called, it will throw an exception in python */
- void setSinEnv(int sizeArray, sfloat *pArray)
+ /* no need to return an error code, if sms_error is called, it will throw an exception in python */
+ void setSinEnv(int sizeArray, sfloat *pArray)
+ {
+ if(!$self->ready)
{
- if(!$self->ready)
- {
- sms_error("modify parameter structure has not been initialized");
- return;
- }
- if(sizeArray != $self->sizeSinEnv)
- {
- sms_error("numpy array is not equal to envelope size");
- return;
- }
- memcpy($self->sinEnv, pArray, sizeof(sfloat) * $self->sizeSinEnv);
+ sms_error("modify parameter structure has not been initialized");
+ return;
+ }
+ if(sizeArray != $self->sizeSinEnv)
+ {
+ sms_error("numpy array is not equal to envelope size");
+ return;
}
+ memcpy($self->sinEnv, pArray, sizeof(sfloat) * $self->sizeSinEnv);
+ }
}
+
diff --git a/sms/soundIO.c b/sms/soundIO.c
index 1de75d6..1f68506 100644
--- a/sms/soundIO.c
+++ b/sms/soundIO.c
@@ -23,9 +23,6 @@
*/
#include "sms.h"
-const char *pChResidualFile = "residual.aiff";
-#define MAX_SAMPLES 10000
-
/*! \brief fill the sound buffer
*
* \param sizeWaveform size of input data
diff --git a/sms/spectralApprox.c b/sms/spectralApprox.c
index 9e77f7a..c19afbe 100644
--- a/sms/spectralApprox.c
+++ b/sms/spectralApprox.c
@@ -35,121 +35,118 @@
* \param sizeSpec2 size of output envelope
* \param nCoefficients number of coefficients to use in approximation
* \return error code \see SMS_ERRORS (or -1 if the algorithm just messes up,
- it will print an error of its own.
+ * it will print an error of its own.
*/
-int sms_spectralApprox (sfloat *pFSpec1, int sizeSpec1, int sizeSpec1Used,
- sfloat *pFSpec2, int sizeSpec2, int nCoefficients)
+int sms_spectralApprox(sfloat *pFSpec1, int sizeSpec1, int sizeSpec1Used,
+ sfloat *pFSpec2, int sizeSpec2, int nCoefficients,
+ sfloat *envelope)
{
- sfloat fHopSize, fCurrentLoc = 0, fLeft = 0, fRight = 0, fValue = 0,
- fLastLocation, fSizeX, fSpec2Acum=0, fNextHop, fDeltaY, *pFEnvelope;
- int iFirstGood = 0, iLastSample = 0, i, j;
+ sfloat fHopSize, fCurrentLoc = 0, fLeft = 0, fRight = 0, fValue = 0,
+ fLastLocation, fSizeX, fSpec2Acum=0, fNextHop, fDeltaY;
+ int iFirstGood = 0, iLastSample = 0, i, j;
- /* when number of coefficients is smaller than 2 do not approximate */
- if (nCoefficients < 2)
- {
- for (i = 0; i < sizeSpec2; i++)
- pFSpec2[i] = 1;
- return(SMS_OK);
- }
-
- if ((pFEnvelope = (sfloat *) calloc(nCoefficients, sizeof(sfloat))) == NULL)
- return(SMS_MALLOC);
-
- /* calculate the hop size */
- if (sizeSpec1 != sizeSpec1Used)
- fHopSize = (sfloat) sizeSpec1Used / nCoefficients;
- else //why is this here, would be the same as sizeSpec1Used / nCoefficients
- fHopSize = (sfloat) sizeSpec1 / nCoefficients;
- if(nCoefficients > sizeSpec1)
- nCoefficients = sizeSpec1;
+ /* when number of coefficients is smaller than 2 do not approximate */
+ if(nCoefficients < 2)
+ {
+ for (i = 0; i < sizeSpec2; i++)
+ pFSpec2[i] = 1;
+ return SMS_OK;
+ }
+ /* calculate the hop size */
+ if(sizeSpec1 != sizeSpec1Used)
fHopSize = (sfloat) sizeSpec1Used / nCoefficients;
-
- /* approximate by linear interpolation */
- if (fHopSize > 1)
- {
- iFirstGood = 0;
- for (i = 0; i < nCoefficients; i++)
- {
- iLastSample = fLastLocation = fCurrentLoc + fHopSize;
- iLastSample = MIN (sizeSpec1-1, iLastSample);
- if (iLastSample < sizeSpec1-1)
- fRight = pFSpec1[iLastSample] +
- (pFSpec1[iLastSample+1] - pFSpec1[iLastSample]) *
- (fLastLocation - iLastSample);
- else
- fRight = pFSpec1[iLastSample];
- fValue = 0;
- for (j = iFirstGood; j <= iLastSample; j++)
- fValue = MAX (fValue, pFSpec1[j]);
- fValue = MAX (fValue, MAX (fRight, fLeft));
- pFEnvelope[i] = fValue;
- fLeft = fRight;
- fCurrentLoc = fLastLocation;
- iFirstGood = (int) (1+ fCurrentLoc);
- }
- }
- else if (fHopSize == 1)
- {
- for (i = 0; i < nCoefficients; i++)
- pFEnvelope[i] = pFSpec1[i];
- }
- else
- {
- free (pFEnvelope);
- //printf ("SpectralApprox: sizeSpec1 has too many nCoefficients\n"); /* \todo need to increase the frequency? */
- sms_error ("SpectralApprox: sizeSpec1 has too many nCoefficients\n"); /* \todo need to increase the frequency? */
- return -1;
- }
+ else //why is this here, would be the same as sizeSpec1Used / nCoefficients
+ fHopSize = (sfloat) sizeSpec1 / nCoefficients;
+
+ if(nCoefficients > sizeSpec1)
+ nCoefficients = sizeSpec1;
+
+ fHopSize = (sfloat) sizeSpec1Used / nCoefficients;
+
+ /* approximate by linear interpolation */
+ if (fHopSize > 1)
+ {
+ iFirstGood = 0;
+ for(i = 0; i < nCoefficients; i++)
+ {
+ iLastSample = fLastLocation = fCurrentLoc + fHopSize;
+ iLastSample = MIN (sizeSpec1-1, iLastSample);
+ if(iLastSample < sizeSpec1-1)
+ fRight = pFSpec1[iLastSample] +
+ (pFSpec1[iLastSample+1] - pFSpec1[iLastSample]) *
+ (fLastLocation - iLastSample);
+ else
+ fRight = pFSpec1[iLastSample];
+ fValue = 0;
+ for(j = iFirstGood; j <= iLastSample; j++)
+ fValue = MAX (fValue, pFSpec1[j]);
+ fValue = MAX (fValue, MAX (fRight, fLeft));
+ envelope[i] = fValue;
+ fLeft = fRight;
+ fCurrentLoc = fLastLocation;
+ iFirstGood = (int) (1+ fCurrentLoc);
+ }
+ }
+ else if(fHopSize == 1)
+ {
+ for(i = 0; i < nCoefficients; i++)
+ envelope[i] = pFSpec1[i];
+ }
+ else
+ {
+ sms_error("SpectralApprox: sizeSpec1 has too many nCoefficients\n"); /* \todo need to increase the frequency? */
+ return -1;
+ }
+
+ /* Creates Spec2 from Envelope */
+ if(nCoefficients < sizeSpec2)
+ {
+ fSizeX = (sfloat) (sizeSpec2-1) / nCoefficients;
- /* Creates Spec2 from Envelope */
- if (nCoefficients < sizeSpec2)
- {
- fSizeX = (sfloat) (sizeSpec2-1) / nCoefficients;
+ /* the first step */
+ fNextHop = fSizeX / 2;
+ fDeltaY = envelope[0] / fNextHop;
+ fSpec2Acum=pFSpec2[j=0]=0;
+ while(++j < fNextHop)
+ pFSpec2[j] = (fSpec2Acum += fDeltaY);
- /* the first step */
- fNextHop = fSizeX / 2;
- fDeltaY = pFEnvelope[0] / fNextHop;
- fSpec2Acum=pFSpec2[j=0]=0;
- while (++j < fNextHop)
- pFSpec2[j] = (fSpec2Acum += fDeltaY);
-
- /* middle values */
- for (i = 0; i <= nCoefficients-2; ++i)
- {
- fDeltaY = (pFEnvelope[i+1] - pFEnvelope[i]) / fSizeX;
- /* first point of a segment */
- pFSpec2[j] = (fSpec2Acum = (pFEnvelope[i]+(fDeltaY*(j-fNextHop))));
- ++j;
- /* remaining points */
- fNextHop += fSizeX;
- while (j < fNextHop)
- pFSpec2[j++] = (fSpec2Acum += fDeltaY);
- }
+ /* middle values */
+ for(i = 0; i <= nCoefficients-2; ++i)
+ {
+ fDeltaY = (envelope[i+1] - envelope[i]) / fSizeX;
+ /* first point of a segment */
+ pFSpec2[j] = (fSpec2Acum = (envelope[i]+(fDeltaY*(j-fNextHop))));
+ ++j;
+ /* remaining points */
+ fNextHop += fSizeX;
+ while(j < fNextHop)
+ pFSpec2[j++] = (fSpec2Acum += fDeltaY);
+ }
- /* last step */
- fDeltaY = -pFEnvelope[i] * 2 / fSizeX;
- /* first point of the last segment */
- pFSpec2[j] = (fSpec2Acum = (pFEnvelope[i]+(fDeltaY*(j-fNextHop))));
- ++j;
- fNextHop += fSizeX / 2;
- while (j < sizeSpec2-1)
- pFSpec2[j++]=(fSpec2Acum += fDeltaY);
- /* last should be exactly zero */
- pFSpec2[sizeSpec2-1] = .0;
+ /* last step */
+ fDeltaY = -envelope[i] * 2 / fSizeX;
+ /* first point of the last segment */
+ pFSpec2[j] = (fSpec2Acum = (envelope[i]+(fDeltaY*(j-fNextHop))));
+ ++j;
+ fNextHop += fSizeX / 2;
+ while(j < sizeSpec2-1)
+ pFSpec2[j++]=(fSpec2Acum += fDeltaY);
+ /* last should be exactly zero */
+ pFSpec2[sizeSpec2-1] = .0;
+ }
+ else if(nCoefficients == sizeSpec2)
+ {
+ for(i = 0; i < nCoefficients; i++)
+ pFSpec2[i] = envelope[i];
+ }
+ else
+ {
+ sms_error("SpectralApprox: sizeSpec2 has too many nCoefficients\n");
+ return -1;
}
- else if (nCoefficients == sizeSpec2)
- {
- for (i = 0; i < nCoefficients; i++)
- pFSpec2[i] = pFEnvelope[i];
- }
- else
- {
- free (pFEnvelope);
- //printf ("SpectralApprox: sizeSpec2 has too many nCoefficients\n");
- sms_error ("SpectralApprox: sizeSpec2 has too many nCoefficients\n");
- return -1;
- }
- free (pFEnvelope); /* \todo make this a static array */
- return (SMS_OK);
+
+ return SMS_OK;
}
+
+
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); */
-/* } */
diff --git a/sms/stocAnalysis.c b/sms/stocAnalysis.c
index d50df48..d073ee7 100644
--- a/sms/stocAnalysis.c
+++ b/sms/stocAnalysis.c
@@ -26,53 +26,35 @@
#define ENV_THRESHOLD .01 /* \todo was this value for type shorts?? */
/*! \brief main function for the stochastic analysis
- * \param sizeWindow size of buffer
- * \param pResidual pointer to residual signal
+ * \param sizeWindow size of buffer
+ * \param pResidual pointer to residual signal
* \param pWindow pointer to windowing array
- * \param pSmsData pointer to output SMS data
+ * \param pSmsData pointer to output SMS data
+ * \param pAnalParams point to analysis parameters
* \return 0 on success, -1 on error
*/
-int sms_stocAnalysis ( int sizeWindow, sfloat *pResidual, sfloat *pWindow, SMS_Data *pSmsData)
+int sms_stocAnalysis(int sizeWindow, sfloat *pResidual, sfloat *pWindow,
+ SMS_Data *pSmsData, SMS_AnalParams* pAnalParams)
{
- int i;
- sfloat fMag = 0.0;
- sfloat fStocNorm;
+ int i;
+ sfloat fMag = 0.0;
+ sfloat fStocNorm;
- static sfloat *pMagSpectrum;
- static int sizeWindowStatic = 0;
- static int sizeFft = 0;
- static int sizeMag = 0;
- /* update array sizes if sizeWindow is new */
- if (sizeWindowStatic != sizeWindow)
- {
- if(sizeWindowStatic != 0) free(pMagSpectrum);
- sizeWindowStatic = sizeWindow;
- sizeFft = sms_power2(sizeWindow);
- sizeMag = sizeFft >> 1;
- if((pMagSpectrum = (sfloat *) calloc(sizeMag, sizeof(sfloat))) == NULL)
- {
- sms_error("sms_stocAnalysis: error allocating memory for pMagSpectrum");
- return -1;
- }
- }
-
- sms_spectrumMag (sizeWindow, pResidual, pWindow, sizeMag, pMagSpectrum);
-
- sms_spectralApprox (pMagSpectrum, sizeMag, sizeMag, pSmsData->pFStocCoeff,
- pSmsData->nCoeff, pSmsData->nCoeff);
-
- /* get energy of spectrum */
- for (i = 0; i < sizeMag; i++)
- fMag += (pMagSpectrum[i] * pMagSpectrum[i]);
- *pSmsData->pFStocGain = fMag / sizeMag;
- fStocNorm = 1. / *pSmsData->pFStocGain;
+ sms_spectrumMag(sizeWindow, pResidual, pWindow, pAnalParams->sizeStocMagSpectrum,
+ pAnalParams->stocMagSpectrum, pAnalParams->fftBuffer);
- /* normalize envelope */
- /* \todo what good is this scaling, it is only being undone in resynthesis */
-/* for (i = 0; i < pSmsData->nCoeff; i++) */
-/* pSmsData->pFStocCoeff[i] *= fStocNorm; */
-
- // *pSmsData->pFStocGain = sms_magToDB(*pSmsData->pFStocGain);
- return(0);
+ sms_spectralApprox(pAnalParams->stocMagSpectrum, pAnalParams->sizeStocMagSpectrum,
+ pAnalParams->sizeStocMagSpectrum, pSmsData->pFStocCoeff,
+ pSmsData->nCoeff, pSmsData->nCoeff,
+ pAnalParams->approxEnvelope);
+
+ /* get energy of spectrum */
+ for(i = 0; i < pAnalParams->sizeStocMagSpectrum; i++)
+ fMag += (pAnalParams->stocMagSpectrum[i] * pAnalParams->stocMagSpectrum[i]);
+
+ *pSmsData->pFStocGain = fMag / pAnalParams->sizeStocMagSpectrum;
+ fStocNorm = 1. / *pSmsData->pFStocGain;
+
+ return 0;
}
diff --git a/sms/synthesis.c b/sms/synthesis.c
index bba506c..3a8a3bb 100644
--- a/sms/synthesis.c
+++ b/sms/synthesis.c
@@ -28,171 +28,80 @@
* \param pSmsData pointer to SMS data structure frame
* \param pSynthParams pointer to structure of synthesis parameters
*/
-static void SineSynthIFFT (SMS_Data *pSmsData, SMS_SynthParams *pSynthParams)
+static void SineSynthIFFT(SMS_Data *pSmsData, SMS_SynthParams *pSynthParams)
{
- int sizeFft = pSynthParams->sizeHop << 1;
- int iHalfSamplingRate = pSynthParams->iSamplingRate >> 1;
- int sizeMag = pSynthParams->sizeHop;
- int nBins = 8;
- int nTracks = pSmsData->nTracks;
- int iFirstBin, k, i, l, b;
- sfloat fMag=0.0, fFreq=0.0, fPhase=0.0, fLoc, fSin, fCos, fBinRemainder,
- fTmp, fNewMag, fIndex;
- sfloat fSamplingPeriod = 1.0 / pSynthParams->iSamplingRate;
- memset (pSynthParams->pSpectra, 0, sizeFft * sizeof(sfloat));
- for (i = 0; i < nTracks; i++)
+ int sizeFft = pSynthParams->sizeHop << 1;
+ int iHalfSamplingRate = pSynthParams->iSamplingRate >> 1;
+ int sizeMag = pSynthParams->sizeHop;
+ int nBins = 8;
+ int nTracks = pSmsData->nTracks;
+ int iFirstBin, k, i, l, b;
+ sfloat fMag=0.0, fFreq=0.0, fPhase=0.0, fLoc, fSin, fCos, fBinRemainder,
+ fTmp, fNewMag, fIndex;
+ sfloat fSamplingPeriod = 1.0 / pSynthParams->iSamplingRate;
+ memset (pSynthParams->pSpectra, 0, sizeFft * sizeof(sfloat));
+ for (i = 0; i < nTracks; i++)
+ {
+ if(((fMag = pSmsData->pFSinAmp[i]) > 0) &&
+ ((fFreq = (pSmsData->pFSinFreq[i])) < iHalfSamplingRate))
{
- if (((fMag = pSmsData->pFSinAmp[i]) > 0) &&
- ((fFreq = (pSmsData->pFSinFreq[i])) < iHalfSamplingRate))
+ /* \todo maybe this check can be removed if the SynthParams->prevFrame gets random
+ phases in sms_initSynth? */
+ if(pSynthParams->prevFrame.pFSinAmp[i] <= 0)
+ pSynthParams->prevFrame.pFSinPha[i] = TWO_PI * sms_random();
+
+ // fMag = sms_dBToMag(fMag);
+ fTmp = pSynthParams->prevFrame.pFSinPha[i] +
+ TWO_PI * fFreq * fSamplingPeriod * sizeMag;
+ fPhase = fTmp - floor(fTmp * INV_TWO_PI) * TWO_PI;
+ fLoc = sizeFft * fFreq * fSamplingPeriod;
+ iFirstBin = (int) fLoc - 3;
+ fBinRemainder = fLoc - floor (fLoc);
+ fSin = sms_sine(fPhase);
+ fCos = sms_sine(fPhase + PI_2);
+ for (k = 1, l = iFirstBin; k <= nBins; k++, l++)
+ {
+ fIndex = (k - fBinRemainder);
+ if (fIndex > 7.999) fIndex = 0;
+ fNewMag = fMag * sms_sinc (fIndex);
+ if(l > 0 && l < sizeMag)
{
- /* \todo maybe this check can be removed if the SynthParams->prevFrame gets random
- phases in sms_initSynth? */
- if (pSynthParams->prevFrame.pFSinAmp[i] <= 0)
- pSynthParams->prevFrame.pFSinPha[i] = TWO_PI * sms_random();
-
- // fMag = sms_dBToMag (fMag);
- fTmp = pSynthParams->prevFrame.pFSinPha[i] +
- TWO_PI * fFreq * fSamplingPeriod * sizeMag;
- fPhase = fTmp - floor(fTmp * INV_TWO_PI) * TWO_PI;
- fLoc = sizeFft * fFreq * fSamplingPeriod;
- iFirstBin = (int) fLoc - 3;
- fBinRemainder = fLoc - floor (fLoc);
- fSin = sms_sine (fPhase);
- fCos = sms_sine (fPhase + PI_2);
- for (k = 1, l = iFirstBin; k <= nBins; k++, l++)
- {
- fIndex = (k - fBinRemainder);
- if (fIndex > 7.999) fIndex = 0;
- fNewMag = fMag * sms_sinc (fIndex);
- if (l > 0 && l < sizeMag)
- {
- pSynthParams->pSpectra[l*2+1] += fNewMag * fCos;
- pSynthParams->pSpectra[l*2] += fNewMag * fSin;
- }
- else if (l == 0)
- {
- pSynthParams->pSpectra[0] += 2 * fNewMag * fSin;
- }
- else if (l < 0)
- {
- b = abs(l);
- pSynthParams->pSpectra[b*2+1] -= fNewMag * fCos;
- pSynthParams->pSpectra[b*2] += fNewMag * fSin;
- }
- else if (l > sizeMag)
- {
- b = sizeMag - (l - sizeMag);
- pSynthParams->pSpectra[b*2+1] -= fNewMag * fCos;
- pSynthParams->pSpectra[b*2] += fNewMag * fSin;
- }
- else if (l == sizeMag)
- {
- pSynthParams->pSpectra[1] += 2 * fNewMag * fSin;
- }
- }
+ pSynthParams->pSpectra[l*2+1] += fNewMag * fCos;
+ pSynthParams->pSpectra[l*2] += fNewMag * fSin;
}
- pSynthParams->prevFrame.pFSinAmp[i] = fMag;
- pSynthParams->prevFrame.pFSinPha[i] = fPhase;
- pSynthParams->prevFrame.pFSinFreq[i] = fFreq;
- }
-
- sms_ifft(sizeFft, pSynthParams->pSpectra);
-
- for(i = 0, k = sizeMag; i < sizeMag; i++, k++)
- pSynthParams->pSynthBuff[i] += pSynthParams->pSpectra[k] * pSynthParams->pFDetWindow[i];
- for(i= sizeMag, k = 0; i < sizeFft; i++, k++)
- pSynthParams->pSynthBuff[i] += pSynthParams->pSpectra[k] * pSynthParams->pFDetWindow[i];
-
-}
-
-/*! \brief synthesis of one frame of the deterministic component using the IFFT
- *
- *
- * I made this function trying to pull the ifft out of the SineSynthIFFT
- * that part of the code is in the main sms_synthesize function below
- * Next would be sms_stochastic, so they could be summed and synthesized
- * with only one fft, but the problem is that it needs to be 'pre-inverse-windowed'
- * before the stochastic can be summed.
- *
- * \param pSmsData pointer to SMS data structure frame
- * \param pSynthParams pointer to structure of synthesis parameters
- */
-void sms_deterministic (SMS_Data *pSmsData, SMS_SynthParams *pSynthParams)
-{
- int sizeFft = pSynthParams->sizeHop << 1;
- int iHalfSamplingRate = pSynthParams->iSamplingRate >> 1;
- int sizeSpec = pSynthParams->sizeHop;
- int nBins = 8;
- int nTracks = pSmsData->nTracks;
- int iFirstBin, k, i, l, b;
- sfloat fMag=0.0, fFreq=0.0, fPhase=0.0, fLoc, fSin, fCos, fBinRemainder,
- fTmp, fNewMag, fIndex;
- sfloat fSamplingPeriod = 1.0 / pSynthParams->iSamplingRate;
- printf("| in deterministic | ");
-
- for (i = 0; i < nTracks; i++)
- {
- if (((fMag = pSmsData->pFSinAmp[i]) > 0) &&
- (fFreq = pSmsData->pFSinFreq[i] < iHalfSamplingRate)) /* \todo why does this allow f < 0 */
+ else if(l == 0)
{
- /* \todo maybe this check can be removed if the SynthParams->prevFrame gets random
- phases in sms_initSynth? */
- if (pSynthParams->prevFrame.pFSinAmp[i] <= 0)
- pSynthParams->prevFrame.pFSinPha[i] = TWO_PI * sms_random();
-
- //fMag = sms_dBToMag (fMag);
- fTmp = pSynthParams->prevFrame.pFSinPha[i] +
- TWO_PI * fFreq * fSamplingPeriod * sizeSpec;
- fPhase = fTmp - floor(fTmp * INV_TWO_PI) * TWO_PI;
- fLoc = sizeFft * fFreq * fSamplingPeriod;
- iFirstBin = (int) fLoc - 3;
- fBinRemainder = fLoc - floor (fLoc);
- fSin = sms_sine (fPhase);
- fCos = sms_sine (fPhase + PI_2);
- for (k = 1, l = iFirstBin; k <= nBins; k++, l++)
- {
- fIndex = (k - fBinRemainder);
- if (fIndex > 7.999) fIndex = 0;
- fNewMag = fMag * sms_sinc (fIndex);
- if (l > 0 && l < sizeSpec)
- {
- pSynthParams->pSpectra[l*2+1] += fNewMag * fCos;
- pSynthParams->pSpectra[l*2] += fNewMag * fSin;
- }
- else if (l == 0)
- {
- pSynthParams->pSpectra[0] += 2 * fNewMag * fSin;
- }
- else if (l < 0)
- {
- b = abs(l);
- pSynthParams->pSpectra[b*2+1] -= fNewMag * fCos;
- pSynthParams->pSpectra[b*2] += fNewMag * fSin;
- }
- else if (l > sizeSpec)
- {
- b = sizeSpec - (l - sizeSpec);
- pSynthParams->pSpectra[b*2+1] -= fNewMag * fCos;
- pSynthParams->pSpectra[b*2] += fNewMag * fSin;
- }
- else if (l == sizeSpec)
- {
- pSynthParams->pSpectra[1] += 2 * fNewMag * fSin;
- }
- }
+ pSynthParams->pSpectra[0] += 2 * fNewMag * fSin;
}
- pSynthParams->prevFrame.pFSinAmp[i] = fMag;
- pSynthParams->prevFrame.pFSinPha[i] = fPhase;
- pSynthParams->prevFrame.pFSinFreq[i] = fFreq;
+ else if(l < 0)
+ {
+ b = abs(l);
+ pSynthParams->pSpectra[b*2+1] -= fNewMag * fCos;
+ pSynthParams->pSpectra[b*2] += fNewMag * fSin;
+ }
+ else if(l > sizeMag)
+ {
+ b = sizeMag - (l - sizeMag);
+ pSynthParams->pSpectra[b*2+1] -= fNewMag * fCos;
+ pSynthParams->pSpectra[b*2] += fNewMag * fSin;
+ }
+ else if(l == sizeMag)
+ {
+ pSynthParams->pSpectra[1] += 2 * fNewMag * fSin;
+ }
+ }
}
+ pSynthParams->prevFrame.pFSinAmp[i] = fMag;
+ pSynthParams->prevFrame.pFSinPha[i] = fPhase;
+ pSynthParams->prevFrame.pFSinFreq[i] = fFreq;
+ }
-/* sms_ifft(sizeFft, pSynthParams->pSpectra); */
-
-/* for(i = 0, k = sizeMag; i < sizeMag; i++, k++) */
-/* pSynthParams->pSynthBuff[i] += pSynthParams->pSpectra[k] * pSynthParams->pFDetWindow[i]; */
-/* for(i= sizeMag, k = 0; i < sizeFft; i++, k++) */
-/* pSynthParams->pSynthBuff[i] += pSynthParams->pSpectra[k] * pSynthParams->pFDetWindow[i]; */
+ sms_ifft(sizeFft, pSynthParams->pSpectra);
+ for(i = 0, k = sizeMag; i < sizeMag; i++, k++)
+ pSynthParams->pSynthBuff[i] += pSynthParams->pSpectra[k] * pSynthParams->pFDetWindow[i];
+ for(i= sizeMag, k = 0; i < sizeFft; i++, k++)
+ pSynthParams->pSynthBuff[i] += pSynthParams->pSpectra[k] * pSynthParams->pFDetWindow[i];
}
/*! \brief synthesis of one frame of the stochastic component by apprimating phases
@@ -205,87 +114,38 @@ void sms_deterministic (SMS_Data *pSmsData, SMS_SynthParams *pSynthParams)
* \return
* \todo cleanup returns and various constant multipliers. check that approximation is ok
*/
-static int StocSynthApprox (SMS_Data *pSmsData, SMS_SynthParams *pSynthParams)
+static int StocSynthApprox(SMS_Data *pSmsData, SMS_SynthParams *pSynthParams)
{
- int i, sizeSpec1Used;
- 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)
- return 0;
+ int i, sizeSpec1Used;
+ int sizeSpec1 = pSmsData->nCoeff;
+ int sizeSpec2 = pSynthParams->sizeHop;
+ int sizeFft = pSynthParams->sizeHop << 1; /* 50% overlap, so sizeFft is 2x sizeHop */
+ sfloat fStocGain;
- // *(pSmsData->pFStocGain) = sms_dBToMag(*(pSmsData->pFStocGain));
+ /* if no gain or no coefficients return */
+ if (*(pSmsData->pFStocGain) <= 0)
+ return 0;
- /* \todo check why this was here */
- /* for (i = 0; i < sizeSpec1; i++)
- pSmsData->pFStocCoeff[i] *= 2 * *(pSmsData->pFStocGain) ;
- */
- sizeSpec1Used = sizeSpec1 * pSynthParams->iSamplingRate /
- pSynthParams->iOriginalSRate;
- /* sizeSpec1Used cannot be more than what is available \todo check by graph */
- if(sizeSpec1Used > sizeSpec1) sizeSpec1Used = sizeSpec1;
- //printf("iSamplingRate: %d, iOriginalSRate: %d, sizeSpec1: %d, sizeSpec1Used: %d, sizeSpec2: %d \n",
- // pSynthParams->iSamplingRate, pSynthParams->iOriginalSRate, sizeSpec1, sizeSpec1Used, sizeSpec2);
- sms_spectralApprox (pSmsData->pFStocCoeff, sizeSpec1, sizeSpec1Used,
- pSynthParams->pMagBuff, sizeSpec2, sizeSpec1Used);
+ // *(pSmsData->pFStocGain) = sms_dBToMag(*(pSmsData->pFStocGain));
- /* generate random phases */
- for (i = 0; i < sizeSpec2; i++)
- pSynthParams->pPhaseBuff[i] = TWO_PI * sms_random();
+ sizeSpec1Used = sizeSpec1 * pSynthParams->iSamplingRate /
+ pSynthParams->iOriginalSRate;
- sms_invQuickSpectrumW (pSynthParams->pMagBuff, pSynthParams->pPhaseBuff,
- sizeFft, pSynthParams->pSynthBuff, sizeFft,
- pSynthParams->pFStocWindow);
- return 1;
-}
+ /* sizeSpec1Used cannot be more than what is available \todo check by graph */
+ if(sizeSpec1Used > sizeSpec1) sizeSpec1Used = sizeSpec1;
-/*! \brief synthesis of one frame of the residual component, modeled as stochastic,
- * by approximating phases
- *
- * computes a linearly interpolated spectral envelope to fit the correct number of output
- * audio samples. Phases are generated randomly.
- *
- * \todo needs to be pre-windowed to match the windowing effect of the deterministic,
- * so when they are summed then they can be ifft'ed and overlap-added properly
- *
- * \param pSmsData pointer to the current SMS frame
- * \param pSynthParams pointer to a strucure of synthesis parameters
- * \return
- */
-int sms_stochastic (SMS_Data *pSmsData, SMS_SynthParams *pSynthParams)
-{
- int i, sizeOriginalSpecUsed;
- int sizeOriginalSpec = pSmsData->nCoeff;
- int sizeSpec = pSynthParams->sizeHop;
- int sizeFft = pSynthParams->sizeHop << 1; /* 50% overlap, so sizeFft is 2x sizeHop */
-
- /* if no gain or no coefficients return */
- if (*(pSmsData->pFStocGain) <= 0)
- return (0);
-
-/* *(pSmsData->pFStocGain) = sms_dBToMag(*(pSmsData->pFStocGain)); */
-
- /* scale the coefficients to normal amplitude */
- /*! \todo why is it also multiplied by 2? Why aren't the coeffecients just stored with gain already multiplied?*/
-/* for (i = 0; i < sizeOriginalSpec; i++) */
-/* pSmsData->pFStocCoeff[i] *= 2 * *(pSmsData->pFStocGain) ; */
-
- sizeOriginalSpecUsed = sizeOriginalSpec * pSynthParams->iSamplingRate /
- pSynthParams->iOriginalSRate;
- /* sizeOriginalSpecUsed cannot be more than what is available */
- if(sizeOriginalSpecUsed > sizeOriginalSpec) sizeOriginalSpecUsed = sizeOriginalSpec;
- sms_spectralApprox (pSmsData->pFStocCoeff, sizeOriginalSpec, sizeOriginalSpecUsed,
- pSynthParams->pMagBuff, sizeSpec, sizeOriginalSpecUsed);
+ sms_spectralApprox(pSmsData->pFStocCoeff, sizeSpec1, sizeSpec1Used,
+ pSynthParams->pMagBuff, sizeSpec2, sizeSpec1Used,
+ pSynthParams->approxEnvelope);
- /* generate random phases */
- for (i = 0; i < sizeSpec; i++)
- pSynthParams->pPhaseBuff[i] = TWO_PI * sms_random();
+ /* generate random phases */
+ for(i = 0; i < sizeSpec2; i++)
+ pSynthParams->pPhaseBuff[i] = TWO_PI * sms_random();
- /* \todo first multiply the pMagBuff by a window in order to properly un-window below */
- sms_PolarToRect(sizeSpec, pSynthParams->pSpectra, pSynthParams->pMagBuff, pSynthParams->pPhaseBuff);
- return (0);
+ sms_invQuickSpectrumW(pSynthParams->pMagBuff, pSynthParams->pPhaseBuff,
+ sizeFft, pSynthParams->pSynthBuff, sizeFft,
+ pSynthParams->pFStocWindow, pSynthParams->pSpectra);
+ return 1;
}
/*! \brief synthesizes one frame of SMS data
@@ -294,67 +154,47 @@ int sms_stochastic (SMS_Data *pSmsData, SMS_SynthParams *pSynthParams)
* \param pFSynthesis output sound buffer
* \param pSynthParams synthesis parameters
*/
-void sms_synthesize(SMS_Data *pSmsData, sfloat *pFSynthesis,
- SMS_SynthParams *pSynthParams)
+void sms_synthesize(SMS_Data *pSmsData, sfloat *pFSynthesis, SMS_SynthParams *pSynthParams)
{
- int i, k;
- int sizeHop = pSynthParams->sizeHop;
- int sizeFft = sizeHop << 1;
-
- memcpy (pSynthParams->pSynthBuff, (sfloat *)(pSynthParams->pSynthBuff+sizeHop),
- sizeof(sfloat) * sizeHop);
- memset (pSynthParams->pSynthBuff+sizeHop, 0, sizeof(sfloat) * sizeHop);
-
- /* convert mags from linear to db */
- sms_arrayMagToDB(pSmsData->nTracks, pSmsData->pFSinAmp);
-
- /* decide which combo of synthesis methods to use */
- if(pSynthParams->iSynthesisType == SMS_STYPE_ALL)
+ int i, k;
+ int sizeHop = pSynthParams->sizeHop;
+ int sizeFft = sizeHop << 1;
+
+ memcpy(pSynthParams->pSynthBuff, (sfloat *)(pSynthParams->pSynthBuff+sizeHop),
+ sizeof(sfloat) * sizeHop);
+ memset(pSynthParams->pSynthBuff+sizeHop, 0, sizeof(sfloat) * sizeHop);
+
+ /* convert mags from linear to db */
+ /*sms_arrayMagToDB(pSmsData->nTracks, pSmsData->pFSinAmp);*/
+
+ /* decide which combo of synthesis methods to use */
+ if(pSynthParams->iSynthesisType == SMS_STYPE_ALL)
+ {
+ if(pSynthParams->iDetSynthType == SMS_DET_IFFT)
+ SineSynthIFFT(pSmsData, pSynthParams);
+ else /*pSynthParams->iDetSynthType == SMS_DET_SIN*/
{
- if(pSynthParams->iDetSynthType == SMS_DET_IFFT &&
- pSynthParams->iStochasticType == SMS_STOC_IFFT)
- {
- memset (pSynthParams->pSpectra, 0, sizeFft * sizeof(sfloat));
- sms_deterministic(pSmsData, pSynthParams);
- sms_ifft(sizeFft, pSynthParams->pSpectra);
-
- for(i = 0, k = sizeHop; i < sizeHop; i++, k++)
- pSynthParams->pSynthBuff[i] += pSynthParams->pSpectra[k] * pSynthParams->pFDetWindow[i];
- for(i= sizeHop, k = 0; i < sizeFft; i++, k++)
- pSynthParams->pSynthBuff[i] += pSynthParams->pSpectra[k] * pSynthParams->pFDetWindow[i];
-
- //sms_invSpectrum(sizeFft, pSynthParams->pSynthBuff,
-
-
- }
- else /* can't use combo IFFT, synthesize seperately and sum */
- {
- if(pSynthParams->iDetSynthType == SMS_DET_IFFT)
- SineSynthIFFT (pSmsData, pSynthParams);
- else /*pSynthParams->iDetSynthType == SMS_DET_SIN*/
- {
- sms_sineSynthFrame (pSmsData, pSynthParams->pSynthBuff+sizeHop, pSynthParams->sizeHop,
- &(pSynthParams->prevFrame), pSynthParams->iSamplingRate);
- }
- StocSynthApprox (pSmsData, pSynthParams);
- }
-
+ sms_sineSynthFrame(pSmsData, pSynthParams->pSynthBuff, pSynthParams->sizeHop,
+ &(pSynthParams->prevFrame), pSynthParams->iSamplingRate);
}
- else if(pSynthParams->iSynthesisType == SMS_STYPE_DET)
+ StocSynthApprox(pSmsData, pSynthParams);
+ }
+ else if(pSynthParams->iSynthesisType == SMS_STYPE_DET)
+ {
+ if(pSynthParams->iDetSynthType == SMS_DET_IFFT)
+ SineSynthIFFT (pSmsData, pSynthParams);
+ else /*pSynthParams->iDetSynthType == SMS_DET_SIN*/
{
- if(pSynthParams->iDetSynthType == SMS_DET_IFFT)
- SineSynthIFFT (pSmsData, pSynthParams);
- else /*pSynthParams->iDetSynthType == SMS_DET_SIN*/
- {
- sms_sineSynthFrame (pSmsData, pSynthParams->pSynthBuff+sizeHop, pSynthParams->sizeHop,
- &(pSynthParams->prevFrame), pSynthParams->iSamplingRate);
- }
+ sms_sineSynthFrame(pSmsData, pSynthParams->pSynthBuff, pSynthParams->sizeHop,
+ &(pSynthParams->prevFrame), pSynthParams->iSamplingRate);
}
- else /* pSynthParams->iSynthesisType == SMS_STYPE_STOC */
- StocSynthApprox(pSmsData, pSynthParams);
+ }
+ else /* pSynthParams->iSynthesisType == SMS_STYPE_STOC */
+ StocSynthApprox(pSmsData, pSynthParams);
- /* de-emphasize the sound */
- for(i = 0; i < sizeHop; i++)
- pFSynthesis[i] = sms_deEmphasis(pSynthParams->pSynthBuff[i+sizeHop], pSynthParams);
+ /* de-emphasize the sound and normalize*/
+ for(i = 0; i < sizeHop; i++)
+ pFSynthesis[i] = sms_deEmphasis(pSynthParams->pSynthBuff[i], pSynthParams);
}
+
diff --git a/sms/tables.c b/sms/tables.c
index 1802952..85d21cb 100644
--- a/sms/tables.c
+++ b/sms/tables.c
@@ -40,57 +40,61 @@ static sfloat *sms_tab_sinc;
* \param nTableSize size of table
* \return error code \see SMS_MALLOC in SMS_ERRORS
*/
-int sms_prepSine (int nTableSize)
+int sms_prepSine(int nTableSize)
{
- register int i;
- sfloat fTheta;
-
- if((sms_tab_sine = (sfloat *)malloc(nTableSize*sizeof(sfloat))) == 0)
- return (SMS_MALLOC);
- fSineScale = (sfloat)(TWO_PI) / (sfloat)(nTableSize - 1);
- fSineIncr = 1.0 / fSineScale;
- fTheta = 0.0;
- for(i = 0; i < nTableSize; i++)
- {
- fTheta = fSineScale * (sfloat)i;
- sms_tab_sine[i] = sin(fTheta);
- }
- return (SMS_OK);
+ register int i;
+ sfloat fTheta;
+
+ sms_tab_sine = (sfloat *)malloc(nTableSize * sizeof(sfloat));
+ if(sms_tab_sine == NULL)
+ {
+ sms_error("Could not allocate memory for sine table");
+ return SMS_MALLOC;
+ }
+ fSineScale = (sfloat)(TWO_PI) / (sfloat)(nTableSize - 1);
+ fSineIncr = 1.0 / fSineScale;
+ fTheta = 0.0;
+ for(i = 0; i < nTableSize; i++)
+ {
+ fTheta = fSineScale * (sfloat)i;
+ sms_tab_sine[i] = sin(fTheta);
+ }
+ return SMS_OK;
}
/*! \brief clear sine table */
void sms_clearSine()
{
- if(sms_tab_sine)
- free(sms_tab_sine);
- sms_tab_sine = 0;
+ if(sms_tab_sine)
+ free(sms_tab_sine);
+ sms_tab_sine = NULL;
}
/*! \brief table-lookup sine method
* \param fTheta angle in radians
* \return approximately sin(fTheta)
*/
-sfloat sms_sine (sfloat fTheta)
+sfloat sms_sine(sfloat fTheta)
{
- int i;
- fTheta = fTheta - floor(fTheta * INV_TWO_PI) * TWO_PI;
-
- if(fTheta < 0)
- {
- i = .5 - (fTheta * fSineIncr);
- return(-(sms_tab_sine[i]));
- }
- else
- {
- i = fTheta * fSineIncr + .5;
- return(sms_tab_sine[i]);
- }
+ int i;
+ fTheta = fTheta - floor(fTheta * INV_TWO_PI) * TWO_PI;
+
+ if(fTheta < 0)
+ {
+ i = .5 - (fTheta * fSineIncr);
+ return -(sms_tab_sine[i]);
+ }
+ else
+ {
+ i = fTheta * fSineIncr + .5;
+ return sms_tab_sine[i];
+ }
}
/*! \brief Sinc method to generate the lookup table
*/
-static sfloat Sinc (sfloat x, sfloat N)
+static sfloat Sinc(sfloat x, sfloat N)
{
- return (sinf ((N/2) * x) / sinf (x/2));
+ return sinf((N/2) * x) / sinf(x/2);
}
/*! \brief prepare the Sinc table
@@ -101,41 +105,45 @@ static sfloat Sinc (sfloat x, sfloat N)
* \param nTableSize size of table
* \return error code \see SMS_MALLOC in SMS_ERRORS
*/
-int sms_prepSinc (int nTableSize)
+int sms_prepSinc(int nTableSize)
{
- int i, m;
+ int i, m;
sfloat N = 512.0;
sfloat fA[4] = {.35875, .48829, .14128, .01168};
- sfloat fMax = 0;
- sfloat fTheta = -4.0 * TWO_PI / N;
- sfloat fThetaIncr = (8.0 * TWO_PI / N) / (nTableSize);
+ sfloat fMax = 0;
+ sfloat fTheta = -4.0 * TWO_PI / N;
+ sfloat fThetaIncr = (8.0 * TWO_PI / N) / (nTableSize);
+
+ sms_tab_sinc = (sfloat *)calloc(nTableSize, sizeof(sfloat));
+ if(sms_tab_sinc == NULL)
+ {
+ sms_error("Could not allocate memory for sinc table");
+ return (SMS_MALLOC);
+ }
+
+ for(i = 0; i < nTableSize; i++)
+ {
+ for (m = 0; m < 4; m++)
+ sms_tab_sinc[i] += -1 * (fA[m]/2) *
+ (Sinc (fTheta - m * TWO_PI/N, N) +
+ Sinc (fTheta + m * TWO_PI/N, N));
+ fTheta += fThetaIncr;
+ }
- if((sms_tab_sinc = (sfloat *) calloc (nTableSize, sizeof(sfloat))) == 0)
- return (SMS_MALLOC);
-
- for(i = 0; i < nTableSize; i++)
- {
- for (m = 0; m < 4; m++)
- sms_tab_sinc[i] += -1 * (fA[m]/2) *
- (Sinc (fTheta - m * TWO_PI/N, N) +
- Sinc (fTheta + m * TWO_PI/N, N));
- fTheta += fThetaIncr;
- }
- fMax = sms_tab_sinc[(int) nTableSize / 2];
- for (i = 0; i < nTableSize; i++)
- sms_tab_sinc[i] = sms_tab_sinc[i] / fMax;
-
- fSincScale = (sfloat) nTableSize / 8.0;
-
- return (SMS_OK);
+ fMax = sms_tab_sinc[(int) nTableSize / 2];
+ for (i = 0; i < nTableSize; i++)
+ sms_tab_sinc[i] = sms_tab_sinc[i] / fMax;
+
+ fSincScale = (sfloat) nTableSize / 8.0;
+ return SMS_OK;
}
/*! \brief clear sine table */
void sms_clearSinc()
{
- if(sms_tab_sinc)
- free(sms_tab_sinc);
- sms_tab_sinc = 0;
+ if(sms_tab_sinc)
+ free(sms_tab_sinc);
+ sms_tab_sinc = 0;
}
/*! \brief global sinc table-lookup method
@@ -145,9 +153,10 @@ void sms_clearSinc()
* \param fTheta angle in radians
* \return approximately sinc(fTheta)
*/
-sfloat sms_sinc (sfloat fTheta)
+sfloat sms_sinc(sfloat fTheta)
{
int index = (int) (.5 + fSincScale * fTheta);
-
- return (sms_tab_sinc[index]);
+ return sms_tab_sinc[index];
}
+
+