this notebook demostrates some of the intersample detection technuques: throw resampling and throw parabolic interpolation. The accuracy of both methods can be tested on real time by shifting a sinc function from the sampling point and evaluating the error introduced by both systems
In [1]:
import ipywidgets as wg
import essentia.standard as es
import numpy as np
import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
In [2]:
# Parameters
duration = 10 # s
fs = 1 # hz
k = 1. # amplitude
oversamplingFactor = 4 # factor of oversampling for the real signal
nSamples = fs * duration
time = np.arange(-nSamples/2, nSamples/2,
2 ** -oversamplingFactor, dtype='float')
samplingPoints = time[::2 ** oversamplingFactor]
In [3]:
def shifted_sinc(x, k, offset):
xShifted = x - offset
y = np.zeros(len(xShifted))
for idx, i in enumerate(xShifted):
if not i:
y[idx] = k
else:
y[idx] = (k * np.sin(np.pi * i) / (np.pi * i))
return y
In [4]:
def resampleStrategy(y, fs, quality=0, oversampling=4):
yResample = es.Resample(inputSampleRate=fs,
outputSampleRate=fs*oversampling,
quality=quality)(y.astype(np.float32))
tResample = np.arange(np.min(samplingPoints), np.max(samplingPoints)
+ 1, 1. / (fs * oversampling))
tResample = tResample[:len(yResample)]
# getting the stimated peaks
yResMax = np.max(yResample)
tResMax = tResample[np.argmax(yResample)]
return yResample, tResample, yResMax, tResMax
In [5]:
def parabolicInterpolation(y, threshold=.6):
# todo plot the parabol maybe
positions, amplitudes = es.PeakDetection(threshold=threshold)\
(y.astype(np.float32))
pos = int(positions[0] * (len(y-1)))
a = y[pos - 1]
b = y[pos]
c = y[pos + 1]
tIntMax = samplingPoints[pos] + (a - c) / (2 * (a - 2 * b + c))
yIntMax = b - ((a - b) ** 2) / (8 * (a - 2 * b + c))
return tIntMax, yIntMax
In [6]:
def process():
## Processing
# "real" sinc
yReal = shifted_sinc(time, k, offset.value)
# sampled sinc
y = shifted_sinc(samplingPoints, k, offset.value)
# Resample strategy
yResample, tResample, yResMax, tResMax = \
resampleStrategy(y, fs, quality=0, oversampling=4)
# Parabolic Interpolation extrategy
tIntMax, yIntMax = parabolicInterpolation(y)
## Plotting
ax.clear()
plt.title('Interpeak detection estrategies')
ax.grid(True)
ax.grid(xdata=samplingPoints)
ax.plot(time, yReal, label='real signal')
yRealMax = np.max(yReal)
sampledLabel = 'sampled signal. Error:{:.3f}'\
.format(np.abs(np.max(y) - yRealMax))
ax.plot(samplingPoints, y, label=sampledLabel, ls='-.',
color='r', marker='x', markersize=6, alpha=.7)
ax.plot(tResample, yResample, ls='-.',
color='y', marker='x', alpha=.7)
resMaxLabel = 'Resample Peak. Error:{:.3f}'\
.format(np.abs(yResMax - yRealMax))
ax.plot(tResMax, yResMax, label= resMaxLabel,
color='y', marker = 'x', markersize=12)
intMaxLabel = 'Interpolation Peak. Error:{:.3f}'\
.format(np.abs(yIntMax - yRealMax))
ax.plot(tIntMax, yIntMax, label= intMaxLabel,
marker = 'x', markersize=12)
fig.legend()
fig.show()
In [7]:
offset = wg.FloatSlider()
offset.max = 1
offset.min = -1
offset.step = .1
display(offset)
fig, ax = plt.subplots()
process()
def on_value_change(change):
process()
offset.observe(on_value_change, names='value')
In [ ]: