从 Raspberry Pi 上的麦克风读取频率
Posted
技术标签:
【中文标题】从 Raspberry Pi 上的麦克风读取频率【英文标题】:Read frequency from mic on Raspberry Pi 【发布时间】:2016-03-27 17:13:55 【问题描述】:有没有一种简单的方法可以录制几秒钟的声音并将其转换为频率?我有一个 USB 麦克风和一个树莓派 2 B。
在发布的文件 (convert2note.py) 中,我想知道如何使 f 等于从麦克风获得的频率。 This is what the program looks like so far
#d=69+12*log(2)*(f/440)
#d is midi, f is frequency
import math
f=raw_input("Type the frequency to be converted to midi: ")
d=69+(12*math.log(float(f)/440))/(math.log(2))
d=round(int(d))
notes = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]
print notes[d % len(notes)]
非常感谢:D
【问题讨论】:
您最初的问题是——如何使用 python 从麦克风中捕捉声音?我想知道,因为您似乎没有任何麦克风输入。如果这是您的问题,这里有几个答案引用了一些可能有用的库。 是你的第二个问题,我如何获取我捕获的声音,然后确定该波的频率,这里还有几个问题,参考方法似乎可以工作 @PyNEwbie 是的,这些都是我的问题。你能把我转发到正确的网站吗?我很不知道从哪里开始以及如何解决这个问题。谢谢! 这里是关于如何从树莓派上的麦克风捕获声音的讨论。http://raspberrypi.stackexchange.com/questions/4027/how-do-capture-audio-using-python
。只需在堆栈站点中使用上述关键字搜索即可引导您进行相关讨论。
【参考方案1】:
例如,要捕获音频,您可以使用sox
程序。有关详细信息,请参阅链接文档,但它可能很简单:
rec input.wav
但下面是用来使文件与下面代码所期望的格式相匹配的;
rec −c 2 −b 16 −e signed-integer -r 44100 input.wav
(技术上只有-c
、-b
和-e
选项是匹配下面代码所必需的。您可以降低采样率-r
以加快处理速度)
要在 Python 中处理音频,最好将其保存在 wav
文件中,因为 Python 在标准库中有一个用于读取这些音频的模块。
为了将音频转换为频率,我们将使用 Numpy 的 fast Fourier transform for real input 形式的 discrete Fourier transform。请参阅下面的代码片段,其中我也使用 matplotlib 来制作绘图。
以下代码假定为 2 通道(立体声)16 位 WAV 文件。
from __future__ import print_function, division
import wave
import numpy as np
import matplotlib.pyplot as plt
wr = wave.open('input.wav', 'r')
sz = wr.getframerate()
q = 5 # time window to analyze in seconds
c = 12 # number of time windows to process
sf = 1.5 # signal scale factor
for num in range(c):
print('Processing from to s'.format(num*q, (num+1)*q))
avgf = np.zeros(int(sz/2+1))
snd = np.array([])
# The sound signal for q seconds is concatenated. The fft over that
# period is averaged to average out noise.
for j in range(q):
da = np.fromstring(wr.readframes(sz), dtype=np.int16)
left, right = da[0::2]*sf, da[1::2]*sf
lf, rf = abs(np.fft.rfft(left)), abs(np.fft.rfft(right))
snd = np.concatenate((snd, (left+right)/2))
avgf += (lf+rf)/2
avgf /= q
# Plot both the signal and frequencies.
plt.figure(1)
a = plt.subplot(211) # signal
r = 2**16/2
a.set_ylim([-r, r])
a.set_xlabel('time [s]')
a.set_ylabel('signal [-]')
x = np.arange(44100*q)/44100
plt.plot(x, snd)
b = plt.subplot(212) # frequencies
b.set_xscale('log')
b.set_xlabel('frequency [Hz]')
b.set_ylabel('|amplitude|')
plt.plot(abs(avgf))
plt.savefig('simple:02d.png'.format(num))
plt.clf()
avgf
数组现在保存左右频率的平均值。情节是这样的;
如您所见,声音信号通常包含许多频率。
【讨论】:
以上是关于从 Raspberry Pi 上的麦克风读取频率的主要内容,如果未能解决你的问题,请参考以下文章
Pymodbus - 在 raspberry pi3 的 uart 上通过 rs485 读取电能表的输入寄存器
无法使用 Raspberry PI 从 RDM6300 读取 RFID 数据
如何在 Raspberry Pi 4 上使用 Azure 语音服务 C# SDK 设置麦克风
OSError: [Errno 5] Raspberry PI GPS shield Python 上的输入/输出错误