AudioQueue で Speex オーディオ形式をエンコード/デコードした経験がある人はいますか?
SpeakHere サンプルを編集して実装してみました。しかし成功しない!
Apple API ドキュメントから、AudioQueue はコーデックをサポートできますが、サンプルが見つかりません。誰か私に提案をしてもらえますか?XCode 4 のプロジェクトで、すでに Speex コーデックを正常にコンパイルしました。
AudioQueue で Speex オーディオ形式をエンコード/デコードした経験がある人はいますか?
SpeakHere サンプルを編集して実装してみました。しかし成功しない!
Apple API ドキュメントから、AudioQueue はコーデックをサポートできますが、サンプルが見つかりません。誰か私に提案をしてもらえますか?XCode 4 のプロジェクトで、すでに Speex コーデックを正常にコンパイルしました。
アップルのサンプルコード「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 に含めてビルドする必要があります。
以下は、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;
}