1
+ #!/usr/bin/env python
2
+
3
+ # scrollphat_spectrum.py at https://gist.github.com/fvdbosch/45cd94bf056d218bc464c6966aa81782
4
+ # loopback_spectrum.conf at https://gist.github.com/fvdbosch/b08d5158f32a2a68ed5e71c9dde50b21#file-loopback_spectrum-conf
5
+ # Original script by Pimoroni: https://learn.pimoroni.com/tutorial/sandyj/scroll-phat-spectrum-analyser
6
+ # Modified to take audio stream from loopback device as input, instead of file
7
+
8
+ import sys
9
+ import wave
10
+ import alsaaudio as aa
11
+ from struct import unpack
12
+ import numpy as np
13
+ import scrollphat
14
+ import pyaudio
15
+
16
+ chunk = 4096 # Change if too fast/slow, never less than 2**11
17
+ sample_rate = 32000
18
+
19
+ # CHANGE THIS TO CORRECT INPUT DEVICE
20
+ # Enable stereo mixing in your sound card
21
+ # to make you sound output an input
22
+ # Use list_devices() to list all your input devices
23
+ device = 0
24
+
25
+ p = pyaudio .PyAudio ()
26
+ stream = p .open (format = pyaudio .paInt16 ,
27
+ channels = 1 ,
28
+ rate = sample_rate ,
29
+ input = True ,
30
+ frames_per_buffer = chunk ,
31
+ input_device_index = device )
32
+
33
+ matrix = [0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ]
34
+ power = []
35
+ weighting = [1 , 1 , 2 , 4 , 8 , 8 , 8 , 8 , 16 , 16 , 16 ]
36
+
37
+ scrollphat .set_brightness (10 )
38
+ #scrollphat.set_rotate(180)
39
+
40
+ # https://gist.github.com/limitedmage/2628477#file-soundlight-py
41
+ def list_devices ():
42
+ # List all audio input devices
43
+ p = pyaudio .PyAudio ()
44
+ i = 0
45
+ n = p .get_device_count ()
46
+ while i < n :
47
+ dev = p .get_device_info_by_index (i )
48
+ if dev ['maxInputChannels' ] > 0 :
49
+ print str (i )+ '. ' + dev ['name' ]
50
+ i += 1
51
+
52
+ def power_index (val ):
53
+ return int (2 * chunk * val / sample_rate )
54
+
55
+ def compute_fft (data , chunk , sample_rate ):
56
+ global matrix
57
+ data = unpack ("%dh" % (len (data ) / 2 ), data )
58
+ data = np .array (data , dtype = 'h' )
59
+
60
+ fourier = np .fft .rfft (data )
61
+ fourier = np .delete (fourier , len (fourier ) - 1 )
62
+
63
+ power = np .abs (fourier )
64
+ matrix [0 ] = int (np .mean (power [power_index (0 ) :power_index (156 ) :1 ]))
65
+ matrix [1 ] = int (np .mean (power [power_index (156 ) :power_index (313 ) :1 ]))
66
+ matrix [2 ] = int (np .mean (power [power_index (313 ) :power_index (625 ) :1 ]))
67
+ matrix [3 ] = int (np .mean (power [power_index (625 ) :power_index (1000 ) :1 ]))
68
+ matrix [4 ] = int (np .mean (power [power_index (1000 ) :power_index (2000 ) :1 ]))
69
+ matrix [5 ] = int (np .mean (power [power_index (2000 ) :power_index (3000 ) :1 ]))
70
+ matrix [6 ] = int (np .mean (power [power_index (3000 ) :power_index (4000 ) :1 ]))
71
+ matrix [7 ] = int (np .mean (power [power_index (4000 ) :power_index (5000 ) :1 ]))
72
+ matrix [8 ] = int (np .mean (power [power_index (5000 ) :power_index (6000 ) :1 ]))
73
+ matrix [9 ] = int (np .mean (power [power_index (6000 ) :power_index (7000 ) :1 ]))
74
+ matrix [10 ] = int (np .mean (power [power_index (7000 ):power_index (8000 ) :1 ]))
75
+
76
+ matrix = np .divide (np .multiply (matrix , weighting ), 1000000 )
77
+ matrix = matrix .clip (0 , 5 )
78
+ matrix = [float (m ) for m in matrix ]
79
+
80
+ return matrix
81
+
82
+ list_devices ()
83
+
84
+ while True :
85
+ data = stream .read (chunk )
86
+ matrix = compute_fft (data , chunk , sample_rate )
87
+ scrollphat .graph (matrix , 0 , 5 )
0 commit comments