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