从 pyaudio 中提取 numpy 数组会导致噪声和失真

问题描述 投票:0回答:1

我的目标是记录计算机的音频输出,实时处理它,然后实时做出反应。我正在使用 PyAudio 和允许环回设备的补丁。我可以毫无问题地将音频录制到文件中,而且听起来很完美,但是当我尝试将其转换为 numpy 数组来处理它时,它主要是噪音,您可以听到信号极度失真。

这是产生噪声输出的最小示例。在这种情况下,输入是麦克风来剪切输入选择代码,但结果是相同的:我的输入的极其嘈杂的表示。

import numpy as np
import pyaudiowpatch as pyaudio
import wave
import sounddevice as sd
from matplotlib import pyplot as plt

FORMAT = pyaudio.paInt16
CHANNELS = 2
RATE = 44100
CHUNK = 1048
RECORD_SECONDS = 5
WAVE_OUTPUT_FILENAME = "file.wav"


p = pyaudio.PyAudio()


stream = p.open(format=FORMAT, channels=CHANNELS,
                    rate=RATE, input=True,
                    frames_per_buffer=CHUNK)
print("recording...")
frames = []
fulldata = np.empty(RATE*RECORD_SECONDS*CHANNELS)

for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
    print(i)
    data = stream.read(CHUNK)
    numpydata = np.frombuffer(data, dtype='int16')
    fulldata[i*CHUNK*CHANNELS:(i+1)*CHUNK*CHANNELS] = numpydata
    frames.append(data)
print("finished recording")
channel0 = fulldata[0::CHANNELS]

print('playing')
sd.play(channel0, samplerate=RATE, blocking=True)


# stop Recording
stream.stop_stream()
stream.close()
p.terminate()

waveFile = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
waveFile.setnchannels(CHANNELS)
waveFile.setsampwidth(p.get_sample_size(FORMAT))
waveFile.setframerate(RATE)
waveFile.writeframes(b''.join(frames))
waveFile.close()

为了达到这一点,我遵循了从 pyaudio 中获取 numpy 数据的其他问题,并且录制的文件听起来很完美,因此转换之前的一切似乎都有效。输入有两个通道,我不确定数据是如何构造的,所以我假设数据正在交替通道,这也在提供channel0代码的另一个问题中建议。我假设在获取数据和使用 SD 播放数据之间存在问题。我什至尝试先将其保存到文件中,然后使用 librosa 再次加载它,当使用 sd 播放时,这听起来很完美。我确实注意到,在记录时采样率为 48000,但在加载 wav 文件时,sr 为 22050。我还尝试查看 writeframes 函数以获取有关此问题的任何线索,但没有运气。 p.get_sample_size(FORMAT) 是两个,因为 waveFile 期望提供它,但 np 不知道它,我认为这可能会导致一些问题,但我不知道如何调查这个问题。

我刚刚在堆栈上搜索了更多内容,有几个关于转换为 np 的问题,他们都说通道是交替的,这个解决方案应该有效。这可能与延迟有关吗?但我真的不知道如何设置。

是否有不同的方法将其转换为 np 数组,或者我在这里遗漏了其他内容?非常感谢任何对此的帮助。

numpy audio pyaudio python-sounddevice
1个回答
0
投票

哇我自己发现了错误。问题出在

fulldata = np.empty(RATE*RECORD_SECONDS*CHANNELS)

我没有指定数据类型,因此 np 创建了一个 float64 数组,并且可能做了一些奇怪的转换,导致了失真。我将其更改为 int16 现在可以使用了。

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.