Beispiel #1
0
static void record_handler(void *userData, AudioQueueRef inQ,
			   AudioQueueBufferRef inQB,
			   const AudioTimeStamp *inStartTime,
			   UInt32 inNumPackets,
			   const AudioStreamPacketDescription *inPacketDesc)
{
	struct ausrc_st *st = userData;
	unsigned int ptime;
	ausrc_read_h *rh;
	void *arg;
	(void)inStartTime;
	(void)inNumPackets;
	(void)inPacketDesc;

	pthread_mutex_lock(&st->mutex);
	ptime = st->ptime;
	rh  = st->rh;
	arg = st->arg;
	pthread_mutex_unlock(&st->mutex);

	if (!rh)
		return;

	rh(inQB->mAudioData, inQB->mAudioDataByteSize/2, arg);

	AudioQueueEnqueueBuffer(inQ, inQB, 0, NULL);

	/* Force a sleep here, coreaudio's timing is too fast */
#if !TARGET_OS_IPHONE
#define ENCODE_TIME 1000
	usleep((ptime * 1000) - ENCODE_TIME);
#endif
}
Beispiel #2
0
bool Device::add(audio::Buffer &buf)
{
# ifdef NNT_MACH
    
    int suc = 0;
    for (core::vector<AudioQueueBufferRef>::iterator each = buf.handle().begin();
         each != buf.handle().end();
         ++each)
    {
        OSStatus sta = AudioQueueEnqueueBuffer(buf.queue, *each, 0, NULL);
        if (sta)
        {
            trace_msg("failed to add audio buffer");
        }
        else
        {
            ++suc;
        }
    }
    
    // if success, the buffer will freed when dispose the queue.
    buf.need_release = suc == 0;
    
    return suc != 0;
    
# endif
    return false;
}
Beispiel #3
0
void  auAudioOutputCallback(void *SELF, AudioQueueRef queue, AudioQueueBufferRef buffer)
{
  Audio* self = (Audio*) SELF;
  int resultFrames = self->audioCallback(SELF, (auSample_t*)buffer->mAudioData, (buffer->mAudioDataBytesCapacity / self->dataFormat.mBytesPerFrame), self->dataFormat.mChannelsPerFrame);
  buffer->mAudioDataByteSize = resultFrames * self->dataFormat.mBytesPerFrame;//buffer->mAudioDataBytesCapacity;
  AudioQueueEnqueueBuffer(queue, buffer, 0, NULL);
}
Beispiel #4
0
/*auStart-------------------------------------------------*/
BOOL auPlay(Audio* self)
{ 
  if(!self->isPlaying)
    {

#ifdef __APPLE__
      int i;
      for(i=0; i<AU_NUM_AUDIO_BUFFERS; i++)
        {
          if(self->isOutput)
            auAudioOutputCallback(self, self->queue, self->buffers[i]);
          else
            AudioQueueEnqueueBuffer(self->queue, self->buffers[i],0, NULL);
        }
      OSStatus error = AudioQueueStart(self->queue, NULL);
      if(error) fprintf(stderr, "Audio.c: unable to start queue\n");

#elif defined __linux__
      int error = pthread_create(&(self->thread), NULL, auAudioCallback, self);
      if(error != 0) perror("Audio.c: error creating Audio thread");

#endif
      else self->isPlaying = YES;
    }
    
  return self->isPlaying;
}
// Audio Queue callback function, called when an input buffer has been filled.
static void MyAQInputCallback(void *inUserData, AudioQueueRef inQueue,
							  AudioQueueBufferRef inBuffer,
							  const AudioTimeStamp *inStartTime,
							  UInt32 inNumPackets,
							  const AudioStreamPacketDescription *inPacketDesc)
{
	MyRecorder *recorder = (MyRecorder *)inUserData;
	
	// if inNumPackets is greater then zero, our buffer contains audio data
	// in the format we specified (AAC)
	if (inNumPackets > 0)
	{
		// write packets to file
		CheckError(AudioFileWritePackets(recorder->recordFile, FALSE, inBuffer->mAudioDataByteSize,
										 inPacketDesc, recorder->recordPacket, &inNumPackets, 
										 inBuffer->mAudioData), "AudioFileWritePackets failed");
		// increment packet index
		recorder->recordPacket += inNumPackets;
	}
	
	// if we're not stopping, re-enqueue the buffer so that it gets filled again
	if (recorder->running)
		CheckError(AudioQueueEnqueueBuffer(inQueue, inBuffer,
										   0, NULL), "AudioQueueEnqueueBuffer failed");
}
void CAudioQueueManager::_HandleOutputBuffer(AudioQueueBufferRef outBuffer) {
	if (!_isRunning || _soundQBuffer.SoundCount() == 0) {
		outBuffer->mAudioDataByteSize = outBuffer->mAudioDataBytesCapacity;
        bzero(outBuffer->mAudioData, outBuffer->mAudioDataBytesCapacity);
	} else {
		
		int neededFrames = _framesPerBuffer;
		unsigned char* buf = (unsigned char*)outBuffer->mAudioData;
		int bytesInBuffer = 0;

		for ( ; _soundQBuffer.SoundCount() && neededFrames; neededFrames--) {
			short* buffer = _soundQBuffer.DequeueSoundBuffer();
			memcpy(buf, buffer, _bytesPerQueueBuffer);
			_soundQBuffer.EnqueueFreeBuffer(buffer);
			OSAtomicAdd32(-_sampleFrameCount, &_samplesInQueue);
			buf += _bytesPerQueueBuffer;
			bytesInBuffer += _bytesPerQueueBuffer;
		}
		
		outBuffer->mAudioDataByteSize = bytesInBuffer;
#if defined(DEBUG_SOUND)
		if (outBuffer->mAudioDataByteSize == 0)
			printf("audio buffer underrun.");
		else if (outBuffer->mAudioDataByteSize < outBuffer->mAudioDataBytesCapacity) 
			printf("audio buffer less than capacity %u < %u.", (unsigned int)outBuffer->mAudioDataByteSize, (unsigned int)outBuffer->mAudioDataBytesCapacity);
#endif
	}
	
	OSStatus res = AudioQueueEnqueueBuffer(_queue, outBuffer, 0, NULL);
	if (res != 0)
		throw "Unable to enqueue buffer";
}
/** @internal @This handles audio input.
 *
 * @param upipe description structure of the pipe
 * @param uref uref structure
 * @param upump_p reference to upump structure
 */
static void upipe_osx_audioqueue_sink_input_audio(struct upipe *upipe,
        struct uref *uref, struct upump **upump_p)
{
    struct upipe_osx_audioqueue_sink *osx_audioqueue =
        upipe_osx_audioqueue_sink_from_upipe(upipe);
    struct AudioQueueBuffer *qbuf;
    size_t size = 0;

    if (unlikely(!ubase_check(uref_block_size(uref, &size)))) {
        upipe_warn(upipe, "could not get block size");
        uref_free(uref);
        return;
    }

    /* TODO block ? */
#if 0
    upump_mgr_use(upump->mgr);
    upump_mgr_sink_block(upump->mgr);
#endif

    /* allocate queue buf, extract block, enqueue
     * Audioqueue has no support for "external" buffers */
    AudioQueueAllocateBuffer(osx_audioqueue->queue, size, &qbuf);
    uref_block_extract(uref, 0, -1, qbuf->mAudioData);
    qbuf->mAudioDataByteSize = size;
    qbuf->mUserData = (*upump_p)->mgr;
    AudioQueueEnqueueBuffer(osx_audioqueue->queue, qbuf, 0, NULL);

    uref_free(uref);
}
void AudioPluginOSX::AudioCallback(void * arg, AudioQueueRef queue, AudioQueueBufferRef buffer)
{

	AudioPluginOSX * plugin = static_cast<AudioPluginOSX *>(arg);

	u32 num_samples     = buffer->mAudioDataBytesCapacity / sizeof(Sample);
	u32 samples_written = plugin->mAudioBuffer.Drain(static_cast<Sample *>(buffer->mAudioData), num_samples);

	u32 remaining_samples = plugin->mAudioBuffer.GetNumBufferedSamples();
	plugin->mBufferLenMs = (1000 * remaining_samples) / kOutputFrequency;

	float ms = (float)samples_written * 1000.f / (float)kOutputFrequency;
	DPF_AUDIO("Playing %d samples @%dHz - %.2fms - bufferlen now %d\n",
			samples_written, kOutputFrequency, ms, plugin->mBufferLenMs);

	if (samples_written == 0)
	{
		// Would be nice to sleep here until we have something to play,
		// but AudioQueue doesn't seem to like that.
		// Leave the buffer untouched, and requeue for now.
		DPF_AUDIO("********************* Audio buffer is empty ***********************\n");
	}
	else
	{
		buffer->mAudioDataByteSize = samples_written * sizeof(Sample);
	}

	AudioQueueEnqueueBuffer(queue, buffer, 0, NULL);

	if (!plugin->mKeepRunning)
	{
		CFRunLoopStop(CFRunLoopGetCurrent());
	}

}
Beispiel #9
0
void AudioQueueCallback(void * inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer) {
    audio_output_t * p_aout = (audio_output_t *)inUserData;
    block_t *   p_buffer = NULL;

    if (p_aout) {
        struct aout_sys_t * p_sys = p_aout->sys;
        aout_packet_t * packet = &p_sys->packet;

        if (packet)
        {
            vlc_mutex_lock( &packet->lock );
            p_buffer = aout_FifoPop2( &packet->fifo );
            vlc_mutex_unlock( &packet->lock );
        }
    }

    if ( p_buffer != NULL ) {
        memcpy( inBuffer->mAudioData, p_buffer->p_buffer, p_buffer->i_buffer );
        inBuffer->mAudioDataByteSize = p_buffer->i_buffer;
        block_Release( p_buffer );
    } else {
        memset( inBuffer->mAudioData, 0, inBuffer->mAudioDataBytesCapacity );
        inBuffer->mAudioDataByteSize = inBuffer->mAudioDataBytesCapacity;
    }
    AudioQueueEnqueueBuffer(inAQ, inBuffer, 0, NULL);
}
static void MyAQOutputCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inCompleteAQBuffer) 
{
	MyPlayer *aqp = (MyPlayer*)inUserData;
	if (aqp->isDone) return;
	
	// read audio data from file into supplied buffer
	UInt32 numBytes;
	UInt32 nPackets = aqp->numPacketsToRead;	
	CheckError(AudioFileReadPackets(aqp->playbackFile,
									false,
									&numBytes,
									aqp->packetDescs,
									aqp->packetPosition,
									&nPackets,
									inCompleteAQBuffer->mAudioData),
			   "AudioFileReadPackets failed");
	
	// enqueue buffer into the Audio Queue
	// if nPackets == 0 it means we are EOF (all data has been read from file)
	if (nPackets > 0)
	{
		inCompleteAQBuffer->mAudioDataByteSize = numBytes;		
		AudioQueueEnqueueBuffer(inAQ,
								inCompleteAQBuffer,
								(aqp->packetDescs ? nPackets : 0),
								aqp->packetDescs);
		aqp->packetPosition += nPackets;
	}
	else
	{
		CheckError(AudioQueueStop(inAQ, false), "AudioQueueStop failed");
		aqp->isDone = true;
	}
}
void WavPlayer::aqBufferCallback(void *in, AudioQueueRef inQ, AudioQueueBufferRef outQB)
{
    AQCallbackStruct *aqc;
    unsigned char *coreAudioBuffer;

    aqc = (AQCallbackStruct *) in;
    coreAudioBuffer = (unsigned char*) outQB->mAudioData;

    printf("Sync: %u / %u\n", (unsigned int)aqc->PlayPtr, (unsigned int)aqc->SampleLen);

    if(aqc->FrameCount > 0)
    {
        outQB->mAudioDataByteSize = aqc->DataFormat.mBytesPerFrame * aqc->FrameCount;
        for(int i = 0; i < aqc->FrameCount * aqc->DataFormat.mBytesPerFrame; i++)
        {
            if(aqc->PlayPtr > aqc->SampleLen)
            {
                aqc->PlayPtr = 0;
                i = 0;
            }
            coreAudioBuffer[i] = aqc->PCMBuffer[aqc->PlayPtr];
            aqc->PlayPtr++;
        }
        AudioQueueEnqueueBuffer(inQ, outQB, 0, NULL);
    }
}
Beispiel #12
0
// ____________________________________________________________________________________
// AudioQueue callback function, called when an input buffers has been filled.
static void MyInputBufferHandler(	void *                          inUserData,
									AudioQueueRef                   inAQ,
									AudioQueueBufferRef             inBuffer,
									const AudioTimeStamp *          inStartTime,
									UInt32							inNumPackets,
									const AudioStreamPacketDescription *inPacketDesc)
{
	MyRecorder *aqr = (MyRecorder *)inUserData;

	try {
		if (aqr->verbose) {
			printf("buf data %p, 0x%x bytes, 0x%x packets\n", inBuffer->mAudioData,
				(int)inBuffer->mAudioDataByteSize, (int)inNumPackets);
		}
		
		if (inNumPackets > 0) {
			// write packets to file
			XThrowIfError(AudioFileWritePackets(aqr->recordFile, FALSE, inBuffer->mAudioDataByteSize,
				inPacketDesc, aqr->recordPacket, &inNumPackets, inBuffer->mAudioData),
				"AudioFileWritePackets failed");
			aqr->recordPacket += inNumPackets;
		}

		// if we're not stopping, re-enqueue the buffe so that it gets filled again
		if (aqr->running)
			XThrowIfError(AudioQueueEnqueueBuffer(inAQ, inBuffer, 0, NULL), "AudioQueueEnqueueBuffer failed");
	} 
	catch (CAXException e) {
		char buf[256];
		fprintf(stderr, "MyInputBufferHandler: %s (%s)\n", e.mOperation, e.FormatError(buf));
	}	
}
    void AudioOutputDeviceCoreAudio::HandleOutputBuffer (
        void                 *aqData,
        AudioQueueRef        inAQ,
        AudioQueueBufferRef  inBuffer
    ) {
        AQPlayerState* pAqData = (AQPlayerState*) aqData;
        if (atomic_read(&(pAqData->mIsRunning)) == 0) {
            AudioQueueFlush(pAqData->mQueue);
            AudioQueueStop (pAqData->mQueue, true);
            return;
        }

        if(atomic_read(&(pAqData->pDevice->restartQueue))) return;

        uint bufferSize = pAqData->pDevice->uiBufferSize;

        // let all connected engines render 'fragmentSize' sample points
        pAqData->pDevice->RenderAudio(bufferSize);

        Float32* pDataBuf = (Float32*)(inBuffer->mAudioData);

        uint uiCoreAudioChannels = pAqData->pDevice->uiCoreAudioChannels;
        for (int c = 0; c < uiCoreAudioChannels; c++) {
            float* in  = pAqData->pDevice->Channels[c]->Buffer();
            for (int i = 0, o = c; i < bufferSize; i++ , o += uiCoreAudioChannels) {
                pDataBuf[o] = in[i];
            }
        }

        inBuffer->mAudioDataByteSize = (uiCoreAudioChannels * 4) * bufferSize;

        OSStatus res = AudioQueueEnqueueBuffer(pAqData->mQueue, inBuffer, 0, NULL);
        if(res) std::cerr << "AudioQueueEnqueueBuffer: Error " << res << std::endl;
    }
Beispiel #14
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());
        }
    }
}
Beispiel #15
0
void AQBufferCallback(void *in,
                      AudioQueueRef inQ,
                      AudioQueueBufferRef outQB) {
    AQCallbackStruct *aqc;
    short *coreAudioBuffer;
    short sample;
    int i;
    
    aqc = (AQCallbackStruct *) in;
    coreAudioBuffer = (short*) outQB->mAudioData;
    
    printf("Sync: %ld / %ld\n", aqc->playPtr, aqc->sampleLen);
    if (aqc->playPtr >= aqc->sampleLen) {
        AudioQueueDispose(aqc->queue, true);
        return;
    }
    
    if (aqc->frameCount > 0) {
        outQB->mAudioDataByteSize = 4 * aqc->frameCount;
        for(i=0; i<aqc->frameCount*2; i+=2) {
            if (aqc->playPtr > aqc->sampleLen)
                sample = 0;
            else
                sample = (aqc->pcmBuffer[aqc->playPtr]);
            coreAudioBuffer[i] =   sample;
            coreAudioBuffer[i+1] = sample;
            aqc->playPtr++;
        }
        AudioQueueEnqueueBuffer(inQ, outQB, 0, NULL);
    }
}
Beispiel #16
0
static void rdpsnd_audio_play(rdpsndDevicePlugin* device, BYTE* data, int size)
{
	rdpsndAudioQPlugin* aq_plugin_p = (rdpsndAudioQPlugin *) device;
	AudioQueueBufferRef aq_buf_ref;
	int                 len;
    
	if (!aq_plugin_p->is_open) {
		return;
	}

	/* get next empty buffer */
	aq_buf_ref = aq_plugin_p->buffers[aq_plugin_p->buf_index];
    
	// fill aq_buf_ref with audio data
	len = size > AQ_BUF_SIZE ? AQ_BUF_SIZE : size;
    
	memcpy(aq_buf_ref->mAudioData, (char *) data, len);
	aq_buf_ref->mAudioDataByteSize = len;
    
	// add buffer to audioqueue
	AudioQueueEnqueueBuffer(aq_plugin_p->aq_ref, aq_buf_ref, 0, 0);
    
	// update buf_index
	aq_plugin_p->buf_index++;
	if (aq_plugin_p->buf_index >= AQ_NUM_BUFFERS) {
		aq_plugin_p->buf_index = 0;
	}
}
Beispiel #17
0
static void HandleOutputBuffer (void                *aqData,
                                AudioQueueRef       inAQ,
                                AudioQueueBufferRef inBuffer) {
  AQPlayerState *pAqData = (AQPlayerState *) aqData;

  if (pAqData->mIsRunning == 0) return;
  UInt32 numBytesReadFromFile;
  UInt32 numPackets = pAqData->mNumPacketsToRead;

  AudioFileReadPackets (pAqData->mAudioFile,
                        false,
                        &numBytesReadFromFile,
                        pAqData->mPacketDescs,
                        pAqData->mCurrentPacket,
                        &numPackets,
                        inBuffer->mAudioData);
  if (numPackets > 0) {
    inBuffer->mAudioDataByteSize = numBytesReadFromFile;
    AudioQueueEnqueueBuffer (pAqData->mQueue,
                             inBuffer,
                             (pAqData->mPacketDescs ? numPackets : 0),
                             pAqData->mPacketDescs);
    pAqData->mCurrentPacket += numPackets;
  } else {
    AudioQueueStop (pAqData->mQueue,
                    false);
    //printf("Play Stopped!\n");
    pAqData->mIsRunning = false;
  }
}
Beispiel #18
0
void setupRead(MSFilter * f)
{
	AQData *d = (AQData *) f->data;
	OSStatus err;

	// allocate and enqueue buffers
	int bufferIndex;

	for (bufferIndex = 0; bufferIndex < kNumberAudioInDataBuffers;
		 ++bufferIndex) {

		AudioQueueBufferRef buffer;

		err = AudioQueueAllocateBuffer(d->readQueue,
									   d->readBufferByteSize, &buffer);
		if (err != noErr) {
			ms_error("setupRead:AudioQueueAllocateBuffer %d", err);
		}

		err = AudioQueueEnqueueBuffer(d->readQueue, buffer, 0, NULL);
		if (err != noErr) {
			ms_error("AudioQueueEnqueueBuffer %d", err);
		}
	}
}
Beispiel #19
0
static void AQTestBufferCallback(void *					inUserData,
								AudioQueueRef			inAQ,
								AudioQueueBufferRef		inCompleteAQBuffer) 
{
	AQTestInfo * myInfo = (AQTestInfo *)inUserData;
	if (myInfo->mDone) return;
		
	UInt32 numBytes;
	UInt32 nPackets = myInfo->mNumPacketsToRead;

	OSStatus result = AudioFileReadPackets(myInfo->mAudioFile, false, &numBytes, myInfo->mPacketDescs, myInfo->mCurrentPacket, &nPackets, 
								inCompleteAQBuffer->mAudioData);
	if (result) {
		DebugMessageN1 ("Error reading from file: %d\n", (int)result);
		exit(1);
	}
	
	if (nPackets > 0) {
		inCompleteAQBuffer->mAudioDataByteSize = numBytes;		

		AudioQueueEnqueueBuffer(inAQ, inCompleteAQBuffer, (myInfo->mPacketDescs ? nPackets : 0), myInfo->mPacketDescs);
		
		myInfo->mCurrentPacket += nPackets;
	} else {
		result = AudioQueueStop(myInfo->mQueue, false);
		if (result) {
			DebugMessageN1 ("AudioQueueStop(false) failed: %d", (int)result);
			exit(1);
		}
			// reading nPackets == 0 is our EOF condition
		myInfo->mDone = true;
	}
}
Beispiel #20
0
// ____________________________________________________________________________________
// AudioQueue callback function, called when an input buffers has been filled.
static void MyInputBufferHandler(	void *                          inUserData,
									AudioQueueRef                   inAQ,
									AudioQueueBufferRef             inBuffer,
									const AudioTimeStamp *          inStartTime,
									UInt32							inNumPackets,
									const AudioStreamPacketDescription *inPacketDesc)
{
	MyRecorder *aqr = (MyRecorder *)inUserData;
	
	if (aqr->verbose) {
		printf("buf data %p, 0x%x bytes, 0x%x packets\n", inBuffer->mAudioData,
			(int)inBuffer->mAudioDataByteSize, (int)inNumPackets);
	}
	
	if (inNumPackets > 0) {
		// write packets to file
		CheckError(AudioFileWritePackets(aqr->recordFile, FALSE, inBuffer->mAudioDataByteSize,
			inPacketDesc, aqr->recordPacket, &inNumPackets, inBuffer->mAudioData),
			"AudioFileWritePackets failed");
		aqr->recordPacket += inNumPackets;
	}

	// if we're not stopping, re-enqueue the buffe so that it gets filled again
	if (aqr->running)
		CheckError(AudioQueueEnqueueBuffer(inAQ, inBuffer, 0, NULL), "AudioQueueEnqueueBuffer failed");
}
Beispiel #21
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;
}
Beispiel #22
0
// Define a playback audio queue callback function
static void AQTestBufferCallback(
    void                   *inUserData,
    AudioQueueRef          inAQ,
    AudioQueueBufferRef    inCompleteAQBuffer
)
{
    struct myAQStruct *myInfo = (struct myAQStruct *)inUserData;
    if (myInfo->mDone) return;
    UInt32 numBytes;
    UInt32 nPackets = myInfo->mNumPacketsToRead;
 
	printf("called\n");
    UInt32 bytesRead = bufferSizeInSamples * 4;
    UInt32 packetsRead = bufferSizeInSamples;

    AudioFileReadPacketData(
			myInfo->mAudioFile,
			false,
			&bytesRead,
			NULL,
			currentPacket,
			&packetsRead,
			inCompleteAQBuffer->mAudioData);
    inCompleteAQBuffer->mAudioDataByteSize = bytesRead;
    currentPacket += packetsRead;

    if (bytesRead == 0) {
        AudioQueueStop(inAQ, false);
    } else {
        AudioQueueEnqueueBuffer(inAQ, inCompleteAQBuffer, 0, NULL);
    }
    /* printf("called\n"); */
    /* AudioFileReadPacketData( */
        /* myInfo->mAudioFile, */
        /* false, */
        /* &numBytes, */
        /* myInfo->mPacketDescs, */
        /* myInfo->mCurrentPacket, */
        /* &nPackets, */
        /* inCompleteAQBuffer->mAudioData */
    /* ); */
    /* printf("read %d packets %d bytes\n", numBytes, nPackets); */
    /* if (nPackets > 0) { */
        /* inCompleteAQBuffer->mAudioDataByteSize = numBytes; */
        /* AudioQueueEnqueueBuffer ( */
            /* inAQ, */
            /* inCompleteAQBuffer, */
            /* (myInfo->mPacketDescs ? nPackets : 0), */
            /* myInfo->mPacketDescs */
        /* ); */
        /* myInfo->mCurrentPacket += nPackets; */
    /* } else { */
        /* AudioQueueStop ( */
            /* myInfo->mQueue, */
            /* false */
        /* ); */
        /* myInfo->mDone = true; */
    /* } */
}
static void AQTestBufferCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inCompleteAQBuffer) 
{
	AQTestInfo * myInfo = (AQTestInfo *)inUserData;
	if (myInfo->mDone) return;
		
	UInt32 numBytes;
	UInt32 nPackets = myInfo->mNumPacketsToRead;
	OSStatus result = AudioFileReadPackets(myInfo->mAudioFile,      // The audio file from which packets of audio data are to be read.
                                           false,                   // Set to true to cache the data. Otherwise, set to false.
                                           &numBytes,               // On output, a pointer to the number of bytes actually returned.
                                           myInfo->mPacketDescs,    // A pointer to an array of packet descriptions that have been allocated.
                                           myInfo->mCurrentPacket,  // The packet index of the first packet you want to be returned.
                                           &nPackets,               // On input, a pointer to the number of packets to read. On output, the number of packets actually read.
                                           inCompleteAQBuffer->mAudioData); // A pointer to user-allocated memory.
	if (result) {
		DebugMessageN1 ("Error reading from file: %d\n", (int)result);
		exit(1);
	}
    
    // we have some data
	if (nPackets > 0) {
		inCompleteAQBuffer->mAudioDataByteSize = numBytes;
        
		result = AudioQueueEnqueueBuffer(inAQ,                                  // The audio queue that owns the audio queue buffer.
                                         inCompleteAQBuffer,                    // The audio queue buffer to add to the buffer queue.
                                         (myInfo->mPacketDescs ? nPackets : 0), // The number of packets of audio data in the inBuffer parameter. See Docs.
                                         myInfo->mPacketDescs);                 // An array of packet descriptions. Or NULL. See Docs.
		if (result) {
			DebugMessageN1 ("Error enqueuing buffer: %d\n", (int)result);
			exit(1);
		}
        
		myInfo->mCurrentPacket += nPackets;
        
	} else {
        // **** This ensures that we flush the queue when done -- ensures you get all the data out ****
		
        if (!myInfo->mFlushed) {
			result = AudioQueueFlush(myInfo->mQueue);
			
            if (result) {
				DebugMessageN1("AudioQueueFlush failed: %d", (int)result);
				exit(1);
			}
            
			myInfo->mFlushed = true;
		}
		
		result = AudioQueueStop(myInfo->mQueue, false);
		if (result) {
			DebugMessageN1("AudioQueueStop(false) failed: %d", (int)result);
			exit(1);
		}
        
		// reading nPackets == 0 is our EOF condition
		myInfo->mDone = true;
	}
}
Beispiel #24
0
static void writeCallback(void *aqData,
						  AudioQueueRef inAQ, AudioQueueBufferRef inBuffer)
{
	AQData *d = (AQData *) aqData;
	OSStatus err;

	int len =
		(d->writeBufferByteSize * d->writeAudioFormat.mSampleRate / 1) /
		d->devicewriteFormat.mSampleRate /
		d->devicewriteFormat.mChannelsPerFrame;

	ms_mutex_lock(&d->mutex);
	if (d->write_started == FALSE) {
		ms_mutex_unlock(&d->mutex);
		return;
	}
	if (d->bufferizer->size >= len) {
#if 0
		UInt32 bsize = d->writeBufferByteSize;
		uint8_t *pData = ms_malloc(len);

		ms_bufferizer_read(d->bufferizer, pData, len);
		err = AudioConverterConvertBuffer(d->writeAudioConverter,
										  len,
										  pData,
										  &bsize, inBuffer->mAudioData);
		if (err != noErr) {
			ms_error("writeCallback: AudioConverterConvertBuffer %d", err);
		}
		ms_free(pData);

		if (bsize != d->writeBufferByteSize)
			ms_warning("d->writeBufferByteSize = %i len = %i bsize = %i",
					   d->writeBufferByteSize, len, bsize);
#else
		ms_bufferizer_read(d->bufferizer, inBuffer->mAudioData, len);
#endif
	} else {
		memset(inBuffer->mAudioData, 0, d->writeBufferByteSize);
	}
	inBuffer->mAudioDataByteSize = d->writeBufferByteSize;

	if (gain_changed_out == true)
	  {
	    AudioQueueSetParameter (d->writeQueue,
				    kAudioQueueParam_Volume,
				    gain_volume_out);
	    gain_changed_out = false;
	  }

	err = AudioQueueEnqueueBuffer(d->writeQueue, inBuffer, 0, NULL);
	if (err != noErr) {
		ms_error("AudioQueueEnqueueBuffer %d", err);
	}
	ms_mutex_unlock(&d->mutex);
}
Beispiel #25
0
void putWriteAQ(void *aqData, int queuenum)
{
	AQData *d = (AQData *) aqData;
	OSStatus err;
	err = AudioQueueEnqueueBuffer(d->writeQueue,
								  d->writeBuffers[queuenum], 0, NULL);
	if (err != noErr) {
		ms_error("AudioQueueEnqueueBuffer %d", err);
	}
}
Beispiel #26
0
static void AQBufferCallback(void *userdata,
							 AudioQueueRef outQ,
							 AudioQueueBufferRef outQB)
{
	unsigned char *coreAudioBuffer;
	coreAudioBuffer = (unsigned char*) outQB->mAudioData;

	int res = dequeue(coreAudioBuffer, in.mDataFormat.mBytesPerFrame * in.frameCount);
	outQB->mAudioDataByteSize = in.mDataFormat.mBytesPerFrame * in.frameCount;

	AudioQueueEnqueueBuffer(outQ, outQB, 0, NULL);
}
long AudioStreamDecoder::EnqueueBuffer()
{
	bool locked = false;

	if (mFinished)
		return 0;

	long err = AudioQueueEnqueueBuffer(mQueue, *mCurrentBuffer, 0, NULL);
	BAIL_IF(err, "AudioQueueEnqueueBuffer returned %ld\n", err);

	if (++mCurrentBuffer == mBuffers + kBufferCount)
		mCurrentBuffer = mBuffers;

	if (!mStarted && !mFinished)
	{
		mStarted = true;

		err = AudioQueueStart(mQueue, NULL);
		BAIL_IF(err, "AudioQueueStart returned %ld\n", err);
	}

	err = pthread_mutex_lock(&mMutex);
	BAIL_IF(err, "pthread_mutex_lock returned %ld\n", err);

	locked = true;

	while ((*mCurrentBuffer)->mUserData && !mFinished)
	{
		err = pthread_cond_wait(&mCond, &mMutex);
		BAIL_IF(err, "pthread_cond_wait returned %ld\n", err);
	}

	(*mCurrentBuffer)->mUserData = this;
	(*mCurrentBuffer)->mAudioDataByteSize = 0;
	(*mCurrentBuffer)->mPacketDescriptionCount = 0;

bail:
	long err2;

	if (locked)
	{
		err2 = pthread_mutex_unlock(&mMutex);
		CARP_IF(err2, "pthread_mutex_unlock returned %ld\n", err2);
	}

	if (err && mStarted)
	{
		err2 = SetFinished();
		CARP_IF(err2, "SetFinished returned %ld\n", err2);
	}

	return err;
}
Beispiel #28
0
static void AQBufferCallback(void *userdata, AudioQueueRef outQ,
 AudioQueueBufferRef outQB)
{
  unsigned char *coreAudioBuffer;
  coreAudioBuffer = (unsigned char*) outQB->mAudioData;
  
  outQB->mAudioDataByteSize = IPHONE_AUDIO_BUFFER_SIZE;
  AudioQueueSetParameter(outQ, kAudioQueueParam_Volume, __audioVolume);
  audio_callback(coreAudioBuffer, IPHONE_AUDIO_BUFFER_SIZE);
  
  AudioQueueEnqueueBuffer(outQ, outQB, 0, NULL);
}
Beispiel #29
0
void Audio_Queue::enqueueBuffer()
{
    AQ_ASSERT(!m_bufferInUse[m_fillBufferIndex]);
    
    Stream_Configuration *config = Stream_Configuration::configuration();
    
    AQ_TRACE("%s: enter\n", __PRETTY_FUNCTION__);
    
    pthread_mutex_lock(&m_bufferInUseMutex);
    
    m_bufferInUse[m_fillBufferIndex] = true;
    m_buffersUsed++;
    
    // enqueue buffer
    AudioQueueBufferRef fillBuf = m_audioQueueBuffer[m_fillBufferIndex];
    fillBuf->mAudioDataByteSize = m_bytesFilled;
    
    pthread_mutex_unlock(&m_bufferInUseMutex);
    
    AQ_ASSERT(m_packetsFilled > 0);
    OSStatus err = AudioQueueEnqueueBuffer(m_outAQ, fillBuf, m_packetsFilled, m_packetDescs);
    
    if (!err) {
        m_lastError = noErr;
        start();
    } else {
        /* If we get an error here, it very likely means that the audio queue is no longer
           running */
        AQ_TRACE("%s: error in AudioQueueEnqueueBuffer\n", __PRETTY_FUNCTION__);
        m_lastError = err;
        return;
    }
    
    pthread_mutex_lock(&m_bufferInUseMutex);
    // go to next buffer
    if (++m_fillBufferIndex >= config->bufferCount) {
        m_fillBufferIndex = 0; 
    }
    // reset bytes filled
    m_bytesFilled = 0;
    // reset packets filled
    m_packetsFilled = 0;
    
    // wait until next buffer is not in use
    
    while (m_bufferInUse[m_fillBufferIndex]) {
        AQ_TRACE("waiting for buffer %u\n", (unsigned int)m_fillBufferIndex);
        
        pthread_cond_wait(&m_bufferFreeCondition, &m_bufferInUseMutex);
    }
    pthread_mutex_unlock(&m_bufferInUseMutex);
}
Beispiel #30
0
static void audio_callback (void *aux, AudioQueueRef aq, AudioQueueBufferRef bufout)
{
    audio_fifo_t *af = aux;
    audio_fifo_data_t *afd = audio_get(af);

    bufout->mAudioDataByteSize = afd->nsamples * sizeof(short) * afd->channels;

    assert(bufout->mAudioDataByteSize <= state.buffer_size);
    memcpy(bufout->mAudioData, afd->samples, bufout->mAudioDataByteSize);

    AudioQueueEnqueueBuffer(state.queue, bufout, 0, NULL);
    free(afd);
}