Live detector working
This commit is contained in:
parent
7465ef13ea
commit
dde00782d4
@ -2,13 +2,18 @@
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
from scipy.signal import butter, lfilter, decimate
|
from scipy.signal import butter, lfilter, decimate
|
||||||
|
|
||||||
def anti_alias(data, sample_rate, max_frequency):
|
def anti_alias(data, sample_rate, max_frequency, order=5):
|
||||||
FILTER_HEADROOM = 1.2
|
FILTER_HEADROOM = 1.2
|
||||||
nyquist_rate = 2 * max_frequency
|
nyquist_rate = 2 * max_frequency
|
||||||
downsample_factor = 1
|
downsample_factor = 1
|
||||||
|
|
||||||
if sample_rate > nyquist_rate:
|
if sample_rate > nyquist_rate:
|
||||||
filtered_data = lowpass_filter(data, max_frequency * FILTER_HEADROOM, sample_rate)
|
filtered_data = lowpass_filter(
|
||||||
|
data,
|
||||||
|
max_frequency * FILTER_HEADROOM,
|
||||||
|
sample_rate,
|
||||||
|
order
|
||||||
|
)
|
||||||
|
|
||||||
downsample_factor = int(sample_rate / nyquist_rate)
|
downsample_factor = int(sample_rate / nyquist_rate)
|
||||||
filtered_data = decimate(filtered_data, downsample_factor)
|
filtered_data = decimate(filtered_data, downsample_factor)
|
||||||
@ -18,9 +23,9 @@ def anti_alias(data, sample_rate, max_frequency):
|
|||||||
|
|
||||||
return filtered_data, sample_rate, downsample_factor
|
return filtered_data, sample_rate, downsample_factor
|
||||||
|
|
||||||
def smoothing_filter(data, window_size=256):
|
def smoothing_filter(data, window_size=256, mode='same'):
|
||||||
window = np.ones(window_size) / window_size
|
window = np.ones(window_size) / window_size
|
||||||
return np.convolve(data, window, mode='same')
|
return np.convolve(data, window, mode=mode)
|
||||||
|
|
||||||
# Stolen from selcald
|
# Stolen from selcald
|
||||||
def note(freq, length, amp=1.0, rate=44100):
|
def note(freq, length, amp=1.0, rate=44100):
|
||||||
|
|||||||
@ -5,12 +5,13 @@ import threading
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
import signal as sig
|
import signal as sig
|
||||||
from tones import TONES
|
from tones import TONES
|
||||||
from filters import anti_alias, bandpass_filter, note
|
from filters import anti_alias, bandpass_filter, note, smoothing_filter
|
||||||
from scipy import signal
|
from scipy import signal
|
||||||
from scipy.signal import butter, lfilter, decimate
|
from scipy.signal import butter, lfilter, decimate
|
||||||
|
|
||||||
import pyqtgraph as pg
|
import pyqtgraph as pg
|
||||||
from pyqtgraph.Qt import QtGui, QtWidgets, mkQApp
|
from pyqtgraph.Qt import QtGui, QtWidgets, mkQApp
|
||||||
|
import time
|
||||||
|
|
||||||
keep_running = True
|
keep_running = True
|
||||||
def signal_handler(sig, frame):
|
def signal_handler(sig, frame):
|
||||||
@ -40,11 +41,13 @@ class DetectorGui(QtWidgets.QMainWindow):
|
|||||||
|
|
||||||
self.tone_data = {}
|
self.tone_data = {}
|
||||||
self.tone_lines = {}
|
self.tone_lines = {}
|
||||||
|
self.tone_pens = {}
|
||||||
|
|
||||||
for tone,color in zip(TONES.keys(), colors):
|
for tone,color in zip(TONES.keys(), colors):
|
||||||
self.tone_data[tone] = np.zeros(int(10000), dtype=np.float64) #np.array([], dtype=np.float64)
|
self.tone_data[tone] = np.zeros(1000, dtype=np.float64) #np.array([], dtype=np.float64) #np.zeros(int(10000), dtype=np.float64)
|
||||||
self.tone_lines[tone] = self.plot.plot(self.tone_data[tone], pen=pg.mkPen(color=color), name=tone)
|
self.tone_lines[tone] = self.plot.plot(self.tone_data[tone], pen=pg.mkPen(color=color), name=tone)
|
||||||
legend.addItem(self.tone_lines[tone], tone)
|
legend.addItem(self.tone_lines[tone], tone)
|
||||||
|
self.tone_pens[tone] = pg.mkPen(color=color)
|
||||||
|
|
||||||
self.plot.setLabel('left', 'Signal Correlation')
|
self.plot.setLabel('left', 'Signal Correlation')
|
||||||
self.plot.setLabel('bottom', 'Time (samples)')
|
self.plot.setLabel('bottom', 'Time (samples)')
|
||||||
@ -64,11 +67,19 @@ class DetectorGui(QtWidgets.QMainWindow):
|
|||||||
self.tone_lines[tone].setData(self.tone_data[tone])
|
self.tone_lines[tone].setData(self.tone_data[tone])
|
||||||
|
|
||||||
def push_tones(self, tone, values):
|
def push_tones(self, tone, values):
|
||||||
|
s = time.perf_counter()
|
||||||
#self.tone_data[tone] = np.append(self.tone_data[tone], values)
|
#self.tone_data[tone] = np.append(self.tone_data[tone], values)
|
||||||
|
a = time.perf_counter()
|
||||||
|
|
||||||
self.tone_data[tone] = np.roll(self.tone_data[tone], -len(values))
|
self.tone_data[tone] = np.roll(self.tone_data[tone], -len(values))
|
||||||
self.tone_data[tone][-len(values):] = values
|
self.tone_data[tone][-len(values):] = values
|
||||||
self.tone_lines[tone].setData(self.tone_data[tone])
|
self.tone_lines[tone].setData(self.tone_data[tone])
|
||||||
|
#self.tone_lines[tone].setData(values)
|
||||||
|
g = time.perf_counter()
|
||||||
|
|
||||||
|
#print(a-s, g-a)
|
||||||
|
|
||||||
|
#self.plot.plot(values, pen=self.tone_pens[tone])
|
||||||
|
|
||||||
|
|
||||||
mkQApp("Correlation matrix display")
|
mkQApp("Correlation matrix display")
|
||||||
@ -91,27 +102,37 @@ def read_audio_from_stdin(chunk_size, process_chunk):
|
|||||||
process_chunk(audio_chunk)
|
process_chunk(audio_chunk)
|
||||||
|
|
||||||
sample_rate = 44100
|
sample_rate = 44100
|
||||||
note_length = 0.1
|
note_length = 0.5
|
||||||
N = 256
|
|
||||||
cumsum_convolution = np.ones(N)/N
|
|
||||||
|
|
||||||
|
guard_duration = 0.01
|
||||||
|
|
||||||
def process_audio_chunk(audio_chunk):
|
def process_audio_chunk(audio_chunk):
|
||||||
global gui
|
global gui
|
||||||
|
|
||||||
data = audio_chunk
|
data = audio_chunk
|
||||||
|
|
||||||
sample_rate = 44100
|
sample_rate = 44100
|
||||||
|
|
||||||
data, sample_rate, decimation = anti_alias(data, sample_rate, 4800)
|
s = time.perf_counter()
|
||||||
|
data, sample_rate, decimation = anti_alias(data, sample_rate, 4800, 8)
|
||||||
|
data = data / (np.max(data) + 0.0001)
|
||||||
pure_signals = {tone:note(freq, note_length, rate=sample_rate) for tone,freq in TONES.items()}
|
pure_signals = {tone:note(freq, note_length, rate=sample_rate) for tone,freq in TONES.items()}
|
||||||
correlations = {tone:np.abs(signal.correlate(data, pure, mode='same')) for tone,pure in pure_signals.items()}
|
aa = time.perf_counter()
|
||||||
massaged = {tone:decimate(np.convolve(correlation, cumsum_convolution, mode='valid'), 4) for tone,correlation in correlations.items()}
|
|
||||||
|
|
||||||
print('processing done')
|
correlations = {tone:smoothing_filter(np.abs(signal.correlate(data, pure, mode='same')), 64) for tone,pure in pure_signals.items()}
|
||||||
|
corr = time.perf_counter()
|
||||||
|
|
||||||
for tone,massage in massaged.items():
|
guard_samples = int(guard_duration * sample_rate)
|
||||||
gui.push_tones(tone, massage )
|
for tone,massage in correlations.items():
|
||||||
|
#gui.push_tones(tone, massage)
|
||||||
|
gui.push_tone(tone, np.mean(massage))
|
||||||
|
gui.push_tones(tone, massage[guard_samples:-guard_samples:100])
|
||||||
|
|
||||||
|
draw = time.perf_counter()
|
||||||
|
|
||||||
|
#print(aa-s, corr-aa, draw-corr)
|
||||||
|
if draw - s > 0.1:
|
||||||
|
print("FAILED")
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
sig.signal(sig.SIGINT, signal_handler)
|
sig.signal(sig.SIGINT, signal_handler)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user