Browse Source

more fft testing. still not happy with the results.

Thomas B 3 months ago
parent
commit
5fc618f54f
1 changed files with 32 additions and 8 deletions
  1. 32
    8
      audio.py

+ 32
- 8
audio.py View File

@@ -12,13 +12,13 @@ import pyaudio
12 12
 import numpy as np
13 13
 
14 14
 class AudioVisualizer:
15
-    def __init__(self, g, f = 20, t = 60.0):
15
+    def __init__(self, g, f = 20, t = 60.0, fft = True):
16 16
         self.gui = g
17 17
         self.interval = 1.0 / f
18 18
         self.timeout = t
19
+        self.do_fft = fft
19 20
 
20 21
         self.chunk = 1024 * 2 # stereo
21
-        self.do_fft = False
22 22
 
23 23
         self.p = pyaudio.PyAudio()
24 24
         self.s = self.p.open(format=pyaudio.paInt16, channels=2, rate=44100, input=True)
@@ -37,11 +37,30 @@ class AudioVisualizer:
37 37
         h = int(val) / 32768.0 * self.gui.height / 2
38 38
         self.gui.set_pixel(x, y_off + (16 - h), (255, 255, 255))
39 39
 
40
-    def draw_bar(self, x, val, y_off):
41
-        h = int(val) / (32768.0 * 2) * (self.gui.height / 2)
40
+    def draw_bar(self, x, val, y_off, max_val):
41
+        if max_val <= 0.0:
42
+            max_val = 1.0
43
+        h = int(val) / float(max_val) * self.gui.height / 2
42 44
         for y in range(0, int(h)):
43 45
             self.gui.set_pixel(x, y_off + (32 - y), (255, 255, 255))
44 46
 
47
+    # stolen from https://github.com/aiXander/Realtime_PyAudio_FFT/blob/master/src/fft.py
48
+    def calc_fft(self, data):
49
+        data = data * np.hamming(len(data))
50
+        try:
51
+            fft = np.abs(np.fft.rfft(data)[1:])
52
+        except:
53
+            fft = np.fft.fft(data)
54
+            left, right = np.split(np.abs(fft), 2)
55
+            fft = np.add(left, right[::-1])
56
+
57
+        #try:
58
+        #    fft = np.multiply(20, np.log10(fft))
59
+        #except:
60
+        #    pass
61
+
62
+        return fft
63
+
45 64
     def draw(self):
46 65
         frames = self.s.read(self.chunk)
47 66
 
@@ -53,18 +72,23 @@ class AudioVisualizer:
53 72
 
54 73
         if self.do_fft:
55 74
             # FFT
56
-            left = np.fft.fft(left)
57
-            right = np.fft.fft(right)
75
+            left = self.calc_fft(left)
76
+            right = self.calc_fft(right)
58 77
 
59 78
         # average down to fit screen
60 79
         m = self.chunk / 2 / self.gui.width # stereo
80
+        if self.do_fft:
81
+            m = m / 2
61 82
         left = left.reshape(-1, int(m)).mean(axis=1)
62 83
         right = right.reshape(-1, int(m)).mean(axis=1)
63 84
 
85
+        l_max = max(left)
86
+        r_max = max(right)
87
+
64 88
         for x in range(0, self.gui.width):
65 89
             if self.do_fft:
66
-                self.draw_bar(x, left[x], 0)
67
-                self.draw_bar(x, right[x], self.gui.height / 2)
90
+                self.draw_bar(x, left[x], 0, l_max)
91
+                self.draw_bar(x, right[x], self.gui.height / 2, r_max)
68 92
             else:
69 93
                 self.draw_line(x, left[x], 0)
70 94
                 self.draw_line(x, right[x], self.gui.height / 2)

Loading…
Cancel
Save