Search
lxdream.org :: lxdream/src/drivers/audio_osx.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/drivers/audio_osx.c
changeset 697:479b8c213f61
next700:4650d0c7f6f9
author nkeynes
date Sun Jun 22 04:01:27 2008 +0000 (13 years ago)
permissions -rw-r--r--
last change Commit work-in-progress CoreAudio driver
(along with various changes to the audio subsystem)
file annotate diff log raw
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/src/drivers/audio_osx.c Sun Jun 22 04:01:27 2008 +0000
1.3 @@ -0,0 +1,142 @@
1.4 +/**
1.5 + * $Id$
1.6 + *
1.7 + * The darwin core-audio audio driver
1.8 + *
1.9 + * Copyright (c) 2008 Nathan Keynes.
1.10 + *
1.11 + * This program is free software; you can redistribute it and/or modify
1.12 + * it under the terms of the GNU General Public License as published by
1.13 + * the Free Software Foundation; either version 2 of the License, or
1.14 + * (at your option) any later version.
1.15 + *
1.16 + * This program is distributed in the hope that it will be useful,
1.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.19 + * GNU General Public License for more details.
1.20 + */
1.21 +#include <stdio.h>
1.22 +#include <unistd.h>
1.23 +#include <AudioToolbox/AudioToolbox.h>
1.24 +#include <AudioUnit/AudioUnitProperties.h>
1.25 +#include "aica/audio.h"
1.26 +#include "lxdream.h"
1.27 +
1.28 +static AudioUnit output_au;
1.29 +static volatile audio_buffer_t output_buffer = NULL;
1.30 +static int sample_size;
1.31 +
1.32 +OSStatus audio_osx_callback( void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags,
1.33 + const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber,
1.34 + UInt32 inNumberFrames, AudioBufferList *ioData )
1.35 +{
1.36 + char *output = ioData->mBuffers[0].mData;
1.37 + int data_requested = inNumberFrames * sample_size;
1.38 +
1.39 + while( output_buffer != NULL && data_requested > 0 ) {
1.40 + int copysize = output_buffer->length - output_buffer->posn;
1.41 + if( copysize > data_requested ) {
1.42 + copysize = data_requested;
1.43 + }
1.44 + memcpy( output, &output_buffer->data[output_buffer->posn], copysize );
1.45 + output += copysize;
1.46 + data_requested -= copysize;
1.47 + output_buffer->posn += copysize;
1.48 + if( output_buffer->posn >= output_buffer->length ) {
1.49 + output_buffer = audio_next_read_buffer();
1.50 + }
1.51 + }
1.52 + if( data_requested > 0 ) {
1.53 + memset( output, 0, data_requested );
1.54 + }
1.55 + return noErr;
1.56 +}
1.57 +
1.58 +static gboolean audio_osx_shutdown()
1.59 +{
1.60 + AudioUnitUninitialize( output_au );
1.61 + CloseComponent( output_au );
1.62 + return TRUE;
1.63 +}
1.64 +
1.65 +static gboolean audio_osx_init()
1.66 +{
1.67 + AURenderCallbackStruct callbackData;
1.68 + AudioStreamBasicDescription outputDesc;
1.69 + UInt32 outputDescSize = sizeof(outputDesc);
1.70 + ComponentDescription cd;
1.71 + Component c;
1.72 +
1.73 + cd.componentType = kAudioUnitType_Output;
1.74 + cd.componentSubType = kAudioUnitSubType_DefaultOutput;
1.75 + cd.componentManufacturer = kAudioUnitManufacturer_Apple;
1.76 + cd.componentFlags = 0;
1.77 + cd.componentFlagsMask = 0;
1.78 +
1.79 + c = FindNextComponent( NULL, &cd );
1.80 + if( c == NULL ) {
1.81 + return FALSE;
1.82 + }
1.83 +
1.84 + if( OpenAComponent( c, &output_au ) != noErr ) {
1.85 + return FALSE;
1.86 + }
1.87 +
1.88 + if( AudioUnitGetProperty( output_au, kAudioUnitProperty_StreamFormat,
1.89 + kAudioUnitScope_Global, 0, &outputDesc, &outputDescSize ) != noErr ) {
1.90 + CloseComponent( output_au );
1.91 + return FALSE;
1.92 + }
1.93 +
1.94 + outputDesc.mSampleRate = DEFAULT_SAMPLE_RATE;
1.95 + sample_size = outputDesc.mBytesPerFrame;
1.96 +
1.97 + if( AudioUnitSetProperty( output_au, kAudioUnitProperty_StreamFormat,
1.98 + kAudioUnitScope_Global, 0, &outputDesc, sizeof(outputDesc) ) != noErr ) {
1.99 + CloseComponent( output_au );
1.100 + return FALSE;
1.101 + }
1.102 +
1.103 + if( AudioUnitInitialize( output_au ) != noErr ) {
1.104 + CloseComponent( output_au );
1.105 + return FALSE;
1.106 + }
1.107 +
1.108 + callbackData.inputProc = audio_osx_callback;
1.109 + callbackData.inputProcRefCon = NULL;
1.110 + if( AudioUnitSetProperty( output_au, kAudioUnitProperty_SetRenderCallback,
1.111 + kAudioUnitScope_Global, 0, &callbackData, sizeof(callbackData)) != noErr ) {
1.112 + audio_osx_shutdown();
1.113 + return FALSE;
1.114 + }
1.115 +
1.116 + return TRUE;
1.117 +}
1.118 +static gboolean audio_osx_process_buffer( audio_buffer_t buffer )
1.119 +{
1.120 + if( output_buffer == NULL ) {
1.121 + output_buffer = buffer;
1.122 + output_buffer->posn = 0;
1.123 + AudioOutputUnitStart(output_au);
1.124 + return FALSE;
1.125 + }
1.126 +}
1.127 +
1.128 +void audio_osx_start()
1.129 +{
1.130 +}
1.131 +
1.132 +void audio_osx_stop()
1.133 +{
1.134 +}
1.135 +
1.136 +
1.137 +struct audio_driver audio_osx_driver = { "osx",
1.138 + DEFAULT_SAMPLE_RATE,
1.139 + AUDIO_FMT_FLOATST,
1.140 + audio_osx_init,
1.141 + audio_osx_start,
1.142 + audio_osx_process_buffer,
1.143 + audio_osx_stop,
1.144 + audio_osx_shutdown};
1.145 +
.