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