{
rdpsndDevicePlugin device;
+ int latency;
+ int wformat;
+ int block_size;
char* device_name;
snd_pcm_t* pcm_handle;
snd_mixer_t* mixer_handle;
UINT32 source_rate;
UINT32 actual_rate;
+ UINT32 wLocalTimeClose;
snd_pcm_format_t format;
UINT32 source_channels;
UINT32 actual_channels;
int bytes_per_channel;
- int wformat;
- int block_size;
- int latency;
snd_pcm_uframes_t buffer_size;
snd_pcm_uframes_t period_size;
snd_pcm_uframes_t start_threshold;
status = snd_pcm_get_params(alsa->pcm_handle, &buffer_size, &period_size);
SND_PCM_CHECK("snd_pcm_get_params", status);
- printf("Parameters: BufferSize: %d PeriodSize: %d\n", (int) buffer_size, (int) period_size);
-
return 0;
}
snd_pcm_drop(alsa->pcm_handle);
if (alsa->latency < 0)
- alsa->latency = 250;
+ alsa->latency = 400;
alsa->buffer_size = alsa->latency * (alsa->actual_rate / 1000);
static void rdpsnd_alsa_close(rdpsndDevicePlugin* device)
{
- rdpsndAlsaPlugin* alsa = (rdpsndAlsaPlugin*)device;
+ int status;
+ snd_htimestamp_t tstamp;
+ snd_pcm_uframes_t frames;
+ rdpsndAlsaPlugin* alsa = (rdpsndAlsaPlugin*) device;
+
+ if (!alsa->pcm_handle)
+ return;
+
+ status = snd_pcm_htimestamp(alsa->pcm_handle, &frames, &tstamp);
+
+ if (status != 0)
+ frames = 0;
+
+ alsa->wLocalTimeClose = GetTickCount();
+ alsa->wLocalTimeClose += (((frames * 1000) / alsa->actual_rate) / alsa->actual_channels);
+}
+
+static void rdpsnd_alsa_free(rdpsndDevicePlugin* device)
+{
+ rdpsndAlsaPlugin* alsa = (rdpsndAlsaPlugin*) device;
if (alsa->pcm_handle)
{
snd_mixer_close(alsa->mixer_handle);
alsa->mixer_handle = NULL;
}
-}
-
-static void rdpsnd_alsa_free(rdpsndDevicePlugin* device)
-{
- rdpsndAlsaPlugin* alsa = (rdpsndAlsaPlugin*) device;
-
- rdpsnd_alsa_close(device);
free(alsa->device_name);
int dstFrameSize;
rdpsndAlsaPlugin* alsa = (rdpsndAlsaPlugin*) device;
- if (!alsa->pcm_handle)
- return NULL;
-
if (alsa->wformat == WAVE_FORMAT_ADPCM)
{
alsa->dsp_context->decode_ms_adpcm(alsa->dsp_context,
int offset;
int length;
int status;
- int frames;
int frame_size;
- snd_htimestamp_t tstampA;
- snd_htimestamp_t tstampB;
- snd_pcm_uframes_t framesA;
- snd_pcm_uframes_t framesB;
+ UINT32 wCurrentTime;
+ snd_htimestamp_t tstamp;
+ snd_pcm_uframes_t frames;
+
rdpsndAlsaPlugin* alsa = (rdpsndAlsaPlugin*) device;
offset = 0;
data = wave->data;
length = wave->length;
frame_size = alsa->actual_channels * alsa->bytes_per_channel;
- frames = (length - offset) / frame_size;
- snd_pcm_htimestamp(alsa->pcm_handle, &framesA, &tstampA);
+ if (alsa->wLocalTimeClose)
+ {
+ wCurrentTime = GetTickCount();
+
+ if (snd_pcm_htimestamp(alsa->pcm_handle, &frames, &tstamp) == -EPIPE)
+ {
+ if (wCurrentTime > alsa->wLocalTimeClose)
+ snd_pcm_recover(alsa->pcm_handle, -EPIPE, 1);
+ }
+
+ alsa->wLocalTimeClose = 0;
+ }
while (offset < length)
{
free(data);
- snd_pcm_htimestamp(alsa->pcm_handle, &framesB, &tstampB);
+ snd_pcm_htimestamp(alsa->pcm_handle, &frames, &tstamp);
- wave->wPlaybackDelay = ((framesB * 1000) / alsa->actual_rate);
+ wave->wPlaybackDelay = ((frames * 1000) / alsa->actual_rate);
wave->wLocalTimeB = GetTickCount();
wave->wLocalTimeB += wave->wPlaybackDelay;
device->WaveConfirm(device, wave);
}
-static void rdpsnd_alsa_start(rdpsndDevicePlugin* device)
-{
- rdpsndAlsaPlugin* alsa = (rdpsndAlsaPlugin*) device;
-
- if (!alsa->pcm_handle)
- return;
-
- snd_pcm_start(alsa->pcm_handle);
-}
-
COMMAND_LINE_ARGUMENT_A rdpsnd_alsa_args[] =
{
{ "dev", COMMAND_LINE_VALUE_REQUIRED, "<device>", NULL, NULL, -1, NULL, "device" },
alsa->device.SetVolume = rdpsnd_alsa_set_volume;
alsa->device.WaveDecode = rdpsnd_alsa_wave_decode;
alsa->device.WavePlay = rdpsnd_alsa_wave_play;
- alsa->device.Start = rdpsnd_alsa_start;
alsa->device.Close = rdpsnd_alsa_close;
alsa->device.Free = rdpsnd_alsa_free;
UINT16 waveDataSize;
UINT32 wTimeStamp;
- BOOL isOpen;
int latency;
+ BOOL isOpen;
UINT16 fixedFormat;
UINT16 fixedChannel;
UINT32 fixedRate;
UINT16 wFormatNo;
AUDIO_FORMAT* format;
+ rdpsnd->expectingWave = TRUE;
+
stream_read_UINT16(s, rdpsnd->wTimeStamp);
stream_read_UINT16(s, wFormatNo);
stream_read_BYTE(s, rdpsnd->cBlockNo);
stream_read(s, rdpsnd->waveData, 4);
rdpsnd->waveDataSize = BodySize - 8;
- rdpsnd->expectingWave = TRUE;
format = &rdpsnd->ClientFormats[wFormatNo];
rdpsnd->isOpen = TRUE;
rdpsnd->wCurrentFormatNo = wFormatNo;
- rdpsnd_print_audio_format(format);
-
if (rdpsnd->device)
{
IFCALL(rdpsnd->device->Open, rdpsnd->device, format, rdpsnd->latency);
if (rdpsnd->device)
{
- IFCALL(rdpsnd->device->Start, rdpsnd->device);
+ IFCALL(rdpsnd->device->Close, rdpsnd->device);
}
+
+ rdpsnd->isOpen = FALSE;
}
static void rdpsnd_recv_volume_pdu(rdpsndPlugin* rdpsnd, STREAM* s)
stream_seek_BYTE(s); /* bPad */
stream_read_UINT16(s, BodySize);
- DEBUG_SVC("msgType %d BodySize %d", msgType, BodySize);
+ //printf("msgType %d BodySize %d\n", msgType, BodySize);
switch (msgType)
{