2

Pyaudio でマイクからオーディオをキャプチャし、opus コーデックでエンコード/デコードしようとしています。SvartalF ( https://github.com/svartalf/python-opus ) によって作成された libopus へのバインディングを使用しています。

これが私のコードです:

import pyaudio
from opus import encoder, decoder

def streaming(p):
    chunk = 960
    FORMAT = pyaudio.paInt16
    CHANNELS = 1
    RATE = 48000
    streamin = p.open(format = FORMAT,
            channels = CHANNELS, 
            rate = RATE, 
            input = True,
            input_device_index = 7,
            frames_per_buffer = chunk)
    streamout = p.open(format = FORMAT,
            channels = CHANNELS, 
            rate = 48000, 
            output = True,
            output_device_index = p.get_default_input_device_info()["index"],
            frames_per_buffer = chunk)
    enc = encoder.Encoder(RATE,CHANNELS,'voip')
    dec = decoder.Decoder(RATE,CHANNELS)
    data = []
    for i in xrange(100):
        data.append(streamin.read(chunk*2))
    streamout.write(''.join(data))
    encdata = []
    for x in data:
        encdata.append(enc.encode(x,chunk))
    print "DATA LENGTH :", len(''.join(data))
    print "ENCDATA LENGTH :", len(''.join(encdata))
    decdata = ''
    for x in encdata:
        decdata += dec.decode(x,chunk)
    print "DECDATA LENGTH :", len(decdata)
    streamout.write(decdata)
    streamin.close()
    streamout.close()


p = pyaudio.PyAudio()
streaming(p)
p.terminate()

orchunk*2の代わりにchunk入れなければなりませんが、理由がわかりません。data.append(streamin.read(chunk*2))DECDATA LENGTH == DATA LENGTH*2

出力:

DATA LENGTH :    384000  
ENCDATA LENGTH : 12865  
DECDATA LENGTH : 384000

エンコード/デコードがなければ、最初のstreamout.write(''.join(data))ものは完全に機能します。エンコード/デコードでは、streamout.write(decdata)ちょっと動作しますが、多くのパチパチ音が混ざっています.

ここで何が間違っていますか?

4

2 に答える 2

-3

出力を半分にカットして、最初の部分を取ります。試行錯誤の結果、このソリューションは満足のいくものであることがわかりました。

from opus import decoder as opus_decoder
from opus import encoder as opus_encoder

class OpusCodec():
    def __init__(self, *args, **kwargs):
        self.chunk = 960
        self.channels = 1
        self.rate = 48000
        self.encoder = opus_encoder.Encoder(
            self.rate, 
            self.channels,
            opus_encoder.APPLICATION_TYPES_MAP['voip']
        )
        self.decoder = opus_decoder.Decoder(
            self.rate, 
            self.channels, 
        )

    def encode(self, data, **kwargs):
        if not 'frame_size' in kwargs:
            kwargs['frame_size'] = self.chunk
        out = self.encoder.encode(data, frame_size=self.chunk)
        return out

    def decode(self, data, **kwargs):
        if not 'frame_size' in kwargs:
            kwargs['frame_size'] = self.chunk
        out = self.decoder.decode(data, **kwargs)
        return out[0:int(len(out)/2)] # hackety hack :D
于 2013-12-17T21:53:52.160 に答える