Ton of work on CoreAudio driver for new 1.3 features...most of the SDL-ryan-multiple-audio-device
authorRyan C. Gordon <icculus@icculus.org>
Tue, 03 Oct 2006 05:58:44 +0000
branchSDL-ryan-multiple-audio-device
changeset 3785da2ea0694d11
parent 3784 37c9c4590689
child 3786 b70f4e9291bb
Ton of work on CoreAudio driver for new 1.3 features...most of the
multi-device support is wired up, and the starts of capture support, too.

All is still subject to change, and what's there is still a little flakey.
configure.in
src/audio/macosx/SDL_coreaudio.c
src/audio/macosx/SDL_coreaudio.h
     1.1 --- a/configure.in	Sun Oct 01 05:24:03 2006 +0000
     1.2 +++ b/configure.in	Tue Oct 03 05:58:44 2006 +0000
     1.3 @@ -2323,7 +2323,7 @@
     1.4          EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,Carbon"
     1.5          # If either the audio or CD driver is used, add the AudioUnit framework
     1.6          if test x$enable_audio = xyes -o x$enable_cdrom = xyes; then
     1.7 -            EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,AudioToolbox -Wl,-framework,AudioUnit"
     1.8 +            EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,CoreAudio -framework,AudioToolbox -Wl,-framework,AudioUnit"
     1.9          fi
    1.10          ;;
    1.11      *-*-mint*)
     2.1 --- a/src/audio/macosx/SDL_coreaudio.c	Sun Oct 01 05:24:03 2006 +0000
     2.2 +++ b/src/audio/macosx/SDL_coreaudio.c	Tue Oct 03 05:58:44 2006 +0000
     2.3 @@ -21,6 +21,7 @@
     2.4  */
     2.5  #include "SDL_config.h"
     2.6  
     2.7 +#include <CoreAudio/CoreAudio.h>
     2.8  #include <AudioUnit/AudioUnit.h>
     2.9  
    2.10  #include "SDL_audio.h"
    2.11 @@ -29,6 +30,148 @@
    2.12  #include "SDL_coreaudio.h"
    2.13  
    2.14  
    2.15 +typedef struct COREAUDIO_DeviceList
    2.16 +{
    2.17 +    AudioDeviceID id;
    2.18 +    const char *name;
    2.19 +} COREAUDIO_DeviceList;
    2.20 +
    2.21 +static COREAUDIO_DeviceList *inputDevices = NULL;
    2.22 +static int inputDeviceCount = 0;
    2.23 +static COREAUDIO_DeviceList *outputDevices = NULL;
    2.24 +static int outputDeviceCount = 0;
    2.25 +
    2.26 +static void
    2.27 +free_device_list(COREAUDIO_DeviceList **devices, int *devCount)
    2.28 +{
    2.29 +    if (*devices) {
    2.30 +        int i = *devCount;
    2.31 +        while (i--)
    2.32 +            SDL_free((void *) (*devices)[i].name);
    2.33 +        SDL_free(*devices);
    2.34 +        *devices = NULL;
    2.35 +    }
    2.36 +    *devCount = 0;
    2.37 +}
    2.38 +
    2.39 +
    2.40 +static void
    2.41 +build_device_list(int iscapture, COREAUDIO_DeviceList **devices, int *devCount)
    2.42 +{
    2.43 +    Boolean outWritable = 0;
    2.44 +    OSStatus result = noErr;
    2.45 +    UInt32 size = 0;
    2.46 +    AudioDeviceID *devs = NULL;
    2.47 +    UInt32 i = 0;
    2.48 +    UInt32 max = 0;
    2.49 +
    2.50 +    free_device_list(devices, devCount);
    2.51 +
    2.52 +    result = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices,
    2.53 +                                         &size, &outWritable);
    2.54 +
    2.55 +    if (result != kAudioHardwareNoError)
    2.56 +        return;
    2.57 +
    2.58 +    devs = (AudioDeviceID *) alloca(size);
    2.59 +    if (devs == NULL)
    2.60 +        return;
    2.61 +
    2.62 +    max = size / sizeof (AudioDeviceID);
    2.63 +    *devices = (COREAUDIO_DeviceList *) SDL_malloc(max * sizeof (**devices));
    2.64 +    if (*devices == NULL)
    2.65 +        return;
    2.66 +
    2.67 +    result = AudioHardwareGetProperty(kAudioHardwarePropertyDevices,
    2.68 +                                     &size, devs);
    2.69 +    if (result != kAudioHardwareNoError)
    2.70 +        return;
    2.71 +
    2.72 +    for (i = 0; i < max; i++) {
    2.73 +        char *ptr = NULL;
    2.74 +        AudioDeviceID dev = devs[i];
    2.75 +        AudioBufferList *buflist = NULL;
    2.76 +        int usable = 0;
    2.77 +
    2.78 +        result = AudioDeviceGetPropertyInfo(dev, 0, iscapture,
    2.79 +                                      kAudioDevicePropertyStreamConfiguration,
    2.80 +                                      &size, &outWritable);
    2.81 +        if (result != noErr)
    2.82 +            continue;
    2.83 +
    2.84 +        buflist = (AudioBufferList *) SDL_malloc(size);
    2.85 +        if (buflist == NULL)
    2.86 +            continue;
    2.87 +
    2.88 +        result = AudioDeviceGetProperty(dev, 0, iscapture,
    2.89 +                                      kAudioDevicePropertyStreamConfiguration,
    2.90 +                                      &size, buflist);
    2.91 +
    2.92 +        if (result == noErr) {
    2.93 +            UInt32 j;
    2.94 +            for (j = 0; j < buflist->mNumberBuffers; j++) {
    2.95 +                if (buflist->mBuffers[j].mNumberChannels > 0) {
    2.96 +                    usable = 1;
    2.97 +                    break;
    2.98 +                }
    2.99 +            }
   2.100 +        }
   2.101 +
   2.102 +        SDL_free(buflist);
   2.103 +
   2.104 +        if (!usable)
   2.105 +            continue;
   2.106 +
   2.107 +        /* !!! FIXME: use CFStrings, instead, and convert to UTF-8. */
   2.108 +        result = AudioDeviceGetPropertyInfo(dev, 0, iscapture,
   2.109 +                                           kAudioDevicePropertyDeviceName,
   2.110 +                                           &size, &outWritable);
   2.111 +
   2.112 +        if (result != kAudioHardwareNoError)
   2.113 +            continue;
   2.114 +
   2.115 +        ptr = (char *) SDL_malloc(size + 1);
   2.116 +        if (ptr == NULL)
   2.117 +            continue;
   2.118 +
   2.119 +        result = AudioDeviceGetProperty(dev, 0, iscapture,
   2.120 +                                       kAudioDevicePropertyDeviceName,
   2.121 +                                       &size, ptr);
   2.122 +
   2.123 +        if (result != kAudioHardwareNoError)
   2.124 +            continue;
   2.125 +
   2.126 +        while ((size > 0) && (ptr[size-1] == ' '))
   2.127 +            size--; /* I have a USB device with whitespace at the end... */
   2.128 +
   2.129 +        if (size == 0) {
   2.130 +            SDL_free(ptr);
   2.131 +        } else {
   2.132 +            ptr[size] = '\0';
   2.133 +            (*devices)[*devCount].id = dev;
   2.134 +            (*devices)[*devCount].name = ptr;
   2.135 +            (*devCount)++;
   2.136 +        }
   2.137 +    }
   2.138 +}
   2.139 +
   2.140 +static int
   2.141 +find_device_id(const char *devname, int iscapture, AudioDeviceID *id)
   2.142 +{
   2.143 +    int i = ((iscapture) ? inputDeviceCount : outputDeviceCount);
   2.144 +    COREAUDIO_DeviceList *devs = ((iscapture) ? inputDevices : outputDevices);
   2.145 +    while (i--) {
   2.146 +        if (SDL_strcmp(devname, devs->name) == 0) {
   2.147 +            *id = devs->id;
   2.148 +            return 1;
   2.149 +        }
   2.150 +        devs++;
   2.151 +    }
   2.152 +
   2.153 +    return 0;
   2.154 +}
   2.155 +
   2.156 +
   2.157  /* Audio driver functions */
   2.158  
   2.159  static int COREAUDIO_OpenAudio(_THIS, const char *devname, int iscapture);
   2.160 @@ -48,6 +191,10 @@
   2.161  static int
   2.162  COREAUDIO_Init(SDL_AudioDriverImpl *impl)
   2.163  {
   2.164 +    /* !!! FIXME: should these _really_ be static? */
   2.165 +    build_device_list(0, &outputDevices, &outputDeviceCount);
   2.166 +    build_device_list(1, &inputDevices, &inputDeviceCount);
   2.167 +
   2.168      /* Set the function pointers */
   2.169      impl->OpenAudio = COREAUDIO_OpenAudio;
   2.170      impl->WaitAudio = COREAUDIO_WaitAudio;
   2.171 @@ -65,15 +212,22 @@
   2.172  
   2.173  /* The CoreAudio callback */
   2.174  static OSStatus
   2.175 -audioCallback(void *inRefCon,
   2.176 -              AudioUnitRenderActionFlags inActionFlags,
   2.177 +outputCallback(void *inRefCon,
   2.178 +              AudioUnitRenderActionFlags *ioActionFlags,
   2.179                const AudioTimeStamp * inTimeStamp,
   2.180 -              UInt32 inBusNumber, AudioBuffer * ioData)
   2.181 +              UInt32 inBusNumber, UInt32 inNumberFrames,
   2.182 +              AudioBufferList *ioDataList)
   2.183  {
   2.184      SDL_AudioDevice *this = (SDL_AudioDevice *) inRefCon;
   2.185 +    AudioBuffer *ioData = &ioDataList->mBuffers[0];
   2.186      UInt32 remaining, len;
   2.187      void *ptr;
   2.188  
   2.189 +    if (ioDataList->mNumberBuffers != 1) {
   2.190 +        fprintf(stderr, "!!! FIXME SDL!\n");
   2.191 +        return noErr;
   2.192 +    }
   2.193 +
   2.194      /* Only do anything if audio is enabled and not paused */
   2.195      if (!this->enabled || this->paused) {
   2.196          SDL_memset(ioData->mData, this->spec.silence, ioData->mDataByteSize);
   2.197 @@ -116,6 +270,19 @@
   2.198      return 0;
   2.199  }
   2.200  
   2.201 +static OSStatus
   2.202 +inputCallback(void *inRefCon,
   2.203 +              AudioUnitRenderActionFlags *ioActionFlags,
   2.204 +              const AudioTimeStamp * inTimeStamp,
   2.205 +              UInt32 inBusNumber, UInt32 inNumberFrames,
   2.206 +              AudioBufferList *ioData)
   2.207 +{
   2.208 +    //err = AudioUnitRender(afr->fAudioUnit, ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, afr->fAudioBuffer);
   2.209 +    // !!! FIXME: write me!
   2.210 +    return noErr;
   2.211 +}
   2.212 +
   2.213 +
   2.214  /* Dummy functions -- we don't use thread-based audio */
   2.215  void
   2.216  COREAUDIO_WaitAudio(_THIS)
   2.217 @@ -138,59 +305,191 @@
   2.218  void
   2.219  COREAUDIO_CloseAudio(_THIS)
   2.220  {
   2.221 -    OSStatus result;
   2.222 -    struct AudioUnitInputCallback callback;
   2.223 +    if (this->hidden != NULL) {
   2.224 +        OSStatus result = noErr;
   2.225 +        AURenderCallbackStruct callback;
   2.226 +        const AudioUnitElement output_bus = 0;
   2.227 +        const AudioUnitElement input_bus = 1;
   2.228 +        const int iscapture = this->hidden->isCapture;
   2.229 +        const AudioUnitElement bus = ((iscapture) ? input_bus : output_bus);
   2.230 +        const AudioUnitScope scope = ((iscapture) ? kAudioUnitScope_Output :
   2.231 +                                                    kAudioUnitScope_Input);
   2.232  
   2.233 -    if (this->hidden == NULL) {
   2.234 -        return;
   2.235 +        /* stop processing the audio unit */
   2.236 +        result = AudioOutputUnitStop(this->hidden->audioUnit);
   2.237 +
   2.238 +        /* Remove the input callback */
   2.239 +        memset(&callback, '\0', sizeof (AURenderCallbackStruct));
   2.240 +        result = AudioUnitSetProperty(this->hidden->audioUnit,
   2.241 +                                      kAudioUnitProperty_SetRenderCallback,
   2.242 +                                      scope, bus, &callback, sizeof (callback));
   2.243 +
   2.244 +        CloseComponent(this->hidden->audioUnit);
   2.245 +
   2.246 +        SDL_free(this->hidden->buffer);
   2.247 +        SDL_free(this->hidden);
   2.248 +        this->hidden = NULL;
   2.249      }
   2.250 +}
   2.251  
   2.252 -    /* stop processing the audio unit */
   2.253 -    result = AudioOutputUnitStop(this->hidden->outputAudioUnit);
   2.254 -    if (result != noErr) {
   2.255 -        SDL_SetError("COREAUDIO_CloseAudio: AudioOutputUnitStop");
   2.256 -        return;
   2.257 -    }
   2.258 -
   2.259 -    /* Remove the input callback */
   2.260 -    callback.inputProc = 0;
   2.261 -    callback.inputProcRefCon = 0;
   2.262 -    result = AudioUnitSetProperty(this->hidden->outputAudioUnit,
   2.263 -                                  kAudioUnitProperty_SetInputCallback,
   2.264 -                                  kAudioUnitScope_Input,
   2.265 -                                  0, &callback, sizeof(callback));
   2.266 -    if (result != noErr) {
   2.267 -        SDL_SetError
   2.268 -            ("COREAUDIO_CloseAudio: AudioUnitSetProperty (kAudioUnitProperty_SetInputCallback)");
   2.269 -        return;
   2.270 -    }
   2.271 -
   2.272 -    result = CloseComponent(this->hidden->outputAudioUnit);
   2.273 -    if (result != noErr) {
   2.274 -        SDL_SetError("COREAUDIO_CloseAudio: CloseComponent");
   2.275 -        return;
   2.276 -    }
   2.277 -
   2.278 -    SDL_free(this->hidden->buffer);
   2.279 -    SDL_free(this->hidden);
   2.280 -    this->hidden = NULL;
   2.281 -}
   2.282  
   2.283  #define CHECK_RESULT(msg) \
   2.284      if (result != noErr) { \
   2.285          COREAUDIO_CloseAudio(this); \
   2.286          SDL_SetError("CoreAudio error (%s): %d", msg, (int) result); \
   2.287 -        return -1; \
   2.288 +        return 0; \
   2.289      }
   2.290  
   2.291 +static int
   2.292 +find_device_by_name(_THIS, const char *devname, int iscapture)
   2.293 +{
   2.294 +    AudioDeviceID devid = 0;
   2.295 +    OSStatus result = noErr;
   2.296 +    UInt32 size = 0;
   2.297 +    UInt32 alive = 0;
   2.298 +    pid_t pid = 0;
   2.299 +
   2.300 +    if (devname == NULL) {
   2.301 +        size = sizeof (AudioDeviceID);
   2.302 +        const AudioHardwarePropertyID propid =
   2.303 +                    ((iscapture) ? kAudioHardwarePropertyDefaultInputDevice :
   2.304 +                                   kAudioHardwarePropertyDefaultOutputDevice);
   2.305 +
   2.306 +        result = AudioHardwareGetProperty(propid, &size, &devid);
   2.307 +        CHECK_RESULT("AudioHardwareGetProperty (default device)");
   2.308 +    } else {
   2.309 +        if (!find_device_id(devname, iscapture, &devid)) {
   2.310 +            SDL_SetError("CoreAudio: No such audio device.");
   2.311 +            return 0;
   2.312 +        }
   2.313 +    }
   2.314 +
   2.315 +    size = sizeof (alive);
   2.316 +    result = AudioDeviceGetProperty(devid, 0, iscapture,
   2.317 +                                    kAudioDevicePropertyDeviceIsAlive,
   2.318 +                                    &size, &alive);
   2.319 +    CHECK_RESULT("AudioDeviceGetProperty (kAudioDevicePropertyDeviceIsAlive)");
   2.320 +
   2.321 +    if (!alive) {
   2.322 +        SDL_SetError("CoreAudio: requested device exists, but isn't alive.");
   2.323 +        return 0;
   2.324 +    }
   2.325 +
   2.326 +    size = sizeof (pid);
   2.327 +    result = AudioDeviceGetProperty(devid, 0, iscapture,
   2.328 +                                    kAudioDevicePropertyHogMode, &size, &pid);
   2.329 +
   2.330 +    /* some devices don't support this property, so errors are fine here. */
   2.331 +    if ((result == noErr) && (pid != -1)) {
   2.332 +        SDL_SetError("CoreAudio: requested device is being hogged.");
   2.333 +        return 0;
   2.334 +    }
   2.335 +
   2.336 +    this->hidden->deviceID = devid;
   2.337 +    return 1;
   2.338 +}
   2.339 +
   2.340 +
   2.341 +static int
   2.342 +prepare_audiounit(_THIS, const char *devname, int iscapture,
   2.343 +                  const AudioStreamBasicDescription *strdesc)
   2.344 +{
   2.345 +    OSStatus result = noErr;
   2.346 +    AURenderCallbackStruct callback;
   2.347 +    ComponentDescription desc;
   2.348 +    Component comp = NULL;
   2.349 +    int use_system_device = 0;
   2.350 +    UInt32 enableIO = 0;
   2.351 +    const AudioUnitElement output_bus = 0;
   2.352 +    const AudioUnitElement input_bus = 1;
   2.353 +    const AudioUnitElement bus = ((iscapture) ? input_bus : output_bus);
   2.354 +    const AudioUnitScope scope = ((iscapture) ? kAudioUnitScope_Output :
   2.355 +                                                kAudioUnitScope_Input);
   2.356 +
   2.357 +    /* !!! FIXME: move something like this to higher level. */
   2.358 +    if ( (devname == NULL) && (SDL_getenv("SDL_AUDIO_DEVNAME")) )
   2.359 +        devname = SDL_getenv("SDL_AUDIO_DEVNAME");
   2.360 +
   2.361 +    if (!find_device_by_name(this, devname, iscapture)) {
   2.362 +        SDL_SetError("Couldn't find requested CoreAudio device");
   2.363 +        return 0;
   2.364 +    }
   2.365 +
   2.366 +    memset(&desc, '\0', sizeof(ComponentDescription));
   2.367 +    desc.componentType = kAudioUnitType_Output;
   2.368 +    desc.componentSubType = kAudioUnitSubType_HALOutput;
   2.369 +    desc.componentManufacturer = kAudioUnitManufacturer_Apple;
   2.370 +
   2.371 +    comp = FindNextComponent(NULL, &desc);
   2.372 +    if (comp == NULL) {
   2.373 +        SDL_SetError("Couldn't find requested CoreAudio component");
   2.374 +        return 0;
   2.375 +    }
   2.376 +
   2.377 +    /* Open & initialize the audio unit */
   2.378 +    result = OpenAComponent(comp, &this->hidden->audioUnit);
   2.379 +    CHECK_RESULT("OpenAComponent");
   2.380 +
   2.381 +    // !!! FIXME: this is wrong?
   2.382 +    enableIO = ((iscapture) ? 1 : 0);
   2.383 +    result = AudioUnitSetProperty(this->hidden->audioUnit,
   2.384 +                                  kAudioOutputUnitProperty_EnableIO,
   2.385 +                                  kAudioUnitScope_Input, input_bus,
   2.386 +                                  &enableIO, sizeof (enableIO));
   2.387 +    CHECK_RESULT("AudioUnitSetProperty (kAudioUnitProperty_EnableIO input)");
   2.388 +
   2.389 +    // !!! FIXME: this is wrong?
   2.390 +    enableIO = ((iscapture) ? 0 : 1);
   2.391 +    result = AudioUnitSetProperty(this->hidden->audioUnit,
   2.392 +                                  kAudioOutputUnitProperty_EnableIO,
   2.393 +                                  kAudioUnitScope_Output, output_bus,
   2.394 +                                  &enableIO, sizeof (enableIO));
   2.395 +    CHECK_RESULT("AudioUnitSetProperty (kAudioUnitProperty_EnableIO output)");
   2.396 +
   2.397 +    result = AudioUnitSetProperty(this->hidden->audioUnit,
   2.398 +                                  kAudioOutputUnitProperty_CurrentDevice,
   2.399 +                                  kAudioUnitScope_Global, 0,
   2.400 +                                  &this->hidden->deviceID,
   2.401 +                                  sizeof (AudioDeviceID));
   2.402 +    CHECK_RESULT("AudioUnitSetProperty (kAudioOutputUnitProperty_CurrentDevice)");
   2.403 +
   2.404 +    /* Set the data format of the audio unit. */
   2.405 +    result = AudioUnitSetProperty(this->hidden->audioUnit,
   2.406 +                                  kAudioUnitProperty_StreamFormat,
   2.407 +                                  scope, bus, strdesc, sizeof (*strdesc));
   2.408 +    CHECK_RESULT("AudioUnitSetProperty (kAudioUnitProperty_StreamFormat)");
   2.409 +
   2.410 +    /* Set the audio callback */
   2.411 +    memset(&callback, '\0', sizeof (AURenderCallbackStruct));
   2.412 +    callback.inputProc = ((iscapture) ? inputCallback : outputCallback);
   2.413 +    callback.inputProcRefCon = this;
   2.414 +    result = AudioUnitSetProperty(this->hidden->audioUnit,
   2.415 +                                  kAudioUnitProperty_SetRenderCallback,
   2.416 +                                  scope, bus, &callback, sizeof (callback));
   2.417 +    CHECK_RESULT("AudioUnitSetProperty (kAudioUnitProperty_SetInputCallback)");
   2.418 +
   2.419 +    /* Calculate the final parameters for this audio specification */
   2.420 +    SDL_CalculateAudioSpec(&this->spec);
   2.421 +
   2.422 +    /* Allocate a sample buffer */
   2.423 +    this->hidden->bufferOffset = this->hidden->bufferSize = this->spec.size;
   2.424 +    this->hidden->buffer = SDL_malloc(this->hidden->bufferSize);
   2.425 +
   2.426 +    result = AudioUnitInitialize(this->hidden->audioUnit);
   2.427 +    CHECK_RESULT("AudioUnitInitialize");
   2.428 +
   2.429 +    /* Finally, start processing of the audio unit */
   2.430 +    result = AudioOutputUnitStart(this->hidden->audioUnit);
   2.431 +    CHECK_RESULT("AudioOutputUnitStart");
   2.432 +
   2.433 +    /* We're running! */
   2.434 +    return 1;
   2.435 +}
   2.436 +
   2.437  
   2.438  int
   2.439  COREAUDIO_OpenAudio(_THIS, const char *devname, int iscapture)
   2.440  {
   2.441 -    OSStatus result = noErr;
   2.442 -    Component comp;
   2.443 -    ComponentDescription desc;
   2.444 -    struct AudioUnitInputCallback callback;
   2.445      AudioStreamBasicDescription strdesc;
   2.446      SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
   2.447      int valid_datatype = 0;
   2.448 @@ -204,7 +503,7 @@
   2.449      }
   2.450      SDL_memset(this->hidden, 0, (sizeof *this->hidden));
   2.451  
   2.452 -    /* !!! FIXME: check devname and iscapture... */
   2.453 +    this->hidden->isCapture = iscapture;
   2.454  
   2.455      /* Setup a AudioStreamBasicDescription with the requested format */
   2.456      memset(&strdesc, '\0', sizeof(AudioStreamBasicDescription));
   2.457 @@ -251,53 +550,11 @@
   2.458      strdesc.mBytesPerPacket =
   2.459          strdesc.mBytesPerFrame * strdesc.mFramesPerPacket;
   2.460  
   2.461 -    /* Locate the default output audio unit */
   2.462 -    memset(&desc, '\0', sizeof(ComponentDescription));
   2.463 -    desc.componentType = kAudioUnitComponentType;
   2.464 -    desc.componentSubType = kAudioUnitSubType_Output;
   2.465 -    desc.componentManufacturer = kAudioUnitID_DefaultOutput;
   2.466 -    desc.componentFlags = 0;
   2.467 -    desc.componentFlagsMask = 0;
   2.468 -
   2.469 -    comp = FindNextComponent(NULL, &desc);
   2.470 -    if (comp == NULL) {
   2.471 -        COREAUDIO_CloseAudio(this);
   2.472 -        SDL_SetError
   2.473 -            ("Failed to start CoreAudio: FindNextComponent returned NULL");
   2.474 -        return 0;
   2.475 +    if (!prepare_audiounit(this, devname, iscapture, &strdesc)) {
   2.476 +        return 0;  /* prepare_audiounit() will call SDL_SetError()... */
   2.477      }
   2.478  
   2.479 -    /* Open & initialize the default output audio unit */
   2.480 -    result = OpenAComponent(comp, &this->hidden->outputAudioUnit);
   2.481 -    CHECK_RESULT("OpenAComponent")
   2.482 -        result = AudioUnitInitialize(this->hidden->outputAudioUnit);
   2.483 -    CHECK_RESULT("AudioUnitInitialize")
   2.484 -        /* Set the input format of the audio unit. */
   2.485 -        result = AudioUnitSetProperty(this->hidden->outputAudioUnit,
   2.486 -                                      kAudioUnitProperty_StreamFormat,
   2.487 -                                      kAudioUnitScope_Input,
   2.488 -                                      0, &strdesc, sizeof(strdesc));
   2.489 -    CHECK_RESULT("AudioUnitSetProperty (kAudioUnitProperty_StreamFormat)")
   2.490 -        /* Set the audio callback */
   2.491 -        callback.inputProc = audioCallback;
   2.492 -    callback.inputProcRefCon = this;
   2.493 -    result = AudioUnitSetProperty(this->hidden->outputAudioUnit,
   2.494 -                                  kAudioUnitProperty_SetInputCallback,
   2.495 -                                  kAudioUnitScope_Input,
   2.496 -                                  0, &callback, sizeof(callback));
   2.497 -    CHECK_RESULT("AudioUnitSetProperty (kAudioUnitProperty_SetInputCallback)")
   2.498 -        /* Calculate the final parameters for this audio specification */
   2.499 -        SDL_CalculateAudioSpec(&this->spec);
   2.500 -
   2.501 -    /* Allocate a sample buffer */
   2.502 -    this->hidden->bufferOffset = this->hidden->bufferSize = this->spec.size;
   2.503 -    this->hidden->buffer = SDL_malloc(this->hidden->bufferSize);
   2.504 -
   2.505 -    /* Finally, start processing of the audio unit */
   2.506 -    result = AudioOutputUnitStart(this->hidden->outputAudioUnit);
   2.507 -    CHECK_RESULT("AudioOutputUnitStart")
   2.508 -        /* We're running! */
   2.509 -        return (1);
   2.510 +    return 1;  /* good to go. */
   2.511  }
   2.512  
   2.513  /* vi: set ts=4 sw=4 expandtab: */
     3.1 --- a/src/audio/macosx/SDL_coreaudio.h	Sun Oct 01 05:24:03 2006 +0000
     3.2 +++ b/src/audio/macosx/SDL_coreaudio.h	Tue Oct 03 05:58:44 2006 +0000
     3.3 @@ -31,10 +31,12 @@
     3.4  
     3.5  struct SDL_PrivateAudioData
     3.6  {
     3.7 -    AudioUnit outputAudioUnit;
     3.8 +    AudioUnit audioUnit;
     3.9      void *buffer;
    3.10      UInt32 bufferOffset;
    3.11      UInt32 bufferSize;
    3.12 +    AudioDeviceID deviceID;
    3.13 +    int isCapture;
    3.14  };
    3.15  
    3.16  #endif /* _SDL_coreaudio_h */