changeset 416:14efef6f4bae

implement 'split_and_join_with_silence'
author Amine Sehili <amine.sehili@gmail.com>
date Wed, 16 Oct 2024 20:42:58 +0200
parents e26dcf224846
children 5f32574c9788
files auditok/core.py tests/test_core.py
diffstat 2 files changed, 103 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/auditok/core.py	Wed Oct 16 20:08:37 2024 +0200
+++ b/auditok/core.py	Wed Oct 16 20:42:58 2024 +0200
@@ -24,7 +24,14 @@
 except ImportError:
     from . import signal
 
-__all__ = ["load", "split", "make_silence", "AudioRegion", "StreamTokenizer"]
+__all__ = [
+    "load",
+    "split",
+    "make_silence",
+    "split_and_join_with_silence",
+    "AudioRegion",
+    "StreamTokenizer",
+]
 
 
 DEFAULT_ANALYSIS_WINDOW = 0.05
@@ -333,6 +340,36 @@
     return region
 
 
+def split_and_join_with_silence(input, silence_duration, **kwargs):
+    """Split input audio and join (i.e. glue) the resulting regions with a
+    silence of duration `silence_duration`. This can be used to create audio
+    data with shortened or lengthened silence between audio events.
+
+
+    Parameters
+    ----------
+    silence_duration : float
+        silence duration in seconds.
+
+    Returns
+    -------
+    AudioRegion, None
+        An AudioRegion with the desired between-events silence duration.
+        None if no audio event could be detected in input data.
+
+    See also
+    --------
+    :func:`load`
+    """
+    regions = list(split(input, **kwargs))
+    if regions:
+        first = regions[0]
+        # create a silence with the same parameters as input audio
+        silence = make_silence(silence_duration, first.sr, first.sw, first.ch)
+        return silence.join(regions)
+    return None
+
+
 def _duration_to_nb_windows(
     duration, analysis_window, round_fn=round, epsilon=0
 ):
--- a/tests/test_core.py	Wed Oct 16 20:08:37 2024 +0200
+++ b/tests/test_core.py	Wed Oct 16 20:42:58 2024 +0200
@@ -8,7 +8,14 @@
 import numpy as np
 import pytest
 
-from auditok import AudioParameterError, AudioRegion, load, make_silence, split
+from auditok import (
+    AudioParameterError,
+    AudioRegion,
+    load,
+    make_silence,
+    split,
+    split_and_join_with_silence,
+)
 from auditok.core import (
     _duration_to_nb_windows,
     _make_audio_region,
@@ -105,6 +112,63 @@
 
 
 @pytest.mark.parametrize(
+    "duration",
+    [
+        (0,),  # zero_second
+        (1,),  # one_second
+        (1.0001,),  # 1.0001_second
+    ],
+    ids=[
+        "zero_second",
+        "one_second",
+        "1.0001_second",
+    ],
+)
+def test_split_and_join_with_silence(duration):
+    duration = 1.0
+    sampling_rate = 10
+    sample_width = 2
+    channels = 1
+
+    regions = split(
+        input="tests/data/test_split_10HZ_mono.raw",
+        min_dur=0.2,
+        max_dur=5,
+        max_silence=0.2,
+        drop_trailing_silence=False,
+        strict_min_dur=False,
+        analysis_window=0.1,
+        sr=sampling_rate,
+        sw=sample_width,
+        ch=channels,
+        eth=50,
+    )
+
+    size = round(duration * sampling_rate) * sample_width * channels
+    join_data = b"\0" * size
+    expected_data = join_data.join(region.data for region in regions)
+    expected_region = AudioRegion(
+        expected_data, sampling_rate, sample_width, channels
+    )
+
+    region_with_silence = split_and_join_with_silence(
+        input="tests/data/test_split_10HZ_mono.raw",
+        silence_duration=duration,
+        min_dur=0.2,
+        max_dur=5,
+        max_silence=0.2,
+        drop_trailing_silence=False,
+        strict_min_dur=False,
+        analysis_window=0.1,
+        sr=sampling_rate,
+        sw=sample_width,
+        ch=channels,
+        eth=50,
+    )
+    assert region_with_silence == expected_region
+
+
+@pytest.mark.parametrize(
     "duration, analysis_window, round_fn, expected, kwargs",
     [
         (0, 1, None, 0, None),  # zero_duration