summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorJohn Glover <j@johnglover.net>2012-07-06 14:53:01 +0100
committerJohn Glover <j@johnglover.net>2012-07-06 14:53:01 +0100
commitd15e78188a9cdbd70640ac57e42d4a598c89b532 (patch)
tree6c7c371cc7271312ec74f4c6e80eef44513568e6 /tests
parente124bdb052109b1b0e73ae51f55df32f52dbcf9c (diff)
downloadsimpl-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.py74
-rw-r--r--tests/test_residual.py90
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)