0

I am trying to record the audio in segment of 40ms. Audio Queue Interface can deal with 40ms Audio Frame? If 'Yes' then how can we achieve it?

Thanks.

Till
  • 27,559
  • 13
  • 88
  • 122
Pravin
  • 1
  • 2

1 Answers1

0

yes, its possible , you need to set configure AudioQueue Accordingly,

Basically the AudioQueue Buffer size, has to be set for 40ms, so it would be around,

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];
        return 0;
    }   
    return bytes;
}

and to set the format,

void AQRecorder::SetupAudioFormat(UInt32 inFormatID)
{
    AudioStreamBasicDescription sRecordFormat;
    FillOutASBDForLPCM (sRecordFormat,
                        SAMPLING_RATE,
                        1,
                        8*BYTES_PER_PACKET,
                        8*BYTES_PER_PACKET,
                        false,
                        false
                        );
    memset(&mRecordFormat, 0, sizeof(mRecordFormat));

    mRecordFormat.SetFrom(sRecordFormat);
}

for my case, values of these Macros are,

#define SAMPLING_RATE 16000
#define kNumberRecordBuffers    3
#define BYTES_PER_PACKET 2
Amitg2k12
  • 3,765
  • 10
  • 48
  • 97
  • Hi Rohan, Thanks for your response, I have changed the project accordingly and it's working at my end. As I am new to this field, How can I make sure that it is working at 40ms audio frame per packet? Thanks, Pravin – Pravin Feb 28 '13 at 10:01
  • AudioQueue framework, throws a callback when the enqueued buffer is filled, so the minimum interval would be 40ms for sure... – Amitg2k12 Mar 01 '13 at 16:03
  • Thanks Rohan, Can you please give me idea (formula) about 40ms audio frame per packet calculation with respect to Macros/Define i.e. SAMPLING_RATE, kNumberRecordBuffers, BYTES_PER_PACKET – Pravin Mar 13 '13 at 11:30
  • in the above function just pass float secods = .04 – Amitg2k12 Mar 13 '13 at 12:36
  • @Amitg2k12 where and how to pass and use float secods = .04 – Naresh Aug 22 '13 at 05:22
  • 1
    @Naresh in the function AQRecorder::ComputeRecordBufferSize(const AudioStreamBasicDescription *format, float seconds) , 2nd parameter should be .04 – Amitg2k12 Sep 06 '13 at 06:57
  • Hello, currently I used this function to compute the buffer size for 30ms, sample rate 8000 and 16 bits, and I get 480 for the buffer size. It's correct. But I will get many callback to fill in the buffer with 30 ms? Why? Why not just one buffer within 30 ms? Thanks – Ecroo Jul 03 '15 at 05:51
  • @ Ecro : AudioQueue callback will hit asynchronously to get the buffer as and when audio queue needed, normally audioQueue request once in a while for most of time, – Amitg2k12 Jul 08 '15 at 13:41