-
Notifications
You must be signed in to change notification settings - Fork 413
/
realtime_spectrogram.py
77 lines (59 loc) · 1.99 KB
/
realtime_spectrogram.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
"""
musicinformationretrieval.com/realtime_spectrogram.py
PyAudio example: display a live log-spectrogram in the terminal.
For more examples using PyAudio:
https://github.com/mwickert/scikit-dsp-comm/blob/master/sk_dsp_comm/pyaudio_helper.py
"""
import librosa
import numpy
import pyaudio
import time
# Define global variables.
CHANNELS = 1
RATE = 44100
FRAMES_PER_BUFFER = 1000
N_FFT = 4096
SCREEN_WIDTH = 178
ENERGY_THRESHOLD = 0.4
# Choose the frequency range of your log-spectrogram.
F_LO = librosa.note_to_hz('C2')
F_HI = librosa.note_to_hz('C9')
M = librosa.filters.mel(RATE, N_FFT, SCREEN_WIDTH, fmin=F_LO, fmax=F_HI)
p = pyaudio.PyAudio()
def generate_string_from_audio(audio_data):
"""
This function takes one audio buffer as a numpy array and returns a
string to be printed to the terminal.
"""
# Compute real FFT.
x_fft = numpy.fft.rfft(audio_data, n=N_FFT)
# Compute mel spectrum.
melspectrum = M.dot(abs(x_fft))
# Initialize output characters to display.
char_list = [' ']*SCREEN_WIDTH
for i in range(SCREEN_WIDTH):
# If there is energy in this frequency bin, display an asterisk.
if melspectrum[i] > ENERGY_THRESHOLD:
char_list[i] = '*'
# Draw frequency axis guidelines.
elif i % 30 == 29:
char_list[i] = '|'
# Return string.
return ''.join(char_list)
def callback(in_data, frame_count, time_info, status):
audio_data = numpy.fromstring(in_data, dtype=numpy.float32)
print( generate_string_from_audio(audio_data) )
return (in_data, pyaudio.paContinue)
stream = p.open(format=pyaudio.paFloat32,
channels=CHANNELS,
rate=RATE,
input=True, # Do record input.
output=False, # Do not play back output.
frames_per_buffer=FRAMES_PER_BUFFER,
stream_callback=callback)
stream.start_stream()
while stream.is_active():
time.sleep(0.100)
stream.stop_stream()
stream.close()
p.terminate()