简体   繁体   English

从Raspberry Pi上的麦克风读取频率

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM