unify queue-handling in rdpsnd.c (remove private copies from all

drivers)


git-svn-id: svn://svn.code.sf.net/p/rdesktop/code/trunk/rdesktop@1253 423420c4-83ab-492f-b58f-81f9feb106b5
This commit is contained in:
Michael Gernoth 2006-09-17 10:32:18 +00:00
parent f4dce045b5
commit ec4862937f
7 changed files with 183 additions and 273 deletions

View File

@ -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;
}
}

36
rdpsnd.h Normal file
View File

@ -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);

View File

@ -21,6 +21,7 @@
*/
#include "rdesktop.h"
#include "rdpsnd.h"
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
@ -28,25 +29,14 @@
#include <sys/time.h>
#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;

View File

@ -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 <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <ao/ao.h>
#include <sys/time.h>
#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;

View File

@ -28,6 +28,7 @@
#endif
#include "rdesktop.h"
#include "rdpsnd.h"
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
@ -35,22 +36,12 @@
#include <sys/ioctl.h>
#include <sys/soundcard.h>
#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

View File

@ -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

View File

@ -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 <unistd.h>
#include <fcntl.h>
#include <errno.h>
@ -31,22 +32,12 @@
#include <stropts.h>
#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;
}