Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get array of float audio data from AudioQueueRef in iOS?

I'm working on getting audio into the iPhone in a form where I can pass it to a (C++) analysis algorithm. There are, of course, many options: the AudioQueue tutorial at trailsinthesand gets things started.

The audio callback, though, gives an AudioQueueRef, and I'm finding Apple's documentation thin on this side of things. Built-in methods to write to a file, but nothing where you actually peer inside the packets to see the data.

I need data. I don't want to write anything to a file, which is what all the tutorials — and even Apple's convenience I/O objects — seem to be aiming at. Apple's AVAudioRecorder (infuriatingly) will give you levels and write the data, but not actually give you access to it. Unless I'm missing something...

How to do this? In the code below there is inBuffer->mAudioData which is tantalizingly close but I can find no information about what format this 'data' is in or how to access it.

AudioQueue Callback:

void AudioInputCallback(void *inUserData,
    AudioQueueRef inAQ,
    AudioQueueBufferRef inBuffer,
    const AudioTimeStamp *inStartTime,
    UInt32 inNumberPacketDescriptions,
    const AudioStreamPacketDescription *inPacketDescs)
{
    static int count = 0;
    RecordState* recordState = (RecordState*)inUserData;    
    AudioQueueEnqueueBuffer(recordState->queue, inBuffer, 0, NULL);

    ++count;
    printf("Got buffer %d\n", count);
}

And the code to write the audio to a file:

OSStatus status = AudioFileWritePackets(recordState->audioFile,
                false,
                inBuffer->mAudioDataByteSize,
                inPacketDescs,
                recordState->currentPacket,
                &inNumberPacketDescriptions,
                inBuffer->mAudioData); // THIS! This is what I want to look inside of.
if(status == 0)
{
     recordState->currentPacket += inNumberPacketDescriptions;
}
like image 966
buildsucceeded Avatar asked Oct 24 '11 19:10

buildsucceeded


1 Answers

  // so you don't have to hunt them all down when you decide to switch to float: 
  #define AUDIO_DATA_TYPE_FORMAT SInt16

  // the actual sample-grabbing code:
  int sampleCount = inBuffer->mAudioDataBytesCapacity / sizeof(AUDIO_DATA_TYPE_FORMAT);
  AUDIO_DATA_TYPE_FORMAT *samples = (AUDIO_DATA_TYPE_FORMAT*)inBuffer->mAudioData;

Then you have your (in this case SInt16) array samples which you can access from samples[0] to samples[sampleCount-1].

like image 147
buildsucceeded Avatar answered Oct 24 '22 11:10

buildsucceeded