diff --git a/rdpsnd.c b/rdpsnd.c index 21d57bb..0d05233 100644 --- a/rdpsnd.c +++ b/rdpsnd.c @@ -20,6 +20,7 @@ */ #include "rdesktop.h" +#include "rdpsnd.h" #define RDPSND_CLOSE 1 #define RDPSND_WRITE 2 @@ -30,6 +31,10 @@ #define RDPSND_NEGOTIATE 7 #define MAX_FORMATS 10 +#define MAX_QUEUE 10 + +BOOL g_dsp_busy = False; +int g_dsp_fd; static VCHANNEL *rdpsnd_channel; @@ -37,6 +42,8 @@ static BOOL device_open; static WAVEFORMATEX formats[MAX_FORMATS]; static unsigned int format_count; static unsigned int current_format; +static unsigned int queue_hi, queue_lo; +static struct audio_packet packet_queue[MAX_QUEUE]; static STREAM rdpsnd_init_packet(uint16 type, uint16 size) @@ -66,7 +73,7 @@ rdpsnd_send_completion(uint16 tick, uint8 packet_index) STREAM s; s = rdpsnd_init_packet(RDPSND_COMPLETION, 4); - out_uint16_le(s, tick + 50); + out_uint16_le(s, tick); out_uint8(s, packet_index); out_uint8(s, 0); s_mark_end(s); @@ -214,7 +221,7 @@ rdpsnd_process(STREAM s) current_format = format; } - wave_out_write(s, tick, packet_index); + rdpsnd_queue_write(s, tick, packet_index); awaiting_data_packet = False; return; } @@ -260,5 +267,70 @@ rdpsnd_init(void) rdpsnd_channel = channel_register("rdpsnd", CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP, rdpsnd_process); + return (rdpsnd_channel != NULL); } + +void +rdpsnd_queue_write(STREAM s, uint16 tick, uint8 index) +{ + struct audio_packet *packet = &packet_queue[queue_hi]; + unsigned int next_hi = (queue_hi + 1) % MAX_QUEUE; + + if (next_hi == queue_lo) + { + error("No space to queue audio packet\n"); + return; + } + + queue_hi = next_hi; + + packet->s = *s; + packet->tick = tick; + packet->index = index; + packet->s.p += 4; + + /* we steal the data buffer from s, give it a new one */ + s->data = malloc(s->size); + + if (!g_dsp_busy) + wave_out_play(); +} + +inline struct audio_packet * +rdpsnd_queue_current_packet(void) +{ + return &packet_queue[queue_lo]; +} + +inline BOOL +rdpsnd_queue_empty(void) +{ + return (queue_lo == queue_hi); +} + +inline void +rdpsnd_queue_init(void) +{ + queue_lo = queue_hi = 0; +} + +inline void +rdpsnd_queue_next(void) +{ + free(packet_queue[queue_lo].s.data); + queue_lo = (queue_lo + 1) % MAX_QUEUE; +} + +inline int +rdpsnd_queue_next_tick(void) +{ + if (((queue_lo + 1) % MAX_QUEUE) != queue_hi) + { + return packet_queue[(queue_lo + 1) % MAX_QUEUE].tick; + } + else + { + return (packet_queue[queue_lo].tick + 65535) % 65536; + } +} diff --git a/rdpsnd.h b/rdpsnd.h new file mode 100644 index 0000000..e2e9989 --- /dev/null +++ b/rdpsnd.h @@ -0,0 +1,36 @@ +/* + rdesktop: A Remote Desktop Protocol client. + Sound infrastructure + Copyright (C) Michael Gernoth 2006 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +struct audio_packet +{ + struct stream s; + uint16 tick; + uint8 index; +}; + +extern BOOL g_dsp_busy; +extern int g_dsp_fd; + +void rdpsnd_queue_write(STREAM s, uint16 tick, uint8 index); +inline struct audio_packet *rdpsnd_queue_current_packet(void); +inline BOOL rdpsnd_queue_empty(void); +inline void rdpsnd_queue_init(void); +inline void rdpsnd_queue_next(void); +inline int rdpsnd_queue_next_tick(void); diff --git a/rdpsnd_alsa.c b/rdpsnd_alsa.c index a72cb2d..d1c394a 100644 --- a/rdpsnd_alsa.c +++ b/rdpsnd_alsa.c @@ -21,6 +21,7 @@ */ #include "rdesktop.h" +#include "rdpsnd.h" #include #include #include @@ -28,25 +29,14 @@ #include #define DEFAULTDEVICE "default" -#define MAX_QUEUE 10 #define MAX_FRAMES 32 -int g_dsp_fd; -BOOL g_dsp_busy = False; static snd_pcm_t *pcm_handle = NULL; static snd_pcm_stream_t stream = SND_PCM_STREAM_PLAYBACK; static BOOL reopened; static short samplewidth; static int audiochannels; -static struct audio_packet -{ - struct stream s; - uint16 tick; - uint8 index; -} packet_queue[MAX_QUEUE]; -static unsigned int queue_hi, queue_lo; - BOOL wave_out_open(void) { @@ -62,7 +52,7 @@ wave_out_open(void) } g_dsp_fd = 0; - queue_lo = queue_hi = 0; + rdpsnd_queue_init(); reopened = True; @@ -73,13 +63,14 @@ void wave_out_close(void) { /* Ack all remaining packets */ - while (queue_lo != queue_hi) + while (!rdpsnd_queue_empty()) { - rdpsnd_send_completion(packet_queue[queue_lo].tick, packet_queue[queue_lo].index); - free(packet_queue[queue_lo].s.data); - queue_lo = (queue_lo + 1) % MAX_QUEUE; + rdpsnd_send_completion(rdpsnd_queue_current_packet()->tick, + rdpsnd_queue_current_packet()->index); + rdpsnd_queue_next(); } + if (pcm_handle) { snd_pcm_drop(pcm_handle); @@ -230,32 +221,6 @@ wave_out_volume(uint16 left, uint16 right) } } -void -wave_out_write(STREAM s, uint16 tick, uint8 index) -{ - struct audio_packet *packet = &packet_queue[queue_hi]; - unsigned int next_hi = (queue_hi + 1) % MAX_QUEUE; - - if (next_hi == queue_lo) - { - error("No space to queue audio packet\n"); - return; - } - - queue_hi = next_hi; - - packet->s = *s; - packet->tick = tick; - packet->index = index; - packet->s.p += 4; - - /* we steal the data buffer from s, give it a new one */ - s->data = (uint8 *) malloc(s->size); - - if (!g_dsp_busy) - wave_out_play(); -} - void wave_out_play(void) { @@ -275,23 +240,16 @@ wave_out_play(void) prev_us = tv.tv_usec; } - if (queue_lo == queue_hi) + if (rdpsnd_queue_empty()) { g_dsp_busy = 0; return; } - packet = &packet_queue[queue_lo]; + packet = rdpsnd_queue_current_packet(); out = &packet->s; - if (((queue_lo + 1) % MAX_QUEUE) != queue_hi) - { - next_tick = packet_queue[(queue_lo + 1) % MAX_QUEUE].tick; - } - else - { - next_tick = (packet->tick + 65535) % 65536; - } + next_tick = rdpsnd_queue_next_tick(); len = (out->end - out->p) / (samplewidth * audiochannels); if ((len = snd_pcm_writei(pcm_handle, out->p, ((MAX_FRAMES < len) ? MAX_FRAMES : len))) < 0) @@ -320,11 +278,8 @@ wave_out_play(void) (packet->tick + duration) % 65536, next_tick % 65536)); } - /* Until all drivers are using the windows sound-ticks, we need to - substract the 50 ticks added later by rdpsnd.c */ - rdpsnd_send_completion(((packet->tick + duration) % 65536) - 50, packet->index); - free(out->data); - queue_lo = (queue_lo + 1) % MAX_QUEUE; + rdpsnd_send_completion(((packet->tick + duration) % 65536), packet->index); + rdpsnd_queue_next(); } g_dsp_busy = 1; diff --git a/rdpsnd_libao.c b/rdpsnd_libao.c index 3b050dc..19c9020 100644 --- a/rdpsnd_libao.c +++ b/rdpsnd_libao.c @@ -3,7 +3,7 @@ Sound Channel Process Functions - libao-driver Copyright (C) Matthew Chapman 2003 Copyright (C) GuoJunBo guojunbo@ict.ac.cn 2003 - Copyright (C) Michael Gernoth mike@zerfleddert.de 2005 + Copyright (C) Michael Gernoth mike@zerfleddert.de 2005-2006 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -21,17 +21,15 @@ */ #include "rdesktop.h" +#include "rdpsnd.h" #include #include #include #include #include -#define MAX_QUEUE 10 #define WAVEOUTBUF 16 -int g_dsp_fd; -BOOL g_dsp_busy = False; static ao_device *o_device = NULL; static int default_driver; static int samplerate; @@ -39,14 +37,6 @@ static int audiochannels; static BOOL reopened; static short samplewidth; -static struct audio_packet -{ - struct stream s; - uint16 tick; - uint8 index; -} packet_queue[MAX_QUEUE]; -static unsigned int queue_hi, queue_lo; - BOOL wave_out_open(void) { @@ -69,7 +59,7 @@ wave_out_open(void) } g_dsp_fd = 0; - queue_lo = queue_hi = 0; + rdpsnd_queue_init(); reopened = True; @@ -80,11 +70,11 @@ void wave_out_close(void) { /* Ack all remaining packets */ - while (queue_lo != queue_hi) + while (!rdpsnd_queue_empty()) { - rdpsnd_send_completion(packet_queue[queue_lo].tick, packet_queue[queue_lo].index); - free(packet_queue[queue_lo].s.data); - queue_lo = (queue_lo + 1) % MAX_QUEUE; + rdpsnd_send_completion(rdpsnd_queue_current_packet()->tick, + rdpsnd_queue_current_packet()->index); + rdpsnd_queue_next(); } if (o_device != NULL) @@ -144,32 +134,6 @@ wave_out_volume(uint16 left, uint16 right) warning("volume changes not supported with libao-output\n"); } -void -wave_out_write(STREAM s, uint16 tick, uint8 index) -{ - struct audio_packet *packet = &packet_queue[queue_hi]; - unsigned int next_hi = (queue_hi + 1) % MAX_QUEUE; - - if (next_hi == queue_lo) - { - error("No space to queue audio packet\n"); - return; - } - - queue_hi = next_hi; - - packet->s = *s; - packet->tick = tick; - packet->index = index; - packet->s.p += 4; - - /* we steal the data buffer from s, give it a new one */ - s->data = malloc(s->size); - - if (!g_dsp_busy) - wave_out_play(); -} - void wave_out_play(void) { @@ -190,23 +154,16 @@ wave_out_play(void) prev_us = tv.tv_usec; } - if (queue_lo == queue_hi) + if (rdpsnd_queue_empty()) { g_dsp_busy = 0; return; } - packet = &packet_queue[queue_lo]; + packet = rdpsnd_queue_current_packet(); out = &packet->s; - if (((queue_lo + 1) % MAX_QUEUE) != queue_hi) - { - next_tick = packet_queue[(queue_lo + 1) % MAX_QUEUE].tick; - } - else - { - next_tick = (packet->tick + 65535) % 65536; - } + next_tick = rdpsnd_queue_next_tick(); len = 0; @@ -261,11 +218,8 @@ wave_out_play(void) (packet->tick + duration) % 65536, next_tick % 65536)); } - /* Until all drivers are using the windows sound-ticks, we need to - substract the 50 ticks added later by rdpsnd.c */ - rdpsnd_send_completion(((packet->tick + duration) % 65536) - 50, packet->index); - free(out->data); - queue_lo = (queue_lo + 1) % MAX_QUEUE; + rdpsnd_send_completion(((packet->tick + duration) % 65536), packet->index); + rdpsnd_queue_next(); } g_dsp_busy = 1; diff --git a/rdpsnd_oss.c b/rdpsnd_oss.c index bf44e14..c62475e 100644 --- a/rdpsnd_oss.c +++ b/rdpsnd_oss.c @@ -28,6 +28,7 @@ #endif #include "rdesktop.h" +#include "rdpsnd.h" #include #include #include @@ -35,22 +36,12 @@ #include #include +#define DEFAULTDEVICE "/dev/dsp" #define MAX_LEN 512 -#define MAX_QUEUE 10 -int g_dsp_fd; -BOOL g_dsp_busy = False; static int snd_rate; static short samplewidth; -static struct audio_packet -{ - struct stream s; - uint16 tick; - uint8 index; -} packet_queue[MAX_QUEUE]; -static unsigned int queue_hi, queue_lo; - BOOL wave_out_open(void) { @@ -58,7 +49,7 @@ wave_out_open(void) if (dsp_dev == NULL) { - dsp_dev = xstrdup("/dev/dsp"); + dsp_dev = xstrdup(DEFAULTDEVICE); } if ((g_dsp_fd = open(dsp_dev, O_WRONLY)) == -1) @@ -200,32 +191,6 @@ wave_out_volume(uint16 left, uint16 right) } } -void -wave_out_write(STREAM s, uint16 tick, uint8 index) -{ - struct audio_packet *packet = &packet_queue[queue_hi]; - unsigned int next_hi = (queue_hi + 1) % MAX_QUEUE; - - if (next_hi == queue_lo) - { - error("No space to queue audio packet\n"); - return; - } - - queue_hi = next_hi; - - packet->s = *s; - packet->tick = tick; - packet->index = index; - packet->s.p += 4; - - /* we steal the data buffer from s, give it a new one */ - s->data = (uint8 *) malloc(s->size); - - if (!g_dsp_busy) - wave_out_play(); -} - void wave_out_play(void) { @@ -237,13 +202,13 @@ wave_out_play(void) static BOOL started = False; struct timeval tv; - if (queue_lo == queue_hi) + if (rdpsnd_queue_empty()) { g_dsp_busy = 0; return; } - packet = &packet_queue[queue_lo]; + packet = rdpsnd_queue_current_packet(); out = &packet->s; if (!started) @@ -277,9 +242,10 @@ wave_out_play(void) if (elapsed >= (duration * 85) / 100) { - rdpsnd_send_completion(packet->tick, packet->index); - free(out->data); - queue_lo = (queue_lo + 1) % MAX_QUEUE; + /* We need to add 50 to tell windows that time has passed while + * playing this packet */ + rdpsnd_send_completion(packet->tick + 50, packet->index); + rdpsnd_queue_next(); started = False; } else diff --git a/rdpsnd_sgi.c b/rdpsnd_sgi.c index 446066a..5b81928 100644 --- a/rdpsnd_sgi.c +++ b/rdpsnd_sgi.c @@ -28,13 +28,9 @@ #define IRIX_MAX_VOL 65535 -#define MAX_QUEUE 10 - -int g_dsp_fd; ALconfig audioconfig; ALport output_port; -BOOL g_dsp_busy = False; static BOOL g_swapaudio; static int g_snd_rate; static BOOL g_swapaudio; @@ -44,56 +40,46 @@ double min_volume, max_volume, volume_range; int resource, maxFillable; int combinedFrameSize; -static struct audio_packet -{ - struct stream s; - uint16 tick; - uint8 index; -} packet_queue[MAX_QUEUE]; -static unsigned int queue_hi, queue_lo; - BOOL wave_out_open(void) { ALparamInfo pinfo; #if (defined(IRIX_DEBUG)) - fprintf(stderr, "wave_out_open: begin\n"); + fprintf(stderr, "sgi_open: begin\n"); #endif if (alGetParamInfo(AL_DEFAULT_OUTPUT, AL_GAIN, &pinfo) < 0) { - fprintf(stderr, "wave_out_open: alGetParamInfo failed: %s\n", + fprintf(stderr, "sgi_open: alGetParamInfo failed: %s\n", alGetErrorString(oserror())); } min_volume = alFixedToDouble(pinfo.min.ll); max_volume = alFixedToDouble(pinfo.max.ll); volume_range = (max_volume - min_volume); #if (defined(IRIX_DEBUG)) - fprintf(stderr, "wave_out_open: minvol = %lf, maxvol= %lf, range = %lf.\n", + fprintf(stderr, "sgi_open: minvol = %lf, maxvol= %lf, range = %lf.\n", min_volume, max_volume, volume_range); #endif - queue_lo = queue_hi = 0; + rdpsnd_queue_init(); audioconfig = alNewConfig(); if (audioconfig == (ALconfig) 0) { - fprintf(stderr, "wave_out_open: alNewConfig failed: %s\n", - alGetErrorString(oserror())); + fprintf(stderr, "sgi_open: alNewConfig failed: %s\n", alGetErrorString(oserror())); return False; } output_port = alOpenPort("rdpsnd", "w", 0); if (output_port == (ALport) 0) { - fprintf(stderr, "wave_out_open: alOpenPort failed: %s\n", - alGetErrorString(oserror())); + fprintf(stderr, "sgi_open: alOpenPort failed: %s\n", alGetErrorString(oserror())); return False; } #if (defined(IRIX_DEBUG)) - fprintf(stderr, "wave_out_open: returning\n"); + fprintf(stderr, "sgi_open: returning\n"); #endif return True; } @@ -103,21 +89,23 @@ wave_out_close(void) { /* Ack all remaining packets */ #if (defined(IRIX_DEBUG)) - fprintf(stderr, "wave_out_close: begin\n"); + fprintf(stderr, "sgi_close: begin\n"); #endif - while (queue_lo != queue_hi) + while (!rdpsnd_queue_empty()) { - rdpsnd_send_completion(packet_queue[queue_lo].tick, packet_queue[queue_lo].index); - free(packet_queue[queue_lo].s.data); - queue_lo = (queue_lo + 1) % MAX_QUEUE; + /* We need to add 50 to tell windows that time has passed while + * playing this packet */ + rdpsnd_send_completion(rdpsnd_queue_current_packet()->tick + 50, + rdpsnd_queue_current_packet()->index); + rdpsnd_queue_next(); } alDiscardFrames(output_port, 0); alClosePort(output_port); alFreeConfig(audioconfig); #if (defined(IRIX_DEBUG)) - fprintf(stderr, "wave_out_close: returning\n"); + fprintf(stderr, "sgi_close: returning\n"); #endif } @@ -142,7 +130,7 @@ wave_out_set_format(WAVEFORMATEX * pwfx) ALpv params; #if (defined(IRIX_DEBUG)) - fprintf(stderr, "wave_out_set_format: init...\n"); + fprintf(stderr, "sgi_set_format: init...\n"); #endif g_swapaudio = False; @@ -178,7 +166,7 @@ wave_out_set_format(WAVEFORMATEX * pwfx) if (output_port == (ALport) 0) { - fprintf(stderr, "wave_out_set_format: alOpenPort failed: %s\n", + fprintf(stderr, "sgi_set_format: alOpenPort failed: %s\n", alGetErrorString(oserror())); return False; } @@ -192,7 +180,7 @@ wave_out_set_format(WAVEFORMATEX * pwfx) if (frameSize == 0 || channelCount == 0) { - fprintf(stderr, "wave_out_set_format: bad frameSize or channelCount\n"); + fprintf(stderr, "sgi_set_format: bad frameSize or channelCount\n"); return False; } combinedFrameSize = frameSize * channelCount; @@ -213,7 +201,7 @@ wave_out_set_format(WAVEFORMATEX * pwfx) } #if (defined(IRIX_DEBUG)) - fprintf(stderr, "wave_out_set_format: returning...\n"); + fprintf(stderr, "sgi_set_format: returning...\n"); #endif return True; } @@ -226,7 +214,7 @@ wave_out_volume(uint16 left, uint16 right) ALfixed gain[8]; #if (defined(IRIX_DEBUG)) - fprintf(stderr, "wave_out_volume: begin\n"); + fprintf(stderr, "sgi_volume: begin\n"); fprintf(stderr, "left='%d', right='%d'\n", left, right); #endif @@ -241,42 +229,16 @@ wave_out_volume(uint16 left, uint16 right) pv[0].sizeIn = 8; if (alSetParams(AL_DEFAULT_OUTPUT, pv, 1) < 0) { - fprintf(stderr, "wave_out_volume: alSetParams failed: %s\n", + fprintf(stderr, "sgi_volume: alSetParams failed: %s\n", alGetErrorString(oserror())); return; } #if (defined(IRIX_DEBUG)) - fprintf(stderr, "wave_out_volume: returning\n"); + fprintf(stderr, "sgi_volume: returning\n"); #endif } -void -wave_out_write(STREAM s, uint16 tick, uint8 index) -{ - struct audio_packet *packet = &packet_queue[queue_hi]; - unsigned int next_hi = (queue_hi + 1) % MAX_QUEUE; - - if (next_hi == queue_lo) - { - fprintf(stderr, "No space to queue audio packet\n"); - return; - } - - queue_hi = next_hi; - - packet->s = *s; - packet->tick = tick; - packet->index = index; - packet->s.p += 4; - - /* we steal the data buffer from s, give it a new one */ - s->data = malloc(s->size); - - if (!g_dsp_busy) - wave_out_play(); -} - void wave_out_play(void) { @@ -290,13 +252,13 @@ wave_out_play(void) while (1) { - if (queue_lo == queue_hi) + if (rdpsnd_queue_empty()) { g_dsp_busy = False; return; } - packet = &packet_queue[queue_lo]; + packet = rdpsnd_queue_current_packet(); out = &packet->s; /* Swap the current packet, but only once */ @@ -322,8 +284,7 @@ wave_out_play(void) if (gf < (4 * maxFillable / 10)) { rdpsnd_send_completion(packet->tick, packet->index); - free(out->data); - queue_lo = (queue_lo + 1) % MAX_QUEUE; + rdpsnd_queue_next(); swapped = False; } else diff --git a/rdpsnd_sun.c b/rdpsnd_sun.c index 2a9eee7..af9aceb 100644 --- a/rdpsnd_sun.c +++ b/rdpsnd_sun.c @@ -3,7 +3,7 @@ Sound Channel Process Functions - Sun Copyright (C) Matthew Chapman 2003 Copyright (C) GuoJunBo guojunbo@ict.ac.cn 2003 - Copyright (C) Michael Gernoth mike@zerfleddert.de 2003 + Copyright (C) Michael Gernoth mike@zerfleddert.de 2003-2006 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -21,6 +21,7 @@ */ #include "rdesktop.h" +#include "rdpsnd.h" #include #include #include @@ -31,22 +32,12 @@ #include #endif -#define MAX_QUEUE 10 +#define DEFAULTDEVICE "/dev/audio" -int g_dsp_fd; -BOOL g_dsp_busy = False; static BOOL g_reopened; static BOOL g_swapaudio; static short g_samplewidth; -static struct audio_packet -{ - struct stream s; - uint16 tick; - uint8 index; -} packet_queue[MAX_QUEUE]; -static unsigned int queue_hi, queue_lo; - BOOL wave_out_open(void) { @@ -54,7 +45,7 @@ wave_out_open(void) if (dsp_dev == NULL) { - dsp_dev = xstrdup("/dev/audio"); + dsp_dev = xstrdup(DEFAULTDEVICE); } if ((g_dsp_fd = open(dsp_dev, O_WRONLY | O_NONBLOCK)) == -1) @@ -66,7 +57,7 @@ wave_out_open(void) /* Non-blocking so that user interface is responsive */ fcntl(g_dsp_fd, F_SETFL, fcntl(g_dsp_fd, F_GETFL) | O_NONBLOCK); - queue_lo = queue_hi = 0; + rdpsnd_queue_init(); g_reopened = True; return True; @@ -76,11 +67,11 @@ void wave_out_close(void) { /* Ack all remaining packets */ - while (queue_lo != queue_hi) + while (!rdpsnd_queue_empty()) { - rdpsnd_send_completion(packet_queue[queue_lo].tick, packet_queue[queue_lo].index); - free(packet_queue[queue_lo].s.data); - queue_lo = (queue_lo + 1) % MAX_QUEUE; + rdpsnd_send_completion(rdpsnd_queue_current_packet()->tick, + rdpsnd_queue_current_packet()->index); + rdpsnd_queue_next(); } #if defined I_FLUSH && defined FLUSHW @@ -192,32 +183,6 @@ wave_out_volume(uint16 left, uint16 right) } } -void -wave_out_write(STREAM s, uint16 tick, uint8 index) -{ - struct audio_packet *packet = &packet_queue[queue_hi]; - unsigned int next_hi = (queue_hi + 1) % MAX_QUEUE; - - if (next_hi == queue_lo) - { - error("No space to queue audio packet\n"); - return; - } - - queue_hi = next_hi; - - packet->s = *s; - packet->tick = tick; - packet->index = index; - packet->s.p += 4; - - /* we steal the data buffer from s, give it a new one */ - s->data = malloc(s->size); - - if (!g_dsp_busy) - wave_out_play(); -} - void wave_out_play(void) { @@ -243,13 +208,13 @@ wave_out_play(void) g_reopened = False; } - if (queue_lo == queue_hi) + if (rdpsnd_queue_empty()) { g_dsp_busy = 0; return; } - packet = &packet_queue[queue_lo]; + packet = rdpsnd_queue_current_packet(); out = &packet->s; /* Swap the current packet, but only once */ @@ -297,9 +262,10 @@ wave_out_play(void) if (info.play.samples >= samplecnt + ((numsamples * 7) / 10)) { samplecnt += numsamples; - rdpsnd_send_completion(packet->tick, packet->index); - free(out->data); - queue_lo = (queue_lo + 1) % MAX_QUEUE; + /* We need to add 50 to tell windows that time has passed while + * playing this packet */ + rdpsnd_send_completion(packet->tick + 50, packet->index); + rdpsnd_queue_next(); swapped = False; sentcompletion = True; }