如何实时处理音频流

时间:2017-03-06 12:08:40

标签: python-3.x raspberry-pi3 pyaudio pulseaudio

我有一个运行最新jessie的覆盆子pi 3的安装程序,安装了所有更新,我提供了一个A2DP蓝牙接收器,我用手机连接播放音乐。

通过pulseaudio,源(电话)被路由到alsa输出(接收器)。这种方法运作得相当好。

我现在想用python3.4和librosa来分析音频流,我找到了一个很有希望的例子,使用pyaudio调整后使用pulseaudio输入(由于它的默认值,它神奇地起作用)而不是wavfile:

"""PyAudio Example: Play a wave file (callback version)."""

import pyaudio
import wave
import time
import sys
import numpy

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

# define callback (2)
def callback(in_data, frame_count, time_info, status):
    # convert data to array
    data = numpy.fromstring(data, dtype=numpy.float32)
    # process data array using librosa
    # ...
    return (None, pyaudio.paContinue)

# open stream using callback (3)
stream = p.open(format=p.paFloat32,
                channels=1,
                rate=44100,
                input=True,
                output=False,
                frames_per_buffer=int(44100*10),
                stream_callback=callback)

# start the stream (4)
stream.start_stream()

# wait for stream to finish (5)
while stream.is_active():
    time.sleep(0.1)

# stop stream (6)
stream.stop_stream()
stream.close()
wf.close()

# close PyAudio (7)
p.terminate()

现在,虽然数据流原则上有效,但是有一个延迟(缓冲区的长度),用于调用stream_callback。自文档陈述

  

请注意,PyAudio在一个单独的线程中调用回调函数。

我会假设在处理回调时,缓冲区会一直填充主线程。当然,填充缓冲区会有一个初始延迟,之后我希望得到同步流。

我需要在缓冲区中使用更长的部分(请参阅frames_in_buffer),以便librosa能够正确地进行分析。

这样的事情怎么可能?它是否为raspberry ARM的软件端口限制?

我找到了其他答案,但they使用the阻止I/O。我如何将它包装成一个线程,以便librosa分析(可能需要一些时间)不会阻止缓冲区填充?

This blog似乎与cython的性能问题有关,但我不认为延迟是性能问题。 Or可能it?其他人似乎需要一些ALSA tweaks,但在使用pulseaudio时会有帮助吗?

谢谢,任何意见都赞赏!

0 个答案:

没有答案