AudioQueue Как прочитать буфер из CallBack - PullRequest
1 голос
/ 02 июня 2011

Я использую AUdioQueue для записи звука со встроенного микрофона и отправки его через сокет. Я установил буфер AudioQueue для записи буфера, скажем, 30 секунд за один снимок, и соответствующим образом выделяю bufferSize. Это функция, которую я используюустановить AudioDataFormat.

AudioStreamBasicDescription sRecordFormat;
 FillOutASBDForLPCM (sRecordFormat,
                    16000,
                    1,
                    16,
                    16,
                    false,
                    false
                    );

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

int AQRecorder::ComputeRecordBufferSize(const AudioStreamBasicDescription *format, float seconds)
{
    int packets, frames, bytes = 0;
    try {
        frames = (int)ceil(seconds * format->mSampleRate);

        if (format->mBytesPerFrame > 0)
            bytes = frames * format->mBytesPerFrame;
        else {
            UInt32 maxPacketSize;
            if (format->mBytesPerPacket > 0)
                maxPacketSize = format->mBytesPerPacket;    // constant packet size
            else {
                UInt32 propertySize = sizeof(maxPacketSize);
                XThrowIfError(AudioQueueGetProperty(mQueue, kAudioQueueProperty_MaximumOutputPacketSize, &maxPacketSize,
                                                 &propertySize), "couldn't get queue's maximum output packet size");
            }
            if (format->mFramesPerPacket > 0)
                packets = frames / format->mFramesPerPacket;
            else
                packets = frames;   // worst-case scenario: 1 frame in a packet
            if (packets == 0)       // sanity check
                packets = 1;
            bytes = packets * maxPacketSize;
        }
    } catch (CAXException e) {
        char buf[256];
        gLog<<[[NSString stringWithFormat:@"Error:%s (%s)\n",e.mOperation,e.FormatError(buf)] UTF8String]<<endl;
        return 0;
    }   
    return bytes;
}

В следующем примере кода для выделения буфера,

    // allocate and enqueue buffers
    bufferByteSize = ComputeRecordBufferSize(&mRecordFormat, kBufferDurationSeconds);   // enough bytes for 20 ms
    for (i = 0; i < kNumberRecordBuffers; ++i) {
        XThrowIfError(AudioQueueAllocateBuffer(mQueue, bufferByteSize, &mBuffers[i]),
                   "AudioQueueAllocateBuffer failed");
        XThrowIfError(AudioQueueEnqueueBuffer(mQueue, mBuffers[i], 0, NULL),
                   "AudioQueueEnqueueBuffer failed");
    }

Да, вы догадались, большая часть кода ссылается на пример SpeakHere. Когда дело доходит до AudioCallback, мне нужно захватить буфер и отправить его на другой компьютер через сокет,

// ____________________________________________________________________________________
// AudioQueue callback function, called when an input buffers has been filled.
void AQRecorder::MyInputBufferHandler(  void *                              inUserData,
                                        AudioQueueRef                       inAQ,
                                        AudioQueueBufferRef                 inBuffer,
                                        const AudioTimeStamp *              inStartTime,
                                        UInt32                              inNumPackets,
                                        const AudioStreamPacketDescription* inPacketDesc)
{
    AQRecorder *aqr = (AQRecorder *)inUserData;
    try {
           NSLog([NSString stringWithFormat:"Inside AudioBufferCallback no of packet [%d]",inMumPackets]);
        if (inNumPackets > 0) {
            // write packets to file 
                    // This is only for the test 
            XThrowIfError(AudioFileWritePackets(aqr->mRecordFile, FALSE, inBuffer->mAudioDataByteSize,
                                              inPacketDesc, aqr->mRecordPacket, &inNumPackets, inBuffer->mAudioData),
                       "AudioFileWritePackets failed");
            aqr->mRecordPacket += inNumPackets;

            if(aqr->pInputListener){
                aqr->pInputListener(aqr->pClientUserData,inBuffer->mAudioData,(int)inBuffer->mAudioDataByteSize);
            }
        }

        // if we're not stopping, re-enqueue the buffe so that it gets filled again
        if (aqr->IsRunning())
            XThrowIfError(AudioQueueEnqueueBuffer(inAQ, inBuffer, 0, NULL), "AudioQueueEnqueueBuffer failed");
    } 
}

Теперь, когда я вижуЖурнал, данные поступают, но он говорит, что нет пакетов 256, 320, например, когда я передаю данные на другом конце, он не слышен, Может кто-нибудь сказать мне, что мне нужно делать с размером пакета, я былпод впечатлением, что bufferSize достаточно для отправки данных, но я думаю, что-то имеет отношение и к числу пакетов.

1 Ответ

0 голосов
/ 08 июня 2011

Некоторая проблема в управлении буфером, Это приложение должно отправлять данные за 20 мс + - 5 мс возможно, в моем случае этот конкретный случай не был обработан.

...