shithub: aubio

Download patch

ref: 88432a9429e344b282b59f96a8de7d8aaf7a5548
parent: 3f9e8e50f8c3d39d66461a0e53a739f78ebbddf8
author: Paul Brossier <piem@piem.org>
date: Sat Jan 11 16:59:49 EST 2014

python/lib/aubio/slicing.py: rewrite slicing loop from aubiocut, add some tests

--- /dev/null
+++ b/python/lib/aubio/slicing.py
@@ -1,0 +1,56 @@
+from aubio import source, sink
+import os
+
+def slice_source_at_stamps(source_file, timestamps, timestamps_end = None,
+        output_dir = None,
+        samplerate = 0,
+        hopsize = 256):
+
+    source_base_name, source_ext = os.path.splitext(os.path.basename(source_file))
+    if output_dir != None:
+        if not os.path.isdir(output_dir):
+            os.makedirs(output_dir)
+        source_base_name = os.path.join(output_dir, source_base_name)
+
+    def new_sink_name(source_base_name, timestamp):
+        return source_base_name + '_%02.3f' % (timestamp) + '.wav'
+
+    # reopen source file
+    s = source(source_file, samplerate, hopsize)
+    if samplerate == 0: samplerate = s.get_samplerate()
+    # create first sink at 0
+    g = sink(new_sink_name(source_base_name, 0.), samplerate)
+    total_frames = 0
+    # get next region
+    next_stamp = int(timestamps.pop(0))
+    if not next_stamp:
+        next_stamp = int(timestamps.pop(0))
+
+    while True:
+        # get hopsize new samples from source
+        vec, read = s()
+        remaining = next_stamp - total_frames
+        # not enough frames remaining, time to split
+        if remaining <= read:
+            if remaining != 0:
+                # write remaining samples from current region
+                g(vec[0:remaining], remaining)
+            # close this file
+            del g
+            # create a new file for the new region
+            new_sink_path = new_sink_name(source_base_name, next_stamp / float(samplerate))
+            #print "new slice", total_frames, "+", remaining, "=", next_stamp
+            g = sink(new_sink_path, samplerate)
+            if remaining != read:
+                # write the remaining samples in the new file
+                g(vec[remaining:read], read - remaining)
+            if len(timestamps):
+                next_stamp = int(timestamps.pop(0))
+            else:
+                next_stamp = 1e120
+        else:
+            g(vec[0:read], read)
+        total_frames += read
+        if read < hopsize: break
+
+    del g
--- /dev/null
+++ b/python/tests/test_slicing.py
@@ -1,0 +1,41 @@
+#! /usr/bin/env python
+
+from numpy.testing import TestCase, run_module_suite
+from numpy.testing import assert_equal, assert_almost_equal
+
+from aubio import slice_source_at_stamps
+from utils import count_samples_in_file, count_samples_in_directory
+
+import tempfile
+import shutil
+
+class aubio_slicing_test_case(TestCase):
+
+    def setUp(self):
+        self.source_file = 'chocolate_1min.wav'
+        self.output_dir = tempfile.mkdtemp(suffix = 'aubio_slicing_test_case')
+
+    def test_slice_start_only(self):
+        regions_start = [i*1000 for i in range(100)]
+        slice_source_at_stamps(self.source_file, regions_start, output_dir = self.output_dir)
+
+    def test_slice_start_only_no_zero(self):
+        regions_start = [i*1000 for i in range(1, 100)]
+        slice_source_at_stamps(self.source_file, regions_start, output_dir = self.output_dir)
+
+    def test_slice_start_beyond_end(self):
+        regions_start = [i*1000 for i in range(1, 100)]
+        regions_start += [count_samples_in_file(self.source_file)]
+        regions_start += [count_samples_in_file(self.source_file) + 1000]
+        slice_source_at_stamps(self.source_file, regions_start, output_dir = self.output_dir)
+
+    def tearDown(self):
+        original_samples = count_samples_in_file(self.source_file)
+        written_samples = count_samples_in_directory(self.output_dir)
+        assert_equal(original_samples, written_samples,
+            "number samples written different from number of original samples")
+        shutil.rmtree(self.output_dir)
+
+if __name__ == '__main__':
+    from unittest import main
+    main()
--- a/python/tests/utils.py
+++ b/python/tests/utils.py
@@ -18,3 +18,25 @@
     yaml_data = yaml.safe_load(f)
     f.close()
     return yaml_data
+
+def count_samples_in_file(file_path):
+    from aubio import source
+    hopsize = 256
+    s = source(file_path, 0, hopsize)
+    total_frames = 0
+    while True:
+        samples, read = s()
+        total_frames += read
+        if read < hopsize: break
+    return total_frames
+
+def count_samples_in_directory(samples_dir):
+    import os
+    total_frames = 0
+    for f in os.walk(samples_dir):
+        if len(f[2]):
+            for each in f[2]:
+                file_path = os.path.join(f[0], each)
+                if file_path:
+                    total_frames += count_samples_in_file(file_path)
+    return total_frames