|
@@ -6,7 +6,9 @@ This script finds the barker code position in a WAV file
|
|
|
from itertools import count
|
|
|
import argparse
|
|
|
from logging import getLogger, basicConfig
|
|
|
+from math import log10
|
|
|
|
|
|
+import matplotlib.pyplot as plt
|
|
|
import numpy as np
|
|
|
import scipy.io.wavfile
|
|
|
|
|
@@ -40,6 +42,8 @@ def get_parser():
|
|
|
)
|
|
|
return p
|
|
|
|
|
|
+def to_int(val):
|
|
|
+ return int(np.absolute(val))
|
|
|
|
|
|
def all_contigous_series(seq) -> list:
|
|
|
"""
|
|
@@ -93,6 +97,7 @@ class Barker:
|
|
|
self.framerate = framerate
|
|
|
self.wave = wave
|
|
|
self.log = getLogger(self.__class__.__name__)
|
|
|
+ self.fitness_min = len(self.barker) * 2 / 3
|
|
|
|
|
|
self.symbol_ms = symbol_ms
|
|
|
self.chunks_per_symbol = chunks_per_symbol
|
|
@@ -105,8 +110,6 @@ class Barker:
|
|
|
"""
|
|
|
r = np.fft.fft(data, self.framerate)
|
|
|
|
|
|
- def to_int(val):
|
|
|
- return int(np.absolute(val))
|
|
|
|
|
|
values = [to_int(r[freq]) for freq in self.freqs]
|
|
|
if max(values) < self.threshold:
|
|
@@ -156,8 +159,8 @@ class Barker:
|
|
|
elif val == bestvalue:
|
|
|
bestshifts.append(shift)
|
|
|
|
|
|
- if bestvalue < int(len(self.barker) * 2 / 3):
|
|
|
- raise ValueError("Could not find the barker code")
|
|
|
+ if bestvalue < self.fitness_min:
|
|
|
+ raise ValueError("Barker code not found")
|
|
|
|
|
|
bestshifts = largest_contigous_series(bestshifts)
|
|
|
self.log.debug(
|
|
@@ -171,6 +174,39 @@ class Barker:
|
|
|
)
|
|
|
return (bestshift, shift_ms, bestvalue)
|
|
|
|
|
|
+ def get_frames(self, start_ms: int, duration_ms: int) -> list:
|
|
|
+ start_frame = (start_ms * self.framerate) // 1000
|
|
|
+ n_frames = (duration_ms * self.framerate) // 1000
|
|
|
+ data = self.wave[start_frame:start_frame + n_frames]
|
|
|
+ return data
|
|
|
+
|
|
|
+ def cerca_tono(self, data: list, freq: int) -> float:
|
|
|
+ '''ritorna una metrica di qualità'''
|
|
|
+ r = np.fft.fft(data, self.framerate)
|
|
|
+
|
|
|
+ # for i, val in enumerate(r):
|
|
|
+ # v = to_int(val)
|
|
|
+ # if v != 0:
|
|
|
+ # print(i, v)
|
|
|
+ margin = 20
|
|
|
+ good = 0.0
|
|
|
+ bad = 0.0
|
|
|
+
|
|
|
+ for f, val in enumerate(r):
|
|
|
+ if f < 50:
|
|
|
+ continue
|
|
|
+ v = to_int(val)
|
|
|
+ if f > (freq - margin) and f < (freq + margin):
|
|
|
+ good += v
|
|
|
+ bad += v
|
|
|
+ if f == 5000:
|
|
|
+ break
|
|
|
+ # plt.plot(range(len(r)), r)
|
|
|
+ # plt.grid()
|
|
|
+ # plt.show()
|
|
|
+
|
|
|
+ return good / bad
|
|
|
+
|
|
|
|
|
|
def main():
|
|
|
args = get_parser().parse_args()
|
|
@@ -184,8 +220,28 @@ def main():
|
|
|
barker = Barker(
|
|
|
barker_sequence, [args.barker_freq_1, args.barker_freq_2], framerate, data
|
|
|
)
|
|
|
- chunk, shift, fitness = barker.analyze() # in milliseconds
|
|
|
- print(shift)
|
|
|
+ chunk, barker_start, fitness = barker.analyze() # in milliseconds
|
|
|
+ print("shift = %dms" % barker_start)
|
|
|
+ barker_end = barker_start + len(barker_sequence) * barker.symbol_ms
|
|
|
+ toneduration = 500
|
|
|
+ tonestart = barker_end + toneduration
|
|
|
+
|
|
|
+ freq_qual = []
|
|
|
+ for tonefreq in [261, 1244, 2793]:
|
|
|
+ campiona_da = tonestart + toneduration / 5.
|
|
|
+ campiona_durata = toneduration * 3./5
|
|
|
+ campiona_a = campiona_da + campiona_durata
|
|
|
+ data = barker.get_frames(int(campiona_da), int(campiona_durata))
|
|
|
+ qualita = barker.cerca_tono(data, tonefreq)
|
|
|
+ print(tonefreq, campiona_da, campiona_a, qualita, log10(qualita))
|
|
|
+ freq_qual.append(qualita)
|
|
|
+
|
|
|
+ tonestart += toneduration
|
|
|
+
|
|
|
+ tot_qual = sum(freq_qual)
|
|
|
+ norm_qual = tot_qual / 1.614218155663699 # ad-hoc!
|
|
|
+ print('=>', norm_qual)
|
|
|
+
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|