2014-09-23 76 views
0

過濾對於一個項目,我需要蟒蛇音頻播放器沒有抖動

  • 讀WAV文件
  • 過濾
  • 播放WAV文件

下面的代碼是「工作」不同的是,聲音crack,,那是因爲我無法保證數據流能夠繼續傳輸到音頻輸出。過濾需要一段時間,這就是聲音在很短時間內凍結的地方。

未來我想對原始音頻數據做一些額外的計算。我想知道哪種方法最能保持聲音順暢。

import pyaudio 
import wave 
from scipy import signal 
from struct import * 

chunk = 1024 

f = wave.open("sample.wav","rb") 
p = pyaudio.PyAudio() 

stream = p.open(format = p.get_format_from_width(f.getsampwidth()), 
      channels = f.getnchannels(), 
      rate = f.getframerate(), 
      output = True) 

data = f.readframes(chunk) 
b, a = signal.butter(2, 0.01) 

tmp = len(data)/2 
s = '<' 
for i in range(0,tmp): 
    s = s + 'h' 

while data != '': 
    sig = signal.filtfilt(b, a, unpack(s,data)) 

    output_signal = pack(s,*sig) 
    stream.write(output_signal) 
    data = f.readframes(chunk) 

stream.stop_stream() 
stream.close() 
p.terminate() 

在此先感謝!

+0

您是否需要實時過濾,還是可以收集輸出信號並將它們一起寫入? – 2014-09-23 20:53:01

+0

你應該考慮緩衝 – user1767754 2014-09-23 20:53:03

回答

0

你可以嘗試在兩個程序中分割數據的生產者和消費者(這是pyaudio),使用普通的Unix管道連接它們。 Unix管道扮演着緩衝的角色。例如:

在producer.py

while data != '': 
    sig = signal.filtfilt(b, a, unpack(s,data)) 
    output_signal = pack(s,*sig) 
    sys.stdout.write(output_signal)  # <=== 
    data = f.readframes(chunk) 

在consumer.py:

while 1: 
    data = sys.stdin.read(1024) 
    if not data: break 
    stream.write(data) 

命令行調用:

python producer.py | python consumer.py 

如果成功,那麼你也可以例如,使用os.popen()從另一個程序中運行python consumer.py

+0

謝謝你的回答,這對我很有幫助。 – Weller 2014-09-24 21:43:59

+0

我還應該提到,使用兩個線程而不是兩個進程可以獲得相同的效果,而不是使用OS管道,但是例如'queue'模塊。雖然這樣更復雜,但對我來說沒有任何好處。它的主要優點是,如果兩個進程需要交換的不僅僅是一串字節。 – 2014-09-25 11:59:36