summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorJohn Glover <glover.john@gmail.com>2011-01-06 11:54:26 +0000
committerJohn Glover <glover.john@gmail.com>2011-01-06 11:54:26 +0000
commit0c141d4c9a03d4839e2a8626961bd6bbdd3e7f26 (patch)
tree33c6f276f0b9ace8d96535f4afb89926ec33e7bc /tests
parent17c5625449888117208447dd4f86504281357013 (diff)
downloadsimpl-0c141d4c9a03d4839e2a8626961bd6bbdd3e7f26.tar.gz
simpl-0c141d4c9a03d4839e2a8626961bd6bbdd3e7f26.tar.bz2
simpl-0c141d4c9a03d4839e2a8626961bd6bbdd3e7f26.zip
Fixed SMSResidual. Also removed blank frames produced by sms at the beginning of analysis which was causing synthesised audio to be out of sync with the original.
Diffstat (limited to 'tests')
-rw-r--r--tests/sms.py111
1 files changed, 68 insertions, 43 deletions
diff --git a/tests/sms.py b/tests/sms.py
index b09e692..ca51f3f 100644
--- a/tests/sms.py
+++ b/tests/sms.py
@@ -24,10 +24,8 @@ from nose.tools import assert_almost_equals
class TestSimplSMS(object):
FLOAT_PRECISION = 2 # number of decimal places to check for accuracy
input_file = 'audio/flute.wav'
- frame_size = 2048
hop_size = 512
num_frames = 50
- #num_samples = frame_size + ((num_frames - 1) * hop_size)
num_samples = num_frames * hop_size
max_peaks = 10
max_partials = 10
@@ -55,6 +53,7 @@ class TestSimplSMS(object):
analysis_params.minGoodFrames = 1
analysis_params.iCleanTracks = 0
analysis_params.iStochasticType = pysms.SMS_STOC_NONE
+ analysis_params.preEmphasis = 0
return analysis_params
def simplsms_analysis_params(self, sampling_rate):
@@ -74,6 +73,7 @@ class TestSimplSMS(object):
analysis_params.minGoodFrames = 1
analysis_params.iCleanTracks = 0
analysis_params.iStochasticType = simplsms.SMS_STOC_NONE
+ analysis_params.preEmphasis = 0
return analysis_params
def pysms_synthesis_params(self, sampling_rate):
@@ -84,6 +84,7 @@ class TestSimplSMS(object):
synth_params.iStochasticType = pysms.SMS_STOC_NONE
synth_params.sizeHop = self.hop_size
synth_params.nTracks = self.max_peaks
+ synth_params.deEmphasis = 0
return synth_params
def test_size_next_read(self):
@@ -112,13 +113,13 @@ class TestSimplSMS(object):
while current_frame < self.num_frames:
sms_next_read_sizes.append(analysis_params.sizeNextRead)
sample_offset += pysms_size_new_data
- if((sample_offset + analysis_params.sizeNextRead) < self.num_samples):
- pysms_size_new_data = analysis_params.sizeNextRead
- else:
- pysms_size_new_data = self.num_samples - sample_offset
+ pysms_size_new_data = analysis_params.sizeNextRead
# convert frame to floats for libsms
frame = audio[sample_offset:sample_offset + pysms_size_new_data]
frame = np.array(frame, dtype=np.float32)
+ if len(frame) < pysms_size_new_data:
+ frame = np.hstack((frame, np.zeros(pysms_size_new_data - len(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)
@@ -141,6 +142,7 @@ class TestSimplSMS(object):
while current_frame < self.num_frames:
pd.frame_size = pd.get_next_frame_size()
+ #print current_frame, sms_next_read_sizes[current_frame], pd.frame_size
assert sms_next_read_sizes[current_frame] == pd.frame_size
frame = simpl.Frame()
frame.size = pd.frame_size
@@ -181,6 +183,9 @@ class TestSimplSMS(object):
frame.size = size_new_data
frame.audio = np.array(audio[sample_offset:sample_offset + size_new_data],
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)
@@ -242,6 +247,8 @@ class TestSimplSMS(object):
frame = simpl.Frame()
frame.size = size_new_data
frame.audio = audio[sample_offset:sample_offset + size_new_data]
+ if len(frame.audio) < size_new_data:
+ frame.audio = np.hstack((frame.audio, simpl.zeros(size_new_data - len(frame.audio))))
analysis_data = simplsms.SMS_Data()
simplsms.sms_allocFrameH(simpl_sms_header, analysis_data)
status = simplsms.sms_analyze(frame.audio, analysis_data, simpl_analysis_params)
@@ -483,6 +490,8 @@ class TestSimplSMS(object):
sample_offset += size_new_data
size_new_data = analysis_params.sizeNextRead
frame = audio[sample_offset:sample_offset + size_new_data]
+ if len(frame) < size_new_data:
+ frame = np.hstack((frame, simpl.zeros(size_new_data - len(frame))))
analysis_data = simplsms.SMS_Data()
simplsms.sms_allocFrameH(sms_header, analysis_data)
status = simplsms.sms_analyze(frame, analysis_data, analysis_params)
@@ -526,6 +535,8 @@ class TestSimplSMS(object):
frame = simpl.Frame()
frame.size = pd.frame_size
frame.audio = audio[sample_offset:sample_offset + pd.frame_size]
+ if len(frame.audio) < pd.frame_size:
+ frame.audio = np.hstack((frame.audio, simpl.zeros(pd.frame_size - len(frame.audio))))
simpl_peaks.append(pd.find_peaks_in_frame(frame))
sample_offset += pd.frame_size
current_frame += 1
@@ -764,30 +775,27 @@ class TestSimplSMS(object):
p.frequency = sms_freqs[i]
p.phase = sms_phases[i]
peaks.append(p)
- else:
- for i in range(num_partials):
- p = simpl.Peak()
- p.amplitude = 0.0
- p.frequency = 0.0
- p.phase = 0.0
- peaks.append(p)
+ frame.partials = peaks
+ sms_frames.append(frame)
+ current_frame += 1
if status == -1:
do_analysis = False
- frame.partials = peaks
- sms_frames.append(frame)
pysms.sms_freeFrame(analysis_data)
- current_frame += 1
+ # first frame is blank
+ sms_frames = sms_frames[1:]
+
+ # free sms memory
pysms.sms_freeAnalysis(analysis_params)
pysms.sms_closeSF()
pysms.sms_free()
pd = simpl.SMSPeakDetection()
pd.max_peaks = self.max_peaks
- pd.hop_size = self.hop_size
- peaks = pd.find_peaks(audio)[0:self.num_frames]
+ pd.hop_size = self.hop_size
+ peaks = pd.find_peaks(audio)
pt = simpl.SMSPartialTracking()
pt.max_partials = self.max_partials
simpl_frames = pt.find_partials(peaks)
@@ -1023,10 +1031,19 @@ class TestSimplSMS(object):
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:
+ if status == 1:
+ analysis_frames.append(analysis_data)
+ current_frame += 1
+ elif status == 0:
+ pysms.sms_freeFrame(analysis_data)
+ elif status == -1:
do_analysis = False
- current_frame += 1
+ pysms.sms_freeFrame(analysis_data)
+
+ # remove the first frame, it's blank
+ blank_frame = analysis_frames[0]
+ analysis_frames = analysis_frames[1:]
+ pysms.sms_freeFrame(blank_frame)
synth_params = self.pysms_synthesis_params(sampling_rate)
pysms.sms_initSynth(sms_header, synth_params)
@@ -1050,15 +1067,14 @@ class TestSimplSMS(object):
pd = simpl.SMSPeakDetection()
pd.max_peaks = self.max_peaks
pd.hop_size = self.hop_size
- peaks = pd.find_peaks(audio)[0:self.num_frames]
+ peaks = pd.find_peaks(audio)
pt = simpl.SMSPartialTracking()
pt.max_partials = self.max_partials
partials = pt.find_partials(peaks)
synth = simpl.SMSSynthesis()
synth.hop_size = self.hop_size
synth.max_partials = self.max_partials
- synth.stochastic_type = simplsms.SMS_STOC_NONE
- synth.synthesis_type = simplsms.SMS_STYPE_DET
+ synth.det_synthesis_type = simplsms.SMS_DET_IFFT
simpl_audio = synth.synth(partials)
assert len(sms_audio) == len(simpl_audio)
@@ -1066,7 +1082,7 @@ class TestSimplSMS(object):
assert_almost_equals(sms_audio[i], simpl_audio[i], self.FLOAT_PRECISION)
def test_harmonic_synthesis_sin(self):
- """test_harmonic_synthesis
+ """test_harmonic_synthesis_sin
Compare pysms synthesised harmonic component with SMS synthesised
harmonic component."""
audio, sampling_rate = self.get_audio()
@@ -1076,10 +1092,10 @@ class TestSimplSMS(object):
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
+ analysis_params.nFrames = self.num_frames
sms_header = pysms.SMS_Header()
pysms.sms_fillHeader(sms_header, analysis_params, "pysms")
@@ -1095,16 +1111,28 @@ class TestSimplSMS(object):
frame = audio[sample_offset:sample_offset + size_new_data]
# convert frame to floats for libsms
frame = np.array(frame, dtype=np.float32)
+ if len(frame) < size_new_data:
+ frame = np.hstack((frame, np.zeros(size_new_data - len(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:
+ if status == 1:
+ analysis_frames.append(analysis_data)
+ current_frame += 1
+ elif status == 0:
+ pysms.sms_freeFrame(analysis_data)
+ elif status == -1:
do_analysis = False
- current_frame += 1
+ pysms.sms_freeFrame(analysis_data)
+
+ # remove the first frame, it's blank
+ blank_frame = analysis_frames[0]
+ analysis_frames = analysis_frames[1:]
+ pysms.sms_freeFrame(blank_frame)
synth_params = self.pysms_synthesis_params(sampling_rate)
- synth_params.iDetSynthesisType = pysms.SMS_DET_SIN
+ synth_params.iDetSynthType = pysms.SMS_DET_SIN
pysms.sms_initSynth(sms_header, synth_params)
synth_samples = np.zeros(synth_params.sizeHop, dtype=np.float32)
@@ -1126,14 +1154,13 @@ class TestSimplSMS(object):
pd = simpl.SMSPeakDetection()
pd.max_peaks = self.max_peaks
pd.hop_size = self.hop_size
- peaks = pd.find_peaks(audio)[0:self.num_frames]
+ peaks = pd.find_peaks(audio)
pt = simpl.SMSPartialTracking()
pt.max_partials = self.max_partials
partials = pt.find_partials(peaks)
synth = simpl.SMSSynthesis()
synth.hop_size = self.hop_size
synth.max_partials = self.max_partials
- synth.stochastic_type = simplsms.SMS_STOC_NONE
synth.det_synthesis_type = simplsms.SMS_DET_SIN
simpl_audio = synth.synth(partials)
@@ -1144,6 +1171,13 @@ class TestSimplSMS(object):
def test_residual_synthesis(self):
"""test_residual_synthesis
Compare pysms residual signal with SMS residual"""
+
+ # -------------------------------------------
+ # This test is not finished yet. Skip for now
+ from nose.plugins.skip import SkipTest
+ raise SkipTest
+ # -------------------------------------------
+
audio, sampling_rate = self.get_audio()
pysms.sms_init()
snd_header = pysms.SMS_SndHeader()
@@ -1154,7 +1188,6 @@ class TestSimplSMS(object):
analysis_params.nFrames = self.num_frames
analysis_params.nStochasticCoeff = 128
analysis_params.iStochasticType = pysms.SMS_STOC_APPROX
- analysis_params.preEmphasis = 0
if pysms.sms_initAnalysis(analysis_params, snd_header) != 0:
raise Exception("Error allocating memory for analysis_params")
analysis_params.iSizeSound = self.num_samples
@@ -1176,13 +1209,6 @@ class TestSimplSMS(object):
analysis_data = pysms.SMS_Data()
pysms.sms_allocFrameH(sms_header, analysis_data)
status = pysms.sms_analyze(frame, analysis_data, analysis_params)
- #if status == 1:
- # analysis_frames.append(analysis_data)
- #elif status == -1:
- # do_analysis = False
- # pysms.sms_freeFrame(analysis_data)
- #else:
- # pysms.sms_freeFrame(analysis_data)
analysis_frames.append(analysis_data)
if status == -1:
do_analysis = False
@@ -1192,7 +1218,6 @@ class TestSimplSMS(object):
synth_params = self.pysms_synthesis_params(sampling_rate)
synth_params.iStochasticType = pysms.SMS_STOC_APPROX
synth_params.iSynthesisType = pysms.SMS_STYPE_STOC
- synth_params.deEmphasis = 0
pysms.sms_initSynth(sms_header, synth_params)
synth_samples = np.zeros(synth_params.sizeHop, dtype=np.float32)
sms_residual = np.array([], dtype=np.float32)
@@ -1235,7 +1260,7 @@ if __name__ == "__main__":
# useful for debugging, particularly with GDB
import nose
argv = [__file__,
+ "--nocapture",
#__file__ + ":TestSimplSMS.test_residual_synthesis"]
- __file__ + ":TestSimplSMS.test_sms_analyze"]
+ __file__ + ":TestSimplSMS.test_harmonic_synthesis_sin"]
nose.run(argv=argv)
-