// Simple example program that records using an audio queue, // prints the value of one sample from each buffer recorded, // and attempts to stop and restart the recording every two // seconds. // // This can be built from the command line with // // g++ rectest.cc -framework CoreFoundation -framework AudioToolbox -framework CoreAudio -o rectest // #include #include #include static const int kNumberBuffers = 3; struct AQRecorderState { AudioQueueRef mQueue; AudioQueueBufferRef mBuffers[kNumberBuffers]; UInt32 bufferByteSize; SInt64 mCurrentPacket; bool mIsRunning; }; static void HandleInputBuffer(void *aqData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer, const AudioTimeStamp *inStartTime, UInt32 inNumPackets, const AudioStreamPacketDescription *inPacketDesc) { AQRecorderState *pAqData = (AQRecorderState *) aqData; // Print the first sample only printf("%f\n", *((float *) inBuffer->mAudioData)); AudioQueueEnqueueBuffer(pAqData->mQueue, inBuffer, 0, NULL); } bool toggle = false; // Timer callback to toggle recording on and off void tick(CFRunLoopTimerRef timer, void *info) { AQRecorderState *aqs = (AQRecorderState *) info; printf("*** tick ***\n"); if (toggle) { printf("starting audio queue\n"); AudioQueueStart(aqs->mQueue, NULL); } else { printf("stopping audio queue\n"); AudioQueueStop(aqs->mQueue, TRUE); } toggle = ! toggle; } void do_record() { AQRecorderState aqData; AudioStreamBasicDescription df; df.mFormatID = kAudioFormatLinearPCM; df.mSampleRate = 48000.0; df.mChannelsPerFrame = 1; // Mono df.mBitsPerChannel = 32; df.mBytesPerPacket = df.mBytesPerFrame = df.mChannelsPerFrame * sizeof(AudioSampleType); df.mFramesPerPacket = 1; df.mFormatFlags = kAudioFormatFlagsCanonical; AudioQueueNewInput(&df, HandleInputBuffer, &aqData, NULL, // Use internal thread kCFRunLoopCommonModes, 0, // Reserved, must be 0 &aqData.mQueue); // 1/8 second aqData.bufferByteSize = 24000; for (int i = 0; i < kNumberBuffers; ++i) { AudioQueueAllocateBuffer(aqData.mQueue, aqData.bufferByteSize, &aqData.mBuffers[i]); AudioQueueEnqueueBuffer(aqData.mQueue, aqData.mBuffers[i], 0, NULL); } aqData.mCurrentPacket = 0; aqData.mIsRunning = true; // Set up a timer ticking once every 2 seconds to // toggle recording on and off. CFRunLoopTimerContext ctx; ctx.version = 0; ctx.info = &aqData; ctx.retain = NULL; ctx.release = NULL; ctx.copyDescription = NULL; CFRunLoopTimerRef timer = CFRunLoopTimerCreate (NULL, CFAbsoluteTimeGetCurrent() + 2.0, 2.0, 0, 0, tick, &ctx); CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, kCFRunLoopCommonModes); AudioQueueStart(aqData.mQueue, NULL); CFRunLoopRun(); AudioQueueStop(aqData.mQueue, true); aqData.mIsRunning = false; AudioQueueDispose (aqData.mQueue, true); } int main(int argc, char **argv) { do_record(); return 0; }