6

如果有人有使用 AudioQueue 编码/解码 speex 音频格式的经验?

我试图通过编辑 SpeakHere 示例来实现它。但不是成功!

从苹果 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 回答