2011-06-02 50 views
1

我使用AUdioQueue从内置麦克风录制音频并通过套接字发送,我已经设置了AudioQueue缓冲区来记录缓冲区,例如30秒的缓冲区,并适当分配bufferSize , 这是我用来设置AudioDataFormat的功能。AudioQueue如何从回调中读取缓冲区

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这样的,当我在另一端传递数据,它不发声,谁能告诉我,什么我是否需要使用packetSize,我在缓冲区大小的印象下足以发送数据,但我想,也有一些与数据包数量有关。

+0

在回调中,我也在文件中写入数据,该部分工作正常,只有问题是我不明白,如何使用数据包信息。 – Amitg2k12 2011-06-02 14:14:08

回答

0

缓冲区管理中的一些问题, 该应用程序需要在20 ms + - 5 ms内发送数据,在我的情况下,这个特殊情况没有被处理。