2016-08-14 3 views
0

현재 오디오를 스트리밍하는 데 Pyaudio를 사용하고 파이썬으로 파일 데이터를로드하기위한 파이썬 웨이브 라이브러리를 사용하여 파이썬으로 .wav 파일을 처리하고 있습니다. 나중에 신호의 진폭 및 스테레오 신호의 패닝과 관련하여 개별 스테레오 채널의 처리를 포함 할 예정입니다. 그러나 지금은 웨이브 파일의 두 채널을 분리하려고 시도하고 있습니다. 다시 함께 - 입력 데이터와 동일한 데이터로 끝내기를 바랍니다.끊김없는 오디오가 분리 된 다음 .wav 스테레오 채널에 연결됨

아래 코드는 제 코드입니다. getRawSample 메서드는 완벽하게 작동하며 해당 함수를 통해 오디오를 스트리밍 할 수 있습니다. 문제는 내 getSample 메서드입니다. 오디오의 두 채널을 분리하고 함께 결합하면 오디오가 왜곡됩니다. 나는 심지어 내가 진폭과 패닝 조정을하는 부분을 주석 처리했다. 그래서 이론적으로 그것은 데이터 -> 데이터 아웃이다. 내가 오류가 내가 함께 왼쪽과 오른쪽 채널,하지만 확실하지 스티치 방식에 있음을 의심하고

class Sample(threading.Thread) : 

def __init__(self, filepath, chunk): 
    super(Sample, self).__init__() 
    self.CHUNK = chunk 
    self.filepath = filepath 
    self.wave = wave.open(self.filepath, 'rb') 
    self.amp = 0.5 # varies from 0 to 1 
    self.pan = 0 # varies from -pi to pi 
    self.WIDTH = self.wave.getsampwidth() 
    self.CHANNELS = self.wave.getnchannels() 
    self.RATE = self.wave.getframerate() 
    self.MAXFRAMEFEEDS = self.wave.getnframes()/self.CHUNK # maximum even number of chunks 
    self.unpstr = '<{0}h'.format(self.CHUNK*self.WIDTH) # format for unpacking the sample byte string 
    self.pckstr = '<{0}h'.format(self.CHUNK*self.WIDTH) # format for unpacking the sample byte string 

    self.framePos = 0 # keeps track of how many chunks of data fed 

# panning and amplitude adjustment of input sample data 

def panAmp(self, data, panVal, ampVal): # when panning, using constant power panning 
    [left, right] = self.getChannels(data) 
    #left = np.multiply(0.5, left) #(np.sqrt(2)/2)*(np.cos(panVal) + np.sin(panVal)) 
    #right = np.multiply(0.5, right) # (np.sqrt(2)/2)*(np.cos(panVal) - np.sin(panVal)) 
    outputList = self.combineChannels(left, right) 
    dataResult = struct.pack(self.pckstr, *outputList) 
    return dataResult 

def getChannels(self, data): 
    dataPrepare = list(struct.unpack(self.unpstr, data)) 
    left = dataPrepare[0::self.CHANNELS] 
    right = dataPrepare[1::self.CHANNELS] 
    return [left, right] 

def combineChannels(self, left, right): 
    stereoData = left 
    for i in range(0, self.CHUNK/self.WIDTH): 
     index = i*2+1 
     stereoData = np.insert(stereoData, index, right[i*self.WIDTH:(i+1)*self.WIDTH]) 
    return stereoData 

def getSample(self, panVal, ampVal): 
    data = self.wave.readframes(self.CHUNK) 
    self.framePos += 1 
    if self.framePos > self.MAXFRAMEFEEDS: # if no more audio samples to process 
     self.wave.rewind() 
     data = self.wave.readframes(self.CHUNK) 
     self.framePos = 1 
    return self.panAmp(data, panVal, ampVal) 

def getRawSample(self): # for debugging, bypasses pan and amp functions 
    data = self.wave.readframes(self.CHUNK) 
    self.framePos += 1 
    if self.framePos > self.MAXFRAMEFEEDS: # if no more audio samples to process 
     self.wave.rewind() 
     data = self.wave.readframes(self.CHUNK) 
     self.framePos = 1 
    return data 

:
다음은 내 코드의 예입니다. 16 비트 44100khz .wav 파일로 프로젝트를로드합니다. 다음은 결과 오디오 출력을들을 수 있도록 오디오 파일에 대한 링크입니다. 첫 번째 부분은 getSample 메소드를 통해 두 파일 (두 채널 모두)을 실행하고 다음 부분은 getRawSample 메소드를 통해 동일한 파일을 실행합니다. 앞서 말했듯이 스테레오 파일이 왜곡됩니다 같은

오디오에 내놓고 는

https://dl.dropboxusercontent.com/u/24215404/pythonaudiosample.wav

, 그것은 보인다. 위의 파일의 파형을 보면 getSample 메서드를 통과 한 후 오른쪽 및 왼쪽 채널이 정확히 동일하게 보입니다.

필요한 경우 주 기능을 포함하여 내 코드를 게시 할 수도 있습니다. 잘하면 내 질문에 애매한 것은 아니지만 도움이나 의견을 보내 주시면 감사하겠습니다.

답변

0

자주 발생하기 때문에, 나는 그것에 잠을 자고 다음날 해결책을 찾았습니다.
문제는 combineChannels 함수에있었습니다. 는 다음 작업 코드 :

변화는 루프 경계를 들어

  • 있습니다
    def combineChannels(self, left, right): 
        stereoData = left 
        for i in range(0, self.CHUNK): 
         index = i*2+1 
         stereoData = np.insert(stereoData, index, right[i:(i+1)]) 
        return stereoData 
    

    : 나는 1024 개 왼쪽 목록에있는 항목 (내 청크 크기와 같은)과 바로을 가지고 , 당연히 그 중 하나 하나를 반복해야합니다.

  • 인덱스 : 인덱스 정의가 동일하게 유지됩니다.
  • stereoData : 다시 말하지만, 여기서는 오디오 프레임이 포함 된 목록을 사용하고 있습니다. 질문에있는 코드는 내 목록이 bytestring으로 저장되어 있다고 가정하지만 이것이 사실이 아닙니다. 보시다시피 결과 코드는 훨씬 간단합니다.