channels/rdpsnd: cleanup

This commit is contained in:
Marc-André Moreau 2013-02-25 21:46:48 -05:00
parent efb0a15fc9
commit 2b9174a69b
16 changed files with 170 additions and 342 deletions

View File

@ -134,8 +134,8 @@ static BOOL audin_server_recv_formats(audin_server* audin, STREAM* s, UINT32 len
if (audin->context.num_client_formats <= 0)
return FALSE;
audin->context.client_formats = malloc(audin->context.num_client_formats * sizeof(rdpsndFormat));
ZeroMemory(audin->context.client_formats, audin->context.num_client_formats * sizeof(rdpsndFormat));
audin->context.client_formats = malloc(audin->context.num_client_formats * sizeof(AUDIO_FORMAT));
ZeroMemory(audin->context.client_formats, audin->context.num_client_formats * sizeof(AUDIO_FORMAT));
for (i = 0; i < audin->context.num_client_formats; i++)
{
@ -206,7 +206,7 @@ static BOOL audin_server_recv_open_reply(audin_server* audin, STREAM* s, UINT32
static BOOL audin_server_recv_data(audin_server* audin, STREAM* s, UINT32 length)
{
rdpsndFormat* format;
AUDIO_FORMAT* format;
int sbytes_per_sample;
int sbytes_per_frame;
BYTE* src;

View File

@ -45,7 +45,6 @@ struct rdpsnd_alsa_plugin
{
rdpsndDevicePlugin device;
HANDLE thread;
char* device_name;
snd_pcm_t* pcm_handle;
snd_mixer_t* mixer_handle;
@ -58,7 +57,6 @@ struct rdpsnd_alsa_plugin
int wformat;
int block_size;
int latency;
wMessageQueue* queue;
snd_pcm_uframes_t buffer_size;
snd_pcm_uframes_t period_size;
snd_pcm_uframes_t start_threshold;
@ -66,18 +64,6 @@ struct rdpsnd_alsa_plugin
FREERDP_DSP_CONTEXT* dsp_context;
};
struct _RDPSND_WAVE_INFO
{
BYTE* data;
int length;
BYTE cBlockNo;
UINT16 wTimeStamp;
UINT16 wFormatNo;
UINT32 wTimeA;
UINT32 wTimeB;
};
typedef struct _RDPSND_WAVE_INFO RDPSND_WAVE_INFO;
#define SND_PCM_CHECK(_func, _status) \
if (_status < 0) \
{ \
@ -89,6 +75,7 @@ int rdpsnd_alsa_set_hw_params(rdpsndAlsaPlugin* alsa)
{
int status;
snd_pcm_hw_params_t* hw_params;
snd_pcm_uframes_t buffer_size_max;
status = snd_pcm_hw_params_malloc(&hw_params);
SND_PCM_CHECK("snd_pcm_hw_params_malloc", status);
@ -113,9 +100,16 @@ int rdpsnd_alsa_set_hw_params(rdpsndAlsaPlugin* alsa)
SND_PCM_CHECK("snd_pcm_hw_params_set_channels", status);
/* Get maximum buffer size */
status = snd_pcm_hw_params_get_buffer_size_max(hw_params, &alsa->buffer_size);
status = snd_pcm_hw_params_get_buffer_size_max(hw_params, &buffer_size_max);
SND_PCM_CHECK("snd_pcm_hw_params_get_buffer_size_max", status);
if (alsa->buffer_size > buffer_size_max)
{
printf("Warning: requested sound buffer size %d, got %d instead\n",
(int) alsa->buffer_size, (int) buffer_size_max);
alsa->buffer_size = buffer_size_max;
}
/* Set buffer size */
status = snd_pcm_hw_params_set_buffer_size_near(alsa->pcm_handle, hw_params, &alsa->buffer_size);
SND_PCM_CHECK("snd_pcm_hw_params_set_buffer_size_near", status);
@ -141,7 +135,7 @@ int rdpsnd_alsa_set_sw_params(rdpsndAlsaPlugin* alsa)
int status;
snd_pcm_sw_params_t* sw_params;
alsa->start_threshold = alsa->period_size;
alsa->start_threshold = alsa->buffer_size;
status = snd_pcm_sw_params_malloc(&sw_params);
SND_PCM_CHECK("snd_pcm_sw_params_malloc", status);
@ -152,9 +146,6 @@ int rdpsnd_alsa_set_sw_params(rdpsndAlsaPlugin* alsa)
status = snd_pcm_sw_params_set_start_threshold(alsa->pcm_handle, sw_params, alsa->start_threshold);
SND_PCM_CHECK("snd_pcm_sw_params_set_start_threshold", status);
status = snd_pcm_sw_params_set_avail_min(alsa->pcm_handle, sw_params, alsa->buffer_size / 2);
SND_PCM_CHECK("snd_pcm_sw_params_set_avail_min", status);
status = snd_pcm_sw_params(alsa->pcm_handle, sw_params);
SND_PCM_CHECK("snd_pcm_sw_params", status);
@ -175,7 +166,7 @@ int rdpsnd_alsa_validate_params(rdpsndAlsaPlugin* alsa)
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", buffer_size, period_size);
printf("Parameters: BufferSize: %d PeriodSize: %d\n", (int) buffer_size, (int) period_size);
return 0;
}
@ -203,6 +194,11 @@ static int rdpsnd_alsa_set_params(rdpsndAlsaPlugin* alsa)
snd_pcm_drop(alsa->pcm_handle);
if (alsa->latency < 0)
alsa->latency = 250;
alsa->buffer_size = alsa->latency * (alsa->actual_rate / 1000);
if (rdpsnd_alsa_set_hw_params(alsa) < 0)
return -1;
@ -214,7 +210,7 @@ static int rdpsnd_alsa_set_params(rdpsndAlsaPlugin* alsa)
return 0;
}
static void rdpsnd_alsa_set_format(rdpsndDevicePlugin* device, rdpsndFormat* format, int latency)
static void rdpsnd_alsa_set_format(rdpsndDevicePlugin* device, AUDIO_FORMAT* format, int latency)
{
rdpsndAlsaPlugin* alsa = (rdpsndAlsaPlugin*) device;
@ -309,7 +305,7 @@ static void rdpsnd_alsa_open_mixer(rdpsndAlsaPlugin* alsa)
alsa->mixer_handle = handle;
}
static void rdpsnd_alsa_open(rdpsndDevicePlugin* device, rdpsndFormat* format, int latency)
static void rdpsnd_alsa_open(rdpsndDevicePlugin* device, AUDIO_FORMAT* format, int latency)
{
int mode;
int status;
@ -369,7 +365,7 @@ static void rdpsnd_alsa_free(rdpsndDevicePlugin* device)
free(alsa);
}
static BOOL rdpsnd_alsa_format_supported(rdpsndDevicePlugin* device, rdpsndFormat* format)
static BOOL rdpsnd_alsa_format_supported(rdpsndDevicePlugin* device, AUDIO_FORMAT* format)
{
switch (format->wFormatTag)
{
@ -436,161 +432,6 @@ static void rdpsnd_alsa_set_volume(rdpsndDevicePlugin* device, UINT32 value)
}
}
static void* rdpsnd_alsa_schedule_thread(void* arg)
{
BYTE* data;
int length;
int status;
int offset;
int frames;
int frame_size;
wMessage message;
UINT32 wInitialTime;
UINT32 wCurrentTime;
UINT32 wSessionTime;
UINT16 wFixedLatency;
UINT16 wAverageLatency;
UINT16 wAverageSleepLatency;
RDPSND_WAVE_INFO* waveInfo;
snd_pcm_sframes_t available_input;
snd_pcm_sframes_t available_output;
rdpsndAlsaPlugin* alsa = (rdpsndAlsaPlugin*) arg;
rdpsndDevicePlugin* device = (rdpsndDevicePlugin*) arg;
wInitialTime = GetTickCount();
wFixedLatency = 340;
wAverageLatency = wFixedLatency / 2;
wAverageSleepLatency = wFixedLatency / 2;
while (1)
{
if (!MessageQueue_Wait(alsa->queue))
break;
if (!MessageQueue_Peek(alsa->queue, &message, TRUE))
break;
if (message.id == WMQ_QUIT)
break;
frame_size = alsa->actual_channels * alsa->bytes_per_channel;
if (message.id == 0)
{
data = (BYTE*) message.wParam;
length = (int) (size_t) message.lParam;
}
else if (message.id == 1)
{
waveInfo = (RDPSND_WAVE_INFO*) message.wParam;
data = waveInfo->data;
length = waveInfo->length;
}
offset = 0;
available_output = snd_pcm_avail_update(alsa->pcm_handle);
while (offset < length)
{
available_input = (length - offset) / frame_size;
while (available_output < (alsa->buffer_size / 4))
{
snd_pcm_wait(alsa->pcm_handle, -1);
available_output = snd_pcm_avail_update(alsa->pcm_handle);
}
if (available_output > alsa->buffer_size)
{
int gap_ms;
int gap_frames;
gap_frames = available_output - alsa->buffer_size;
gap_ms = gap_frames / (alsa->actual_rate / 1000);
printf("Buffer Underrun Gap: %d ms\n", gap_ms);
}
status = snd_pcm_writei(alsa->pcm_handle, &data[offset],
(available_input < available_output) ? available_input : available_output);
available_output = 0;
if (status == -EPIPE)
{
snd_pcm_recover(alsa->pcm_handle, status, 0);
status = 0;
}
else if (status == -EAGAIN)
{
status = 0;
}
else if (status < 0)
{
DEBUG_WARN("snd_pcm_writei status %d", status);
snd_pcm_close(alsa->pcm_handle);
alsa->pcm_handle = NULL;
rdpsnd_alsa_open((rdpsndDevicePlugin*) alsa, NULL, alsa->latency);
break;
}
available_output = snd_pcm_avail_update(alsa->pcm_handle);
offset += status * frame_size;
}
free(data);
if (message.id == 1)
{
UINT16 wLatency;
UINT16 wTimeStamp;
UINT16 wAudioLength;
UINT16 wSleepLatency;
waveInfo = (RDPSND_WAVE_INFO*) message.wParam;
waveInfo->wTimeB = GetTickCount();
wLatency = (UINT16) (waveInfo->wTimeB - waveInfo->wTimeA);
wTimeStamp = waveInfo->wTimeStamp + wLatency;
frames = length / frame_size;
wAudioLength = frames / (alsa->actual_rate / 1000);
wAverageLatency = (wAverageLatency + wLatency) / 2;
if (wFixedLatency > wLatency)
wSleepLatency = wFixedLatency - wLatency;
else
wSleepLatency = 0;
wSleepLatency = 0;
wAverageSleepLatency = (wAverageSleepLatency + wSleepLatency) / 2;
Sleep(wSleepLatency);
wCurrentTime = GetTickCount();
wSessionTime = wCurrentTime - wInitialTime;
printf("[%06d.%03d] FixedLatency: %d ms AvLatency: %d ms CurrentLatency: %d ms "
"SleepLatency: %d ms AvSleepLatency: %d ms Frames: %d Length: %d ms Channels: %d Rate: %d\n",
wSessionTime / 1000, wSessionTime % 1000,
wFixedLatency, wAverageLatency, wLatency,
wSleepLatency, wAverageSleepLatency,
frames, wAudioLength, alsa->actual_channels, alsa->actual_rate);
wTimeStamp += wSleepLatency;
device->WaveConfirm(device, wTimeStamp, waveInfo->cBlockNo);
free(waveInfo);
}
}
return NULL;
}
BYTE* rdpsnd_process_audio_sample(rdpsndDevicePlugin* device, BYTE* data, int* size)
{
int frames;
@ -638,7 +479,7 @@ BYTE* rdpsnd_process_audio_sample(rdpsndDevicePlugin* device, BYTE* data, int* s
frames = alsa->dsp_context->resampled_frames;
DEBUG_SVC("resampled %d frames at %d to %d frames at %d",
length / srcFrameSize, alsa->source_rate, frames, alsa->actual_rate);
size / srcFrameSize, alsa->source_rate, frames, alsa->actual_rate);
*size = frames * dstFrameSize;
srcData = alsa->dsp_context->resampled_buffer;
@ -649,39 +490,72 @@ BYTE* rdpsnd_process_audio_sample(rdpsndDevicePlugin* device, BYTE* data, int* s
return data;
}
static void rdpsnd_alsa_play(rdpsndDevicePlugin* device, BYTE* data, int size)
static void rdpsnd_alsa_wave_decode(rdpsndDevicePlugin* device, RDPSND_WAVE* wave)
{
BYTE* sample;
rdpsndAlsaPlugin* alsa = (rdpsndAlsaPlugin*) device;
int size;
BYTE* data;
data = rdpsnd_process_audio_sample(device, data, &size);
size = wave->length;
data = rdpsnd_process_audio_sample(device, wave->data, &size);
sample = (BYTE*) malloc(size);
CopyMemory(sample, data, size);
MessageQueue_Post(alsa->queue, (void*) alsa, 0, (void*) sample, (void*) (size_t) size);
wave->data = (BYTE*) malloc(size);
CopyMemory(wave->data, data, size);
wave->length = size;
}
static void rdpsnd_alsa_wave_play(rdpsndDevicePlugin* device,
UINT16 wTimeStamp, UINT16 wFormatNo, BYTE cBlockNo, BYTE* data, int size)
static void rdpsnd_alsa_wave_play(rdpsndDevicePlugin* device, RDPSND_WAVE* wave)
{
RDPSND_WAVE_INFO* waveInfo;
BYTE* data;
int offset;
int length;
int status;
int frame_size;
snd_pcm_sframes_t delay;
rdpsndAlsaPlugin* alsa = (rdpsndAlsaPlugin*) device;
waveInfo = (RDPSND_WAVE_INFO*) malloc(sizeof(RDPSND_WAVE_INFO));
offset = 0;
data = wave->data;
length = wave->length;
frame_size = alsa->actual_channels * alsa->bytes_per_channel;
waveInfo->wTimeA = GetTickCount();
waveInfo->wTimeStamp = wTimeStamp;
waveInfo->wFormatNo = wFormatNo;
waveInfo->cBlockNo = cBlockNo;
snd_pcm_delay(alsa->pcm_handle, &delay);
wave->wPlaybackDelay = ((delay * 1000) / alsa->actual_rate);
//printf("wPlaybackDelay: %d ms\n", wave->wPlaybackDelay);
data = rdpsnd_process_audio_sample(device, data, &size);
while (offset < length)
{
status = snd_pcm_writei(alsa->pcm_handle, &data[offset], (length - offset) / frame_size);
waveInfo->data = (BYTE*) malloc(size);
CopyMemory(waveInfo->data, data, size);
waveInfo->length = size;
if (status == -EPIPE)
{
snd_pcm_recover(alsa->pcm_handle, status, 0);
status = 0;
}
else if (status == -EAGAIN)
{
status = 0;
}
else if (status < 0)
{
printf("status: %d\n", status);
snd_pcm_close(alsa->pcm_handle);
alsa->pcm_handle = NULL;
rdpsnd_alsa_open((rdpsndDevicePlugin*) alsa, NULL, alsa->latency);
break;
}
MessageQueue_Post(alsa->queue, (void*) alsa, 1, (void*) waveInfo, (void*) (size_t) size);
offset += status * frame_size;
}
free(data);
wave->wLocalTimeB = GetTickCount();
wave->wLatency = (UINT16) (wave->wLocalTimeB - wave->wLocalTimeA);
wave->wLatency += wave->wPlaybackDelay;
wave->wLatency += wave->wAudioLength;
wave->wTimeStampB = wave->wTimeStampA + wave->wLatency;
device->WaveConfirm(device, wave);
}
static void rdpsnd_alsa_start(rdpsndDevicePlugin* device)
@ -746,7 +620,7 @@ int freerdp_rdpsnd_client_subsystem_entry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pE
alsa->device.FormatSupported = rdpsnd_alsa_format_supported;
alsa->device.SetFormat = rdpsnd_alsa_set_format;
alsa->device.SetVolume = rdpsnd_alsa_set_volume;
alsa->device.Play = rdpsnd_alsa_play;
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;
@ -770,8 +644,5 @@ int freerdp_rdpsnd_client_subsystem_entry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pE
pEntryPoints->pRegisterRdpsndDevice(pEntryPoints->rdpsnd, (rdpsndDevicePlugin*) alsa);
alsa->queue = MessageQueue_New();
alsa->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) rdpsnd_alsa_schedule_thread, alsa, 0, NULL);
return 0;
}

View File

@ -72,7 +72,7 @@ static void rdpsnd_audio_close(rdpsndDevicePlugin* device)
aq_plugin_p->is_open = 0;
}
static void rdpsnd_audio_open(rdpsndDevicePlugin* device, rdpsndFormat* format, int latency)
static void rdpsnd_audio_open(rdpsndDevicePlugin* device, AUDIO_FORMAT* format, int latency)
{
int rv;
int i;
@ -127,7 +127,7 @@ static void rdpsnd_audio_free(rdpsndDevicePlugin* device)
{
}
static BOOL rdpsnd_audio_format_supported(rdpsndDevicePlugin* device, rdpsndFormat* format)
static BOOL rdpsnd_audio_format_supported(rdpsndDevicePlugin* device, AUDIO_FORMAT* format)
{
switch (format->wFormatTag)
{
@ -144,7 +144,7 @@ static BOOL rdpsnd_audio_format_supported(rdpsndDevicePlugin* device, rdpsndForm
return 0;
}
static void rdpsnd_audio_set_format(rdpsndDevicePlugin* device, rdpsndFormat* format, int latency)
static void rdpsnd_audio_set_format(rdpsndDevicePlugin* device, AUDIO_FORMAT* format, int latency)
{
}

View File

@ -203,7 +203,7 @@ static void rdpsnd_pulse_close(rdpsndDevicePlugin* device)
pa_threaded_mainloop_unlock(pulse->mainloop);
}
static void rdpsnd_pulse_set_format_spec(rdpsndPulsePlugin* pulse, rdpsndFormat* format)
static void rdpsnd_pulse_set_format_spec(rdpsndPulsePlugin* pulse, AUDIO_FORMAT* format)
{
pa_sample_spec sample_spec = { 0 };
@ -249,7 +249,7 @@ static void rdpsnd_pulse_set_format_spec(rdpsndPulsePlugin* pulse, rdpsndFormat*
pulse->block_size = format->nBlockAlign;
}
static void rdpsnd_pulse_open(rdpsndDevicePlugin* device, rdpsndFormat* format, int latency)
static void rdpsnd_pulse_open(rdpsndDevicePlugin* device, AUDIO_FORMAT* format, int latency)
{
pa_stream_state_t state;
pa_stream_flags_t flags;
@ -371,7 +371,7 @@ static void rdpsnd_pulse_free(rdpsndDevicePlugin* device)
free(pulse);
}
static BOOL rdpsnd_pulse_format_supported(rdpsndDevicePlugin* device, rdpsndFormat* format)
static BOOL rdpsnd_pulse_format_supported(rdpsndDevicePlugin* device, AUDIO_FORMAT* format)
{
rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)device;
@ -414,7 +414,7 @@ static BOOL rdpsnd_pulse_format_supported(rdpsndDevicePlugin* device, rdpsndForm
return FALSE;
}
static void rdpsnd_pulse_set_format(rdpsndDevicePlugin* device, rdpsndFormat* format, int latency)
static void rdpsnd_pulse_set_format(rdpsndDevicePlugin* device, AUDIO_FORMAT* format, int latency)
{
rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*) device;

View File

@ -67,8 +67,6 @@ struct rdpsnd_plugin
BYTE waveData[4];
UINT16 waveDataSize;
UINT32 wTimeStamp;
UINT32 wLastTimeStamp;
UINT32 wave_timestamp;
BOOL is_open;
UINT32 close_timestamp;
@ -85,6 +83,8 @@ struct rdpsnd_plugin
rdpsndDevicePlugin* device;
};
void rdpsnd_send_wave_confirm_pdu(rdpsndPlugin* rdpsnd, UINT16 wTimeStamp, BYTE cConfirmedBlockNo);
static void* rdpsnd_schedule_thread(void* arg)
{
STREAM* data;
@ -92,6 +92,7 @@ static void* rdpsnd_schedule_thread(void* arg)
UINT16 wTimeDiff;
UINT16 wTimeStamp;
UINT16 wCurrentTime;
RDPSND_WAVE* wave;
rdpsndPlugin* rdpsnd = (rdpsndPlugin*) arg;
while (1)
@ -105,39 +106,20 @@ static void* rdpsnd_schedule_thread(void* arg)
if (message.id == WMQ_QUIT)
break;
wTimeStamp = (UINT16) (size_t) message.lParam;
wave = (RDPSND_WAVE*) message.wParam;
wCurrentTime = (UINT16) GetTickCount();
//printf("wTimeStamp: %d wCurrentTime: %d\n", wTimeStamp, wCurrentTime);
wTimeStamp = wave->wLocalTimeB;
if (wCurrentTime <= wTimeStamp)
{
wTimeDiff = wTimeStamp - wCurrentTime;
//printf("Sleeping %d ms\n", wTimeDiff);
Sleep(wTimeDiff);
}
data = (STREAM*) message.wParam;
svc_plugin_send((rdpSvcPlugin*) rdpsnd, data);
DEBUG_SVC("processed output data");
rdpsnd_send_wave_confirm_pdu(rdpsnd, wave->wTimeStampB, wave->cBlockNo);
free(wave);
}
#if 0
if (rdpsnd->is_open && (rdpsnd->close_timestamp > 0))
{
if (GetTickCount() > rdpsnd->close_timestamp)
{
if (rdpsnd->device)
IFCALL(rdpsnd->device->Close, rdpsnd->device);
rdpsnd->is_open = FALSE;
rdpsnd->close_timestamp = 0;
DEBUG_SVC("processed close");
}
}
#endif
return NULL;
}
@ -174,17 +156,6 @@ void rdpsnd_free_audio_formats(AUDIO_FORMAT* formats, UINT16 count)
}
}
void rdpsnd_adapt_audio_formats_new_to_old(rdpsndFormat* oldFormat, AUDIO_FORMAT* newFormat)
{
oldFormat->wFormatTag = newFormat->wFormatTag;
oldFormat->nChannels = newFormat->nChannels;
oldFormat->nSamplesPerSec = newFormat->nSamplesPerSec;
oldFormat->nBlockAlign = newFormat->nBlockAlign;
oldFormat->wBitsPerSample = newFormat->wBitsPerSample;
oldFormat->cbSize = newFormat->cbSize;
oldFormat->data = newFormat->data;
}
char* rdpsnd_get_audio_tag_string(UINT16 wFormatTag)
{
switch (wFormatTag)
@ -235,7 +206,6 @@ UINT32 rdpsnd_compute_audio_time_length(AUDIO_FORMAT* format, int size)
void rdpsnd_select_supported_audio_formats(rdpsndPlugin* rdpsnd)
{
int index;
rdpsndFormat sndFormat;
AUDIO_FORMAT* serverFormat;
AUDIO_FORMAT* clientFormat;
@ -258,13 +228,7 @@ void rdpsnd_select_supported_audio_formats(rdpsndPlugin* rdpsnd)
if (rdpsnd->fixed_rate > 0 && (rdpsnd->fixed_rate != serverFormat->nSamplesPerSec))
continue;
/**
* FIXME: temporary adapter to avoid breaking code depending on rdpsndFormat definition
*/
rdpsnd_adapt_audio_formats_new_to_old(&sndFormat, serverFormat);
if (rdpsnd->device && rdpsnd->device->FormatSupported(rdpsnd->device, &sndFormat))
if (rdpsnd->device && rdpsnd->device->FormatSupported(rdpsnd->device, serverFormat))
{
clientFormat = &rdpsnd->ClientFormats[rdpsnd->NumberOfClientFormats++];
@ -413,7 +377,6 @@ static void rdpsnd_recv_wave_info_pdu(rdpsndPlugin* rdpsnd, STREAM* s, UINT16 Bo
{
UINT16 wFormatNo;
AUDIO_FORMAT* format;
rdpsndFormat sndFormat;
stream_read_UINT16(s, rdpsnd->wTimeStamp);
stream_read_UINT16(s, wFormatNo);
@ -422,12 +385,10 @@ static void rdpsnd_recv_wave_info_pdu(rdpsndPlugin* rdpsnd, STREAM* s, UINT16 Bo
stream_read(s, rdpsnd->waveData, 4);
rdpsnd->waveDataSize = BodySize - 8;
rdpsnd->wave_timestamp = GetTickCount();
rdpsnd->expectingWave = TRUE;
rdpsnd->close_timestamp = 0;
format = &rdpsnd->ClientFormats[wFormatNo];
rdpsnd_adapt_audio_formats_new_to_old(&sndFormat, format);
if (!rdpsnd->is_open)
{
@ -436,7 +397,7 @@ static void rdpsnd_recv_wave_info_pdu(rdpsndPlugin* rdpsnd, STREAM* s, UINT16 Bo
if (rdpsnd->device)
{
IFCALL(rdpsnd->device->Open, rdpsnd->device, &sndFormat, rdpsnd->latency);
IFCALL(rdpsnd->device->Open, rdpsnd->device, format, rdpsnd->latency);
}
}
else if (wFormatNo != rdpsnd->wCurrentFormatNo)
@ -445,7 +406,7 @@ static void rdpsnd_recv_wave_info_pdu(rdpsndPlugin* rdpsnd, STREAM* s, UINT16 Bo
if (rdpsnd->device)
{
IFCALL(rdpsnd->device->SetFormat, rdpsnd->device, &sndFormat, rdpsnd->latency);
IFCALL(rdpsnd->device->SetFormat, rdpsnd->device, format, rdpsnd->latency);
}
}
}
@ -465,28 +426,16 @@ void rdpsnd_send_wave_confirm_pdu(rdpsndPlugin* rdpsnd, UINT16 wTimeStamp, BYTE
svc_plugin_send((rdpSvcPlugin*) rdpsnd, pdu);
}
void rdpsnd_device_send_wave_confirm_pdu(rdpsndDevicePlugin* device, UINT16 wTimeStamp, BYTE cConfirmedBlockNo)
void rdpsnd_device_send_wave_confirm_pdu(rdpsndDevicePlugin* device, RDPSND_WAVE* wave)
{
rdpsnd_send_wave_confirm_pdu(device->rdpsnd, wTimeStamp, cConfirmedBlockNo);
}
UINT32 rdpsnd_device_wave_length(rdpsndDevicePlugin* device, int wFormatNo, int size)
{
UINT32 wAudioLength;
AUDIO_FORMAT* format;
format = &device->rdpsnd->ClientFormats[wFormatNo];
wAudioLength = rdpsnd_compute_audio_time_length(format, size);
return wAudioLength;
MessageQueue_Post(device->rdpsnd->MsgPipe->Out, NULL, 0, (void*) wave, NULL);
}
static void rdpsnd_recv_wave_pdu(rdpsndPlugin* rdpsnd, STREAM* s)
{
int size;
BYTE* data;
UINT16 wTimeStamp;
UINT16 wAudioLength;
RDPSND_WAVE* wave;
AUDIO_FORMAT* format;
rdpsnd->expectingWave = FALSE;
@ -503,39 +452,41 @@ static void rdpsnd_recv_wave_pdu(rdpsndPlugin* rdpsnd, STREAM* s)
data = stream_get_head(s);
size = stream_get_size(s);
wave = (RDPSND_WAVE*) malloc(sizeof(RDPSND_WAVE));
wave->wLocalTimeA = GetTickCount();
wave->wTimeStampA = rdpsnd->wTimeStamp;
wave->wFormatNo = rdpsnd->wCurrentFormatNo;
wave->cBlockNo = rdpsnd->cBlockNo;
wave->data = data;
wave->length = size;
format = &rdpsnd->ClientFormats[rdpsnd->wCurrentFormatNo];
wAudioLength = rdpsnd_compute_audio_time_length(format, size);
wave->wAudioLength = rdpsnd_compute_audio_time_length(format, size);
rdpsnd->device->WavePlay = NULL;
if (!rdpsnd->device)
return;
if (rdpsnd->device)
if (rdpsnd->device->WaveDecode)
{
if (rdpsnd->device->WavePlay)
{
IFCALL(rdpsnd->device->WavePlay, rdpsnd->device, rdpsnd->wTimeStamp,
rdpsnd->wCurrentFormatNo, rdpsnd->cBlockNo, data, size);
}
else
{
IFCALL(rdpsnd->device->Play, rdpsnd->device, data, size);
}
IFCALL(rdpsnd->device->WaveDecode, rdpsnd->device, wave);
}
if (rdpsnd->device->WavePlay)
{
IFCALL(rdpsnd->device->WavePlay, rdpsnd->device, wave);
}
else
{
IFCALL(rdpsnd->device->Play, rdpsnd->device, data, size);
}
if (!rdpsnd->device->WavePlay)
{
STREAM* pdu;
wTimeStamp = rdpsnd->wTimeStamp + wAudioLength + TIME_DELAY_MS;
pdu = stream_new(8);
stream_write_BYTE(pdu, SNDC_WAVECONFIRM);
stream_write_BYTE(pdu, 0);
stream_write_UINT16(pdu, 4);
stream_write_UINT16(pdu, wTimeStamp);
stream_write_BYTE(pdu, rdpsnd->cBlockNo); /* cConfirmedBlockNo */
stream_write_BYTE(pdu, 0); /* bPad */
wTimeStamp = rdpsnd->wave_timestamp + wAudioLength + TIME_DELAY_MS;
MessageQueue_Post(rdpsnd->MsgPipe->Out, NULL, 0, (void*) pdu, (void*) (size_t) wTimeStamp);
wave->wTimeStampB = rdpsnd->wTimeStamp + wave->wAudioLength + TIME_DELAY_MS;
wave->wLocalTimeB = wave->wLocalTimeA + wave->wAudioLength + TIME_DELAY_MS;
rdpsnd->device->WaveConfirm(rdpsnd->device, wave);
}
}
@ -625,7 +576,6 @@ static void rdpsnd_register_device_plugin(rdpsndPlugin* rdpsnd, rdpsndDevicePlug
device->rdpsnd = rdpsnd;
device->WaveConfirm = rdpsnd_device_send_wave_confirm_pdu;
device->WaveLength = rdpsnd_device_wave_length;
}
static BOOL rdpsnd_load_device_plugin(rdpsndPlugin* rdpsnd, const char* name, ADDIN_ARGV* args)

View File

@ -22,22 +22,41 @@
#include <freerdp/channels/rdpsnd.h>
struct _RDPSND_WAVE
{
BYTE* data;
int length;
BYTE cBlockNo;
UINT16 wFormatNo;
UINT16 wTimeStampA;
UINT16 wTimeStampB;
UINT16 wLatency;
UINT16 wAudioLength;
UINT16 wPlaybackDelay;
UINT32 wLocalTimeA;
UINT32 wLocalTimeB;
};
typedef struct _RDPSND_WAVE RDPSND_WAVE;
typedef struct rdpsnd_plugin rdpsndPlugin;
typedef struct rdpsnd_device_plugin rdpsndDevicePlugin;
typedef BOOL (*pcFormatSupported) (rdpsndDevicePlugin* device, rdpsndFormat* format);
typedef void (*pcOpen) (rdpsndDevicePlugin* device, rdpsndFormat* format, int latency);
typedef void (*pcSetFormat) (rdpsndDevicePlugin* device, rdpsndFormat* format, int latency);
typedef BOOL (*pcFormatSupported) (rdpsndDevicePlugin* device, AUDIO_FORMAT* format);
typedef void (*pcOpen) (rdpsndDevicePlugin* device, AUDIO_FORMAT* format, int latency);
typedef void (*pcSetFormat) (rdpsndDevicePlugin* device, AUDIO_FORMAT* format, int latency);
typedef void (*pcSetVolume) (rdpsndDevicePlugin* device, UINT32 value);
typedef void (*pcPlay) (rdpsndDevicePlugin* device, BYTE* data, int size);
typedef void (*pcStart) (rdpsndDevicePlugin* device);
typedef void (*pcClose) (rdpsndDevicePlugin* device);
typedef void (*pcFree) (rdpsndDevicePlugin* device);
typedef void (*pcWavePlay) (rdpsndDevicePlugin* device, UINT16 wTimeStamp, UINT16 wFormatNo, BYTE cBlockNo, BYTE* data, int size);
typedef void (*pcWaveConfirm) (rdpsndDevicePlugin* device, UINT16 wTimeStamp, BYTE cConfirmedBlockNo);
typedef UINT32 (*pcWaveLength) (rdpsndDevicePlugin* device, int wFormatNo, int size);
typedef void (*pcWaveDecode) (rdpsndDevicePlugin* device, RDPSND_WAVE* wave);
typedef void (*pcWavePlay) (rdpsndDevicePlugin* device, RDPSND_WAVE* wave);
typedef void (*pcWaveConfirm) (rdpsndDevicePlugin* device, RDPSND_WAVE* wave);
struct rdpsnd_device_plugin
{
@ -52,9 +71,9 @@ struct rdpsnd_device_plugin
pcClose Close;
pcFree Free;
pcWaveDecode WaveDecode;
pcWavePlay WavePlay;
pcWaveConfirm WaveConfirm;
pcWaveLength WaveLength;
};
#define RDPSND_DEVICE_EXPORT_FUNC_NAME "freerdp_rdpsnd_client_subsystem_entry"

View File

@ -63,7 +63,7 @@ struct rdpsnd_winmm_plugin
FREERDP_DSP_CONTEXT* dsp_context;
};
static BOOL rdpsnd_winmm_convert_format(const rdpsndFormat* in, WAVEFORMATEX* out)
static BOOL rdpsnd_winmm_convert_format(const AUDIO_FORMAT* in, WAVEFORMATEX* out)
{
BOOL result = FALSE;
@ -106,7 +106,7 @@ static void rdpsnd_winmm_clear_datablocks(rdpsndWinmmPlugin* winmm, BOOL drain)
}
}
static void rdpsnd_winmm_set_format(rdpsndDevicePlugin* device, rdpsndFormat* format, int latency)
static void rdpsnd_winmm_set_format(rdpsndDevicePlugin* device, AUDIO_FORMAT* format, int latency)
{
rdpsndWinmmPlugin* winmm = (rdpsndWinmmPlugin*)device;
@ -121,7 +121,7 @@ static void rdpsnd_winmm_set_format(rdpsndDevicePlugin* device, rdpsndFormat* fo
winmm->latency = latency;
}
static void rdpsnd_winmm_open(rdpsndDevicePlugin* device, rdpsndFormat* format, int latency)
static void rdpsnd_winmm_open(rdpsndDevicePlugin* device, AUDIO_FORMAT* format, int latency)
{
MMRESULT result;
rdpsndWinmmPlugin* winmm = (rdpsndWinmmPlugin*) device;
@ -167,7 +167,7 @@ static void rdpsnd_winmm_free(rdpsndDevicePlugin* device)
free(winmm);
}
static BOOL rdpsnd_winmm_format_supported(rdpsndDevicePlugin* device, rdpsndFormat* format)
static BOOL rdpsnd_winmm_format_supported(rdpsndDevicePlugin* device, AUDIO_FORMAT* format)
{
MMRESULT result;
WAVEFORMATEX out;

View File

@ -129,8 +129,8 @@ static BOOL rdpsnd_server_recv_formats(rdpsnd_server* rdpsnd, STREAM* s)
if (rdpsnd->context.num_client_formats > 0)
{
rdpsnd->context.client_formats = (rdpsndFormat*) malloc(rdpsnd->context.num_client_formats * sizeof(rdpsndFormat));
ZeroMemory(rdpsnd->context.client_formats, sizeof(rdpsndFormat));
rdpsnd->context.client_formats = (AUDIO_FORMAT*) malloc(rdpsnd->context.num_client_formats * sizeof(AUDIO_FORMAT));
ZeroMemory(rdpsnd->context.client_formats, sizeof(AUDIO_FORMAT));
for (i = 0; i < rdpsnd->context.num_client_formats; i++)
{
@ -255,7 +255,7 @@ static void rdpsnd_server_select_format(rdpsnd_server_context* context, int clie
{
int bs;
int out_buffer_size;
rdpsndFormat *format;
AUDIO_FORMAT *format;
rdpsnd_server* rdpsnd = (rdpsnd_server*) context;
if (client_format_index < 0 || client_format_index >= context->num_client_formats)
@ -309,7 +309,7 @@ static BOOL rdpsnd_server_send_audio_pdu(rdpsnd_server* rdpsnd)
BYTE* src;
int frames;
int fill_size;
rdpsndFormat* format;
AUDIO_FORMAT* format;
int tbytes_per_frame;
STREAM* s = rdpsnd->rdpsnd_pdu;

View File

@ -23,18 +23,6 @@
#include <freerdp/api.h>
#include <freerdp/types.h>
struct rdpsnd_format
{
UINT16 wFormatTag;
UINT16 nChannels;
UINT32 nSamplesPerSec;
UINT16 nBlockAlign;
UINT16 wBitsPerSample;
UINT16 cbSize;
BYTE* data;
};
typedef struct rdpsnd_format rdpsndFormat;
struct AUDIO_FORMAT
{
UINT16 wFormatTag;

View File

@ -41,17 +41,17 @@ struct _audin_server_context
void* data;
/* Server supported formats. Set by server. */
const rdpsndFormat* server_formats;
const AUDIO_FORMAT* server_formats;
int num_server_formats;
/* Server destination PCM audio format. Set by server. */
rdpsndFormat dst_format;
AUDIO_FORMAT dst_format;
/* Server preferred frames per packet. */
int frames_per_packet;
/* Client supported formats. */
rdpsndFormat* client_formats;
AUDIO_FORMAT* client_formats;
int num_client_formats;
int selected_client_format;

View File

@ -41,14 +41,14 @@ struct _rdpsnd_server_context
void* data;
/* Server supported formats. Set by server. */
const rdpsndFormat* server_formats;
const AUDIO_FORMAT* server_formats;
int num_server_formats;
/* Server source PCM audio format. Set by server. */
rdpsndFormat src_format;
AUDIO_FORMAT src_format;
/* Client supported formats. */
rdpsndFormat* client_formats;
AUDIO_FORMAT* client_formats;
int num_client_formats;
int selected_client_format;

View File

@ -25,7 +25,7 @@
#include "mf_audin.h"
static const rdpsndFormat audio_formats[] =
static const AUDIO_FORMAT audio_formats[] =
{
{ 0x11, 2, 22050, 1024, 4, 0, NULL }, /* IMA ADPCM, 22050 Hz, 2 channels */
{ 0x11, 1, 22050, 512, 4, 0, NULL }, /* IMA ADPCM, 22050 Hz, 1 channels */

View File

@ -28,7 +28,7 @@
AQRecorderState recorderState;
static const rdpsndFormat audio_formats[] =
static const AUDIO_FORMAT audio_formats[] =
{
{ 0x11, 2, 22050, 1024, 4, 0, NULL }, /* IMA ADPCM, 22050 Hz, 2 channels */
{ 0x11, 1, 22050, 512, 4, 0, NULL }, /* IMA ADPCM, 22050 Hz, 1 channels */

View File

@ -25,7 +25,7 @@
#include "sf_audin.h"
static const rdpsndFormat test_audio_formats[] =
static const AUDIO_FORMAT test_audio_formats[] =
{
{ 0x11, 2, 22050, 1024, 4, 0, NULL }, /* IMA ADPCM, 22050 Hz, 2 channels */
{ 0x11, 1, 22050, 512, 4, 0, NULL }, /* IMA ADPCM, 22050 Hz, 1 channels */

View File

@ -25,7 +25,7 @@
#include "sf_rdpsnd.h"
static const rdpsndFormat test_audio_formats[] =
static const AUDIO_FORMAT test_audio_formats[] =
{
{ 0x11, 2, 22050, 1024, 4, 0, NULL }, /* IMA ADPCM, 22050 Hz, 2 channels */
{ 0x11, 1, 22050, 512, 4, 0, NULL }, /* IMA ADPCM, 22050 Hz, 1 channels */

View File

@ -41,7 +41,7 @@
#endif
static const rdpsndFormat test_audio_formats[] =
static const AUDIO_FORMAT test_audio_formats[] =
{
{ 0x11, 2, 22050, 1024, 4, 0, NULL }, /* IMA ADPCM, 22050 Hz, 2 channels */
{ 0x11, 1, 22050, 512, 4, 0, NULL }, /* IMA ADPCM, 22050 Hz, 1 channels */