Ejemplo n.º 1
0
int
coreaudio_object_write(struct audio_object *object,
                        const void *data,
                        size_t bytes)
{
	struct coreaudio_object *self = to_coreaudio_object(object);
	if (!self->initialized)
		return noErr;
	bool runningAtStart = self->running;
	if(!runningAtStart) {
		TPCircularBufferClear(&(self->circularBuffer));
	}
	char *dataPtr = (char*)data;

	// copy data to our circular buffer
	// Poll while we don't have space in the buffer.
	AudioBufferList *bufferList;
	UInt32 available;
	while(bytes > 0) {
		while((!runningAtStart || self->running) && (available = TPCircularBufferGetAvailableSpace(&(self->circularBuffer), &(self->format))) == 0)
			usleep(10000);

		// check we didn't stop
		if(runningAtStart &&  (!self->running))
			return noErr;

		bufferList = TPCircularBufferPrepareEmptyAudioBufferListWithAudioFormat(&(self->circularBuffer), &(self->format), available, NULL);

		// we are writing mono/interleaved data so we have one buffer
		UInt32 bytesToWrite = min(bytes, bufferList->mBuffers[0].mDataByteSize);
		bufferList->mBuffers[0].mNumberChannels = (self->format).mChannelsPerFrame;
		bufferList->mBuffers[0].mDataByteSize = bytesToWrite;
		memcpy(bufferList->mBuffers[0].mData, dataPtr, bytesToWrite);
		TPCircularBufferProduceAudioBufferList(&(self->circularBuffer), NULL);
		dataPtr += bytesToWrite;
		bytes -= bytesToWrite;
		if(! runningAtStart) {
			OSStatus err = AudioOutputUnitStart(self->outputUnit);
			if(err == noErr) {
			self->running = TRUE;
			runningAtStart = TRUE;
		} else {
			return err;
		}
	}
	}
	return noErr;
}
bool TPCircularBufferCopyAudioBufferList(TPCircularBuffer *buffer, const AudioBufferList *inBufferList, const AudioTimeStamp *inTimestamp, UInt32 frames, AudioStreamBasicDescription *audioDescription) {

    int byteCount = inBufferList->mBuffers[0].mDataByteSize;
    if ( frames != kTPCircularBufferCopyAll ) {
        byteCount = frames * audioDescription->mBytesPerFrame;
        assert(byteCount <= inBufferList->mBuffers[0].mDataByteSize);
    }
    
    AudioBufferList *bufferList = TPCircularBufferPrepareEmptyAudioBufferList(buffer, inBufferList->mNumberBuffers, byteCount, inTimestamp);
    if ( !bufferList ) return false;
    
    for ( int i=0; i<bufferList->mNumberBuffers; i++ ) {
        memcpy(bufferList->mBuffers[i].mData, inBufferList->mBuffers[i].mData, byteCount);
    }
    
    TPCircularBufferProduceAudioBufferList(buffer, NULL);
    
    return true;
}