diff Alc/backends/null.c @ 0:f9476ff7637e

initial forking of open-al to create multiple listeners
author Robert McIntyre <rlm@mit.edu>
date Tue, 25 Oct 2011 13:02:31 -0700
parents
children
line wrap: on
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/Alc/backends/null.c	Tue Oct 25 13:02:31 2011 -0700
     1.3 @@ -0,0 +1,164 @@
     1.4 +/**
     1.5 + * OpenAL cross platform audio library
     1.6 + * Copyright (C) 2010 by Chris Robinson
     1.7 + * This library is free software; you can redistribute it and/or
     1.8 + *  modify it under the terms of the GNU Library General Public
     1.9 + *  License as published by the Free Software Foundation; either
    1.10 + *  version 2 of the License, or (at your option) any later version.
    1.11 + *
    1.12 + * This library is distributed in the hope that it will be useful,
    1.13 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    1.14 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    1.15 + *  Library General Public License for more details.
    1.16 + *
    1.17 + * You should have received a copy of the GNU Library General Public
    1.18 + *  License along with this library; if not, write to the
    1.19 + *  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    1.20 + *  Boston, MA  02111-1307, USA.
    1.21 + * Or go to http://www.gnu.org/copyleft/lgpl.html
    1.22 + */
    1.23 +
    1.24 +#include "config.h"
    1.25 +
    1.26 +#include <stdlib.h>
    1.27 +#include "alMain.h"
    1.28 +#include "AL/al.h"
    1.29 +#include "AL/alc.h"
    1.30 +
    1.31 +
    1.32 +typedef struct {
    1.33 +    volatile int killNow;
    1.34 +    ALvoid *thread;
    1.35 +} null_data;
    1.36 +
    1.37 +
    1.38 +static const ALCchar nullDevice[] = "No Output";
    1.39 +
    1.40 +static ALuint NullProc(ALvoid *ptr)
    1.41 +{
    1.42 +    ALCdevice *Device = (ALCdevice*)ptr;
    1.43 +    null_data *data = (null_data*)Device->ExtraData;
    1.44 +    ALuint now, start;
    1.45 +    ALuint64 avail, done;
    1.46 +    const ALuint restTime = (ALuint64)Device->UpdateSize * 1000 /
    1.47 +                            Device->Frequency / 2;
    1.48 +
    1.49 +    done = 0;
    1.50 +    start = timeGetTime();
    1.51 +    while(!data->killNow && Device->Connected)
    1.52 +    {
    1.53 +        now = timeGetTime();
    1.54 +
    1.55 +        avail = (ALuint64)(now-start) * Device->Frequency / 1000;
    1.56 +        if(avail < done)
    1.57 +        {
    1.58 +            /* Timer wrapped. Add the remainder of the cycle to the available
    1.59 +             * count and reset the number of samples done */
    1.60 +            avail += (ALuint64)0xFFFFFFFFu*Device->Frequency/1000 - done;
    1.61 +            done = 0;
    1.62 +        }
    1.63 +        if(avail-done < Device->UpdateSize)
    1.64 +        {
    1.65 +            Sleep(restTime);
    1.66 +            continue;
    1.67 +        }
    1.68 +
    1.69 +        while(avail-done >= Device->UpdateSize)
    1.70 +        {
    1.71 +            aluMixData(Device, NULL, Device->UpdateSize);
    1.72 +            done += Device->UpdateSize;
    1.73 +        }
    1.74 +    }
    1.75 +
    1.76 +    return 0;
    1.77 +}
    1.78 +
    1.79 +static ALCboolean null_open_playback(ALCdevice *device, const ALCchar *deviceName)
    1.80 +{
    1.81 +    null_data *data;
    1.82 +
    1.83 +    if(!deviceName)
    1.84 +        deviceName = nullDevice;
    1.85 +    else if(strcmp(deviceName, nullDevice) != 0)
    1.86 +        return ALC_FALSE;
    1.87 +
    1.88 +    data = (null_data*)calloc(1, sizeof(*data));
    1.89 +
    1.90 +    device->szDeviceName = strdup(deviceName);
    1.91 +    device->ExtraData = data;
    1.92 +    return ALC_TRUE;
    1.93 +}
    1.94 +
    1.95 +static void null_close_playback(ALCdevice *device)
    1.96 +{
    1.97 +    null_data *data = (null_data*)device->ExtraData;
    1.98 +
    1.99 +    free(data);
   1.100 +    device->ExtraData = NULL;
   1.101 +}
   1.102 +
   1.103 +static ALCboolean null_reset_playback(ALCdevice *device)
   1.104 +{
   1.105 +    null_data *data = (null_data*)device->ExtraData;
   1.106 +
   1.107 +    SetDefaultWFXChannelOrder(device);
   1.108 +
   1.109 +    data->thread = StartThread(NullProc, device);
   1.110 +    if(data->thread == NULL)
   1.111 +        return ALC_FALSE;
   1.112 +
   1.113 +    return ALC_TRUE;
   1.114 +}
   1.115 +
   1.116 +static void null_stop_playback(ALCdevice *device)
   1.117 +{
   1.118 +    null_data *data = (null_data*)device->ExtraData;
   1.119 +
   1.120 +    if(!data->thread)
   1.121 +        return;
   1.122 +
   1.123 +    data->killNow = 1;
   1.124 +    StopThread(data->thread);
   1.125 +    data->thread = NULL;
   1.126 +
   1.127 +    data->killNow = 0;
   1.128 +}
   1.129 +
   1.130 +
   1.131 +static const BackendFuncs null_funcs = {
   1.132 +    null_open_playback,
   1.133 +    null_close_playback,
   1.134 +    null_reset_playback,
   1.135 +    null_stop_playback,
   1.136 +    NULL,
   1.137 +    NULL,
   1.138 +    NULL,
   1.139 +    NULL,
   1.140 +    NULL,
   1.141 +    NULL
   1.142 +};
   1.143 +
   1.144 +ALCboolean alc_null_init(BackendFuncs *func_list)
   1.145 +{
   1.146 +    *func_list = null_funcs;
   1.147 +    return ALC_TRUE;
   1.148 +}
   1.149 +
   1.150 +void alc_null_deinit(void)
   1.151 +{
   1.152 +}
   1.153 +
   1.154 +void alc_null_probe(enum DevProbe type)
   1.155 +{
   1.156 +    switch(type)
   1.157 +    {
   1.158 +        case DEVICE_PROBE:
   1.159 +            AppendDeviceList(nullDevice);
   1.160 +            break;
   1.161 +        case ALL_DEVICE_PROBE:
   1.162 +            AppendAllDeviceList(nullDevice);
   1.163 +            break;
   1.164 +        case CAPTURE_DEVICE_PROBE:
   1.165 +            break;
   1.166 +    }
   1.167 +}