-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy path2_freq.analysiser.py
71 lines (65 loc) · 2.54 KB
/
2_freq.analysiser.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
import pyaudio # 收集声音
import numpy as np # 处理声音数据
import matplotlib.pyplot as plt # 作图
import matplotlib as mpl
from numpy.fft import rfft, rfftfreq # 傅立叶变换
# 输入音频参数设置
END = False
audio_fmt = pyaudio.paInt8
channel_num = 1
sample_rate = 44000
sample_interval = 1/sample_rate
sample_time = 0.3 # 1/10 秒保证实时效果
chunk = int(sample_time/sample_interval)
p = pyaudio.PyAudio()
stream = p.open(format=audio_fmt, channels=channel_num, rate=sample_rate,\
input=True, frames_per_buffer=chunk)
# 按键中断: 按下按键执行该函数
def on_press(event):
global stream, p, END
if event.key == 'q':
plt.close()
stream.stop_stream()
stream.close()
p.terminate()
END = True
# 作图的设置
mpl.rcParams['toolbar'] = 'None' # 不展示工具栏
fig, ax = plt.subplots(figsize=(12,4))
fig.canvas.mpl_connect('key_press_event', on_press) # 连接一个按键中断函数
#plt.subplots_adjust(left=0.001, top=0.9,right=0.999,bottom=0.1) # 设置边距
plt.get_current_fig_manager().set_window_title('Spectrum') # 设置窗口名字
freq = rfftfreq(chunk, d=sample_interval) # 得到傅立叶变换的横坐标
y_data= np.random.rand(freq.size)
plt.xlabel('Freq. [Hz]')
#plt.ylabel('Amplitude')
#line, = ax.step(freq, y_data, where='mid', color='#C04851')
ax.tick_params(direction='in')
line, = ax.plot(freq, y_data, color='#C04851')
ax.set_xlim(80,1500) # 人声的大概频率范围
ax.set_ylim(-0.01,30)
#plt.axis('off') # 关掉坐标
ax.set(yticklabels=[])
plt.ion() # 交互模式打开,可动态刷新图像
plt.show()
G = 196
colors = ['red', 'green']
for i in range(8):
plt.axvline(x = G*(i+1), color=colors[i%2], linestyle='--', linewidth=1)
ax.annotate('196*{}'.format(i+1), (G*(i+1) + 5, 28), color=colors[i%2])
# 程序主体
while END==False:
data = stream.read(chunk, exception_on_overflow=False) # 获取数据
data = np.frombuffer(data, dtype=np.int8) # 将16进制的数据转化成8位整型
X = rfft(data) # 对实数序列做傅立叶变换
y_data = np.abs(X)*0.01 # 得到幅度, 适当缩放
line.set_ydata(y_data) # 更新y坐标数据
# axfill = ax.fill_between(freq, 0, y_data, step="mid",
# color='#C04851', alpha =0.7)
# axfill_ = ax.fill_between(freq, 0, -1*y_data, step="mid",
# color='#C04851', alpha =0.075)
fig.canvas.draw()
fig.canvas.flush_events()
plt.pause(0.01)
#axfill.remove() # 删除填充的区域
#axfill_.remove()