summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/create_libsms_test_data.py90
-rw-r--r--tests/test_synthesis.py89
2 files changed, 173 insertions, 6 deletions
diff --git a/tests/create_libsms_test_data.py b/tests/create_libsms_test_data.py
index 4adf6f3..0fedbc0 100644
--- a/tests/create_libsms_test_data.py
+++ b/tests/create_libsms_test_data.py
@@ -1,6 +1,7 @@
import os
import json
import numpy as np
+import scipy.io.wavfile as wav
import pysms
import simpl
@@ -38,6 +39,18 @@ def _pysms_analysis_params(sampling_rate):
return analysis_params
+def _pysms_synthesis_params(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.iStochasticType = pysms.SMS_STOC_NONE
+ synth_params.sizeHop = hop_size
+ synth_params.nTracks = max_peaks
+ synth_params.deEmphasis = 0
+ return synth_params
+
+
def _size_next_read():
pysms.sms_init()
snd_header = pysms.SMS_SndHeader()
@@ -165,9 +178,83 @@ def _partial_tracking():
return sms_frames
+def _harmonic_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)
+ 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)
+
+ if status == 1:
+ current_frame += 1
+ analysis_frames.append(analysis_data)
+ elif status == 0:
+ pysms.sms_freeFrame(analysis_data)
+ if status == -1:
+ do_analysis = False
+ pysms.sms_freeFrame(analysis_data)
+
+ # blank_frame = analysis_frames[0]
+ # analysis_frames = analysis_frames[1:]
+ # pysms.sms_freeFrame(blank_frame)
+
+ synth_params = _pysms_synthesis_params(sampling_rate)
+ 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 = _harmonic_synthesis()
test_data = {'size_next_read': size_next_read,
'peak_detection': partial_tracking,
@@ -176,3 +263,6 @@ if __name__ == '__main__':
test_data = json.dumps(test_data)
with open('libsms_test_data.json', 'w') as f:
f.write(test_data)
+
+ wav.write('libsms_harmonic_synthesis.wav', sampling_rate,
+ harmonic_synthesis)
diff --git a/tests/test_synthesis.py b/tests/test_synthesis.py
index 794b047..8c592a5 100644
--- a/tests/test_synthesis.py
+++ b/tests/test_synthesis.py
@@ -1,4 +1,5 @@
import os
+import json
import numpy as np
from nose.tools import assert_almost_equals
import simpl
@@ -6,27 +7,103 @@ import simpl.peak_detection as peak_detection
import simpl.partial_tracking as partial_tracking
import simpl.synthesis as synthesis
-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_test_data_path = os.path.join(
+ os.path.dirname(__file__), 'libsms_test_data.json'
+)
+libsms_harmonic_synthesis_path = os.path.join(
+ os.path.dirname(__file__), 'libsms_harmonic_synthesis.wav'
+)
+
+PeakDetection = peak_detection.PeakDetection
+SMSPeakDetection = peak_detection.SMSPeakDetection
+PartialTracking = partial_tracking.PartialTracking
+SMSPartialTracking = partial_tracking.SMSPartialTracking
+Synthesis = synthesis.Synthesis
+SMSSynthesis = synthesis.SMSSynthesis
+
+
+def _load_libsms_test_data():
+ test_data = None
+ with open(libsms_test_data_path, 'r') as f:
+ test_data = json.loads(f.read())
+ return test_data
class TestSynthesis(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 = PeakDetection()
+ pd.hop_size = hop_size
+ frames = pd.find_peaks(self.audio)
+
+ pt = PartialTracking()
+ pt.max_partials = max_partials
+ frames = pt.find_partials(frames)
+
+ s = Synthesis()
+ s.hop_size = hop_size
+ synth_audio = s.synth(frames)
+
+ assert len(synth_audio) == len(self.audio)
+
+
+class TestSMSSynthesis(object):
+ @classmethod
+ def setup_class(cls):
+ cls.audio = simpl.read_wav(audio_path)[0]
+ cls.audio = cls.audio[0:num_samples]
+ cls.test_data = _load_libsms_test_data()
- def test_synthesis(self):
- pd = peak_detection.PeakDetection()
+ 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()
+ s = SMSSynthesis()
+ s.hop_size = hop_size
synth_audio = s.synth(frames)
- assert len(synth_audio)
+ assert len(synth_audio) == len(self.audio)
+
+ def test_harmonic_synthesis(self):
+ pd = SMSPeakDetection()
+ 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.det_synthesis_type = SMSSynthesis.SMS_DET_IFFT
+ synth_audio = synth.synth(frames)
+
+ assert len(synth_audio) == len(self.audio)
+
+ sms_audio, sampling_rate = simpl.read_wav(
+ libsms_harmonic_synthesis_path
+ )
+
+ assert len(synth_audio) == len(sms_audio)
+
+ for i in range(len(synth_audio)):
+ assert_almost_equals(synth_audio[i], sms_audio[i], float_precision)