如何将numpy数组流式传输到pyaudio流?

时间:2015-06-05 21:01:02

标签: python audio numpy pyaudio

我正在编写一个代码,该代码应该根据用户的动作向用户提供一些音频输出,我想生成声音,而不是要播放固定数量的wav文件。现在,我正在做的是以numpy格式生成信号,将数据存储在wav文件中,然后将同一文件读入pyaudio。我认为这是多余的,但是,我找不到办法做到这一点。我的问题是,我可以直接将一个numpy数组(或常规列表)流式传输到我的pyaudio中来播放吗?

3 个答案:

答案 0 :(得分:5)

如果它只是播放而不需要同步到任何东西,那么你可以执行以下操作:

# Open stream with correct settings
stream = self.p.open(format=pyaudio.paFloat32,
                         channels=CHANNELS,
                         rate=48000,
                         output=True,
                         output_device_index=1
                         )
# Assuming you have a numpy array called samples
data = samples.astype(np.float32).tostring()
stream.write(data)

我使用这种方法,它对我来说很好。如果你需要同时录制,那么这不会奏效。

答案 1 :(得分:2)

如果您只想生成音频音调,那么下面的代码可能很有用,

确实需要pyaudio才能安装为

pip install pyaudio

示例代码

#Play a fixed frequency sound.
from __future__ import division
import math
import pyaudio

#See http://en.wikipedia.org/wiki/Bit_rate#Audio
BITRATE = 44100 #number of frames per second/frameset.      

#See http://www.phy.mtu.edu/~suits/notefreqs.html
FREQUENCY = 2109.89 #Hz, waves per second, 261.63=C4-note.
LENGTH = 1.2 #seconds to play sound

NUMBEROFFRAMES = int(BITRATE * LENGTH)
RESTFRAMES = NUMBEROFFRAMES % BITRATE
WAVEDATA = ''    

for x in xrange(NUMBEROFFRAMES):
WAVEDATA = WAVEDATA+chr(int(math.sin(x/((BITRATE/FREQUENCY)/math.pi))*127+128))    

#fill remainder of frameset with silence
for x in xrange(RESTFRAMES): 
WAVEDATA = WAVEDATA+chr(128)

p = pyaudio.PyAudio()
stream = p.open(format = p.get_format_from_width(1), 
            channels = 1, 
            rate = BITRATE, 
            output = True)
stream.write(WAVEDATA)
stream.stop_stream()
stream.close()
p.terminate()

askubuntu网站

略微修改了代码

答案 2 :(得分:1)

您可以通过pyaudio直接传输数据,无需编写和读取.wav文件。

import pyaudio
p = pyaudio.PyAudio()
stream = p.open(format=pyaudio.paFloat32,
                channels=1,
                rate=44100,
                frames_per_buffer=1024,
                output=True,
                output_device_index=1
                )
samples = np.sin(np.arange(50000)/20)
stream.write(samples.astype(np.float32).tostring())
stream.close()