2017-03-03 108 views
0

當我播放聲音每0.5秒與pygame的時機不好。播放音頻文件時pygame的

這就好比0.2秒暫停0.7秒再0.2秒,這是非常不規則的。


注:

  • 我知道time.sleep()是不是世界上最精確的,但即使有更準確的解決方案from here,問題依然存在

  • 測試上a RaspberryPi

  • 如果我播放多個不同的文件,問題仍然存在s[i].play(),我在一個很大的範圍內。所以,問題不是來自事實它試圖重新播放同一文件

+1

」0.2秒的停頓時間超過0.7秒,然後再0.2秒,這是非常不規則的。「這聽起來對我來說聽起來很不規律,聽起來很循環。聲音持續多久?特別是因爲'0.7 ==(sleep_time + 0.2)' – roganjosh

+0

@roganjosh爲什麼會有這樣一個循環? 's.play()'是非阻塞的並且應該繼續代碼 – Basj

+0

@roganjosh我修改了代碼以利用通道,因此每個播放的聲音都不應該干擾另一個聲音。問題仍然存在... – Basj

回答

1

這裏的原因是:

enter image description here

即使我們降低音頻緩衝區所支持的最小聲卡(1024或512個樣本,而不是pygame的默認4096個),差異仍然存在,使得應該成爲「節拍器節拍」的應該是不合適的。

我會盡快找到一個適合您的工作解決方案。 (我在這個方向有幾個想法)。

1

正如您在自己的答案中所寫的,時間問題的原因很可能是音頻回調與應用程序的其餘部分分離。

音頻後端通常具有某種類型的時鐘,可以從回調函數內部和外部訪問。 我看到了兩個可能的解決方案:

  1. 使用庫,可以讓你實現回調函數自己,計算回調函數內部聲音的開始時間,這些時間用「音頻的當前時間比較時鐘「,並將聲音寫入輸出緩衝區中適當位置的輸出。

  2. 使用一個庫,允許您指定何時開始播放聲音的準確時間(按照「音頻時鐘」)。這個圖書館會爲你做前面的步驟。

對於第一個選項,您可以使用sounddevice模塊。回調函數(您必須實現)將獲得名爲time的參數,該參數的屬性爲time.outputBufferDacTime,它是一個浮點值,用於指定輸出緩衝區的第一個樣本將被回放的時間(以秒爲單位) 。

完全披露:我是sounddevice模塊的作者,所以我的建議很有偏見。

不久之前,我已開始研究rtmixer模塊,該模塊可用於第二個選項。 請注意,這是在非常早期的發展狀態,所以謹慎使用它。 使用此模塊,您不必編寫回調函數,可以使用功能rtmixer.Mixer.play_buffer()在指定的時間(以秒爲單位)播放音頻緩衝區。作爲參考,您可以從rtmixer.Mixer.time獲得當前時間。 「

+0

非常好的答案!謝謝!我接近了同樣的想法:從「播放聲音事件」循環線程發送時間戳,音頻回調將在「混音線程」中使用,並具有適當的位置。我一定會使用'sounddevice',我已經用於我的項目http://www.samplerbox.org!謝謝 – Basj

+0

很酷的東西,我印象深刻! – Matthias

+0

Re @Matthias,'rtmixer'在C或Cython(不是cpython,而是cython)中進行實際的混音/求和來加速它?這是我如何做SamplerBox混合([見這裏](https://github.com/josephernest/SamplerBox/blob/master/samplerbox_audio.pyx)),我想知道你是否也注意到混合數學部分一種編譯語言也大大提高了你的性能。 – Basj