summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--SConstruct8
-rw-r--r--sms.py17
-rw-r--r--sms/analysis.c17
-rw-r--r--sms/fixTracks.c45
-rw-r--r--sms/sineSynth.c12
-rw-r--r--sms/sms.c24
-rw-r--r--sms/synthesis.c4
-rw-r--r--tests/sms.py182
8 files changed, 133 insertions, 176 deletions
diff --git a/SConstruct b/SConstruct
index db62a22..c5a1d1a 100644
--- a/SConstruct
+++ b/SConstruct
@@ -41,7 +41,11 @@ if get_platform() == "unsupported":
exit(1)
# environment
-env = Environment(ENV=os.environ)
+if get_platform() == 'win32':
+ # can only build with mingw on windows
+ env = Environment(ENV=os.environ, tools=['mingw'])
+else:
+ env = Environment(ENV=os.environ)
# set default installation directories
default_install_dir = ""
@@ -128,7 +132,7 @@ try:
except AttributeError:
numpy_include = numpy.get_numpy_include()
except ImportError:
- print "Numpy was not found. Cannot build simpl.\n"
+ print "Numpy was not found. Cannot build simpl."
exit(1)
env.Append(CPPPATH = numpy_include)
diff --git a/sms.py b/sms.py
index 567c412..2890efb 100644
--- a/sms.py
+++ b/sms.py
@@ -141,6 +141,7 @@ class SMSPeakDetection(simpl.PeakDetection):
def set_sampling_rate(self, sampling_rate):
self._sampling_rate = sampling_rate
+ # TODO: update analysis params framerate?
self._analysis_params.iSamplingRate = sampling_rate
def set_window_size(self, window_size):
@@ -244,9 +245,6 @@ class SMSPartialTracking(simpl.PartialTracking):
amps = simpl.zeros(num_peaks)
freqs = simpl.zeros(num_peaks)
phases = simpl.zeros(num_peaks)
- #amps = simpl.zeros(self.max_partials)
- #freqs = simpl.zeros(self.max_partials)
- #phases = simpl.zeros(self.max_partials)
for i in range(num_peaks):
peak = frame[i]
amps[i] = peak.amplitude
@@ -297,14 +295,14 @@ class SMSSynthesis(simpl.Synthesis):
simpl.Synthesis.__init__(self)
simplsms.sms_init()
self._synth_params = simplsms.SMS_SynthParams()
- self._synth_params.iDetSynthType = simplsms.SMS_DET_SIN
+ self._synth_params.iDetSynthType = simplsms.SMS_DET_IFFT
# use the default simpl hop size instead of the default SMS hop size
self._synth_params.sizeHop = self._hop_size
simplsms.sms_initSynth(self._synth_params)
self._current_frame = simpl.zeros(self.hop_size)
self._analysis_frame = simplsms.SMS_Data()
simplsms.sms_allocFrame(self._analysis_frame, self.max_partials,
- self.num_stochastic_coeffs, 1, self.stochastic_type, 0)
+ self.num_stochastic_coeffs, 1, self.stochastic_type, 0)
def __del__(self):
simplsms.sms_freeFrame(self._analysis_frame)
@@ -336,8 +334,9 @@ class SMSSynthesis(simpl.Synthesis):
def set_max_partials(self, max_partials):
self._synth_params.nTracks = max_partials
+ simplsms.sms_freeFrame(self._analysis_frame)
simplsms.sms_allocFrame(self._analysis_frame, max_partials,
- self.num_stochastic_coeffs, 1, self.stochastic_type, 0)
+ self.num_stochastic_coeffs, 1, self.stochastic_type, 0)
def get_sampling_rate(self):
return self._synth_params.iSamplingRate
@@ -356,16 +355,18 @@ class SMSSynthesis(simpl.Synthesis):
def set_num_stochastic_coeffs(self, num_stochastic_coeffs):
self._synth_params.nStochasticCoeff = num_stochastic_coeffs
+ simplsms.sms_freeFrame(self._analysis_frame)
simplsms.sms_allocFrame(self._analysis_frame, self.max_partials,
- num_stochastic_coeffs, 1, self.stochastic_type, 0)
+ num_stochastic_coeffs, 1, self.stochastic_type, 0)
def get_stochastic_type(self):
return self._synth_params.iStochasticType
def set_stochastic_type(self, stochastic_type):
self._synth_params.iStochasticType = stochastic_type
+ simplsms.sms_freeFrame(self._analysis_frame)
simplsms.sms_allocFrame(self._analysis_frame, self.max_partials,
- self.num_stochastic_coeffs, 1, stochastic_type, 0)
+ self.num_stochastic_coeffs, 1, stochastic_type, 0)
def get_original_sampling_rate(self):
return self._synth_params.iOriginalSRate
diff --git a/sms/analysis.c b/sms/analysis.c
index a435a5a..90bec7f 100644
--- a/sms/analysis.c
+++ b/sms/analysis.c
@@ -31,23 +31,6 @@
/*! \brief maximum size for magnitude spectrum */
#define SMS_MAX_SPEC 8192
-void printAnalysisParams(SMS_AnalParams* params)
-{
- printf("fLowestFreq: %f\n"
- "fHighestFreq: %f\n"
- "fMinPeakMag: %f\n"
- "iSamplingRate: %d\n"
- "maxPeaks: %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
*
* This is the main core of analysis calls
diff --git a/sms/fixTracks.c b/sms/fixTracks.c
index 81e24ee..109d854 100644
--- a/sms/fixTracks.c
+++ b/sms/fixTracks.c
@@ -33,8 +33,8 @@
* \param pIState pointer to the state of tracks
* \param pAnalParams pointer to analysis parameters
*/
-static void FillGap (int iCurrentFrame, int iTrack, int *pIState,
- SMS_AnalParams *pAnalParams)
+static void FillGap(int iCurrentFrame, int iTrack, int *pIState,
+ SMS_AnalParams *pAnalParams)
{
int iFrame, iLastFrame = - (pIState[iTrack] - 1);
sfloat fConstant = TWO_PI / pAnalParams->iSamplingRate;
@@ -45,8 +45,8 @@ static void FillGap (int iCurrentFrame, int iTrack, int *pIState,
return;
/* if firstMag is 0 it means that there is no Gap, just the begining of a track */
- if (pAnalParams->ppFrames[iCurrentFrame -
- iLastFrame]->deterministic.pFSinAmp[iTrack] == 0)
+ if(pAnalParams->ppFrames[iCurrentFrame -
+ iLastFrame]->deterministic.pFSinAmp[iTrack] == 0)
{
pIState[iTrack] = 1;
return;
@@ -63,10 +63,10 @@ static void FillGap (int iCurrentFrame, int iTrack, int *pIState,
/* if inharmonic format and the two extremes are very different */
/* do not interpolate, it means that they are different tracks */
- if ((pAnalParams->iFormat == SMS_FORMAT_IH ||
- pAnalParams->iFormat == SMS_FORMAT_IHP) &&
- (MIN (fFirstFreq, fLastFreq) * .5 * pAnalParams->fFreqDeviation <
- fabs ((double) fLastFreq - fFirstFreq)))
+ if((pAnalParams->iFormat == SMS_FORMAT_IH ||
+ pAnalParams->iFormat == SMS_FORMAT_IHP) &&
+ (MIN (fFirstFreq, fLastFreq) * .5 * pAnalParams->fFreqDeviation <
+ fabs(fLastFreq - fFirstFreq)))
{
pIState[iTrack] = 1;
return;
@@ -76,8 +76,7 @@ static void FillGap (int iCurrentFrame, int iTrack, int *pIState,
fFreq = fFirstFreq;
/* fill the gap by interpolating values */
/* if the gap is too long it should consider the lower partials */
- for (iFrame = iCurrentFrame - iLastFrame + 1; iFrame < iCurrentFrame;
- iFrame++)
+ for(iFrame = iCurrentFrame - iLastFrame + 1; iFrame < iCurrentFrame; iFrame++)
{
/* interpolate magnitude */
fMag += fIncrMag;
@@ -119,16 +118,16 @@ static void FillGap (int iCurrentFrame, int iTrack, int *pIState,
* \param pIState pointer to the state of tracks
* \param pAnalParams pointer to analysis parameters
*/
-static void DeleteShortTrack (int iCurrentFrame, int iTrack, int *pIState,
+static void DeleteShortTrack(int iCurrentFrame, int iTrack, int *pIState,
SMS_AnalParams *pAnalParams)
{
int iFrame, frame;
- for (iFrame = 1; iFrame <= pIState[iTrack]; iFrame++)
+ for(iFrame = 1; iFrame <= pIState[iTrack]; iFrame++)
{
frame = iCurrentFrame - iFrame;
- if (frame <= 0)
+ if(frame <= 0)
return;
pAnalParams->ppFrames[frame]->deterministic.pFSinAmp[iTrack] = 0;
@@ -136,11 +135,11 @@ static void DeleteShortTrack (int iCurrentFrame, int iTrack, int *pIState,
pAnalParams->ppFrames[frame]->deterministic.pFSinPha[iTrack] = 0;
}
- if (pAnalParams->iDebugMode == SMS_DBG_CLEAN_TRAJ ||
- pAnalParams->iDebugMode == SMS_DBG_ALL)
- fprintf (stdout, "deleteShortTrack: track %d, frames %d to %d deleted\n",
- iTrack, pAnalParams->ppFrames[iCurrentFrame - pIState[iTrack]]->iFrameNum,
- pAnalParams->ppFrames[iCurrentFrame-1]->iFrameNum);
+ if(pAnalParams->iDebugMode == SMS_DBG_CLEAN_TRAJ ||
+ pAnalParams->iDebugMode == SMS_DBG_ALL)
+ fprintf(stdout, "deleteShortTrack: track %d, frames %d to %d deleted\n",
+ iTrack, pAnalParams->ppFrames[iCurrentFrame - pIState[iTrack]]->iFrameNum,
+ pAnalParams->ppFrames[iCurrentFrame-1]->iFrameNum);
/* reset state */
pIState[iTrack] = -pAnalParams->iMaxSleepingTime;
@@ -227,8 +226,8 @@ 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;
@@ -237,8 +236,8 @@ void sms_scaleDet(sfloat *pFSynthBuffer, sfloat *pFOriginalBuffer,
/* get sound energy */
for(i = 0; i < pAnalParams->sizeHop; i++)
{
- fOriginalMag += fabs((double) pFOriginalBuffer[i]);
- fSynthesisMag += fabs((double) pFSynthBuffer[i]);
+ fOriginalMag += fabs(pFOriginalBuffer[i]);
+ fSynthesisMag += fabs(pFSynthBuffer[i]);
}
/* if total energy of deterministic sound is larger than original,
@@ -254,7 +253,7 @@ void sms_scaleDet(sfloat *pFSynthBuffer, sfloat *pFOriginalBuffer,
for(iTrack = 0; iTrack < nTrack; iTrack++)
if(pFSinAmp[iTrack] > 0)
- pFSinAmp[iTrack] = sms_magToDB (sms_dBToMag (pFSinAmp[iTrack]) * fCosScaleFactor);
+ pFSinAmp[iTrack] = sms_magToDB(sms_dBToMag(pFSinAmp[iTrack]) * fCosScaleFactor);
}
}
diff --git a/sms/sineSynth.c b/sms/sineSynth.c
index f2110af..c91bf65 100644
--- a/sms/sineSynth.c
+++ b/sms/sineSynth.c
@@ -163,25 +163,23 @@ void sms_sineSynthFrame(SMS_Data *pSmsData, sfloat *pFBuffer,
int iHalfSamplingRate = iSamplingRate >> 1;
/* go through all the tracks */
- for (i = 0; i < nTracks; i++)
+ 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)
+ /* make that sure 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))
+ 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)
+ if(pSmsData->pFSinPha == NULL)
{
SineSynth(fFreq, fMag, pLastFrame, pFBuffer, sizeBuffer, i);
}
diff --git a/sms/sms.c b/sms/sms.c
index 0b0950e..0942783 100644
--- a/sms/sms.c
+++ b/sms/sms.c
@@ -469,34 +469,36 @@ void sms_initSynthParams(SMS_SynthParams *synthParams)
*/
int sms_initSynth(SMS_SynthParams *pSynthParams)
{
- int sizeHop, sizeFft, err;
+ int sizeHop, sizeFft;
/* make sure sizeHop is something to the power of 2 */
sizeHop = sms_power2(pSynthParams->sizeHop);
if(sizeHop != pSynthParams->sizeHop)
{
- sms_error("sizeHop was not a power of two.");
- err = -1;
+ printf("Warning: Synthesis hop size (%d) was not a power of two.\n",
+ pSynthParams->sizeHop);
+ printf(" Changed to %d.\n", sizeHop);
pSynthParams->sizeHop = sizeHop;
}
sizeFft = sizeHop * 2;
- pSynthParams->pFStocWindow =(sfloat *) calloc(sizeFft, sizeof(sfloat));
+ /* TODO: check memory allocation */
+ pSynthParams->pFStocWindow = (sfloat *)calloc(sizeFft, sizeof(sfloat));
sms_getWindow(sizeFft, pSynthParams->pFStocWindow, SMS_WIN_HANNING);
- pSynthParams->pFDetWindow = (sfloat *) calloc(sizeFft, sizeof(sfloat));
+ pSynthParams->pFDetWindow = (sfloat *)calloc(sizeFft, sizeof(sfloat));
sms_getWindow(sizeFft, pSynthParams->pFDetWindow, SMS_WIN_IFFT);
- /* allocate memory for analysis data - size of original hopsize */
- /* previous frame to interpolate from */
+ /* 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->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));
+ 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));
/* approximation envelope */
pSynthParams->approxEnvelope = (sfloat *)calloc(pSynthParams->nStochasticCoeff, sizeof(sfloat));
diff --git a/sms/synthesis.c b/sms/synthesis.c
index 3a8a3bb..c7439f1 100644
--- a/sms/synthesis.c
+++ b/sms/synthesis.c
@@ -182,7 +182,7 @@ void sms_synthesize(SMS_Data *pSmsData, sfloat *pFSynthesis, SMS_SynthParams *p
else if(pSynthParams->iSynthesisType == SMS_STYPE_DET)
{
if(pSynthParams->iDetSynthType == SMS_DET_IFFT)
- SineSynthIFFT (pSmsData, pSynthParams);
+ SineSynthIFFT(pSmsData, pSynthParams);
else /*pSynthParams->iDetSynthType == SMS_DET_SIN*/
{
sms_sineSynthFrame(pSmsData, pSynthParams->pSynthBuff, pSynthParams->sizeHop,
@@ -196,5 +196,3 @@ void sms_synthesize(SMS_Data *pSmsData, sfloat *pFSynthesis, SMS_SynthParams *p
for(i = 0; i < sizeHop; i++)
pFSynthesis[i] = sms_deEmphasis(pSynthParams->pSynthBuff[i], pSynthParams);
}
-
-
diff --git a/tests/sms.py b/tests/sms.py
index 4073caf..920e7c2 100644
--- a/tests/sms.py
+++ b/tests/sms.py
@@ -75,6 +75,14 @@ class TestSimplSMS(object):
analysis_params.iStochasticType = simplsms.SMS_STOC_NONE
return analysis_params
+ def pysms_synthesis_params(self, sampling_rate):
+ synth_params = pysms.SMS_SynthParams()
+ pysms.sms_initSynthParams(synth_params)
+ synth_params.iSamplingRate = sampling_rate
+ synth_params.iSynthesisType = pysms.SMS_STYPE_DET
+ synth_params.sizeHop = self.hop_size
+ return synth_params
+
def test_size_next_read(self):
"""test_size_next_read
Make sure pysms PeakDetection is calculating
@@ -982,104 +990,82 @@ class TestSimplSMS(object):
simplsms.sms_freeAnalysis(analysis_params)
simplsms.sms_free()
- #def test_harmonic_synthesis(self):
- # """test_harmonic_synthesis
- # Compare pysms synthesised harmonic component with SMS synthesised
- # harmonic component."""
- # pysms.sms_init()
- # sms_header = pysms.SMS_Header()
- # snd_header = pysms.SMS_SndHeader()
- # # Try to open the input file to fill snd_header
- # if(pysms.sms_openSF(input_file, snd_header)):
- # raise NameError("error opening sound file: " + pysms.sms_errorString())
- # analysis_params = pysms.SMS_AnalParams()
- # analysis_params.iSamplingRate = 44100
- # analysis_params.iFrameRate = sampling_rate / hop_size
- # sms_header.nStochasticCoeff = 128
- # analysis_params.fDefaultFundamental = 100
- # analysis_params.fHighestFreq = 20000
- # analysis_params.iMaxDelayFrames = 3
- # analysis_params.analDelay = 0
- # analysis_params.minGoodFrames = 1
- # analysis_params.iFormat = pysms.SMS_FORMAT_HP
- # analysis_params.nTracks = max_partials
- # analysis_params.nGuides = max_partials
- # analysis_params.iWindowType = pysms.SMS_WIN_HAMMING
- # pysms.sms_initAnalysis(analysis_params, snd_header)
- # analysis_params.nFrames = num_samples / hop_size
- # analysis_params.iSizeSound = num_samples
- # analysis_params.peakParams.iMaxPeaks = max_peaks
- # analysis_params.iStochasticType = pysms.SMS_STOC_NONE
- # pysms.sms_fillHeader(sms_header, analysis_params, "pysms")
-
- # sample_offset = 0
- # size_new_data = 0
- # current_frame = 0
- # sms_header.nFrames = num_frames
- # analysis_frames = []
- # do_analysis = True
-
- # while do_analysis and (current_frame < num_frames):
- # sample_offset += size_new_data
- # if((sample_offset + analysis_params.sizeNextRead) < num_samples):
- # size_new_data = analysis_params.sizeNextRead
- # else:
- # size_new_data = num_samples - sample_offset
- # frame = audio[sample_offset:sample_offset + size_new_data]
- # analysis_data = pysms.SMS_Data()
- # pysms.sms_allocFrameH(sms_header, analysis_data)
- # status = pysms.sms_analyze(frame, analysis_data, analysis_params)
- # analysis_frames.append(analysis_data)
- # if status == -1:
- # do_analysis = False
- # current_frame += 1
+ def test_harmonic_synthesis(self):
+ """test_harmonic_synthesis
+ Compare pysms synthesised harmonic component with SMS synthesised
+ harmonic component."""
+ audio, sampling_rate = self.get_audio()
+ pysms.sms_init()
+ snd_header = pysms.SMS_SndHeader()
+ # Try to open the input file to fill snd_header
+ if(pysms.sms_openSF(self.input_file, snd_header)):
+ raise NameError("error opening sound file: " + pysms.sms_errorString())
+ analysis_params = self.pysms_analysis_params(sampling_rate)
+ analysis_params.nFrames = self.num_frames
+ if pysms.sms_initAnalysis(analysis_params, snd_header) != 0:
+ raise Exception("Error allocating memory for analysis_params")
+ analysis_params.iSizeSound = self.num_samples
+ sms_header = pysms.SMS_Header()
+ pysms.sms_fillHeader(sms_header, analysis_params, "pysms")
- # pysms.sms_freeAnalysis(analysis_params)
- # pysms.sms_closeSF()
+ sample_offset = 0
+ size_new_data = 0
+ current_frame = 0
+ analysis_frames = []
+ do_analysis = True
- # interp_frame = pysms.SMS_Data()
- # synth_params = pysms.SMS_SynthParams()
- # synth_params.iSynthesisType = pysms.SMS_STYPE_DET
- # synth_params.iDetSynthType = pysms.SMS_DET_SIN
- # synth_params.sizeHop = hop_size
- # synth_params.iSamplingRate = 0
+ while do_analysis and (current_frame < self.num_frames):
+ sample_offset += size_new_data
+ size_new_data = analysis_params.sizeNextRead
+ frame = audio[sample_offset:sample_offset + size_new_data]
+ # convert frame to floats for libsms
+ frame = np.array(frame, dtype=np.float32)
+ analysis_data = pysms.SMS_Data()
+ pysms.sms_allocFrameH(sms_header, analysis_data)
+ status = pysms.sms_analyze(frame, analysis_data, analysis_params)
+ analysis_frames.append(analysis_data)
+ if status == -1:
+ do_analysis = False
+ current_frame += 1
- # pysms.sms_initSynth(sms_header, synth_params)
- # pysms.sms_allocFrame(interp_frame, sms_header.nTracks, sms_header.nStochasticCoeff, 1, sms_header.iStochasticType, sms_header.nEnvCoeff)
+ synth_params = self.pysms_synthesis_params(sampling_rate)
+ pysms.sms_initSynth(sms_header, synth_params)
- # synth_samples = pysms.zeros(synth_params.sizeHop)
- # num_synth_samples = 0
- # target_synth_samples = len(analysis_frames) * hop_size
- # pysms_audio = pysms.array([])
- # current_frame = 0
+ synth_samples = np.zeros(synth_params.sizeHop, dtype=np.float32)
+ sms_audio = np.array([], dtype=np.float32)
+ current_frame = 0
- # while num_synth_samples < target_synth_samples:
- # pysms.sms_synthesize(analysis_frames[current_frame], synth_samples, synth_params)
- # pysms_audio = np.hstack((pysms_audio, synth_samples))
- # num_synth_samples += synth_params.sizeHop
- # current_frame += 1
+ while current_frame < len(analysis_frames):
+ pysms.sms_synthesize(analysis_frames[current_frame], synth_samples, synth_params)
+ sms_audio = np.hstack((sms_audio, synth_samples))
+ current_frame += 1
+ #from scipy.io.wavfile import write
+ #write('sms_audio.wav', sampling_rate, sms_audio)
- # pysms.sms_freeSynth(synth_params)
- # pysms.sms_free()
+ for frame in analysis_frames:
+ pysms.sms_freeFrame(frame)
+ pysms.sms_freeAnalysis(analysis_params)
+ pysms.sms_closeSF()
+ pysms.sms_freeSynth(synth_params)
+ pysms.sms_free()
- # pd = simpl.SMSPeakDetection()
- # pd.max_peaks = max_peaks
- # pd.hop_size = hop_size
- # pt = simpl.SMSPartialTracking()
- # pt.max_partials = max_partials
- # peaks = pd.find_peaks(audio)
- # partials = pt.find_partials(peaks[0:num_frames])
- # synth = simpl.SMSSynthesis()
- # synth.hop_size = hop_size
- # synth.stochastic_type = pysms.SMS_STOC_NONE
- # synth.synthesis_type = pysms.SMS_STYPE_DET
- # synth.max_partials = max_partials
- # simpl_audio = synth.synth(partials)
+ pd = simpl.SMSPeakDetection()
+ pd.max_peaks = self.max_peaks
+ pd.hop_size = self.hop_size
+ 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
+ synth.stochastic_type = pysms.SMS_STOC_NONE
+ synth.synthesis_type = pysms.SMS_STYPE_DET
+ synth.max_partials = self.max_partials
+ simpl_audio = synth.synth(partials)
- # self.assertEquals(pysms_audio.size, simpl_audio.size)
- # for i in range(simpl_audio.size):
- # self.assertAlmostEquals(pysms_audio[i], simpl_audio[i],
- # places = FLOAT_PRECISION)
+ assert len(sms_audio) == len(simpl_audio)
+ for i in range(simpl_audio.size):
+ assert_almost_equals(sms_audio[i], simpl_audio[i], self.FLOAT_PRECISION)
#def test_residual_synthesis(self):
# """test_residual_synthesis
@@ -1153,26 +1139,12 @@ class TestSimplSMS(object):
# res.num_coefficients = 128
# res.type = simpl.SMSResidual.TIME_DOMAIN
# residual = res.find_residual(simpl_harmonic, audio[0:simpl_harmonic.size])
-# print_partials(partials)
-# print simpl_harmonic.size
-# for i in range(residual.size):
-# print residual[i]
-# for i in range(simpl_harmonic.size):
-# print simpl_harmonic[i]
-# from pylab import plot, show
-# plot(simpl_harmonic)
-# plot(residual)
-# plot(audio[0:simpl_harmonic.size])
-# show()
-# from scipy.io.wavfile import write
-# write("res.wav", 44100, residual)
-# res.synth(simpl_harmonic, audio)
if __name__ == "__main__":
# run individual tests programatically
# useful for debugging, particularly with GDB
import nose
argv = [__file__,
- __file__ + ":TestSimplSMS.test_simplsms_interpolate_frames"]
+ __file__ + ":TestSimplSMS.test_harmonic_synthesis"]
nose.run(argv=argv)