diff options
author | John Glover <glover.john@gmail.com> | 2010-12-09 22:19:17 +0000 |
---|---|---|
committer | John Glover <glover.john@gmail.com> | 2010-12-09 22:19:17 +0000 |
commit | 5ca314e5ccf3dfb98fdea9d37646baca66d75ec3 (patch) | |
tree | 40de39619d48a3cca458254d081d97222dac6dd7 | |
parent | b27a8f7182edb2f9e15fd60e78d54fb9fd0c5472 (diff) | |
download | simpl-5ca314e5ccf3dfb98fdea9d37646baca66d75ec3.tar.gz simpl-5ca314e5ccf3dfb98fdea9d37646baca66d75ec3.tar.bz2 simpl-5ca314e5ccf3dfb98fdea9d37646baca66d75ec3.zip |
Fixed bug in SMS peak detection - find_peaks was leaking memory wen saving peaks, and a pointer assignment in find_peaks could lead to a double free in freeAnalysis/freeSpectralPeaks.
-rw-r--r-- | basetypes.py | 7 | ||||
-rw-r--r-- | sms.py | 13 | ||||
-rw-r--r-- | sms/analysis.c | 14 | ||||
-rw-r--r-- | sms/sms.c | 20 | ||||
-rw-r--r-- | tests/sms.py | 2 |
5 files changed, 32 insertions, 24 deletions
diff --git a/basetypes.py b/basetypes.py index 6f076bf..dd0da26 100644 --- a/basetypes.py +++ b/basetypes.py @@ -348,18 +348,19 @@ class Synthesis(object): class Residual(object): "Calculate a residual signal" - TIME_DOMAIN = 0 - FREQUENCY_DOMAIN = 1 def __init__(self): - self.type = Residual.TIME_DOMAIN self.hop_size = 512 self.frame_size = 2048 + # TODO: break this up into find_residual and find_frame_residual + # so that it can be streamed def find_residual(self, synth, original): "Calculate and return the residual signal" raise Exception("NotYetImplemented") + # TODO: break this up into synth and synth_frame + # so that it can be streamed def synth(self, synth, original): "Calculate and return a synthesised residual signal" raise Exception("NotYetImplemented") @@ -41,7 +41,7 @@ class SMSPeakDetection(simpl.PeakDetection): self._analysis_params.nGuides = self._max_peaks if simplsms.sms_initAnalysis(self._analysis_params) != 0: raise Exception("Error allocating memory for analysis_params") - self._peaks = simplsms.SMS_SpectralPeaks(self.max_peaks) + self._peaks = simplsms.SMS_SpectralPeaks(self._max_peaks) # By default, SMS will change the size of the frames being read depending on the # detected fundamental frequency (if any) of the input sound. To prevent this # behaviour (useful when comparing different analysis algorithms), set the @@ -134,6 +134,8 @@ class SMSPeakDetection(simpl.PeakDetection): return self._analysis_params.maxPeaks def set_max_peaks(self, max_peaks): + simplsms.sms_freeAnalysis(self._analysis_params) + simplsms.sms_freeSpectralPeaks(self._peaks) # make sure the new max is less than SMS_MAX_NPEAKS if max_peaks > simplsms.SMS_MAX_NPEAKS: print "Warning: max peaks (" + str(max_peaks) + ")", @@ -141,7 +143,6 @@ class SMSPeakDetection(simpl.PeakDetection): print " Setting to", simplsms.SMS_MAX_NPEAKS, "instead." max_peaks = simplsms.SMS_MAX_NPEAKS # set analysis params - simplsms.sms_freeAnalysis(self._analysis_params) self._max_peaks = max_peaks self._analysis_params.nTracks = max_peaks self._analysis_params.maxPeaks = max_peaks @@ -149,7 +150,6 @@ class SMSPeakDetection(simpl.PeakDetection): if simplsms.sms_initAnalysis(self._analysis_params) != 0: raise Exception("Error allocating memory for analysis_params") # set peaks list - simplsms.sms_freeSpectralPeaks(self._peaks) self._peaks = simplsms.SMS_SpectralPeaks(max_peaks) def get_sampling_rate(self): @@ -403,6 +403,7 @@ class SMSSynthesis(simpl.Synthesis): class SMSResidual(simpl.Residual): + "SMS residual component" def __init__(self): simpl.Residual.__init__(self) @@ -411,12 +412,12 @@ class SMSResidual(simpl.Residual): simplsms.sms_initAnalysis(self._analysis_params) def __del__(self): + simplsms.sms_freeAnalysis(self._analysis_params) simplsms.sms_free() def find_residual(self, synth, original): "Calculate and return the residual signal" - residual = simpl.zeros(synth.size) - if simplsms.sms_findResidual(synth, original, residual, self._analysis_params) == -1: - raise Exception("Residual error: Synthesised audio and original audio have different lengths") + residual = simpl.zeros(len(original)) # residual won't be longer than the original signal + simplsms.sms_findResidual(synth, original, residual, self._analysis_params) return residual diff --git a/sms/analysis.c b/sms/analysis.c index 90bec7f..ec4e0fe 100644 --- a/sms/analysis.c +++ b/sms/analysis.c @@ -156,11 +156,6 @@ int sms_findPeaks(int sizeWaveform, sfloat *pWaveform, SMS_AnalParams *pAnalPara /* 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) { @@ -196,14 +191,17 @@ int sms_findPeaks(int sizeWaveform, sfloat *pWaveform, SMS_AnalParams *pAnalPara /* 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->nPeaks; i++) { if(i < pSpectralPeaks->nPeaksFound) { - pSpectralPeaks->pSpectralPeaks[i].fMag = pow(10.0, 0.05*(pSpectralPeaks->pSpectralPeaks[i].fMag)); + pSpectralPeaks->pSpectralPeaks[i].fMag = + pow(10.0, 0.05*(pAnalParams->ppFrames[iCurrentFrame]->pSpectralPeaks[i].fMag)); + pSpectralPeaks->pSpectralPeaks[i].fFreq = + pAnalParams->ppFrames[iCurrentFrame]->pSpectralPeaks[i].fFreq; + pSpectralPeaks->pSpectralPeaks[i].fPhase = + pAnalParams->ppFrames[iCurrentFrame]->pSpectralPeaks[i].fPhase; } else { @@ -518,6 +518,17 @@ void sms_freeAnalysis(SMS_AnalParams *pAnalParams) free(pAnalParams->stocMagSpectrum); if(pAnalParams->approxEnvelope) free(pAnalParams->approxEnvelope); + + pAnalParams->pFrames = NULL; + pAnalParams->ppFrames = NULL; + pAnalParams->soundBuffer.pFBuffer = NULL; + pAnalParams->synthBuffer.pFBuffer = NULL; + pAnalParams->residual = NULL; + pAnalParams->residualWindow = NULL; + pAnalParams->guideStates = NULL; + pAnalParams->guides = NULL; + pAnalParams->stocMagSpectrum = NULL; + pAnalParams->approxEnvelope = NULL; } /*! \brief free analysis data @@ -579,8 +590,6 @@ void sms_freeSpectralPeaks(SMS_SpectralPeaks* peaks) { if(!peaks) return; - if(peaks->nPeaks <= 0) - return; if(peaks->pSpectralPeaks) free(peaks->pSpectralPeaks); @@ -671,11 +680,11 @@ int sms_clearAnalysisFrame(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, + memset((sfloat *)pAnalParams->ppFrames[iCurrentFrame]->deterministic.pFSinFreq, 0, sizeof(sfloat) * pAnalParams->nGuides); - memset((sfloat *) pAnalParams->ppFrames[iCurrentFrame]->deterministic.pFSinAmp, 0, + memset((sfloat *)pAnalParams->ppFrames[iCurrentFrame]->deterministic.pFSinAmp, 0, sizeof(sfloat) * pAnalParams->nGuides); - memset((sfloat *) pAnalParams->ppFrames[iCurrentFrame]->deterministic.pFSinPha, 0, + memset((sfloat *)pAnalParams->ppFrames[iCurrentFrame]->deterministic.pFSinPha, 0, sizeof(sfloat) * pAnalParams->nGuides); /* clear peaks */ @@ -697,7 +706,6 @@ int sms_initFrame(int iCurrentFrame, SMS_AnalParams *pAnalParams, int sizeWindow /* if first frame set center of data around 0 */ if(pAnalParams->ppFrames[iCurrentFrame]->iFrameNum == 1) pAnalParams->ppFrames[iCurrentFrame]->iFrameSample = 0; - /* if not, increment center of data by sizeHop */ else pAnalParams->ppFrames[iCurrentFrame]->iFrameSample = diff --git a/tests/sms.py b/tests/sms.py index 9fb8fa0..f717900 100644 --- a/tests/sms.py +++ b/tests/sms.py @@ -1050,9 +1050,9 @@ class TestSimplSMS(object): pd = simpl.SMSPeakDetection() pd.max_peaks = self.max_peaks pd.hop_size = self.hop_size + peaks = pd.find_peaks(audio)[0:self.num_frames] pt = simpl.SMSPartialTracking() pt.max_partials = self.max_partials - peaks = pd.find_peaks(audio)[0:self.num_frames] partials = pt.find_partials(peaks) synth = simpl.SMSSynthesis() synth.hop_size = self.hop_size |