annotate 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
rev   line source
rlm@0 1 /**
rlm@0 2 * OpenAL cross platform audio library
rlm@0 3 * Copyright (C) 2010 by Chris Robinson
rlm@0 4 * This library is free software; you can redistribute it and/or
rlm@0 5 * modify it under the terms of the GNU Library General Public
rlm@0 6 * License as published by the Free Software Foundation; either
rlm@0 7 * version 2 of the License, or (at your option) any later version.
rlm@0 8 *
rlm@0 9 * This library is distributed in the hope that it will be useful,
rlm@0 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
rlm@0 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
rlm@0 12 * Library General Public License for more details.
rlm@0 13 *
rlm@0 14 * You should have received a copy of the GNU Library General Public
rlm@0 15 * License along with this library; if not, write to the
rlm@0 16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
rlm@0 17 * Boston, MA 02111-1307, USA.
rlm@0 18 * Or go to http://www.gnu.org/copyleft/lgpl.html
rlm@0 19 */
rlm@0 20
rlm@0 21 #include "config.h"
rlm@0 22
rlm@0 23 #include <stdlib.h>
rlm@0 24 #include "alMain.h"
rlm@0 25 #include "AL/al.h"
rlm@0 26 #include "AL/alc.h"
rlm@0 27
rlm@0 28
rlm@0 29 typedef struct {
rlm@0 30 volatile int killNow;
rlm@0 31 ALvoid *thread;
rlm@0 32 } null_data;
rlm@0 33
rlm@0 34
rlm@0 35 static const ALCchar nullDevice[] = "No Output";
rlm@0 36
rlm@0 37 static ALuint NullProc(ALvoid *ptr)
rlm@0 38 {
rlm@0 39 ALCdevice *Device = (ALCdevice*)ptr;
rlm@0 40 null_data *data = (null_data*)Device->ExtraData;
rlm@0 41 ALuint now, start;
rlm@0 42 ALuint64 avail, done;
rlm@0 43 const ALuint restTime = (ALuint64)Device->UpdateSize * 1000 /
rlm@0 44 Device->Frequency / 2;
rlm@0 45
rlm@0 46 done = 0;
rlm@0 47 start = timeGetTime();
rlm@0 48 while(!data->killNow && Device->Connected)
rlm@0 49 {
rlm@0 50 now = timeGetTime();
rlm@0 51
rlm@0 52 avail = (ALuint64)(now-start) * Device->Frequency / 1000;
rlm@0 53 if(avail < done)
rlm@0 54 {
rlm@0 55 /* Timer wrapped. Add the remainder of the cycle to the available
rlm@0 56 * count and reset the number of samples done */
rlm@0 57 avail += (ALuint64)0xFFFFFFFFu*Device->Frequency/1000 - done;
rlm@0 58 done = 0;
rlm@0 59 }
rlm@0 60 if(avail-done < Device->UpdateSize)
rlm@0 61 {
rlm@0 62 Sleep(restTime);
rlm@0 63 continue;
rlm@0 64 }
rlm@0 65
rlm@0 66 while(avail-done >= Device->UpdateSize)
rlm@0 67 {
rlm@0 68 aluMixData(Device, NULL, Device->UpdateSize);
rlm@0 69 done += Device->UpdateSize;
rlm@0 70 }
rlm@0 71 }
rlm@0 72
rlm@0 73 return 0;
rlm@0 74 }
rlm@0 75
rlm@0 76 static ALCboolean null_open_playback(ALCdevice *device, const ALCchar *deviceName)
rlm@0 77 {
rlm@0 78 null_data *data;
rlm@0 79
rlm@0 80 if(!deviceName)
rlm@0 81 deviceName = nullDevice;
rlm@0 82 else if(strcmp(deviceName, nullDevice) != 0)
rlm@0 83 return ALC_FALSE;
rlm@0 84
rlm@0 85 data = (null_data*)calloc(1, sizeof(*data));
rlm@0 86
rlm@0 87 device->szDeviceName = strdup(deviceName);
rlm@0 88 device->ExtraData = data;
rlm@0 89 return ALC_TRUE;
rlm@0 90 }
rlm@0 91
rlm@0 92 static void null_close_playback(ALCdevice *device)
rlm@0 93 {
rlm@0 94 null_data *data = (null_data*)device->ExtraData;
rlm@0 95
rlm@0 96 free(data);
rlm@0 97 device->ExtraData = NULL;
rlm@0 98 }
rlm@0 99
rlm@0 100 static ALCboolean null_reset_playback(ALCdevice *device)
rlm@0 101 {
rlm@0 102 null_data *data = (null_data*)device->ExtraData;
rlm@0 103
rlm@0 104 SetDefaultWFXChannelOrder(device);
rlm@0 105
rlm@0 106 data->thread = StartThread(NullProc, device);
rlm@0 107 if(data->thread == NULL)
rlm@0 108 return ALC_FALSE;
rlm@0 109
rlm@0 110 return ALC_TRUE;
rlm@0 111 }
rlm@0 112
rlm@0 113 static void null_stop_playback(ALCdevice *device)
rlm@0 114 {
rlm@0 115 null_data *data = (null_data*)device->ExtraData;
rlm@0 116
rlm@0 117 if(!data->thread)
rlm@0 118 return;
rlm@0 119
rlm@0 120 data->killNow = 1;
rlm@0 121 StopThread(data->thread);
rlm@0 122 data->thread = NULL;
rlm@0 123
rlm@0 124 data->killNow = 0;
rlm@0 125 }
rlm@0 126
rlm@0 127
rlm@0 128 static const BackendFuncs null_funcs = {
rlm@0 129 null_open_playback,
rlm@0 130 null_close_playback,
rlm@0 131 null_reset_playback,
rlm@0 132 null_stop_playback,
rlm@0 133 NULL,
rlm@0 134 NULL,
rlm@0 135 NULL,
rlm@0 136 NULL,
rlm@0 137 NULL,
rlm@0 138 NULL
rlm@0 139 };
rlm@0 140
rlm@0 141 ALCboolean alc_null_init(BackendFuncs *func_list)
rlm@0 142 {
rlm@0 143 *func_list = null_funcs;
rlm@0 144 return ALC_TRUE;
rlm@0 145 }
rlm@0 146
rlm@0 147 void alc_null_deinit(void)
rlm@0 148 {
rlm@0 149 }
rlm@0 150
rlm@0 151 void alc_null_probe(enum DevProbe type)
rlm@0 152 {
rlm@0 153 switch(type)
rlm@0 154 {
rlm@0 155 case DEVICE_PROBE:
rlm@0 156 AppendDeviceList(nullDevice);
rlm@0 157 break;
rlm@0 158 case ALL_DEVICE_PROBE:
rlm@0 159 AppendAllDeviceList(nullDevice);
rlm@0 160 break;
rlm@0 161 case CAPTURE_DEVICE_PROBE:
rlm@0 162 break;
rlm@0 163 }
rlm@0 164 }