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 786:8f6ece92500e
prev736:a02d1475ccfd
author nkeynes
date Mon Aug 04 05:58:53 2008 +0000 (15 years ago)
permissions -rw-r--r--
last change Fix typo/array overrun
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@701
    20
#include <CoreAudio/CoreAudio.h>
nkeynes@697
    21
#include "aica/audio.h"
nkeynes@697
    22
#include "lxdream.h"
nkeynes@697
    23
nkeynes@701
    24
#define BUFFER_SIZE (sizeof(float)*2*2205)
nkeynes@701
    25
nkeynes@701
    26
static AudioDeviceID output_device;
nkeynes@697
    27
static volatile audio_buffer_t output_buffer = NULL;
nkeynes@701
    28
static uint32_t buffer_size;
nkeynes@697
    29
nkeynes@701
    30
OSStatus audio_osx_callback( AudioDeviceID inDevice,
nkeynes@736
    31
                             const AudioTimeStamp *inNow,
nkeynes@736
    32
                             const AudioBufferList *inInputData,
nkeynes@736
    33
                             const AudioTimeStamp *inInputTime,
nkeynes@736
    34
                             AudioBufferList *outOutputData,
nkeynes@736
    35
                             const AudioTimeStamp *inOutputTime,
nkeynes@736
    36
                             void *inClientData)
nkeynes@697
    37
{
nkeynes@701
    38
    char *output = outOutputData->mBuffers[0].mData;
nkeynes@701
    39
    int data_requested = buffer_size;
nkeynes@697
    40
nkeynes@697
    41
    while( output_buffer != NULL && data_requested > 0 ) {
nkeynes@697
    42
        int copysize = output_buffer->length - output_buffer->posn;
nkeynes@697
    43
        if( copysize > data_requested ) {
nkeynes@697
    44
            copysize = data_requested;
nkeynes@697
    45
        }
nkeynes@697
    46
        memcpy( output, &output_buffer->data[output_buffer->posn], copysize );
nkeynes@697
    47
        output += copysize;
nkeynes@697
    48
        data_requested -= copysize;
nkeynes@697
    49
        output_buffer->posn += copysize;
nkeynes@697
    50
        if( output_buffer->posn >= output_buffer->length ) {
nkeynes@697
    51
            output_buffer = audio_next_read_buffer();
nkeynes@697
    52
        }
nkeynes@697
    53
    }
nkeynes@697
    54
    if( data_requested > 0 ) {
nkeynes@697
    55
        memset( output, 0, data_requested );
nkeynes@697
    56
    }
nkeynes@697
    57
    return noErr;
nkeynes@697
    58
}
nkeynes@697
    59
nkeynes@697
    60
static gboolean audio_osx_shutdown()
nkeynes@697
    61
{
nkeynes@701
    62
    AudioDeviceStop( output_device, audio_osx_callback );
nkeynes@701
    63
    AudioDeviceRemoveIOProc( output_device, audio_osx_callback );
nkeynes@697
    64
    return TRUE;
nkeynes@697
    65
}
nkeynes@697
    66
nkeynes@697
    67
static gboolean audio_osx_init()
nkeynes@697
    68
{
nkeynes@701
    69
    UInt32 size = sizeof(output_device);
nkeynes@697
    70
    AudioStreamBasicDescription outputDesc;
nkeynes@697
    71
    UInt32 outputDescSize = sizeof(outputDesc);
nkeynes@736
    72
nkeynes@701
    73
    if( AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice,
nkeynes@736
    74
            &size, &output_device) != noErr ||
nkeynes@736
    75
            output_device == kAudioDeviceUnknown ) {
nkeynes@701
    76
        return FALSE;
nkeynes@701
    77
    }
nkeynes@736
    78
nkeynes@701
    79
    if( AudioDeviceGetProperty( output_device, 1, 0, kAudioDevicePropertyStreamFormat,
nkeynes@701
    80
            &outputDescSize, &outputDesc ) != noErr ) {
nkeynes@697
    81
        return FALSE;
nkeynes@697
    82
    }
nkeynes@736
    83
nkeynes@701
    84
    buffer_size = BUFFER_SIZE;
nkeynes@736
    85
nkeynes@701
    86
    if( AudioDeviceSetProperty( output_device, 0, 0, 0, kAudioDevicePropertyBufferSize,
nkeynes@736
    87
            sizeof(buffer_size), &buffer_size ) != noErr ) {
nkeynes@697
    88
        return FALSE;
nkeynes@697
    89
    }
nkeynes@736
    90
nkeynes@701
    91
    AudioDeviceAddIOProc( output_device, audio_osx_callback, NULL );    
nkeynes@697
    92
    return TRUE;
nkeynes@697
    93
}
nkeynes@697
    94
static gboolean audio_osx_process_buffer( audio_buffer_t buffer )
nkeynes@697
    95
{
nkeynes@697
    96
    if( output_buffer == NULL ) {
nkeynes@697
    97
        output_buffer = buffer;
nkeynes@697
    98
        output_buffer->posn = 0;
nkeynes@701
    99
        AudioDeviceStart(output_device, audio_osx_callback);
nkeynes@697
   100
    }
nkeynes@786
   101
    return FALSE;
nkeynes@697
   102
}
nkeynes@697
   103
nkeynes@697
   104
void audio_osx_start()
nkeynes@697
   105
{
nkeynes@701
   106
    if( output_buffer != NULL ) {
nkeynes@701
   107
        AudioDeviceStart(output_device, audio_osx_callback);
nkeynes@701
   108
    }
nkeynes@697
   109
}
nkeynes@697
   110
nkeynes@697
   111
void audio_osx_stop()
nkeynes@697
   112
{
nkeynes@701
   113
    AudioDeviceStop( output_device, audio_osx_callback );
nkeynes@697
   114
}
nkeynes@697
   115
nkeynes@697
   116
nkeynes@700
   117
struct audio_driver audio_osx_driver = { 
nkeynes@701
   118
        "osx",
nkeynes@700
   119
        N_("OS X CoreAudio system driver"), 
nkeynes@697
   120
        DEFAULT_SAMPLE_RATE,
nkeynes@697
   121
        AUDIO_FMT_FLOATST,
nkeynes@697
   122
        audio_osx_init,
nkeynes@697
   123
        audio_osx_start, 
nkeynes@697
   124
        audio_osx_process_buffer,
nkeynes@697
   125
        audio_osx_stop,
nkeynes@697
   126
        audio_osx_shutdown};
nkeynes@697
   127
.