[英]Read frequency from mic on Raspberry Pi
Is there a simple way to record a few seconds of sound and convert it to frequency? 有没有一种简单的方法来录制几秒钟的声音并将其转换为频率? I have a USB mic and a raspberry pi 2 B. 我有一个USB麦克风和一个覆盆子pi 2 B.
In the file posted (convert2note.py) I am wondering how to make f equal to frequency obtained from the mic. 在发布的文件(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)]
Thanks a ton in advance :D 非常感谢提前:D
For capturing audio, you could for example use the sox
program. 为了捕获音频,您可以使用sox
程序。 See the linked documentation for details, but it could be as simple as: 有关详细信息,请参阅链接的文档,但它可以很简单:
rec input.wav
But the following is used to make the file match the format expected by the code below; 但以下用于使文件与下面的代码所期望的格式匹配;
rec −c 2 −b 16 −e signed-integer -r 44100 input.wav
(Technically only the -c
, -b
and -e
options are necessary to match the code below. You could reduce the sample rate -r
to speed up the processing) (从技术上讲,只需要-c
, -b
和-e
选项来匹配下面的代码。您可以降低采样率-r
以加快处理速度)
For processing the audio in Python, it would be best to save it in a wav
file, since Python has a module for reading those in the standard library. 为了在Python中处理音频,最好将其保存在wav
文件中,因为Python有一个用于读取标准库中的模块的模块。
For converting the audio to frequencies we'll use the discrete Fourier transform in the form of Numpy's fast Fourier transform for real input . 为了将音频转换为频率,我们将使用Numpy 快速傅立叶变换形式的离散 傅立叶变换进行实际输入 。 See the code fragment below, where I'm also using matplotlib to make plots. 请参阅下面的代码片段,其中我也使用matplotlib来绘制图表。
The code below assumes a 2-channel (stereo) 16-bit WAV file. 下面的代码假设一个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()
The avgf
array now holds the average of the left and right frequencies. avgf
阵列现在保持左右频率的平均值。 The plots look like this; 情节看起来像这样;
As you can see, a sound signal generally holds many frequencies. 如您所见,声音信号通常包含许多频率。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.