【问题标题】:Prevent ALSA underruns with PyAudio使用 PyAudio 防止 ALSA 欠载
【发布时间】:2013-10-14 09:20:21
【问题描述】:

我写了一个小程序,它记录麦克风的声音并通过网络发送并在那里播放。我正在使用 PyAudio 来完成这项任务。它几乎可以正常工作,但是在两台计算机上,我都从 ALSA 收到错误,表明发生了欠载。我用谷歌搜索了很多关于它的信息,现在我知道什么是欠载。但我仍然不知道如何解决这个问题。大多数时候声音都很好。但是,如果发生欠载,这听起来有点奇怪。我的代码中有什么我应该注意的吗?感觉就像我犯了一个简单的错误,我想念它。

我的系统:python:python3.3,操作系统:Linux Mint Debian Edition UP7,PyAudio v0.2.7

【问题讨论】:

  • 如果你不想增加缓冲区大小:你会如何防止缓冲区清空?
  • 我不知道。因为我在问。
  • 我现在用谷歌搜索了更多关于这个的信息。我发现我对“增加”的翻译是错误的。 (英语不是我的母语)我认为这意味着使缓冲区更小。但是现在我更加困惑了,如果没有足够的数据进入,让缓冲区更大有什么帮助?

标签: python-3.x alsa pyaudio


【解决方案1】:

您是否考虑过同步声音? 你没有提供代码,所以我猜你需要在单独的线程中有一个计时器,它将执行每个 CHUNK_SIZE/RATE 毫秒代码,如下所示:

silence = chr(0)*self.chunk*self.channels*2 
out_stream = ... # is the output stream opened in pyaudio

def play(data):
    # if data has not arrived, play the silence
    # yes, we will sacrifice a sound frame for output buffer consistency
    if data == '':
        data = silence
    out_stream.write(data) 

假设这段代码会定期执行,这样我们总是会提供一些音频数据来输出音频流。

【讨论】:

  • 我不希望我的程序是多线程的,但你的回答让我开始思考。看我的答案或当前的解决方案。
  • 嗯,你的回答也很好。在某种程度上。让我解释。如果缓冲区被填充比读取速度快,您的解决方案将起作用。但是一旦涉及到一些计算,它会减慢缓冲区填充速度,并且您会得到同样的欠载(这是因为缓冲区不包含足够的数据,记得吗?)。这就是我建议多线程的原因。填充将并行进行,防止欠载。
  • 我现在填写了自己的线程。这导致了分段错误。我必须用锁来保护流以摆脱它们。
【解决方案2】:

如果需要,可以通过填充静音来防止欠载。 看起来是这样的:

#...
data = s.recv(CHUNK * WIDTH) # Receive data from peer
stream.write(data) # Play sound
free = stream.get_write_available() # How much space is left in the buffer?
if free > CHUNK # Is there a lot of space in the buffer?
    tofill = free - CHUNK
    stream.write(SILENCE * tofill) # Fill it with silence
#...

【讨论】:

    【解决方案3】:

    我的解决方案是缓冲录制声音的前 10 个数据包/帧。看下面的sn-p

    BUFFER = 10
    while len(queue) < BUFFER:
        continue
    
    while running:
        recorded_frame = queue.pop(0)
        audio.write(recorded_frame)
    

    【讨论】:

      猜你喜欢
      • 2013-01-14
      • 2016-09-06
      • 2012-05-30
      • 2013-12-27
      • 2013-03-26
      • 2019-03-20
      • 2021-10-17
      • 2014-12-20
      • 2011-11-26
      相关资源
      最近更新 更多