Browse Source

calcola qualita complessiva ascolto

boyska 2 years ago
parent
commit
d0ef0f3285
1 changed files with 62 additions and 6 deletions
  1. 62 6
      barker/barker.py

+ 62 - 6
barker/barker.py

@@ -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__":