i have audio data loaded in numpy array , wish segment data finding silent parts, i.e. parts audio amplitude below threshold on a period in time.
an extremely simple way this:
values = ''.join(("1" if (abs(x) < silence_threshold) else "0" x in samples)) pattern = re.compile('1{%d,}'%int(min_silence)) match in pattern.finditer(values): # code goes here
the code above finds parts there @ least min_silence consecutive elements smaller silence_threshold.
now, obviously, above code horribly inefficient , terrible abuse of regular expressions. there other method more efficient, still results in equally simple , short code?
here's numpy-based solution.
i think (?) should faster other options. it's clear.
however, require twice memory various generator-based solutions. long can hold single temporary copy of data in memory (for diff), , boolean array of same length data (1-bit-per-element), should pretty efficient...
import numpy np def main(): # generate random data x = np.cumsum(np.random.random(1000) - 0.5) condition = np.abs(x) < 1 # print start , stop indicies of each region absolute # values of x below 1, , min , max of each of these regions start, stop in contiguous_regions(condition): segment = x[start:stop] print start, stop print segment.min(), segment.max() def contiguous_regions(condition): """finds contiguous true regions of boolean array "condition". returns 2d array first column start index of region , second column end index.""" # find indicies of changes in "condition" d = np.diff(condition) idx, = d.nonzero() # need start things after change in "condition". therefore, # we'll shift index 1 right. idx += 1 if condition[0]: # if start of condition true prepend 0 idx = np.r_[0, idx] if condition[-1]: # if end of condition true, append length of array idx = np.r_[idx, condition.size] # edit # reshape result 2 columns idx.shape = (-1,2) return idx main()
Comments
Post a Comment