2017-03-27 18 views
1

我試圖打開立體聲流並將其轉換爲單聲道,在python中使用wave module。 到目前爲止,我能寫從16位立體聲小端文件中的單個(左或右)聲道:立體聲到蟒蛇的單波插值

LEFT, RIGHT = 0, 1 
def mono_single(cont, chan=LEFT): 
    a = iter(cont) 
    mono_cont = '' 
    if chan: 
     a.next(); a.next() 
    while True: 
     try:       
      mono_cont += a.next() + a.next() 
      a.next(); a.next() 
     except StopIteration: 
      return mono_cont 

stereo = wave.open('stereofile.wav', 'rb') 
mono = wave.open('monofile.wav', 'wb') 
mono.setparams(stereo.getparams()) 
mono.setnchannels(1) 
mono.writeframes(mono_single(stereo.readframes(stereo.getnframes()))) 
mono.close() 

可正常工作。當我嘗試將兩個立體聲聲道縮混到一個單聲道時,問題就出現了。 我認爲之間的簡單平均值左右就足夠了,而這正是我試圖至今:

def mono_mix(cont): 
    a = iter(cont) 
    mono_cont = '' 
    while True: 
     try: 
      left = ord(a.next()) + (ord(a.next()) << 8) 
      right = ord(a.next()) + (ord(a.next()) << 8) 
      value = (left + right)/2 
      mono_cont += chr(value & 255) + chr(value >> 8) 
     except StopIteration: 
      return mono_cont 

stereo = wave.open('stereofile.wav', 'rb') 
mono = wave.open('monofile.wav', 'wb') 
mono.setparams(stereo.getparams()) 
mono.setnchannels(1) 
mono.writeframes(mono_mix(stereo.readframes(stereo.getnframes()))) 
mono.close() 

我從這個得到的是一個「噼噼啪啪」的來源的版本。 我嘗試了不同的組合(我可能誤解了整個排列順序),但目前還沒有運氣。

回答

1

你打算使用外部庫嗎?
如果是,你可以用pydub非常幾行做到這一點很容易如下,

from pydub import AudioSegment 
mysound = AudioSegment.from_wav("/input_path/infile.wav") 
mysound = mysound.set_channels(1) 
mysound.export("/output_path/outfile.wav", format="wav") 
+0

由於選擇單個信道,哪知pydub能夠做那。實際上,它看起來像是在使用我不知道的audioop模塊,所以我想我會檢查它的代碼並編寫自己的函數(我寧願避免使用pydub,因爲我會只需要這種情況)。 – musicamante

0

原來像我不知道有這個audioop內置模塊(感謝的answerAnil_M沒有。另外,我錯了兩個轉換立體聲格式寫作(我應該用結構)

這使得一切絕對更容易:

stereo = wave.open('stereofile.wav', 'rb') 
mono = wave.open('monofile.wav', 'wb') 
mono.setparams(stereo.getparams()) 
mono.setnchannels(1) 
mono.writeframes(audioop.tomono(stereo.readframes(float('inf')), stereo.getsampwidth(), 1, 1)) 
mono.close() 

然後,你可以通過修改最新的2個參數(1, 0左,0, 1右),甚至使用1.414同等功率而不是幅度相等的