如果有人有一些经验,编码/解码speex音频格式与AudioQueue?
我试图通过编辑SpeakHere示例来实现它。但不是成功!
从apple API文档中,AudioQueue可以支持编解码器,但我找不到任何示例。谁能给我一些建议?我已经在XCode 4中成功编译了speex编解码器。
在apple示例代码"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,也许可以帮助到你。好运。
您可以使用FFMPEG实现所有这些,然后使用AudioQueue将其作为PCM播放。FFMPEG库的构建并不是那么轻松,但整个解码/编码过程并不是那么困难:)
FFMPEG官方网站SPEEX官网
您必须下载库并自己构建它们,然后您必须将它们包含到FFMPEG中并构建它
下面是使用audioqueue捕获音频和使用speex编码(宽带)的代码(为了获得更好的音频质量,您可以在单独的线程中编码数据,根据捕获格式更改样本大小)。
<<p> 音频格式/strong> 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;
}