diff options
author | John Glover <glover.john@gmail.com> | 2010-12-08 18:45:14 +0000 |
---|---|---|
committer | John Glover <glover.john@gmail.com> | 2010-12-08 18:45:14 +0000 |
commit | d7eb9bcda3848ce1b3816d428e8dd66d9b0e02d8 (patch) | |
tree | fa51471e087d8d116bffb4969a4c1b14b0438cfe | |
parent | 2a7cc2153f7445453422d74d87d2ce0cf9de51ff (diff) | |
download | simpl-d7eb9bcda3848ce1b3816d428e8dd66d9b0e02d8.tar.gz simpl-d7eb9bcda3848ce1b3816d428e8dd66d9b0e02d8.tar.bz2 simpl-d7eb9bcda3848ce1b3816d428e8dd66d9b0e02d8.zip |
SMSPeakDetection bug fixes
-rw-r--r-- | sms.py | 47 | ||||
-rw-r--r-- | sms/sms.c | 97 | ||||
-rw-r--r-- | sms/sms.h | 6 | ||||
-rw-r--r-- | sms/sms.i | 11 |
4 files changed, 85 insertions, 76 deletions
@@ -26,7 +26,7 @@ class SMSPeakDetection(simpl.PeakDetection): # analysis parameters self._analysis_params = simplsms.SMS_AnalParams() simplsms.sms_initAnalParams(self._analysis_params) - self._analysis_params.iSamplingRate = self.sampling_rate + self._analysis_params.iSamplingRate = self._sampling_rate # set default hop and frame sizes to match those in the parent class self._analysis_params.iFrameRate = self.sampling_rate / self._hop_size self._analysis_params.iWindowType = simplsms.SMS_WIN_HAMMING @@ -50,6 +50,7 @@ class SMSPeakDetection(simpl.PeakDetection): def __del__(self): simplsms.sms_freeAnalysis(self._analysis_params) + simplsms.sms_freeSpectralPeaks(self._peaks) simplsms.sms_free() # properties @@ -84,19 +85,28 @@ class SMSPeakDetection(simpl.PeakDetection): return self._analysis_params.iMaxDelayFrames def set_max_frame_delay(self, max_frame_delay): + simplsms.sms_freeAnalysis(self._analysis_params) self._analysis_params.iMaxDelayFrames = max_frame_delay + if simplsms.sms_initAnalysis(self._analysis_params) != 0: + raise Exception("Error allocating memory for analysis_params") def get_analysis_delay(self): return self._analysis_params.analDelay def set_analysis_delay(self, analysis_delay): + simplsms.sms_freeAnalysis(self._analysis_params) self._analysis_params.analDelay = analysis_delay + if simplsms.sms_initAnalysis(self._analysis_params) != 0: + raise Exception("Error allocating memory for analysis_params") def get_min_good_frames(self): return self._analysis_params.minGoodFrames def set_min_good_frames(self, min_good_frames): + simplsms.sms_freeAnalysis(self._analysis_params) self._analysis_params.minGoodFrames = min_good_frames + if simplsms.sms_initAnalysis(self._analysis_params) != 0: + raise Exception("Error allocating memory for analysis_params") def get_min_frequency(self): return self._analysis_params.fLowestFundamental @@ -115,26 +125,41 @@ class SMSPeakDetection(simpl.PeakDetection): return self._analysis_params.sizeHop def set_hop_size(self, hop_size): - #self._analysis_params.iFrameRate = self.sampling_rate / hop_size - #simplsms.sms_changeHopSize(hop_size, self._analysis_params) - print 'todo: change hop size to', hop_size + simplsms.sms_freeAnalysis(self._analysis_params) + self._analysis_params.iFrameRate = self.sampling_rate / hop_size + if simplsms.sms_initAnalysis(self._analysis_params) != 0: + raise Exception("Error allocating memory for analysis_params") + + def get_max_peaks(self): + return self._analysis_params.maxPeaks def set_max_peaks(self, max_peaks): - # TODO: compare to SMS_MAX_NPEAKS - # also, if > current max_peaks, need to reallocate memory in - # analysis_params + # 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) + ")", + print "set to more than the maximum number of peaks possible in libsms." + 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 self._analysis_params.nGuides = max_peaks - # TODO: create function to deallocate old peaks memory and call that - # before creating the new peak list below + 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): + return self._analysis_params.iSamplingRate def set_sampling_rate(self, sampling_rate): - self._sampling_rate = sampling_rate - # TODO: update analysis params framerate? self._analysis_params.iSamplingRate = sampling_rate + simplsms.sms_freeAnalysis(self._analysis_params) + if simplsms.sms_initAnalysis(self._analysis_params) != 0: + raise Exception("Error allocating memory for analysis_params") def set_window_size(self, window_size): self._window_size = window_size @@ -386,44 +386,6 @@ int sms_initAnalysis(SMS_AnalParams *pAnalParams) return 0; } -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; - - /* 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 */ - 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; - } - pSoundBuf->iMarker = -sizeBuffer; - pSoundBuf->iFirstGood = sizeBuffer; - pSoundBuf->sizeBuffer = sizeBuffer; - - /* deterministic synthesis buffer */ - SMS_SndBuffer *pSynthBuf = &pAnalParams->synthBuffer; - pSynthBuf->sizeBuffer = pAnalParams->sizeHop << 1; - - free(pSynthBuf->pFBuffer); - pSynthBuf->pFBuffer = calloc(sizeBuffer, sizeof(sfloat)); - if(pSynthBuf->pFBuffer == NULL) - { - sms_error("could not allocate memory"); - return; - } - pSynthBuf->iMarker = pSynthBuf->sizeBuffer; -} - /*! \brief give default values to an SMS_SynthParams struct * * This will initialize an SMS_SynthParams with values that work @@ -511,26 +473,6 @@ int sms_initSynth(SMS_SynthParams *pSynthParams) return SMS_OK; } -int sms_changeSynthHop(SMS_SynthParams *pSynthParams, int sizeHop) -{ - int sizeFft = sizeHop * 2; - - pSynthParams->pSynthBuff = (sfloat *) realloc(pSynthParams->pSynthBuff, sizeFft * sizeof(sfloat)); - pSynthParams->pSpectra = (sfloat *) realloc(pSynthParams->pSpectra, sizeFft * sizeof(sfloat)); - pSynthParams->pMagBuff = (sfloat *) realloc(pSynthParams->pMagBuff, sizeHop * sizeof(sfloat)); - pSynthParams->pPhaseBuff = (sfloat *) realloc(pSynthParams->pPhaseBuff, sizeHop * sizeof(sfloat)); - pSynthParams->pFStocWindow = - (sfloat *) realloc(pSynthParams->pFStocWindow, sizeFft * sizeof(sfloat)); - 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); - - pSynthParams->sizeHop = sizeHop; - - return(SMS_OK); -} - /*! \brief free analysis data * * frees all the memory allocated to an SMS_AnalParams by @@ -607,6 +549,45 @@ void sms_freeSynth(SMS_SynthParams *pSynthParams) sms_freeFrame(&pSynthParams->prevFrame); } +/*! \brief Allocate memory for an array of spectral peaks + * + * Creates memory and sets default values. + * + * \param peaks the spectral peaks + * \param n number of peaks + * \return 0 on success, -1 on error + */ +int sms_initSpectralPeaks(SMS_SpectralPeaks* peaks, int n) +{ + peaks->nPeaks = n; + peaks->nPeaksFound = 0; + + peaks->pSpectralPeaks = (SMS_Peak *)malloc(n * sizeof(SMS_Peak)); + if(peaks->pSpectralPeaks == NULL) + { + sms_error("could not allocate memory for spectral peaks"); + return -1; + } + return 0; +} + +/*! \brief Deallocate memory for an array of spectral peaks + * + * \param peaks the spectral peaks + */ +void sms_freeSpectralPeaks(SMS_SpectralPeaks* peaks) +{ + if(!peaks) + return; + if(peaks->nPeaks <= 0) + return; + + if(peaks->pSpectralPeaks) + free(peaks->pSpectralPeaks); + peaks->nPeaks = 0; + peaks->nPeaksFound = 0; +} + /*! \brief set window size for next frame * * adjusts the next window size to fit the currently detected fundamental @@ -580,12 +580,12 @@ 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_freeSynth(SMS_SynthParams *pSynthParams); +int sms_initSpectralPeaks(SMS_SpectralPeaks* peaks, int n); +void sms_freeSpectralPeaks(SMS_SpectralPeaks* peaks); void sms_fillSoundBuffer(int sizeWaveform, sfloat *pWaveform, SMS_AnalParams *pAnalParams); void sms_windowCentered(int sizeWindow, sfloat *pWaveform, sfloat *pWindow, int sizeFft, sfloat *pFftBuffer); @@ -372,13 +372,16 @@ SMS_SpectralPeaks(int n) { SMS_SpectralPeaks *s = (SMS_SpectralPeaks *)malloc(sizeof(SMS_SpectralPeaks)); - s->nPeaks = n; - if((s->pSpectralPeaks = (SMS_Peak *)malloc(n * sizeof(SMS_Peak))) == NULL) + if(s == NULL) { - sms_error("could not allocate memory for spectral peaks"); + sms_error("Could not allocate memory for SMS_SpectralPeaks"); + return NULL; + } + if(sms_initSpectralPeaks(s, n) < 0) + { + sms_error("Could not initialise SMS_SpectralPeaks"); return NULL; } - s->nPeaksFound = 0; return s; } void getFreq(int sizeArray, sfloat *pArray ) |