diff options
author | John Glover <j@johnglover.net> | 2012-07-06 14:53:01 +0100 |
---|---|---|
committer | John Glover <j@johnglover.net> | 2012-07-06 14:53:01 +0100 |
commit | d15e78188a9cdbd70640ac57e42d4a598c89b532 (patch) | |
tree | 6c7c371cc7271312ec74f4c6e80eef44513568e6 /tests | |
parent | e124bdb052109b1b0e73ae51f55df32f52dbcf9c (diff) | |
download | simpl-d15e78188a9cdbd70640ac57e42d4a598c89b532.tar.gz simpl-d15e78188a9cdbd70640ac57e42d4a598c89b532.tar.bz2 simpl-d15e78188a9cdbd70640ac57e42d4a598c89b532.zip |
[residual] Add C++ implementation of SMSResidual.
Diffstat (limited to 'tests')
-rw-r--r-- | tests/create_libsms_test_data.py | 74 | ||||
-rw-r--r-- | tests/test_residual.py | 90 |
2 files changed, 156 insertions, 8 deletions
diff --git a/tests/create_libsms_test_data.py b/tests/create_libsms_test_data.py index 553c292..05b8cee 100644 --- a/tests/create_libsms_test_data.py +++ b/tests/create_libsms_test_data.py @@ -251,11 +251,83 @@ def _harmonic_synthesis(det_synth_type): return synth_audio +def _residual_synthesis(): + pysms.sms_init() + snd_header = pysms.SMS_SndHeader() + + if(pysms.sms_openSF(audio_path, snd_header)): + raise NameError(pysms.sms_errorString()) + + analysis_params = _pysms_analysis_params(sampling_rate) + analysis_params.nStochasticCoeff = 128 + analysis_params.iStochasticType = pysms.SMS_STOC_APPROX + if pysms.sms_initAnalysis(analysis_params, snd_header) != 0: + raise Exception("Error allocating memory for analysis_params") + analysis_params.iSizeSound = num_samples + analysis_params.nFrames = num_frames + sms_header = pysms.SMS_Header() + pysms.sms_fillHeader(sms_header, analysis_params, "pysms") + + sample_offset = 0 + size_new_data = 0 + current_frame = 0 + analysis_frames = [] + do_analysis = True + + while do_analysis and (current_frame < num_frames): + sample_offset += size_new_data + size_new_data = analysis_params.sizeNextRead + + frame_audio = audio[sample_offset:sample_offset + size_new_data] + frame_audio = np.array(frame_audio, dtype=np.float32) + if len(frame_audio) < size_new_data: + frame_audio = np.hstack(( + frame_audio, np.zeros(size_new_data - len(frame_audio), + dtype=np.float32) + )) + + analysis_data = pysms.SMS_Data() + pysms.sms_allocFrameH(sms_header, analysis_data) + status = pysms.sms_analyze(frame_audio, analysis_data, + analysis_params) + + analysis_frames.append(analysis_data) + current_frame += 1 + + if status == -1: + do_analysis = False + + sms_header.nFrames = len(analysis_frames) + synth_params = _pysms_synthesis_params(sampling_rate) + synth_params.iStochasticType = pysms.SMS_STOC_APPROX + synth_params.iSynthesisType = pysms.SMS_STYPE_STOC + pysms.sms_initSynth(sms_header, synth_params) + + synth_frame = np.zeros(synth_params.sizeHop, dtype=np.float32) + synth_audio = np.array([], dtype=np.float32) + + for i in range(len(analysis_frames)): + pysms.sms_synthesize(analysis_frames[i], synth_frame, synth_params) + synth_audio = np.hstack((synth_audio, synth_frame)) + + synth_audio = np.asarray(synth_audio * 32768, np.int16) + + 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() + + return synth_audio + + if __name__ == '__main__': size_next_read = _size_next_read() partial_tracking = _partial_tracking() harmonic_synthesis_ifft = _harmonic_synthesis('ifft') harmonic_synthesis_sin = _harmonic_synthesis('sin') + residual_synthesis = _residual_synthesis() test_data = {'size_next_read': size_next_read, 'peak_detection': partial_tracking, @@ -269,3 +341,5 @@ if __name__ == '__main__': harmonic_synthesis_ifft) wav.write('libsms_harmonic_synthesis_sin.wav', sampling_rate, harmonic_synthesis_sin) + wav.write('libsms_residual_synthesis.wav', sampling_rate, + residual_synthesis) diff --git a/tests/test_residual.py b/tests/test_residual.py index 205ee59..e3992a8 100644 --- a/tests/test_residual.py +++ b/tests/test_residual.py @@ -7,12 +7,28 @@ import simpl.partial_tracking as partial_tracking import simpl.synthesis as synthesis import simpl.residual as residual -float_precision = 5 +float_precision = 2 frame_size = 512 hop_size = 512 +max_peaks = 10 +max_partials = 10 +num_frames = 30 +num_samples = num_frames * hop_size audio_path = os.path.join( os.path.dirname(__file__), 'audio/flute.wav' ) +libsms_residual_synthesis_path = os.path.join( + os.path.dirname(__file__), 'libsms_residual_synthesis.wav' +) + +PeakDetection = peak_detection.PeakDetection +SMSPeakDetection = peak_detection.SMSPeakDetection +PartialTracking = partial_tracking.PartialTracking +SMSPartialTracking = partial_tracking.SMSPartialTracking +Synthesis = synthesis.Synthesis +SMSSynthesis = synthesis.SMSSynthesis +Residual = residual.Residual +SMSResidual = residual.SMSResidual class TestResidual(object): @@ -20,16 +36,74 @@ class TestResidual(object): def setup_class(cls): cls.audio = simpl.read_wav(audio_path)[0] - def test_synthesis(self): - pd = peak_detection.PeakDetection() + def test_basic(self): + pd = PeakDetection() + frames = pd.find_peaks(self.audio) + + pt = PartialTracking() + frames = pt.find_partials(frames) + + synth = Synthesis() + synth_audio = synth.synth(frames) + + res = Residual() + residual_audio = res.find_residual(synth_audio, self.audio) + assert len(residual_audio) + + +class TestSMSResidual(object): + @classmethod + def setup_class(cls): + cls.audio = simpl.read_wav(audio_path)[0] + cls.audio = cls.audio[0:num_samples] + + def test_basic(self): + pd = SMSPeakDetection() + pd.hop_size = hop_size frames = pd.find_peaks(self.audio) - pt = partial_tracking.PartialTracking() + pt = SMSPartialTracking() + pt.max_partials = max_partials frames = pt.find_partials(frames) - s = synthesis.Synthesis() - synth_audio = s.synth(frames) + synth = SMSSynthesis() + synth.hop_size = hop_size + synth_audio = synth.synth(frames) - r = residual.Residual() - residual_audio = r.find_residual(synth_audio, self.audio) + res = SMSResidual() + residual_audio = res.find_residual(synth_audio, self.audio) assert len(residual_audio) + + def test_residual_synthesis(self): + pd = SMSPeakDetection() + pd.max_peaks = max_peaks + pd.hop_size = hop_size + frames = pd.find_peaks(self.audio) + + pt = SMSPartialTracking() + pt.max_partials = max_partials + frames = pt.find_partials(frames) + + synth = SMSSynthesis() + synth.hop_size = hop_size + synth.max_partials = max_partials + simpl_harmonic = synth.synth(frames) + + res = SMSResidual() + res.hop_size = hop_size + simpl_residual = res.synth(simpl_harmonic, self.audio) + + sms_residual, sampling_rate = simpl.read_wav( + libsms_residual_synthesis_path + ) + + assert len(simpl_residual) == len(sms_residual) + + # import matplotlib.pyplot as plt + # plt.plot(simpl_residual) + # plt.plot(sms_residual) + # plt.show() + + for i in range(len(simpl_residual)): + assert_almost_equals(simpl_residual[i], sms_residual[i], + float_precision) |