1 /* -*- c-basic-offset: 8 -*- 2 rdesktop: A Remote Desktop Protocol client. 3 Sound Channel Process Functions - libao-driver 4 Copyright (C) Matthew Chapman 2003 5 Copyright (C) GuoJunBo guojunbo@ict.ac.cn 2003 6 Copyright (C) Michael Gernoth mike@zerfleddert.de 2005 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 2 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License along 19 with this program; if not, write to the Free Software Foundation, Inc., 20 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 */ 22 23 #include "rdesktop.h" 24 #include <unistd.h> 25 #include <fcntl.h> 26 #include <errno.h> 27 #include <ao/ao.h> 28 #include <sys/time.h> 29 30 #define MAX_QUEUE 10 31 #define WAVEOUTBUF 16 32 33 int This->dsp_; 34 ao_device *o_device = NULL; 35 int default_driver; 36 int g_samplerate; 37 int This->channels; 38 BOOL This->dsp_bu = False; 39 static BOOL g_reopened; 40 static short g_samplewidth; 41 42 static struct audio_packet 43 { 44 struct stream s; 45 uint16 tick; 46 uint8 index; 47 } packet_queue[MAX_QUEUE]; 48 static unsigned int queue_hi, queue_lo; 49 50 BOOL 51 wave_out_open(void) 52 { 53 ao_sample_format format; 54 55 ao_initialize(); 56 default_driver = ao_default_driver_id(); 57 58 format.bits = 16; 59 format.channels = 2; 60 This->channels = 2; 61 format.rate = 44100; 62 g_samplerate = 44100; 63 format.byte_format = AO_FMT_LITTLE; 64 65 o_device = ao_open_live(default_driver, &format, NULL); 66 if (o_device == NULL) 67 { 68 return False; 69 } 70 71 This->dsp_ = 0; 72 queue_lo = queue_hi = 0; 73 74 g_reopened = True; 75 76 return True; 77 } 78 79 void 80 wave_out_close(void) 81 { 82 /* Ack all remaining packets */ 83 while (queue_lo != queue_hi) 84 { 85 rdpsnd_send_completion(packet_queue[queue_lo].tick, packet_queue[queue_lo].index); 86 free(packet_queue[queue_lo].s.data); 87 queue_lo = (queue_lo + 1) % MAX_QUEUE; 88 } 89 90 if (o_device != NULL) 91 ao_close(o_device); 92 93 ao_shutdown(); 94 } 95 96 BOOL 97 wave_out_format_supported(WAVEFORMATEX * pwfx) 98 { 99 if (pwfx->wFormatTag != WAVE_FORMAT_PCM) 100 return False; 101 if ((pwfx->nChannels != 1) && (pwfx->nChannels != 2)) 102 return False; 103 if ((pwfx->wBitsPerSample != 8) && (pwfx->wBitsPerSample != 16)) 104 return False; 105 /* The only common denominator between libao output drivers is a sample-rate of 106 44100, we need to upsample 22050 to it */ 107 if ((pwfx->nSamplesPerSec != 44100) && (pwfx->nSamplesPerSec != 22050)) 108 return False; 109 110 return True; 111 } 112 113 BOOL 114 wave_out_set_format(WAVEFORMATEX * pwfx) 115 { 116 ao_sample_format format; 117 118 format.bits = pwfx->wBitsPerSample; 119 format.channels = pwfx->nChannels; 120 This->channels = pwfx->nChannels; 121 format.rate = 44100; 122 g_samplerate = pwfx->nSamplesPerSec; 123 format.byte_format = AO_FMT_LITTLE; 124 125 g_samplewidth = pwfx->wBitsPerSample / 8; 126 127 if (o_device != NULL) 128 ao_close(o_device); 129 130 o_device = ao_open_live(default_driver, &format, NULL); 131 if (o_device == NULL) 132 { 133 return False; 134 } 135 136 g_reopened = True; 137 138 return True; 139 } 140 141 void 142 wave_out_volume(uint16 left, uint16 right) 143 { 144 warning("volume changes not supported with libao-output\n"); 145 } 146 147 void 148 wave_out_write(STREAM s, uint16 tick, uint8 index) 149 { 150 struct audio_packet *packet = &packet_queue[queue_hi]; 151 unsigned int next_hi = (queue_hi + 1) % MAX_QUEUE; 152 153 if (next_hi == queue_lo) 154 { 155 error("No space to queue audio packet\n"); 156 return; 157 } 158 159 queue_hi = next_hi; 160 161 packet->s = *s; 162 packet->tick = tick; 163 packet->index = index; 164 packet->s.p += 4; 165 166 /* we steal the data buffer from s, give it a new one */ 167 s->data = malloc(s->size); 168 169 if (!This->dsp_bu) 170 wave_out_play(); 171 } 172 173 void 174 wave_out_play(void) 175 { 176 struct audio_packet *packet; 177 STREAM out; 178 char outbuf[WAVEOUTBUF]; 179 int offset, len, i; 180 static long prev_s, prev_us; 181 unsigned int duration; 182 struct timeval tv; 183 int next_tick; 184 185 if (g_reopened) 186 { 187 g_reopened = False; 188 gettimeofday(&tv, NULL); 189 prev_s = tv.tv_sec; 190 prev_us = tv.tv_usec; 191 } 192 193 if (queue_lo == queue_hi) 194 { 195 This->dsp_bu = 0; 196 return; 197 } 198 199 packet = &packet_queue[queue_lo]; 200 out = &packet->s; 201 202 if (((queue_lo + 1) % MAX_QUEUE) != queue_hi) 203 { 204 next_tick = packet_queue[(queue_lo + 1) % MAX_QUEUE].tick; 205 } 206 else 207 { 208 next_tick = (packet->tick + 65535) % 65536; 209 } 210 211 len = 0; 212 213 if (g_samplerate == 22050) 214 { 215 /* Resample to 44100 */ 216 for (i = 0; (i < ((WAVEOUTBUF / 4) * (3 - g_samplewidth))) && (out->p < out->end); 217 i++) 218 { 219 /* On a stereo-channel we must make sure that left and right 220 does not get mixed up, so we need to expand the sample- 221 data with channels in mind: 1234 -> 12123434 222 If we have a mono-channel, we can expand the data by simply 223 doubling the sample-data: 1234 -> 11223344 */ 224 if (This->channels == 2) 225 offset = ((i * 2) - (i & 1)) * g_samplewidth; 226 else 227 offset = (i * 2) * g_samplewidth; 228 229 memcpy(&outbuf[offset], out->p, g_samplewidth); 230 memcpy(&outbuf[This->channels * g_samplewidth + offset], out->p, g_samplewidth); 231 232 out->p += g_samplewidth; 233 len += 2 * g_samplewidth; 234 } 235 } 236 else 237 { 238 len = (WAVEOUTBUF > (out->end - out->p)) ? (out->end - out->p) : WAVEOUTBUF; 239 memcpy(outbuf, out->p, len); 240 out->p += len; 241 } 242 243 ao_play(o_device, outbuf, len); 244 245 gettimeofday(&tv, NULL); 246 247 duration = ((tv.tv_sec - prev_s) * 1000000 + (tv.tv_usec - prev_us)) / 1000; 248 249 if (packet->tick > next_tick) 250 next_tick += 65536; 251 252 if ((out->p == out->end) || duration > next_tick - packet->tick + 500) 253 { 254 prev_s = tv.tv_sec; 255 prev_us = tv.tv_usec; 256 257 if (abs((next_tick - packet->tick) - duration) > 20) 258 { 259 DEBUG(("duration: %d, calc: %d, ", duration, next_tick - packet->tick)); 260 DEBUG(("last: %d, is: %d, should: %d\n", packet->tick, 261 (packet->tick + duration) % 65536, next_tick % 65536)); 262 } 263 264 /* Until all drivers are using the windows sound-ticks, we need to 265 substract the 50 ticks added later by rdpsnd.c */ 266 rdpsnd_send_completion(((packet->tick + duration) % 65536) - 50, packet->index); 267 free(out->data); 268 queue_lo = (queue_lo + 1) % MAX_QUEUE; 269 } 270 271 This->dsp_bu = 1; 272 return; 273 } 274