-
Notifications
You must be signed in to change notification settings - Fork 1
/
LSTD.py
57 lines (51 loc) · 2.1 KB
/
LSTD.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# -*- coding: utf-8 -*-
import numpy as np
import scipy
class LSTD_vad(object):
def __init__(self, win_len=0.025, win_step=0.01, Fs=16000, N=5, NFFT=512):
self._win_len = win_len
self._win_step = win_step
self._Fs = Fs
self._N = 5
self._NFFT = NFFT
# sample per window = window lngth * sampling freq.
self._spw = int(win_len * Fs)
# sample per window step = window step * sampling freq.
self._sps = int(win_step * Fs)
self._window = np.hamming(self._spw)
# memory of prev specs
self._last_specs = []
self._lste = None
def noise_spec(self, noise_signal):
'''
calculate noise spectrum
input:
noise_signal -> noisy signal, at least N (LSTE order) frame
'''
if(noise_signal.shape[0] < self._spw + self._sps * self._N):
raise Exception('low information about noise')
signal_len = noise_signal.shape[0]
noise_spec = scipy.fft(noise_signal[:self._spw], self._NFFT)
for i in range(1, int((signal_len - self._spw) / self._sps)):
start = self._sps * i
end = start + self._spw
self._last_specs.append(np.abs(scipy.fft(noise_signal[start:end], self._NFFT)) ** 2)
noise_spec += self._last_specs[-1]
noise_spec /= int((signal_len - self._spw) / self._sps)
self._last_specs = self._last_specs[-self._N:]
self._noise_spec = np.array(np.abs(noise_spec), float)
def update_LSTE(self, frame):
'''
calculate lste for current frame
input:
frame -> np array of length win_len * Fs
'''
if(frame.shape[0] != self._spw):
print('exception')
raise Exception('samples not expected')
self._last_specs.append(np.abs(scipy.fft(frame, self._NFFT)) ** 2)
self._last_specs = self._last_specs[-self._N:]
self._lste = np.array(np.array(self._last_specs).max(axis=0), float)
def compute_LSTD(self):
result = 10.0 * np.log10(np.sum(self._lste / self._noise_spec) / self._NFFT)
return result