Mercurial > audio-send
changeset 2:82b9267a3e19
removed all backends except for the send backend
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Tue, 25 Oct 2011 13:11:31 -0700 |
parents | c41d773a85fb |
children | 96298d83959c |
files | Alc/backends/alsa.c Alc/backends/coreaudio.c Alc/backends/dsound.c Alc/backends/mmdevapi.c Alc/backends/opensl.c Alc/backends/oss.c Alc/backends/portaudio.c Alc/backends/pulseaudio.c Alc/backends/sndio.c Alc/backends/solaris.c Alc/backends/wave.c Alc/backends/winmm.c CMakeLists.txt |
diffstat | 13 files changed, 0 insertions(+), 8119 deletions(-) [+] |
line wrap: on
line diff
1.1 --- a/Alc/backends/alsa.c Tue Oct 25 13:03:35 2011 -0700 1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 1.3 @@ -1,1138 +0,0 @@ 1.4 -/** 1.5 - * OpenAL cross platform audio library 1.6 - * Copyright (C) 1999-2007 by authors. 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 <stdio.h> 1.28 -#include <memory.h> 1.29 - 1.30 -#include "alMain.h" 1.31 - 1.32 -#include <alsa/asoundlib.h> 1.33 - 1.34 - 1.35 -static const ALCchar alsaDevice[] = "ALSA Default"; 1.36 - 1.37 - 1.38 -static void *alsa_handle; 1.39 -#ifdef HAVE_DYNLOAD 1.40 -#define MAKE_FUNC(f) static typeof(f) * p##f 1.41 -MAKE_FUNC(snd_strerror); 1.42 -MAKE_FUNC(snd_pcm_open); 1.43 -MAKE_FUNC(snd_pcm_close); 1.44 -MAKE_FUNC(snd_pcm_nonblock); 1.45 -MAKE_FUNC(snd_pcm_frames_to_bytes); 1.46 -MAKE_FUNC(snd_pcm_bytes_to_frames); 1.47 -MAKE_FUNC(snd_pcm_hw_params_malloc); 1.48 -MAKE_FUNC(snd_pcm_hw_params_free); 1.49 -MAKE_FUNC(snd_pcm_hw_params_any); 1.50 -MAKE_FUNC(snd_pcm_hw_params_set_access); 1.51 -MAKE_FUNC(snd_pcm_hw_params_set_format); 1.52 -MAKE_FUNC(snd_pcm_hw_params_set_channels); 1.53 -MAKE_FUNC(snd_pcm_hw_params_set_periods_near); 1.54 -MAKE_FUNC(snd_pcm_hw_params_set_rate_near); 1.55 -MAKE_FUNC(snd_pcm_hw_params_set_rate); 1.56 -MAKE_FUNC(snd_pcm_hw_params_set_rate_resample); 1.57 -MAKE_FUNC(snd_pcm_hw_params_set_buffer_time_near); 1.58 -MAKE_FUNC(snd_pcm_hw_params_set_period_time_near); 1.59 -MAKE_FUNC(snd_pcm_hw_params_set_buffer_size_near); 1.60 -MAKE_FUNC(snd_pcm_hw_params_set_period_size_near); 1.61 -MAKE_FUNC(snd_pcm_hw_params_set_buffer_size_min); 1.62 -MAKE_FUNC(snd_pcm_hw_params_get_buffer_size); 1.63 -MAKE_FUNC(snd_pcm_hw_params_get_period_size); 1.64 -MAKE_FUNC(snd_pcm_hw_params_get_access); 1.65 -MAKE_FUNC(snd_pcm_hw_params_get_periods); 1.66 -MAKE_FUNC(snd_pcm_hw_params); 1.67 -MAKE_FUNC(snd_pcm_sw_params_malloc); 1.68 -MAKE_FUNC(snd_pcm_sw_params_current); 1.69 -MAKE_FUNC(snd_pcm_sw_params_set_avail_min); 1.70 -MAKE_FUNC(snd_pcm_sw_params); 1.71 -MAKE_FUNC(snd_pcm_sw_params_free); 1.72 -MAKE_FUNC(snd_pcm_prepare); 1.73 -MAKE_FUNC(snd_pcm_start); 1.74 -MAKE_FUNC(snd_pcm_resume); 1.75 -MAKE_FUNC(snd_pcm_wait); 1.76 -MAKE_FUNC(snd_pcm_state); 1.77 -MAKE_FUNC(snd_pcm_avail_update); 1.78 -MAKE_FUNC(snd_pcm_areas_silence); 1.79 -MAKE_FUNC(snd_pcm_mmap_begin); 1.80 -MAKE_FUNC(snd_pcm_mmap_commit); 1.81 -MAKE_FUNC(snd_pcm_readi); 1.82 -MAKE_FUNC(snd_pcm_writei); 1.83 -MAKE_FUNC(snd_pcm_drain); 1.84 -MAKE_FUNC(snd_pcm_recover); 1.85 -MAKE_FUNC(snd_pcm_info_malloc); 1.86 -MAKE_FUNC(snd_pcm_info_free); 1.87 -MAKE_FUNC(snd_pcm_info_set_device); 1.88 -MAKE_FUNC(snd_pcm_info_set_subdevice); 1.89 -MAKE_FUNC(snd_pcm_info_set_stream); 1.90 -MAKE_FUNC(snd_pcm_info_get_name); 1.91 -MAKE_FUNC(snd_ctl_pcm_next_device); 1.92 -MAKE_FUNC(snd_ctl_pcm_info); 1.93 -MAKE_FUNC(snd_ctl_open); 1.94 -MAKE_FUNC(snd_ctl_close); 1.95 -MAKE_FUNC(snd_ctl_card_info_malloc); 1.96 -MAKE_FUNC(snd_ctl_card_info_free); 1.97 -MAKE_FUNC(snd_ctl_card_info); 1.98 -MAKE_FUNC(snd_ctl_card_info_get_name); 1.99 -MAKE_FUNC(snd_ctl_card_info_get_id); 1.100 -MAKE_FUNC(snd_card_next); 1.101 -#undef MAKE_FUNC 1.102 - 1.103 -#define snd_strerror psnd_strerror 1.104 -#define snd_pcm_open psnd_pcm_open 1.105 -#define snd_pcm_close psnd_pcm_close 1.106 -#define snd_pcm_nonblock psnd_pcm_nonblock 1.107 -#define snd_pcm_frames_to_bytes psnd_pcm_frames_to_bytes 1.108 -#define snd_pcm_bytes_to_frames psnd_pcm_bytes_to_frames 1.109 -#define snd_pcm_hw_params_malloc psnd_pcm_hw_params_malloc 1.110 -#define snd_pcm_hw_params_free psnd_pcm_hw_params_free 1.111 -#define snd_pcm_hw_params_any psnd_pcm_hw_params_any 1.112 -#define snd_pcm_hw_params_set_access psnd_pcm_hw_params_set_access 1.113 -#define snd_pcm_hw_params_set_format psnd_pcm_hw_params_set_format 1.114 -#define snd_pcm_hw_params_set_channels psnd_pcm_hw_params_set_channels 1.115 -#define snd_pcm_hw_params_set_periods_near psnd_pcm_hw_params_set_periods_near 1.116 -#define snd_pcm_hw_params_set_rate_near psnd_pcm_hw_params_set_rate_near 1.117 -#define snd_pcm_hw_params_set_rate psnd_pcm_hw_params_set_rate 1.118 -#define snd_pcm_hw_params_set_rate_resample psnd_pcm_hw_params_set_rate_resample 1.119 -#define snd_pcm_hw_params_set_buffer_time_near psnd_pcm_hw_params_set_buffer_time_near 1.120 -#define snd_pcm_hw_params_set_period_time_near psnd_pcm_hw_params_set_period_time_near 1.121 -#define snd_pcm_hw_params_set_buffer_size_near psnd_pcm_hw_params_set_buffer_size_near 1.122 -#define snd_pcm_hw_params_set_period_size_near psnd_pcm_hw_params_set_period_size_near 1.123 -#define snd_pcm_hw_params_set_buffer_size_min psnd_pcm_hw_params_set_buffer_size_min 1.124 -#define snd_pcm_hw_params_get_buffer_size psnd_pcm_hw_params_get_buffer_size 1.125 -#define snd_pcm_hw_params_get_period_size psnd_pcm_hw_params_get_period_size 1.126 -#define snd_pcm_hw_params_get_access psnd_pcm_hw_params_get_access 1.127 -#define snd_pcm_hw_params_get_periods psnd_pcm_hw_params_get_periods 1.128 -#define snd_pcm_hw_params psnd_pcm_hw_params 1.129 -#define snd_pcm_sw_params_malloc psnd_pcm_sw_params_malloc 1.130 -#define snd_pcm_sw_params_current psnd_pcm_sw_params_current 1.131 -#define snd_pcm_sw_params_set_avail_min psnd_pcm_sw_params_set_avail_min 1.132 -#define snd_pcm_sw_params psnd_pcm_sw_params 1.133 -#define snd_pcm_sw_params_free psnd_pcm_sw_params_free 1.134 -#define snd_pcm_prepare psnd_pcm_prepare 1.135 -#define snd_pcm_start psnd_pcm_start 1.136 -#define snd_pcm_resume psnd_pcm_resume 1.137 -#define snd_pcm_wait psnd_pcm_wait 1.138 -#define snd_pcm_state psnd_pcm_state 1.139 -#define snd_pcm_avail_update psnd_pcm_avail_update 1.140 -#define snd_pcm_areas_silence psnd_pcm_areas_silence 1.141 -#define snd_pcm_mmap_begin psnd_pcm_mmap_begin 1.142 -#define snd_pcm_mmap_commit psnd_pcm_mmap_commit 1.143 -#define snd_pcm_readi psnd_pcm_readi 1.144 -#define snd_pcm_writei psnd_pcm_writei 1.145 -#define snd_pcm_drain psnd_pcm_drain 1.146 -#define snd_pcm_recover psnd_pcm_recover 1.147 -#define snd_pcm_info_malloc psnd_pcm_info_malloc 1.148 -#define snd_pcm_info_free psnd_pcm_info_free 1.149 -#define snd_pcm_info_set_device psnd_pcm_info_set_device 1.150 -#define snd_pcm_info_set_subdevice psnd_pcm_info_set_subdevice 1.151 -#define snd_pcm_info_set_stream psnd_pcm_info_set_stream 1.152 -#define snd_pcm_info_get_name psnd_pcm_info_get_name 1.153 -#define snd_ctl_pcm_next_device psnd_ctl_pcm_next_device 1.154 -#define snd_ctl_pcm_info psnd_ctl_pcm_info 1.155 -#define snd_ctl_open psnd_ctl_open 1.156 -#define snd_ctl_close psnd_ctl_close 1.157 -#define snd_ctl_card_info_malloc psnd_ctl_card_info_malloc 1.158 -#define snd_ctl_card_info_free psnd_ctl_card_info_free 1.159 -#define snd_ctl_card_info psnd_ctl_card_info 1.160 -#define snd_ctl_card_info_get_name psnd_ctl_card_info_get_name 1.161 -#define snd_ctl_card_info_get_id psnd_ctl_card_info_get_id 1.162 -#define snd_card_next psnd_card_next 1.163 -#endif 1.164 - 1.165 - 1.166 -static ALCboolean alsa_load(void) 1.167 -{ 1.168 - if(!alsa_handle) 1.169 - { 1.170 -#ifdef HAVE_DYNLOAD 1.171 - alsa_handle = LoadLib("libasound.so.2"); 1.172 - if(!alsa_handle) 1.173 - return ALC_FALSE; 1.174 - 1.175 -#define LOAD_FUNC(f) do { \ 1.176 - p##f = GetSymbol(alsa_handle, #f); \ 1.177 - if(p##f == NULL) { \ 1.178 - CloseLib(alsa_handle); \ 1.179 - alsa_handle = NULL; \ 1.180 - return ALC_FALSE; \ 1.181 - } \ 1.182 -} while(0) 1.183 - LOAD_FUNC(snd_strerror); 1.184 - LOAD_FUNC(snd_pcm_open); 1.185 - LOAD_FUNC(snd_pcm_close); 1.186 - LOAD_FUNC(snd_pcm_nonblock); 1.187 - LOAD_FUNC(snd_pcm_frames_to_bytes); 1.188 - LOAD_FUNC(snd_pcm_bytes_to_frames); 1.189 - LOAD_FUNC(snd_pcm_hw_params_malloc); 1.190 - LOAD_FUNC(snd_pcm_hw_params_free); 1.191 - LOAD_FUNC(snd_pcm_hw_params_any); 1.192 - LOAD_FUNC(snd_pcm_hw_params_set_access); 1.193 - LOAD_FUNC(snd_pcm_hw_params_set_format); 1.194 - LOAD_FUNC(snd_pcm_hw_params_set_channels); 1.195 - LOAD_FUNC(snd_pcm_hw_params_set_periods_near); 1.196 - LOAD_FUNC(snd_pcm_hw_params_set_rate_near); 1.197 - LOAD_FUNC(snd_pcm_hw_params_set_rate); 1.198 - LOAD_FUNC(snd_pcm_hw_params_set_rate_resample); 1.199 - LOAD_FUNC(snd_pcm_hw_params_set_buffer_time_near); 1.200 - LOAD_FUNC(snd_pcm_hw_params_set_period_time_near); 1.201 - LOAD_FUNC(snd_pcm_hw_params_set_buffer_size_near); 1.202 - LOAD_FUNC(snd_pcm_hw_params_set_buffer_size_min); 1.203 - LOAD_FUNC(snd_pcm_hw_params_set_period_size_near); 1.204 - LOAD_FUNC(snd_pcm_hw_params_get_buffer_size); 1.205 - LOAD_FUNC(snd_pcm_hw_params_get_period_size); 1.206 - LOAD_FUNC(snd_pcm_hw_params_get_access); 1.207 - LOAD_FUNC(snd_pcm_hw_params_get_periods); 1.208 - LOAD_FUNC(snd_pcm_hw_params); 1.209 - LOAD_FUNC(snd_pcm_sw_params_malloc); 1.210 - LOAD_FUNC(snd_pcm_sw_params_current); 1.211 - LOAD_FUNC(snd_pcm_sw_params_set_avail_min); 1.212 - LOAD_FUNC(snd_pcm_sw_params); 1.213 - LOAD_FUNC(snd_pcm_sw_params_free); 1.214 - LOAD_FUNC(snd_pcm_prepare); 1.215 - LOAD_FUNC(snd_pcm_start); 1.216 - LOAD_FUNC(snd_pcm_resume); 1.217 - LOAD_FUNC(snd_pcm_wait); 1.218 - LOAD_FUNC(snd_pcm_state); 1.219 - LOAD_FUNC(snd_pcm_avail_update); 1.220 - LOAD_FUNC(snd_pcm_areas_silence); 1.221 - LOAD_FUNC(snd_pcm_mmap_begin); 1.222 - LOAD_FUNC(snd_pcm_mmap_commit); 1.223 - LOAD_FUNC(snd_pcm_readi); 1.224 - LOAD_FUNC(snd_pcm_writei); 1.225 - LOAD_FUNC(snd_pcm_drain); 1.226 - LOAD_FUNC(snd_pcm_recover); 1.227 - LOAD_FUNC(snd_pcm_info_malloc); 1.228 - LOAD_FUNC(snd_pcm_info_free); 1.229 - LOAD_FUNC(snd_pcm_info_set_device); 1.230 - LOAD_FUNC(snd_pcm_info_set_subdevice); 1.231 - LOAD_FUNC(snd_pcm_info_set_stream); 1.232 - LOAD_FUNC(snd_pcm_info_get_name); 1.233 - LOAD_FUNC(snd_ctl_pcm_next_device); 1.234 - LOAD_FUNC(snd_ctl_pcm_info); 1.235 - LOAD_FUNC(snd_ctl_open); 1.236 - LOAD_FUNC(snd_ctl_close); 1.237 - LOAD_FUNC(snd_ctl_card_info_malloc); 1.238 - LOAD_FUNC(snd_ctl_card_info_free); 1.239 - LOAD_FUNC(snd_ctl_card_info); 1.240 - LOAD_FUNC(snd_ctl_card_info_get_name); 1.241 - LOAD_FUNC(snd_ctl_card_info_get_id); 1.242 - LOAD_FUNC(snd_card_next); 1.243 -#undef LOAD_FUNC 1.244 -#else 1.245 - alsa_handle = (void*)0xDEADBEEF; 1.246 -#endif 1.247 - } 1.248 - return ALC_TRUE; 1.249 -} 1.250 - 1.251 - 1.252 -typedef struct { 1.253 - snd_pcm_t *pcmHandle; 1.254 - 1.255 - ALvoid *buffer; 1.256 - ALsizei size; 1.257 - 1.258 - ALboolean doCapture; 1.259 - RingBuffer *ring; 1.260 - 1.261 - volatile int killNow; 1.262 - ALvoid *thread; 1.263 -} alsa_data; 1.264 - 1.265 -typedef struct { 1.266 - ALCchar *name; 1.267 - char *card; 1.268 - int dev; 1.269 -} DevMap; 1.270 - 1.271 -static DevMap *allDevNameMap; 1.272 -static ALuint numDevNames; 1.273 -static DevMap *allCaptureDevNameMap; 1.274 -static ALuint numCaptureDevNames; 1.275 - 1.276 -static const char *device_prefix; 1.277 -static const char *capture_prefix; 1.278 - 1.279 - 1.280 -static DevMap *probe_devices(snd_pcm_stream_t stream, ALuint *count) 1.281 -{ 1.282 - snd_ctl_t *handle; 1.283 - int card, err, dev, idx; 1.284 - snd_ctl_card_info_t *info; 1.285 - snd_pcm_info_t *pcminfo; 1.286 - DevMap *DevList; 1.287 - char name[1024]; 1.288 - 1.289 - snd_ctl_card_info_malloc(&info); 1.290 - snd_pcm_info_malloc(&pcminfo); 1.291 - 1.292 - card = -1; 1.293 - if((err=snd_card_next(&card)) < 0) 1.294 - ERR("Failed to find a card: %s\n", snd_strerror(err)); 1.295 - 1.296 - DevList = malloc(sizeof(DevMap) * 1); 1.297 - DevList[0].name = strdup("ALSA Default"); 1.298 - DevList[0].card = NULL; 1.299 - DevList[0].dev = 0; 1.300 - idx = 1; 1.301 - while(card >= 0) 1.302 - { 1.303 - sprintf(name, "hw:%d", card); 1.304 - if((err = snd_ctl_open(&handle, name, 0)) < 0) 1.305 - { 1.306 - ERR("control open (%i): %s\n", card, snd_strerror(err)); 1.307 - goto next_card; 1.308 - } 1.309 - if((err = snd_ctl_card_info(handle, info)) < 0) 1.310 - { 1.311 - ERR("control hardware info (%i): %s\n", card, snd_strerror(err)); 1.312 - snd_ctl_close(handle); 1.313 - goto next_card; 1.314 - } 1.315 - 1.316 - dev = -1; 1.317 - while(1) 1.318 - { 1.319 - const char *cname, *dname, *cid; 1.320 - void *temp; 1.321 - 1.322 - if(snd_ctl_pcm_next_device(handle, &dev) < 0) 1.323 - ERR("snd_ctl_pcm_next_device failed\n"); 1.324 - if(dev < 0) 1.325 - break; 1.326 - 1.327 - snd_pcm_info_set_device(pcminfo, dev); 1.328 - snd_pcm_info_set_subdevice(pcminfo, 0); 1.329 - snd_pcm_info_set_stream(pcminfo, stream); 1.330 - if((err = snd_ctl_pcm_info(handle, pcminfo)) < 0) { 1.331 - if(err != -ENOENT) 1.332 - ERR("control digital audio info (%i): %s\n", card, snd_strerror(err)); 1.333 - continue; 1.334 - } 1.335 - 1.336 - temp = realloc(DevList, sizeof(DevMap) * (idx+1)); 1.337 - if(temp) 1.338 - { 1.339 - DevList = temp; 1.340 - cname = snd_ctl_card_info_get_name(info); 1.341 - dname = snd_pcm_info_get_name(pcminfo); 1.342 - cid = snd_ctl_card_info_get_id(info); 1.343 - snprintf(name, sizeof(name), "%s, %s (CARD=%s,DEV=%d)", 1.344 - cname, dname, cid, dev); 1.345 - DevList[idx].name = strdup(name); 1.346 - DevList[idx].card = strdup(cid); 1.347 - DevList[idx].dev = dev; 1.348 - idx++; 1.349 - } 1.350 - } 1.351 - snd_ctl_close(handle); 1.352 - next_card: 1.353 - if(snd_card_next(&card) < 0) { 1.354 - ERR("snd_card_next failed\n"); 1.355 - break; 1.356 - } 1.357 - } 1.358 - 1.359 - snd_pcm_info_free(pcminfo); 1.360 - snd_ctl_card_info_free(info); 1.361 - 1.362 - *count = idx; 1.363 - return DevList; 1.364 -} 1.365 - 1.366 - 1.367 -static int xrun_recovery(snd_pcm_t *handle, int err) 1.368 -{ 1.369 - err = snd_pcm_recover(handle, err, 1); 1.370 - if(err < 0) 1.371 - ERR("recover failed: %s\n", snd_strerror(err)); 1.372 - return err; 1.373 -} 1.374 - 1.375 -static int verify_state(snd_pcm_t *handle) 1.376 -{ 1.377 - snd_pcm_state_t state = snd_pcm_state(handle); 1.378 - if(state == SND_PCM_STATE_DISCONNECTED) 1.379 - return -ENODEV; 1.380 - if(state == SND_PCM_STATE_XRUN) 1.381 - { 1.382 - int err = xrun_recovery(handle, -EPIPE); 1.383 - if(err < 0) return err; 1.384 - } 1.385 - else if(state == SND_PCM_STATE_SUSPENDED) 1.386 - { 1.387 - int err = xrun_recovery(handle, -ESTRPIPE); 1.388 - if(err < 0) return err; 1.389 - } 1.390 - 1.391 - return state; 1.392 -} 1.393 - 1.394 - 1.395 -static ALuint ALSAProc(ALvoid *ptr) 1.396 -{ 1.397 - ALCdevice *pDevice = (ALCdevice*)ptr; 1.398 - alsa_data *data = (alsa_data*)pDevice->ExtraData; 1.399 - const snd_pcm_channel_area_t *areas = NULL; 1.400 - snd_pcm_sframes_t avail, commitres; 1.401 - snd_pcm_uframes_t offset, frames; 1.402 - char *WritePtr; 1.403 - int err; 1.404 - 1.405 - SetRTPriority(); 1.406 - 1.407 - while(!data->killNow) 1.408 - { 1.409 - int state = verify_state(data->pcmHandle); 1.410 - if(state < 0) 1.411 - { 1.412 - ERR("Invalid state detected: %s\n", snd_strerror(state)); 1.413 - aluHandleDisconnect(pDevice); 1.414 - break; 1.415 - } 1.416 - 1.417 - avail = snd_pcm_avail_update(data->pcmHandle); 1.418 - if(avail < 0) 1.419 - { 1.420 - ERR("available update failed: %s\n", snd_strerror(avail)); 1.421 - continue; 1.422 - } 1.423 - 1.424 - // make sure there's frames to process 1.425 - if((snd_pcm_uframes_t)avail < pDevice->UpdateSize) 1.426 - { 1.427 - if(state != SND_PCM_STATE_RUNNING) 1.428 - { 1.429 - err = snd_pcm_start(data->pcmHandle); 1.430 - if(err < 0) 1.431 - { 1.432 - ERR("start failed: %s\n", snd_strerror(err)); 1.433 - continue; 1.434 - } 1.435 - } 1.436 - if(snd_pcm_wait(data->pcmHandle, 1000) == 0) 1.437 - ERR("Wait timeout... buffer size too low?\n"); 1.438 - continue; 1.439 - } 1.440 - avail -= avail%pDevice->UpdateSize; 1.441 - 1.442 - // it is possible that contiguous areas are smaller, thus we use a loop 1.443 - while(avail > 0) 1.444 - { 1.445 - frames = avail; 1.446 - 1.447 - err = snd_pcm_mmap_begin(data->pcmHandle, &areas, &offset, &frames); 1.448 - if(err < 0) 1.449 - { 1.450 - ERR("mmap begin error: %s\n", snd_strerror(err)); 1.451 - break; 1.452 - } 1.453 - 1.454 - WritePtr = (char*)areas->addr + (offset * areas->step / 8); 1.455 - aluMixData(pDevice, WritePtr, frames); 1.456 - 1.457 - commitres = snd_pcm_mmap_commit(data->pcmHandle, offset, frames); 1.458 - if(commitres < 0 || (commitres-frames) != 0) 1.459 - { 1.460 - ERR("mmap commit error: %s\n", 1.461 - snd_strerror(commitres >= 0 ? -EPIPE : commitres)); 1.462 - break; 1.463 - } 1.464 - 1.465 - avail -= frames; 1.466 - } 1.467 - } 1.468 - 1.469 - return 0; 1.470 -} 1.471 - 1.472 -static ALuint ALSANoMMapProc(ALvoid *ptr) 1.473 -{ 1.474 - ALCdevice *pDevice = (ALCdevice*)ptr; 1.475 - alsa_data *data = (alsa_data*)pDevice->ExtraData; 1.476 - snd_pcm_sframes_t avail; 1.477 - char *WritePtr; 1.478 - 1.479 - SetRTPriority(); 1.480 - 1.481 - while(!data->killNow) 1.482 - { 1.483 - int state = verify_state(data->pcmHandle); 1.484 - if(state < 0) 1.485 - { 1.486 - ERR("Invalid state detected: %s\n", snd_strerror(state)); 1.487 - aluHandleDisconnect(pDevice); 1.488 - break; 1.489 - } 1.490 - 1.491 - WritePtr = data->buffer; 1.492 - avail = data->size / snd_pcm_frames_to_bytes(data->pcmHandle, 1); 1.493 - aluMixData(pDevice, WritePtr, avail); 1.494 - 1.495 - while(avail > 0) 1.496 - { 1.497 - int ret = snd_pcm_writei(data->pcmHandle, WritePtr, avail); 1.498 - switch (ret) 1.499 - { 1.500 - case -EAGAIN: 1.501 - continue; 1.502 - case -ESTRPIPE: 1.503 - case -EPIPE: 1.504 - case -EINTR: 1.505 - ret = snd_pcm_recover(data->pcmHandle, ret, 1); 1.506 - if(ret < 0) 1.507 - avail = 0; 1.508 - break; 1.509 - default: 1.510 - if (ret >= 0) 1.511 - { 1.512 - WritePtr += snd_pcm_frames_to_bytes(data->pcmHandle, ret); 1.513 - avail -= ret; 1.514 - } 1.515 - break; 1.516 - } 1.517 - if (ret < 0) 1.518 - { 1.519 - ret = snd_pcm_prepare(data->pcmHandle); 1.520 - if(ret < 0) 1.521 - break; 1.522 - } 1.523 - } 1.524 - } 1.525 - 1.526 - return 0; 1.527 -} 1.528 - 1.529 -static ALCboolean alsa_open_playback(ALCdevice *device, const ALCchar *deviceName) 1.530 -{ 1.531 - alsa_data *data; 1.532 - char driver[128]; 1.533 - int i; 1.534 - 1.535 - strncpy(driver, GetConfigValue("alsa", "device", "default"), sizeof(driver)-1); 1.536 - driver[sizeof(driver)-1] = 0; 1.537 - 1.538 - if(!deviceName) 1.539 - deviceName = alsaDevice; 1.540 - else if(strcmp(deviceName, alsaDevice) != 0) 1.541 - { 1.542 - size_t idx; 1.543 - 1.544 - if(!allDevNameMap) 1.545 - allDevNameMap = probe_devices(SND_PCM_STREAM_PLAYBACK, &numDevNames); 1.546 - 1.547 - for(idx = 0;idx < numDevNames;idx++) 1.548 - { 1.549 - if(allDevNameMap[idx].name && 1.550 - strcmp(deviceName, allDevNameMap[idx].name) == 0) 1.551 - { 1.552 - if(idx > 0) 1.553 - snprintf(driver, sizeof(driver), "%sCARD=%s,DEV=%d", device_prefix, 1.554 - allDevNameMap[idx].card, allDevNameMap[idx].dev); 1.555 - break; 1.556 - } 1.557 - } 1.558 - if(idx == numDevNames) 1.559 - return ALC_FALSE; 1.560 - } 1.561 - 1.562 - data = (alsa_data*)calloc(1, sizeof(alsa_data)); 1.563 - 1.564 - i = snd_pcm_open(&data->pcmHandle, driver, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK); 1.565 - if(i >= 0) 1.566 - { 1.567 - i = snd_pcm_nonblock(data->pcmHandle, 0); 1.568 - if(i < 0) 1.569 - snd_pcm_close(data->pcmHandle); 1.570 - } 1.571 - if(i < 0) 1.572 - { 1.573 - free(data); 1.574 - ERR("Could not open playback device '%s': %s\n", driver, snd_strerror(i)); 1.575 - return ALC_FALSE; 1.576 - } 1.577 - 1.578 - device->szDeviceName = strdup(deviceName); 1.579 - device->ExtraData = data; 1.580 - return ALC_TRUE; 1.581 -} 1.582 - 1.583 -static void alsa_close_playback(ALCdevice *device) 1.584 -{ 1.585 - alsa_data *data = (alsa_data*)device->ExtraData; 1.586 - 1.587 - snd_pcm_close(data->pcmHandle); 1.588 - free(data); 1.589 - device->ExtraData = NULL; 1.590 -} 1.591 - 1.592 -static ALCboolean alsa_reset_playback(ALCdevice *device) 1.593 -{ 1.594 - alsa_data *data = (alsa_data*)device->ExtraData; 1.595 - snd_pcm_uframes_t periodSizeInFrames; 1.596 - unsigned int periodLen, bufferLen; 1.597 - snd_pcm_sw_params_t *sp = NULL; 1.598 - snd_pcm_hw_params_t *p = NULL; 1.599 - snd_pcm_access_t access; 1.600 - snd_pcm_format_t format; 1.601 - unsigned int periods; 1.602 - unsigned int rate; 1.603 - int allowmmap; 1.604 - char *err; 1.605 - int i; 1.606 - 1.607 - 1.608 - format = -1; 1.609 - switch(device->FmtType) 1.610 - { 1.611 - case DevFmtByte: 1.612 - format = SND_PCM_FORMAT_S8; 1.613 - break; 1.614 - case DevFmtUByte: 1.615 - format = SND_PCM_FORMAT_U8; 1.616 - break; 1.617 - case DevFmtShort: 1.618 - format = SND_PCM_FORMAT_S16; 1.619 - break; 1.620 - case DevFmtUShort: 1.621 - format = SND_PCM_FORMAT_U16; 1.622 - break; 1.623 - case DevFmtFloat: 1.624 - format = SND_PCM_FORMAT_FLOAT; 1.625 - break; 1.626 - } 1.627 - 1.628 - allowmmap = GetConfigValueBool("alsa", "mmap", 1); 1.629 - periods = device->NumUpdates; 1.630 - periodLen = (ALuint64)device->UpdateSize * 1000000 / device->Frequency; 1.631 - bufferLen = periodLen * periods; 1.632 - rate = device->Frequency; 1.633 - 1.634 - err = NULL; 1.635 - snd_pcm_hw_params_malloc(&p); 1.636 - 1.637 - if((i=snd_pcm_hw_params_any(data->pcmHandle, p)) < 0) 1.638 - err = "any"; 1.639 - /* set interleaved access */ 1.640 - if(i >= 0 && (!allowmmap || (i=snd_pcm_hw_params_set_access(data->pcmHandle, p, SND_PCM_ACCESS_MMAP_INTERLEAVED)) < 0)) 1.641 - { 1.642 - if(periods > 2) 1.643 - { 1.644 - periods--; 1.645 - bufferLen = periodLen * periods; 1.646 - } 1.647 - if((i=snd_pcm_hw_params_set_access(data->pcmHandle, p, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) 1.648 - err = "set access"; 1.649 - } 1.650 - /* set format (implicitly sets sample bits) */ 1.651 - if(i >= 0 && (i=snd_pcm_hw_params_set_format(data->pcmHandle, p, format)) < 0) 1.652 - { 1.653 - device->FmtType = DevFmtFloat; 1.654 - if(format == SND_PCM_FORMAT_FLOAT || 1.655 - (i=snd_pcm_hw_params_set_format(data->pcmHandle, p, SND_PCM_FORMAT_FLOAT)) < 0) 1.656 - { 1.657 - device->FmtType = DevFmtShort; 1.658 - if(format == SND_PCM_FORMAT_S16 || 1.659 - (i=snd_pcm_hw_params_set_format(data->pcmHandle, p, SND_PCM_FORMAT_S16)) < 0) 1.660 - { 1.661 - device->FmtType = DevFmtUByte; 1.662 - if(format == SND_PCM_FORMAT_U8 || 1.663 - (i=snd_pcm_hw_params_set_format(data->pcmHandle, p, SND_PCM_FORMAT_U8)) < 0) 1.664 - err = "set format"; 1.665 - } 1.666 - } 1.667 - } 1.668 - /* set channels (implicitly sets frame bits) */ 1.669 - if(i >= 0 && (i=snd_pcm_hw_params_set_channels(data->pcmHandle, p, ChannelsFromDevFmt(device->FmtChans))) < 0) 1.670 - { 1.671 - if((i=snd_pcm_hw_params_set_channels(data->pcmHandle, p, 2)) < 0) 1.672 - { 1.673 - if((i=snd_pcm_hw_params_set_channels(data->pcmHandle, p, 1)) < 0) 1.674 - err = "set channels"; 1.675 - else 1.676 - { 1.677 - if((device->Flags&DEVICE_CHANNELS_REQUEST)) 1.678 - ERR("Failed to set %s, got Mono instead\n", DevFmtChannelsString(device->FmtChans)); 1.679 - device->FmtChans = DevFmtMono; 1.680 - } 1.681 - } 1.682 - else 1.683 - { 1.684 - if((device->Flags&DEVICE_CHANNELS_REQUEST)) 1.685 - ERR("Failed to set %s, got Stereo instead\n", DevFmtChannelsString(device->FmtChans)); 1.686 - device->FmtChans = DevFmtStereo; 1.687 - } 1.688 - device->Flags &= ~DEVICE_CHANNELS_REQUEST; 1.689 - } 1.690 - if(i >= 0 && (i=snd_pcm_hw_params_set_rate_resample(data->pcmHandle, p, 0)) < 0) 1.691 - { 1.692 - ERR("Failed to disable ALSA resampler\n"); 1.693 - i = 0; 1.694 - } 1.695 - /* set rate (implicitly constrains period/buffer parameters) */ 1.696 - if(i >= 0 && (i=snd_pcm_hw_params_set_rate_near(data->pcmHandle, p, &rate, NULL)) < 0) 1.697 - err = "set rate near"; 1.698 - /* set buffer time (implicitly constrains period/buffer parameters) */ 1.699 - if(i >= 0 && (i=snd_pcm_hw_params_set_buffer_time_near(data->pcmHandle, p, &bufferLen, NULL)) < 0) 1.700 - err = "set buffer time near"; 1.701 - /* set period time in frame units (implicitly sets buffer size/bytes/time and period size/bytes) */ 1.702 - if(i >= 0 && (i=snd_pcm_hw_params_set_period_time_near(data->pcmHandle, p, &periodLen, NULL)) < 0) 1.703 - err = "set period time near"; 1.704 - /* install and prepare hardware configuration */ 1.705 - if(i >= 0 && (i=snd_pcm_hw_params(data->pcmHandle, p)) < 0) 1.706 - err = "set params"; 1.707 - if(i >= 0 && (i=snd_pcm_hw_params_get_access(p, &access)) < 0) 1.708 - err = "get access"; 1.709 - if(i >= 0 && (i=snd_pcm_hw_params_get_period_size(p, &periodSizeInFrames, NULL)) < 0) 1.710 - err = "get period size"; 1.711 - if(i >= 0 && (i=snd_pcm_hw_params_get_periods(p, &periods, NULL)) < 0) 1.712 - err = "get periods"; 1.713 - if(i < 0) 1.714 - { 1.715 - ERR("%s failed: %s\n", err, snd_strerror(i)); 1.716 - snd_pcm_hw_params_free(p); 1.717 - return ALC_FALSE; 1.718 - } 1.719 - 1.720 - snd_pcm_hw_params_free(p); 1.721 - 1.722 - err = NULL; 1.723 - snd_pcm_sw_params_malloc(&sp); 1.724 - 1.725 - if((i=snd_pcm_sw_params_current(data->pcmHandle, sp)) != 0) 1.726 - err = "sw current"; 1.727 - if(i == 0 && (i=snd_pcm_sw_params_set_avail_min(data->pcmHandle, sp, periodSizeInFrames)) != 0) 1.728 - err = "sw set avail min"; 1.729 - if(i == 0 && (i=snd_pcm_sw_params(data->pcmHandle, sp)) != 0) 1.730 - err = "sw set params"; 1.731 - if(i != 0) 1.732 - { 1.733 - ERR("%s failed: %s\n", err, snd_strerror(i)); 1.734 - snd_pcm_sw_params_free(sp); 1.735 - return ALC_FALSE; 1.736 - } 1.737 - 1.738 - snd_pcm_sw_params_free(sp); 1.739 - 1.740 - if(device->Frequency != rate) 1.741 - { 1.742 - if((device->Flags&DEVICE_FREQUENCY_REQUEST)) 1.743 - ERR("Failed to set %dhz, got %dhz instead\n", device->Frequency, rate); 1.744 - device->Flags &= ~DEVICE_FREQUENCY_REQUEST; 1.745 - device->Frequency = rate; 1.746 - } 1.747 - 1.748 - SetDefaultChannelOrder(device); 1.749 - 1.750 - data->size = snd_pcm_frames_to_bytes(data->pcmHandle, periodSizeInFrames); 1.751 - if(access == SND_PCM_ACCESS_RW_INTERLEAVED) 1.752 - { 1.753 - /* Increase periods by one, since the temp buffer counts as an extra 1.754 - * period */ 1.755 - periods++; 1.756 - data->buffer = malloc(data->size); 1.757 - if(!data->buffer) 1.758 - { 1.759 - ERR("buffer malloc failed\n"); 1.760 - return ALC_FALSE; 1.761 - } 1.762 - device->UpdateSize = periodSizeInFrames; 1.763 - device->NumUpdates = periods; 1.764 - data->thread = StartThread(ALSANoMMapProc, device); 1.765 - } 1.766 - else 1.767 - { 1.768 - i = snd_pcm_prepare(data->pcmHandle); 1.769 - if(i < 0) 1.770 - { 1.771 - ERR("prepare error: %s\n", snd_strerror(i)); 1.772 - return ALC_FALSE; 1.773 - } 1.774 - device->UpdateSize = periodSizeInFrames; 1.775 - device->NumUpdates = periods; 1.776 - data->thread = StartThread(ALSAProc, device); 1.777 - } 1.778 - if(data->thread == NULL) 1.779 - { 1.780 - ERR("Could not create playback thread\n"); 1.781 - free(data->buffer); 1.782 - data->buffer = NULL; 1.783 - return ALC_FALSE; 1.784 - } 1.785 - 1.786 - return ALC_TRUE; 1.787 -} 1.788 - 1.789 -static void alsa_stop_playback(ALCdevice *device) 1.790 -{ 1.791 - alsa_data *data = (alsa_data*)device->ExtraData; 1.792 - 1.793 - if(data->thread) 1.794 - { 1.795 - data->killNow = 1; 1.796 - StopThread(data->thread); 1.797 - data->thread = NULL; 1.798 - } 1.799 - data->killNow = 0; 1.800 - free(data->buffer); 1.801 - data->buffer = NULL; 1.802 -} 1.803 - 1.804 - 1.805 -static ALCboolean alsa_open_capture(ALCdevice *pDevice, const ALCchar *deviceName) 1.806 -{ 1.807 - snd_pcm_hw_params_t *p; 1.808 - snd_pcm_uframes_t bufferSizeInFrames; 1.809 - snd_pcm_format_t format; 1.810 - ALuint frameSize; 1.811 - alsa_data *data; 1.812 - char driver[128]; 1.813 - char *err; 1.814 - int i; 1.815 - 1.816 - strncpy(driver, GetConfigValue("alsa", "capture", "default"), sizeof(driver)-1); 1.817 - driver[sizeof(driver)-1] = 0; 1.818 - 1.819 - if(!allCaptureDevNameMap) 1.820 - allCaptureDevNameMap = probe_devices(SND_PCM_STREAM_CAPTURE, &numCaptureDevNames); 1.821 - 1.822 - if(!deviceName) 1.823 - deviceName = allCaptureDevNameMap[0].name; 1.824 - else 1.825 - { 1.826 - size_t idx; 1.827 - 1.828 - for(idx = 0;idx < numCaptureDevNames;idx++) 1.829 - { 1.830 - if(allCaptureDevNameMap[idx].name && 1.831 - strcmp(deviceName, allCaptureDevNameMap[idx].name) == 0) 1.832 - { 1.833 - if(idx > 0) 1.834 - snprintf(driver, sizeof(driver), "%sCARD=%s,DEV=%d", capture_prefix, 1.835 - allCaptureDevNameMap[idx].card, allCaptureDevNameMap[idx].dev); 1.836 - break; 1.837 - } 1.838 - } 1.839 - if(idx == numCaptureDevNames) 1.840 - return ALC_FALSE; 1.841 - } 1.842 - 1.843 - data = (alsa_data*)calloc(1, sizeof(alsa_data)); 1.844 - 1.845 - i = snd_pcm_open(&data->pcmHandle, driver, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK); 1.846 - if(i < 0) 1.847 - { 1.848 - ERR("Could not open capture device '%s': %s\n", driver, snd_strerror(i)); 1.849 - free(data); 1.850 - return ALC_FALSE; 1.851 - } 1.852 - 1.853 - format = -1; 1.854 - switch(pDevice->FmtType) 1.855 - { 1.856 - case DevFmtByte: 1.857 - format = SND_PCM_FORMAT_S8; 1.858 - break; 1.859 - case DevFmtUByte: 1.860 - format = SND_PCM_FORMAT_U8; 1.861 - break; 1.862 - case DevFmtShort: 1.863 - format = SND_PCM_FORMAT_S16; 1.864 - break; 1.865 - case DevFmtUShort: 1.866 - format = SND_PCM_FORMAT_U16; 1.867 - break; 1.868 - case DevFmtFloat: 1.869 - format = SND_PCM_FORMAT_FLOAT; 1.870 - break; 1.871 - } 1.872 - 1.873 - err = NULL; 1.874 - bufferSizeInFrames = pDevice->UpdateSize * pDevice->NumUpdates; 1.875 - snd_pcm_hw_params_malloc(&p); 1.876 - 1.877 - if((i=snd_pcm_hw_params_any(data->pcmHandle, p)) < 0) 1.878 - err = "any"; 1.879 - /* set interleaved access */ 1.880 - if(i >= 0 && (i=snd_pcm_hw_params_set_access(data->pcmHandle, p, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) 1.881 - err = "set access"; 1.882 - /* set format (implicitly sets sample bits) */ 1.883 - if(i >= 0 && (i=snd_pcm_hw_params_set_format(data->pcmHandle, p, format)) < 0) 1.884 - err = "set format"; 1.885 - /* set channels (implicitly sets frame bits) */ 1.886 - if(i >= 0 && (i=snd_pcm_hw_params_set_channels(data->pcmHandle, p, ChannelsFromDevFmt(pDevice->FmtChans))) < 0) 1.887 - err = "set channels"; 1.888 - /* set rate (implicitly constrains period/buffer parameters) */ 1.889 - if(i >= 0 && (i=snd_pcm_hw_params_set_rate(data->pcmHandle, p, pDevice->Frequency, 0)) < 0) 1.890 - err = "set rate near"; 1.891 - /* set buffer size in frame units (implicitly sets period size/bytes/time and buffer time/bytes) */ 1.892 - if(i >= 0 && (i=snd_pcm_hw_params_set_buffer_size_near(data->pcmHandle, p, &bufferSizeInFrames)) < 0) 1.893 - err = "set buffer size near"; 1.894 - /* install and prepare hardware configuration */ 1.895 - if(i >= 0 && (i=snd_pcm_hw_params(data->pcmHandle, p)) < 0) 1.896 - err = "set params"; 1.897 - if(i < 0) 1.898 - { 1.899 - ERR("%s failed: %s\n", err, snd_strerror(i)); 1.900 - snd_pcm_hw_params_free(p); 1.901 - goto error; 1.902 - } 1.903 - 1.904 - if((i=snd_pcm_hw_params_get_period_size(p, &bufferSizeInFrames, NULL)) < 0) 1.905 - { 1.906 - ERR("get size failed: %s\n", snd_strerror(i)); 1.907 - snd_pcm_hw_params_free(p); 1.908 - goto error; 1.909 - } 1.910 - 1.911 - snd_pcm_hw_params_free(p); 1.912 - 1.913 - frameSize = FrameSizeFromDevFmt(pDevice->FmtChans, pDevice->FmtType); 1.914 - 1.915 - data->ring = CreateRingBuffer(frameSize, pDevice->UpdateSize*pDevice->NumUpdates); 1.916 - if(!data->ring) 1.917 - { 1.918 - ERR("ring buffer create failed\n"); 1.919 - goto error; 1.920 - } 1.921 - 1.922 - data->size = snd_pcm_frames_to_bytes(data->pcmHandle, bufferSizeInFrames); 1.923 - data->buffer = malloc(data->size); 1.924 - if(!data->buffer) 1.925 - { 1.926 - ERR("buffer malloc failed\n"); 1.927 - goto error; 1.928 - } 1.929 - 1.930 - pDevice->szDeviceName = strdup(deviceName); 1.931 - 1.932 - pDevice->ExtraData = data; 1.933 - return ALC_TRUE; 1.934 - 1.935 -error: 1.936 - free(data->buffer); 1.937 - DestroyRingBuffer(data->ring); 1.938 - snd_pcm_close(data->pcmHandle); 1.939 - free(data); 1.940 - 1.941 - pDevice->ExtraData = NULL; 1.942 - return ALC_FALSE; 1.943 -} 1.944 - 1.945 -static void alsa_close_capture(ALCdevice *pDevice) 1.946 -{ 1.947 - alsa_data *data = (alsa_data*)pDevice->ExtraData; 1.948 - 1.949 - snd_pcm_close(data->pcmHandle); 1.950 - DestroyRingBuffer(data->ring); 1.951 - 1.952 - free(data->buffer); 1.953 - free(data); 1.954 - pDevice->ExtraData = NULL; 1.955 -} 1.956 - 1.957 -static void alsa_start_capture(ALCdevice *Device) 1.958 -{ 1.959 - alsa_data *data = (alsa_data*)Device->ExtraData; 1.960 - int err; 1.961 - 1.962 - err = snd_pcm_start(data->pcmHandle); 1.963 - if(err < 0) 1.964 - { 1.965 - ERR("start failed: %s\n", snd_strerror(err)); 1.966 - aluHandleDisconnect(Device); 1.967 - } 1.968 - else 1.969 - data->doCapture = AL_TRUE; 1.970 -} 1.971 - 1.972 -static void alsa_stop_capture(ALCdevice *Device) 1.973 -{ 1.974 - alsa_data *data = (alsa_data*)Device->ExtraData; 1.975 - snd_pcm_drain(data->pcmHandle); 1.976 - data->doCapture = AL_FALSE; 1.977 -} 1.978 - 1.979 -static ALCuint alsa_available_samples(ALCdevice *Device) 1.980 -{ 1.981 - alsa_data *data = (alsa_data*)Device->ExtraData; 1.982 - snd_pcm_sframes_t avail; 1.983 - 1.984 - avail = (Device->Connected ? snd_pcm_avail_update(data->pcmHandle) : 0); 1.985 - if(avail < 0) 1.986 - { 1.987 - ERR("avail update failed: %s\n", snd_strerror(avail)); 1.988 - 1.989 - if((avail=snd_pcm_recover(data->pcmHandle, avail, 1)) >= 0) 1.990 - { 1.991 - if(data->doCapture) 1.992 - avail = snd_pcm_start(data->pcmHandle); 1.993 - if(avail >= 0) 1.994 - avail = snd_pcm_avail_update(data->pcmHandle); 1.995 - } 1.996 - if(avail < 0) 1.997 - { 1.998 - ERR("restore error: %s\n", snd_strerror(avail)); 1.999 - aluHandleDisconnect(Device); 1.1000 - } 1.1001 - } 1.1002 - while(avail > 0) 1.1003 - { 1.1004 - snd_pcm_sframes_t amt; 1.1005 - 1.1006 - amt = snd_pcm_bytes_to_frames(data->pcmHandle, data->size); 1.1007 - if(avail < amt) amt = avail; 1.1008 - 1.1009 - amt = snd_pcm_readi(data->pcmHandle, data->buffer, amt); 1.1010 - if(amt < 0) 1.1011 - { 1.1012 - ERR("read error: %s\n", snd_strerror(amt)); 1.1013 - 1.1014 - if(amt == -EAGAIN) 1.1015 - continue; 1.1016 - if((amt=snd_pcm_recover(data->pcmHandle, amt, 1)) >= 0) 1.1017 - { 1.1018 - if(data->doCapture) 1.1019 - amt = snd_pcm_start(data->pcmHandle); 1.1020 - if(amt >= 0) 1.1021 - amt = snd_pcm_avail_update(data->pcmHandle); 1.1022 - } 1.1023 - if(amt < 0) 1.1024 - { 1.1025 - ERR("restore error: %s\n", snd_strerror(amt)); 1.1026 - aluHandleDisconnect(Device); 1.1027 - break; 1.1028 - } 1.1029 - avail = amt; 1.1030 - continue; 1.1031 - } 1.1032 - 1.1033 - WriteRingBuffer(data->ring, data->buffer, amt); 1.1034 - avail -= amt; 1.1035 - } 1.1036 - 1.1037 - return RingBufferSize(data->ring); 1.1038 -} 1.1039 - 1.1040 -static void alsa_capture_samples(ALCdevice *Device, ALCvoid *Buffer, ALCuint Samples) 1.1041 -{ 1.1042 - alsa_data *data = (alsa_data*)Device->ExtraData; 1.1043 - 1.1044 - if(Samples <= alsa_available_samples(Device)) 1.1045 - ReadRingBuffer(data->ring, Buffer, Samples); 1.1046 - else 1.1047 - alcSetError(Device, ALC_INVALID_VALUE); 1.1048 -} 1.1049 - 1.1050 - 1.1051 -static const BackendFuncs alsa_funcs = { 1.1052 - alsa_open_playback, 1.1053 - alsa_close_playback, 1.1054 - alsa_reset_playback, 1.1055 - alsa_stop_playback, 1.1056 - alsa_open_capture, 1.1057 - alsa_close_capture, 1.1058 - alsa_start_capture, 1.1059 - alsa_stop_capture, 1.1060 - alsa_capture_samples, 1.1061 - alsa_available_samples 1.1062 -}; 1.1063 - 1.1064 -ALCboolean alc_alsa_init(BackendFuncs *func_list) 1.1065 -{ 1.1066 - if(!alsa_load()) 1.1067 - return ALC_FALSE; 1.1068 - device_prefix = GetConfigValue("alsa", "device-prefix", "plughw:"); 1.1069 - capture_prefix = GetConfigValue("alsa", "capture-prefix", "plughw:"); 1.1070 - *func_list = alsa_funcs; 1.1071 - return ALC_TRUE; 1.1072 -} 1.1073 - 1.1074 -void alc_alsa_deinit(void) 1.1075 -{ 1.1076 - ALuint i; 1.1077 - 1.1078 - for(i = 0;i < numDevNames;++i) 1.1079 - { 1.1080 - free(allDevNameMap[i].name); 1.1081 - free(allDevNameMap[i].card); 1.1082 - } 1.1083 - free(allDevNameMap); 1.1084 - allDevNameMap = NULL; 1.1085 - numDevNames = 0; 1.1086 - 1.1087 - for(i = 0;i < numCaptureDevNames;++i) 1.1088 - { 1.1089 - free(allCaptureDevNameMap[i].name); 1.1090 - free(allCaptureDevNameMap[i].card); 1.1091 - } 1.1092 - free(allCaptureDevNameMap); 1.1093 - allCaptureDevNameMap = NULL; 1.1094 - numCaptureDevNames = 0; 1.1095 - 1.1096 -#ifdef HAVE_DYNLOAD 1.1097 - if(alsa_handle) 1.1098 - CloseLib(alsa_handle); 1.1099 - alsa_handle = NULL; 1.1100 -#endif 1.1101 -} 1.1102 - 1.1103 -void alc_alsa_probe(enum DevProbe type) 1.1104 -{ 1.1105 - ALuint i; 1.1106 - 1.1107 - switch(type) 1.1108 - { 1.1109 - case DEVICE_PROBE: 1.1110 - AppendDeviceList(alsaDevice); 1.1111 - break; 1.1112 - 1.1113 - case ALL_DEVICE_PROBE: 1.1114 - for(i = 0;i < numDevNames;++i) 1.1115 - { 1.1116 - free(allDevNameMap[i].name); 1.1117 - free(allDevNameMap[i].card); 1.1118 - } 1.1119 - 1.1120 - free(allDevNameMap); 1.1121 - allDevNameMap = probe_devices(SND_PCM_STREAM_PLAYBACK, &numDevNames); 1.1122 - 1.1123 - for(i = 0;i < numDevNames;++i) 1.1124 - AppendAllDeviceList(allDevNameMap[i].name); 1.1125 - break; 1.1126 - 1.1127 - case CAPTURE_DEVICE_PROBE: 1.1128 - for(i = 0;i < numCaptureDevNames;++i) 1.1129 - { 1.1130 - free(allCaptureDevNameMap[i].name); 1.1131 - free(allCaptureDevNameMap[i].card); 1.1132 - } 1.1133 - 1.1134 - free(allCaptureDevNameMap); 1.1135 - allCaptureDevNameMap = probe_devices(SND_PCM_STREAM_CAPTURE, &numCaptureDevNames); 1.1136 - 1.1137 - for(i = 0;i < numCaptureDevNames;++i) 1.1138 - AppendCaptureDeviceList(allCaptureDevNameMap[i].name); 1.1139 - break; 1.1140 - } 1.1141 -}
2.1 --- a/Alc/backends/coreaudio.c Tue Oct 25 13:03:35 2011 -0700 2.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 2.3 @@ -1,719 +0,0 @@ 2.4 -/** 2.5 - * OpenAL cross platform audio library 2.6 - * Copyright (C) 1999-2007 by authors. 2.7 - * This library is free software; you can redistribute it and/or 2.8 - * modify it under the terms of the GNU Library General Public 2.9 - * License as published by the Free Software Foundation; either 2.10 - * version 2 of the License, or (at your option) any later version. 2.11 - * 2.12 - * This library is distributed in the hope that it will be useful, 2.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 2.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 2.15 - * Library General Public License for more details. 2.16 - * 2.17 - * You should have received a copy of the GNU Library General Public 2.18 - * License along with this library; if not, write to the 2.19 - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 2.20 - * Boston, MA 02111-1307, USA. 2.21 - * Or go to http://www.gnu.org/copyleft/lgpl.html 2.22 - */ 2.23 - 2.24 -#include "config.h" 2.25 - 2.26 -#include <stdio.h> 2.27 -#include <stdlib.h> 2.28 -#include <string.h> 2.29 - 2.30 -#include "alMain.h" 2.31 -#include "AL/al.h" 2.32 -#include "AL/alc.h" 2.33 - 2.34 -#include <CoreServices/CoreServices.h> 2.35 -#include <unistd.h> 2.36 -#include <AudioUnit/AudioUnit.h> 2.37 -#include <AudioToolbox/AudioToolbox.h> 2.38 - 2.39 - 2.40 -typedef struct { 2.41 - AudioUnit audioUnit; 2.42 - 2.43 - ALuint frameSize; 2.44 - ALdouble sampleRateRatio; // Ratio of hardware sample rate / requested sample rate 2.45 - AudioStreamBasicDescription format; // This is the OpenAL format as a CoreAudio ASBD 2.46 - 2.47 - AudioConverterRef audioConverter; // Sample rate converter if needed 2.48 - AudioBufferList *bufferList; // Buffer for data coming from the input device 2.49 - ALCvoid *resampleBuffer; // Buffer for returned RingBuffer data when resampling 2.50 - 2.51 - RingBuffer *ring; 2.52 -} ca_data; 2.53 - 2.54 -static const ALCchar ca_device[] = "CoreAudio Default"; 2.55 - 2.56 - 2.57 -static void destroy_buffer_list(AudioBufferList* list) 2.58 -{ 2.59 - if(list) 2.60 - { 2.61 - UInt32 i; 2.62 - for(i = 0;i < list->mNumberBuffers;i++) 2.63 - free(list->mBuffers[i].mData); 2.64 - free(list); 2.65 - } 2.66 -} 2.67 - 2.68 -static AudioBufferList* allocate_buffer_list(UInt32 channelCount, UInt32 byteSize) 2.69 -{ 2.70 - AudioBufferList *list; 2.71 - 2.72 - list = calloc(1, sizeof(AudioBufferList) + sizeof(AudioBuffer)); 2.73 - if(list) 2.74 - { 2.75 - list->mNumberBuffers = 1; 2.76 - 2.77 - list->mBuffers[0].mNumberChannels = channelCount; 2.78 - list->mBuffers[0].mDataByteSize = byteSize; 2.79 - list->mBuffers[0].mData = malloc(byteSize); 2.80 - if(list->mBuffers[0].mData == NULL) 2.81 - { 2.82 - free(list); 2.83 - list = NULL; 2.84 - } 2.85 - } 2.86 - return list; 2.87 -} 2.88 - 2.89 -static OSStatus ca_callback(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, 2.90 - UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData) 2.91 -{ 2.92 - ALCdevice *device = (ALCdevice*)inRefCon; 2.93 - ca_data *data = (ca_data*)device->ExtraData; 2.94 - 2.95 - aluMixData(device, ioData->mBuffers[0].mData, 2.96 - ioData->mBuffers[0].mDataByteSize / data->frameSize); 2.97 - 2.98 - return noErr; 2.99 -} 2.100 - 2.101 -static OSStatus ca_capture_conversion_callback(AudioConverterRef inAudioConverter, UInt32 *ioNumberDataPackets, 2.102 - AudioBufferList *ioData, AudioStreamPacketDescription **outDataPacketDescription, void* inUserData) 2.103 -{ 2.104 - ALCdevice *device = (ALCdevice*)inUserData; 2.105 - ca_data *data = (ca_data*)device->ExtraData; 2.106 - 2.107 - // Read from the ring buffer and store temporarily in a large buffer 2.108 - ReadRingBuffer(data->ring, data->resampleBuffer, (ALsizei)(*ioNumberDataPackets)); 2.109 - 2.110 - // Set the input data 2.111 - ioData->mNumberBuffers = 1; 2.112 - ioData->mBuffers[0].mNumberChannels = data->format.mChannelsPerFrame; 2.113 - ioData->mBuffers[0].mData = data->resampleBuffer; 2.114 - ioData->mBuffers[0].mDataByteSize = (*ioNumberDataPackets) * data->format.mBytesPerFrame; 2.115 - 2.116 - return noErr; 2.117 -} 2.118 - 2.119 -static OSStatus ca_capture_callback(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, 2.120 - const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, 2.121 - UInt32 inNumberFrames, AudioBufferList *ioData) 2.122 -{ 2.123 - ALCdevice *device = (ALCdevice*)inRefCon; 2.124 - ca_data *data = (ca_data*)device->ExtraData; 2.125 - AudioUnitRenderActionFlags flags = 0; 2.126 - OSStatus err; 2.127 - 2.128 - // fill the bufferList with data from the input device 2.129 - err = AudioUnitRender(data->audioUnit, &flags, inTimeStamp, 1, inNumberFrames, data->bufferList); 2.130 - if(err != noErr) 2.131 - { 2.132 - ERR("AudioUnitRender error: %d\n", err); 2.133 - return err; 2.134 - } 2.135 - 2.136 - WriteRingBuffer(data->ring, data->bufferList->mBuffers[0].mData, inNumberFrames); 2.137 - 2.138 - return noErr; 2.139 -} 2.140 - 2.141 -static ALCboolean ca_open_playback(ALCdevice *device, const ALCchar *deviceName) 2.142 -{ 2.143 - ComponentDescription desc; 2.144 - Component comp; 2.145 - ca_data *data; 2.146 - OSStatus err; 2.147 - 2.148 - if(!deviceName) 2.149 - deviceName = ca_device; 2.150 - else if(strcmp(deviceName, ca_device) != 0) 2.151 - return ALC_FALSE; 2.152 - 2.153 - /* open the default output unit */ 2.154 - desc.componentType = kAudioUnitType_Output; 2.155 - desc.componentSubType = kAudioUnitSubType_DefaultOutput; 2.156 - desc.componentManufacturer = kAudioUnitManufacturer_Apple; 2.157 - desc.componentFlags = 0; 2.158 - desc.componentFlagsMask = 0; 2.159 - 2.160 - comp = FindNextComponent(NULL, &desc); 2.161 - if(comp == NULL) 2.162 - { 2.163 - ERR("FindNextComponent failed\n"); 2.164 - return ALC_FALSE; 2.165 - } 2.166 - 2.167 - data = calloc(1, sizeof(*data)); 2.168 - device->ExtraData = data; 2.169 - 2.170 - err = OpenAComponent(comp, &data->audioUnit); 2.171 - if(err != noErr) 2.172 - { 2.173 - ERR("OpenAComponent failed\n"); 2.174 - free(data); 2.175 - device->ExtraData = NULL; 2.176 - return ALC_FALSE; 2.177 - } 2.178 - 2.179 - return ALC_TRUE; 2.180 -} 2.181 - 2.182 -static void ca_close_playback(ALCdevice *device) 2.183 -{ 2.184 - ca_data *data = (ca_data*)device->ExtraData; 2.185 - 2.186 - CloseComponent(data->audioUnit); 2.187 - 2.188 - free(data); 2.189 - device->ExtraData = NULL; 2.190 -} 2.191 - 2.192 -static ALCboolean ca_reset_playback(ALCdevice *device) 2.193 -{ 2.194 - ca_data *data = (ca_data*)device->ExtraData; 2.195 - AudioStreamBasicDescription streamFormat; 2.196 - AURenderCallbackStruct input; 2.197 - OSStatus err; 2.198 - UInt32 size; 2.199 - 2.200 - /* init and start the default audio unit... */ 2.201 - err = AudioUnitInitialize(data->audioUnit); 2.202 - if(err != noErr) 2.203 - { 2.204 - ERR("AudioUnitInitialize failed\n"); 2.205 - return ALC_FALSE; 2.206 - } 2.207 - 2.208 - err = AudioOutputUnitStart(data->audioUnit); 2.209 - if(err != noErr) 2.210 - { 2.211 - ERR("AudioOutputUnitStart failed\n"); 2.212 - return ALC_FALSE; 2.213 - } 2.214 - 2.215 - /* retrieve default output unit's properties (output side) */ 2.216 - size = sizeof(AudioStreamBasicDescription); 2.217 - err = AudioUnitGetProperty(data->audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &streamFormat, &size); 2.218 - if(err != noErr || size != sizeof(AudioStreamBasicDescription)) 2.219 - { 2.220 - ERR("AudioUnitGetProperty failed\n"); 2.221 - return ALC_FALSE; 2.222 - } 2.223 - 2.224 -#if 0 2.225 - TRACE("Output streamFormat of default output unit -\n"); 2.226 - TRACE(" streamFormat.mFramesPerPacket = %d\n", streamFormat.mFramesPerPacket); 2.227 - TRACE(" streamFormat.mChannelsPerFrame = %d\n", streamFormat.mChannelsPerFrame); 2.228 - TRACE(" streamFormat.mBitsPerChannel = %d\n", streamFormat.mBitsPerChannel); 2.229 - TRACE(" streamFormat.mBytesPerPacket = %d\n", streamFormat.mBytesPerPacket); 2.230 - TRACE(" streamFormat.mBytesPerFrame = %d\n", streamFormat.mBytesPerFrame); 2.231 - TRACE(" streamFormat.mSampleRate = %5.0f\n", streamFormat.mSampleRate); 2.232 -#endif 2.233 - 2.234 - /* set default output unit's input side to match output side */ 2.235 - err = AudioUnitSetProperty(data->audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &streamFormat, size); 2.236 - if(err != noErr) 2.237 - { 2.238 - ERR("AudioUnitSetProperty failed\n"); 2.239 - return ALC_FALSE; 2.240 - } 2.241 - 2.242 - if(device->Frequency != streamFormat.mSampleRate) 2.243 - { 2.244 - if((device->Flags&DEVICE_FREQUENCY_REQUEST)) 2.245 - ERR("CoreAudio does not support changing sample rates (wanted %dhz, got %dhz)\n", device->Frequency, streamFormat.mSampleRate); 2.246 - device->Flags &= ~DEVICE_FREQUENCY_REQUEST; 2.247 - 2.248 - device->UpdateSize = (ALuint)((ALuint64)device->UpdateSize * 2.249 - streamFormat.mSampleRate / 2.250 - device->Frequency); 2.251 - device->Frequency = streamFormat.mSampleRate; 2.252 - } 2.253 - 2.254 - /* FIXME: How to tell what channels are what in the output device, and how 2.255 - * to specify what we're giving? eg, 6.0 vs 5.1 */ 2.256 - switch(streamFormat.mChannelsPerFrame) 2.257 - { 2.258 - case 1: 2.259 - if((device->Flags&DEVICE_CHANNELS_REQUEST) && 2.260 - device->FmtChans != DevFmtMono) 2.261 - { 2.262 - ERR("Failed to set %s, got Mono instead\n", DevFmtChannelsString(device->FmtChans)); 2.263 - device->Flags &= ~DEVICE_CHANNELS_REQUEST; 2.264 - } 2.265 - device->FmtChans = DevFmtMono; 2.266 - break; 2.267 - case 2: 2.268 - if((device->Flags&DEVICE_CHANNELS_REQUEST) && 2.269 - device->FmtChans != DevFmtStereo) 2.270 - { 2.271 - ERR("Failed to set %s, got Stereo instead\n", DevFmtChannelsString(device->FmtChans)); 2.272 - device->Flags &= ~DEVICE_CHANNELS_REQUEST; 2.273 - } 2.274 - device->FmtChans = DevFmtStereo; 2.275 - break; 2.276 - case 4: 2.277 - if((device->Flags&DEVICE_CHANNELS_REQUEST) && 2.278 - device->FmtChans != DevFmtQuad) 2.279 - { 2.280 - ERR("Failed to set %s, got Quad instead\n", DevFmtChannelsString(device->FmtChans)); 2.281 - device->Flags &= ~DEVICE_CHANNELS_REQUEST; 2.282 - } 2.283 - device->FmtChans = DevFmtQuad; 2.284 - break; 2.285 - case 6: 2.286 - if((device->Flags&DEVICE_CHANNELS_REQUEST) && 2.287 - device->FmtChans != DevFmtX51) 2.288 - { 2.289 - ERR("Failed to set %s, got 5.1 Surround instead\n", DevFmtChannelsString(device->FmtChans)); 2.290 - device->Flags &= ~DEVICE_CHANNELS_REQUEST; 2.291 - } 2.292 - device->FmtChans = DevFmtX51; 2.293 - break; 2.294 - case 7: 2.295 - if((device->Flags&DEVICE_CHANNELS_REQUEST) && 2.296 - device->FmtChans != DevFmtX61) 2.297 - { 2.298 - ERR("Failed to set %s, got 6.1 Surround instead\n", DevFmtChannelsString(device->FmtChans)); 2.299 - device->Flags &= ~DEVICE_CHANNELS_REQUEST; 2.300 - } 2.301 - device->FmtChans = DevFmtX61; 2.302 - break; 2.303 - case 8: 2.304 - if((device->Flags&DEVICE_CHANNELS_REQUEST) && 2.305 - device->FmtChans != DevFmtX71) 2.306 - { 2.307 - ERR("Failed to set %s, got 7.1 Surround instead\n", DevFmtChannelsString(device->FmtChans)); 2.308 - device->Flags &= ~DEVICE_CHANNELS_REQUEST; 2.309 - } 2.310 - device->FmtChans = DevFmtX71; 2.311 - break; 2.312 - default: 2.313 - ERR("Unhandled channel count (%d), using Stereo\n", streamFormat.mChannelsPerFrame); 2.314 - device->Flags &= ~DEVICE_CHANNELS_REQUEST; 2.315 - device->FmtChans = DevFmtStereo; 2.316 - streamFormat.mChannelsPerFrame = 2; 2.317 - break; 2.318 - } 2.319 - SetDefaultWFXChannelOrder(device); 2.320 - 2.321 - /* use channel count and sample rate from the default output unit's current 2.322 - * parameters, but reset everything else */ 2.323 - streamFormat.mFramesPerPacket = 1; 2.324 - switch(device->FmtType) 2.325 - { 2.326 - case DevFmtUByte: 2.327 - device->FmtType = DevFmtByte; 2.328 - /* fall-through */ 2.329 - case DevFmtByte: 2.330 - streamFormat.mBitsPerChannel = 8; 2.331 - streamFormat.mBytesPerPacket = streamFormat.mChannelsPerFrame; 2.332 - streamFormat.mBytesPerFrame = streamFormat.mChannelsPerFrame; 2.333 - break; 2.334 - case DevFmtUShort: 2.335 - case DevFmtFloat: 2.336 - device->FmtType = DevFmtShort; 2.337 - /* fall-through */ 2.338 - case DevFmtShort: 2.339 - streamFormat.mBitsPerChannel = 16; 2.340 - streamFormat.mBytesPerPacket = 2 * streamFormat.mChannelsPerFrame; 2.341 - streamFormat.mBytesPerFrame = 2 * streamFormat.mChannelsPerFrame; 2.342 - break; 2.343 - } 2.344 - streamFormat.mFormatID = kAudioFormatLinearPCM; 2.345 - streamFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | 2.346 - kAudioFormatFlagsNativeEndian | 2.347 - kLinearPCMFormatFlagIsPacked; 2.348 - 2.349 - err = AudioUnitSetProperty(data->audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &streamFormat, sizeof(AudioStreamBasicDescription)); 2.350 - if(err != noErr) 2.351 - { 2.352 - ERR("AudioUnitSetProperty failed\n"); 2.353 - return ALC_FALSE; 2.354 - } 2.355 - 2.356 - /* setup callback */ 2.357 - data->frameSize = FrameSizeFromDevFmt(device->FmtChans, device->FmtType); 2.358 - input.inputProc = ca_callback; 2.359 - input.inputProcRefCon = device; 2.360 - 2.361 - err = AudioUnitSetProperty(data->audioUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &input, sizeof(AURenderCallbackStruct)); 2.362 - if(err != noErr) 2.363 - { 2.364 - ERR("AudioUnitSetProperty failed\n"); 2.365 - return ALC_FALSE; 2.366 - } 2.367 - 2.368 - return ALC_TRUE; 2.369 -} 2.370 - 2.371 -static void ca_stop_playback(ALCdevice *device) 2.372 -{ 2.373 - ca_data *data = (ca_data*)device->ExtraData; 2.374 - OSStatus err; 2.375 - 2.376 - AudioOutputUnitStop(data->audioUnit); 2.377 - err = AudioUnitUninitialize(data->audioUnit); 2.378 - if(err != noErr) 2.379 - ERR("-- AudioUnitUninitialize failed.\n"); 2.380 -} 2.381 - 2.382 -static ALCboolean ca_open_capture(ALCdevice *device, const ALCchar *deviceName) 2.383 -{ 2.384 - AudioStreamBasicDescription requestedFormat; // The application requested format 2.385 - AudioStreamBasicDescription hardwareFormat; // The hardware format 2.386 - AudioStreamBasicDescription outputFormat; // The AudioUnit output format 2.387 - AURenderCallbackStruct input; 2.388 - ComponentDescription desc; 2.389 - AudioDeviceID inputDevice; 2.390 - UInt32 outputFrameCount; 2.391 - UInt32 propertySize; 2.392 - UInt32 enableIO; 2.393 - Component comp; 2.394 - ca_data *data; 2.395 - OSStatus err; 2.396 - 2.397 - desc.componentType = kAudioUnitType_Output; 2.398 - desc.componentSubType = kAudioUnitSubType_HALOutput; 2.399 - desc.componentManufacturer = kAudioUnitManufacturer_Apple; 2.400 - desc.componentFlags = 0; 2.401 - desc.componentFlagsMask = 0; 2.402 - 2.403 - // Search for component with given description 2.404 - comp = FindNextComponent(NULL, &desc); 2.405 - if(comp == NULL) 2.406 - { 2.407 - ERR("FindNextComponent failed\n"); 2.408 - return ALC_FALSE; 2.409 - } 2.410 - 2.411 - data = calloc(1, sizeof(*data)); 2.412 - device->ExtraData = data; 2.413 - 2.414 - // Open the component 2.415 - err = OpenAComponent(comp, &data->audioUnit); 2.416 - if(err != noErr) 2.417 - { 2.418 - ERR("OpenAComponent failed\n"); 2.419 - goto error; 2.420 - } 2.421 - 2.422 - // Turn off AudioUnit output 2.423 - enableIO = 0; 2.424 - err = AudioUnitSetProperty(data->audioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, 0, &enableIO, sizeof(ALuint)); 2.425 - if(err != noErr) 2.426 - { 2.427 - ERR("AudioUnitSetProperty failed\n"); 2.428 - goto error; 2.429 - } 2.430 - 2.431 - // Turn on AudioUnit input 2.432 - enableIO = 1; 2.433 - err = AudioUnitSetProperty(data->audioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, &enableIO, sizeof(ALuint)); 2.434 - if(err != noErr) 2.435 - { 2.436 - ERR("AudioUnitSetProperty failed\n"); 2.437 - goto error; 2.438 - } 2.439 - 2.440 - // Get the default input device 2.441 - propertySize = sizeof(AudioDeviceID); 2.442 - err = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, &propertySize, &inputDevice); 2.443 - if(err != noErr) 2.444 - { 2.445 - ERR("AudioHardwareGetProperty failed\n"); 2.446 - goto error; 2.447 - } 2.448 - 2.449 - if(inputDevice == kAudioDeviceUnknown) 2.450 - { 2.451 - ERR("No input device found\n"); 2.452 - goto error; 2.453 - } 2.454 - 2.455 - // Track the input device 2.456 - err = AudioUnitSetProperty(data->audioUnit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &inputDevice, sizeof(AudioDeviceID)); 2.457 - if(err != noErr) 2.458 - { 2.459 - ERR("AudioUnitSetProperty failed\n"); 2.460 - goto error; 2.461 - } 2.462 - 2.463 - // set capture callback 2.464 - input.inputProc = ca_capture_callback; 2.465 - input.inputProcRefCon = device; 2.466 - 2.467 - err = AudioUnitSetProperty(data->audioUnit, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global, 0, &input, sizeof(AURenderCallbackStruct)); 2.468 - if(err != noErr) 2.469 - { 2.470 - ERR("AudioUnitSetProperty failed\n"); 2.471 - goto error; 2.472 - } 2.473 - 2.474 - // Initialize the device 2.475 - err = AudioUnitInitialize(data->audioUnit); 2.476 - if(err != noErr) 2.477 - { 2.478 - ERR("AudioUnitInitialize failed\n"); 2.479 - goto error; 2.480 - } 2.481 - 2.482 - // Get the hardware format 2.483 - propertySize = sizeof(AudioStreamBasicDescription); 2.484 - err = AudioUnitGetProperty(data->audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 1, &hardwareFormat, &propertySize); 2.485 - if(err != noErr || propertySize != sizeof(AudioStreamBasicDescription)) 2.486 - { 2.487 - ERR("AudioUnitGetProperty failed\n"); 2.488 - goto error; 2.489 - } 2.490 - 2.491 - // Set up the requested format description 2.492 - switch(device->FmtType) 2.493 - { 2.494 - case DevFmtUByte: 2.495 - requestedFormat.mBitsPerChannel = 8; 2.496 - requestedFormat.mFormatFlags = kAudioFormatFlagIsPacked; 2.497 - break; 2.498 - case DevFmtShort: 2.499 - requestedFormat.mBitsPerChannel = 16; 2.500 - requestedFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked; 2.501 - break; 2.502 - case DevFmtFloat: 2.503 - requestedFormat.mBitsPerChannel = 32; 2.504 - requestedFormat.mFormatFlags = kAudioFormatFlagIsPacked; 2.505 - break; 2.506 - case DevFmtByte: 2.507 - case DevFmtUShort: 2.508 - ERR("%s samples not supported\n", DevFmtTypeString(device->FmtType)); 2.509 - goto error; 2.510 - } 2.511 - 2.512 - switch(device->FmtChans) 2.513 - { 2.514 - case DevFmtMono: 2.515 - requestedFormat.mChannelsPerFrame = 1; 2.516 - break; 2.517 - case DevFmtStereo: 2.518 - requestedFormat.mChannelsPerFrame = 2; 2.519 - break; 2.520 - 2.521 - case DevFmtQuad: 2.522 - case DevFmtX51: 2.523 - case DevFmtX51Side: 2.524 - case DevFmtX61: 2.525 - case DevFmtX71: 2.526 - ERR("%s not supported\n", DevFmtChannelsString(device->FmtChans)); 2.527 - goto error; 2.528 - } 2.529 - 2.530 - requestedFormat.mBytesPerFrame = requestedFormat.mChannelsPerFrame * requestedFormat.mBitsPerChannel / 8; 2.531 - requestedFormat.mBytesPerPacket = requestedFormat.mBytesPerFrame; 2.532 - requestedFormat.mSampleRate = device->Frequency; 2.533 - requestedFormat.mFormatID = kAudioFormatLinearPCM; 2.534 - requestedFormat.mReserved = 0; 2.535 - requestedFormat.mFramesPerPacket = 1; 2.536 - 2.537 - // save requested format description for later use 2.538 - data->format = requestedFormat; 2.539 - data->frameSize = FrameSizeFromDevFmt(device->FmtChans, device->FmtType); 2.540 - 2.541 - // Use intermediate format for sample rate conversion (outputFormat) 2.542 - // Set sample rate to the same as hardware for resampling later 2.543 - outputFormat = requestedFormat; 2.544 - outputFormat.mSampleRate = hardwareFormat.mSampleRate; 2.545 - 2.546 - // Determine sample rate ratio for resampling 2.547 - data->sampleRateRatio = outputFormat.mSampleRate / device->Frequency; 2.548 - 2.549 - // The output format should be the requested format, but using the hardware sample rate 2.550 - // This is because the AudioUnit will automatically scale other properties, except for sample rate 2.551 - err = AudioUnitSetProperty(data->audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, (void *)&outputFormat, sizeof(outputFormat)); 2.552 - if(err != noErr) 2.553 - { 2.554 - ERR("AudioUnitSetProperty failed\n"); 2.555 - goto error; 2.556 - } 2.557 - 2.558 - // Set the AudioUnit output format frame count 2.559 - outputFrameCount = device->UpdateSize * data->sampleRateRatio; 2.560 - err = AudioUnitSetProperty(data->audioUnit, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Output, 0, &outputFrameCount, sizeof(outputFrameCount)); 2.561 - if(err != noErr) 2.562 - { 2.563 - ERR("AudioUnitSetProperty failed: %d\n", err); 2.564 - goto error; 2.565 - } 2.566 - 2.567 - // Set up sample converter 2.568 - err = AudioConverterNew(&outputFormat, &requestedFormat, &data->audioConverter); 2.569 - if(err != noErr) 2.570 - { 2.571 - ERR("AudioConverterNew failed: %d\n", err); 2.572 - goto error; 2.573 - } 2.574 - 2.575 - // Create a buffer for use in the resample callback 2.576 - data->resampleBuffer = malloc(device->UpdateSize * data->frameSize * data->sampleRateRatio); 2.577 - 2.578 - // Allocate buffer for the AudioUnit output 2.579 - data->bufferList = allocate_buffer_list(outputFormat.mChannelsPerFrame, device->UpdateSize * data->frameSize * data->sampleRateRatio); 2.580 - if(data->bufferList == NULL) 2.581 - { 2.582 - alcSetError(device, ALC_OUT_OF_MEMORY); 2.583 - goto error; 2.584 - } 2.585 - 2.586 - data->ring = CreateRingBuffer(data->frameSize, (device->UpdateSize * data->sampleRateRatio) * device->NumUpdates); 2.587 - if(data->ring == NULL) 2.588 - { 2.589 - alcSetError(device, ALC_OUT_OF_MEMORY); 2.590 - goto error; 2.591 - } 2.592 - 2.593 - return ALC_TRUE; 2.594 - 2.595 -error: 2.596 - DestroyRingBuffer(data->ring); 2.597 - free(data->resampleBuffer); 2.598 - destroy_buffer_list(data->bufferList); 2.599 - 2.600 - if(data->audioConverter) 2.601 - AudioConverterDispose(data->audioConverter); 2.602 - if(data->audioUnit) 2.603 - CloseComponent(data->audioUnit); 2.604 - 2.605 - free(data); 2.606 - device->ExtraData = NULL; 2.607 - 2.608 - return ALC_FALSE; 2.609 -} 2.610 - 2.611 -static void ca_close_capture(ALCdevice *device) 2.612 -{ 2.613 - ca_data *data = (ca_data*)device->ExtraData; 2.614 - 2.615 - DestroyRingBuffer(data->ring); 2.616 - free(data->resampleBuffer); 2.617 - destroy_buffer_list(data->bufferList); 2.618 - 2.619 - AudioConverterDispose(data->audioConverter); 2.620 - CloseComponent(data->audioUnit); 2.621 - 2.622 - free(data); 2.623 - device->ExtraData = NULL; 2.624 -} 2.625 - 2.626 -static void ca_start_capture(ALCdevice *device) 2.627 -{ 2.628 - ca_data *data = (ca_data*)device->ExtraData; 2.629 - OSStatus err = AudioOutputUnitStart(data->audioUnit); 2.630 - if(err != noErr) 2.631 - ERR("AudioOutputUnitStart failed\n"); 2.632 -} 2.633 - 2.634 -static void ca_stop_capture(ALCdevice *device) 2.635 -{ 2.636 - ca_data *data = (ca_data*)device->ExtraData; 2.637 - OSStatus err = AudioOutputUnitStop(data->audioUnit); 2.638 - if(err != noErr) 2.639 - ERR("AudioOutputUnitStop failed\n"); 2.640 -} 2.641 - 2.642 -static ALCuint ca_available_samples(ALCdevice *device) 2.643 -{ 2.644 - ca_data *data = device->ExtraData; 2.645 - return RingBufferSize(data->ring) / data->sampleRateRatio; 2.646 -} 2.647 - 2.648 -static void ca_capture_samples(ALCdevice *device, ALCvoid *buffer, ALCuint samples) 2.649 -{ 2.650 - ca_data *data = (ca_data*)device->ExtraData; 2.651 - 2.652 - if(samples <= ca_available_samples(device)) 2.653 - { 2.654 - AudioBufferList *list; 2.655 - UInt32 frameCount; 2.656 - OSStatus err; 2.657 - 2.658 - // If no samples are requested, just return 2.659 - if(samples == 0) 2.660 - return; 2.661 - 2.662 - // Allocate a temporary AudioBufferList to use as the return resamples data 2.663 - list = alloca(sizeof(AudioBufferList) + sizeof(AudioBuffer)); 2.664 - 2.665 - // Point the resampling buffer to the capture buffer 2.666 - list->mNumberBuffers = 1; 2.667 - list->mBuffers[0].mNumberChannels = data->format.mChannelsPerFrame; 2.668 - list->mBuffers[0].mDataByteSize = samples * data->frameSize; 2.669 - list->mBuffers[0].mData = buffer; 2.670 - 2.671 - // Resample into another AudioBufferList 2.672 - frameCount = samples; 2.673 - err = AudioConverterFillComplexBuffer(data->audioConverter, ca_capture_conversion_callback, device, 2.674 - &frameCount, list, NULL); 2.675 - if(err != noErr) 2.676 - { 2.677 - ERR("AudioConverterFillComplexBuffer error: %d\n", err); 2.678 - alcSetError(device, ALC_INVALID_VALUE); 2.679 - } 2.680 - } 2.681 - else 2.682 - alcSetError(device, ALC_INVALID_VALUE); 2.683 -} 2.684 - 2.685 -static const BackendFuncs ca_funcs = { 2.686 - ca_open_playback, 2.687 - ca_close_playback, 2.688 - ca_reset_playback, 2.689 - ca_stop_playback, 2.690 - ca_open_capture, 2.691 - ca_close_capture, 2.692 - ca_start_capture, 2.693 - ca_stop_capture, 2.694 - ca_capture_samples, 2.695 - ca_available_samples 2.696 -}; 2.697 - 2.698 -ALCboolean alc_ca_init(BackendFuncs *func_list) 2.699 -{ 2.700 - *func_list = ca_funcs; 2.701 - return ALC_TRUE; 2.702 -} 2.703 - 2.704 -void alc_ca_deinit(void) 2.705 -{ 2.706 -} 2.707 - 2.708 -void alc_ca_probe(enum DevProbe type) 2.709 -{ 2.710 - switch(type) 2.711 - { 2.712 - case DEVICE_PROBE: 2.713 - AppendDeviceList(ca_device); 2.714 - break; 2.715 - case ALL_DEVICE_PROBE: 2.716 - AppendAllDeviceList(ca_device); 2.717 - break; 2.718 - case CAPTURE_DEVICE_PROBE: 2.719 - AppendCaptureDeviceList(ca_device); 2.720 - break; 2.721 - } 2.722 -}
3.1 --- a/Alc/backends/dsound.c Tue Oct 25 13:03:35 2011 -0700 3.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 3.3 @@ -1,614 +0,0 @@ 3.4 -/** 3.5 - * OpenAL cross platform audio library 3.6 - * Copyright (C) 1999-2007 by authors. 3.7 - * This library is free software; you can redistribute it and/or 3.8 - * modify it under the terms of the GNU Library General Public 3.9 - * License as published by the Free Software Foundation; either 3.10 - * version 2 of the License, or (at your option) any later version. 3.11 - * 3.12 - * This library is distributed in the hope that it will be useful, 3.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 3.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 3.15 - * Library General Public License for more details. 3.16 - * 3.17 - * You should have received a copy of the GNU Library General Public 3.18 - * License along with this library; if not, write to the 3.19 - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 3.20 - * Boston, MA 02111-1307, USA. 3.21 - * Or go to http://www.gnu.org/copyleft/lgpl.html 3.22 - */ 3.23 - 3.24 -#include "config.h" 3.25 - 3.26 -#define _WIN32_WINNT 0x0500 3.27 -#include <stdlib.h> 3.28 -#include <stdio.h> 3.29 -#include <memory.h> 3.30 - 3.31 -#include <dsound.h> 3.32 -#include <cguid.h> 3.33 -#include <mmreg.h> 3.34 -#ifndef _WAVEFORMATEXTENSIBLE_ 3.35 -#include <ks.h> 3.36 -#include <ksmedia.h> 3.37 -#endif 3.38 - 3.39 -#include "alMain.h" 3.40 -#include "AL/al.h" 3.41 -#include "AL/alc.h" 3.42 - 3.43 -#ifndef DSSPEAKER_5POINT1 3.44 -#define DSSPEAKER_5POINT1 6 3.45 -#endif 3.46 -#ifndef DSSPEAKER_7POINT1 3.47 -#define DSSPEAKER_7POINT1 7 3.48 -#endif 3.49 - 3.50 -DEFINE_GUID(KSDATAFORMAT_SUBTYPE_PCM, 0x00000001, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); 3.51 -DEFINE_GUID(KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, 0x00000003, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); 3.52 - 3.53 - 3.54 -static HMODULE ds_handle; 3.55 -static HRESULT (WINAPI *pDirectSoundCreate)(LPCGUID pcGuidDevice, IDirectSound **ppDS, IUnknown *pUnkOuter); 3.56 -static HRESULT (WINAPI *pDirectSoundEnumerateA)(LPDSENUMCALLBACKA pDSEnumCallback, void *pContext); 3.57 - 3.58 -#define DirectSoundCreate pDirectSoundCreate 3.59 -#define DirectSoundEnumerateA pDirectSoundEnumerateA 3.60 - 3.61 - 3.62 -typedef struct { 3.63 - // DirectSound Playback Device 3.64 - IDirectSound *lpDS; 3.65 - IDirectSoundBuffer *DSpbuffer; 3.66 - IDirectSoundBuffer *DSsbuffer; 3.67 - IDirectSoundNotify *DSnotify; 3.68 - HANDLE hNotifyEvent; 3.69 - 3.70 - volatile int killNow; 3.71 - ALvoid *thread; 3.72 -} DSoundData; 3.73 - 3.74 - 3.75 -typedef struct { 3.76 - ALCchar *name; 3.77 - GUID guid; 3.78 -} DevMap; 3.79 - 3.80 -static const ALCchar dsDevice[] = "DirectSound Default"; 3.81 -static DevMap *DeviceList; 3.82 -static ALuint NumDevices; 3.83 - 3.84 -#define MAX_UPDATES 128 3.85 - 3.86 -static ALCboolean DSoundLoad(void) 3.87 -{ 3.88 - ALCboolean ok = ALC_TRUE; 3.89 - if(!ds_handle) 3.90 - { 3.91 - ds_handle = LoadLibraryA("dsound.dll"); 3.92 - if(ds_handle == NULL) 3.93 - { 3.94 - ERR("Failed to load dsound.dll\n"); 3.95 - return ALC_FALSE; 3.96 - } 3.97 - 3.98 -#define LOAD_FUNC(x) do { \ 3.99 - if((p##x = (void*)GetProcAddress(ds_handle, #x)) == NULL) { \ 3.100 - ERR("Could not load %s from dsound.dll\n", #x); \ 3.101 - ok = ALC_FALSE; \ 3.102 - } \ 3.103 -} while(0) 3.104 - LOAD_FUNC(DirectSoundCreate); 3.105 - LOAD_FUNC(DirectSoundEnumerateA); 3.106 -#undef LOAD_FUNC 3.107 - 3.108 - if(!ok) 3.109 - { 3.110 - FreeLibrary(ds_handle); 3.111 - ds_handle = NULL; 3.112 - } 3.113 - } 3.114 - return ok; 3.115 -} 3.116 - 3.117 - 3.118 -static BOOL CALLBACK DSoundEnumDevices(LPGUID guid, LPCSTR desc, LPCSTR drvname, LPVOID data) 3.119 -{ 3.120 - char str[1024]; 3.121 - void *temp; 3.122 - int count; 3.123 - ALuint i; 3.124 - 3.125 - (void)data; 3.126 - (void)drvname; 3.127 - 3.128 - if(!guid) 3.129 - return TRUE; 3.130 - 3.131 - count = 0; 3.132 - do { 3.133 - if(count == 0) 3.134 - snprintf(str, sizeof(str), "%s", desc); 3.135 - else 3.136 - snprintf(str, sizeof(str), "%s #%d", desc, count+1); 3.137 - count++; 3.138 - 3.139 - for(i = 0;i < NumDevices;i++) 3.140 - { 3.141 - if(strcmp(str, DeviceList[i].name) == 0) 3.142 - break; 3.143 - } 3.144 - } while(i != NumDevices); 3.145 - 3.146 - temp = realloc(DeviceList, sizeof(DevMap) * (NumDevices+1)); 3.147 - if(temp) 3.148 - { 3.149 - DeviceList = temp; 3.150 - DeviceList[NumDevices].name = strdup(str); 3.151 - DeviceList[NumDevices].guid = *guid; 3.152 - NumDevices++; 3.153 - } 3.154 - 3.155 - return TRUE; 3.156 -} 3.157 - 3.158 - 3.159 -static ALuint DSoundProc(ALvoid *ptr) 3.160 -{ 3.161 - ALCdevice *pDevice = (ALCdevice*)ptr; 3.162 - DSoundData *pData = (DSoundData*)pDevice->ExtraData; 3.163 - DSBCAPS DSBCaps; 3.164 - DWORD LastCursor = 0; 3.165 - DWORD PlayCursor; 3.166 - VOID *WritePtr1, *WritePtr2; 3.167 - DWORD WriteCnt1, WriteCnt2; 3.168 - BOOL Playing = FALSE; 3.169 - DWORD FrameSize; 3.170 - DWORD FragSize; 3.171 - DWORD avail; 3.172 - HRESULT err; 3.173 - 3.174 - SetRTPriority(); 3.175 - 3.176 - memset(&DSBCaps, 0, sizeof(DSBCaps)); 3.177 - DSBCaps.dwSize = sizeof(DSBCaps); 3.178 - err = IDirectSoundBuffer_GetCaps(pData->DSsbuffer, &DSBCaps); 3.179 - if(FAILED(err)) 3.180 - { 3.181 - ERR("Failed to get buffer caps: 0x%lx\n", err); 3.182 - aluHandleDisconnect(pDevice); 3.183 - return 1; 3.184 - } 3.185 - 3.186 - FrameSize = FrameSizeFromDevFmt(pDevice->FmtChans, pDevice->FmtType); 3.187 - FragSize = pDevice->UpdateSize * FrameSize; 3.188 - 3.189 - IDirectSoundBuffer_GetCurrentPosition(pData->DSsbuffer, &LastCursor, NULL); 3.190 - while(!pData->killNow) 3.191 - { 3.192 - // Get current play cursor 3.193 - IDirectSoundBuffer_GetCurrentPosition(pData->DSsbuffer, &PlayCursor, NULL); 3.194 - avail = (PlayCursor-LastCursor+DSBCaps.dwBufferBytes) % DSBCaps.dwBufferBytes; 3.195 - 3.196 - if(avail < FragSize) 3.197 - { 3.198 - if(!Playing) 3.199 - { 3.200 - err = IDirectSoundBuffer_Play(pData->DSsbuffer, 0, 0, DSBPLAY_LOOPING); 3.201 - if(FAILED(err)) 3.202 - { 3.203 - ERR("Failed to play buffer: 0x%lx\n", err); 3.204 - aluHandleDisconnect(pDevice); 3.205 - return 1; 3.206 - } 3.207 - Playing = TRUE; 3.208 - } 3.209 - 3.210 - avail = WaitForSingleObjectEx(pData->hNotifyEvent, 2000, FALSE); 3.211 - if(avail != WAIT_OBJECT_0) 3.212 - ERR("WaitForSingleObjectEx error: 0x%lx\n", avail); 3.213 - continue; 3.214 - } 3.215 - avail -= avail%FragSize; 3.216 - 3.217 - // Lock output buffer 3.218 - WriteCnt1 = 0; 3.219 - WriteCnt2 = 0; 3.220 - err = IDirectSoundBuffer_Lock(pData->DSsbuffer, LastCursor, avail, &WritePtr1, &WriteCnt1, &WritePtr2, &WriteCnt2, 0); 3.221 - 3.222 - // If the buffer is lost, restore it and lock 3.223 - if(err == DSERR_BUFFERLOST) 3.224 - { 3.225 - WARN("Buffer lost, restoring...\n"); 3.226 - err = IDirectSoundBuffer_Restore(pData->DSsbuffer); 3.227 - if(SUCCEEDED(err)) 3.228 - { 3.229 - Playing = FALSE; 3.230 - LastCursor = 0; 3.231 - err = IDirectSoundBuffer_Lock(pData->DSsbuffer, 0, DSBCaps.dwBufferBytes, &WritePtr1, &WriteCnt1, &WritePtr2, &WriteCnt2, 0); 3.232 - } 3.233 - } 3.234 - 3.235 - // Successfully locked the output buffer 3.236 - if(SUCCEEDED(err)) 3.237 - { 3.238 - // If we have an active context, mix data directly into output buffer otherwise fill with silence 3.239 - aluMixData(pDevice, WritePtr1, WriteCnt1/FrameSize); 3.240 - aluMixData(pDevice, WritePtr2, WriteCnt2/FrameSize); 3.241 - 3.242 - // Unlock output buffer only when successfully locked 3.243 - IDirectSoundBuffer_Unlock(pData->DSsbuffer, WritePtr1, WriteCnt1, WritePtr2, WriteCnt2); 3.244 - } 3.245 - else 3.246 - { 3.247 - ERR("Buffer lock error: %#lx\n", err); 3.248 - aluHandleDisconnect(pDevice); 3.249 - return 1; 3.250 - } 3.251 - 3.252 - // Update old write cursor location 3.253 - LastCursor += WriteCnt1+WriteCnt2; 3.254 - LastCursor %= DSBCaps.dwBufferBytes; 3.255 - } 3.256 - 3.257 - return 0; 3.258 -} 3.259 - 3.260 -static ALCboolean DSoundOpenPlayback(ALCdevice *device, const ALCchar *deviceName) 3.261 -{ 3.262 - DSoundData *pData = NULL; 3.263 - LPGUID guid = NULL; 3.264 - HRESULT hr; 3.265 - 3.266 - if(!deviceName) 3.267 - deviceName = dsDevice; 3.268 - else if(strcmp(deviceName, dsDevice) != 0) 3.269 - { 3.270 - ALuint i; 3.271 - 3.272 - if(!DeviceList) 3.273 - { 3.274 - hr = DirectSoundEnumerateA(DSoundEnumDevices, NULL); 3.275 - if(FAILED(hr)) 3.276 - ERR("Error enumerating DirectSound devices (%#x)!\n", (unsigned int)hr); 3.277 - } 3.278 - 3.279 - for(i = 0;i < NumDevices;i++) 3.280 - { 3.281 - if(strcmp(deviceName, DeviceList[i].name) == 0) 3.282 - { 3.283 - guid = &DeviceList[i].guid; 3.284 - break; 3.285 - } 3.286 - } 3.287 - if(i == NumDevices) 3.288 - return ALC_FALSE; 3.289 - } 3.290 - 3.291 - //Initialise requested device 3.292 - pData = calloc(1, sizeof(DSoundData)); 3.293 - if(!pData) 3.294 - { 3.295 - alcSetError(device, ALC_OUT_OF_MEMORY); 3.296 - return ALC_FALSE; 3.297 - } 3.298 - 3.299 - hr = DS_OK; 3.300 - pData->hNotifyEvent = CreateEvent(NULL, FALSE, FALSE, NULL); 3.301 - if(pData->hNotifyEvent == NULL) 3.302 - hr = E_FAIL; 3.303 - 3.304 - //DirectSound Init code 3.305 - if(SUCCEEDED(hr)) 3.306 - hr = DirectSoundCreate(guid, &pData->lpDS, NULL); 3.307 - if(SUCCEEDED(hr)) 3.308 - hr = IDirectSound_SetCooperativeLevel(pData->lpDS, GetForegroundWindow(), DSSCL_PRIORITY); 3.309 - if(FAILED(hr)) 3.310 - { 3.311 - if(pData->lpDS) 3.312 - IDirectSound_Release(pData->lpDS); 3.313 - if(pData->hNotifyEvent) 3.314 - CloseHandle(pData->hNotifyEvent); 3.315 - free(pData); 3.316 - ERR("Device init failed: 0x%08lx\n", hr); 3.317 - return ALC_FALSE; 3.318 - } 3.319 - 3.320 - device->szDeviceName = strdup(deviceName); 3.321 - device->ExtraData = pData; 3.322 - return ALC_TRUE; 3.323 -} 3.324 - 3.325 -static void DSoundClosePlayback(ALCdevice *device) 3.326 -{ 3.327 - DSoundData *pData = device->ExtraData; 3.328 - 3.329 - IDirectSound_Release(pData->lpDS); 3.330 - CloseHandle(pData->hNotifyEvent); 3.331 - free(pData); 3.332 - device->ExtraData = NULL; 3.333 -} 3.334 - 3.335 -static ALCboolean DSoundResetPlayback(ALCdevice *device) 3.336 -{ 3.337 - DSoundData *pData = (DSoundData*)device->ExtraData; 3.338 - DSBUFFERDESC DSBDescription; 3.339 - WAVEFORMATEXTENSIBLE OutputType; 3.340 - DWORD speakers; 3.341 - HRESULT hr; 3.342 - 3.343 - memset(&OutputType, 0, sizeof(OutputType)); 3.344 - 3.345 - switch(device->FmtType) 3.346 - { 3.347 - case DevFmtByte: 3.348 - device->FmtType = DevFmtUByte; 3.349 - break; 3.350 - case DevFmtUShort: 3.351 - device->FmtType = DevFmtShort; 3.352 - break; 3.353 - case DevFmtUByte: 3.354 - case DevFmtShort: 3.355 - case DevFmtFloat: 3.356 - break; 3.357 - } 3.358 - 3.359 - hr = IDirectSound_GetSpeakerConfig(pData->lpDS, &speakers); 3.360 - if(SUCCEEDED(hr)) 3.361 - { 3.362 - if(!(device->Flags&DEVICE_CHANNELS_REQUEST)) 3.363 - { 3.364 - speakers = DSSPEAKER_CONFIG(speakers); 3.365 - if(speakers == DSSPEAKER_MONO) 3.366 - device->FmtChans = DevFmtMono; 3.367 - else if(speakers == DSSPEAKER_STEREO || speakers == DSSPEAKER_HEADPHONE) 3.368 - device->FmtChans = DevFmtStereo; 3.369 - else if(speakers == DSSPEAKER_QUAD) 3.370 - device->FmtChans = DevFmtQuad; 3.371 - else if(speakers == DSSPEAKER_5POINT1) 3.372 - device->FmtChans = DevFmtX51; 3.373 - else if(speakers == DSSPEAKER_7POINT1) 3.374 - device->FmtChans = DevFmtX71; 3.375 - else 3.376 - ERR("Unknown system speaker config: 0x%lx\n", speakers); 3.377 - } 3.378 - 3.379 - switch(device->FmtChans) 3.380 - { 3.381 - case DevFmtMono: 3.382 - OutputType.dwChannelMask = SPEAKER_FRONT_CENTER; 3.383 - break; 3.384 - case DevFmtStereo: 3.385 - OutputType.dwChannelMask = SPEAKER_FRONT_LEFT | 3.386 - SPEAKER_FRONT_RIGHT; 3.387 - break; 3.388 - case DevFmtQuad: 3.389 - OutputType.dwChannelMask = SPEAKER_FRONT_LEFT | 3.390 - SPEAKER_FRONT_RIGHT | 3.391 - SPEAKER_BACK_LEFT | 3.392 - SPEAKER_BACK_RIGHT; 3.393 - break; 3.394 - case DevFmtX51: 3.395 - OutputType.dwChannelMask = SPEAKER_FRONT_LEFT | 3.396 - SPEAKER_FRONT_RIGHT | 3.397 - SPEAKER_FRONT_CENTER | 3.398 - SPEAKER_LOW_FREQUENCY | 3.399 - SPEAKER_BACK_LEFT | 3.400 - SPEAKER_BACK_RIGHT; 3.401 - break; 3.402 - case DevFmtX51Side: 3.403 - OutputType.dwChannelMask = SPEAKER_FRONT_LEFT | 3.404 - SPEAKER_FRONT_RIGHT | 3.405 - SPEAKER_FRONT_CENTER | 3.406 - SPEAKER_LOW_FREQUENCY | 3.407 - SPEAKER_SIDE_LEFT | 3.408 - SPEAKER_SIDE_RIGHT; 3.409 - break; 3.410 - case DevFmtX61: 3.411 - OutputType.dwChannelMask = SPEAKER_FRONT_LEFT | 3.412 - SPEAKER_FRONT_RIGHT | 3.413 - SPEAKER_FRONT_CENTER | 3.414 - SPEAKER_LOW_FREQUENCY | 3.415 - SPEAKER_BACK_CENTER | 3.416 - SPEAKER_SIDE_LEFT | 3.417 - SPEAKER_SIDE_RIGHT; 3.418 - break; 3.419 - case DevFmtX71: 3.420 - OutputType.dwChannelMask = SPEAKER_FRONT_LEFT | 3.421 - SPEAKER_FRONT_RIGHT | 3.422 - SPEAKER_FRONT_CENTER | 3.423 - SPEAKER_LOW_FREQUENCY | 3.424 - SPEAKER_BACK_LEFT | 3.425 - SPEAKER_BACK_RIGHT | 3.426 - SPEAKER_SIDE_LEFT | 3.427 - SPEAKER_SIDE_RIGHT; 3.428 - break; 3.429 - } 3.430 - 3.431 - OutputType.Format.wFormatTag = WAVE_FORMAT_PCM; 3.432 - OutputType.Format.nChannels = ChannelsFromDevFmt(device->FmtChans); 3.433 - OutputType.Format.wBitsPerSample = BytesFromDevFmt(device->FmtType) * 8; 3.434 - OutputType.Format.nBlockAlign = OutputType.Format.nChannels*OutputType.Format.wBitsPerSample/8; 3.435 - OutputType.Format.nSamplesPerSec = device->Frequency; 3.436 - OutputType.Format.nAvgBytesPerSec = OutputType.Format.nSamplesPerSec*OutputType.Format.nBlockAlign; 3.437 - OutputType.Format.cbSize = 0; 3.438 - } 3.439 - 3.440 - if(OutputType.Format.nChannels > 2 || device->FmtType == DevFmtFloat) 3.441 - { 3.442 - OutputType.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; 3.443 - OutputType.Samples.wValidBitsPerSample = OutputType.Format.wBitsPerSample; 3.444 - OutputType.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX); 3.445 - if(device->FmtType == DevFmtFloat) 3.446 - OutputType.SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT; 3.447 - else 3.448 - OutputType.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; 3.449 - } 3.450 - else 3.451 - { 3.452 - if(SUCCEEDED(hr)) 3.453 - { 3.454 - memset(&DSBDescription,0,sizeof(DSBUFFERDESC)); 3.455 - DSBDescription.dwSize=sizeof(DSBUFFERDESC); 3.456 - DSBDescription.dwFlags=DSBCAPS_PRIMARYBUFFER; 3.457 - hr = IDirectSound_CreateSoundBuffer(pData->lpDS, &DSBDescription, &pData->DSpbuffer, NULL); 3.458 - } 3.459 - if(SUCCEEDED(hr)) 3.460 - hr = IDirectSoundBuffer_SetFormat(pData->DSpbuffer,&OutputType.Format); 3.461 - } 3.462 - 3.463 - if(SUCCEEDED(hr)) 3.464 - { 3.465 - if(device->NumUpdates > MAX_UPDATES) 3.466 - { 3.467 - device->UpdateSize = (device->UpdateSize*device->NumUpdates + 3.468 - MAX_UPDATES-1) / MAX_UPDATES; 3.469 - device->NumUpdates = MAX_UPDATES; 3.470 - } 3.471 - 3.472 - memset(&DSBDescription,0,sizeof(DSBUFFERDESC)); 3.473 - DSBDescription.dwSize=sizeof(DSBUFFERDESC); 3.474 - DSBDescription.dwFlags=DSBCAPS_CTRLPOSITIONNOTIFY|DSBCAPS_GETCURRENTPOSITION2|DSBCAPS_GLOBALFOCUS; 3.475 - DSBDescription.dwBufferBytes=device->UpdateSize * device->NumUpdates * 3.476 - OutputType.Format.nBlockAlign; 3.477 - DSBDescription.lpwfxFormat=&OutputType.Format; 3.478 - hr = IDirectSound_CreateSoundBuffer(pData->lpDS, &DSBDescription, &pData->DSsbuffer, NULL); 3.479 - } 3.480 - 3.481 - if(SUCCEEDED(hr)) 3.482 - { 3.483 - hr = IDirectSoundBuffer_QueryInterface(pData->DSsbuffer, &IID_IDirectSoundNotify, (LPVOID *)&pData->DSnotify); 3.484 - if(SUCCEEDED(hr)) 3.485 - { 3.486 - DSBPOSITIONNOTIFY notifies[MAX_UPDATES]; 3.487 - ALuint i; 3.488 - 3.489 - for(i = 0;i < device->NumUpdates;++i) 3.490 - { 3.491 - notifies[i].dwOffset = i * device->UpdateSize * 3.492 - OutputType.Format.nBlockAlign; 3.493 - notifies[i].hEventNotify = pData->hNotifyEvent; 3.494 - } 3.495 - if(IDirectSoundNotify_SetNotificationPositions(pData->DSnotify, device->NumUpdates, notifies) != DS_OK) 3.496 - hr = E_FAIL; 3.497 - } 3.498 - } 3.499 - 3.500 - if(SUCCEEDED(hr)) 3.501 - { 3.502 - ResetEvent(pData->hNotifyEvent); 3.503 - SetDefaultWFXChannelOrder(device); 3.504 - pData->thread = StartThread(DSoundProc, device); 3.505 - if(pData->thread == NULL) 3.506 - hr = E_FAIL; 3.507 - } 3.508 - 3.509 - if(FAILED(hr)) 3.510 - { 3.511 - if(pData->DSnotify != NULL) 3.512 - IDirectSoundNotify_Release(pData->DSnotify); 3.513 - pData->DSnotify = NULL; 3.514 - if(pData->DSsbuffer != NULL) 3.515 - IDirectSoundBuffer_Release(pData->DSsbuffer); 3.516 - pData->DSsbuffer = NULL; 3.517 - if(pData->DSpbuffer != NULL) 3.518 - IDirectSoundBuffer_Release(pData->DSpbuffer); 3.519 - pData->DSpbuffer = NULL; 3.520 - return ALC_FALSE; 3.521 - } 3.522 - 3.523 - return ALC_TRUE; 3.524 -} 3.525 - 3.526 -static void DSoundStopPlayback(ALCdevice *device) 3.527 -{ 3.528 - DSoundData *pData = device->ExtraData; 3.529 - 3.530 - if(!pData->thread) 3.531 - return; 3.532 - 3.533 - pData->killNow = 1; 3.534 - StopThread(pData->thread); 3.535 - pData->thread = NULL; 3.536 - 3.537 - pData->killNow = 0; 3.538 - 3.539 - IDirectSoundNotify_Release(pData->DSnotify); 3.540 - pData->DSnotify = NULL; 3.541 - IDirectSoundBuffer_Release(pData->DSsbuffer); 3.542 - pData->DSsbuffer = NULL; 3.543 - if(pData->DSpbuffer != NULL) 3.544 - IDirectSoundBuffer_Release(pData->DSpbuffer); 3.545 - pData->DSpbuffer = NULL; 3.546 -} 3.547 - 3.548 - 3.549 -static const BackendFuncs DSoundFuncs = { 3.550 - DSoundOpenPlayback, 3.551 - DSoundClosePlayback, 3.552 - DSoundResetPlayback, 3.553 - DSoundStopPlayback, 3.554 - NULL, 3.555 - NULL, 3.556 - NULL, 3.557 - NULL, 3.558 - NULL, 3.559 - NULL 3.560 -}; 3.561 - 3.562 - 3.563 -ALCboolean alcDSoundInit(BackendFuncs *FuncList) 3.564 -{ 3.565 - if(!DSoundLoad()) 3.566 - return ALC_FALSE; 3.567 - *FuncList = DSoundFuncs; 3.568 - return ALC_TRUE; 3.569 -} 3.570 - 3.571 -void alcDSoundDeinit(void) 3.572 -{ 3.573 - ALuint i; 3.574 - 3.575 - for(i = 0;i < NumDevices;++i) 3.576 - free(DeviceList[i].name); 3.577 - free(DeviceList); 3.578 - DeviceList = NULL; 3.579 - NumDevices = 0; 3.580 - 3.581 - if(ds_handle) 3.582 - FreeLibrary(ds_handle); 3.583 - ds_handle = NULL; 3.584 -} 3.585 - 3.586 -void alcDSoundProbe(enum DevProbe type) 3.587 -{ 3.588 - HRESULT hr; 3.589 - ALuint i; 3.590 - 3.591 - switch(type) 3.592 - { 3.593 - case DEVICE_PROBE: 3.594 - AppendDeviceList(dsDevice); 3.595 - break; 3.596 - 3.597 - case ALL_DEVICE_PROBE: 3.598 - for(i = 0;i < NumDevices;++i) 3.599 - free(DeviceList[i].name); 3.600 - free(DeviceList); 3.601 - DeviceList = NULL; 3.602 - NumDevices = 0; 3.603 - 3.604 - hr = DirectSoundEnumerateA(DSoundEnumDevices, NULL); 3.605 - if(FAILED(hr)) 3.606 - ERR("Error enumerating DirectSound devices (%#x)!\n", (unsigned int)hr); 3.607 - else 3.608 - { 3.609 - for(i = 0;i < NumDevices;i++) 3.610 - AppendAllDeviceList(DeviceList[i].name); 3.611 - } 3.612 - break; 3.613 - 3.614 - case CAPTURE_DEVICE_PROBE: 3.615 - break; 3.616 - } 3.617 -}
4.1 --- a/Alc/backends/mmdevapi.c Tue Oct 25 13:03:35 2011 -0700 4.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 4.3 @@ -1,775 +0,0 @@ 4.4 -/** 4.5 - * OpenAL cross platform audio library 4.6 - * Copyright (C) 2011 by authors. 4.7 - * This library is free software; you can redistribute it and/or 4.8 - * modify it under the terms of the GNU Library General Public 4.9 - * License as published by the Free Software Foundation; either 4.10 - * version 2 of the License, or (at your option) any later version. 4.11 - * 4.12 - * This library is distributed in the hope that it will be useful, 4.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 4.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 4.15 - * Library General Public License for more details. 4.16 - * 4.17 - * You should have received a copy of the GNU Library General Public 4.18 - * License along with this library; if not, write to the 4.19 - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 4.20 - * Boston, MA 02111-1307, USA. 4.21 - * Or go to http://www.gnu.org/copyleft/lgpl.html 4.22 - */ 4.23 - 4.24 -#include "config.h" 4.25 - 4.26 -#define COBJMACROS 4.27 -#define _WIN32_WINNT 0x0500 4.28 -#include <stdlib.h> 4.29 -#include <stdio.h> 4.30 -#include <memory.h> 4.31 - 4.32 -#include <mmdeviceapi.h> 4.33 -#include <audioclient.h> 4.34 -#include <cguid.h> 4.35 -#include <mmreg.h> 4.36 -#ifndef _WAVEFORMATEXTENSIBLE_ 4.37 -#include <ks.h> 4.38 -#include <ksmedia.h> 4.39 -#endif 4.40 - 4.41 -#include "alMain.h" 4.42 -#include "AL/al.h" 4.43 -#include "AL/alc.h" 4.44 - 4.45 - 4.46 -DEFINE_GUID(KSDATAFORMAT_SUBTYPE_PCM, 0x00000001, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); 4.47 -DEFINE_GUID(KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, 0x00000003, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); 4.48 - 4.49 -#define MONO SPEAKER_FRONT_CENTER 4.50 -#define STEREO (SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT) 4.51 -#define QUAD (SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_BACK_LEFT|SPEAKER_BACK_RIGHT) 4.52 -#define X5DOT1 (SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_LOW_FREQUENCY|SPEAKER_BACK_LEFT|SPEAKER_BACK_RIGHT) 4.53 -#define X5DOT1SIDE (SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_LOW_FREQUENCY|SPEAKER_SIDE_LEFT|SPEAKER_SIDE_RIGHT) 4.54 -#define X6DOT1 (SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_LOW_FREQUENCY|SPEAKER_BACK_CENTER|SPEAKER_SIDE_LEFT|SPEAKER_SIDE_RIGHT) 4.55 -#define X7DOT1 (SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_LOW_FREQUENCY|SPEAKER_BACK_LEFT|SPEAKER_BACK_RIGHT|SPEAKER_SIDE_LEFT|SPEAKER_SIDE_RIGHT) 4.56 - 4.57 - 4.58 -typedef struct { 4.59 - IMMDevice *mmdev; 4.60 - IAudioClient *client; 4.61 - HANDLE hNotifyEvent; 4.62 - 4.63 - HANDLE MsgEvent; 4.64 - 4.65 - volatile int killNow; 4.66 - ALvoid *thread; 4.67 -} MMDevApiData; 4.68 - 4.69 - 4.70 -static const ALCchar mmDevice[] = "WASAPI Default"; 4.71 - 4.72 - 4.73 -static HANDLE ThreadHdl; 4.74 -static DWORD ThreadID; 4.75 - 4.76 -typedef struct { 4.77 - HANDLE FinishedEvt; 4.78 - HRESULT result; 4.79 -} ThreadRequest; 4.80 - 4.81 -#define WM_USER_OpenDevice (WM_USER+0) 4.82 -#define WM_USER_ResetDevice (WM_USER+1) 4.83 -#define WM_USER_StopDevice (WM_USER+2) 4.84 -#define WM_USER_CloseDevice (WM_USER+3) 4.85 - 4.86 -static HRESULT WaitForResponse(ThreadRequest *req) 4.87 -{ 4.88 - if(WaitForSingleObject(req->FinishedEvt, INFINITE) == WAIT_OBJECT_0) 4.89 - return req->result; 4.90 - ERR("Message response error: %lu\n", GetLastError()); 4.91 - return E_FAIL; 4.92 -} 4.93 - 4.94 - 4.95 -static ALuint MMDevApiProc(ALvoid *ptr) 4.96 -{ 4.97 - ALCdevice *device = ptr; 4.98 - MMDevApiData *data = device->ExtraData; 4.99 - union { 4.100 - IAudioRenderClient *iface; 4.101 - void *ptr; 4.102 - } render; 4.103 - UINT32 written, len; 4.104 - BYTE *buffer; 4.105 - HRESULT hr; 4.106 - 4.107 - hr = CoInitialize(NULL); 4.108 - if(FAILED(hr)) 4.109 - { 4.110 - ERR("CoInitialize(NULL) failed: 0x%08lx\n", hr); 4.111 - aluHandleDisconnect(device); 4.112 - return 0; 4.113 - } 4.114 - 4.115 - hr = IAudioClient_GetService(data->client, &IID_IAudioRenderClient, &render.ptr); 4.116 - if(FAILED(hr)) 4.117 - { 4.118 - ERR("Failed to get AudioRenderClient service: 0x%08lx\n", hr); 4.119 - aluHandleDisconnect(device); 4.120 - return 0; 4.121 - } 4.122 - 4.123 - SetRTPriority(); 4.124 - 4.125 - while(!data->killNow) 4.126 - { 4.127 - hr = IAudioClient_GetCurrentPadding(data->client, &written); 4.128 - if(FAILED(hr)) 4.129 - { 4.130 - ERR("Failed to get padding: 0x%08lx\n", hr); 4.131 - aluHandleDisconnect(device); 4.132 - break; 4.133 - } 4.134 - 4.135 - len = device->UpdateSize*device->NumUpdates - written; 4.136 - if(len < device->UpdateSize) 4.137 - { 4.138 - DWORD res; 4.139 - res = WaitForSingleObjectEx(data->hNotifyEvent, 2000, FALSE); 4.140 - if(res != WAIT_OBJECT_0) 4.141 - ERR("WaitForSingleObjectEx error: 0x%lx\n", res); 4.142 - continue; 4.143 - } 4.144 - len -= len%device->UpdateSize; 4.145 - 4.146 - hr = IAudioRenderClient_GetBuffer(render.iface, len, &buffer); 4.147 - if(SUCCEEDED(hr)) 4.148 - { 4.149 - aluMixData(device, buffer, len); 4.150 - hr = IAudioRenderClient_ReleaseBuffer(render.iface, len, 0); 4.151 - } 4.152 - if(FAILED(hr)) 4.153 - { 4.154 - ERR("Failed to buffer data: 0x%08lx\n", hr); 4.155 - aluHandleDisconnect(device); 4.156 - break; 4.157 - } 4.158 - } 4.159 - 4.160 - IAudioRenderClient_Release(render.iface); 4.161 - 4.162 - CoUninitialize(); 4.163 - return 0; 4.164 -} 4.165 - 4.166 - 4.167 -static ALCboolean MakeExtensible(WAVEFORMATEXTENSIBLE *out, const WAVEFORMATEX *in) 4.168 -{ 4.169 - memset(out, 0, sizeof(*out)); 4.170 - if(in->wFormatTag == WAVE_FORMAT_EXTENSIBLE) 4.171 - *out = *(WAVEFORMATEXTENSIBLE*)in; 4.172 - else if(in->wFormatTag == WAVE_FORMAT_PCM) 4.173 - { 4.174 - out->Format = *in; 4.175 - out->Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; 4.176 - out->Format.cbSize = sizeof(*out) - sizeof(*in); 4.177 - if(out->Format.nChannels == 1) 4.178 - out->dwChannelMask = MONO; 4.179 - else if(out->Format.nChannels == 2) 4.180 - out->dwChannelMask = STEREO; 4.181 - else 4.182 - ERR("Unhandled PCM channel count: %d\n", out->Format.nChannels); 4.183 - out->SubFormat = KSDATAFORMAT_SUBTYPE_PCM; 4.184 - } 4.185 - else if(in->wFormatTag == WAVE_FORMAT_IEEE_FLOAT) 4.186 - { 4.187 - out->Format = *in; 4.188 - out->Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; 4.189 - out->Format.cbSize = sizeof(*out) - sizeof(*in); 4.190 - if(out->Format.nChannels == 1) 4.191 - out->dwChannelMask = MONO; 4.192 - else if(out->Format.nChannels == 2) 4.193 - out->dwChannelMask = STEREO; 4.194 - else 4.195 - ERR("Unhandled IEEE float channel count: %d\n", out->Format.nChannels); 4.196 - out->SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT; 4.197 - } 4.198 - else 4.199 - { 4.200 - ERR("Unhandled format tag: 0x%04x\n", in->wFormatTag); 4.201 - return ALC_FALSE; 4.202 - } 4.203 - return ALC_TRUE; 4.204 -} 4.205 - 4.206 -static HRESULT DoReset(ALCdevice *device) 4.207 -{ 4.208 - MMDevApiData *data = device->ExtraData; 4.209 - WAVEFORMATEXTENSIBLE OutputType; 4.210 - WAVEFORMATEX *wfx = NULL; 4.211 - REFERENCE_TIME min_per; 4.212 - UINT32 buffer_len, min_len; 4.213 - HRESULT hr; 4.214 - 4.215 - hr = IAudioClient_GetMixFormat(data->client, &wfx); 4.216 - if(FAILED(hr)) 4.217 - { 4.218 - ERR("Failed to get mix format: 0x%08lx\n", hr); 4.219 - return hr; 4.220 - } 4.221 - 4.222 - if(!MakeExtensible(&OutputType, wfx)) 4.223 - { 4.224 - CoTaskMemFree(wfx); 4.225 - return E_FAIL; 4.226 - } 4.227 - CoTaskMemFree(wfx); 4.228 - wfx = NULL; 4.229 - 4.230 - if(!(device->Flags&DEVICE_FREQUENCY_REQUEST)) 4.231 - device->Frequency = OutputType.Format.nSamplesPerSec; 4.232 - if(!(device->Flags&DEVICE_CHANNELS_REQUEST)) 4.233 - { 4.234 - if(OutputType.Format.nChannels == 1 && OutputType.dwChannelMask == MONO) 4.235 - device->FmtChans = DevFmtMono; 4.236 - else if(OutputType.Format.nChannels == 2 && OutputType.dwChannelMask == STEREO) 4.237 - device->FmtChans = DevFmtStereo; 4.238 - else if(OutputType.Format.nChannels == 4 && OutputType.dwChannelMask == QUAD) 4.239 - device->FmtChans = DevFmtQuad; 4.240 - else if(OutputType.Format.nChannels == 6 && OutputType.dwChannelMask == X5DOT1) 4.241 - device->FmtChans = DevFmtX51; 4.242 - else if(OutputType.Format.nChannels == 6 && OutputType.dwChannelMask == X5DOT1SIDE) 4.243 - device->FmtChans = DevFmtX51Side; 4.244 - else if(OutputType.Format.nChannels == 7 && OutputType.dwChannelMask == X6DOT1) 4.245 - device->FmtChans = DevFmtX61; 4.246 - else if(OutputType.Format.nChannels == 8 && OutputType.dwChannelMask == X7DOT1) 4.247 - device->FmtChans = DevFmtX71; 4.248 - else 4.249 - ERR("Unhandled channel config: %d -- 0x%08lx\n", OutputType.Format.nChannels, OutputType.dwChannelMask); 4.250 - } 4.251 - 4.252 - switch(device->FmtChans) 4.253 - { 4.254 - case DevFmtMono: 4.255 - OutputType.Format.nChannels = 1; 4.256 - OutputType.dwChannelMask = MONO; 4.257 - break; 4.258 - case DevFmtStereo: 4.259 - OutputType.Format.nChannels = 2; 4.260 - OutputType.dwChannelMask = STEREO; 4.261 - break; 4.262 - case DevFmtQuad: 4.263 - OutputType.Format.nChannels = 4; 4.264 - OutputType.dwChannelMask = QUAD; 4.265 - break; 4.266 - case DevFmtX51: 4.267 - OutputType.Format.nChannels = 6; 4.268 - OutputType.dwChannelMask = X5DOT1; 4.269 - break; 4.270 - case DevFmtX51Side: 4.271 - OutputType.Format.nChannels = 6; 4.272 - OutputType.dwChannelMask = X5DOT1SIDE; 4.273 - break; 4.274 - case DevFmtX61: 4.275 - OutputType.Format.nChannels = 7; 4.276 - OutputType.dwChannelMask = X6DOT1; 4.277 - break; 4.278 - case DevFmtX71: 4.279 - OutputType.Format.nChannels = 8; 4.280 - OutputType.dwChannelMask = X7DOT1; 4.281 - break; 4.282 - } 4.283 - switch(device->FmtType) 4.284 - { 4.285 - case DevFmtByte: 4.286 - device->FmtType = DevFmtUByte; 4.287 - /* fall-through */ 4.288 - case DevFmtUByte: 4.289 - OutputType.Format.wBitsPerSample = 8; 4.290 - OutputType.Samples.wValidBitsPerSample = 8; 4.291 - OutputType.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; 4.292 - break; 4.293 - case DevFmtUShort: 4.294 - device->FmtType = DevFmtShort; 4.295 - /* fall-through */ 4.296 - case DevFmtShort: 4.297 - OutputType.Format.wBitsPerSample = 16; 4.298 - OutputType.Samples.wValidBitsPerSample = 16; 4.299 - OutputType.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; 4.300 - break; 4.301 - case DevFmtFloat: 4.302 - OutputType.Format.wBitsPerSample = 32; 4.303 - OutputType.Samples.wValidBitsPerSample = 32; 4.304 - OutputType.SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT; 4.305 - break; 4.306 - } 4.307 - OutputType.Format.nSamplesPerSec = device->Frequency; 4.308 - 4.309 - OutputType.Format.nBlockAlign = OutputType.Format.nChannels * 4.310 - OutputType.Format.wBitsPerSample / 8; 4.311 - OutputType.Format.nAvgBytesPerSec = OutputType.Format.nSamplesPerSec * 4.312 - OutputType.Format.nBlockAlign; 4.313 - 4.314 - hr = IAudioClient_IsFormatSupported(data->client, AUDCLNT_SHAREMODE_SHARED, &OutputType.Format, &wfx); 4.315 - if(FAILED(hr)) 4.316 - { 4.317 - ERR("Failed to check format support: 0x%08lx\n", hr); 4.318 - hr = IAudioClient_GetMixFormat(data->client, &wfx); 4.319 - } 4.320 - if(FAILED(hr)) 4.321 - { 4.322 - ERR("Failed to find a supported format: 0x%08lx\n", hr); 4.323 - return hr; 4.324 - } 4.325 - 4.326 - if(wfx != NULL) 4.327 - { 4.328 - if(!MakeExtensible(&OutputType, wfx)) 4.329 - { 4.330 - CoTaskMemFree(wfx); 4.331 - return E_FAIL; 4.332 - } 4.333 - CoTaskMemFree(wfx); 4.334 - wfx = NULL; 4.335 - 4.336 - if(device->Frequency != OutputType.Format.nSamplesPerSec) 4.337 - { 4.338 - if((device->Flags&DEVICE_FREQUENCY_REQUEST)) 4.339 - ERR("Failed to set %dhz, got %ldhz instead\n", device->Frequency, OutputType.Format.nSamplesPerSec); 4.340 - device->Flags &= ~DEVICE_FREQUENCY_REQUEST; 4.341 - device->Frequency = OutputType.Format.nSamplesPerSec; 4.342 - } 4.343 - 4.344 - if(!((device->FmtChans == DevFmtMono && OutputType.Format.nChannels == 1 && OutputType.dwChannelMask == MONO) || 4.345 - (device->FmtChans == DevFmtStereo && OutputType.Format.nChannels == 2 && OutputType.dwChannelMask == STEREO) || 4.346 - (device->FmtChans == DevFmtQuad && OutputType.Format.nChannels == 4 && OutputType.dwChannelMask == QUAD) || 4.347 - (device->FmtChans == DevFmtX51 && OutputType.Format.nChannels == 6 && OutputType.dwChannelMask == X5DOT1) || 4.348 - (device->FmtChans == DevFmtX51Side && OutputType.Format.nChannels == 6 && OutputType.dwChannelMask == X5DOT1SIDE) || 4.349 - (device->FmtChans == DevFmtX61 && OutputType.Format.nChannels == 7 && OutputType.dwChannelMask == X6DOT1) || 4.350 - (device->FmtChans == DevFmtX71 && OutputType.Format.nChannels == 8 && OutputType.dwChannelMask == X7DOT1))) 4.351 - { 4.352 - if((device->Flags&DEVICE_CHANNELS_REQUEST)) 4.353 - ERR("Failed to set %s, got %d channels (0x%08lx) instead\n", DevFmtChannelsString(device->FmtChans), OutputType.Format.nChannels, OutputType.dwChannelMask); 4.354 - device->Flags &= ~DEVICE_CHANNELS_REQUEST; 4.355 - 4.356 - if(OutputType.Format.nChannels == 1 && OutputType.dwChannelMask == MONO) 4.357 - device->FmtChans = DevFmtMono; 4.358 - else if(OutputType.Format.nChannels == 2 && OutputType.dwChannelMask == STEREO) 4.359 - device->FmtChans = DevFmtStereo; 4.360 - else if(OutputType.Format.nChannels == 4 && OutputType.dwChannelMask == QUAD) 4.361 - device->FmtChans = DevFmtQuad; 4.362 - else if(OutputType.Format.nChannels == 6 && OutputType.dwChannelMask == X5DOT1) 4.363 - device->FmtChans = DevFmtX51; 4.364 - else if(OutputType.Format.nChannels == 6 && OutputType.dwChannelMask == X5DOT1SIDE) 4.365 - device->FmtChans = DevFmtX51Side; 4.366 - else if(OutputType.Format.nChannels == 7 && OutputType.dwChannelMask == X6DOT1) 4.367 - device->FmtChans = DevFmtX61; 4.368 - else if(OutputType.Format.nChannels == 8 && OutputType.dwChannelMask == X7DOT1) 4.369 - device->FmtChans = DevFmtX71; 4.370 - else 4.371 - { 4.372 - ERR("Unhandled extensible channels: %d -- 0x%08lx\n", OutputType.Format.nChannels, OutputType.dwChannelMask); 4.373 - device->FmtChans = DevFmtStereo; 4.374 - OutputType.Format.nChannels = 2; 4.375 - OutputType.dwChannelMask = STEREO; 4.376 - } 4.377 - } 4.378 - 4.379 - if(IsEqualGUID(&OutputType.SubFormat, &KSDATAFORMAT_SUBTYPE_PCM)) 4.380 - { 4.381 - if(OutputType.Samples.wValidBitsPerSample == 0) 4.382 - OutputType.Samples.wValidBitsPerSample = OutputType.Format.wBitsPerSample; 4.383 - if(OutputType.Samples.wValidBitsPerSample != OutputType.Format.wBitsPerSample || 4.384 - !((device->FmtType == DevFmtUByte && OutputType.Format.wBitsPerSample == 8) || 4.385 - (device->FmtType == DevFmtShort && OutputType.Format.wBitsPerSample == 16))) 4.386 - { 4.387 - ERR("Failed to set %s samples, got %d/%d-bit instead\n", DevFmtTypeString(device->FmtType), OutputType.Samples.wValidBitsPerSample, OutputType.Format.wBitsPerSample); 4.388 - if(OutputType.Format.wBitsPerSample == 8) 4.389 - device->FmtType = DevFmtUByte; 4.390 - else if(OutputType.Format.wBitsPerSample == 16) 4.391 - device->FmtType = DevFmtShort; 4.392 - else 4.393 - { 4.394 - device->FmtType = DevFmtShort; 4.395 - OutputType.Format.wBitsPerSample = 16; 4.396 - } 4.397 - OutputType.Samples.wValidBitsPerSample = OutputType.Format.wBitsPerSample; 4.398 - } 4.399 - } 4.400 - else if(IsEqualGUID(&OutputType.SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)) 4.401 - { 4.402 - if(OutputType.Samples.wValidBitsPerSample == 0) 4.403 - OutputType.Samples.wValidBitsPerSample = OutputType.Format.wBitsPerSample; 4.404 - if(OutputType.Samples.wValidBitsPerSample != OutputType.Format.wBitsPerSample || 4.405 - !((device->FmtType == DevFmtFloat && OutputType.Format.wBitsPerSample == 32))) 4.406 - { 4.407 - ERR("Failed to set %s samples, got %d/%d-bit instead\n", DevFmtTypeString(device->FmtType), OutputType.Samples.wValidBitsPerSample, OutputType.Format.wBitsPerSample); 4.408 - if(OutputType.Format.wBitsPerSample != 32) 4.409 - { 4.410 - device->FmtType = DevFmtFloat; 4.411 - OutputType.Format.wBitsPerSample = 32; 4.412 - } 4.413 - OutputType.Samples.wValidBitsPerSample = OutputType.Format.wBitsPerSample; 4.414 - } 4.415 - } 4.416 - else 4.417 - { 4.418 - ERR("Unhandled format sub-type\n"); 4.419 - device->FmtType = DevFmtShort; 4.420 - OutputType.Format.wBitsPerSample = 16; 4.421 - OutputType.Samples.wValidBitsPerSample = OutputType.Format.wBitsPerSample; 4.422 - OutputType.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; 4.423 - } 4.424 - } 4.425 - 4.426 - SetDefaultWFXChannelOrder(device); 4.427 - 4.428 - hr = IAudioClient_GetDevicePeriod(data->client, &min_per, NULL); 4.429 - if(SUCCEEDED(hr)) 4.430 - { 4.431 - min_len = (min_per*device->Frequency + 10000000-1) / 10000000; 4.432 - if(min_len < device->UpdateSize) 4.433 - min_len *= (device->UpdateSize + min_len/2)/min_len; 4.434 - 4.435 - device->NumUpdates = (device->NumUpdates*device->UpdateSize + min_len/2) / 4.436 - min_len; 4.437 - device->NumUpdates = maxu(device->NumUpdates, 2); 4.438 - device->UpdateSize = min_len; 4.439 - 4.440 - hr = IAudioClient_Initialize(data->client, AUDCLNT_SHAREMODE_SHARED, 4.441 - AUDCLNT_STREAMFLAGS_EVENTCALLBACK, 4.442 - ((REFERENCE_TIME)device->UpdateSize* 4.443 - device->NumUpdates*10000000 + 4.444 - device->Frequency-1) / device->Frequency, 4.445 - 0, &OutputType.Format, NULL); 4.446 - } 4.447 - if(FAILED(hr)) 4.448 - { 4.449 - ERR("Failed to initialize audio client: 0x%08lx\n", hr); 4.450 - return hr; 4.451 - } 4.452 - 4.453 - hr = IAudioClient_GetBufferSize(data->client, &buffer_len); 4.454 - if(FAILED(hr)) 4.455 - { 4.456 - ERR("Failed to get audio buffer info: 0x%08lx\n", hr); 4.457 - return hr; 4.458 - } 4.459 - 4.460 - device->NumUpdates = buffer_len / device->UpdateSize; 4.461 - if(device->NumUpdates <= 1) 4.462 - { 4.463 - device->NumUpdates = 1; 4.464 - ERR("Audio client returned buffer_len < period*2; expect break up\n"); 4.465 - } 4.466 - 4.467 - ResetEvent(data->hNotifyEvent); 4.468 - hr = IAudioClient_SetEventHandle(data->client, data->hNotifyEvent); 4.469 - if(SUCCEEDED(hr)) 4.470 - hr = IAudioClient_Start(data->client); 4.471 - if(FAILED(hr)) 4.472 - { 4.473 - ERR("Failed to start audio client: 0x%08lx\n", hr); 4.474 - return hr; 4.475 - } 4.476 - 4.477 - data->thread = StartThread(MMDevApiProc, device); 4.478 - if(!data->thread) 4.479 - { 4.480 - IAudioClient_Stop(data->client); 4.481 - ERR("Failed to start thread\n"); 4.482 - return E_FAIL; 4.483 - } 4.484 - 4.485 - return hr; 4.486 -} 4.487 - 4.488 - 4.489 -static DWORD CALLBACK MessageProc(void *ptr) 4.490 -{ 4.491 - ThreadRequest *req = ptr; 4.492 - IMMDeviceEnumerator *Enumerator; 4.493 - MMDevApiData *data; 4.494 - ALCdevice *device; 4.495 - HRESULT hr; 4.496 - MSG msg; 4.497 - 4.498 - TRACE("Starting message thread\n"); 4.499 - 4.500 - hr = CoInitialize(NULL); 4.501 - if(FAILED(hr)) 4.502 - { 4.503 - WARN("Failed to initialize COM: 0x%08lx\n", hr); 4.504 - req->result = hr; 4.505 - SetEvent(req->FinishedEvt); 4.506 - return 0; 4.507 - } 4.508 - 4.509 - hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, &ptr); 4.510 - if(FAILED(hr)) 4.511 - { 4.512 - WARN("Failed to create IMMDeviceEnumerator instance: 0x%08lx\n", hr); 4.513 - CoUninitialize(); 4.514 - req->result = hr; 4.515 - SetEvent(req->FinishedEvt); 4.516 - return 0; 4.517 - } 4.518 - Enumerator = ptr; 4.519 - IMMDeviceEnumerator_Release(Enumerator); 4.520 - Enumerator = NULL; 4.521 - 4.522 - req->result = S_OK; 4.523 - SetEvent(req->FinishedEvt); 4.524 - 4.525 - TRACE("Starting message loop\n"); 4.526 - while(GetMessage(&msg, NULL, 0, 0)) 4.527 - { 4.528 - TRACE("Got message %u\n", msg.message); 4.529 - switch(msg.message) 4.530 - { 4.531 - case WM_USER_OpenDevice: 4.532 - req = (ThreadRequest*)msg.wParam; 4.533 - device = (ALCdevice*)msg.lParam; 4.534 - data = device->ExtraData; 4.535 - 4.536 - hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, &ptr); 4.537 - if(SUCCEEDED(hr)) 4.538 - { 4.539 - Enumerator = ptr; 4.540 - hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(Enumerator, eRender, eMultimedia, &data->mmdev); 4.541 - IMMDeviceEnumerator_Release(Enumerator); 4.542 - Enumerator = NULL; 4.543 - } 4.544 - if(SUCCEEDED(hr)) 4.545 - hr = IMMDevice_Activate(data->mmdev, &IID_IAudioClient, CLSCTX_INPROC_SERVER, NULL, &ptr); 4.546 - if(SUCCEEDED(hr)) 4.547 - data->client = ptr; 4.548 - 4.549 - if(FAILED(hr)) 4.550 - { 4.551 - if(data->mmdev) 4.552 - IMMDevice_Release(data->mmdev); 4.553 - data->mmdev = NULL; 4.554 - } 4.555 - 4.556 - req->result = hr; 4.557 - SetEvent(req->FinishedEvt); 4.558 - continue; 4.559 - 4.560 - case WM_USER_ResetDevice: 4.561 - req = (ThreadRequest*)msg.wParam; 4.562 - device = (ALCdevice*)msg.lParam; 4.563 - 4.564 - req->result = DoReset(device); 4.565 - SetEvent(req->FinishedEvt); 4.566 - continue; 4.567 - 4.568 - case WM_USER_StopDevice: 4.569 - req = (ThreadRequest*)msg.wParam; 4.570 - device = (ALCdevice*)msg.lParam; 4.571 - data = device->ExtraData; 4.572 - 4.573 - if(data->thread) 4.574 - { 4.575 - data->killNow = 1; 4.576 - StopThread(data->thread); 4.577 - data->thread = NULL; 4.578 - 4.579 - data->killNow = 0; 4.580 - 4.581 - IAudioClient_Stop(data->client); 4.582 - } 4.583 - 4.584 - req->result = S_OK; 4.585 - SetEvent(req->FinishedEvt); 4.586 - continue; 4.587 - 4.588 - case WM_USER_CloseDevice: 4.589 - req = (ThreadRequest*)msg.wParam; 4.590 - device = (ALCdevice*)msg.lParam; 4.591 - data = device->ExtraData; 4.592 - 4.593 - IAudioClient_Release(data->client); 4.594 - data->client = NULL; 4.595 - 4.596 - IMMDevice_Release(data->mmdev); 4.597 - data->mmdev = NULL; 4.598 - 4.599 - req->result = S_OK; 4.600 - SetEvent(req->FinishedEvt); 4.601 - continue; 4.602 - 4.603 - default: 4.604 - ERR("Unexpected message: %u\n", msg.message); 4.605 - continue; 4.606 - } 4.607 - } 4.608 - TRACE("Message loop finished\n"); 4.609 - 4.610 - CoUninitialize(); 4.611 - return 0; 4.612 -} 4.613 - 4.614 - 4.615 -static BOOL MMDevApiLoad(void) 4.616 -{ 4.617 - static HRESULT InitResult; 4.618 - if(!ThreadHdl) 4.619 - { 4.620 - ThreadRequest req; 4.621 - InitResult = E_FAIL; 4.622 - 4.623 - req.FinishedEvt = CreateEvent(NULL, FALSE, FALSE, NULL); 4.624 - if(req.FinishedEvt == NULL) 4.625 - ERR("Failed to create event: %lu\n", GetLastError()); 4.626 - else 4.627 - { 4.628 - ThreadHdl = CreateThread(NULL, 0, MessageProc, &req, 0, &ThreadID); 4.629 - if(ThreadHdl != NULL) 4.630 - InitResult = WaitForResponse(&req); 4.631 - CloseHandle(req.FinishedEvt); 4.632 - } 4.633 - } 4.634 - return SUCCEEDED(InitResult); 4.635 -} 4.636 - 4.637 - 4.638 -static ALCboolean MMDevApiOpenPlayback(ALCdevice *device, const ALCchar *deviceName) 4.639 -{ 4.640 - MMDevApiData *data = NULL; 4.641 - HRESULT hr; 4.642 - 4.643 - if(!deviceName) 4.644 - deviceName = mmDevice; 4.645 - else if(strcmp(deviceName, mmDevice) != 0) 4.646 - return ALC_FALSE; 4.647 - 4.648 - //Initialise requested device 4.649 - data = calloc(1, sizeof(MMDevApiData)); 4.650 - if(!data) 4.651 - { 4.652 - alcSetError(device, ALC_OUT_OF_MEMORY); 4.653 - return ALC_FALSE; 4.654 - } 4.655 - device->ExtraData = data; 4.656 - 4.657 - hr = S_OK; 4.658 - data->hNotifyEvent = CreateEvent(NULL, FALSE, FALSE, NULL); 4.659 - data->MsgEvent = CreateEvent(NULL, FALSE, FALSE, NULL); 4.660 - if(data->hNotifyEvent == NULL || data->MsgEvent == NULL) 4.661 - hr = E_FAIL; 4.662 - 4.663 - if(SUCCEEDED(hr)) 4.664 - { 4.665 - ThreadRequest req = { data->MsgEvent, 0 }; 4.666 - 4.667 - hr = E_FAIL; 4.668 - if(PostThreadMessage(ThreadID, WM_USER_OpenDevice, (WPARAM)&req, (LPARAM)device)) 4.669 - hr = WaitForResponse(&req); 4.670 - } 4.671 - 4.672 - if(FAILED(hr)) 4.673 - { 4.674 - if(data->hNotifyEvent != NULL) 4.675 - CloseHandle(data->hNotifyEvent); 4.676 - data->hNotifyEvent = NULL; 4.677 - if(data->MsgEvent != NULL) 4.678 - CloseHandle(data->MsgEvent); 4.679 - data->MsgEvent = NULL; 4.680 - 4.681 - free(data); 4.682 - device->ExtraData = NULL; 4.683 - 4.684 - ERR("Device init failed: 0x%08lx\n", hr); 4.685 - return ALC_FALSE; 4.686 - } 4.687 - 4.688 - device->szDeviceName = strdup(deviceName); 4.689 - return ALC_TRUE; 4.690 -} 4.691 - 4.692 -static void MMDevApiClosePlayback(ALCdevice *device) 4.693 -{ 4.694 - MMDevApiData *data = device->ExtraData; 4.695 - ThreadRequest req = { data->MsgEvent, 0 }; 4.696 - 4.697 - if(PostThreadMessage(ThreadID, WM_USER_CloseDevice, (WPARAM)&req, (LPARAM)device)) 4.698 - (void)WaitForResponse(&req); 4.699 - 4.700 - CloseHandle(data->MsgEvent); 4.701 - data->MsgEvent = NULL; 4.702 - 4.703 - CloseHandle(data->hNotifyEvent); 4.704 - data->hNotifyEvent = NULL; 4.705 - 4.706 - free(data); 4.707 - device->ExtraData = NULL; 4.708 -} 4.709 - 4.710 -static ALCboolean MMDevApiResetPlayback(ALCdevice *device) 4.711 -{ 4.712 - MMDevApiData *data = device->ExtraData; 4.713 - ThreadRequest req = { data->MsgEvent, 0 }; 4.714 - HRESULT hr = E_FAIL; 4.715 - 4.716 - if(PostThreadMessage(ThreadID, WM_USER_ResetDevice, (WPARAM)&req, (LPARAM)device)) 4.717 - hr = WaitForResponse(&req); 4.718 - 4.719 - return SUCCEEDED(hr) ? ALC_TRUE : ALC_FALSE; 4.720 -} 4.721 - 4.722 -static void MMDevApiStopPlayback(ALCdevice *device) 4.723 -{ 4.724 - MMDevApiData *data = device->ExtraData; 4.725 - ThreadRequest req = { data->MsgEvent, 0 }; 4.726 - 4.727 - if(PostThreadMessage(ThreadID, WM_USER_StopDevice, (WPARAM)&req, (LPARAM)device)) 4.728 - (void)WaitForResponse(&req); 4.729 -} 4.730 - 4.731 - 4.732 -static const BackendFuncs MMDevApiFuncs = { 4.733 - MMDevApiOpenPlayback, 4.734 - MMDevApiClosePlayback, 4.735 - MMDevApiResetPlayback, 4.736 - MMDevApiStopPlayback, 4.737 - NULL, 4.738 - NULL, 4.739 - NULL, 4.740 - NULL, 4.741 - NULL, 4.742 - NULL 4.743 -}; 4.744 - 4.745 - 4.746 -ALCboolean alcMMDevApiInit(BackendFuncs *FuncList) 4.747 -{ 4.748 - if(!MMDevApiLoad()) 4.749 - return ALC_FALSE; 4.750 - *FuncList = MMDevApiFuncs; 4.751 - return ALC_TRUE; 4.752 -} 4.753 - 4.754 -void alcMMDevApiDeinit(void) 4.755 -{ 4.756 - if(ThreadHdl) 4.757 - { 4.758 - TRACE("Sending WM_QUIT to Thread %04lx\n", ThreadID); 4.759 - PostThreadMessage(ThreadID, WM_QUIT, 0, 0); 4.760 - CloseHandle(ThreadHdl); 4.761 - ThreadHdl = NULL; 4.762 - } 4.763 -} 4.764 - 4.765 -void alcMMDevApiProbe(enum DevProbe type) 4.766 -{ 4.767 - switch(type) 4.768 - { 4.769 - case DEVICE_PROBE: 4.770 - AppendDeviceList(mmDevice); 4.771 - break; 4.772 - case ALL_DEVICE_PROBE: 4.773 - AppendAllDeviceList(mmDevice); 4.774 - break; 4.775 - case CAPTURE_DEVICE_PROBE: 4.776 - break; 4.777 - } 4.778 -}
5.1 --- a/Alc/backends/opensl.c Tue Oct 25 13:03:35 2011 -0700 5.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 5.3 @@ -1,425 +0,0 @@ 5.4 -/* 5.5 - * Copyright (C) 2011 The Android Open Source Project 5.6 - * 5.7 - * Licensed under the Apache License, Version 2.0 (the "License"); 5.8 - * you may not use this file except in compliance with the License. 5.9 - * You may obtain a copy of the License at 5.10 - * 5.11 - * http://www.apache.org/licenses/LICENSE-2.0 5.12 - * 5.13 - * Unless required by applicable law or agreed to in writing, software 5.14 - * distributed under the License is distributed on an "AS IS" BASIS, 5.15 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 5.16 - * See the License for the specific language governing permissions and 5.17 - * limitations under the License. 5.18 - */ 5.19 - 5.20 -/* This is an OpenAL backend for Android using the native audio APIs based on 5.21 - * OpenSL ES 1.0.1. It is based on source code for the native-audio sample app 5.22 - * bundled with NDK. 5.23 - */ 5.24 - 5.25 -#include "config.h" 5.26 - 5.27 -#include <stdlib.h> 5.28 -#include "alMain.h" 5.29 -#include "AL/al.h" 5.30 -#include "AL/alc.h" 5.31 - 5.32 - 5.33 -#include <SLES/OpenSLES.h> 5.34 -#if 1 5.35 -#include <SLES/OpenSLES_Android.h> 5.36 -#else 5.37 -extern SLAPIENTRY const SLInterfaceID SL_IID_ANDROIDSIMPLEBUFFERQUEUE; 5.38 - 5.39 -struct SLAndroidSimpleBufferQueueItf_; 5.40 -typedef const struct SLAndroidSimpleBufferQueueItf_ * const * SLAndroidSimpleBufferQueueItf; 5.41 - 5.42 -typedef void (*slAndroidSimpleBufferQueueCallback)(SLAndroidSimpleBufferQueueItf caller, void *pContext); 5.43 - 5.44 -typedef struct SLAndroidSimpleBufferQueueState_ { 5.45 - SLuint32 count; 5.46 - SLuint32 index; 5.47 -} SLAndroidSimpleBufferQueueState; 5.48 - 5.49 - 5.50 -struct SLAndroidSimpleBufferQueueItf_ { 5.51 - SLresult (*Enqueue) ( 5.52 - SLAndroidSimpleBufferQueueItf self, 5.53 - const void *pBuffer, 5.54 - SLuint32 size 5.55 - ); 5.56 - SLresult (*Clear) ( 5.57 - SLAndroidSimpleBufferQueueItf self 5.58 - ); 5.59 - SLresult (*GetState) ( 5.60 - SLAndroidSimpleBufferQueueItf self, 5.61 - SLAndroidSimpleBufferQueueState *pState 5.62 - ); 5.63 - SLresult (*RegisterCallback) ( 5.64 - SLAndroidSimpleBufferQueueItf self, 5.65 - slAndroidSimpleBufferQueueCallback callback, 5.66 - void* pContext 5.67 - ); 5.68 -}; 5.69 - 5.70 -#define SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE ((SLuint32) 0x800007BD) 5.71 - 5.72 -typedef struct SLDataLocator_AndroidSimpleBufferQueue { 5.73 - SLuint32 locatorType; 5.74 - SLuint32 numBuffers; 5.75 -} SLDataLocator_AndroidSimpleBufferQueue; 5.76 - 5.77 -#endif 5.78 - 5.79 -/* Helper macros */ 5.80 -#define SLObjectItf_Realize(a,b) ((*(a))->Realize((a),(b))) 5.81 -#define SLObjectItf_GetInterface(a,b,c) ((*(a))->GetInterface((a),(b),(c))) 5.82 -#define SLObjectItf_Destroy(a) ((*(a))->Destroy((a))) 5.83 - 5.84 -#define SLEngineItf_CreateOutputMix(a,b,c,d,e) ((*(a))->CreateOutputMix((a),(b),(c),(d),(e))) 5.85 -#define SLEngineItf_CreateAudioPlayer(a,b,c,d,e,f,g) ((*(a))->CreateAudioPlayer((a),(b),(c),(d),(e),(f),(g))) 5.86 - 5.87 -#define SLPlayItf_SetPlayState(a,b) ((*(a))->SetPlayState((a),(b))) 5.88 - 5.89 - 5.90 -typedef struct { 5.91 - /* engine interfaces */ 5.92 - SLObjectItf engineObject; 5.93 - SLEngineItf engine; 5.94 - 5.95 - /* output mix interfaces */ 5.96 - SLObjectItf outputMix; 5.97 - 5.98 - /* buffer queue player interfaces */ 5.99 - SLObjectItf bufferQueueObject; 5.100 - 5.101 - void *buffer; 5.102 - ALuint bufferSize; 5.103 - 5.104 - ALuint frameSize; 5.105 -} osl_data; 5.106 - 5.107 - 5.108 -static const ALCchar opensl_device[] = "OpenSL"; 5.109 - 5.110 - 5.111 -static SLuint32 GetChannelMask(enum DevFmtChannels chans) 5.112 -{ 5.113 - switch(chans) 5.114 - { 5.115 - case DevFmtMono: return SL_SPEAKER_FRONT_CENTER; 5.116 - case DevFmtStereo: return SL_SPEAKER_FRONT_LEFT|SL_SPEAKER_FRONT_RIGHT; 5.117 - case DevFmtQuad: return SL_SPEAKER_FRONT_LEFT|SL_SPEAKER_FRONT_RIGHT| 5.118 - SL_SPEAKER_BACK_LEFT|SL_SPEAKER_BACK_RIGHT; 5.119 - case DevFmtX51: return SL_SPEAKER_FRONT_LEFT|SL_SPEAKER_FRONT_RIGHT| 5.120 - SL_SPEAKER_FRONT_CENTER|SL_SPEAKER_LOW_FREQUENCY| 5.121 - SL_SPEAKER_BACK_LEFT|SL_SPEAKER_BACK_RIGHT; 5.122 - case DevFmtX61: return SL_SPEAKER_FRONT_LEFT|SL_SPEAKER_FRONT_RIGHT| 5.123 - SL_SPEAKER_FRONT_CENTER|SL_SPEAKER_LOW_FREQUENCY| 5.124 - SL_SPEAKER_BACK_CENTER| 5.125 - SL_SPEAKER_SIDE_LEFT|SL_SPEAKER_SIDE_RIGHT; 5.126 - case DevFmtX71: return SL_SPEAKER_FRONT_LEFT|SL_SPEAKER_FRONT_RIGHT| 5.127 - SL_SPEAKER_FRONT_CENTER|SL_SPEAKER_LOW_FREQUENCY| 5.128 - SL_SPEAKER_BACK_LEFT|SL_SPEAKER_BACK_RIGHT| 5.129 - SL_SPEAKER_SIDE_LEFT|SL_SPEAKER_SIDE_RIGHT; 5.130 - case DevFmtX51Side: return SL_SPEAKER_FRONT_LEFT|SL_SPEAKER_FRONT_RIGHT| 5.131 - SL_SPEAKER_FRONT_CENTER|SL_SPEAKER_LOW_FREQUENCY| 5.132 - SL_SPEAKER_SIDE_LEFT|SL_SPEAKER_SIDE_RIGHT; 5.133 - } 5.134 - return 0; 5.135 -} 5.136 - 5.137 -static const char *res_str(SLresult result) 5.138 -{ 5.139 - switch(result) 5.140 - { 5.141 - case SL_RESULT_SUCCESS: return "Success"; 5.142 - case SL_RESULT_PRECONDITIONS_VIOLATED: return "Preconditions violated"; 5.143 - case SL_RESULT_PARAMETER_INVALID: return "Parameter invalid"; 5.144 - case SL_RESULT_MEMORY_FAILURE: return "Memory failure"; 5.145 - case SL_RESULT_RESOURCE_ERROR: return "Resource error"; 5.146 - case SL_RESULT_RESOURCE_LOST: return "Resource lost"; 5.147 - case SL_RESULT_IO_ERROR: return "I/O error"; 5.148 - case SL_RESULT_BUFFER_INSUFFICIENT: return "Buffer insufficient"; 5.149 - case SL_RESULT_CONTENT_CORRUPTED: return "Content corrupted"; 5.150 - case SL_RESULT_CONTENT_UNSUPPORTED: return "Content unsupported"; 5.151 - case SL_RESULT_CONTENT_NOT_FOUND: return "Content not found"; 5.152 - case SL_RESULT_PERMISSION_DENIED: return "Permission denied"; 5.153 - case SL_RESULT_FEATURE_UNSUPPORTED: return "Feature unsupported"; 5.154 - case SL_RESULT_INTERNAL_ERROR: return "Internal error"; 5.155 - case SL_RESULT_UNKNOWN_ERROR: return "Unknown error"; 5.156 - case SL_RESULT_OPERATION_ABORTED: return "Operation aborted"; 5.157 - case SL_RESULT_CONTROL_LOST: return "Control lost"; 5.158 - case SL_RESULT_READONLY: return "ReadOnly"; 5.159 - case SL_RESULT_ENGINEOPTION_UNSUPPORTED: return "Engine option unsupported"; 5.160 - case SL_RESULT_SOURCE_SINK_INCOMPATIBLE: return "Source/Sink incompatible"; 5.161 - } 5.162 - return "Unknown error code"; 5.163 -} 5.164 - 5.165 -#define PRINTERR(x, s) do { \ 5.166 - if((x) != SL_RESULT_SUCCESS) \ 5.167 - ERR("%s: %s\n", (s), res_str((x))); \ 5.168 -} while(0) 5.169 - 5.170 -/* this callback handler is called every time a buffer finishes playing */ 5.171 -static void opensl_callback(SLAndroidSimpleBufferQueueItf bq, void *context) 5.172 -{ 5.173 - ALCdevice *Device = context; 5.174 - osl_data *data = Device->ExtraData; 5.175 - SLresult result; 5.176 - 5.177 - aluMixData(Device, data->buffer, data->bufferSize/data->frameSize); 5.178 - 5.179 - result = (*bq)->Enqueue(bq, data->buffer, data->bufferSize); 5.180 - PRINTERR(result, "bq->Enqueue"); 5.181 -} 5.182 - 5.183 - 5.184 -static ALCboolean opensl_open_playback(ALCdevice *Device, const ALCchar *deviceName) 5.185 -{ 5.186 - osl_data *data = NULL; 5.187 - SLresult result; 5.188 - 5.189 - if(!deviceName) 5.190 - deviceName = opensl_device; 5.191 - else if(strcmp(deviceName, opensl_device) != 0) 5.192 - return ALC_FALSE; 5.193 - 5.194 - data = calloc(1, sizeof(*data)); 5.195 - if(!data) 5.196 - { 5.197 - alcSetError(Device, ALC_OUT_OF_MEMORY); 5.198 - return ALC_FALSE; 5.199 - } 5.200 - 5.201 - // create engine 5.202 - result = slCreateEngine(&data->engineObject, 0, NULL, 0, NULL, NULL); 5.203 - PRINTERR(result, "slCreateEngine"); 5.204 - if(SL_RESULT_SUCCESS == result) 5.205 - { 5.206 - result = SLObjectItf_Realize(data->engineObject, SL_BOOLEAN_FALSE); 5.207 - PRINTERR(result, "engine->Realize"); 5.208 - } 5.209 - if(SL_RESULT_SUCCESS == result) 5.210 - { 5.211 - result = SLObjectItf_GetInterface(data->engineObject, SL_IID_ENGINE, &data->engine); 5.212 - PRINTERR(result, "engine->GetInterface"); 5.213 - } 5.214 - if(SL_RESULT_SUCCESS == result) 5.215 - { 5.216 - result = SLEngineItf_CreateOutputMix(data->engine, &data->outputMix, 0, NULL, NULL); 5.217 - PRINTERR(result, "engine->CreateOutputMix"); 5.218 - } 5.219 - if(SL_RESULT_SUCCESS == result) 5.220 - { 5.221 - result = SLObjectItf_Realize(data->outputMix, SL_BOOLEAN_FALSE); 5.222 - PRINTERR(result, "outputMix->Realize"); 5.223 - } 5.224 - 5.225 - if(SL_RESULT_SUCCESS != result) 5.226 - { 5.227 - if(data->outputMix != NULL) 5.228 - SLObjectItf_Destroy(data->outputMix); 5.229 - data->outputMix = NULL; 5.230 - 5.231 - if(data->engineObject != NULL) 5.232 - SLObjectItf_Destroy(data->engineObject); 5.233 - data->engineObject = NULL; 5.234 - data->engine = NULL; 5.235 - 5.236 - free(data); 5.237 - return ALC_FALSE; 5.238 - } 5.239 - 5.240 - Device->szDeviceName = strdup(deviceName); 5.241 - Device->ExtraData = data; 5.242 - 5.243 - return ALC_TRUE; 5.244 -} 5.245 - 5.246 - 5.247 -static void opensl_close_playback(ALCdevice *Device) 5.248 -{ 5.249 - osl_data *data = Device->ExtraData; 5.250 - 5.251 - SLObjectItf_Destroy(data->outputMix); 5.252 - data->outputMix = NULL; 5.253 - 5.254 - SLObjectItf_Destroy(data->engineObject); 5.255 - data->engineObject = NULL; 5.256 - data->engine = NULL; 5.257 - 5.258 - free(data); 5.259 - Device->ExtraData = NULL; 5.260 -} 5.261 - 5.262 -static ALCboolean opensl_reset_playback(ALCdevice *Device) 5.263 -{ 5.264 - osl_data *data = Device->ExtraData; 5.265 - SLDataLocator_AndroidSimpleBufferQueue loc_bufq; 5.266 - SLAndroidSimpleBufferQueueItf bufferQueue; 5.267 - SLDataLocator_OutputMix loc_outmix; 5.268 - SLDataFormat_PCM format_pcm; 5.269 - SLDataSource audioSrc; 5.270 - SLDataSink audioSnk; 5.271 - SLPlayItf player; 5.272 - SLInterfaceID id; 5.273 - SLboolean req; 5.274 - SLresult result; 5.275 - ALuint i; 5.276 - 5.277 - 5.278 - Device->UpdateSize = (ALuint64)Device->UpdateSize * 44100 / Device->Frequency; 5.279 - Device->UpdateSize = Device->UpdateSize * Device->NumUpdates / 2; 5.280 - Device->NumUpdates = 2; 5.281 - 5.282 - Device->Frequency = 44100; 5.283 - Device->FmtChans = DevFmtStereo; 5.284 - Device->FmtType = DevFmtShort; 5.285 - 5.286 - SetDefaultWFXChannelOrder(Device); 5.287 - 5.288 - 5.289 - id = SL_IID_ANDROIDSIMPLEBUFFERQUEUE; 5.290 - req = SL_BOOLEAN_TRUE; 5.291 - 5.292 - loc_bufq.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE; 5.293 - loc_bufq.numBuffers = Device->NumUpdates; 5.294 - 5.295 - format_pcm.formatType = SL_DATAFORMAT_PCM; 5.296 - format_pcm.numChannels = ChannelsFromDevFmt(Device->FmtChans); 5.297 - format_pcm.samplesPerSec = Device->Frequency * 1000; 5.298 - format_pcm.bitsPerSample = BytesFromDevFmt(Device->FmtType) * 8; 5.299 - format_pcm.containerSize = format_pcm.bitsPerSample; 5.300 - format_pcm.channelMask = GetChannelMask(Device->FmtChans); 5.301 - format_pcm.endianness = SL_BYTEORDER_NATIVE; 5.302 - 5.303 - audioSrc.pLocator = &loc_bufq; 5.304 - audioSrc.pFormat = &format_pcm; 5.305 - 5.306 - loc_outmix.locatorType = SL_DATALOCATOR_OUTPUTMIX; 5.307 - loc_outmix.outputMix = data->outputMix; 5.308 - audioSnk.pLocator = &loc_outmix; 5.309 - audioSnk.pFormat = NULL; 5.310 - 5.311 - 5.312 - result = SLEngineItf_CreateAudioPlayer(data->engine, &data->bufferQueueObject, &audioSrc, &audioSnk, 1, &id, &req); 5.313 - PRINTERR(result, "engine->CreateAudioPlayer"); 5.314 - if(SL_RESULT_SUCCESS == result) 5.315 - { 5.316 - result = SLObjectItf_Realize(data->bufferQueueObject, SL_BOOLEAN_FALSE); 5.317 - PRINTERR(result, "bufferQueue->Realize"); 5.318 - } 5.319 - if(SL_RESULT_SUCCESS == result) 5.320 - { 5.321 - result = SLObjectItf_GetInterface(data->bufferQueueObject, SL_IID_BUFFERQUEUE, &bufferQueue); 5.322 - PRINTERR(result, "bufferQueue->GetInterface"); 5.323 - } 5.324 - if(SL_RESULT_SUCCESS == result) 5.325 - { 5.326 - result = (*bufferQueue)->RegisterCallback(bufferQueue, opensl_callback, Device); 5.327 - PRINTERR(result, "bufferQueue->RegisterCallback"); 5.328 - } 5.329 - if(SL_RESULT_SUCCESS == result) 5.330 - { 5.331 - data->frameSize = FrameSizeFromDevFmt(Device->FmtChans, Device->FmtType); 5.332 - data->bufferSize = Device->UpdateSize * data->frameSize; 5.333 - data->buffer = calloc(1, data->bufferSize); 5.334 - if(!data->buffer) 5.335 - { 5.336 - result = SL_RESULT_MEMORY_FAILURE; 5.337 - PRINTERR(result, "calloc"); 5.338 - } 5.339 - } 5.340 - /* enqueue the first buffer to kick off the callbacks */ 5.341 - for(i = 0;i < Device->NumUpdates;i++) 5.342 - { 5.343 - if(SL_RESULT_SUCCESS == result) 5.344 - { 5.345 - result = (*bufferQueue)->Enqueue(bufferQueue, data->buffer, data->bufferSize); 5.346 - PRINTERR(result, "bufferQueue->Enqueue"); 5.347 - } 5.348 - } 5.349 - if(SL_RESULT_SUCCESS == result) 5.350 - { 5.351 - result = SLObjectItf_GetInterface(data->bufferQueueObject, SL_IID_PLAY, &player); 5.352 - PRINTERR(result, "bufferQueue->GetInterface"); 5.353 - } 5.354 - if(SL_RESULT_SUCCESS == result) 5.355 - { 5.356 - result = SLPlayItf_SetPlayState(player, SL_PLAYSTATE_PLAYING); 5.357 - PRINTERR(result, "player->SetPlayState"); 5.358 - } 5.359 - 5.360 - if(SL_RESULT_SUCCESS != result) 5.361 - { 5.362 - if(data->bufferQueueObject != NULL) 5.363 - SLObjectItf_Destroy(data->bufferQueueObject); 5.364 - data->bufferQueueObject = NULL; 5.365 - 5.366 - free(data->buffer); 5.367 - data->buffer = NULL; 5.368 - data->bufferSize = 0; 5.369 - 5.370 - return ALC_FALSE; 5.371 - } 5.372 - 5.373 - return ALC_TRUE; 5.374 -} 5.375 - 5.376 - 5.377 -static void opensl_stop_playback(ALCdevice *Device) 5.378 -{ 5.379 - osl_data *data = Device->ExtraData; 5.380 - 5.381 - if(data->bufferQueueObject != NULL) 5.382 - SLObjectItf_Destroy(data->bufferQueueObject); 5.383 - data->bufferQueueObject = NULL; 5.384 - 5.385 - free(data->buffer); 5.386 - data->buffer = NULL; 5.387 - data->bufferSize = 0; 5.388 -} 5.389 - 5.390 - 5.391 -static const BackendFuncs opensl_funcs = { 5.392 - opensl_open_playback, 5.393 - opensl_close_playback, 5.394 - opensl_reset_playback, 5.395 - opensl_stop_playback, 5.396 - NULL, 5.397 - NULL, 5.398 - NULL, 5.399 - NULL, 5.400 - NULL, 5.401 - NULL 5.402 -}; 5.403 - 5.404 - 5.405 -ALCboolean alc_opensl_init(BackendFuncs *func_list) 5.406 -{ 5.407 - *func_list = opensl_funcs; 5.408 - return ALC_TRUE; 5.409 -} 5.410 - 5.411 -void alc_opensl_deinit(void) 5.412 -{ 5.413 -} 5.414 - 5.415 -void alc_opensl_probe(enum DevProbe type) 5.416 -{ 5.417 - switch(type) 5.418 - { 5.419 - case DEVICE_PROBE: 5.420 - AppendDeviceList(opensl_device); 5.421 - break; 5.422 - case ALL_DEVICE_PROBE: 5.423 - AppendAllDeviceList(opensl_device); 5.424 - break; 5.425 - case CAPTURE_DEVICE_PROBE: 5.426 - break; 5.427 - } 5.428 -}
6.1 --- a/Alc/backends/oss.c Tue Oct 25 13:03:35 2011 -0700 6.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 6.3 @@ -1,536 +0,0 @@ 6.4 -/** 6.5 - * OpenAL cross platform audio library 6.6 - * Copyright (C) 1999-2007 by authors. 6.7 - * This library is free software; you can redistribute it and/or 6.8 - * modify it under the terms of the GNU Library General Public 6.9 - * License as published by the Free Software Foundation; either 6.10 - * version 2 of the License, or (at your option) any later version. 6.11 - * 6.12 - * This library is distributed in the hope that it will be useful, 6.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 6.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 6.15 - * Library General Public License for more details. 6.16 - * 6.17 - * You should have received a copy of the GNU Library General Public 6.18 - * License along with this library; if not, write to the 6.19 - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 6.20 - * Boston, MA 02111-1307, USA. 6.21 - * Or go to http://www.gnu.org/copyleft/lgpl.html 6.22 - */ 6.23 - 6.24 -#include "config.h" 6.25 - 6.26 -#include <sys/ioctl.h> 6.27 -#include <sys/types.h> 6.28 -#include <sys/stat.h> 6.29 -#include <fcntl.h> 6.30 -#include <stdlib.h> 6.31 -#include <stdio.h> 6.32 -#include <memory.h> 6.33 -#include <unistd.h> 6.34 -#include <errno.h> 6.35 -#include <math.h> 6.36 -#include "alMain.h" 6.37 -#include "AL/al.h" 6.38 -#include "AL/alc.h" 6.39 - 6.40 -#include <sys/soundcard.h> 6.41 - 6.42 -/* 6.43 - * The OSS documentation talks about SOUND_MIXER_READ, but the header 6.44 - * only contains MIXER_READ. Play safe. Same for WRITE. 6.45 - */ 6.46 -#ifndef SOUND_MIXER_READ 6.47 -#define SOUND_MIXER_READ MIXER_READ 6.48 -#endif 6.49 -#ifndef SOUND_MIXER_WRITE 6.50 -#define SOUND_MIXER_WRITE MIXER_WRITE 6.51 -#endif 6.52 - 6.53 -static const ALCchar oss_device[] = "OSS Default"; 6.54 - 6.55 -typedef struct { 6.56 - int fd; 6.57 - volatile int killNow; 6.58 - ALvoid *thread; 6.59 - 6.60 - ALubyte *mix_data; 6.61 - int data_size; 6.62 - 6.63 - RingBuffer *ring; 6.64 - int doCapture; 6.65 -} oss_data; 6.66 - 6.67 - 6.68 -static int log2i(ALCuint x) 6.69 -{ 6.70 - int y = 0; 6.71 - while (x > 1) 6.72 - { 6.73 - x >>= 1; 6.74 - y++; 6.75 - } 6.76 - return y; 6.77 -} 6.78 - 6.79 - 6.80 -static ALuint OSSProc(ALvoid *ptr) 6.81 -{ 6.82 - ALCdevice *pDevice = (ALCdevice*)ptr; 6.83 - oss_data *data = (oss_data*)pDevice->ExtraData; 6.84 - ALint frameSize; 6.85 - ssize_t wrote; 6.86 - 6.87 - SetRTPriority(); 6.88 - 6.89 - frameSize = FrameSizeFromDevFmt(pDevice->FmtChans, pDevice->FmtType); 6.90 - 6.91 - while(!data->killNow && pDevice->Connected) 6.92 - { 6.93 - ALint len = data->data_size; 6.94 - ALubyte *WritePtr = data->mix_data; 6.95 - 6.96 - aluMixData(pDevice, WritePtr, len/frameSize); 6.97 - while(len > 0 && !data->killNow) 6.98 - { 6.99 - wrote = write(data->fd, WritePtr, len); 6.100 - if(wrote < 0) 6.101 - { 6.102 - if(errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR) 6.103 - { 6.104 - ERR("write failed: %s\n", strerror(errno)); 6.105 - aluHandleDisconnect(pDevice); 6.106 - break; 6.107 - } 6.108 - 6.109 - Sleep(1); 6.110 - continue; 6.111 - } 6.112 - 6.113 - len -= wrote; 6.114 - WritePtr += wrote; 6.115 - } 6.116 - } 6.117 - 6.118 - return 0; 6.119 -} 6.120 - 6.121 -static ALuint OSSCaptureProc(ALvoid *ptr) 6.122 -{ 6.123 - ALCdevice *pDevice = (ALCdevice*)ptr; 6.124 - oss_data *data = (oss_data*)pDevice->ExtraData; 6.125 - int frameSize; 6.126 - int amt; 6.127 - 6.128 - SetRTPriority(); 6.129 - 6.130 - frameSize = FrameSizeFromDevFmt(pDevice->FmtChans, pDevice->FmtType); 6.131 - 6.132 - while(!data->killNow) 6.133 - { 6.134 - amt = read(data->fd, data->mix_data, data->data_size); 6.135 - if(amt < 0) 6.136 - { 6.137 - ERR("read failed: %s\n", strerror(errno)); 6.138 - aluHandleDisconnect(pDevice); 6.139 - break; 6.140 - } 6.141 - if(amt == 0) 6.142 - { 6.143 - Sleep(1); 6.144 - continue; 6.145 - } 6.146 - if(data->doCapture) 6.147 - WriteRingBuffer(data->ring, data->mix_data, amt/frameSize); 6.148 - } 6.149 - 6.150 - return 0; 6.151 -} 6.152 - 6.153 -static ALCboolean oss_open_playback(ALCdevice *device, const ALCchar *deviceName) 6.154 -{ 6.155 - char driver[64]; 6.156 - oss_data *data; 6.157 - 6.158 - strncpy(driver, GetConfigValue("oss", "device", "/dev/dsp"), sizeof(driver)-1); 6.159 - driver[sizeof(driver)-1] = 0; 6.160 - if(!deviceName) 6.161 - deviceName = oss_device; 6.162 - else if(strcmp(deviceName, oss_device) != 0) 6.163 - return ALC_FALSE; 6.164 - 6.165 - data = (oss_data*)calloc(1, sizeof(oss_data)); 6.166 - data->killNow = 0; 6.167 - 6.168 - data->fd = open(driver, O_WRONLY); 6.169 - if(data->fd == -1) 6.170 - { 6.171 - free(data); 6.172 - ERR("Could not open %s: %s\n", driver, strerror(errno)); 6.173 - return ALC_FALSE; 6.174 - } 6.175 - 6.176 - device->szDeviceName = strdup(deviceName); 6.177 - device->ExtraData = data; 6.178 - return ALC_TRUE; 6.179 -} 6.180 - 6.181 -static void oss_close_playback(ALCdevice *device) 6.182 -{ 6.183 - oss_data *data = (oss_data*)device->ExtraData; 6.184 - 6.185 - close(data->fd); 6.186 - free(data); 6.187 - device->ExtraData = NULL; 6.188 -} 6.189 - 6.190 -static ALCboolean oss_reset_playback(ALCdevice *device) 6.191 -{ 6.192 - oss_data *data = (oss_data*)device->ExtraData; 6.193 - int numFragmentsLogSize; 6.194 - int log2FragmentSize; 6.195 - unsigned int periods; 6.196 - audio_buf_info info; 6.197 - ALuint frameSize; 6.198 - int numChannels; 6.199 - int ossFormat; 6.200 - int ossSpeed; 6.201 - char *err; 6.202 - 6.203 - switch(device->FmtType) 6.204 - { 6.205 - case DevFmtByte: 6.206 - ossFormat = AFMT_S8; 6.207 - break; 6.208 - case DevFmtUByte: 6.209 - ossFormat = AFMT_U8; 6.210 - break; 6.211 - case DevFmtUShort: 6.212 - case DevFmtFloat: 6.213 - device->FmtType = DevFmtShort; 6.214 - /* fall-through */ 6.215 - case DevFmtShort: 6.216 - ossFormat = AFMT_S16_NE; 6.217 - break; 6.218 - } 6.219 - 6.220 - periods = device->NumUpdates; 6.221 - numChannels = ChannelsFromDevFmt(device->FmtChans); 6.222 - frameSize = numChannels * BytesFromDevFmt(device->FmtType); 6.223 - 6.224 - ossSpeed = device->Frequency; 6.225 - log2FragmentSize = log2i(device->UpdateSize * frameSize); 6.226 - 6.227 - /* according to the OSS spec, 16 bytes are the minimum */ 6.228 - if (log2FragmentSize < 4) 6.229 - log2FragmentSize = 4; 6.230 - /* Subtract one period since the temp mixing buffer counts as one. Still 6.231 - * need at least two on the card, though. */ 6.232 - if(periods > 2) periods--; 6.233 - numFragmentsLogSize = (periods << 16) | log2FragmentSize; 6.234 - 6.235 -#define CHECKERR(func) if((func) < 0) { \ 6.236 - err = #func; \ 6.237 - goto err; \ 6.238 -} 6.239 - /* Don't fail if SETFRAGMENT fails. We can handle just about anything 6.240 - * that's reported back via GETOSPACE */ 6.241 - ioctl(data->fd, SNDCTL_DSP_SETFRAGMENT, &numFragmentsLogSize); 6.242 - CHECKERR(ioctl(data->fd, SNDCTL_DSP_SETFMT, &ossFormat)); 6.243 - CHECKERR(ioctl(data->fd, SNDCTL_DSP_CHANNELS, &numChannels)); 6.244 - CHECKERR(ioctl(data->fd, SNDCTL_DSP_SPEED, &ossSpeed)); 6.245 - CHECKERR(ioctl(data->fd, SNDCTL_DSP_GETOSPACE, &info)); 6.246 - if(0) 6.247 - { 6.248 - err: 6.249 - ERR("%s failed: %s\n", err, strerror(errno)); 6.250 - return ALC_FALSE; 6.251 - } 6.252 -#undef CHECKERR 6.253 - 6.254 - if((int)ChannelsFromDevFmt(device->FmtChans) != numChannels) 6.255 - { 6.256 - ERR("Failed to set %s, got %d channels instead\n", DevFmtChannelsString(device->FmtChans), numChannels); 6.257 - return ALC_FALSE; 6.258 - } 6.259 - 6.260 - if(!((ossFormat == AFMT_S8 && device->FmtType == DevFmtByte) || 6.261 - (ossFormat == AFMT_U8 && device->FmtType == DevFmtUByte) || 6.262 - (ossFormat == AFMT_S16_NE && device->FmtType == DevFmtShort))) 6.263 - { 6.264 - ERR("Failed to set %s samples, got OSS format %#x\n", DevFmtTypeString(device->FmtType), ossFormat); 6.265 - return ALC_FALSE; 6.266 - } 6.267 - 6.268 - if(device->Frequency != (ALuint)ossSpeed) 6.269 - { 6.270 - if((device->Flags&DEVICE_FREQUENCY_REQUEST)) 6.271 - ERR("Failed to set %dhz, got %dhz instead\n", device->Frequency, ossSpeed); 6.272 - device->Flags &= ~DEVICE_FREQUENCY_REQUEST; 6.273 - device->Frequency = ossSpeed; 6.274 - } 6.275 - device->UpdateSize = info.fragsize / frameSize; 6.276 - device->NumUpdates = info.fragments + 1; 6.277 - 6.278 - data->data_size = device->UpdateSize * frameSize; 6.279 - data->mix_data = calloc(1, data->data_size); 6.280 - 6.281 - SetDefaultChannelOrder(device); 6.282 - 6.283 - data->thread = StartThread(OSSProc, device); 6.284 - if(data->thread == NULL) 6.285 - { 6.286 - free(data->mix_data); 6.287 - data->mix_data = NULL; 6.288 - return ALC_FALSE; 6.289 - } 6.290 - 6.291 - return ALC_TRUE; 6.292 -} 6.293 - 6.294 -static void oss_stop_playback(ALCdevice *device) 6.295 -{ 6.296 - oss_data *data = (oss_data*)device->ExtraData; 6.297 - 6.298 - if(!data->thread) 6.299 - return; 6.300 - 6.301 - data->killNow = 1; 6.302 - StopThread(data->thread); 6.303 - data->thread = NULL; 6.304 - 6.305 - data->killNow = 0; 6.306 - if(ioctl(data->fd, SNDCTL_DSP_RESET) != 0) 6.307 - ERR("Error resetting device: %s\n", strerror(errno)); 6.308 - 6.309 - free(data->mix_data); 6.310 - data->mix_data = NULL; 6.311 -} 6.312 - 6.313 - 6.314 -static ALCboolean oss_open_capture(ALCdevice *device, const ALCchar *deviceName) 6.315 -{ 6.316 - int numFragmentsLogSize; 6.317 - int log2FragmentSize; 6.318 - unsigned int periods; 6.319 - audio_buf_info info; 6.320 - ALuint frameSize; 6.321 - int numChannels; 6.322 - char driver[64]; 6.323 - oss_data *data; 6.324 - int ossFormat; 6.325 - int ossSpeed; 6.326 - char *err; 6.327 - 6.328 - strncpy(driver, GetConfigValue("oss", "capture", "/dev/dsp"), sizeof(driver)-1); 6.329 - driver[sizeof(driver)-1] = 0; 6.330 - if(!deviceName) 6.331 - deviceName = oss_device; 6.332 - else if(strcmp(deviceName, oss_device) != 0) 6.333 - return ALC_FALSE; 6.334 - 6.335 - data = (oss_data*)calloc(1, sizeof(oss_data)); 6.336 - data->killNow = 0; 6.337 - 6.338 - data->fd = open(driver, O_RDONLY); 6.339 - if(data->fd == -1) 6.340 - { 6.341 - free(data); 6.342 - ERR("Could not open %s: %s\n", driver, strerror(errno)); 6.343 - return ALC_FALSE; 6.344 - } 6.345 - 6.346 - switch(device->FmtType) 6.347 - { 6.348 - case DevFmtByte: 6.349 - ossFormat = AFMT_S8; 6.350 - break; 6.351 - case DevFmtUByte: 6.352 - ossFormat = AFMT_U8; 6.353 - break; 6.354 - case DevFmtShort: 6.355 - ossFormat = AFMT_S16_NE; 6.356 - break; 6.357 - case DevFmtUShort: 6.358 - case DevFmtFloat: 6.359 - free(data); 6.360 - ERR("%s capture samples not supported on OSS\n", DevFmtTypeString(device->FmtType)); 6.361 - return ALC_FALSE; 6.362 - } 6.363 - 6.364 - periods = 4; 6.365 - numChannels = ChannelsFromDevFmt(device->FmtChans); 6.366 - frameSize = numChannels * BytesFromDevFmt(device->FmtType); 6.367 - ossSpeed = device->Frequency; 6.368 - log2FragmentSize = log2i(device->UpdateSize * device->NumUpdates * 6.369 - frameSize / periods); 6.370 - 6.371 - /* according to the OSS spec, 16 bytes are the minimum */ 6.372 - if (log2FragmentSize < 4) 6.373 - log2FragmentSize = 4; 6.374 - numFragmentsLogSize = (periods << 16) | log2FragmentSize; 6.375 - 6.376 -#define CHECKERR(func) if((func) < 0) { \ 6.377 - err = #func; \ 6.378 - goto err; \ 6.379 -} 6.380 - CHECKERR(ioctl(data->fd, SNDCTL_DSP_SETFRAGMENT, &numFragmentsLogSize)); 6.381 - CHECKERR(ioctl(data->fd, SNDCTL_DSP_SETFMT, &ossFormat)); 6.382 - CHECKERR(ioctl(data->fd, SNDCTL_DSP_CHANNELS, &numChannels)); 6.383 - CHECKERR(ioctl(data->fd, SNDCTL_DSP_SPEED, &ossSpeed)); 6.384 - CHECKERR(ioctl(data->fd, SNDCTL_DSP_GETISPACE, &info)); 6.385 - if(0) 6.386 - { 6.387 - err: 6.388 - ERR("%s failed: %s\n", err, strerror(errno)); 6.389 - close(data->fd); 6.390 - free(data); 6.391 - return ALC_FALSE; 6.392 - } 6.393 -#undef CHECKERR 6.394 - 6.395 - if((int)ChannelsFromDevFmt(device->FmtChans) != numChannels) 6.396 - { 6.397 - ERR("Failed to set %s, got %d channels instead\n", DevFmtChannelsString(device->FmtChans), numChannels); 6.398 - close(data->fd); 6.399 - free(data); 6.400 - return ALC_FALSE; 6.401 - } 6.402 - 6.403 - if(!((ossFormat == AFMT_S8 && device->FmtType == DevFmtByte) || 6.404 - (ossFormat == AFMT_U8 && device->FmtType == DevFmtUByte) || 6.405 - (ossFormat == AFMT_S16_NE && device->FmtType == DevFmtShort))) 6.406 - { 6.407 - ERR("Failed to set %s samples, got OSS format %#x\n", DevFmtTypeString(device->FmtType), ossFormat); 6.408 - close(data->fd); 6.409 - free(data); 6.410 - return ALC_FALSE; 6.411 - } 6.412 - 6.413 - data->ring = CreateRingBuffer(frameSize, device->UpdateSize * device->NumUpdates); 6.414 - if(!data->ring) 6.415 - { 6.416 - ERR("Ring buffer create failed\n"); 6.417 - close(data->fd); 6.418 - free(data); 6.419 - return ALC_FALSE; 6.420 - } 6.421 - 6.422 - data->data_size = info.fragsize; 6.423 - data->mix_data = calloc(1, data->data_size); 6.424 - 6.425 - device->ExtraData = data; 6.426 - data->thread = StartThread(OSSCaptureProc, device); 6.427 - if(data->thread == NULL) 6.428 - { 6.429 - device->ExtraData = NULL; 6.430 - free(data->mix_data); 6.431 - free(data); 6.432 - return ALC_FALSE; 6.433 - } 6.434 - 6.435 - device->szDeviceName = strdup(deviceName); 6.436 - return ALC_TRUE; 6.437 -} 6.438 - 6.439 -static void oss_close_capture(ALCdevice *device) 6.440 -{ 6.441 - oss_data *data = (oss_data*)device->ExtraData; 6.442 - data->killNow = 1; 6.443 - StopThread(data->thread); 6.444 - 6.445 - close(data->fd); 6.446 - 6.447 - DestroyRingBuffer(data->ring); 6.448 - 6.449 - free(data->mix_data); 6.450 - free(data); 6.451 - device->ExtraData = NULL; 6.452 -} 6.453 - 6.454 -static void oss_start_capture(ALCdevice *pDevice) 6.455 -{ 6.456 - oss_data *data = (oss_data*)pDevice->ExtraData; 6.457 - data->doCapture = 1; 6.458 -} 6.459 - 6.460 -static void oss_stop_capture(ALCdevice *pDevice) 6.461 -{ 6.462 - oss_data *data = (oss_data*)pDevice->ExtraData; 6.463 - data->doCapture = 0; 6.464 -} 6.465 - 6.466 -static void oss_capture_samples(ALCdevice *pDevice, ALCvoid *pBuffer, ALCuint lSamples) 6.467 -{ 6.468 - oss_data *data = (oss_data*)pDevice->ExtraData; 6.469 - if(lSamples <= (ALCuint)RingBufferSize(data->ring)) 6.470 - ReadRingBuffer(data->ring, pBuffer, lSamples); 6.471 - else 6.472 - alcSetError(pDevice, ALC_INVALID_VALUE); 6.473 -} 6.474 - 6.475 -static ALCuint oss_available_samples(ALCdevice *pDevice) 6.476 -{ 6.477 - oss_data *data = (oss_data*)pDevice->ExtraData; 6.478 - return RingBufferSize(data->ring); 6.479 -} 6.480 - 6.481 - 6.482 -static const BackendFuncs oss_funcs = { 6.483 - oss_open_playback, 6.484 - oss_close_playback, 6.485 - oss_reset_playback, 6.486 - oss_stop_playback, 6.487 - oss_open_capture, 6.488 - oss_close_capture, 6.489 - oss_start_capture, 6.490 - oss_stop_capture, 6.491 - oss_capture_samples, 6.492 - oss_available_samples 6.493 -}; 6.494 - 6.495 -ALCboolean alc_oss_init(BackendFuncs *func_list) 6.496 -{ 6.497 - *func_list = oss_funcs; 6.498 - return ALC_TRUE; 6.499 -} 6.500 - 6.501 -void alc_oss_deinit(void) 6.502 -{ 6.503 -} 6.504 - 6.505 -void alc_oss_probe(enum DevProbe type) 6.506 -{ 6.507 - switch(type) 6.508 - { 6.509 - case DEVICE_PROBE: 6.510 - { 6.511 -#ifdef HAVE_STAT 6.512 - struct stat buf; 6.513 - if(stat(GetConfigValue("oss", "device", "/dev/dsp"), &buf) == 0) 6.514 -#endif 6.515 - AppendDeviceList(oss_device); 6.516 - } 6.517 - break; 6.518 - 6.519 - case ALL_DEVICE_PROBE: 6.520 - { 6.521 -#ifdef HAVE_STAT 6.522 - struct stat buf; 6.523 - if(stat(GetConfigValue("oss", "device", "/dev/dsp"), &buf) == 0) 6.524 -#endif 6.525 - AppendAllDeviceList(oss_device); 6.526 - } 6.527 - break; 6.528 - 6.529 - case CAPTURE_DEVICE_PROBE: 6.530 - { 6.531 -#ifdef HAVE_STAT 6.532 - struct stat buf; 6.533 - if(stat(GetConfigValue("oss", "capture", "/dev/dsp"), &buf) == 0) 6.534 -#endif 6.535 - AppendCaptureDeviceList(oss_device); 6.536 - } 6.537 - break; 6.538 - } 6.539 -}
7.1 --- a/Alc/backends/portaudio.c Tue Oct 25 13:03:35 2011 -0700 7.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 7.3 @@ -1,449 +0,0 @@ 7.4 -/** 7.5 - * OpenAL cross platform audio library 7.6 - * Copyright (C) 1999-2007 by authors. 7.7 - * This library is free software; you can redistribute it and/or 7.8 - * modify it under the terms of the GNU Library General Public 7.9 - * License as published by the Free Software Foundation; either 7.10 - * version 2 of the License, or (at your option) any later version. 7.11 - * 7.12 - * This library is distributed in the hope that it will be useful, 7.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 7.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 7.15 - * Library General Public License for more details. 7.16 - * 7.17 - * You should have received a copy of the GNU Library General Public 7.18 - * License along with this library; if not, write to the 7.19 - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 7.20 - * Boston, MA 02111-1307, USA. 7.21 - * Or go to http://www.gnu.org/copyleft/lgpl.html 7.22 - */ 7.23 - 7.24 -#include "config.h" 7.25 - 7.26 -#include <stdio.h> 7.27 -#include <stdlib.h> 7.28 -#include <string.h> 7.29 -#include "alMain.h" 7.30 -#include "AL/al.h" 7.31 -#include "AL/alc.h" 7.32 - 7.33 -#include <portaudio.h> 7.34 - 7.35 - 7.36 -static const ALCchar pa_device[] = "PortAudio Default"; 7.37 - 7.38 - 7.39 -static void *pa_handle; 7.40 -#ifdef HAVE_DYNLOAD 7.41 -#define MAKE_FUNC(x) static typeof(x) * p##x 7.42 -MAKE_FUNC(Pa_Initialize); 7.43 -MAKE_FUNC(Pa_Terminate); 7.44 -MAKE_FUNC(Pa_GetErrorText); 7.45 -MAKE_FUNC(Pa_StartStream); 7.46 -MAKE_FUNC(Pa_StopStream); 7.47 -MAKE_FUNC(Pa_OpenStream); 7.48 -MAKE_FUNC(Pa_CloseStream); 7.49 -MAKE_FUNC(Pa_GetDefaultOutputDevice); 7.50 -MAKE_FUNC(Pa_GetStreamInfo); 7.51 -#undef MAKE_FUNC 7.52 - 7.53 -#define Pa_Initialize pPa_Initialize 7.54 -#define Pa_Terminate pPa_Terminate 7.55 -#define Pa_GetErrorText pPa_GetErrorText 7.56 -#define Pa_StartStream pPa_StartStream 7.57 -#define Pa_StopStream pPa_StopStream 7.58 -#define Pa_OpenStream pPa_OpenStream 7.59 -#define Pa_CloseStream pPa_CloseStream 7.60 -#define Pa_GetDefaultOutputDevice pPa_GetDefaultOutputDevice 7.61 -#define Pa_GetStreamInfo pPa_GetStreamInfo 7.62 -#endif 7.63 - 7.64 -static ALCboolean pa_load(void) 7.65 -{ 7.66 - if(!pa_handle) 7.67 - { 7.68 - PaError err; 7.69 - 7.70 -#ifdef HAVE_DYNLOAD 7.71 -#ifdef _WIN32 7.72 -# define PALIB "portaudio.dll" 7.73 -#elif defined(__APPLE__) && defined(__MACH__) 7.74 -# define PALIB "libportaudio.2.dylib" 7.75 -#elif defined(__OpenBSD__) 7.76 -# define PALIB "libportaudio.so" 7.77 -#else 7.78 -# define PALIB "libportaudio.so.2" 7.79 -#endif 7.80 - 7.81 - pa_handle = LoadLib(PALIB); 7.82 - if(!pa_handle) 7.83 - return ALC_FALSE; 7.84 - 7.85 -#define LOAD_FUNC(f) do { \ 7.86 - p##f = GetSymbol(pa_handle, #f); \ 7.87 - if(p##f == NULL) \ 7.88 - { \ 7.89 - CloseLib(pa_handle); \ 7.90 - pa_handle = NULL; \ 7.91 - return ALC_FALSE; \ 7.92 - } \ 7.93 -} while(0) 7.94 - LOAD_FUNC(Pa_Initialize); 7.95 - LOAD_FUNC(Pa_Terminate); 7.96 - LOAD_FUNC(Pa_GetErrorText); 7.97 - LOAD_FUNC(Pa_StartStream); 7.98 - LOAD_FUNC(Pa_StopStream); 7.99 - LOAD_FUNC(Pa_OpenStream); 7.100 - LOAD_FUNC(Pa_CloseStream); 7.101 - LOAD_FUNC(Pa_GetDefaultOutputDevice); 7.102 - LOAD_FUNC(Pa_GetStreamInfo); 7.103 -#undef LOAD_FUNC 7.104 -#else 7.105 - pa_handle = (void*)0xDEADBEEF; 7.106 -#endif 7.107 - 7.108 - if((err=Pa_Initialize()) != paNoError) 7.109 - { 7.110 - ERR("Pa_Initialize() returned an error: %s\n", Pa_GetErrorText(err)); 7.111 - CloseLib(pa_handle); 7.112 - pa_handle = NULL; 7.113 - return ALC_FALSE; 7.114 - } 7.115 - } 7.116 - return ALC_TRUE; 7.117 -} 7.118 - 7.119 - 7.120 -typedef struct { 7.121 - PaStream *stream; 7.122 - ALuint update_size; 7.123 - 7.124 - RingBuffer *ring; 7.125 -} pa_data; 7.126 - 7.127 - 7.128 -static int pa_callback(const void *inputBuffer, void *outputBuffer, 7.129 - unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo, 7.130 - const PaStreamCallbackFlags statusFlags, void *userData) 7.131 -{ 7.132 - ALCdevice *device = (ALCdevice*)userData; 7.133 - 7.134 - (void)inputBuffer; 7.135 - (void)timeInfo; 7.136 - (void)statusFlags; 7.137 - 7.138 - aluMixData(device, outputBuffer, framesPerBuffer); 7.139 - return 0; 7.140 -} 7.141 - 7.142 -static int pa_capture_cb(const void *inputBuffer, void *outputBuffer, 7.143 - unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo, 7.144 - const PaStreamCallbackFlags statusFlags, void *userData) 7.145 -{ 7.146 - ALCdevice *device = (ALCdevice*)userData; 7.147 - pa_data *data = (pa_data*)device->ExtraData; 7.148 - 7.149 - (void)outputBuffer; 7.150 - (void)timeInfo; 7.151 - (void)statusFlags; 7.152 - 7.153 - WriteRingBuffer(data->ring, inputBuffer, framesPerBuffer); 7.154 - return 0; 7.155 -} 7.156 - 7.157 - 7.158 -static ALCboolean pa_open_playback(ALCdevice *device, const ALCchar *deviceName) 7.159 -{ 7.160 - PaStreamParameters outParams; 7.161 - pa_data *data; 7.162 - PaError err; 7.163 - 7.164 - if(!deviceName) 7.165 - deviceName = pa_device; 7.166 - else if(strcmp(deviceName, pa_device) != 0) 7.167 - return ALC_FALSE; 7.168 - 7.169 - data = (pa_data*)calloc(1, sizeof(pa_data)); 7.170 - data->update_size = device->UpdateSize; 7.171 - 7.172 - device->ExtraData = data; 7.173 - 7.174 - outParams.device = GetConfigValueInt("port", "device", -1); 7.175 - if(outParams.device < 0) 7.176 - outParams.device = Pa_GetDefaultOutputDevice(); 7.177 - outParams.suggestedLatency = (device->UpdateSize*device->NumUpdates) / 7.178 - (float)device->Frequency; 7.179 - outParams.hostApiSpecificStreamInfo = NULL; 7.180 - 7.181 - switch(device->FmtType) 7.182 - { 7.183 - case DevFmtByte: 7.184 - outParams.sampleFormat = paInt8; 7.185 - break; 7.186 - case DevFmtUByte: 7.187 - outParams.sampleFormat = paUInt8; 7.188 - break; 7.189 - case DevFmtUShort: 7.190 - device->FmtType = DevFmtShort; 7.191 - /* fall-through */ 7.192 - case DevFmtShort: 7.193 - outParams.sampleFormat = paInt16; 7.194 - break; 7.195 - case DevFmtFloat: 7.196 - outParams.sampleFormat = paFloat32; 7.197 - break; 7.198 - } 7.199 - outParams.channelCount = ((device->FmtChans == DevFmtMono) ? 1 : 2); 7.200 - 7.201 - SetDefaultChannelOrder(device); 7.202 - 7.203 - err = Pa_OpenStream(&data->stream, NULL, &outParams, device->Frequency, 7.204 - device->UpdateSize, paNoFlag, pa_callback, device); 7.205 - if(err != paNoError) 7.206 - { 7.207 - ERR("Pa_OpenStream() returned an error: %s\n", Pa_GetErrorText(err)); 7.208 - device->ExtraData = NULL; 7.209 - free(data); 7.210 - return ALC_FALSE; 7.211 - } 7.212 - 7.213 - device->szDeviceName = strdup(deviceName); 7.214 - 7.215 - if((ALuint)outParams.channelCount != ChannelsFromDevFmt(device->FmtChans)) 7.216 - { 7.217 - if(outParams.channelCount != 1 && outParams.channelCount != 2) 7.218 - { 7.219 - ERR("Unhandled channel count: %u\n", outParams.channelCount); 7.220 - Pa_CloseStream(data->stream); 7.221 - device->ExtraData = NULL; 7.222 - free(data); 7.223 - return ALC_FALSE; 7.224 - } 7.225 - if((device->Flags&DEVICE_CHANNELS_REQUEST)) 7.226 - ERR("Failed to set %s, got %u channels instead\n", DevFmtChannelsString(device->FmtChans), outParams.channelCount); 7.227 - device->Flags &= ~DEVICE_CHANNELS_REQUEST; 7.228 - device->FmtChans = ((outParams.channelCount==1) ? DevFmtMono : DevFmtStereo); 7.229 - } 7.230 - 7.231 - return ALC_TRUE; 7.232 -} 7.233 - 7.234 -static void pa_close_playback(ALCdevice *device) 7.235 -{ 7.236 - pa_data *data = (pa_data*)device->ExtraData; 7.237 - PaError err; 7.238 - 7.239 - err = Pa_CloseStream(data->stream); 7.240 - if(err != paNoError) 7.241 - ERR("Error closing stream: %s\n", Pa_GetErrorText(err)); 7.242 - 7.243 - free(data); 7.244 - device->ExtraData = NULL; 7.245 -} 7.246 - 7.247 -static ALCboolean pa_reset_playback(ALCdevice *device) 7.248 -{ 7.249 - pa_data *data = (pa_data*)device->ExtraData; 7.250 - const PaStreamInfo *streamInfo; 7.251 - PaError err; 7.252 - 7.253 - streamInfo = Pa_GetStreamInfo(data->stream); 7.254 - if(device->Frequency != streamInfo->sampleRate) 7.255 - { 7.256 - if((device->Flags&DEVICE_FREQUENCY_REQUEST)) 7.257 - ERR("PortAudio does not support changing sample rates (wanted %dhz, got %.1fhz)\n", device->Frequency, streamInfo->sampleRate); 7.258 - device->Flags &= ~DEVICE_FREQUENCY_REQUEST; 7.259 - device->Frequency = streamInfo->sampleRate; 7.260 - } 7.261 - device->UpdateSize = data->update_size; 7.262 - 7.263 - err = Pa_StartStream(data->stream); 7.264 - if(err != paNoError) 7.265 - { 7.266 - ERR("Pa_StartStream() returned an error: %s\n", Pa_GetErrorText(err)); 7.267 - return ALC_FALSE; 7.268 - } 7.269 - 7.270 - return ALC_TRUE; 7.271 -} 7.272 - 7.273 -static void pa_stop_playback(ALCdevice *device) 7.274 -{ 7.275 - pa_data *data = (pa_data*)device->ExtraData; 7.276 - PaError err; 7.277 - 7.278 - err = Pa_StopStream(data->stream); 7.279 - if(err != paNoError) 7.280 - ERR("Error stopping stream: %s\n", Pa_GetErrorText(err)); 7.281 -} 7.282 - 7.283 - 7.284 -static ALCboolean pa_open_capture(ALCdevice *device, const ALCchar *deviceName) 7.285 -{ 7.286 - PaStreamParameters inParams; 7.287 - ALuint frame_size; 7.288 - pa_data *data; 7.289 - PaError err; 7.290 - 7.291 - if(!deviceName) 7.292 - deviceName = pa_device; 7.293 - else if(strcmp(deviceName, pa_device) != 0) 7.294 - return ALC_FALSE; 7.295 - 7.296 - data = (pa_data*)calloc(1, sizeof(pa_data)); 7.297 - if(data == NULL) 7.298 - { 7.299 - alcSetError(device, ALC_OUT_OF_MEMORY); 7.300 - return ALC_FALSE; 7.301 - } 7.302 - 7.303 - frame_size = FrameSizeFromDevFmt(device->FmtChans, device->FmtType); 7.304 - data->ring = CreateRingBuffer(frame_size, device->UpdateSize*device->NumUpdates); 7.305 - if(data->ring == NULL) 7.306 - { 7.307 - alcSetError(device, ALC_OUT_OF_MEMORY); 7.308 - goto error; 7.309 - } 7.310 - 7.311 - inParams.device = GetConfigValueInt("port", "capture", -1); 7.312 - if(inParams.device < 0) 7.313 - inParams.device = Pa_GetDefaultOutputDevice(); 7.314 - inParams.suggestedLatency = 0.0f; 7.315 - inParams.hostApiSpecificStreamInfo = NULL; 7.316 - 7.317 - switch(device->FmtType) 7.318 - { 7.319 - case DevFmtByte: 7.320 - inParams.sampleFormat = paInt8; 7.321 - break; 7.322 - case DevFmtUByte: 7.323 - inParams.sampleFormat = paUInt8; 7.324 - break; 7.325 - case DevFmtShort: 7.326 - inParams.sampleFormat = paInt16; 7.327 - break; 7.328 - case DevFmtFloat: 7.329 - inParams.sampleFormat = paFloat32; 7.330 - break; 7.331 - case DevFmtUShort: 7.332 - ERR("Unsigned short samples not supported\n"); 7.333 - goto error; 7.334 - } 7.335 - inParams.channelCount = ChannelsFromDevFmt(device->FmtChans); 7.336 - 7.337 - err = Pa_OpenStream(&data->stream, &inParams, NULL, device->Frequency, 7.338 - paFramesPerBufferUnspecified, paNoFlag, pa_capture_cb, device); 7.339 - if(err != paNoError) 7.340 - { 7.341 - ERR("Pa_OpenStream() returned an error: %s\n", Pa_GetErrorText(err)); 7.342 - goto error; 7.343 - } 7.344 - 7.345 - device->szDeviceName = strdup(deviceName); 7.346 - 7.347 - device->ExtraData = data; 7.348 - return ALC_TRUE; 7.349 - 7.350 -error: 7.351 - DestroyRingBuffer(data->ring); 7.352 - free(data); 7.353 - return ALC_FALSE; 7.354 -} 7.355 - 7.356 -static void pa_close_capture(ALCdevice *device) 7.357 -{ 7.358 - pa_data *data = (pa_data*)device->ExtraData; 7.359 - PaError err; 7.360 - 7.361 - err = Pa_CloseStream(data->stream); 7.362 - if(err != paNoError) 7.363 - ERR("Error closing stream: %s\n", Pa_GetErrorText(err)); 7.364 - 7.365 - free(data); 7.366 - device->ExtraData = NULL; 7.367 -} 7.368 - 7.369 -static void pa_start_capture(ALCdevice *device) 7.370 -{ 7.371 - pa_data *data = device->ExtraData; 7.372 - PaError err; 7.373 - 7.374 - err = Pa_StartStream(data->stream); 7.375 - if(err != paNoError) 7.376 - ERR("Error starting stream: %s\n", Pa_GetErrorText(err)); 7.377 -} 7.378 - 7.379 -static void pa_stop_capture(ALCdevice *device) 7.380 -{ 7.381 - pa_data *data = (pa_data*)device->ExtraData; 7.382 - PaError err; 7.383 - 7.384 - err = Pa_StopStream(data->stream); 7.385 - if(err != paNoError) 7.386 - ERR("Error stopping stream: %s\n", Pa_GetErrorText(err)); 7.387 -} 7.388 - 7.389 -static void pa_capture_samples(ALCdevice *device, ALCvoid *buffer, ALCuint samples) 7.390 -{ 7.391 - pa_data *data = device->ExtraData; 7.392 - if(samples <= (ALCuint)RingBufferSize(data->ring)) 7.393 - ReadRingBuffer(data->ring, buffer, samples); 7.394 - else 7.395 - alcSetError(device, ALC_INVALID_VALUE); 7.396 -} 7.397 - 7.398 -static ALCuint pa_available_samples(ALCdevice *device) 7.399 -{ 7.400 - pa_data *data = device->ExtraData; 7.401 - return RingBufferSize(data->ring); 7.402 -} 7.403 - 7.404 - 7.405 -static const BackendFuncs pa_funcs = { 7.406 - pa_open_playback, 7.407 - pa_close_playback, 7.408 - pa_reset_playback, 7.409 - pa_stop_playback, 7.410 - pa_open_capture, 7.411 - pa_close_capture, 7.412 - pa_start_capture, 7.413 - pa_stop_capture, 7.414 - pa_capture_samples, 7.415 - pa_available_samples 7.416 -}; 7.417 - 7.418 -ALCboolean alc_pa_init(BackendFuncs *func_list) 7.419 -{ 7.420 - if(!pa_load()) 7.421 - return ALC_FALSE; 7.422 - *func_list = pa_funcs; 7.423 - return ALC_TRUE; 7.424 -} 7.425 - 7.426 -void alc_pa_deinit(void) 7.427 -{ 7.428 - if(pa_handle) 7.429 - { 7.430 - Pa_Terminate(); 7.431 -#ifdef HAVE_DYNLOAD 7.432 - CloseLib(pa_handle); 7.433 -#endif 7.434 - pa_handle = NULL; 7.435 - } 7.436 -} 7.437 - 7.438 -void alc_pa_probe(enum DevProbe type) 7.439 -{ 7.440 - switch(type) 7.441 - { 7.442 - case DEVICE_PROBE: 7.443 - AppendDeviceList(pa_device); 7.444 - break; 7.445 - case ALL_DEVICE_PROBE: 7.446 - AppendAllDeviceList(pa_device); 7.447 - break; 7.448 - case CAPTURE_DEVICE_PROBE: 7.449 - AppendCaptureDeviceList(pa_device); 7.450 - break; 7.451 - } 7.452 -}
8.1 --- a/Alc/backends/pulseaudio.c Tue Oct 25 13:03:35 2011 -0700 8.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 8.3 @@ -1,1418 +0,0 @@ 8.4 -/** 8.5 - * OpenAL cross platform audio library 8.6 - * Copyright (C) 2009 by Konstantinos Natsakis <konstantinos.natsakis@gmail.com> 8.7 - * Copyright (C) 2010 by Chris Robinson <chris.kcat@gmail.com> 8.8 - * This library is free software; you can redistribute it and/or 8.9 - * modify it under the terms of the GNU Library General Public 8.10 - * License as published by the Free Software Foundation; either 8.11 - * version 2 of the License, or (at your option) any later version. 8.12 - * 8.13 - * This library is distributed in the hope that it will be useful, 8.14 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 8.15 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 8.16 - * Library General Public License for more details. 8.17 - * 8.18 - * You should have received a copy of the GNU Library General Public 8.19 - * License along with this library; if not, write to the 8.20 - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 8.21 - * Boston, MA 02111-1307, USA. 8.22 - * Or go to http://www.gnu.org/copyleft/lgpl.html 8.23 - */ 8.24 - 8.25 -#include "config.h" 8.26 - 8.27 -#include "alMain.h" 8.28 - 8.29 -#include <pulse/pulseaudio.h> 8.30 - 8.31 -#if PA_API_VERSION == 11 8.32 -#define PA_STREAM_ADJUST_LATENCY 0x2000U 8.33 -#define PA_STREAM_EARLY_REQUESTS 0x4000U 8.34 -static __inline int PA_STREAM_IS_GOOD(pa_stream_state_t x) 8.35 -{ 8.36 - return (x == PA_STREAM_CREATING || x == PA_STREAM_READY); 8.37 -} 8.38 -static __inline int PA_CONTEXT_IS_GOOD(pa_context_state_t x) 8.39 -{ 8.40 - return (x == PA_CONTEXT_CONNECTING || x == PA_CONTEXT_AUTHORIZING || 8.41 - x == PA_CONTEXT_SETTING_NAME || x == PA_CONTEXT_READY); 8.42 -} 8.43 -#define PA_STREAM_IS_GOOD PA_STREAM_IS_GOOD 8.44 -#define PA_CONTEXT_IS_GOOD PA_CONTEXT_IS_GOOD 8.45 -#elif PA_API_VERSION != 12 8.46 -#error Invalid PulseAudio API version 8.47 -#endif 8.48 - 8.49 -#ifndef PA_CHECK_VERSION 8.50 -#define PA_CHECK_VERSION(major,minor,micro) \ 8.51 - ((PA_MAJOR > (major)) || \ 8.52 - (PA_MAJOR == (major) && PA_MINOR > (minor)) || \ 8.53 - (PA_MAJOR == (major) && PA_MINOR == (minor) && PA_MICRO >= (micro))) 8.54 -#endif 8.55 - 8.56 -static void *pa_handle; 8.57 -#ifdef HAVE_DYNLOAD 8.58 -#define MAKE_FUNC(x) static typeof(x) * p##x 8.59 -MAKE_FUNC(pa_context_unref); 8.60 -MAKE_FUNC(pa_sample_spec_valid); 8.61 -MAKE_FUNC(pa_stream_drop); 8.62 -MAKE_FUNC(pa_strerror); 8.63 -MAKE_FUNC(pa_context_get_state); 8.64 -MAKE_FUNC(pa_stream_get_state); 8.65 -MAKE_FUNC(pa_threaded_mainloop_signal); 8.66 -MAKE_FUNC(pa_stream_peek); 8.67 -MAKE_FUNC(pa_threaded_mainloop_wait); 8.68 -MAKE_FUNC(pa_threaded_mainloop_unlock); 8.69 -MAKE_FUNC(pa_threaded_mainloop_in_thread); 8.70 -MAKE_FUNC(pa_context_new); 8.71 -MAKE_FUNC(pa_threaded_mainloop_stop); 8.72 -MAKE_FUNC(pa_context_disconnect); 8.73 -MAKE_FUNC(pa_threaded_mainloop_start); 8.74 -MAKE_FUNC(pa_threaded_mainloop_get_api); 8.75 -MAKE_FUNC(pa_context_set_state_callback); 8.76 -MAKE_FUNC(pa_stream_write); 8.77 -MAKE_FUNC(pa_xfree); 8.78 -MAKE_FUNC(pa_stream_connect_record); 8.79 -MAKE_FUNC(pa_stream_connect_playback); 8.80 -MAKE_FUNC(pa_stream_readable_size); 8.81 -MAKE_FUNC(pa_stream_writable_size); 8.82 -MAKE_FUNC(pa_stream_cork); 8.83 -MAKE_FUNC(pa_stream_is_suspended); 8.84 -MAKE_FUNC(pa_stream_get_device_name); 8.85 -MAKE_FUNC(pa_path_get_filename); 8.86 -MAKE_FUNC(pa_get_binary_name); 8.87 -MAKE_FUNC(pa_threaded_mainloop_free); 8.88 -MAKE_FUNC(pa_context_errno); 8.89 -MAKE_FUNC(pa_xmalloc); 8.90 -MAKE_FUNC(pa_stream_unref); 8.91 -MAKE_FUNC(pa_threaded_mainloop_accept); 8.92 -MAKE_FUNC(pa_stream_set_write_callback); 8.93 -MAKE_FUNC(pa_threaded_mainloop_new); 8.94 -MAKE_FUNC(pa_context_connect); 8.95 -MAKE_FUNC(pa_stream_set_buffer_attr); 8.96 -MAKE_FUNC(pa_stream_get_buffer_attr); 8.97 -MAKE_FUNC(pa_stream_get_sample_spec); 8.98 -MAKE_FUNC(pa_stream_get_time); 8.99 -MAKE_FUNC(pa_stream_set_read_callback); 8.100 -MAKE_FUNC(pa_stream_set_state_callback); 8.101 -MAKE_FUNC(pa_stream_set_moved_callback); 8.102 -MAKE_FUNC(pa_stream_set_underflow_callback); 8.103 -MAKE_FUNC(pa_stream_new); 8.104 -MAKE_FUNC(pa_stream_disconnect); 8.105 -MAKE_FUNC(pa_threaded_mainloop_lock); 8.106 -MAKE_FUNC(pa_channel_map_init_auto); 8.107 -MAKE_FUNC(pa_channel_map_parse); 8.108 -MAKE_FUNC(pa_channel_map_snprint); 8.109 -MAKE_FUNC(pa_channel_map_equal); 8.110 -MAKE_FUNC(pa_context_get_server_info); 8.111 -MAKE_FUNC(pa_context_get_sink_info_by_name); 8.112 -MAKE_FUNC(pa_context_get_sink_info_list); 8.113 -MAKE_FUNC(pa_context_get_source_info_list); 8.114 -MAKE_FUNC(pa_operation_get_state); 8.115 -MAKE_FUNC(pa_operation_unref); 8.116 -#if PA_CHECK_VERSION(0,9,15) 8.117 -MAKE_FUNC(pa_channel_map_superset); 8.118 -MAKE_FUNC(pa_stream_set_buffer_attr_callback); 8.119 -#endif 8.120 -#if PA_CHECK_VERSION(0,9,16) 8.121 -MAKE_FUNC(pa_stream_begin_write); 8.122 -#endif 8.123 -#undef MAKE_FUNC 8.124 - 8.125 -#define pa_context_unref ppa_context_unref 8.126 -#define pa_sample_spec_valid ppa_sample_spec_valid 8.127 -#define pa_stream_drop ppa_stream_drop 8.128 -#define pa_strerror ppa_strerror 8.129 -#define pa_context_get_state ppa_context_get_state 8.130 -#define pa_stream_get_state ppa_stream_get_state 8.131 -#define pa_threaded_mainloop_signal ppa_threaded_mainloop_signal 8.132 -#define pa_stream_peek ppa_stream_peek 8.133 -#define pa_threaded_mainloop_wait ppa_threaded_mainloop_wait 8.134 -#define pa_threaded_mainloop_unlock ppa_threaded_mainloop_unlock 8.135 -#define pa_threaded_mainloop_in_thread ppa_threaded_mainloop_in_thread 8.136 -#define pa_context_new ppa_context_new 8.137 -#define pa_threaded_mainloop_stop ppa_threaded_mainloop_stop 8.138 -#define pa_context_disconnect ppa_context_disconnect 8.139 -#define pa_threaded_mainloop_start ppa_threaded_mainloop_start 8.140 -#define pa_threaded_mainloop_get_api ppa_threaded_mainloop_get_api 8.141 -#define pa_context_set_state_callback ppa_context_set_state_callback 8.142 -#define pa_stream_write ppa_stream_write 8.143 -#define pa_xfree ppa_xfree 8.144 -#define pa_stream_connect_record ppa_stream_connect_record 8.145 -#define pa_stream_connect_playback ppa_stream_connect_playback 8.146 -#define pa_stream_readable_size ppa_stream_readable_size 8.147 -#define pa_stream_writable_size ppa_stream_writable_size 8.148 -#define pa_stream_cork ppa_stream_cork 8.149 -#define pa_stream_is_suspended ppa_stream_is_suspended 8.150 -#define pa_stream_get_device_name ppa_stream_get_device_name 8.151 -#define pa_path_get_filename ppa_path_get_filename 8.152 -#define pa_get_binary_name ppa_get_binary_name 8.153 -#define pa_threaded_mainloop_free ppa_threaded_mainloop_free 8.154 -#define pa_context_errno ppa_context_errno 8.155 -#define pa_xmalloc ppa_xmalloc 8.156 -#define pa_stream_unref ppa_stream_unref 8.157 -#define pa_threaded_mainloop_accept ppa_threaded_mainloop_accept 8.158 -#define pa_stream_set_write_callback ppa_stream_set_write_callback 8.159 -#define pa_threaded_mainloop_new ppa_threaded_mainloop_new 8.160 -#define pa_context_connect ppa_context_connect 8.161 -#define pa_stream_set_buffer_attr ppa_stream_set_buffer_attr 8.162 -#define pa_stream_get_buffer_attr ppa_stream_get_buffer_attr 8.163 -#define pa_stream_get_sample_spec ppa_stream_get_sample_spec 8.164 -#define pa_stream_get_time ppa_stream_get_time 8.165 -#define pa_stream_set_read_callback ppa_stream_set_read_callback 8.166 -#define pa_stream_set_state_callback ppa_stream_set_state_callback 8.167 -#define pa_stream_set_moved_callback ppa_stream_set_moved_callback 8.168 -#define pa_stream_set_underflow_callback ppa_stream_set_underflow_callback 8.169 -#define pa_stream_new ppa_stream_new 8.170 -#define pa_stream_disconnect ppa_stream_disconnect 8.171 -#define pa_threaded_mainloop_lock ppa_threaded_mainloop_lock 8.172 -#define pa_channel_map_init_auto ppa_channel_map_init_auto 8.173 -#define pa_channel_map_parse ppa_channel_map_parse 8.174 -#define pa_channel_map_snprint ppa_channel_map_snprint 8.175 -#define pa_channel_map_equal ppa_channel_map_equal 8.176 -#define pa_context_get_server_info ppa_context_get_server_info 8.177 -#define pa_context_get_sink_info_by_name ppa_context_get_sink_info_by_name 8.178 -#define pa_context_get_sink_info_list ppa_context_get_sink_info_list 8.179 -#define pa_context_get_source_info_list ppa_context_get_source_info_list 8.180 -#define pa_operation_get_state ppa_operation_get_state 8.181 -#define pa_operation_unref ppa_operation_unref 8.182 -#if PA_CHECK_VERSION(0,9,15) 8.183 -#define pa_channel_map_superset ppa_channel_map_superset 8.184 -#define pa_stream_set_buffer_attr_callback ppa_stream_set_buffer_attr_callback 8.185 -#endif 8.186 -#if PA_CHECK_VERSION(0,9,16) 8.187 -#define pa_stream_begin_write ppa_stream_begin_write 8.188 -#endif 8.189 - 8.190 -#endif 8.191 - 8.192 -#ifndef PATH_MAX 8.193 -#define PATH_MAX 4096 8.194 -#endif 8.195 - 8.196 -typedef struct { 8.197 - char *device_name; 8.198 - 8.199 - ALCuint samples; 8.200 - ALCuint frame_size; 8.201 - 8.202 - RingBuffer *ring; 8.203 - 8.204 - pa_buffer_attr attr; 8.205 - pa_sample_spec spec; 8.206 - 8.207 - pa_threaded_mainloop *loop; 8.208 - 8.209 - ALvoid *thread; 8.210 - volatile ALboolean killNow; 8.211 - 8.212 - pa_stream *stream; 8.213 - pa_context *context; 8.214 -} pulse_data; 8.215 - 8.216 -typedef struct { 8.217 - char *name; 8.218 - char *device_name; 8.219 -} DevMap; 8.220 - 8.221 - 8.222 -static const ALCchar pulse_device[] = "PulseAudio Default"; 8.223 -static DevMap *allDevNameMap; 8.224 -static ALuint numDevNames; 8.225 -static DevMap *allCaptureDevNameMap; 8.226 -static ALuint numCaptureDevNames; 8.227 -static pa_context_flags_t pulse_ctx_flags; 8.228 - 8.229 - 8.230 -static void context_state_callback(pa_context *context, void *pdata) 8.231 -{ 8.232 - pa_threaded_mainloop *loop = pdata; 8.233 - pa_context_state_t state; 8.234 - 8.235 - state = pa_context_get_state(context); 8.236 - if(state == PA_CONTEXT_READY || !PA_CONTEXT_IS_GOOD(state)) 8.237 - pa_threaded_mainloop_signal(loop, 0); 8.238 -} 8.239 - 8.240 -static pa_context *connect_context(pa_threaded_mainloop *loop, ALboolean silent) 8.241 -{ 8.242 - const char *name = "OpenAL Soft"; 8.243 - char path_name[PATH_MAX]; 8.244 - pa_context_state_t state; 8.245 - pa_context *context; 8.246 - int err; 8.247 - 8.248 - if(pa_get_binary_name(path_name, sizeof(path_name))) 8.249 - name = pa_path_get_filename(path_name); 8.250 - 8.251 - context = pa_context_new(pa_threaded_mainloop_get_api(loop), name); 8.252 - if(!context) 8.253 - { 8.254 - ERR("pa_context_new() failed\n"); 8.255 - return NULL; 8.256 - } 8.257 - 8.258 - pa_context_set_state_callback(context, context_state_callback, loop); 8.259 - 8.260 - if((err=pa_context_connect(context, NULL, pulse_ctx_flags, NULL)) >= 0) 8.261 - { 8.262 - while((state=pa_context_get_state(context)) != PA_CONTEXT_READY) 8.263 - { 8.264 - if(!PA_CONTEXT_IS_GOOD(state)) 8.265 - { 8.266 - err = pa_context_errno(context); 8.267 - if(err > 0) err = -err; 8.268 - break; 8.269 - } 8.270 - 8.271 - pa_threaded_mainloop_wait(loop); 8.272 - } 8.273 - } 8.274 - pa_context_set_state_callback(context, NULL, NULL); 8.275 - 8.276 - if(err < 0) 8.277 - { 8.278 - if(!silent) 8.279 - ERR("Context did not connect: %s\n", pa_strerror(err)); 8.280 - pa_context_unref(context); 8.281 - return NULL; 8.282 - } 8.283 - 8.284 - return context; 8.285 -} 8.286 - 8.287 - 8.288 -static ALCboolean pulse_load(void) //{{{ 8.289 -{ 8.290 - ALCboolean ret = ALC_FALSE; 8.291 - if(!pa_handle) 8.292 - { 8.293 - pa_threaded_mainloop *loop; 8.294 - 8.295 -#ifdef HAVE_DYNLOAD 8.296 - 8.297 -#ifdef _WIN32 8.298 -#define PALIB "libpulse-0.dll" 8.299 -#elif defined(__APPLE__) && defined(__MACH__) 8.300 -#define PALIB "libpulse.0.dylib" 8.301 -#else 8.302 -#define PALIB "libpulse.so.0" 8.303 -#endif 8.304 - pa_handle = LoadLib(PALIB); 8.305 - if(!pa_handle) 8.306 - return ALC_FALSE; 8.307 - 8.308 -#define LOAD_FUNC(x) do { \ 8.309 - p##x = GetSymbol(pa_handle, #x); \ 8.310 - if(!(p##x)) { \ 8.311 - CloseLib(pa_handle); \ 8.312 - pa_handle = NULL; \ 8.313 - return ALC_FALSE; \ 8.314 - } \ 8.315 -} while(0) 8.316 - LOAD_FUNC(pa_context_unref); 8.317 - LOAD_FUNC(pa_sample_spec_valid); 8.318 - LOAD_FUNC(pa_stream_drop); 8.319 - LOAD_FUNC(pa_strerror); 8.320 - LOAD_FUNC(pa_context_get_state); 8.321 - LOAD_FUNC(pa_stream_get_state); 8.322 - LOAD_FUNC(pa_threaded_mainloop_signal); 8.323 - LOAD_FUNC(pa_stream_peek); 8.324 - LOAD_FUNC(pa_threaded_mainloop_wait); 8.325 - LOAD_FUNC(pa_threaded_mainloop_unlock); 8.326 - LOAD_FUNC(pa_threaded_mainloop_in_thread); 8.327 - LOAD_FUNC(pa_context_new); 8.328 - LOAD_FUNC(pa_threaded_mainloop_stop); 8.329 - LOAD_FUNC(pa_context_disconnect); 8.330 - LOAD_FUNC(pa_threaded_mainloop_start); 8.331 - LOAD_FUNC(pa_threaded_mainloop_get_api); 8.332 - LOAD_FUNC(pa_context_set_state_callback); 8.333 - LOAD_FUNC(pa_stream_write); 8.334 - LOAD_FUNC(pa_xfree); 8.335 - LOAD_FUNC(pa_stream_connect_record); 8.336 - LOAD_FUNC(pa_stream_connect_playback); 8.337 - LOAD_FUNC(pa_stream_readable_size); 8.338 - LOAD_FUNC(pa_stream_writable_size); 8.339 - LOAD_FUNC(pa_stream_cork); 8.340 - LOAD_FUNC(pa_stream_is_suspended); 8.341 - LOAD_FUNC(pa_stream_get_device_name); 8.342 - LOAD_FUNC(pa_path_get_filename); 8.343 - LOAD_FUNC(pa_get_binary_name); 8.344 - LOAD_FUNC(pa_threaded_mainloop_free); 8.345 - LOAD_FUNC(pa_context_errno); 8.346 - LOAD_FUNC(pa_xmalloc); 8.347 - LOAD_FUNC(pa_stream_unref); 8.348 - LOAD_FUNC(pa_threaded_mainloop_accept); 8.349 - LOAD_FUNC(pa_stream_set_write_callback); 8.350 - LOAD_FUNC(pa_threaded_mainloop_new); 8.351 - LOAD_FUNC(pa_context_connect); 8.352 - LOAD_FUNC(pa_stream_set_buffer_attr); 8.353 - LOAD_FUNC(pa_stream_get_buffer_attr); 8.354 - LOAD_FUNC(pa_stream_get_sample_spec); 8.355 - LOAD_FUNC(pa_stream_get_time); 8.356 - LOAD_FUNC(pa_stream_set_read_callback); 8.357 - LOAD_FUNC(pa_stream_set_state_callback); 8.358 - LOAD_FUNC(pa_stream_set_moved_callback); 8.359 - LOAD_FUNC(pa_stream_set_underflow_callback); 8.360 - LOAD_FUNC(pa_stream_new); 8.361 - LOAD_FUNC(pa_stream_disconnect); 8.362 - LOAD_FUNC(pa_threaded_mainloop_lock); 8.363 - LOAD_FUNC(pa_channel_map_init_auto); 8.364 - LOAD_FUNC(pa_channel_map_parse); 8.365 - LOAD_FUNC(pa_channel_map_snprint); 8.366 - LOAD_FUNC(pa_channel_map_equal); 8.367 - LOAD_FUNC(pa_context_get_server_info); 8.368 - LOAD_FUNC(pa_context_get_sink_info_by_name); 8.369 - LOAD_FUNC(pa_context_get_sink_info_list); 8.370 - LOAD_FUNC(pa_context_get_source_info_list); 8.371 - LOAD_FUNC(pa_operation_get_state); 8.372 - LOAD_FUNC(pa_operation_unref); 8.373 -#undef LOAD_FUNC 8.374 -#define LOAD_OPTIONAL_FUNC(x) do { \ 8.375 - p##x = GetSymbol(pa_handle, #x); \ 8.376 -} while(0) 8.377 -#if PA_CHECK_VERSION(0,9,15) 8.378 - LOAD_OPTIONAL_FUNC(pa_channel_map_superset); 8.379 - LOAD_OPTIONAL_FUNC(pa_stream_set_buffer_attr_callback); 8.380 -#endif 8.381 -#if PA_CHECK_VERSION(0,9,16) 8.382 - LOAD_OPTIONAL_FUNC(pa_stream_begin_write); 8.383 -#endif 8.384 -#undef LOAD_OPTIONAL_FUNC 8.385 - 8.386 -#else /* HAVE_DYNLOAD */ 8.387 - pa_handle = (void*)0xDEADBEEF; 8.388 -#endif 8.389 - 8.390 - if((loop=pa_threaded_mainloop_new()) && 8.391 - pa_threaded_mainloop_start(loop) >= 0) 8.392 - { 8.393 - pa_context *context; 8.394 - 8.395 - pa_threaded_mainloop_lock(loop); 8.396 - context = connect_context(loop, AL_TRUE); 8.397 - if(context) 8.398 - { 8.399 - ret = ALC_TRUE; 8.400 - 8.401 - pa_context_disconnect(context); 8.402 - pa_context_unref(context); 8.403 - } 8.404 - pa_threaded_mainloop_unlock(loop); 8.405 - pa_threaded_mainloop_stop(loop); 8.406 - } 8.407 - if(loop) 8.408 - pa_threaded_mainloop_free(loop); 8.409 - 8.410 - if(!ret) 8.411 - { 8.412 -#ifdef HAVE_DYNLOAD 8.413 - CloseLib(pa_handle); 8.414 -#endif 8.415 - pa_handle = NULL; 8.416 - } 8.417 - } 8.418 - return ret; 8.419 -} //}}} 8.420 - 8.421 -// PulseAudio Event Callbacks //{{{ 8.422 -static void stream_state_callback(pa_stream *stream, void *pdata) //{{{ 8.423 -{ 8.424 - pa_threaded_mainloop *loop = pdata; 8.425 - pa_stream_state_t state; 8.426 - 8.427 - state = pa_stream_get_state(stream); 8.428 - if(state == PA_STREAM_READY || !PA_STREAM_IS_GOOD(state)) 8.429 - pa_threaded_mainloop_signal(loop, 0); 8.430 -}//}}} 8.431 - 8.432 -static void stream_signal_callback(pa_stream *stream, void *pdata) //{{{ 8.433 -{ 8.434 - ALCdevice *Device = pdata; 8.435 - pulse_data *data = Device->ExtraData; 8.436 - (void)stream; 8.437 - 8.438 - pa_threaded_mainloop_signal(data->loop, 0); 8.439 -}//}}} 8.440 - 8.441 -static void stream_buffer_attr_callback(pa_stream *stream, void *pdata) //{{{ 8.442 -{ 8.443 - ALCdevice *Device = pdata; 8.444 - pulse_data *data = Device->ExtraData; 8.445 - 8.446 - LockDevice(Device); 8.447 - 8.448 - data->attr = *(pa_stream_get_buffer_attr(stream)); 8.449 - Device->UpdateSize = data->attr.minreq / data->frame_size; 8.450 - Device->NumUpdates = (data->attr.tlength/data->frame_size) / Device->UpdateSize; 8.451 - if(Device->NumUpdates <= 1) 8.452 - { 8.453 - Device->NumUpdates = 1; 8.454 - ERR("PulseAudio returned minreq > tlength/2; expect break up\n"); 8.455 - } 8.456 - 8.457 - UnlockDevice(Device); 8.458 -}//}}} 8.459 - 8.460 -static void stream_device_callback(pa_stream *stream, void *pdata) //{{{ 8.461 -{ 8.462 - ALCdevice *Device = pdata; 8.463 - pulse_data *data = Device->ExtraData; 8.464 - 8.465 - free(data->device_name); 8.466 - data->device_name = strdup(pa_stream_get_device_name(stream)); 8.467 -}//}}} 8.468 - 8.469 -static void context_state_callback2(pa_context *context, void *pdata) //{{{ 8.470 -{ 8.471 - ALCdevice *Device = pdata; 8.472 - pulse_data *data = Device->ExtraData; 8.473 - 8.474 - if(pa_context_get_state(context) == PA_CONTEXT_FAILED) 8.475 - { 8.476 - ERR("Received context failure!\n"); 8.477 - aluHandleDisconnect(Device); 8.478 - } 8.479 - pa_threaded_mainloop_signal(data->loop, 0); 8.480 -}//}}} 8.481 - 8.482 -static void stream_state_callback2(pa_stream *stream, void *pdata) //{{{ 8.483 -{ 8.484 - ALCdevice *Device = pdata; 8.485 - pulse_data *data = Device->ExtraData; 8.486 - 8.487 - if(pa_stream_get_state(stream) == PA_STREAM_FAILED) 8.488 - { 8.489 - ERR("Received stream failure!\n"); 8.490 - aluHandleDisconnect(Device); 8.491 - } 8.492 - pa_threaded_mainloop_signal(data->loop, 0); 8.493 -}//}}} 8.494 - 8.495 -static void stream_success_callback(pa_stream *stream, int success, void *pdata) //{{{ 8.496 -{ 8.497 - ALCdevice *Device = pdata; 8.498 - pulse_data *data = Device->ExtraData; 8.499 - (void)stream; 8.500 - (void)success; 8.501 - 8.502 - pa_threaded_mainloop_signal(data->loop, 0); 8.503 -}//}}} 8.504 - 8.505 -static void sink_info_callback(pa_context *context, const pa_sink_info *info, int eol, void *pdata) //{{{ 8.506 -{ 8.507 - ALCdevice *device = pdata; 8.508 - pulse_data *data = device->ExtraData; 8.509 - char chanmap_str[256] = ""; 8.510 - const struct { 8.511 - const char *str; 8.512 - enum DevFmtChannels chans; 8.513 - } chanmaps[] = { 8.514 - { "front-left,front-right,front-center,lfe,rear-left,rear-right,side-left,side-right", 8.515 - DevFmtX71 }, 8.516 - { "front-left,front-right,front-center,lfe,rear-center,side-left,side-right", 8.517 - DevFmtX61 }, 8.518 - { "front-left,front-right,front-center,lfe,rear-left,rear-right", 8.519 - DevFmtX51 }, 8.520 - { "front-left,front-right,front-center,lfe,side-left,side-right", 8.521 - DevFmtX51Side }, 8.522 - { "front-left,front-right,rear-left,rear-right", DevFmtQuad }, 8.523 - { "front-left,front-right", DevFmtStereo }, 8.524 - { "mono", DevFmtMono }, 8.525 - { NULL, 0 } 8.526 - }; 8.527 - int i; 8.528 - (void)context; 8.529 - 8.530 - if(eol) 8.531 - { 8.532 - pa_threaded_mainloop_signal(data->loop, 0); 8.533 - return; 8.534 - } 8.535 - 8.536 - for(i = 0;chanmaps[i].str;i++) 8.537 - { 8.538 - pa_channel_map map; 8.539 - if(!pa_channel_map_parse(&map, chanmaps[i].str)) 8.540 - continue; 8.541 - 8.542 - if(pa_channel_map_equal(&info->channel_map, &map) 8.543 -#if PA_CHECK_VERSION(0,9,15) 8.544 - || (pa_channel_map_superset && 8.545 - pa_channel_map_superset(&info->channel_map, &map)) 8.546 -#endif 8.547 - ) 8.548 - { 8.549 - device->FmtChans = chanmaps[i].chans; 8.550 - return; 8.551 - } 8.552 - } 8.553 - 8.554 - pa_channel_map_snprint(chanmap_str, sizeof(chanmap_str), &info->channel_map); 8.555 - ERR("Failed to find format for channel map:\n %s\n", chanmap_str); 8.556 -}//}}} 8.557 - 8.558 -static void sink_device_callback(pa_context *context, const pa_sink_info *info, int eol, void *pdata) //{{{ 8.559 -{ 8.560 - pa_threaded_mainloop *loop = pdata; 8.561 - char str[1024]; 8.562 - void *temp; 8.563 - int count; 8.564 - ALuint i; 8.565 - 8.566 - (void)context; 8.567 - 8.568 - if(eol) 8.569 - { 8.570 - pa_threaded_mainloop_signal(loop, 0); 8.571 - return; 8.572 - } 8.573 - 8.574 - count = 0; 8.575 - do { 8.576 - if(count == 0) 8.577 - snprintf(str, sizeof(str), "%s", info->description); 8.578 - else 8.579 - snprintf(str, sizeof(str), "%s #%d", info->description, count+1); 8.580 - count++; 8.581 - 8.582 - for(i = 0;i < numDevNames;i++) 8.583 - { 8.584 - if(strcmp(str, allDevNameMap[i].name) == 0) 8.585 - break; 8.586 - } 8.587 - } while(i != numDevNames); 8.588 - 8.589 - temp = realloc(allDevNameMap, (numDevNames+1) * sizeof(*allDevNameMap)); 8.590 - if(temp) 8.591 - { 8.592 - allDevNameMap = temp; 8.593 - allDevNameMap[numDevNames].name = strdup(str); 8.594 - allDevNameMap[numDevNames].device_name = strdup(info->name); 8.595 - numDevNames++; 8.596 - } 8.597 -}//}}} 8.598 - 8.599 -static void source_device_callback(pa_context *context, const pa_source_info *info, int eol, void *pdata) //{{{ 8.600 -{ 8.601 - pa_threaded_mainloop *loop = pdata; 8.602 - char str[1024]; 8.603 - void *temp; 8.604 - int count; 8.605 - ALuint i; 8.606 - 8.607 - (void)context; 8.608 - 8.609 - if(eol) 8.610 - { 8.611 - pa_threaded_mainloop_signal(loop, 0); 8.612 - return; 8.613 - } 8.614 - 8.615 - count = 0; 8.616 - do { 8.617 - if(count == 0) 8.618 - snprintf(str, sizeof(str), "%s", info->description); 8.619 - else 8.620 - snprintf(str, sizeof(str), "%s #%d", info->description, count+1); 8.621 - count++; 8.622 - 8.623 - for(i = 0;i < numCaptureDevNames;i++) 8.624 - { 8.625 - if(strcmp(str, allCaptureDevNameMap[i].name) == 0) 8.626 - break; 8.627 - } 8.628 - } while(i != numCaptureDevNames); 8.629 - 8.630 - temp = realloc(allCaptureDevNameMap, (numCaptureDevNames+1) * sizeof(*allCaptureDevNameMap)); 8.631 - if(temp) 8.632 - { 8.633 - allCaptureDevNameMap = temp; 8.634 - allCaptureDevNameMap[numCaptureDevNames].name = strdup(str); 8.635 - allCaptureDevNameMap[numCaptureDevNames].device_name = strdup(info->name); 8.636 - numCaptureDevNames++; 8.637 - } 8.638 -}//}}} 8.639 -//}}} 8.640 - 8.641 -// PulseAudio I/O Callbacks //{{{ 8.642 -static void stream_write_callback(pa_stream *stream, size_t len, void *pdata) //{{{ 8.643 -{ 8.644 - ALCdevice *Device = pdata; 8.645 - pulse_data *data = Device->ExtraData; 8.646 - (void)stream; 8.647 - (void)len; 8.648 - 8.649 - pa_threaded_mainloop_signal(data->loop, 0); 8.650 -} //}}} 8.651 -//}}} 8.652 - 8.653 -static ALuint PulseProc(ALvoid *param) 8.654 -{ 8.655 - ALCdevice *Device = param; 8.656 - pulse_data *data = Device->ExtraData; 8.657 - ssize_t len; 8.658 - 8.659 - SetRTPriority(); 8.660 - 8.661 - pa_threaded_mainloop_lock(data->loop); 8.662 - do { 8.663 - len = (Device->Connected ? pa_stream_writable_size(data->stream) : 0); 8.664 - len -= len%(Device->UpdateSize*data->frame_size); 8.665 - if(len == 0) 8.666 - { 8.667 - pa_threaded_mainloop_wait(data->loop); 8.668 - continue; 8.669 - } 8.670 - 8.671 - while(len > 0) 8.672 - { 8.673 - size_t newlen = len; 8.674 - void *buf; 8.675 - pa_free_cb_t free_func = NULL; 8.676 - 8.677 -#if PA_CHECK_VERSION(0,9,16) 8.678 - if(!pa_stream_begin_write || 8.679 - pa_stream_begin_write(data->stream, &buf, &newlen) < 0) 8.680 -#endif 8.681 - { 8.682 - buf = pa_xmalloc(newlen); 8.683 - free_func = pa_xfree; 8.684 - } 8.685 - pa_threaded_mainloop_unlock(data->loop); 8.686 - 8.687 - aluMixData(Device, buf, newlen/data->frame_size); 8.688 - 8.689 - pa_threaded_mainloop_lock(data->loop); 8.690 - pa_stream_write(data->stream, buf, newlen, free_func, 0, PA_SEEK_RELATIVE); 8.691 - len -= newlen; 8.692 - } 8.693 - } while(Device->Connected && !data->killNow); 8.694 - pa_threaded_mainloop_unlock(data->loop); 8.695 - 8.696 - return 0; 8.697 -} 8.698 - 8.699 -static pa_stream *connect_playback_stream(ALCdevice *device, 8.700 - pa_stream_flags_t flags, pa_buffer_attr *attr, pa_sample_spec *spec, 8.701 - pa_channel_map *chanmap) 8.702 -{ 8.703 - pulse_data *data = device->ExtraData; 8.704 - pa_stream_state_t state; 8.705 - pa_stream *stream; 8.706 - 8.707 - stream = pa_stream_new(data->context, "Playback Stream", spec, chanmap); 8.708 - if(!stream) 8.709 - { 8.710 - ERR("pa_stream_new() failed: %s\n", 8.711 - pa_strerror(pa_context_errno(data->context))); 8.712 - return NULL; 8.713 - } 8.714 - 8.715 - pa_stream_set_state_callback(stream, stream_state_callback, data->loop); 8.716 - 8.717 - if(pa_stream_connect_playback(stream, data->device_name, attr, flags, NULL, NULL) < 0) 8.718 - { 8.719 - ERR("Stream did not connect: %s\n", 8.720 - pa_strerror(pa_context_errno(data->context))); 8.721 - pa_stream_unref(stream); 8.722 - return NULL; 8.723 - } 8.724 - 8.725 - while((state=pa_stream_get_state(stream)) != PA_STREAM_READY) 8.726 - { 8.727 - if(!PA_STREAM_IS_GOOD(state)) 8.728 - { 8.729 - ERR("Stream did not get ready: %s\n", 8.730 - pa_strerror(pa_context_errno(data->context))); 8.731 - pa_stream_unref(stream); 8.732 - return NULL; 8.733 - } 8.734 - 8.735 - pa_threaded_mainloop_wait(data->loop); 8.736 - } 8.737 - pa_stream_set_state_callback(stream, NULL, NULL); 8.738 - 8.739 - return stream; 8.740 -} 8.741 - 8.742 -static void probe_devices(ALboolean capture) 8.743 -{ 8.744 - pa_threaded_mainloop *loop; 8.745 - 8.746 - if(capture == AL_FALSE) 8.747 - allDevNameMap = malloc(sizeof(DevMap) * 1); 8.748 - else 8.749 - allCaptureDevNameMap = malloc(sizeof(DevMap) * 1); 8.750 - 8.751 - if((loop=pa_threaded_mainloop_new()) && 8.752 - pa_threaded_mainloop_start(loop) >= 0) 8.753 - { 8.754 - pa_context *context; 8.755 - 8.756 - pa_threaded_mainloop_lock(loop); 8.757 - context = connect_context(loop, AL_FALSE); 8.758 - if(context) 8.759 - { 8.760 - pa_operation *o; 8.761 - 8.762 - if(capture == AL_FALSE) 8.763 - o = pa_context_get_sink_info_list(context, sink_device_callback, loop); 8.764 - else 8.765 - o = pa_context_get_source_info_list(context, source_device_callback, loop); 8.766 - while(pa_operation_get_state(o) == PA_OPERATION_RUNNING) 8.767 - pa_threaded_mainloop_wait(loop); 8.768 - pa_operation_unref(o); 8.769 - 8.770 - pa_context_disconnect(context); 8.771 - pa_context_unref(context); 8.772 - } 8.773 - pa_threaded_mainloop_unlock(loop); 8.774 - pa_threaded_mainloop_stop(loop); 8.775 - } 8.776 - if(loop) 8.777 - pa_threaded_mainloop_free(loop); 8.778 -} 8.779 - 8.780 - 8.781 -static ALCboolean pulse_open(ALCdevice *device, const ALCchar *device_name) //{{{ 8.782 -{ 8.783 - pulse_data *data = pa_xmalloc(sizeof(pulse_data)); 8.784 - memset(data, 0, sizeof(*data)); 8.785 - 8.786 - if(!(data->loop = pa_threaded_mainloop_new())) 8.787 - { 8.788 - ERR("pa_threaded_mainloop_new() failed!\n"); 8.789 - goto out; 8.790 - } 8.791 - if(pa_threaded_mainloop_start(data->loop) < 0) 8.792 - { 8.793 - ERR("pa_threaded_mainloop_start() failed\n"); 8.794 - goto out; 8.795 - } 8.796 - 8.797 - pa_threaded_mainloop_lock(data->loop); 8.798 - device->ExtraData = data; 8.799 - 8.800 - data->context = connect_context(data->loop, AL_FALSE); 8.801 - if(!data->context) 8.802 - { 8.803 - pa_threaded_mainloop_unlock(data->loop); 8.804 - goto out; 8.805 - } 8.806 - pa_context_set_state_callback(data->context, context_state_callback2, device); 8.807 - 8.808 - device->szDeviceName = strdup(device_name); 8.809 - 8.810 - pa_threaded_mainloop_unlock(data->loop); 8.811 - return ALC_TRUE; 8.812 - 8.813 -out: 8.814 - if(data->loop) 8.815 - { 8.816 - pa_threaded_mainloop_stop(data->loop); 8.817 - pa_threaded_mainloop_free(data->loop); 8.818 - } 8.819 - 8.820 - device->ExtraData = NULL; 8.821 - pa_xfree(data); 8.822 - return ALC_FALSE; 8.823 -} //}}} 8.824 - 8.825 -static void pulse_close(ALCdevice *device) //{{{ 8.826 -{ 8.827 - pulse_data *data = device->ExtraData; 8.828 - 8.829 - pa_threaded_mainloop_lock(data->loop); 8.830 - 8.831 - if(data->stream) 8.832 - { 8.833 - pa_stream_disconnect(data->stream); 8.834 - pa_stream_unref(data->stream); 8.835 - } 8.836 - 8.837 - pa_context_disconnect(data->context); 8.838 - pa_context_unref(data->context); 8.839 - 8.840 - pa_threaded_mainloop_unlock(data->loop); 8.841 - 8.842 - pa_threaded_mainloop_stop(data->loop); 8.843 - pa_threaded_mainloop_free(data->loop); 8.844 - 8.845 - DestroyRingBuffer(data->ring); 8.846 - free(data->device_name); 8.847 - 8.848 - device->ExtraData = NULL; 8.849 - pa_xfree(data); 8.850 -} //}}} 8.851 -//}}} 8.852 - 8.853 -// OpenAL {{{ 8.854 -static ALCboolean pulse_open_playback(ALCdevice *device, const ALCchar *device_name) //{{{ 8.855 -{ 8.856 - char *pulse_name = NULL; 8.857 - pa_sample_spec spec; 8.858 - pulse_data *data; 8.859 - 8.860 - if(!allDevNameMap) 8.861 - probe_devices(AL_FALSE); 8.862 - 8.863 - if(!device_name) 8.864 - device_name = pulse_device; 8.865 - else if(strcmp(device_name, pulse_device) != 0) 8.866 - { 8.867 - ALuint i; 8.868 - 8.869 - for(i = 0;i < numDevNames;i++) 8.870 - { 8.871 - if(strcmp(device_name, allDevNameMap[i].name) == 0) 8.872 - { 8.873 - pulse_name = allDevNameMap[i].device_name; 8.874 - break; 8.875 - } 8.876 - } 8.877 - if(i == numDevNames) 8.878 - return ALC_FALSE; 8.879 - } 8.880 - 8.881 - if(pulse_open(device, device_name) == ALC_FALSE) 8.882 - return ALC_FALSE; 8.883 - 8.884 - data = device->ExtraData; 8.885 - 8.886 - pa_threaded_mainloop_lock(data->loop); 8.887 - 8.888 - spec.format = PA_SAMPLE_S16NE; 8.889 - spec.rate = 44100; 8.890 - spec.channels = 2; 8.891 - 8.892 - data->device_name = pulse_name; 8.893 - pa_stream *stream = connect_playback_stream(device, 0, NULL, &spec, NULL); 8.894 - if(!stream) 8.895 - { 8.896 - pa_threaded_mainloop_unlock(data->loop); 8.897 - goto fail; 8.898 - } 8.899 - 8.900 - if(pa_stream_is_suspended(stream)) 8.901 - { 8.902 - ERR("Device is suspended\n"); 8.903 - pa_stream_disconnect(stream); 8.904 - pa_stream_unref(stream); 8.905 - pa_threaded_mainloop_unlock(data->loop); 8.906 - goto fail; 8.907 - } 8.908 - data->device_name = strdup(pa_stream_get_device_name(stream)); 8.909 - 8.910 - pa_stream_disconnect(stream); 8.911 - pa_stream_unref(stream); 8.912 - 8.913 - pa_threaded_mainloop_unlock(data->loop); 8.914 - 8.915 - return ALC_TRUE; 8.916 - 8.917 -fail: 8.918 - pulse_close(device); 8.919 - return ALC_FALSE; 8.920 -} //}}} 8.921 - 8.922 -static void pulse_close_playback(ALCdevice *device) //{{{ 8.923 -{ 8.924 - pulse_close(device); 8.925 -} //}}} 8.926 - 8.927 -static ALCboolean pulse_reset_playback(ALCdevice *device) //{{{ 8.928 -{ 8.929 - pulse_data *data = device->ExtraData; 8.930 - pa_stream_flags_t flags = 0; 8.931 - pa_channel_map chanmap; 8.932 - 8.933 - pa_threaded_mainloop_lock(data->loop); 8.934 - 8.935 - if(!(device->Flags&DEVICE_CHANNELS_REQUEST)) 8.936 - { 8.937 - pa_operation *o; 8.938 - o = pa_context_get_sink_info_by_name(data->context, data->device_name, sink_info_callback, device); 8.939 - while(pa_operation_get_state(o) == PA_OPERATION_RUNNING) 8.940 - pa_threaded_mainloop_wait(data->loop); 8.941 - pa_operation_unref(o); 8.942 - } 8.943 - if(!(device->Flags&DEVICE_FREQUENCY_REQUEST)) 8.944 - flags |= PA_STREAM_FIX_RATE; 8.945 - 8.946 - data->frame_size = FrameSizeFromDevFmt(device->FmtChans, device->FmtType); 8.947 - data->attr.prebuf = -1; 8.948 - data->attr.fragsize = -1; 8.949 - data->attr.minreq = device->UpdateSize * data->frame_size; 8.950 - data->attr.tlength = data->attr.minreq * device->NumUpdates; 8.951 - if(data->attr.tlength < data->attr.minreq*2) 8.952 - data->attr.tlength = data->attr.minreq*2; 8.953 - data->attr.maxlength = data->attr.tlength; 8.954 - flags |= PA_STREAM_EARLY_REQUESTS; 8.955 - flags |= PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_AUTO_TIMING_UPDATE; 8.956 - 8.957 - switch(device->FmtType) 8.958 - { 8.959 - case DevFmtByte: 8.960 - device->FmtType = DevFmtUByte; 8.961 - /* fall-through */ 8.962 - case DevFmtUByte: 8.963 - data->spec.format = PA_SAMPLE_U8; 8.964 - break; 8.965 - case DevFmtUShort: 8.966 - device->FmtType = DevFmtShort; 8.967 - /* fall-through */ 8.968 - case DevFmtShort: 8.969 - data->spec.format = PA_SAMPLE_S16NE; 8.970 - break; 8.971 - case DevFmtFloat: 8.972 - data->spec.format = PA_SAMPLE_FLOAT32NE; 8.973 - break; 8.974 - } 8.975 - data->spec.rate = device->Frequency; 8.976 - data->spec.channels = ChannelsFromDevFmt(device->FmtChans); 8.977 - 8.978 - if(pa_sample_spec_valid(&data->spec) == 0) 8.979 - { 8.980 - ERR("Invalid sample format\n"); 8.981 - pa_threaded_mainloop_unlock(data->loop); 8.982 - return ALC_FALSE; 8.983 - } 8.984 - 8.985 - if(!pa_channel_map_init_auto(&chanmap, data->spec.channels, PA_CHANNEL_MAP_WAVEEX)) 8.986 - { 8.987 - ERR("Couldn't build map for channel count (%d)!\n", data->spec.channels); 8.988 - pa_threaded_mainloop_unlock(data->loop); 8.989 - return ALC_FALSE; 8.990 - } 8.991 - SetDefaultWFXChannelOrder(device); 8.992 - 8.993 - data->stream = connect_playback_stream(device, flags, &data->attr, &data->spec, &chanmap); 8.994 - if(!data->stream) 8.995 - { 8.996 - pa_threaded_mainloop_unlock(data->loop); 8.997 - return ALC_FALSE; 8.998 - } 8.999 - 8.1000 - pa_stream_set_state_callback(data->stream, stream_state_callback2, device); 8.1001 - 8.1002 - data->spec = *(pa_stream_get_sample_spec(data->stream)); 8.1003 - if(device->Frequency != data->spec.rate) 8.1004 - { 8.1005 - pa_operation *o; 8.1006 - 8.1007 - if((device->Flags&DEVICE_FREQUENCY_REQUEST)) 8.1008 - ERR("Failed to set frequency %dhz, got %dhz instead\n", device->Frequency, data->spec.rate); 8.1009 - device->Flags &= ~DEVICE_FREQUENCY_REQUEST; 8.1010 - 8.1011 - /* Server updated our playback rate, so modify the buffer attribs 8.1012 - * accordingly. */ 8.1013 - data->attr.minreq = (ALuint64)(data->attr.minreq/data->frame_size) * 8.1014 - data->spec.rate / device->Frequency * data->frame_size; 8.1015 - data->attr.tlength = data->attr.minreq * device->NumUpdates; 8.1016 - data->attr.maxlength = data->attr.tlength; 8.1017 - 8.1018 - o = pa_stream_set_buffer_attr(data->stream, &data->attr, 8.1019 - stream_success_callback, device); 8.1020 - while(pa_operation_get_state(o) == PA_OPERATION_RUNNING) 8.1021 - pa_threaded_mainloop_wait(data->loop); 8.1022 - pa_operation_unref(o); 8.1023 - 8.1024 - device->Frequency = data->spec.rate; 8.1025 - } 8.1026 - 8.1027 - stream_buffer_attr_callback(data->stream, device); 8.1028 -#if PA_CHECK_VERSION(0,9,15) 8.1029 - if(pa_stream_set_buffer_attr_callback) 8.1030 - pa_stream_set_buffer_attr_callback(data->stream, stream_buffer_attr_callback, device); 8.1031 -#endif 8.1032 - pa_stream_set_moved_callback(data->stream, stream_device_callback, device); 8.1033 - pa_stream_set_write_callback(data->stream, stream_write_callback, device); 8.1034 - pa_stream_set_underflow_callback(data->stream, stream_signal_callback, device); 8.1035 - 8.1036 - data->thread = StartThread(PulseProc, device); 8.1037 - if(!data->thread) 8.1038 - { 8.1039 -#if PA_CHECK_VERSION(0,9,15) 8.1040 - if(pa_stream_set_buffer_attr_callback) 8.1041 - pa_stream_set_buffer_attr_callback(data->stream, NULL, NULL); 8.1042 -#endif 8.1043 - pa_stream_set_moved_callback(data->stream, NULL, NULL); 8.1044 - pa_stream_set_write_callback(data->stream, NULL, NULL); 8.1045 - pa_stream_set_underflow_callback(data->stream, NULL, NULL); 8.1046 - pa_stream_disconnect(data->stream); 8.1047 - pa_stream_unref(data->stream); 8.1048 - data->stream = NULL; 8.1049 - 8.1050 - pa_threaded_mainloop_unlock(data->loop); 8.1051 - return ALC_FALSE; 8.1052 - } 8.1053 - 8.1054 - pa_threaded_mainloop_unlock(data->loop); 8.1055 - return ALC_TRUE; 8.1056 -} //}}} 8.1057 - 8.1058 -static void pulse_stop_playback(ALCdevice *device) //{{{ 8.1059 -{ 8.1060 - pulse_data *data = device->ExtraData; 8.1061 - 8.1062 - if(!data->stream) 8.1063 - return; 8.1064 - 8.1065 - data->killNow = AL_TRUE; 8.1066 - if(data->thread) 8.1067 - { 8.1068 - pa_threaded_mainloop_signal(data->loop, 0); 8.1069 - StopThread(data->thread); 8.1070 - data->thread = NULL; 8.1071 - } 8.1072 - data->killNow = AL_FALSE; 8.1073 - 8.1074 - pa_threaded_mainloop_lock(data->loop); 8.1075 - 8.1076 -#if PA_CHECK_VERSION(0,9,15) 8.1077 - if(pa_stream_set_buffer_attr_callback) 8.1078 - pa_stream_set_buffer_attr_callback(data->stream, NULL, NULL); 8.1079 -#endif 8.1080 - pa_stream_set_moved_callback(data->stream, NULL, NULL); 8.1081 - pa_stream_set_write_callback(data->stream, NULL, NULL); 8.1082 - pa_stream_set_underflow_callback(data->stream, NULL, NULL); 8.1083 - pa_stream_disconnect(data->stream); 8.1084 - pa_stream_unref(data->stream); 8.1085 - data->stream = NULL; 8.1086 - 8.1087 - pa_threaded_mainloop_unlock(data->loop); 8.1088 -} //}}} 8.1089 - 8.1090 - 8.1091 -static ALCboolean pulse_open_capture(ALCdevice *device, const ALCchar *device_name) //{{{ 8.1092 -{ 8.1093 - char *pulse_name = NULL; 8.1094 - pulse_data *data; 8.1095 - pa_stream_flags_t flags = 0; 8.1096 - pa_stream_state_t state; 8.1097 - pa_channel_map chanmap; 8.1098 - 8.1099 - if(!allCaptureDevNameMap) 8.1100 - probe_devices(AL_TRUE); 8.1101 - 8.1102 - if(!device_name) 8.1103 - device_name = pulse_device; 8.1104 - else if(strcmp(device_name, pulse_device) != 0) 8.1105 - { 8.1106 - ALuint i; 8.1107 - 8.1108 - for(i = 0;i < numCaptureDevNames;i++) 8.1109 - { 8.1110 - if(strcmp(device_name, allCaptureDevNameMap[i].name) == 0) 8.1111 - { 8.1112 - pulse_name = allCaptureDevNameMap[i].device_name; 8.1113 - break; 8.1114 - } 8.1115 - } 8.1116 - if(i == numCaptureDevNames) 8.1117 - return ALC_FALSE; 8.1118 - } 8.1119 - 8.1120 - if(pulse_open(device, device_name) == ALC_FALSE) 8.1121 - return ALC_FALSE; 8.1122 - 8.1123 - data = device->ExtraData; 8.1124 - pa_threaded_mainloop_lock(data->loop); 8.1125 - 8.1126 - data->samples = device->UpdateSize * device->NumUpdates; 8.1127 - data->frame_size = FrameSizeFromDevFmt(device->FmtChans, device->FmtType); 8.1128 - if(data->samples < 100 * device->Frequency / 1000) 8.1129 - data->samples = 100 * device->Frequency / 1000; 8.1130 - 8.1131 - if(!(data->ring = CreateRingBuffer(data->frame_size, data->samples))) 8.1132 - { 8.1133 - pa_threaded_mainloop_unlock(data->loop); 8.1134 - goto fail; 8.1135 - } 8.1136 - 8.1137 - data->attr.minreq = -1; 8.1138 - data->attr.prebuf = -1; 8.1139 - data->attr.maxlength = data->samples * data->frame_size; 8.1140 - data->attr.tlength = -1; 8.1141 - data->attr.fragsize = minu(data->samples, 50*device->Frequency/1000) * 8.1142 - data->frame_size; 8.1143 - 8.1144 - data->spec.rate = device->Frequency; 8.1145 - data->spec.channels = ChannelsFromDevFmt(device->FmtChans); 8.1146 - 8.1147 - switch(device->FmtType) 8.1148 - { 8.1149 - case DevFmtUByte: 8.1150 - data->spec.format = PA_SAMPLE_U8; 8.1151 - break; 8.1152 - case DevFmtShort: 8.1153 - data->spec.format = PA_SAMPLE_S16NE; 8.1154 - break; 8.1155 - case DevFmtFloat: 8.1156 - data->spec.format = PA_SAMPLE_FLOAT32NE; 8.1157 - break; 8.1158 - case DevFmtByte: 8.1159 - case DevFmtUShort: 8.1160 - ERR("Capture format type %#x capture not supported on PulseAudio\n", device->FmtType); 8.1161 - pa_threaded_mainloop_unlock(data->loop); 8.1162 - goto fail; 8.1163 - } 8.1164 - 8.1165 - if(pa_sample_spec_valid(&data->spec) == 0) 8.1166 - { 8.1167 - ERR("Invalid sample format\n"); 8.1168 - pa_threaded_mainloop_unlock(data->loop); 8.1169 - goto fail; 8.1170 - } 8.1171 - 8.1172 - if(!pa_channel_map_init_auto(&chanmap, data->spec.channels, PA_CHANNEL_MAP_WAVEEX)) 8.1173 - { 8.1174 - ERR("Couldn't build map for channel count (%d)!\n", data->spec.channels); 8.1175 - pa_threaded_mainloop_unlock(data->loop); 8.1176 - goto fail; 8.1177 - } 8.1178 - 8.1179 - data->stream = pa_stream_new(data->context, "Capture Stream", &data->spec, &chanmap); 8.1180 - if(!data->stream) 8.1181 - { 8.1182 - ERR("pa_stream_new() failed: %s\n", 8.1183 - pa_strerror(pa_context_errno(data->context))); 8.1184 - 8.1185 - pa_threaded_mainloop_unlock(data->loop); 8.1186 - goto fail; 8.1187 - } 8.1188 - 8.1189 - pa_stream_set_state_callback(data->stream, stream_state_callback, data->loop); 8.1190 - 8.1191 - flags |= PA_STREAM_START_CORKED|PA_STREAM_ADJUST_LATENCY; 8.1192 - if(pa_stream_connect_record(data->stream, pulse_name, &data->attr, flags) < 0) 8.1193 - { 8.1194 - ERR("Stream did not connect: %s\n", 8.1195 - pa_strerror(pa_context_errno(data->context))); 8.1196 - 8.1197 - pa_stream_unref(data->stream); 8.1198 - data->stream = NULL; 8.1199 - 8.1200 - pa_threaded_mainloop_unlock(data->loop); 8.1201 - goto fail; 8.1202 - } 8.1203 - 8.1204 - while((state=pa_stream_get_state(data->stream)) != PA_STREAM_READY) 8.1205 - { 8.1206 - if(!PA_STREAM_IS_GOOD(state)) 8.1207 - { 8.1208 - ERR("Stream did not get ready: %s\n", 8.1209 - pa_strerror(pa_context_errno(data->context))); 8.1210 - 8.1211 - pa_stream_unref(data->stream); 8.1212 - data->stream = NULL; 8.1213 - 8.1214 - pa_threaded_mainloop_unlock(data->loop); 8.1215 - goto fail; 8.1216 - } 8.1217 - 8.1218 - pa_threaded_mainloop_wait(data->loop); 8.1219 - } 8.1220 - pa_stream_set_state_callback(data->stream, stream_state_callback2, device); 8.1221 - 8.1222 - pa_threaded_mainloop_unlock(data->loop); 8.1223 - return ALC_TRUE; 8.1224 - 8.1225 -fail: 8.1226 - pulse_close(device); 8.1227 - return ALC_FALSE; 8.1228 -} //}}} 8.1229 - 8.1230 -static void pulse_close_capture(ALCdevice *device) //{{{ 8.1231 -{ 8.1232 - pulse_close(device); 8.1233 -} //}}} 8.1234 - 8.1235 -static void pulse_start_capture(ALCdevice *device) //{{{ 8.1236 -{ 8.1237 - pulse_data *data = device->ExtraData; 8.1238 - pa_operation *o; 8.1239 - 8.1240 - pa_threaded_mainloop_lock(data->loop); 8.1241 - o = pa_stream_cork(data->stream, 0, stream_success_callback, device); 8.1242 - while(pa_operation_get_state(o) == PA_OPERATION_RUNNING) 8.1243 - pa_threaded_mainloop_wait(data->loop); 8.1244 - pa_operation_unref(o); 8.1245 - pa_threaded_mainloop_unlock(data->loop); 8.1246 -} //}}} 8.1247 - 8.1248 -static void pulse_stop_capture(ALCdevice *device) //{{{ 8.1249 -{ 8.1250 - pulse_data *data = device->ExtraData; 8.1251 - pa_operation *o; 8.1252 - 8.1253 - pa_threaded_mainloop_lock(data->loop); 8.1254 - o = pa_stream_cork(data->stream, 1, stream_success_callback, device); 8.1255 - while(pa_operation_get_state(o) == PA_OPERATION_RUNNING) 8.1256 - pa_threaded_mainloop_wait(data->loop); 8.1257 - pa_operation_unref(o); 8.1258 - pa_threaded_mainloop_unlock(data->loop); 8.1259 -} //}}} 8.1260 - 8.1261 -static ALCuint pulse_available_samples(ALCdevice *device) //{{{ 8.1262 -{ 8.1263 - pulse_data *data = device->ExtraData; 8.1264 - size_t samples; 8.1265 - 8.1266 - pa_threaded_mainloop_lock(data->loop); 8.1267 - /* Capture is done in fragment-sized chunks, so we loop until we get all 8.1268 - * that's available */ 8.1269 - samples = (device->Connected ? pa_stream_readable_size(data->stream) : 0); 8.1270 - while(samples > 0) 8.1271 - { 8.1272 - const void *buf; 8.1273 - size_t length; 8.1274 - 8.1275 - if(pa_stream_peek(data->stream, &buf, &length) < 0) 8.1276 - { 8.1277 - ERR("pa_stream_peek() failed: %s\n", 8.1278 - pa_strerror(pa_context_errno(data->context))); 8.1279 - break; 8.1280 - } 8.1281 - 8.1282 - WriteRingBuffer(data->ring, buf, length/data->frame_size); 8.1283 - samples -= length; 8.1284 - 8.1285 - pa_stream_drop(data->stream); 8.1286 - } 8.1287 - pa_threaded_mainloop_unlock(data->loop); 8.1288 - 8.1289 - return RingBufferSize(data->ring); 8.1290 -} //}}} 8.1291 - 8.1292 -static void pulse_capture_samples(ALCdevice *device, ALCvoid *buffer, ALCuint samples) //{{{ 8.1293 -{ 8.1294 - pulse_data *data = device->ExtraData; 8.1295 - 8.1296 - if(pulse_available_samples(device) >= samples) 8.1297 - ReadRingBuffer(data->ring, buffer, samples); 8.1298 - else 8.1299 - alcSetError(device, ALC_INVALID_VALUE); 8.1300 -} //}}} 8.1301 - 8.1302 - 8.1303 -static const BackendFuncs pulse_funcs = { //{{{ 8.1304 - pulse_open_playback, 8.1305 - pulse_close_playback, 8.1306 - pulse_reset_playback, 8.1307 - pulse_stop_playback, 8.1308 - pulse_open_capture, 8.1309 - pulse_close_capture, 8.1310 - pulse_start_capture, 8.1311 - pulse_stop_capture, 8.1312 - pulse_capture_samples, 8.1313 - pulse_available_samples 8.1314 -}; //}}} 8.1315 - 8.1316 -ALCboolean alc_pulse_init(BackendFuncs *func_list) //{{{ 8.1317 -{ 8.1318 - if(!pulse_load()) 8.1319 - return ALC_FALSE; 8.1320 - 8.1321 - *func_list = pulse_funcs; 8.1322 - 8.1323 - pulse_ctx_flags = 0; 8.1324 - if(!GetConfigValueBool("pulse", "spawn-server", 0)) 8.1325 - pulse_ctx_flags |= PA_CONTEXT_NOAUTOSPAWN; 8.1326 - 8.1327 - return ALC_TRUE; 8.1328 -} //}}} 8.1329 - 8.1330 -void alc_pulse_deinit(void) //{{{ 8.1331 -{ 8.1332 - ALuint i; 8.1333 - 8.1334 - for(i = 0;i < numDevNames;++i) 8.1335 - { 8.1336 - free(allDevNameMap[i].name); 8.1337 - free(allDevNameMap[i].device_name); 8.1338 - } 8.1339 - free(allDevNameMap); 8.1340 - allDevNameMap = NULL; 8.1341 - numDevNames = 0; 8.1342 - 8.1343 - for(i = 0;i < numCaptureDevNames;++i) 8.1344 - { 8.1345 - free(allCaptureDevNameMap[i].name); 8.1346 - free(allCaptureDevNameMap[i].device_name); 8.1347 - } 8.1348 - free(allCaptureDevNameMap); 8.1349 - allCaptureDevNameMap = NULL; 8.1350 - numCaptureDevNames = 0; 8.1351 - 8.1352 -#ifdef HAVE_DYNLOAD 8.1353 - if(pa_handle) 8.1354 - CloseLib(pa_handle); 8.1355 - pa_handle = NULL; 8.1356 -#endif 8.1357 -} //}}} 8.1358 - 8.1359 -void alc_pulse_probe(enum DevProbe type) //{{{ 8.1360 -{ 8.1361 - pa_threaded_mainloop *loop; 8.1362 - ALuint i; 8.1363 - 8.1364 - switch(type) 8.1365 - { 8.1366 - case DEVICE_PROBE: 8.1367 - if((loop=pa_threaded_mainloop_new()) && 8.1368 - pa_threaded_mainloop_start(loop) >= 0) 8.1369 - { 8.1370 - pa_context *context; 8.1371 - 8.1372 - pa_threaded_mainloop_lock(loop); 8.1373 - context = connect_context(loop, AL_FALSE); 8.1374 - if(context) 8.1375 - { 8.1376 - AppendDeviceList(pulse_device); 8.1377 - 8.1378 - pa_context_disconnect(context); 8.1379 - pa_context_unref(context); 8.1380 - } 8.1381 - pa_threaded_mainloop_unlock(loop); 8.1382 - pa_threaded_mainloop_stop(loop); 8.1383 - } 8.1384 - if(loop) 8.1385 - pa_threaded_mainloop_free(loop); 8.1386 - break; 8.1387 - 8.1388 - case ALL_DEVICE_PROBE: 8.1389 - for(i = 0;i < numDevNames;++i) 8.1390 - { 8.1391 - free(allDevNameMap[i].name); 8.1392 - free(allDevNameMap[i].device_name); 8.1393 - } 8.1394 - free(allDevNameMap); 8.1395 - allDevNameMap = NULL; 8.1396 - numDevNames = 0; 8.1397 - 8.1398 - probe_devices(AL_FALSE); 8.1399 - 8.1400 - for(i = 0;i < numDevNames;i++) 8.1401 - AppendAllDeviceList(allDevNameMap[i].name); 8.1402 - break; 8.1403 - 8.1404 - case CAPTURE_DEVICE_PROBE: 8.1405 - for(i = 0;i < numCaptureDevNames;++i) 8.1406 - { 8.1407 - free(allCaptureDevNameMap[i].name); 8.1408 - free(allCaptureDevNameMap[i].device_name); 8.1409 - } 8.1410 - free(allCaptureDevNameMap); 8.1411 - allCaptureDevNameMap = NULL; 8.1412 - numCaptureDevNames = 0; 8.1413 - 8.1414 - probe_devices(AL_TRUE); 8.1415 - 8.1416 - for(i = 0;i < numCaptureDevNames;i++) 8.1417 - AppendCaptureDeviceList(allCaptureDevNameMap[i].name); 8.1418 - break; 8.1419 - } 8.1420 -} //}}} 8.1421 -//}}}
9.1 --- a/Alc/backends/sndio.c Tue Oct 25 13:03:35 2011 -0700 9.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 9.3 @@ -1,381 +0,0 @@ 9.4 -/** 9.5 - * OpenAL cross platform audio library 9.6 - * Copyright (C) 1999-2007 by authors. 9.7 - * This library is free software; you can redistribute it and/or 9.8 - * modify it under the terms of the GNU Library General Public 9.9 - * License as published by the Free Software Foundation; either 9.10 - * version 2 of the License, or (at your option) any later version. 9.11 - * 9.12 - * This library is distributed in the hope that it will be useful, 9.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 9.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 9.15 - * Library General Public License for more details. 9.16 - * 9.17 - * You should have received a copy of the GNU Library General Public 9.18 - * License along with this library; if not, write to the 9.19 - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 9.20 - * Boston, MA 02111-1307, USA. 9.21 - * Or go to http://www.gnu.org/copyleft/lgpl.html 9.22 - */ 9.23 - 9.24 -#include "config.h" 9.25 - 9.26 -#include <stdio.h> 9.27 -#include <stdlib.h> 9.28 -#include <string.h> 9.29 -#include "alMain.h" 9.30 -#include "AL/al.h" 9.31 -#include "AL/alc.h" 9.32 - 9.33 -#include <sndio.h> 9.34 - 9.35 - 9.36 -static const ALCchar sndio_device[] = "SndIO Default"; 9.37 - 9.38 - 9.39 -static void *sndio_handle; 9.40 -#ifdef HAVE_DYNLOAD 9.41 -#define MAKE_FUNC(x) static typeof(x) * p##x 9.42 -MAKE_FUNC(sio_initpar); 9.43 -MAKE_FUNC(sio_open); 9.44 -MAKE_FUNC(sio_close); 9.45 -MAKE_FUNC(sio_setpar); 9.46 -MAKE_FUNC(sio_getpar); 9.47 -MAKE_FUNC(sio_getcap); 9.48 -MAKE_FUNC(sio_onmove); 9.49 -MAKE_FUNC(sio_write); 9.50 -MAKE_FUNC(sio_read); 9.51 -MAKE_FUNC(sio_start); 9.52 -MAKE_FUNC(sio_stop); 9.53 -MAKE_FUNC(sio_nfds); 9.54 -MAKE_FUNC(sio_pollfd); 9.55 -MAKE_FUNC(sio_revents); 9.56 -MAKE_FUNC(sio_eof); 9.57 -MAKE_FUNC(sio_setvol); 9.58 -MAKE_FUNC(sio_onvol); 9.59 - 9.60 -#define sio_initpar psio_initpar 9.61 -#define sio_open psio_open 9.62 -#define sio_close psio_close 9.63 -#define sio_setpar psio_setpar 9.64 -#define sio_getpar psio_getpar 9.65 -#define sio_getcap psio_getcap 9.66 -#define sio_onmove psio_onmove 9.67 -#define sio_write psio_write 9.68 -#define sio_read psio_read 9.69 -#define sio_start psio_start 9.70 -#define sio_stop psio_stop 9.71 -#define sio_nfds psio_nfds 9.72 -#define sio_pollfd psio_pollfd 9.73 -#define sio_revents psio_revents 9.74 -#define sio_eof psio_eof 9.75 -#define sio_setvol psio_setvol 9.76 -#define sio_onvol psio_onvol 9.77 -#endif 9.78 - 9.79 - 9.80 -static ALCboolean sndio_load(void) 9.81 -{ 9.82 - if(!sndio_handle) 9.83 - { 9.84 -#ifdef HAVE_DYNLOAD 9.85 - sndio_handle = LoadLib("libsndio.so"); 9.86 - if(!sndio_handle) 9.87 - return ALC_FALSE; 9.88 - 9.89 -#define LOAD_FUNC(f) do { \ 9.90 - p##f = GetSymbol(sndio_handle, #f); \ 9.91 - if(p##f == NULL) { \ 9.92 - CloseLib(sndio_handle); \ 9.93 - sndio_handle = NULL; \ 9.94 - return ALC_FALSE; \ 9.95 - } \ 9.96 -} while(0) 9.97 - LOAD_FUNC(sio_initpar); 9.98 - LOAD_FUNC(sio_open); 9.99 - LOAD_FUNC(sio_close); 9.100 - LOAD_FUNC(sio_setpar); 9.101 - LOAD_FUNC(sio_getpar); 9.102 - LOAD_FUNC(sio_getcap); 9.103 - LOAD_FUNC(sio_onmove); 9.104 - LOAD_FUNC(sio_write); 9.105 - LOAD_FUNC(sio_read); 9.106 - LOAD_FUNC(sio_start); 9.107 - LOAD_FUNC(sio_stop); 9.108 - LOAD_FUNC(sio_nfds); 9.109 - LOAD_FUNC(sio_pollfd); 9.110 - LOAD_FUNC(sio_revents); 9.111 - LOAD_FUNC(sio_eof); 9.112 - LOAD_FUNC(sio_setvol); 9.113 - LOAD_FUNC(sio_onvol); 9.114 -#undef LOAD_FUNC 9.115 -#else 9.116 - sndio_handle = (void*)0xDEADBEEF; 9.117 -#endif 9.118 - } 9.119 - return ALC_TRUE; 9.120 -} 9.121 - 9.122 - 9.123 -typedef struct { 9.124 - struct sio_hdl *sndHandle; 9.125 - 9.126 - ALvoid *mix_data; 9.127 - ALsizei data_size; 9.128 - 9.129 - volatile int killNow; 9.130 - ALvoid *thread; 9.131 -} sndio_data; 9.132 - 9.133 - 9.134 -static ALuint sndio_proc(ALvoid *ptr) 9.135 -{ 9.136 - ALCdevice *device = ptr; 9.137 - sndio_data *data = device->ExtraData; 9.138 - ALsizei frameSize; 9.139 - size_t wrote; 9.140 - 9.141 - SetRTPriority(); 9.142 - 9.143 - frameSize = FrameSizeFromDevFmt(device->FmtChans, device->FmtType); 9.144 - 9.145 - while(!data->killNow && device->Connected) 9.146 - { 9.147 - ALsizei len = data->data_size; 9.148 - ALubyte *WritePtr = data->mix_data; 9.149 - 9.150 - aluMixData(device, WritePtr, len/frameSize); 9.151 - while(len > 0 && !data->killNow) 9.152 - { 9.153 - wrote = sio_write(data->sndHandle, WritePtr, len); 9.154 - if(wrote == 0) 9.155 - { 9.156 - ERR("sio_write failed\n"); 9.157 - aluHandleDisconnect(device); 9.158 - break; 9.159 - } 9.160 - 9.161 - len -= wrote; 9.162 - WritePtr += wrote; 9.163 - } 9.164 - } 9.165 - 9.166 - return 0; 9.167 -} 9.168 - 9.169 - 9.170 - 9.171 -static ALCboolean sndio_open_playback(ALCdevice *device, const ALCchar *deviceName) 9.172 -{ 9.173 - sndio_data *data; 9.174 - 9.175 - if(!deviceName) 9.176 - deviceName = sndio_device; 9.177 - else if(strcmp(deviceName, sndio_device) != 0) 9.178 - return ALC_FALSE; 9.179 - 9.180 - data = calloc(1, sizeof(*data)); 9.181 - data->killNow = 0; 9.182 - 9.183 - data->sndHandle = sio_open(NULL, SIO_PLAY, 0); 9.184 - if(data->sndHandle == NULL) 9.185 - { 9.186 - free(data); 9.187 - ERR("Could not open device\n"); 9.188 - return ALC_FALSE; 9.189 - } 9.190 - 9.191 - device->szDeviceName = strdup(deviceName); 9.192 - device->ExtraData = data; 9.193 - 9.194 - return ALC_TRUE; 9.195 -} 9.196 - 9.197 -static void sndio_close_playback(ALCdevice *device) 9.198 -{ 9.199 - sndio_data *data = device->ExtraData; 9.200 - 9.201 - sio_close(data->sndHandle); 9.202 - free(data); 9.203 - device->ExtraData = NULL; 9.204 -} 9.205 - 9.206 -static ALCboolean sndio_reset_playback(ALCdevice *device) 9.207 -{ 9.208 - sndio_data *data = device->ExtraData; 9.209 - struct sio_par par; 9.210 - 9.211 - sio_initpar(&par); 9.212 - 9.213 - par.rate = device->Frequency; 9.214 - 9.215 - par.pchan = ((device->FmtChans != DevFmtMono) ? 2 : 1); 9.216 - 9.217 - switch(device->FmtType) 9.218 - { 9.219 - case DevFmtByte: 9.220 - par.bits = 8; 9.221 - par.sig = 1; 9.222 - break; 9.223 - case DevFmtUByte: 9.224 - par.bits = 8; 9.225 - par.sig = 0; 9.226 - break; 9.227 - case DevFmtFloat: 9.228 - device->FmtType = DevFmtShort; 9.229 - /* fall-through */ 9.230 - case DevFmtShort: 9.231 - par.bits = 16; 9.232 - par.sig = 1; 9.233 - break; 9.234 - case DevFmtUShort: 9.235 - par.bits = 16; 9.236 - par.sig = 0; 9.237 - break; 9.238 - } 9.239 - par.le = SIO_LE_NATIVE; 9.240 - 9.241 - par.round = device->UpdateSize; 9.242 - par.appbufsz = device->UpdateSize * (device->NumUpdates-1); 9.243 - if(!par.appbufsz) par.appbufsz = device->UpdateSize; 9.244 - 9.245 - 9.246 - if(!sio_setpar(data->sndHandle, &par) || !sio_getpar(data->sndHandle, &par)) 9.247 - { 9.248 - ERR("Failed to set device parameters\n"); 9.249 - return ALC_FALSE; 9.250 - } 9.251 - 9.252 - if(par.rate != device->Frequency) 9.253 - { 9.254 - if((device->Flags&DEVICE_FREQUENCY_REQUEST)) 9.255 - ERR("Failed to set frequency %uhz, got %uhz instead\n", device->Frequency, par.rate); 9.256 - device->Flags &= ~DEVICE_FREQUENCY_REQUEST; 9.257 - device->Frequency = par.rate; 9.258 - } 9.259 - 9.260 - if(par.pchan != ChannelsFromDevFmt(device->FmtChans)) 9.261 - { 9.262 - if(par.pchan != 1 && par.pchan != 2) 9.263 - { 9.264 - ERR("Unhandled channel count: %u\n", par.pchan); 9.265 - return ALC_FALSE; 9.266 - } 9.267 - if((device->Flags&DEVICE_CHANNELS_REQUEST)) 9.268 - ERR("Failed to set %s, got %u channels instead\n", DevFmtChannelsString(device->FmtChans), par.pchan); 9.269 - device->Flags &= ~DEVICE_CHANNELS_REQUEST; 9.270 - device->FmtChans = ((par.pchan==1) ? DevFmtMono : DevFmtStereo); 9.271 - } 9.272 - 9.273 - if(par.bits != par.bps*8) 9.274 - { 9.275 - ERR("Padded samples not supported (%u of %u bits)\n", par.bits, par.bps*8); 9.276 - return ALC_FALSE; 9.277 - } 9.278 - 9.279 - if(par.bits == 8 && par.sig == 1) 9.280 - device->FmtType = DevFmtByte; 9.281 - else if(par.bits == 8 && par.sig == 0) 9.282 - device->FmtType = DevFmtUByte; 9.283 - else if(par.bits == 16 && par.sig == 1) 9.284 - device->FmtType = DevFmtShort; 9.285 - else if(par.bits == 16 && par.sig == 0) 9.286 - device->FmtType = DevFmtUShort; 9.287 - else 9.288 - { 9.289 - ERR("Unhandled sample format: %s %u-bit\n", (par.sig?"signed":"unsigned"), par.bits); 9.290 - return ALC_FALSE; 9.291 - } 9.292 - 9.293 - 9.294 - device->UpdateSize = par.round; 9.295 - device->NumUpdates = (par.bufsz/par.round) + 1; 9.296 - 9.297 - SetDefaultChannelOrder(device); 9.298 - 9.299 - 9.300 - if(!sio_start(data->sndHandle)) 9.301 - { 9.302 - ERR("Error starting playback\n"); 9.303 - return ALC_FALSE; 9.304 - } 9.305 - 9.306 - data->data_size = device->UpdateSize * par.bps * par.pchan; 9.307 - data->mix_data = calloc(1, data->data_size); 9.308 - 9.309 - data->thread = StartThread(sndio_proc, device); 9.310 - if(data->thread == NULL) 9.311 - { 9.312 - sio_stop(data->sndHandle); 9.313 - free(data->mix_data); 9.314 - data->mix_data = NULL; 9.315 - return ALC_FALSE; 9.316 - } 9.317 - 9.318 - return ALC_TRUE; 9.319 -} 9.320 - 9.321 -static void sndio_stop_playback(ALCdevice *device) 9.322 -{ 9.323 - sndio_data *data = device->ExtraData; 9.324 - 9.325 - if(!data->thread) 9.326 - return; 9.327 - 9.328 - data->killNow = 1; 9.329 - StopThread(data->thread); 9.330 - data->thread = NULL; 9.331 - 9.332 - data->killNow = 0; 9.333 - if(!sio_stop(data->sndHandle)) 9.334 - ERR("Error stopping device\n"); 9.335 - 9.336 - free(data->mix_data); 9.337 - data->mix_data = NULL; 9.338 -} 9.339 - 9.340 - 9.341 -static const BackendFuncs sndio_funcs = { 9.342 - sndio_open_playback, 9.343 - sndio_close_playback, 9.344 - sndio_reset_playback, 9.345 - sndio_stop_playback, 9.346 - NULL, 9.347 - NULL, 9.348 - NULL, 9.349 - NULL, 9.350 - NULL, 9.351 - NULL 9.352 -}; 9.353 - 9.354 -ALCboolean alc_sndio_init(BackendFuncs *func_list) 9.355 -{ 9.356 - if(!sndio_load()) 9.357 - return ALC_FALSE; 9.358 - *func_list = sndio_funcs; 9.359 - return ALC_TRUE; 9.360 -} 9.361 - 9.362 -void alc_sndio_deinit(void) 9.363 -{ 9.364 -#ifdef HAVE_DYNLOAD 9.365 - if(sndio_handle) 9.366 - CloseLib(sndio_handle); 9.367 - sndio_handle = NULL; 9.368 -#endif 9.369 -} 9.370 - 9.371 -void alc_sndio_probe(enum DevProbe type) 9.372 -{ 9.373 - switch(type) 9.374 - { 9.375 - case DEVICE_PROBE: 9.376 - AppendDeviceList(sndio_device); 9.377 - break; 9.378 - case ALL_DEVICE_PROBE: 9.379 - AppendAllDeviceList(sndio_device); 9.380 - break; 9.381 - case CAPTURE_DEVICE_PROBE: 9.382 - break; 9.383 - } 9.384 -}
10.1 --- a/Alc/backends/solaris.c Tue Oct 25 13:03:35 2011 -0700 10.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 10.3 @@ -1,282 +0,0 @@ 10.4 -/** 10.5 - * OpenAL cross platform audio library 10.6 - * Copyright (C) 1999-2007 by authors. 10.7 - * This library is free software; you can redistribute it and/or 10.8 - * modify it under the terms of the GNU Library General Public 10.9 - * License as published by the Free Software Foundation; either 10.10 - * version 2 of the License, or (at your option) any later version. 10.11 - * 10.12 - * This library is distributed in the hope that it will be useful, 10.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 10.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10.15 - * Library General Public License for more details. 10.16 - * 10.17 - * You should have received a copy of the GNU Library General Public 10.18 - * License along with this library; if not, write to the 10.19 - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 10.20 - * Boston, MA 02111-1307, USA. 10.21 - * Or go to http://www.gnu.org/copyleft/lgpl.html 10.22 - */ 10.23 - 10.24 -#include "config.h" 10.25 - 10.26 -#include <sys/ioctl.h> 10.27 -#include <sys/types.h> 10.28 -#include <sys/stat.h> 10.29 -#include <fcntl.h> 10.30 -#include <stdlib.h> 10.31 -#include <stdio.h> 10.32 -#include <memory.h> 10.33 -#include <unistd.h> 10.34 -#include <errno.h> 10.35 -#include <math.h> 10.36 -#include "alMain.h" 10.37 -#include "AL/al.h" 10.38 -#include "AL/alc.h" 10.39 - 10.40 -#include <sys/audioio.h> 10.41 - 10.42 - 10.43 -static const ALCchar solaris_device[] = "Solaris Default"; 10.44 - 10.45 -typedef struct { 10.46 - int fd; 10.47 - volatile int killNow; 10.48 - ALvoid *thread; 10.49 - 10.50 - ALubyte *mix_data; 10.51 - int data_size; 10.52 -} solaris_data; 10.53 - 10.54 - 10.55 -static ALuint SolarisProc(ALvoid *ptr) 10.56 -{ 10.57 - ALCdevice *pDevice = (ALCdevice*)ptr; 10.58 - solaris_data *data = (solaris_data*)pDevice->ExtraData; 10.59 - ALint frameSize; 10.60 - int wrote; 10.61 - 10.62 - SetRTPriority(); 10.63 - 10.64 - frameSize = FrameSizeFromDevFmt(pDevice->FmtChans, pDevice->FmtType); 10.65 - 10.66 - while(!data->killNow && pDevice->Connected) 10.67 - { 10.68 - ALint len = data->data_size; 10.69 - ALubyte *WritePtr = data->mix_data; 10.70 - 10.71 - aluMixData(pDevice, WritePtr, len/frameSize); 10.72 - while(len > 0 && !data->killNow) 10.73 - { 10.74 - wrote = write(data->fd, WritePtr, len); 10.75 - if(wrote < 0) 10.76 - { 10.77 - if(errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR) 10.78 - { 10.79 - ERR("write failed: %s\n", strerror(errno)); 10.80 - aluHandleDisconnect(pDevice); 10.81 - break; 10.82 - } 10.83 - 10.84 - Sleep(1); 10.85 - continue; 10.86 - } 10.87 - 10.88 - len -= wrote; 10.89 - WritePtr += wrote; 10.90 - } 10.91 - } 10.92 - 10.93 - return 0; 10.94 -} 10.95 - 10.96 - 10.97 -static ALCboolean solaris_open_playback(ALCdevice *device, const ALCchar *deviceName) 10.98 -{ 10.99 - char driver[64]; 10.100 - solaris_data *data; 10.101 - 10.102 - strncpy(driver, GetConfigValue("solaris", "device", "/dev/audio"), sizeof(driver)-1); 10.103 - driver[sizeof(driver)-1] = 0; 10.104 - 10.105 - if(!deviceName) 10.106 - deviceName = solaris_device; 10.107 - else if(strcmp(deviceName, solaris_device) != 0) 10.108 - return ALC_FALSE; 10.109 - 10.110 - data = (solaris_data*)calloc(1, sizeof(solaris_data)); 10.111 - data->killNow = 0; 10.112 - 10.113 - data->fd = open(driver, O_WRONLY); 10.114 - if(data->fd == -1) 10.115 - { 10.116 - free(data); 10.117 - ERR("Could not open %s: %s\n", driver, strerror(errno)); 10.118 - return ALC_FALSE; 10.119 - } 10.120 - 10.121 - device->szDeviceName = strdup(deviceName); 10.122 - device->ExtraData = data; 10.123 - return ALC_TRUE; 10.124 -} 10.125 - 10.126 -static void solaris_close_playback(ALCdevice *device) 10.127 -{ 10.128 - solaris_data *data = (solaris_data*)device->ExtraData; 10.129 - 10.130 - close(data->fd); 10.131 - free(data); 10.132 - device->ExtraData = NULL; 10.133 -} 10.134 - 10.135 -static ALCboolean solaris_reset_playback(ALCdevice *device) 10.136 -{ 10.137 - solaris_data *data = (solaris_data*)device->ExtraData; 10.138 - audio_info_t info; 10.139 - ALuint frameSize; 10.140 - int numChannels; 10.141 - 10.142 - AUDIO_INITINFO(&info); 10.143 - 10.144 - info.play.sample_rate = device->Frequency; 10.145 - 10.146 - if(device->FmtChans != DevFmtMono) 10.147 - device->FmtChans = DevFmtStereo; 10.148 - numChannels = ChannelsFromDevFmt(device->FmtChans); 10.149 - info.play.channels = numChannels; 10.150 - 10.151 - switch(device->FmtType) 10.152 - { 10.153 - case DevFmtByte: 10.154 - info.play.precision = 8; 10.155 - info.play.encoding = AUDIO_ENCODING_LINEAR; 10.156 - break; 10.157 - case DevFmtUByte: 10.158 - info.play.precision = 8; 10.159 - info.play.encoding = AUDIO_ENCODING_LINEAR8; 10.160 - break; 10.161 - case DevFmtUShort: 10.162 - case DevFmtFloat: 10.163 - device->FmtType = DevFmtShort; 10.164 - /* fall-through */ 10.165 - case DevFmtShort: 10.166 - info.play.precision = 16; 10.167 - info.play.encoding = AUDIO_ENCODING_LINEAR; 10.168 - break; 10.169 - } 10.170 - 10.171 - frameSize = numChannels * BytesFromDevFmt(device->FmtType); 10.172 - info.play.buffer_size = device->UpdateSize*device->NumUpdates * frameSize; 10.173 - 10.174 - if(ioctl(data->fd, AUDIO_SETINFO, &info) < 0) 10.175 - { 10.176 - ERR("ioctl failed: %s\n", strerror(errno)); 10.177 - return ALC_FALSE; 10.178 - } 10.179 - 10.180 - if(ChannelsFromDevFmt(device->FmtChans) != info.play.channels) 10.181 - { 10.182 - ERR("Could not set %d channels, got %d instead\n", ChannelsFromDevFmt(device->FmtChans), info.play.channels); 10.183 - return ALC_FALSE; 10.184 - } 10.185 - 10.186 - if(!((info.play.precision == 8 && info.play.encoding == AUDIO_ENCODING_LINEAR && 10.187 - device->FmtType == DevFmtByte) || 10.188 - (info.play.precision == 8 && info.play.encoding == AUDIO_ENCODING_LINEAR8 && 10.189 - device->FmtType == DevFmtUByte) || 10.190 - (info.play.precision == 16 && info.play.encoding == AUDIO_ENCODING_LINEAR && 10.191 - device->FmtType == DevFmtShort))) 10.192 - { 10.193 - ERR("Could not set %#x sample type, got %d (%#x)\n", 10.194 - device->FmtType, info.play.precision, info.play.encoding); 10.195 - return ALC_FALSE; 10.196 - } 10.197 - 10.198 - if(device->Frequency != info.play.sample_rate) 10.199 - { 10.200 - if((device->Flags&DEVICE_FREQUENCY_REQUEST)) 10.201 - ERR("Failed to set requested frequency %dhz, got %dhz instead\n", device->Frequency, info.play.sample_rate); 10.202 - device->Flags &= ~DEVICE_FREQUENCY_REQUEST; 10.203 - device->Frequency = info.play.sample_rate; 10.204 - } 10.205 - device->UpdateSize = (info.play.buffer_size/device->NumUpdates) + 1; 10.206 - 10.207 - data->data_size = device->UpdateSize * frameSize; 10.208 - data->mix_data = calloc(1, data->data_size); 10.209 - 10.210 - SetDefaultChannelOrder(device); 10.211 - 10.212 - data->thread = StartThread(SolarisProc, device); 10.213 - if(data->thread == NULL) 10.214 - { 10.215 - free(data->mix_data); 10.216 - data->mix_data = NULL; 10.217 - return ALC_FALSE; 10.218 - } 10.219 - 10.220 - return ALC_TRUE; 10.221 -} 10.222 - 10.223 -static void solaris_stop_playback(ALCdevice *device) 10.224 -{ 10.225 - solaris_data *data = (solaris_data*)device->ExtraData; 10.226 - 10.227 - if(!data->thread) 10.228 - return; 10.229 - 10.230 - data->killNow = 1; 10.231 - StopThread(data->thread); 10.232 - data->thread = NULL; 10.233 - 10.234 - data->killNow = 0; 10.235 - if(ioctl(data->fd, AUDIO_DRAIN) < 0) 10.236 - ERR("Error draining device: %s\n", strerror(errno)); 10.237 - 10.238 - free(data->mix_data); 10.239 - data->mix_data = NULL; 10.240 -} 10.241 - 10.242 - 10.243 -static const BackendFuncs solaris_funcs = { 10.244 - solaris_open_playback, 10.245 - solaris_close_playback, 10.246 - solaris_reset_playback, 10.247 - solaris_stop_playback, 10.248 - NULL, 10.249 - NULL, 10.250 - NULL, 10.251 - NULL, 10.252 - NULL, 10.253 - NULL 10.254 -}; 10.255 - 10.256 -ALCboolean alc_solaris_init(BackendFuncs *func_list) 10.257 -{ 10.258 - *func_list = solaris_funcs; 10.259 - return ALC_TRUE; 10.260 -} 10.261 - 10.262 -void alc_solaris_deinit(void) 10.263 -{ 10.264 -} 10.265 - 10.266 -void alc_solaris_probe(enum DevProbe type) 10.267 -{ 10.268 -#ifdef HAVE_STAT 10.269 - struct stat buf; 10.270 - if(stat(GetConfigValue("solaris", "device", "/dev/audio"), &buf) != 0) 10.271 - return; 10.272 -#endif 10.273 - 10.274 - switch(type) 10.275 - { 10.276 - case DEVICE_PROBE: 10.277 - AppendDeviceList(solaris_device); 10.278 - break; 10.279 - case ALL_DEVICE_PROBE: 10.280 - AppendAllDeviceList(solaris_device); 10.281 - break; 10.282 - case CAPTURE_DEVICE_PROBE: 10.283 - break; 10.284 - } 10.285 -}
11.1 --- a/Alc/backends/wave.c Tue Oct 25 13:03:35 2011 -0700 11.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 11.3 @@ -1,357 +0,0 @@ 11.4 -/** 11.5 - * OpenAL cross platform audio library 11.6 - * Copyright (C) 1999-2007 by authors. 11.7 - * This library is free software; you can redistribute it and/or 11.8 - * modify it under the terms of the GNU Library General Public 11.9 - * License as published by the Free Software Foundation; either 11.10 - * version 2 of the License, or (at your option) any later version. 11.11 - * 11.12 - * This library is distributed in the hope that it will be useful, 11.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 11.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11.15 - * Library General Public License for more details. 11.16 - * 11.17 - * You should have received a copy of the GNU Library General Public 11.18 - * License along with this library; if not, write to the 11.19 - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 11.20 - * Boston, MA 02111-1307, USA. 11.21 - * Or go to http://www.gnu.org/copyleft/lgpl.html 11.22 - */ 11.23 - 11.24 -#include "config.h" 11.25 - 11.26 -#include <stdlib.h> 11.27 -#include <stdio.h> 11.28 -#include <memory.h> 11.29 -#include "alMain.h" 11.30 -#include "AL/al.h" 11.31 -#include "AL/alc.h" 11.32 - 11.33 - 11.34 -typedef struct { 11.35 - FILE *f; 11.36 - long DataStart; 11.37 - 11.38 - ALvoid *buffer; 11.39 - ALuint size; 11.40 - 11.41 - volatile int killNow; 11.42 - ALvoid *thread; 11.43 -} wave_data; 11.44 - 11.45 - 11.46 -static const ALCchar waveDevice[] = "Wave File Writer"; 11.47 - 11.48 -static const ALubyte SUBTYPE_PCM[] = { 11.49 - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xaa, 11.50 - 0x00, 0x38, 0x9b, 0x71 11.51 -}; 11.52 -static const ALubyte SUBTYPE_FLOAT[] = { 11.53 - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xaa, 11.54 - 0x00, 0x38, 0x9b, 0x71 11.55 -}; 11.56 - 11.57 -static const ALuint channel_masks[] = { 11.58 - 0, /* invalid */ 11.59 - 0x4, /* Mono */ 11.60 - 0x1 | 0x2, /* Stereo */ 11.61 - 0, /* 3 channel */ 11.62 - 0x1 | 0x2 | 0x10 | 0x20, /* Quad */ 11.63 - 0, /* 5 channel */ 11.64 - 0x1 | 0x2 | 0x4 | 0x8 | 0x10 | 0x20, /* 5.1 */ 11.65 - 0x1 | 0x2 | 0x4 | 0x8 | 0x100 | 0x200 | 0x400, /* 6.1 */ 11.66 - 0x1 | 0x2 | 0x4 | 0x8 | 0x10 | 0x20 | 0x200 | 0x400, /* 7.1 */ 11.67 -}; 11.68 - 11.69 - 11.70 -static void fwrite16le(ALushort val, FILE *f) 11.71 -{ 11.72 - fputc(val&0xff, f); 11.73 - fputc((val>>8)&0xff, f); 11.74 -} 11.75 - 11.76 -static void fwrite32le(ALuint val, FILE *f) 11.77 -{ 11.78 - fputc(val&0xff, f); 11.79 - fputc((val>>8)&0xff, f); 11.80 - fputc((val>>16)&0xff, f); 11.81 - fputc((val>>24)&0xff, f); 11.82 -} 11.83 - 11.84 - 11.85 -static ALuint WaveProc(ALvoid *ptr) 11.86 -{ 11.87 - ALCdevice *pDevice = (ALCdevice*)ptr; 11.88 - wave_data *data = (wave_data*)pDevice->ExtraData; 11.89 - ALuint frameSize; 11.90 - ALuint now, start; 11.91 - ALuint64 avail, done; 11.92 - size_t fs; 11.93 - union { 11.94 - short s; 11.95 - char b[sizeof(short)]; 11.96 - } uSB; 11.97 - const ALuint restTime = (ALuint64)pDevice->UpdateSize * 1000 / 11.98 - pDevice->Frequency / 2; 11.99 - 11.100 - uSB.s = 1; 11.101 - frameSize = FrameSizeFromDevFmt(pDevice->FmtChans, pDevice->FmtType); 11.102 - 11.103 - done = 0; 11.104 - start = timeGetTime(); 11.105 - while(!data->killNow && pDevice->Connected) 11.106 - { 11.107 - now = timeGetTime(); 11.108 - 11.109 - avail = (ALuint64)(now-start) * pDevice->Frequency / 1000; 11.110 - if(avail < done) 11.111 - { 11.112 - /* Timer wrapped. Add the remainder of the cycle to the available 11.113 - * count and reset the number of samples done */ 11.114 - avail += (ALuint64)0xFFFFFFFFu*pDevice->Frequency/1000 - done; 11.115 - done = 0; 11.116 - } 11.117 - if(avail-done < pDevice->UpdateSize) 11.118 - { 11.119 - Sleep(restTime); 11.120 - continue; 11.121 - } 11.122 - 11.123 - while(avail-done >= pDevice->UpdateSize) 11.124 - { 11.125 - aluMixData(pDevice, data->buffer, pDevice->UpdateSize); 11.126 - done += pDevice->UpdateSize; 11.127 - 11.128 - if(uSB.b[0] != 1) 11.129 - { 11.130 - ALuint bytesize = BytesFromDevFmt(pDevice->FmtType); 11.131 - ALubyte *bytes = data->buffer; 11.132 - ALuint i; 11.133 - 11.134 - if(bytesize == 1) 11.135 - { 11.136 - for(i = 0;i < data->size;i++) 11.137 - fputc(bytes[i], data->f); 11.138 - } 11.139 - else if(bytesize == 2) 11.140 - { 11.141 - for(i = 0;i < data->size;i++) 11.142 - fputc(bytes[i^1], data->f); 11.143 - } 11.144 - else if(bytesize == 4) 11.145 - { 11.146 - for(i = 0;i < data->size;i++) 11.147 - fputc(bytes[i^3], data->f); 11.148 - } 11.149 - } 11.150 - else 11.151 - fs = fwrite(data->buffer, frameSize, pDevice->UpdateSize, 11.152 - data->f); 11.153 - if(ferror(data->f)) 11.154 - { 11.155 - ERR("Error writing to file\n"); 11.156 - aluHandleDisconnect(pDevice); 11.157 - break; 11.158 - } 11.159 - } 11.160 - } 11.161 - 11.162 - return 0; 11.163 -} 11.164 - 11.165 -static ALCboolean wave_open_playback(ALCdevice *device, const ALCchar *deviceName) 11.166 -{ 11.167 - wave_data *data; 11.168 - const char *fname; 11.169 - 11.170 - fname = GetConfigValue("wave", "file", ""); 11.171 - if(!fname[0]) 11.172 - return ALC_FALSE; 11.173 - 11.174 - if(!deviceName) 11.175 - deviceName = waveDevice; 11.176 - else if(strcmp(deviceName, waveDevice) != 0) 11.177 - return ALC_FALSE; 11.178 - 11.179 - data = (wave_data*)calloc(1, sizeof(wave_data)); 11.180 - 11.181 - data->f = fopen(fname, "wb"); 11.182 - if(!data->f) 11.183 - { 11.184 - free(data); 11.185 - ERR("Could not open file '%s': %s\n", fname, strerror(errno)); 11.186 - return ALC_FALSE; 11.187 - } 11.188 - 11.189 - device->szDeviceName = strdup(deviceName); 11.190 - device->ExtraData = data; 11.191 - return ALC_TRUE; 11.192 -} 11.193 - 11.194 -static void wave_close_playback(ALCdevice *device) 11.195 -{ 11.196 - wave_data *data = (wave_data*)device->ExtraData; 11.197 - 11.198 - fclose(data->f); 11.199 - free(data); 11.200 - device->ExtraData = NULL; 11.201 -} 11.202 - 11.203 -static ALCboolean wave_reset_playback(ALCdevice *device) 11.204 -{ 11.205 - wave_data *data = (wave_data*)device->ExtraData; 11.206 - ALuint channels=0, bits=0; 11.207 - size_t val; 11.208 - 11.209 - fseek(data->f, 0, SEEK_SET); 11.210 - clearerr(data->f); 11.211 - 11.212 - switch(device->FmtType) 11.213 - { 11.214 - case DevFmtByte: 11.215 - device->FmtType = DevFmtUByte; 11.216 - break; 11.217 - case DevFmtUShort: 11.218 - device->FmtType = DevFmtShort; 11.219 - break; 11.220 - case DevFmtUByte: 11.221 - case DevFmtShort: 11.222 - case DevFmtFloat: 11.223 - break; 11.224 - } 11.225 - bits = BytesFromDevFmt(device->FmtType) * 8; 11.226 - channels = ChannelsFromDevFmt(device->FmtChans); 11.227 - 11.228 - fprintf(data->f, "RIFF"); 11.229 - fwrite32le(0xFFFFFFFF, data->f); // 'RIFF' header len; filled in at close 11.230 - 11.231 - fprintf(data->f, "WAVE"); 11.232 - 11.233 - fprintf(data->f, "fmt "); 11.234 - fwrite32le(40, data->f); // 'fmt ' header len; 40 bytes for EXTENSIBLE 11.235 - 11.236 - // 16-bit val, format type id (extensible: 0xFFFE) 11.237 - fwrite16le(0xFFFE, data->f); 11.238 - // 16-bit val, channel count 11.239 - fwrite16le(channels, data->f); 11.240 - // 32-bit val, frequency 11.241 - fwrite32le(device->Frequency, data->f); 11.242 - // 32-bit val, bytes per second 11.243 - fwrite32le(device->Frequency * channels * bits / 8, data->f); 11.244 - // 16-bit val, frame size 11.245 - fwrite16le(channels * bits / 8, data->f); 11.246 - // 16-bit val, bits per sample 11.247 - fwrite16le(bits, data->f); 11.248 - // 16-bit val, extra byte count 11.249 - fwrite16le(22, data->f); 11.250 - // 16-bit val, valid bits per sample 11.251 - fwrite16le(bits, data->f); 11.252 - // 32-bit val, channel mask 11.253 - fwrite32le(channel_masks[channels], data->f); 11.254 - // 16 byte GUID, sub-type format 11.255 - val = fwrite(((bits==32) ? SUBTYPE_FLOAT : SUBTYPE_PCM), 1, 16, data->f); 11.256 - 11.257 - fprintf(data->f, "data"); 11.258 - fwrite32le(0xFFFFFFFF, data->f); // 'data' header len; filled in at close 11.259 - 11.260 - if(ferror(data->f)) 11.261 - { 11.262 - ERR("Error writing header: %s\n", strerror(errno)); 11.263 - return ALC_FALSE; 11.264 - } 11.265 - 11.266 - data->DataStart = ftell(data->f); 11.267 - 11.268 - data->size = device->UpdateSize * channels * bits / 8; 11.269 - data->buffer = malloc(data->size); 11.270 - if(!data->buffer) 11.271 - { 11.272 - ERR("Buffer malloc failed\n"); 11.273 - return ALC_FALSE; 11.274 - } 11.275 - 11.276 - SetDefaultWFXChannelOrder(device); 11.277 - 11.278 - data->thread = StartThread(WaveProc, device); 11.279 - if(data->thread == NULL) 11.280 - { 11.281 - free(data->buffer); 11.282 - data->buffer = NULL; 11.283 - return ALC_FALSE; 11.284 - } 11.285 - 11.286 - return ALC_TRUE; 11.287 -} 11.288 - 11.289 -static void wave_stop_playback(ALCdevice *device) 11.290 -{ 11.291 - wave_data *data = (wave_data*)device->ExtraData; 11.292 - ALuint dataLen; 11.293 - long size; 11.294 - 11.295 - if(!data->thread) 11.296 - return; 11.297 - 11.298 - data->killNow = 1; 11.299 - StopThread(data->thread); 11.300 - data->thread = NULL; 11.301 - 11.302 - data->killNow = 0; 11.303 - 11.304 - free(data->buffer); 11.305 - data->buffer = NULL; 11.306 - 11.307 - size = ftell(data->f); 11.308 - if(size > 0) 11.309 - { 11.310 - dataLen = size - data->DataStart; 11.311 - if(fseek(data->f, data->DataStart-4, SEEK_SET) == 0) 11.312 - fwrite32le(dataLen, data->f); // 'data' header len 11.313 - if(fseek(data->f, 4, SEEK_SET) == 0) 11.314 - fwrite32le(size-8, data->f); // 'WAVE' header len 11.315 - } 11.316 -} 11.317 - 11.318 - 11.319 -static const BackendFuncs wave_funcs = { 11.320 - wave_open_playback, 11.321 - wave_close_playback, 11.322 - wave_reset_playback, 11.323 - wave_stop_playback, 11.324 - NULL, 11.325 - NULL, 11.326 - NULL, 11.327 - NULL, 11.328 - NULL, 11.329 - NULL 11.330 -}; 11.331 - 11.332 -ALCboolean alc_wave_init(BackendFuncs *func_list) 11.333 -{ 11.334 - *func_list = wave_funcs; 11.335 - printf("WAVE: I'm init!!\n"); 11.336 - return ALC_TRUE; 11.337 -} 11.338 - 11.339 -void alc_wave_deinit(void) 11.340 -{ 11.341 -} 11.342 - 11.343 -void alc_wave_probe(enum DevProbe type) 11.344 -{ 11.345 - printf("WAVE: I'm being probed :)\n"); 11.346 - if(!ConfigValueExists("wave", "file")) 11.347 - return; 11.348 - 11.349 - switch(type) 11.350 - { 11.351 - case DEVICE_PROBE: 11.352 - AppendDeviceList(waveDevice); 11.353 - break; 11.354 - case ALL_DEVICE_PROBE: 11.355 - AppendAllDeviceList(waveDevice); 11.356 - break; 11.357 - case CAPTURE_DEVICE_PROBE: 11.358 - break; 11.359 - } 11.360 -}
12.1 --- a/Alc/backends/winmm.c Tue Oct 25 13:03:35 2011 -0700 12.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 12.3 @@ -1,780 +0,0 @@ 12.4 -/** 12.5 - * OpenAL cross platform audio library 12.6 - * Copyright (C) 1999-2007 by authors. 12.7 - * This library is free software; you can redistribute it and/or 12.8 - * modify it under the terms of the GNU Library General Public 12.9 - * License as published by the Free Software Foundation; either 12.10 - * version 2 of the License, or (at your option) any later version. 12.11 - * 12.12 - * This library is distributed in the hope that it will be useful, 12.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 12.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12.15 - * Library General Public License for more details. 12.16 - * 12.17 - * You should have received a copy of the GNU Library General Public 12.18 - * License along with this library; if not, write to the 12.19 - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 12.20 - * Boston, MA 02111-1307, USA. 12.21 - * Or go to http://www.gnu.org/copyleft/lgpl.html 12.22 - */ 12.23 - 12.24 -#include "config.h" 12.25 - 12.26 -#define _WIN32_WINNT 0x0500 12.27 -#include <stdlib.h> 12.28 -#include <stdio.h> 12.29 -#include <memory.h> 12.30 - 12.31 -#include <windows.h> 12.32 -#include <mmsystem.h> 12.33 - 12.34 -#include "alMain.h" 12.35 -#include "AL/al.h" 12.36 -#include "AL/alc.h" 12.37 - 12.38 - 12.39 -typedef struct { 12.40 - // MMSYSTEM Device 12.41 - volatile ALboolean bWaveShutdown; 12.42 - HANDLE hWaveThreadEvent; 12.43 - HANDLE hWaveThread; 12.44 - DWORD ulWaveThreadID; 12.45 - LONG lWaveBuffersCommitted; 12.46 - WAVEHDR WaveBuffer[4]; 12.47 - 12.48 - union { 12.49 - HWAVEIN In; 12.50 - HWAVEOUT Out; 12.51 - } hWaveHandle; 12.52 - 12.53 - ALuint Frequency; 12.54 - 12.55 - RingBuffer *pRing; 12.56 -} WinMMData; 12.57 - 12.58 - 12.59 -static const ALCchar woDefault[] = "WaveOut Default"; 12.60 - 12.61 -static ALCchar **PlaybackDeviceList; 12.62 -static ALuint NumPlaybackDevices; 12.63 -static ALCchar **CaptureDeviceList; 12.64 -static ALuint NumCaptureDevices; 12.65 - 12.66 - 12.67 -static void ProbePlaybackDevices(void) 12.68 -{ 12.69 - ALuint i; 12.70 - 12.71 - for(i = 0;i < NumPlaybackDevices;i++) 12.72 - free(PlaybackDeviceList[i]); 12.73 - 12.74 - NumPlaybackDevices = waveOutGetNumDevs(); 12.75 - PlaybackDeviceList = realloc(PlaybackDeviceList, sizeof(ALCchar*) * NumPlaybackDevices); 12.76 - for(i = 0;i < NumPlaybackDevices;i++) 12.77 - { 12.78 - WAVEOUTCAPS WaveCaps; 12.79 - 12.80 - PlaybackDeviceList[i] = NULL; 12.81 - if(waveOutGetDevCaps(i, &WaveCaps, sizeof(WaveCaps)) == MMSYSERR_NOERROR) 12.82 - { 12.83 - char name[1024]; 12.84 - ALuint count, j; 12.85 - 12.86 - count = 0; 12.87 - do { 12.88 - if(count == 0) 12.89 - snprintf(name, sizeof(name), "%s", WaveCaps.szPname); 12.90 - else 12.91 - snprintf(name, sizeof(name), "%s #%d", WaveCaps.szPname, count+1); 12.92 - count++; 12.93 - 12.94 - for(j = 0;j < i;j++) 12.95 - { 12.96 - if(strcmp(name, PlaybackDeviceList[j]) == 0) 12.97 - break; 12.98 - } 12.99 - } while(j != i); 12.100 - 12.101 - PlaybackDeviceList[i] = strdup(name); 12.102 - } 12.103 - } 12.104 -} 12.105 - 12.106 -static void ProbeCaptureDevices(void) 12.107 -{ 12.108 - ALuint i; 12.109 - 12.110 - for(i = 0;i < NumCaptureDevices;i++) 12.111 - free(CaptureDeviceList[i]); 12.112 - 12.113 - NumCaptureDevices = waveInGetNumDevs(); 12.114 - CaptureDeviceList = realloc(CaptureDeviceList, sizeof(ALCchar*) * NumCaptureDevices); 12.115 - for(i = 0;i < NumCaptureDevices;i++) 12.116 - { 12.117 - WAVEINCAPS WaveInCaps; 12.118 - 12.119 - CaptureDeviceList[i] = NULL; 12.120 - if(waveInGetDevCaps(i, &WaveInCaps, sizeof(WAVEINCAPS)) == MMSYSERR_NOERROR) 12.121 - { 12.122 - char name[1024]; 12.123 - ALuint count, j; 12.124 - 12.125 - count = 0; 12.126 - do { 12.127 - if(count == 0) 12.128 - snprintf(name, sizeof(name), "%s", WaveInCaps.szPname); 12.129 - else 12.130 - snprintf(name, sizeof(name), "%s #%d", WaveInCaps.szPname, count+1); 12.131 - count++; 12.132 - 12.133 - for(j = 0;j < i;j++) 12.134 - { 12.135 - if(strcmp(name, CaptureDeviceList[j]) == 0) 12.136 - break; 12.137 - } 12.138 - } while(j != i); 12.139 - 12.140 - CaptureDeviceList[i] = strdup(name); 12.141 - } 12.142 - } 12.143 -} 12.144 - 12.145 - 12.146 -/* 12.147 - WaveOutProc 12.148 - 12.149 - Posts a message to 'PlaybackThreadProc' everytime a WaveOut Buffer is completed and 12.150 - returns to the application (for more data) 12.151 -*/ 12.152 -static void CALLBACK WaveOutProc(HWAVEOUT hDevice,UINT uMsg,DWORD_PTR dwInstance,DWORD_PTR dwParam1,DWORD_PTR dwParam2) 12.153 -{ 12.154 - ALCdevice *pDevice = (ALCdevice*)dwInstance; 12.155 - WinMMData *pData = pDevice->ExtraData; 12.156 - 12.157 - (void)hDevice; 12.158 - (void)dwParam2; 12.159 - 12.160 - if(uMsg != WOM_DONE) 12.161 - return; 12.162 - 12.163 - // Decrement number of buffers in use 12.164 - InterlockedDecrement(&pData->lWaveBuffersCommitted); 12.165 - 12.166 - if(pData->bWaveShutdown == AL_FALSE) 12.167 - { 12.168 - // Notify Wave Processor Thread that a Wave Header has returned 12.169 - PostThreadMessage(pData->ulWaveThreadID, uMsg, 0, dwParam1); 12.170 - } 12.171 - else 12.172 - { 12.173 - if(pData->lWaveBuffersCommitted == 0) 12.174 - { 12.175 - // Post 'Quit' Message to WaveOut Processor Thread 12.176 - PostThreadMessage(pData->ulWaveThreadID, WM_QUIT, 0, 0); 12.177 - } 12.178 - } 12.179 -} 12.180 - 12.181 -/* 12.182 - PlaybackThreadProc 12.183 - 12.184 - Used by "MMSYSTEM" Device. Called when a WaveOut buffer has used up its 12.185 - audio data. 12.186 -*/ 12.187 -static DWORD WINAPI PlaybackThreadProc(LPVOID lpParameter) 12.188 -{ 12.189 - ALCdevice *pDevice = (ALCdevice*)lpParameter; 12.190 - WinMMData *pData = pDevice->ExtraData; 12.191 - LPWAVEHDR pWaveHdr; 12.192 - ALuint FrameSize; 12.193 - MSG msg; 12.194 - 12.195 - FrameSize = FrameSizeFromDevFmt(pDevice->FmtChans, pDevice->FmtType); 12.196 - 12.197 - SetRTPriority(); 12.198 - 12.199 - while(GetMessage(&msg, NULL, 0, 0)) 12.200 - { 12.201 - if(msg.message != WOM_DONE || pData->bWaveShutdown) 12.202 - continue; 12.203 - 12.204 - pWaveHdr = ((LPWAVEHDR)msg.lParam); 12.205 - 12.206 - aluMixData(pDevice, pWaveHdr->lpData, pWaveHdr->dwBufferLength/FrameSize); 12.207 - 12.208 - // Send buffer back to play more data 12.209 - waveOutWrite(pData->hWaveHandle.Out, pWaveHdr, sizeof(WAVEHDR)); 12.210 - InterlockedIncrement(&pData->lWaveBuffersCommitted); 12.211 - } 12.212 - 12.213 - // Signal Wave Thread completed event 12.214 - if(pData->hWaveThreadEvent) 12.215 - SetEvent(pData->hWaveThreadEvent); 12.216 - 12.217 - ExitThread(0); 12.218 - 12.219 - return 0; 12.220 -} 12.221 - 12.222 -/* 12.223 - WaveInProc 12.224 - 12.225 - Posts a message to 'CaptureThreadProc' everytime a WaveIn Buffer is completed and 12.226 - returns to the application (with more data) 12.227 -*/ 12.228 -static void CALLBACK WaveInProc(HWAVEIN hDevice,UINT uMsg,DWORD_PTR dwInstance,DWORD_PTR dwParam1,DWORD_PTR dwParam2) 12.229 -{ 12.230 - ALCdevice *pDevice = (ALCdevice*)dwInstance; 12.231 - WinMMData *pData = pDevice->ExtraData; 12.232 - 12.233 - (void)hDevice; 12.234 - (void)dwParam2; 12.235 - 12.236 - if(uMsg != WIM_DATA) 12.237 - return; 12.238 - 12.239 - // Decrement number of buffers in use 12.240 - InterlockedDecrement(&pData->lWaveBuffersCommitted); 12.241 - 12.242 - if(pData->bWaveShutdown == AL_FALSE) 12.243 - { 12.244 - // Notify Wave Processor Thread that a Wave Header has returned 12.245 - PostThreadMessage(pData->ulWaveThreadID,uMsg,0,dwParam1); 12.246 - } 12.247 - else 12.248 - { 12.249 - if(pData->lWaveBuffersCommitted == 0) 12.250 - { 12.251 - // Post 'Quit' Message to WaveIn Processor Thread 12.252 - PostThreadMessage(pData->ulWaveThreadID,WM_QUIT,0,0); 12.253 - } 12.254 - } 12.255 -} 12.256 - 12.257 -/* 12.258 - CaptureThreadProc 12.259 - 12.260 - Used by "MMSYSTEM" Device. Called when a WaveIn buffer had been filled with new 12.261 - audio data. 12.262 -*/ 12.263 -static DWORD WINAPI CaptureThreadProc(LPVOID lpParameter) 12.264 -{ 12.265 - ALCdevice *pDevice = (ALCdevice*)lpParameter; 12.266 - WinMMData *pData = pDevice->ExtraData; 12.267 - LPWAVEHDR pWaveHdr; 12.268 - ALuint FrameSize; 12.269 - MSG msg; 12.270 - 12.271 - FrameSize = FrameSizeFromDevFmt(pDevice->FmtChans, pDevice->FmtType); 12.272 - 12.273 - while(GetMessage(&msg, NULL, 0, 0)) 12.274 - { 12.275 - if(msg.message != WIM_DATA || pData->bWaveShutdown) 12.276 - continue; 12.277 - 12.278 - pWaveHdr = ((LPWAVEHDR)msg.lParam); 12.279 - 12.280 - WriteRingBuffer(pData->pRing, (ALubyte*)pWaveHdr->lpData, 12.281 - pWaveHdr->dwBytesRecorded/FrameSize); 12.282 - 12.283 - // Send buffer back to capture more data 12.284 - waveInAddBuffer(pData->hWaveHandle.In,pWaveHdr,sizeof(WAVEHDR)); 12.285 - InterlockedIncrement(&pData->lWaveBuffersCommitted); 12.286 - } 12.287 - 12.288 - // Signal Wave Thread completed event 12.289 - if(pData->hWaveThreadEvent) 12.290 - SetEvent(pData->hWaveThreadEvent); 12.291 - 12.292 - ExitThread(0); 12.293 - 12.294 - return 0; 12.295 -} 12.296 - 12.297 - 12.298 -static ALCboolean WinMMOpenPlayback(ALCdevice *pDevice, const ALCchar *deviceName) 12.299 -{ 12.300 - WAVEFORMATEX wfexFormat; 12.301 - WinMMData *pData = NULL; 12.302 - UINT lDeviceID = 0; 12.303 - MMRESULT res; 12.304 - ALuint i = 0; 12.305 - 12.306 - // Find the Device ID matching the deviceName if valid 12.307 - if(!deviceName || strcmp(deviceName, woDefault) == 0) 12.308 - lDeviceID = WAVE_MAPPER; 12.309 - else 12.310 - { 12.311 - if(!PlaybackDeviceList) 12.312 - ProbePlaybackDevices(); 12.313 - 12.314 - for(i = 0;i < NumPlaybackDevices;i++) 12.315 - { 12.316 - if(PlaybackDeviceList[i] && 12.317 - strcmp(deviceName, PlaybackDeviceList[i]) == 0) 12.318 - { 12.319 - lDeviceID = i; 12.320 - break; 12.321 - } 12.322 - } 12.323 - if(i == NumPlaybackDevices) 12.324 - return ALC_FALSE; 12.325 - } 12.326 - 12.327 - pData = calloc(1, sizeof(*pData)); 12.328 - if(!pData) 12.329 - { 12.330 - alcSetError(pDevice, ALC_OUT_OF_MEMORY); 12.331 - return ALC_FALSE; 12.332 - } 12.333 - pDevice->ExtraData = pData; 12.334 - 12.335 - if(pDevice->FmtChans != DevFmtMono) 12.336 - { 12.337 - if((pDevice->Flags&DEVICE_CHANNELS_REQUEST) && 12.338 - pDevice->FmtChans != DevFmtStereo) 12.339 - { 12.340 - ERR("Failed to set %s, got Stereo instead\n", DevFmtChannelsString(pDevice->FmtChans)); 12.341 - pDevice->Flags &= ~DEVICE_CHANNELS_REQUEST; 12.342 - } 12.343 - pDevice->FmtChans = DevFmtStereo; 12.344 - } 12.345 - switch(pDevice->FmtType) 12.346 - { 12.347 - case DevFmtByte: 12.348 - pDevice->FmtType = DevFmtUByte; 12.349 - break; 12.350 - case DevFmtUShort: 12.351 - case DevFmtFloat: 12.352 - pDevice->FmtType = DevFmtShort; 12.353 - break; 12.354 - case DevFmtUByte: 12.355 - case DevFmtShort: 12.356 - break; 12.357 - } 12.358 - 12.359 - memset(&wfexFormat, 0, sizeof(WAVEFORMATEX)); 12.360 - wfexFormat.wFormatTag = WAVE_FORMAT_PCM; 12.361 - wfexFormat.nChannels = ChannelsFromDevFmt(pDevice->FmtChans); 12.362 - wfexFormat.wBitsPerSample = BytesFromDevFmt(pDevice->FmtType) * 8; 12.363 - wfexFormat.nBlockAlign = wfexFormat.wBitsPerSample * 12.364 - wfexFormat.nChannels / 8; 12.365 - wfexFormat.nSamplesPerSec = pDevice->Frequency; 12.366 - wfexFormat.nAvgBytesPerSec = wfexFormat.nSamplesPerSec * 12.367 - wfexFormat.nBlockAlign; 12.368 - wfexFormat.cbSize = 0; 12.369 - 12.370 - if((res=waveOutOpen(&pData->hWaveHandle.Out, lDeviceID, &wfexFormat, (DWORD_PTR)&WaveOutProc, (DWORD_PTR)pDevice, CALLBACK_FUNCTION)) != MMSYSERR_NOERROR) 12.371 - { 12.372 - ERR("waveOutOpen failed: %u\n", res); 12.373 - goto failure; 12.374 - } 12.375 - 12.376 - pData->hWaveThreadEvent = CreateEvent(NULL, FALSE, FALSE, NULL); 12.377 - if(pData->hWaveThreadEvent == NULL) 12.378 - { 12.379 - ERR("CreateEvent failed: %lu\n", GetLastError()); 12.380 - goto failure; 12.381 - } 12.382 - 12.383 - pData->Frequency = pDevice->Frequency; 12.384 - 12.385 - pDevice->szDeviceName = strdup((lDeviceID==WAVE_MAPPER) ? woDefault : 12.386 - PlaybackDeviceList[lDeviceID]); 12.387 - return ALC_TRUE; 12.388 - 12.389 -failure: 12.390 - if(pData->hWaveThreadEvent) 12.391 - CloseHandle(pData->hWaveThreadEvent); 12.392 - 12.393 - if(pData->hWaveHandle.Out) 12.394 - waveOutClose(pData->hWaveHandle.Out); 12.395 - 12.396 - free(pData); 12.397 - pDevice->ExtraData = NULL; 12.398 - return ALC_FALSE; 12.399 -} 12.400 - 12.401 -static void WinMMClosePlayback(ALCdevice *device) 12.402 -{ 12.403 - WinMMData *pData = (WinMMData*)device->ExtraData; 12.404 - 12.405 - // Close the Wave device 12.406 - CloseHandle(pData->hWaveThreadEvent); 12.407 - pData->hWaveThreadEvent = 0; 12.408 - 12.409 - waveOutClose(pData->hWaveHandle.Out); 12.410 - pData->hWaveHandle.Out = 0; 12.411 - 12.412 - free(pData); 12.413 - device->ExtraData = NULL; 12.414 -} 12.415 - 12.416 -static ALCboolean WinMMResetPlayback(ALCdevice *device) 12.417 -{ 12.418 - WinMMData *pData = (WinMMData*)device->ExtraData; 12.419 - ALbyte *BufferData; 12.420 - ALint lBufferSize; 12.421 - ALuint i; 12.422 - 12.423 - pData->hWaveThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)PlaybackThreadProc, (LPVOID)device, 0, &pData->ulWaveThreadID); 12.424 - if(pData->hWaveThread == NULL) 12.425 - return ALC_FALSE; 12.426 - 12.427 - device->UpdateSize = (ALuint)((ALuint64)device->UpdateSize * 12.428 - pData->Frequency / device->Frequency); 12.429 - if(device->Frequency != pData->Frequency) 12.430 - { 12.431 - if((device->Flags&DEVICE_FREQUENCY_REQUEST)) 12.432 - ERR("WinMM does not support changing sample rates (wanted %dhz, got %dhz)\n", device->Frequency, pData->Frequency); 12.433 - device->Flags &= ~DEVICE_FREQUENCY_REQUEST; 12.434 - device->Frequency = pData->Frequency; 12.435 - } 12.436 - 12.437 - SetDefaultWFXChannelOrder(device); 12.438 - 12.439 - pData->lWaveBuffersCommitted = 0; 12.440 - 12.441 - // Create 4 Buffers 12.442 - lBufferSize = device->UpdateSize*device->NumUpdates / 4; 12.443 - lBufferSize *= FrameSizeFromDevFmt(device->FmtChans, device->FmtType); 12.444 - 12.445 - BufferData = calloc(4, lBufferSize); 12.446 - for(i = 0;i < 4;i++) 12.447 - { 12.448 - memset(&pData->WaveBuffer[i], 0, sizeof(WAVEHDR)); 12.449 - pData->WaveBuffer[i].dwBufferLength = lBufferSize; 12.450 - pData->WaveBuffer[i].lpData = ((i==0) ? (LPSTR)BufferData : 12.451 - (pData->WaveBuffer[i-1].lpData + 12.452 - pData->WaveBuffer[i-1].dwBufferLength)); 12.453 - waveOutPrepareHeader(pData->hWaveHandle.Out, &pData->WaveBuffer[i], sizeof(WAVEHDR)); 12.454 - waveOutWrite(pData->hWaveHandle.Out, &pData->WaveBuffer[i], sizeof(WAVEHDR)); 12.455 - InterlockedIncrement(&pData->lWaveBuffersCommitted); 12.456 - } 12.457 - 12.458 - return ALC_TRUE; 12.459 -} 12.460 - 12.461 -static void WinMMStopPlayback(ALCdevice *device) 12.462 -{ 12.463 - WinMMData *pData = (WinMMData*)device->ExtraData; 12.464 - void *buffer = NULL; 12.465 - int i; 12.466 - 12.467 - if(pData->hWaveThread == NULL) 12.468 - return; 12.469 - 12.470 - // Set flag to stop processing headers 12.471 - pData->bWaveShutdown = AL_TRUE; 12.472 - 12.473 - // Wait for signal that Wave Thread has been destroyed 12.474 - WaitForSingleObjectEx(pData->hWaveThreadEvent, 5000, FALSE); 12.475 - 12.476 - CloseHandle(pData->hWaveThread); 12.477 - pData->hWaveThread = 0; 12.478 - 12.479 - pData->bWaveShutdown = AL_FALSE; 12.480 - 12.481 - // Release the wave buffers 12.482 - for(i = 0;i < 4;i++) 12.483 - { 12.484 - waveOutUnprepareHeader(pData->hWaveHandle.Out, &pData->WaveBuffer[i], sizeof(WAVEHDR)); 12.485 - if(i == 0) buffer = pData->WaveBuffer[i].lpData; 12.486 - pData->WaveBuffer[i].lpData = NULL; 12.487 - } 12.488 - free(buffer); 12.489 -} 12.490 - 12.491 - 12.492 -static ALCboolean WinMMOpenCapture(ALCdevice *pDevice, const ALCchar *deviceName) 12.493 -{ 12.494 - WAVEFORMATEX wfexCaptureFormat; 12.495 - DWORD ulCapturedDataSize; 12.496 - WinMMData *pData = NULL; 12.497 - UINT lDeviceID = 0; 12.498 - ALbyte *BufferData; 12.499 - ALint lBufferSize; 12.500 - MMRESULT res; 12.501 - ALuint i; 12.502 - 12.503 - if(!CaptureDeviceList) 12.504 - ProbeCaptureDevices(); 12.505 - 12.506 - // Find the Device ID matching the deviceName if valid 12.507 - if(deviceName) 12.508 - { 12.509 - for(i = 0;i < NumCaptureDevices;i++) 12.510 - { 12.511 - if(CaptureDeviceList[i] && 12.512 - strcmp(deviceName, CaptureDeviceList[i]) == 0) 12.513 - { 12.514 - lDeviceID = i; 12.515 - break; 12.516 - } 12.517 - } 12.518 - } 12.519 - else 12.520 - { 12.521 - for(i = 0;i < NumCaptureDevices;i++) 12.522 - { 12.523 - if(CaptureDeviceList[i]) 12.524 - { 12.525 - lDeviceID = i; 12.526 - break; 12.527 - } 12.528 - } 12.529 - } 12.530 - if(i == NumCaptureDevices) 12.531 - return ALC_FALSE; 12.532 - 12.533 - pData = calloc(1, sizeof(*pData)); 12.534 - if(!pData) 12.535 - { 12.536 - alcSetError(pDevice, ALC_OUT_OF_MEMORY); 12.537 - return ALC_FALSE; 12.538 - } 12.539 - pDevice->ExtraData = pData; 12.540 - 12.541 - if((pDevice->FmtChans != DevFmtMono && pDevice->FmtChans != DevFmtStereo) || 12.542 - (pDevice->FmtType != DevFmtUByte && pDevice->FmtType != DevFmtShort)) 12.543 - { 12.544 - alcSetError(pDevice, ALC_INVALID_ENUM); 12.545 - goto failure; 12.546 - } 12.547 - 12.548 - memset(&wfexCaptureFormat, 0, sizeof(WAVEFORMATEX)); 12.549 - wfexCaptureFormat.wFormatTag = WAVE_FORMAT_PCM; 12.550 - wfexCaptureFormat.nChannels = ChannelsFromDevFmt(pDevice->FmtChans); 12.551 - wfexCaptureFormat.wBitsPerSample = BytesFromDevFmt(pDevice->FmtType) * 8; 12.552 - wfexCaptureFormat.nBlockAlign = wfexCaptureFormat.wBitsPerSample * 12.553 - wfexCaptureFormat.nChannels / 8; 12.554 - wfexCaptureFormat.nSamplesPerSec = pDevice->Frequency; 12.555 - wfexCaptureFormat.nAvgBytesPerSec = wfexCaptureFormat.nSamplesPerSec * 12.556 - wfexCaptureFormat.nBlockAlign; 12.557 - wfexCaptureFormat.cbSize = 0; 12.558 - 12.559 - if((res=waveInOpen(&pData->hWaveHandle.In, lDeviceID, &wfexCaptureFormat, (DWORD_PTR)&WaveInProc, (DWORD_PTR)pDevice, CALLBACK_FUNCTION)) != MMSYSERR_NOERROR) 12.560 - { 12.561 - ERR("waveInOpen failed: %u\n", res); 12.562 - goto failure; 12.563 - } 12.564 - 12.565 - pData->hWaveThreadEvent = CreateEvent(NULL, FALSE, FALSE, NULL); 12.566 - if(pData->hWaveThreadEvent == NULL) 12.567 - { 12.568 - ERR("CreateEvent failed: %lu\n", GetLastError()); 12.569 - goto failure; 12.570 - } 12.571 - 12.572 - pData->Frequency = pDevice->Frequency; 12.573 - 12.574 - // Allocate circular memory buffer for the captured audio 12.575 - ulCapturedDataSize = pDevice->UpdateSize*pDevice->NumUpdates; 12.576 - 12.577 - // Make sure circular buffer is at least 100ms in size 12.578 - if(ulCapturedDataSize < (wfexCaptureFormat.nSamplesPerSec / 10)) 12.579 - ulCapturedDataSize = wfexCaptureFormat.nSamplesPerSec / 10; 12.580 - 12.581 - pData->pRing = CreateRingBuffer(wfexCaptureFormat.nBlockAlign, ulCapturedDataSize); 12.582 - if(!pData->pRing) 12.583 - goto failure; 12.584 - 12.585 - pData->lWaveBuffersCommitted = 0; 12.586 - 12.587 - // Create 4 Buffers of 50ms each 12.588 - lBufferSize = wfexCaptureFormat.nAvgBytesPerSec / 20; 12.589 - lBufferSize -= (lBufferSize % wfexCaptureFormat.nBlockAlign); 12.590 - 12.591 - BufferData = calloc(4, lBufferSize); 12.592 - if(!BufferData) 12.593 - goto failure; 12.594 - 12.595 - for(i = 0;i < 4;i++) 12.596 - { 12.597 - memset(&pData->WaveBuffer[i], 0, sizeof(WAVEHDR)); 12.598 - pData->WaveBuffer[i].dwBufferLength = lBufferSize; 12.599 - pData->WaveBuffer[i].lpData = ((i==0) ? (LPSTR)BufferData : 12.600 - (pData->WaveBuffer[i-1].lpData + 12.601 - pData->WaveBuffer[i-1].dwBufferLength)); 12.602 - pData->WaveBuffer[i].dwFlags = 0; 12.603 - pData->WaveBuffer[i].dwLoops = 0; 12.604 - waveInPrepareHeader(pData->hWaveHandle.In, &pData->WaveBuffer[i], sizeof(WAVEHDR)); 12.605 - waveInAddBuffer(pData->hWaveHandle.In, &pData->WaveBuffer[i], sizeof(WAVEHDR)); 12.606 - InterlockedIncrement(&pData->lWaveBuffersCommitted); 12.607 - } 12.608 - 12.609 - pData->hWaveThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CaptureThreadProc, (LPVOID)pDevice, 0, &pData->ulWaveThreadID); 12.610 - if (pData->hWaveThread == NULL) 12.611 - goto failure; 12.612 - 12.613 - pDevice->szDeviceName = strdup(CaptureDeviceList[lDeviceID]); 12.614 - return ALC_TRUE; 12.615 - 12.616 -failure: 12.617 - if(pData->hWaveThread) 12.618 - CloseHandle(pData->hWaveThread); 12.619 - 12.620 - for(i = 0;i < 4;i++) 12.621 - { 12.622 - if(pData->WaveBuffer[i].lpData) 12.623 - { 12.624 - waveInUnprepareHeader(pData->hWaveHandle.In, &pData->WaveBuffer[i], sizeof(WAVEHDR)); 12.625 - if(i == 0) 12.626 - free(pData->WaveBuffer[i].lpData); 12.627 - } 12.628 - } 12.629 - 12.630 - if(pData->pRing) 12.631 - DestroyRingBuffer(pData->pRing); 12.632 - 12.633 - if(pData->hWaveThreadEvent) 12.634 - CloseHandle(pData->hWaveThreadEvent); 12.635 - 12.636 - if(pData->hWaveHandle.In) 12.637 - waveInClose(pData->hWaveHandle.In); 12.638 - 12.639 - free(pData); 12.640 - pDevice->ExtraData = NULL; 12.641 - return ALC_FALSE; 12.642 -} 12.643 - 12.644 -static void WinMMCloseCapture(ALCdevice *pDevice) 12.645 -{ 12.646 - WinMMData *pData = (WinMMData*)pDevice->ExtraData; 12.647 - void *buffer = NULL; 12.648 - int i; 12.649 - 12.650 - // Call waveOutReset to shutdown wave device 12.651 - pData->bWaveShutdown = AL_TRUE; 12.652 - waveInReset(pData->hWaveHandle.In); 12.653 - 12.654 - // Wait for signal that Wave Thread has been destroyed 12.655 - WaitForSingleObjectEx(pData->hWaveThreadEvent, 5000, FALSE); 12.656 - 12.657 - CloseHandle(pData->hWaveThread); 12.658 - pData->hWaveThread = 0; 12.659 - 12.660 - // Release the wave buffers 12.661 - for(i = 0;i < 4;i++) 12.662 - { 12.663 - waveInUnprepareHeader(pData->hWaveHandle.In, &pData->WaveBuffer[i], sizeof(WAVEHDR)); 12.664 - if(i == 0) buffer = pData->WaveBuffer[i].lpData; 12.665 - pData->WaveBuffer[i].lpData = NULL; 12.666 - } 12.667 - free(buffer); 12.668 - 12.669 - DestroyRingBuffer(pData->pRing); 12.670 - pData->pRing = NULL; 12.671 - 12.672 - // Close the Wave device 12.673 - CloseHandle(pData->hWaveThreadEvent); 12.674 - pData->hWaveThreadEvent = 0; 12.675 - 12.676 - waveInClose(pData->hWaveHandle.In); 12.677 - pData->hWaveHandle.In = 0; 12.678 - 12.679 - free(pData); 12.680 - pDevice->ExtraData = NULL; 12.681 -} 12.682 - 12.683 -static void WinMMStartCapture(ALCdevice *pDevice) 12.684 -{ 12.685 - WinMMData *pData = (WinMMData*)pDevice->ExtraData; 12.686 - waveInStart(pData->hWaveHandle.In); 12.687 -} 12.688 - 12.689 -static void WinMMStopCapture(ALCdevice *pDevice) 12.690 -{ 12.691 - WinMMData *pData = (WinMMData*)pDevice->ExtraData; 12.692 - waveInStop(pData->hWaveHandle.In); 12.693 -} 12.694 - 12.695 -static ALCuint WinMMAvailableSamples(ALCdevice *pDevice) 12.696 -{ 12.697 - WinMMData *pData = (WinMMData*)pDevice->ExtraData; 12.698 - return RingBufferSize(pData->pRing); 12.699 -} 12.700 - 12.701 -static void WinMMCaptureSamples(ALCdevice *pDevice, ALCvoid *pBuffer, ALCuint lSamples) 12.702 -{ 12.703 - WinMMData *pData = (WinMMData*)pDevice->ExtraData; 12.704 - 12.705 - if(WinMMAvailableSamples(pDevice) >= lSamples) 12.706 - ReadRingBuffer(pData->pRing, pBuffer, lSamples); 12.707 - else 12.708 - alcSetError(pDevice, ALC_INVALID_VALUE); 12.709 -} 12.710 - 12.711 - 12.712 -static const BackendFuncs WinMMFuncs = { 12.713 - WinMMOpenPlayback, 12.714 - WinMMClosePlayback, 12.715 - WinMMResetPlayback, 12.716 - WinMMStopPlayback, 12.717 - WinMMOpenCapture, 12.718 - WinMMCloseCapture, 12.719 - WinMMStartCapture, 12.720 - WinMMStopCapture, 12.721 - WinMMCaptureSamples, 12.722 - WinMMAvailableSamples 12.723 -}; 12.724 - 12.725 -ALCboolean alcWinMMInit(BackendFuncs *FuncList) 12.726 -{ 12.727 - *FuncList = WinMMFuncs; 12.728 - return ALC_TRUE; 12.729 -} 12.730 - 12.731 -void alcWinMMDeinit() 12.732 -{ 12.733 - ALuint lLoop; 12.734 - 12.735 - for(lLoop = 0;lLoop < NumPlaybackDevices;lLoop++) 12.736 - free(PlaybackDeviceList[lLoop]); 12.737 - free(PlaybackDeviceList); 12.738 - PlaybackDeviceList = NULL; 12.739 - 12.740 - NumPlaybackDevices = 0; 12.741 - 12.742 - 12.743 - for(lLoop = 0; lLoop < NumCaptureDevices; lLoop++) 12.744 - free(CaptureDeviceList[lLoop]); 12.745 - free(CaptureDeviceList); 12.746 - CaptureDeviceList = NULL; 12.747 - 12.748 - NumCaptureDevices = 0; 12.749 -} 12.750 - 12.751 -void alcWinMMProbe(enum DevProbe type) 12.752 -{ 12.753 - ALuint i; 12.754 - 12.755 - switch(type) 12.756 - { 12.757 - case DEVICE_PROBE: 12.758 - ProbePlaybackDevices(); 12.759 - if(NumPlaybackDevices > 0) 12.760 - AppendDeviceList(woDefault); 12.761 - break; 12.762 - 12.763 - case ALL_DEVICE_PROBE: 12.764 - ProbePlaybackDevices(); 12.765 - if(NumPlaybackDevices > 0) 12.766 - AppendAllDeviceList(woDefault); 12.767 - for(i = 0;i < NumPlaybackDevices;i++) 12.768 - { 12.769 - if(PlaybackDeviceList[i]) 12.770 - AppendAllDeviceList(PlaybackDeviceList[i]); 12.771 - } 12.772 - break; 12.773 - 12.774 - case CAPTURE_DEVICE_PROBE: 12.775 - ProbeCaptureDevices(); 12.776 - for(i = 0;i < NumCaptureDevices;i++) 12.777 - { 12.778 - if(CaptureDeviceList[i]) 12.779 - AppendCaptureDeviceList(CaptureDeviceList[i]); 12.780 - } 12.781 - break; 12.782 - } 12.783 -}
13.1 --- a/CMakeLists.txt Tue Oct 25 13:03:35 2011 -0700 13.2 +++ b/CMakeLists.txt Tue Oct 25 13:11:31 2011 -0700 13.3 @@ -25,32 +25,8 @@ 13.4 SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS TRUE) 13.5 13.6 13.7 -OPTION(ALSA "Check for ALSA backend" ON) 13.8 -OPTION(OSS "Check for OSS backend" ON) 13.9 -OPTION(SOLARIS "Check for Solaris backend" ON) 13.10 -OPTION(SNDIO "Check for SndIO backend" ON) 13.11 -OPTION(MMDEVAPI "Check for MMDevApi" ON) 13.12 -OPTION(DSOUND "Check for DirectSound backend" ON) 13.13 -OPTION(WINMM "Check for Windows Multimedia backend" ON) 13.14 -OPTION(PORTAUDIO "Check for PortAudio backend" ON) 13.15 -OPTION(PULSEAUDIO "Check for PulseAudio backend" ON) 13.16 -OPTION(COREAUDIO "Check for CoreAudio backend" ON) 13.17 -OPTION(OPENSL "Check for OpenSL backend" ON) 13.18 -OPTION(WAVE "Enable Wave Writer backend" ON) 13.19 OPTION(SEND "Enable Send Backend" ON) 13.20 13.21 -OPTION(REQUIRE_ALSA "Require ALSA backend" OFF) 13.22 -OPTION(REQUIRE_OSS "Require OSS backend" OFF) 13.23 -OPTION(REQUIRE_SOLARIS "Require Solaris backend" OFF) 13.24 -OPTION(REQUIRE_SNDIO "Require SndIO backend" OFF) 13.25 -OPTION(REQUIRE_MMDEVAPI "Require MMDevApi" OFF) 13.26 -OPTION(REQUIRE_DSOUND "Require DirectSound backend" OFF) 13.27 -OPTION(REQUIRE_WINMM "Require Windows Multimedia backend" OFF) 13.28 -OPTION(REQUIRE_PORTAUDIO "Require PortAudio backend" OFF) 13.29 -OPTION(REQUIRE_PULSEAUDIO "Require PulseAudio backend" OFF) 13.30 -OPTION(REQUIRE_COREAUDIO "Require CoreAudio backend" OFF) 13.31 -OPTION(REQUIRE_OPENSL "Require OpenSL backend" OFF) 13.32 - 13.33 OPTION(DLOPEN "Check for the dlopen API for loading optional libs" ON) 13.34 13.35 OPTION(WERROR "Treat compile warnings as errors" OFF) 13.36 @@ -399,221 +375,8 @@ 13.37 ) 13.38 13.39 SET(BACKENDS "") 13.40 -SET(HAVE_ALSA 0) 13.41 -SET(HAVE_OSS 0) 13.42 -SET(HAVE_SOLARIS 0) 13.43 -SET(HAVE_SNDIO 0) 13.44 -SET(HAVE_DSOUND 0) 13.45 -SET(HAVE_WINMM 0) 13.46 -SET(HAVE_PORTAUDIO 0) 13.47 -SET(HAVE_PULSEAUDIO 0) 13.48 -SET(HAVE_COREAUDIO 0) 13.49 -SET(HAVE_OPENSL 0) 13.50 -SET(HAVE_WAVE 0) 13.51 13.52 13.53 -# Check ALSA backend 13.54 -IF(ALSA) 13.55 - CHECK_INCLUDE_FILE(alsa/asoundlib.h HAVE_ALSA_ASOUNDLIB_H) 13.56 - IF(HAVE_ALSA_ASOUNDLIB_H) 13.57 - CHECK_SHARED_FUNCTION_EXISTS(snd_pcm_open "alsa/asoundlib.h" asound "" HAVE_LIBASOUND) 13.58 - IF(HAVE_LIBASOUND OR HAVE_DLFCN_H OR WIN32) 13.59 - SET(HAVE_ALSA 1) 13.60 - SET(ALC_OBJS ${ALC_OBJS} Alc/backends/alsa.c) 13.61 - IF(HAVE_DLFCN_H OR WIN32) 13.62 - SET(BACKENDS "${BACKENDS} ALSA,") 13.63 - ELSE() 13.64 - SET(BACKENDS "${BACKENDS} ALSA \(linked\),") 13.65 - SET(EXTRA_LIBS asound ${EXTRA_LIBS}) 13.66 - ENDIF() 13.67 - ENDIF() 13.68 - ENDIF() 13.69 -ENDIF() 13.70 -IF(REQUIRE_ALSA AND NOT HAVE_ALSA) 13.71 - MESSAGE(FATAL_ERROR "Failed to enabled required ALSA backend") 13.72 -ENDIF() 13.73 - 13.74 -# Check OSS backend 13.75 -IF(OSS) 13.76 - CHECK_INCLUDE_FILE(sys/soundcard.h HAVE_SYS_SOUNDCARD_H) 13.77 - IF(HAVE_SYS_SOUNDCARD_H) 13.78 - SET(HAVE_OSS 1) 13.79 - SET(ALC_OBJS ${ALC_OBJS} Alc/backends/oss.c) 13.80 - SET(BACKENDS "${BACKENDS} OSS,") 13.81 - ENDIF() 13.82 -ENDIF() 13.83 -IF(REQUIRE_OSS AND NOT HAVE_OSS) 13.84 - MESSAGE(FATAL_ERROR "Failed to enabled required OSS backend") 13.85 -ENDIF() 13.86 - 13.87 -# Check Solaris backend 13.88 -IF(SOLARIS) 13.89 - CHECK_INCLUDE_FILE(sys/audioio.h HAVE_SYS_AUDIOIO_H) 13.90 - IF(HAVE_SYS_AUDIOIO_H) 13.91 - SET(HAVE_SOLARIS 1) 13.92 - SET(ALC_OBJS ${ALC_OBJS} Alc/backends/solaris.c) 13.93 - SET(BACKENDS "${BACKENDS} Solaris,") 13.94 - ENDIF() 13.95 -ENDIF() 13.96 -IF(REQUIRE_SOLARIS AND NOT HAVE_SOLARIS) 13.97 - MESSAGE(FATAL_ERROR "Failed to enabled required Solaris backend") 13.98 -ENDIF() 13.99 - 13.100 -# Check SndIO backend 13.101 -IF(SNDIO) 13.102 - CHECK_INCLUDE_FILE(sndio.h HAVE_SNDIO_H) 13.103 - IF(HAVE_SNDIO_H) 13.104 - CHECK_SHARED_FUNCTION_EXISTS(sio_open "sndio.h" sndio "" HAVE_LIBSNDIO) 13.105 - IF(HAVE_LIBSNDIO OR HAVE_DLFCN_H OR WIN32) 13.106 - SET(HAVE_SNDIO 1) 13.107 - SET(ALC_OBJS ${ALC_OBJS} Alc/backends/sndio.c) 13.108 - IF(HAVE_DLFCN_H OR WIN32) 13.109 - SET(BACKENDS "${BACKENDS} SndIO,") 13.110 - ELSE() 13.111 - SET(BACKENDS "${BACKENDS} SndIO \(linked\),") 13.112 - SET(EXTRA_LIBS sndio ${EXTRA_LIBS}) 13.113 - ENDIF() 13.114 - ENDIF() 13.115 - ENDIF() 13.116 -ENDIF() 13.117 -IF(REQUIRE_SNDIO AND NOT HAVE_SNDIO) 13.118 - MESSAGE(FATAL_ERROR "Failed to enabled required SndIO backend") 13.119 -ENDIF() 13.120 - 13.121 -# Check for MMDevApi backend 13.122 -IF(HAVE_WINDOWS_H) 13.123 - IF(MMDEVAPI) 13.124 - CHECK_INCLUDE_FILE(mmdeviceapi.h HAVE_MMDEVICEAPI_H) 13.125 - IF(HAVE_MMDEVICEAPI_H) 13.126 - SET(HAVE_MMDEVAPI 1) 13.127 - SET(ALC_OBJS ${ALC_OBJS} Alc/backends/mmdevapi.c) 13.128 - 13.129 - SET(BACKENDS "${BACKENDS} MMDevApi,") 13.130 - ENDIF() 13.131 - ENDIF() 13.132 -ENDIF() 13.133 -IF(REQUIRE_MMDEVAPI AND NOT HAVE_MMDEVAPI) 13.134 - MESSAGE(FATAL_ERROR "Failed to enabled required MMDevApi backend") 13.135 -ENDIF() 13.136 - 13.137 -# Check DSound/MMSystem backend 13.138 -IF(DSOUND) 13.139 - CHECK_INCLUDE_FILE(dsound.h HAVE_DSOUND_H) 13.140 - IF(HAVE_DSOUND_H) 13.141 - CHECK_SHARED_FUNCTION_EXISTS(DirectSoundCreate "dsound.h" dsound "" HAVE_LIBDSOUND) 13.142 - IF(HAVE_LIBDSOUND OR HAVE_DLFCN_H OR WIN32) 13.143 - SET(HAVE_DSOUND 1) 13.144 - SET(ALC_OBJS ${ALC_OBJS} Alc/backends/dsound.c) 13.145 - 13.146 - IF(HAVE_DLFCN_H OR WIN32) 13.147 - SET(BACKENDS "${BACKENDS} DirectSound,") 13.148 - ELSE() 13.149 - SET(BACKENDS "${BACKENDS} DirectSound \(linked\),") 13.150 - SET(EXTRA_LIBS dsound ${EXTRA_LIBS}) 13.151 - ENDIF() 13.152 - ENDIF() 13.153 - ENDIF() 13.154 -ENDIF() 13.155 -IF(REQUIRE_DSOUND AND NOT HAVE_DSOUND) 13.156 - MESSAGE(FATAL_ERROR "Failed to enabled required DSound backend") 13.157 -ENDIF() 13.158 - 13.159 -IF(HAVE_WINDOWS_H) 13.160 - IF(WINMM) 13.161 - CHECK_INCLUDE_FILES("windows.h;mmsystem.h" HAVE_MMSYSTEM_H -D_WIN32_WINNT=0x0500) 13.162 - IF(HAVE_MMSYSTEM_H AND HAVE_LIBWINMM) 13.163 - SET(HAVE_WINMM 1) 13.164 - SET(ALC_OBJS ${ALC_OBJS} Alc/backends/winmm.c) 13.165 - SET(BACKENDS "${BACKENDS} WinMM,") 13.166 - ENDIF() 13.167 - ENDIF() 13.168 -ENDIF() 13.169 -IF(REQUIRE_WINMM AND NOT HAVE_WINMM) 13.170 - MESSAGE(FATAL_ERROR "Failed to enable required WinMM backend") 13.171 -ENDIF() 13.172 - 13.173 -# Check PortAudio backend 13.174 -IF(PORTAUDIO) 13.175 - CHECK_INCLUDE_FILE(portaudio.h HAVE_PORTAUDIO_H) 13.176 - IF(HAVE_PORTAUDIO_H) 13.177 - CHECK_SHARED_FUNCTION_EXISTS(Pa_Initialize "portaudio.h" portaudio "" HAVE_LIBPORTAUDIO) 13.178 - IF(HAVE_LIBPORTAUDIO OR HAVE_DLFCN_H OR WIN32) 13.179 - SET(HAVE_PORTAUDIO 1) 13.180 - SET(ALC_OBJS ${ALC_OBJS} Alc/backends/portaudio.c) 13.181 - IF(HAVE_DLFCN_H OR WIN32) 13.182 - SET(BACKENDS "${BACKENDS} PortAudio,") 13.183 - ELSE() 13.184 - SET(BACKENDS "${BACKENDS} PortAudio \(linked\),") 13.185 - SET(EXTRA_LIBS portaudio ${EXTRA_LIBS}) 13.186 - ENDIF() 13.187 - ENDIF() 13.188 - ENDIF() 13.189 -ENDIF() 13.190 -IF(REQUIRE_PORTAUDIO AND NOT HAVE_PORTAUDIO) 13.191 - MESSAGE(FATAL_ERROR "Failed to enabled required PortAudio backend") 13.192 -ENDIF() 13.193 - 13.194 -# Check PulseAudio backend 13.195 -IF(PULSEAUDIO) 13.196 - CHECK_INCLUDE_FILE(pulse/pulseaudio.h HAVE_PULSE_PULSEAUDIO_H) 13.197 - IF(HAVE_PULSE_PULSEAUDIO_H) 13.198 - CHECK_SHARED_FUNCTION_EXISTS(pa_context_new "pulse/pulseaudio.h" pulse "" HAVE_LIBPULSE) 13.199 - IF(HAVE_LIBPULSE OR HAVE_DLFCN_H OR WIN32) 13.200 - SET(HAVE_PULSEAUDIO 1) 13.201 - SET(ALC_OBJS ${ALC_OBJS} Alc/backends/pulseaudio.c) 13.202 - IF(HAVE_DLFCN_H OR WIN32) 13.203 - SET(BACKENDS "${BACKENDS} PulseAudio,") 13.204 - ELSE() 13.205 - SET(BACKENDS "${BACKENDS} PulseAudio \(linked\),") 13.206 - SET(EXTRA_LIBS pulse ${EXTRA_LIBS}) 13.207 - ENDIF() 13.208 - ENDIF() 13.209 - ENDIF() 13.210 -ENDIF() 13.211 -IF(REQUIRE_PULSEAUDIO AND NOT HAVE_PULSEAUDIO) 13.212 - MESSAGE(FATAL_ERROR "Failed to enabled required PulseAudio backend") 13.213 -ENDIF() 13.214 - 13.215 -# Check CoreAudio backend 13.216 -IF(COREAUDIO) 13.217 - CHECK_INCLUDE_FILE(/System/Library/Frameworks/CoreAudio.framework/Headers/CoreAudio.h HAVE_COREAUDIO_FRAMEWORK) 13.218 - IF(HAVE_COREAUDIO_FRAMEWORK) 13.219 - SET(HAVE_COREAUDIO 1) 13.220 - SET(ALC_OBJS ${ALC_OBJS} Alc/backends/coreaudio.c) 13.221 - SET(BACKENDS "${BACKENDS} CoreAudio,") 13.222 - SET(EXTRA_LIBS /System/Library/Frameworks/CoreAudio.framework ${EXTRA_LIBS}) 13.223 - SET(EXTRA_LIBS /System/Library/Frameworks/AudioUnit.framework ${EXTRA_LIBS}) 13.224 - SET(EXTRA_LIBS /System/Library/Frameworks/ApplicationServices.framework ${EXTRA_LIBS}) 13.225 - ENDIF() 13.226 -ENDIF() 13.227 -IF(REQUIRE_COREAUDIO AND NOT HAVE_COREAUDIO) 13.228 - MESSAGE(FATAL_ERROR "Failed to enabled required CoreAudio backend") 13.229 -ENDIF() 13.230 - 13.231 -# Check for OpenSL (Android) backend 13.232 -IF(OPENSL) 13.233 - CHECK_INCLUDE_FILE(SLES/OpenSLES_Android.h HAVE_SLES_OPENSLES_ANDROID_H) 13.234 - IF(HAVE_SLES_OPENSLES_ANDROID_H) 13.235 - CHECK_SHARED_FUNCTION_EXISTS(slCreateEngine "SLES/OpenSLES.h" OpenSLES "" HAVE_LIBOPENSLES) 13.236 - IF(HAVE_LIBOPENSLES) 13.237 - SET(HAVE_OPENSL 1) 13.238 - SET(ALC_OBJS ${ALC_OBJS} Alc/backends/opensl.c) 13.239 - SET(BACKENDS "${BACKENDS} OpenSL,") 13.240 - SET(EXTRA_LIBS OpenSLES ${EXTRA_LIBS}) 13.241 - ENDIF() 13.242 - ENDIF() 13.243 -ENDIF() 13.244 -IF(REQUIRE_OPENSL AND NOT HAVE_OPENSL) 13.245 - MESSAGE(FATAL_ERROR "Failed to enable required OpenSL backend") 13.246 -ENDIF() 13.247 - 13.248 -# Optionally enable the Wave Writer backend 13.249 -IF(WAVE) 13.250 - SET(HAVE_WAVE 1) 13.251 - SET(ALC_OBJS ${ALC_OBJS} Alc/backends/wave.c) 13.252 - SET(BACKENDS "${BACKENDS} WaveFile,") 13.253 -ENDIF() 13.254 - 13.255 13.256 SET(ALC_OBJS ${ALC_OBJS} Alc/backends/send.c) 13.257 SET(BACKENDS "${BACKENDS} Send,") 13.258 @@ -682,14 +445,6 @@ 13.259 MESSAGE(STATUS " ${BACKENDS}") 13.260 MESSAGE(STATUS "") 13.261 13.262 -IF(WIN32) 13.263 - IF(NOT HAVE_DSOUND) 13.264 - MESSAGE(STATUS "WARNING: Building the Windows version without DirectSound output") 13.265 - MESSAGE(STATUS " This is probably NOT what you want!") 13.266 - MESSAGE(STATUS "") 13.267 - ENDIF() 13.268 -ENDIF() 13.269 - 13.270 # Install alsoft.conf configuration file 13.271 IF(ALSOFT_CONFIG) 13.272 INSTALL(FILES alsoftrc.sample