Как кодировать / декодировать Speex с AudioQueue в IOS - PullRequest
6 голосов
/ 02 августа 2011

Если у кого-нибудь есть опыт кодирования / декодирования аудио-формата speex с AudioQueue?

Я попытался реализовать это, отредактировав образец SpeakHere.Но не успех!

Из документа API Apple AudioQueue может поддерживать кодек, но я не могу найти образец.Кто-нибудь может дать мне какое-нибудь предложение?Я уже успешно скомпилировал кодек speex в своем проекте в XCode 4.

Ответы [ 3 ]

0 голосов
/ 08 августа 2012

Вы можете достичь всего этого с FFMPEG, а затем воспроизводить его как PCM с AudioQueue. Сборка библиотеки FFMPEG не так безболезненна, но весь процесс декодирования / кодирования не так сложен:)

Официальный сайт FFMPEG Официальный сайт SPEEX

Вам нужно будет скачать библиотеки и собрать их самостоятельно, а затем вам нужно будет включить их в FFMPEG и собрать их.

0 голосов
/ 31 августа 2012

Ниже приведен код для захвата аудио с использованием аудио очереди и кодирования (широкополосного) с использованием 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 encoder

    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;
    }
0 голосов
/ 19 марта 2012

в примере кода 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, может быть, он вам поможет удачи.

...