Search
lxdream.org :: lxdream/src/drivers/audio_osx.c
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 (15 years ago)
permissions -rw-r--r--
last change Commit work-in-progress CoreAudio driver
(along with various changes to the audio subsystem)
view annotate diff log raw
     1 /**
     2  * $Id$
     3  * 
     4  * The darwin core-audio audio driver
     5  *
     6  * Copyright (c) 2008 Nathan Keynes.
     7  *
     8  * This program is free software; you can redistribute it and/or modify
     9  * it under the terms of the GNU General Public License as published by
    10  * the Free Software Foundation; either version 2 of the License, or
    11  * (at your option) any later version.
    12  *
    13  * This program is distributed in the hope that it will be useful,
    14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    16  * GNU General Public License for more details.
    17  */
    18 #include <stdio.h>
    19 #include <unistd.h>
    20 #include <AudioToolbox/AudioToolbox.h>
    21 #include <AudioUnit/AudioUnitProperties.h>
    22 #include "aica/audio.h"
    23 #include "lxdream.h"
    25 static AudioUnit output_au;
    26 static volatile audio_buffer_t output_buffer = NULL;
    27 static int sample_size;
    29 OSStatus audio_osx_callback( void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags,
    30                              const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber,
    31                              UInt32 inNumberFrames, AudioBufferList *ioData )
    32 {
    33     char *output = ioData->mBuffers[0].mData;
    34     int data_requested = inNumberFrames * sample_size;
    36     while( output_buffer != NULL && data_requested > 0 ) {
    37         int copysize = output_buffer->length - output_buffer->posn;
    38         if( copysize > data_requested ) {
    39             copysize = data_requested;
    40         }
    41         memcpy( output, &output_buffer->data[output_buffer->posn], copysize );
    42         output += copysize;
    43         data_requested -= copysize;
    44         output_buffer->posn += copysize;
    45         if( output_buffer->posn >= output_buffer->length ) {
    46             output_buffer = audio_next_read_buffer();
    47         }
    48     }
    49     if( data_requested > 0 ) {
    50         memset( output, 0, data_requested );
    51     }
    52     return noErr;
    53 }
    55 static gboolean audio_osx_shutdown()
    56 {
    57     AudioUnitUninitialize( output_au );
    58     CloseComponent( output_au );
    59     return TRUE;
    60 }
    62 static gboolean audio_osx_init()
    63 {
    64     AURenderCallbackStruct callbackData;
    65     AudioStreamBasicDescription outputDesc;
    66     UInt32 outputDescSize = sizeof(outputDesc);
    67     ComponentDescription cd;
    68     Component c;
    70     cd.componentType = kAudioUnitType_Output;
    71     cd.componentSubType = kAudioUnitSubType_DefaultOutput;
    72     cd.componentManufacturer = kAudioUnitManufacturer_Apple;
    73     cd.componentFlags = 0;
    74     cd.componentFlagsMask = 0;
    76     c = FindNextComponent( NULL, &cd );
    77     if( c == NULL ) {
    78         return FALSE;
    79     }
    81     if( OpenAComponent( c, &output_au ) != noErr ) {
    82         return FALSE;
    83     }
    85     if( AudioUnitGetProperty( output_au, kAudioUnitProperty_StreamFormat,
    86             kAudioUnitScope_Global, 0, &outputDesc, &outputDescSize ) != noErr ) {
    87         CloseComponent( output_au );
    88         return FALSE;
    89     }
    91     outputDesc.mSampleRate = DEFAULT_SAMPLE_RATE;
    92     sample_size = outputDesc.mBytesPerFrame;
    94     if( AudioUnitSetProperty( output_au, kAudioUnitProperty_StreamFormat,
    95             kAudioUnitScope_Global, 0, &outputDesc, sizeof(outputDesc) ) != noErr ) {
    96         CloseComponent( output_au );
    97         return FALSE;
    98     }
   100     if( AudioUnitInitialize( output_au ) != noErr ) {
   101         CloseComponent( output_au );
   102         return FALSE;
   103     }
   105     callbackData.inputProc = audio_osx_callback;
   106     callbackData.inputProcRefCon = NULL;
   107     if( AudioUnitSetProperty( output_au, kAudioUnitProperty_SetRenderCallback,
   108             kAudioUnitScope_Global, 0, &callbackData, sizeof(callbackData)) != noErr ) {
   109         audio_osx_shutdown();
   110         return FALSE;
   111     }
   113     return TRUE;
   114 }
   115 static gboolean audio_osx_process_buffer( audio_buffer_t buffer )
   116 {
   117     if( output_buffer == NULL ) {
   118         output_buffer = buffer;
   119         output_buffer->posn = 0;
   120         AudioOutputUnitStart(output_au);
   121         return FALSE;
   122     }
   123 }
   125 void audio_osx_start()
   126 {
   127 }
   129 void audio_osx_stop()
   130 {
   131 }
   134 struct audio_driver audio_osx_driver = { "osx", 
   135         DEFAULT_SAMPLE_RATE,
   136         AUDIO_FMT_FLOATST,
   137         audio_osx_init,
   138         audio_osx_start, 
   139         audio_osx_process_buffer,
   140         audio_osx_stop,
   141         audio_osx_shutdown};
.