如何获得在 Python 3.x 中录制的音频的频率和幅度?

CML*_*LSC 1 python audio python-3.x

我正在尝试录制音频并以 1 秒为间隔获取音频的平均频率和幅度,而无需写入文件。如果您使用 pyaudio 从文件中读取,有很多关于如何完成此操作的示例,尽管可用于此特定情况的任何内容都使用 Python 2.7 库,而 Python 3.x 似乎不存在这些库。

任何帮助,将不胜感激!

Woo*_*Dev 9

获取音频

我不确定您使用什么库来录制音频,但实时录制/播放(在我看来)的常规方法PyAudio(您只提到它是为了从文件中读取)。

他们有一个用于实时处理的阻塞非阻塞音频 I/O的示例。例如,使用阻塞模式示例,您可以在每次收到新的音频块时执行 DSP 处理。

"""PyAudio Example: Play a wave file."""

import pyaudio
import wave
import sys

CHUNK = 1024

if len(sys.argv) < 2:
    print("Plays a wave file.\n\nUsage: %s filename.wav" % sys.argv[0])
    sys.exit(-1)

wf = wave.open(sys.argv[1], 'rb')

# instantiate PyAudio (1)
p = pyaudio.PyAudio()

# open stream (2)
stream = p.open(format=p.get_format_from_width(wf.getsampwidth()),
                channels=wf.getnchannels(),
                rate=wf.getframerate(),
                output=True)

# read data
data = wf.readframes(CHUNK)

# play stream (3)
while len(data) > 0:
    stream.write(data)
    data = wf.readframes(CHUNK)
    # Do all of your DSP processing here i.e. function call or whatever

# stop stream (4)
stream.stop_stream()
stream.close()

# close PyAudio (5)
p.terminate()
Run Code Online (Sandbox Code Playgroud)

寻找振幅

如果您想要任何给定点的信号幅度,那么您所要做的就是取样本数组中一个样本的绝对值,即从音频块数据中获取第三个样本的幅度。

ampSample3 = abs(data[2])
Run Code Online (Sandbox Code Playgroud)

显然,这对于单个样本幅度通常不是那么有用,但最好查看整个块。因此,您可以计算每个值的绝对值,将所有数组相加并除以块大小(平均值)。

blockAmplitudeMean = sum(numpy.absolute(x))/len(x)
Run Code Online (Sandbox Code Playgroud)

但是在处理音频时,我们通常需要块的RMS值。

blockLinearRms= numpy.sqrt(numpy.mean(data**2)) # Linear value between 0 -> 1
blockLogRms = 20 * math.log10(blockLinearRms) # Decibel (dB value) between 0 dB -> -inf dB
Run Code Online (Sandbox Code Playgroud)

获取频率

在您的问题中,您刚刚指定获取音频的频率,这可能意味着两件事之一。

确定频谱

通常用于 DSP,可以使用DFT(离散傅立叶变换)分析频谱。您通常会在名称FFT(快速傅立叶变换)下看到它,因为这是 DFT 最流行的实现。已经有 Python 库可以为您实现 FFT 并且易于使用。

请注意,这将为您提供一个包含复杂信息(真实信号 + 相位信息)即频率信息的块大小长度的数组。这并不意味着您一定可以识别传入音频的音高(您不能直接判断某人正在钢琴上演奏 A1 音符,除非信号质量非常高并且您仍然具有一些基本的 DSP 处理以及FFT)。

以供参考:

如果您想对频率信息进行处理,您可以在处理循环中调用此函数。

确定音高(/音符)

这是许多人试图完成的一项重要任务。大多数算法通常涉及 FFT(如前所述),但在顶部还有另一层复杂的处理。除非您想开发自己的算法,否则我建议使用库: