void AudioEnginePropertyListenerProc (void *inUserData, AudioQueueRef inAQ, AudioQueuePropertyID inID) { //We are only interested in the property kAudioQueueProperty_IsRunning if (inID != kAudioQueueProperty_IsRunning) return; struct myAQStruct *myInfo = (struct myAQStruct *)inUserData; /* Get the current status of the AQ, running or stopped */ UInt32 isQueueRunning = false; UInt32 size = sizeof(isQueueRunning); AudioQueueGetProperty(myInfo->mQueue, kAudioQueueProperty_IsRunning, &isQueueRunning, &size); /* The callback event is the start of the queue */ if (isQueueRunning) { /* reset current packet counter */ myInfo->mCurrentPacket = 0; for (int i = 0; i < 3; i++) { /* * For the first time allocate buffers for this AQ. * Buffers are reused in turns until the AQ stops */ AudioQueueAllocateBuffer(myInfo->mQueue, bufferSizeInSamples * 4, &myInfo->mBuffers[i]); UInt32 bytesRead = bufferSizeInSamples * 4; UInt32 packetsRead = bufferSizeInSamples; /* * Read data from audio source into the buffer of AQ * supplied in this callback event. Buffers are used in turns * to hide the latency */ AudioFileReadPacketData( myInfo->mAudioFile, false, /* isUseCache, set to false */ &bytesRead, NULL, myInfo->mCurrentPacket, &packetsRead, myInfo->mBuffers[i]->mAudioData); /* in case the buffer size is smaller than bytes requestd to read */ myInfo->mBuffers[i]->mAudioDataByteSize = bytesRead; myInfo->mCurrentPacket += packetsRead; AudioQueueEnqueueBuffer(myInfo->mQueue, myInfo->mBuffers[i], 0, NULL); } } else { /* The callback event is the state of AQ changed to not running */ if (myInfo->mAudioFile != NULL) { AudioQueueStop(myInfo->mQueue, false); AudioFileClose(myInfo->mAudioFile); myInfo->mAudioFile = NULL; for (int i = 0; i < 3; i++) { AudioQueueFreeBuffer(myInfo->mQueue, myInfo->mBuffers[i]); myInfo->mBuffers[i] = NULL; } CFRunLoopStop(CFRunLoopGetCurrent()); } } }
/* destructor */ static tsk_object_t* tdav_consumer_audioqueue_dtor(tsk_object_t * self) { tdav_consumer_audioqueue_t *consumer = self; if(consumer){ // Stop the consumer if not done if(consumer->started){ tdav_consumer_audioqueue_stop(self); } // Free all buffers and dispose the queue if (consumer->queue) { tsk_size_t i; for(i=0; i<CoreAudioPlayBuffers; i++){ AudioQueueFreeBuffer(consumer->queue, consumer->buffers[i]); } AudioQueueDispose(consumer->queue, true); } /* deinit base */ tdav_consumer_audio_deinit(TDAV_CONSUMER_AUDIO(consumer)); } return self; }
/* destructor */ static tsk_object_t* tdav_producer_audioqueue_dtor(tsk_object_t * self) { tdav_producer_audioqueue_t *producer = self; if(producer){ // Stop the producer if not done if(producer->started){ tdav_producer_audioqueue_stop(self); } // Free all buffers and dispose the queue if (producer->queue) { tsk_size_t i; for(i=0; i<CoreAudioRecordBuffers; i++){ AudioQueueFreeBuffer(producer->queue, producer->buffers[i]); } AudioQueueDispose(producer->queue, true); } /* deinit base */ tdav_producer_audio_deinit(TDAV_PRODUCER_AUDIO(producer)); } return self; }
static void auplay_destructor(void *arg) { struct auplay_st *st = arg; uint32_t i; pthread_mutex_lock(&st->mutex); st->wh = NULL; pthread_mutex_unlock(&st->mutex); audio_session_disable(); if (st->queue) { AudioQueuePause(st->queue); AudioQueueStop(st->queue, true); for (i=0; i<ARRAY_SIZE(st->buf); i++) if (st->buf[i]) AudioQueueFreeBuffer(st->queue, st->buf[i]); AudioQueueDispose(st->queue, true); } mem_deref(st->ap); pthread_mutex_destroy(&st->mutex); }
/*auDestroy-----------------------------------------------*/ Audio* auDestroy(Audio* self) { if(self != NULL) { if(self->isPlaying) auPause(self); #if defined __APPLE__ int i; for(i=0; i<AU_NUM_AUDIO_BUFFERS; i++) if(self->buffers[i] != NULL) AudioQueueFreeBuffer(self->queue, self->buffers[i]); if(self->queue != NULL) AudioQueueDispose(self->queue, YES); #elif defined __linux__ if(self->device != NULL) { snd_pcm_close(self->device); self->device = NULL; } if(self->sampleBuffer) free(self->sampleBuffer); //if(self->thread != NULL) //pthread_detach(self->thread); #endif free(self); } return (Audio*)NULL; }
OSStatus darwin_free_context ( darwin_context* io_context ) { OSStatus result = kAudio_ParamError; if( NULL != io_context ) { CPC_LOG_STRING( CPC_LOG_LEVEL_DEBUG, "Stopping audio queue..." ); result = AudioQueueStop( io_context->audio_queue, true ); CPC_LOG_STRING( CPC_LOG_LEVEL_DEBUG, "Stopped audio queue." ); if( noErr == result ) { for( UINT32 i = 0; i < io_context->number_of_buffers; i++ ) { if( NULL != io_context->audio_buffers[ i ] ) { result = AudioQueueFreeBuffer ( io_context->audio_queue, io_context->audio_buffers[ i ] ); if( result ) { CPC_ERROR ( "Could not free queue buffer: 0x%x.", result ); CPC_PRINT_CODE( CPC_LOG_LEVEL_ERROR, result ); } } } result = AudioQueueDispose( io_context->audio_queue, true ); if( result ) { CPC_ERROR( "Could not dispose of queue: 0x%x.", result ); CPC_PRINT_CODE( CPC_LOG_LEVEL_ERROR, result ); } } else { CPC_ERROR( "Could not stop audio queue: 0x%x.", result ); CPC_PRINT_CODE( CPC_LOG_LEVEL_ERROR, result ); } } return( result ); }
static GstFlowReturn gst_atdec_handle_frame (GstAudioDecoder * decoder, GstBuffer * buffer) { AudioTimeStamp timestamp = { 0 }; AudioStreamPacketDescription packet; AudioQueueBufferRef input_buffer, output_buffer; GstBuffer *out; GstMapInfo info; GstAudioInfo *audio_info; int size, out_frames; GstFlowReturn flow_ret = GST_FLOW_OK; GstATDec *atdec = GST_ATDEC (decoder); if (buffer == NULL) return GST_FLOW_OK; audio_info = gst_audio_decoder_get_audio_info (decoder); /* copy the input buffer into an AudioQueueBuffer */ size = gst_buffer_get_size (buffer); AudioQueueAllocateBuffer (atdec->queue, size, &input_buffer); gst_buffer_extract (buffer, 0, input_buffer->mAudioData, size); input_buffer->mAudioDataByteSize = size; /* assume framed input */ packet.mStartOffset = 0; packet.mVariableFramesInPacket = 1; packet.mDataByteSize = size; /* enqueue the buffer. It will get free'd once the gst_atdec_buffer_emptied * callback is called */ AudioQueueEnqueueBuffer (atdec->queue, input_buffer, 1, &packet); /* figure out how many frames we need to pull out of the queue */ out_frames = GST_CLOCK_TIME_TO_FRAMES (GST_BUFFER_DURATION (buffer), audio_info->rate); size = out_frames * audio_info->bpf; AudioQueueAllocateBuffer (atdec->queue, size, &output_buffer); /* pull the frames */ AudioQueueOfflineRender (atdec->queue, ×tamp, output_buffer, out_frames); if (output_buffer->mAudioDataByteSize) { out = gst_audio_decoder_allocate_output_buffer (decoder, output_buffer->mAudioDataByteSize); gst_buffer_map (out, &info, GST_MAP_WRITE); memcpy (info.data, output_buffer->mAudioData, output_buffer->mAudioDataByteSize); gst_buffer_unmap (out, &info); flow_ret = gst_audio_decoder_finish_frame (decoder, out, 1); } AudioQueueFreeBuffer (atdec->queue, output_buffer); return flow_ret; }
long AudioStreamDecoder::Stop() { long err = 0; if (mStream) { err = AudioFileStreamClose(mStream); CARP_IF(err, "AudioFileStreamClose returned %ld\n", err); mStream = NULL; } if (mStarted) { err = AudioQueueFlush(mQueue); BAIL_IF(err, "AudioQueueFlush returned %ld\n", err); err = AudioQueueStop(mQueue, true); BAIL_IF(err, "AudioQueueStop returned %ld\n", err); err = pthread_mutex_lock(&mMutex); BAIL_IF(err, "pthread_mutex_lock returned %ld\n", err); if (!mFinished) { err = pthread_cond_wait(&mCond, &mMutex); BAIL_IF(err, "pthread_cond_wait returned %ld\n", err); } err = pthread_mutex_unlock(&mMutex); BAIL_IF(err, "pthread_mutex_unlock returned %ld\n", err); mStarted = false; mFinished = false; } if (mQueue) { for (int i = 0; i < kBufferCount; i++) { if (mBuffers[i]) { err = AudioQueueFreeBuffer(mQueue, mBuffers[i]); CARP_IF(err, "AudioQueueFreeBuffer returned %ld\n", err); } } err = AudioQueueDispose(mQueue, true); CARP_IF(err, "AudioQueueDispose returned %ld\n", err); mQueue = NULL; } bail: return err; }
/** @internal @This is called by AudioQueue after reading a buffer * @param _upipe description structure of the pipe (void) * @param queue AudioQueue * @param qbuf AudioQueue buffer */ static void upipe_osx_audioqueue_sink_cb(void *_upipe, AudioQueueRef queue, struct AudioQueueBuffer *qbuf) { /* TODO uncblock ? */ #if 0 struct upump_mgr *upump_mgr = qbuf->mUserData; upump_mgr_sink_unblock(upump_mgr); upump_mgr_release(upump_mgr); #endif AudioQueueFreeBuffer(queue, qbuf); }
static Boolean DisposeBuffer(AudioQueueRef inAQ, std::vector<AudioQueueBufferRef> inDisposeBufferList, AudioQueueBufferRef inBufferToDispose) { for (unsigned int i=0; i < inDisposeBufferList.size(); i++) { if (inBufferToDispose == inDisposeBufferList[i]) { OSStatus result = AudioQueueFreeBuffer(inAQ, inBufferToDispose); if (result == noErr) inDisposeBufferList.pop_back(); return true; } } return false; }
void clear_buffers() { if (d_owner->need_release && d_owner->queue) { for (core::vector<AudioQueueBufferRef>::iterator each = buffers.begin(); each != buffers.end(); ++each) { if (*each != NULL) { AudioQueueFreeBuffer(d_owner->queue, *each); *each = NULL; } } } }
void dealloc() { # ifdef NNT_MACH if (d_owner->need_release) { for (core::vector<AudioQueueBufferRef>::iterator each = buffers.begin(); each != buffers.end(); ++each) { AudioQueueFreeBuffer(d_owner->queue, *each); } } # endif }
u32 AudioPluginOSX::AudioThread(void * arg) { AudioPluginOSX * plugin = static_cast<AudioPluginOSX *>(arg); AudioStreamBasicDescription format; format.mSampleRate = kOutputFrequency; format.mFormatID = kAudioFormatLinearPCM; format.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked; format.mBitsPerChannel = 8 * sizeof(s16); format.mChannelsPerFrame = kNumChannels; format.mBytesPerFrame = sizeof(s16) * kNumChannels; format.mFramesPerPacket = 1; format.mBytesPerPacket = format.mBytesPerFrame * format.mFramesPerPacket; format.mReserved = 0; AudioQueueRef queue; AudioQueueBufferRef buffers[kNumBuffers]; AudioQueueNewOutput(&format, &AudioCallback, plugin, CFRunLoopGetCurrent(), kCFRunLoopCommonModes, 0, &queue); for (u32 i = 0; i < kNumBuffers; ++i) { AudioQueueAllocateBuffer(queue, kAudioQueueBufferLength, &buffers[i]); buffers[i]->mAudioDataByteSize = kAudioQueueBufferLength; AudioCallback(plugin, queue, buffers[i]); } AudioQueueStart(queue, NULL); CFRunLoopRun(); AudioQueueStop(queue, false); AudioQueueDispose(queue, false); for (u32 i = 0; i < kNumBuffers; ++i) { AudioQueueFreeBuffer(queue, buffers[i]); buffers[i] = NULL; } return 0; }
static void macosx_play (int argc, char *argv []) { MacOSXAudioData audio_data ; OSStatus err ; int i ; int k ; memset (&audio_data, 0x55, sizeof (audio_data)) ; for (k = 1 ; k < argc ; k++) { memset (&(audio_data.sfinfo), 0, sizeof (audio_data.sfinfo)) ; printf ("Playing %s\n", argv [k]) ; if (! (audio_data.sndfile = sf_open (argv [k], SFM_READ, &(audio_data.sfinfo)))) { puts (sf_strerror (NULL)) ; continue ; } ; if (audio_data.sfinfo.channels < 1 || audio_data.sfinfo.channels > 2) { printf ("Error : channels = %d.\n", audio_data.sfinfo.channels) ; continue ; } ; /* fill ASBD */ audio_data.format.mSampleRate = audio_data.sfinfo.samplerate ; audio_data.format.mChannelsPerFrame = audio_data.sfinfo.channels ; audio_data.format.mFormatID = kAudioFormatLinearPCM ; audio_data.format.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked ; audio_data.format.mBytesPerPacket = audio_data.format.mChannelsPerFrame * 2 ; audio_data.format.mFramesPerPacket = 1 ; audio_data.format.mBytesPerFrame = audio_data.format.mBytesPerPacket ; audio_data.format.mBitsPerChannel = 16 ; audio_data.format.mReserved = 0 ; /* create the queue */ if ((err = AudioQueueNewOutput (&(audio_data.format), macosx_audio_out_callback, &audio_data, CFRunLoopGetCurrent (), kCFRunLoopCommonModes, 0, &(audio_data.queue))) != noErr) { printf ("AudioQueueNewOutput failed\n") ; return ; } ; /* add property listener */ if ((err = AudioQueueAddPropertyListener (audio_data.queue, kAudioQueueProperty_IsRunning, macosx_audio_out_property_callback, &audio_data)) != noErr) { printf ("AudioQueueAddPropertyListener failed\n") ; return ; } ; /* create the buffers */ for (i = 0 ; i < kNumberOfAudioBuffers ; i++) { if ((err = AudioQueueAllocateBuffer (audio_data.queue, kBytesPerAudioBuffer, &audio_data.queueBuffer [i])) != noErr) { printf ("AudioQueueAllocateBuffer failed\n") ; return ; } ; macosx_fill_buffer (&audio_data, audio_data.queueBuffer [i]) ; } ; audio_data.done_playing = SF_FALSE ; /* start queue */ if ((err = AudioQueueStart (audio_data.queue, NULL)) != noErr) { printf ("AudioQueueStart failed\n") ; return ; } ; while (audio_data.done_playing == SF_FALSE) CFRunLoopRun () ; /* free the buffers */ for (i = 0 ; i < kNumberOfAudioBuffers ; i++) { if ((err = AudioQueueFreeBuffer (audio_data.queue, audio_data.queueBuffer [i])) != noErr) { printf ("AudioQueueFreeBuffer failed\n") ; return ; } ; } ; /* free the queue */ if ((err = AudioQueueDispose (audio_data.queue, true)) != noErr) { printf ("AudioQueueDispose failed\n") ; return ; } ; sf_close (audio_data.sndfile) ; } ; return ; } /* macosx_play, AudioQueue implementation */
static void gst_atdec_buffer_emptied (void *user_data, AudioQueueRef queue, AudioQueueBufferRef buffer) { AudioQueueFreeBuffer (queue, buffer); }