Beispiel #1
0
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;
}
Beispiel #4
0
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);
}
Beispiel #5
0
/*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;
}
Beispiel #6
0
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 );
}
Beispiel #7
0
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, &timestamp, 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);
}
Beispiel #10
0
		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;
		}
Beispiel #11
0
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;
            }
        }
    }
}
Beispiel #12
0
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;
}
Beispiel #14
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 */
Beispiel #15
0
static void
gst_atdec_buffer_emptied (void *user_data, AudioQueueRef queue,
    AudioQueueBufferRef buffer)
{
  AudioQueueFreeBuffer (queue, buffer);
}