Skip to content

Commit 3745569

Browse files
committed
audio events detection uses newer scipy functions
1 parent 33735ba commit 3745569

File tree

1 file changed

+19
-13
lines changed

1 file changed

+19
-13
lines changed

ibllib/io/extractors/training_audio.py

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,17 @@
44
import logging
55

66
import numpy as np
7-
from scipy import signal
7+
import scipy.signal
8+
import scipy.ndimage
89
from scipy.io import wavfile
910

11+
1012
from neurodsp.utils import WindowGenerator
1113
from neurodsp import fourier
1214
import ibllib.io.raw_data_loaders as ioraw
1315
from ibllib.io.extractors.training_trials import GoCueTimes
1416

17+
1518
logger_ = logging.getLogger('ibllib')
1619

1720
NS_WIN = 2 ** 18 # 2 ** np.ceil(np.log2(1 * fs))
@@ -22,16 +25,19 @@
2225
READY_TONE_SPL = 85
2326

2427

25-
def _running_mean(x, N):
26-
cumsum = np.cumsum(np.insert(x, 0, 0))
27-
return (cumsum[N:] - cumsum[:-N]) / N
28-
29-
30-
def _detect_ready_tone(w, fs):
28+
def detect_ready_tone(w, fs, ftone=FTONE, threshold=0.8):
29+
"""
30+
Detects a transient sinusoid signal in a time-serie
31+
:param w: audio time seried
32+
:param fs: sampling frequency (Hz)
33+
:param ftone: frequency of the tone to detect
34+
:param threshold: ratio of the Hilbert to the signal, between 0 and 1 (set to 0.8)
35+
:return:
36+
"""
3137
# get envelope of DC free signal and envelope of BP signal around freq of interest
32-
h = np.abs(signal.hilbert(w - np.median(w)))
33-
fh = np.abs(signal.hilbert(fourier.bp(w, si=1 / fs, b=FTONE * np.array([0.9, 0.95, 1.15, 1.1]))))
34-
dtect = _running_mean(fh / (h + 1e-3), int(fs * 0.1)) > 0.8
38+
h = np.abs(scipy.signal.hilbert(w - np.median(w)))
39+
fh = np.abs(scipy.signal.hilbert(fourier.bp(w, si=1 / fs, b=ftone * np.array([0.9, 0.95, 1.15, 1.1]))))
40+
dtect = scipy.ndimage.uniform_filter1d(fh / (h + 1e-3), int(fs * 0.1)) > threshold
3541
return np.where(np.diff(dtect.astype(int)) == 1)[0]
3642
# tone = np.sin(2 * np.pi * FTONE * np.arange(0, fs * 0.1) / fs)
3743
# tone = tone / np.sum(tone ** 2)
@@ -78,16 +84,16 @@ def welchogram(fs, wav, nswin=NS_WIN, overlap=OVERLAP, nperseg=NS_WELCH):
7884
# load the current window into memory
7985
w = np.float64(wav[first:last]) * _get_conversion_factor()
8086
# detection of ready tones
81-
a = [d + first for d in _detect_ready_tone(w, fs)]
87+
a = [d + first for d in detect_ready_tone(w, fs)]
8288
if len(a):
8389
detect += a
8490
# the last window may not allow a pwelch
8591
if (last - first) < nperseg:
8692
continue
8793
# compute PSD estimate for the current window
8894
iw = window_generator.iw
89-
_, W[iw, :] = signal.welch(w, fs=fs, window='hann', nperseg=nperseg, axis=-1,
90-
detrend='constant', return_onesided=True, scaling='density')
95+
_, W[iw, :] = scipy.signal.welch(w, fs=fs, window='hann', nperseg=nperseg, axis=-1,
96+
detrend='constant', return_onesided=True, scaling='density')
9197
# the onset detection may have duplicates with sliding window, average them and remove
9298
detect = np.sort(np.array(detect)) / fs
9399
ind = np.where(np.diff(detect) < 0.1)[0]

0 commit comments

Comments
 (0)