6

AudioQueue で Speex オーディオ形式をエンコード/デコードした経験がある人はいますか?

SpeakHere サンプルを編集して実装してみました。しかし成功しない!

Apple API ドキュメントから、AudioQueue はコーデックをサポートできますが、サンプルが見つかりません。誰か私に提案をしてもらえますか?XCode 4 のプロジェクトで、すでに Speex コーデックを正常にコンパイルしました。

4

3 に答える 3

0

アップルのサンプルコード「SpeakHere」では、次のようなことができます。

AudioQueueNewInput(
                                     &mRecordFormat,
                                     MyInputBufferHandler,
                                     this /* userData */,
                                     NULL /* run loop */,
                                     NULL /* run loop mode */,
                                     0 /* flags */, &mQueue)

関数「MyInputBufferHandler」で次のようなことができます

[self encoder:(short *)buffer->mAudioData count:buffer->mAudioDataByteSize/sizeof(short)];

次のようなエンコーダ機能:

while ( count >= samplesPerFrame )
    {
        speex_bits_reset( &bits );

        speex_encode_int( enc_state, samples, &bits ); 

        static const unsigned maxSize = 256;
        char data[maxSize];
        unsigned size = (unsigned)speex_bits_write( &bits, data, maxSize );
        /*
                    do some thing... for example :send to server
        */

        samples += samplesPerFrame;
        count -= samplesPerFrame;
    }

これは一般的な考え方です。もちろん事実は難しいですが、VOIPのオープンソースを見ることができ、おそらくあなたを助けることができます。幸運を。

于 2012-03-19T05:59:03.413 に答える
0

これらすべてを FFMPEG で実現し、AudioQueue で PCM として再生できます。FFMPEGライブラリの構築はそれほど簡単ではありませんが、デコード/エンコードプロセス全体はそれほど難しくありません:)

FFMPEG公式サイト SPEEX公式サイト

ライブラリをダウンロードして自分でビルドする必要があります。次に、それらを FFMPEG に含めてビルドする必要があります。

于 2012-08-08T15:06:28.370 に答える
0

以下は、audioqueue を使用してオーディオをキャプチャし、speex を使用してエンコード (広帯域) するためのコードです (オーディオの品質を向上させるには、別のスレッドでデータをエンコードできます。キャプチャ形式に応じてサンプルサイズを変更します)。

音声フォーマット

    mSampleRate = 16000;
    mFormatID = kAudioFormatLinearPCM;
    mFramesPerPacket = 1;
    mChannelsPerFrame = 1;
    mBytesPerFrame = 2;
    mBytesPerPacket = 2;
    mBitsPerChannel = 16;
    mReserved = 0;
    mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked; 

キャプチャ コールバック

    void CAudioCapturer::AudioInputCallback(void *inUserData, 
                           AudioQueueRef inAQ, 
                           AudioQueueBufferRef inBuffer, 
                           const AudioTimeStamp *inStartTime, 
                           UInt32 inNumberPacketDescriptions, 
                           const AudioStreamPacketDescription *inPacketDescs)
    {
    CAudioCapturer *This = (CMacAudioCapturer *)inUserData;

int len = 640;
char data[640];
char *pSrc = (char *)inBuffer->mAudioData;

while (len <= inBuffer->mAudioDataByteSize) 
{
    memcpy(data,pSrc,640);
    int enclen = encode(buffer,encBuffer);
    len=len+640;

    pSrc+=640; // 640 is the frame size for WB in speex (320 short)
}

AudioQueueEnqueueBuffer(This->m_audioQueue, inBuffer, 0, NULL);
    }

Speex エンコーダ

    int encode(char *buffer,char *pDest)
    {
int nbBytes=0;
speex_bits_reset(&encbits);

speex_encode_int(encstate, (short*)(buffer)  , &encbits);

nbBytes = speex_bits_write(&encbits, pDest ,640/(sizeof(short))); 

return nbBytes;
    }
于 2012-08-31T06:20:23.250 に答える