changeset 372:d653e3f58f3c

`samples` should always return a list of arrays
author Amine Sehili <amine.sehili@gmail.com>
date Fri, 15 Jan 2021 21:02:29 +0100
parents 8d3e2b492c6f
children 562b7a64b7ea
files auditok/signal.py tests/test_signal.py
diffstat 2 files changed, 34 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/auditok/signal.py	Mon Jan 11 21:13:08 2021 +0100
+++ b/auditok/signal.py	Fri Jan 15 21:02:29 2021 +0100
@@ -12,7 +12,7 @@
     calculate_energy_single_channel
     calculate_energy_multichannel
 """
-from array import array
+from array import array as array_
 import audioop
 import math
 
@@ -21,14 +21,30 @@
 
 
 def to_array(data, sample_width, channels):
+    """Extract individual channels of audio data and return a list of arrays of
+    numeric samples. This will always return a list of `array.array` objects
+    (one per channel) even if audio data is mono.
+
+    Parameters
+    ----------
+    data : bytes
+        raw audio data.
+    sample_width : int
+        size in bytes of one audio sample (one channel considered).
+
+    Returns
+    -------
+    samples_arrays : list
+        list of arrays of audio samples.
+    """
     fmt = FORMAT[sample_width]
     if channels == 1:
-        return array(fmt, data)
+        return [array_(fmt, data)]
     return separate_channels(data, fmt, channels)
 
 
 def extract_single_channel(data, fmt, channels, selected):
-    samples = array(fmt, data)
+    samples = array_(fmt, data)
     return samples[selected::channels]
 
 
@@ -55,11 +71,11 @@
     mono_audio : bytes
         mixed down audio data.
     """
-    all_channels = array(fmt, data)
+    all_channels = array_(fmt, data)
     mono_channels = [
-        array(fmt, all_channels[ch::channels]) for ch in range(channels)
+        array_(fmt, all_channels[ch::channels]) for ch in range(channels)
     ]
-    avg_arr = array(
+    avg_arr = array_(
         fmt,
         (round(sum(samples) / channels) for samples in zip(*mono_channels)),
     )
@@ -77,7 +93,7 @@
     data : bytes
         2-channel audio data to mix down.
     sample_width : int
-        size of audio samples (for 1 channel) in bytes.
+        size in bytes of one audio sample (one channel considered).
 
     Returns
     -------
@@ -85,7 +101,7 @@
         mixed down audio data.
     """
     fmt = FORMAT[sample_width]
-    arr = array(fmt, audioop.tomono(data, sample_width, 0.5, 0.5))
+    arr = array_(fmt, audioop.tomono(data, sample_width, 0.5, 0.5))
     return arr
 
 
@@ -109,9 +125,9 @@
     channels_arr : list
         list of audio channels, each as a standard `array.array`.
     """
-    all_channels = array(fmt, data)
+    all_channels = array_(fmt, data)
     mono_channels = [
-        array(fmt, all_channels[ch::channels]) for ch in range(channels)
+        array_(fmt, all_channels[ch::channels]) for ch in range(channels)
     ]
     return mono_channels
 
@@ -150,7 +166,7 @@
     data : bytes
         single-channel audio data.
     sample_width : int
-        size in bytes of one audio sample.
+        size in bytes of one audio sample (one channel considered).
     aggregation_fn : callable, default: max
         aggregation function to apply to the resulting per-channel energies.
 
--- a/tests/test_signal.py	Mon Jan 11 21:13:08 2021 +0100
+++ b/tests/test_signal.py	Fri Jan 15 21:02:29 2021 +0100
@@ -14,22 +14,18 @@
         self.numpy_fmt = {"b": np.int8, "h": np.int16, "i": np.int32}
 
     @genty_dataset(
-        int8_mono=(1, [48, 49, 50, 51, 52, 53, 54, 55, 57, 65, 66, 67]),
-        int16_mono=(2, [12592, 13106, 13620, 14134, 16697, 17218]),
-        int32_mono=(4, [858927408, 926299444, 1128415545]),
+        int8_mono=(1, [[48, 49, 50, 51, 52, 53, 54, 55, 57, 65, 66, 67]]),
+        int16_mono=(2, [[12592, 13106, 13620, 14134, 16697, 17218]]),
+        int32_mono=(4, [[858927408, 926299444, 1128415545]]),
         int8_stereo=(1, [[48, 50, 52, 54, 57, 66], [49, 51, 53, 55, 65, 67]]),
         int16_stereo=(2, [[12592, 13620, 16697], [13106, 14134, 17218]]),
         int32_3channel=(4, [[858927408], [926299444], [1128415545]]),
     )
     def test_to_array(self, sample_width, expected):
-        if isinstance(expected[0], list):
-            channels = len(expected)
-            expected = [
-                array_(signal_.FORMAT[sample_width], xi) for xi in expected
-            ]
-        else:
-            channels = 1
-            expected = array_(signal_.FORMAT[sample_width], expected)
+        channels = len(expected)
+        expected = [
+            array_(signal_.FORMAT[sample_width], xi) for xi in expected
+        ]
         result = signal_.to_array(self.data, sample_width, channels)
         result_numpy = signal_numpy.to_array(self.data, sample_width, channels)
         self.assertEqual(result, expected)