Skip to content

Instantly share code, notes, and snippets.

@rudolfbyker
Created October 4, 2021 18:58
Show Gist options
  • Save rudolfbyker/66bec4cd6100af26edb86da62e4c7146 to your computer and use it in GitHub Desktop.
Save rudolfbyker/66bec4cd6100af26edb86da62e4c7146 to your computer and use it in GitHub Desktop.
Find silences in audio samples
import numpy as np
def find_silences_of_minimum_length(data: np.array, min_length: int) -> Generator[Tuple[int, int], None, None]:
"""
Get a (start, stop) tuple for each detected silence of minimum length.
The start is inclusive, and the stop is exclusive, to match Python's list slicing.
>>> list(find_silences_of_minimum_length([1,0,1], 1))
[(1, 2)]
>>> list(find_silences_of_minimum_length([1,0,1], 2))
[]
>>> list(find_silences_of_minimum_length([1,0,0,1], 1))
[(1, 3)]
>>> list(find_silences_of_minimum_length([1,0,0,1], 2))
[(1, 3)]
>>> list(find_silences_of_minimum_length([1,0,0,1], 3))
[]
>>> list(find_silences_of_minimum_length([0,0,0,0,1,0,1,0,0,1,0,0,0,1,0,0,0,0,1], 1))
[(0, 4), (5, 6), (7, 9), (10, 13), (14, 18)]
>>> list(find_silences_of_minimum_length([0,0,0,0,1,0,1,0,0,1,0,0,0,1,0,0,0,0,1], 2))
[(0, 4), (7, 9), (10, 13), (14, 18)]
>>> list(find_silences_of_minimum_length([0,0,0,0,1,0,1,0,0,1,0,0,0,1,0,0,0,0,1], 3))
[(0, 4), (10, 13), (14, 18)]
"""
if min_length < 1:
raise ValueError("Minimum length must be >= 1")
for start, stop in find_all_silences(data):
if stop - start >= min_length:
yield start, stop
def find_all_silences(data: np.array) -> Generator[Tuple[int, int], None, None]:
"""
Get a (start, stop) tuple for each detected silence.
The start is inclusive, and the stop is exclusive, to match Python's list slicing.
>>> list(find_all_silences([1,0,1]))
[(1, 2)]
>>> list(find_all_silences([1,0,0,1]))
[(1, 3)]
>>> list(find_all_silences([0,0,0,0,1,0,1,0,0,1,0,0,0,1,0,0,0,0,1]))
[(0, 4), (5, 6), (7, 9), (10, 13), (14, 18)]
"""
t_first_zero = None
for t, sample in tqdm(enumerate(data)):
is_zero = np.all(sample == 0)
if is_zero:
# Sample is silent
if t_first_zero is None:
# The silence starts at this samples.
t_first_zero = t
else:
# This sample just continues the silence.
pass
else:
# Sample is not silent.
if t_first_zero is not None:
# This sample broke the silence.
yield t_first_zero, t
t_first_zero = None
else:
# It was already not silent.
pass
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment