2016-10-12 23:50:00 +02:00
|
|
|
from __future__ import print_function
|
|
|
|
from __future__ import division
|
|
|
|
import numpy as np
|
|
|
|
from scipy.interpolate import interp1d
|
|
|
|
import matplotlib
|
|
|
|
matplotlib.use('TkAgg')
|
|
|
|
import matplotlib.pylab as plt
|
|
|
|
plt.style.use('lawson')
|
|
|
|
import microphone as mic
|
2016-10-14 07:27:45 +02:00
|
|
|
import config
|
2016-10-12 23:50:00 +02:00
|
|
|
|
|
|
|
# FFT statistics for a few previous updates
|
2016-10-14 07:27:45 +02:00
|
|
|
_ys_historical_energy = np.zeros(shape=(config.N_SUBBANDS, config.N_HISTORY))
|
2016-10-12 23:50:00 +02:00
|
|
|
|
|
|
|
|
|
|
|
def beat_detect(ys):
|
2016-10-14 07:27:45 +02:00
|
|
|
global _ys_historical_energy
|
2016-10-12 23:50:00 +02:00
|
|
|
# Beat energy criterion
|
|
|
|
current_energy = ys * ys
|
2016-10-14 07:27:45 +02:00
|
|
|
mean_energy = np.mean(_ys_historical_energy, axis=1)
|
|
|
|
has_beat_energy = current_energy > mean_energy * config.ENERGY_THRESHOLD
|
|
|
|
_ys_historical_energy = np.roll(_ys_historical_energy, shift=1, axis=1)
|
|
|
|
_ys_historical_energy[:, 0] = current_energy
|
2016-10-12 23:50:00 +02:00
|
|
|
# Beat variance criterion
|
2016-10-14 07:27:45 +02:00
|
|
|
ys_variance = np.var(_ys_historical_energy, axis=1)
|
|
|
|
has_beat_variance = ys_variance > config.VARIANCE_THRESHOLD
|
2016-10-12 23:50:00 +02:00
|
|
|
# Combined energy + variance detection
|
|
|
|
has_beat = has_beat_energy * has_beat_variance
|
|
|
|
return has_beat
|
|
|
|
|
|
|
|
|
|
|
|
def fft(data):
|
|
|
|
"""Returns |fft(data)|"""
|
|
|
|
yL, yR = np.split(np.abs(np.fft.fft(data)), 2)
|
|
|
|
ys = np.add(yL, yR[::-1])
|
2016-10-14 07:27:45 +02:00
|
|
|
xs = np.arange(int(config.MIC_RATE / config.FPS) / 2, dtype=float)
|
|
|
|
xs *= float(config.MIC_RATE) / int(config.MIC_RATE / config.FPS)
|
2016-10-12 23:50:00 +02:00
|
|
|
return xs, ys
|
|
|
|
|
|
|
|
|
2016-10-14 07:27:45 +02:00
|
|
|
# def fft(data):
|
|
|
|
# """Returns |fft(data)|"""
|
|
|
|
# yL, yR = np.split(np.abs(np.fft.fft(data)), 2)
|
|
|
|
# ys = np.add(yL, yR[::-1])
|
|
|
|
# xs = np.arange(mic.CHUNK / 2, dtype=float) * float(mic.RATE) / mic.CHUNK
|
|
|
|
# return xs, ys
|
|
|
|
|
|
|
|
|
2016-10-12 23:50:00 +02:00
|
|
|
def fft_log_partition(data, fmin=30, fmax=20000, subbands=64):
|
|
|
|
"""Returns FFT partitioned into subbands that are logarithmically spaced"""
|
|
|
|
xs, ys = fft(data)
|
|
|
|
xs_log = np.logspace(np.log10(fmin), np.log10(fmax), num=subbands * 32)
|
|
|
|
f = interp1d(xs, ys)
|
|
|
|
ys_log = f(xs_log)
|
|
|
|
X, Y = [], []
|
|
|
|
for i in range(0, subbands * 32, 32):
|
|
|
|
X.append(np.mean(xs_log[i:i + 32]))
|
|
|
|
Y.append(np.mean(ys_log[i:i + 32]))
|
|
|
|
return np.array(X), np.array(Y)
|