diff --git a/channels/audin/client/alsa/audin_alsa.c b/channels/audin/client/alsa/audin_alsa.c index 33c852057..6ec44fdc4 100644 --- a/channels/audin/client/alsa/audin_alsa.c +++ b/channels/audin/client/alsa/audin_alsa.c @@ -31,7 +31,7 @@ #include #include -#include +#include #include #include "audin_main.h" diff --git a/channels/audin/client/pulse/audin_pulse.c b/channels/audin/client/pulse/audin_pulse.c index 75b1e4cdf..2d4906ea2 100644 --- a/channels/audin/client/pulse/audin_pulse.c +++ b/channels/audin/client/pulse/audin_pulse.c @@ -32,7 +32,7 @@ #include #include -#include +#include #include "audin_main.h" diff --git a/channels/audin/server/audin.c b/channels/audin/server/audin.c index 06d135b02..ec6eb4ffb 100644 --- a/channels/audin/server/audin.c +++ b/channels/audin/server/audin.c @@ -27,7 +27,7 @@ #include -#include +#include #include #include #include diff --git a/channels/rdpsnd/client/alsa/rdpsnd_alsa.c b/channels/rdpsnd/client/alsa/rdpsnd_alsa.c index 0df9c6a48..6070cd5db 100644 --- a/channels/rdpsnd/client/alsa/rdpsnd_alsa.c +++ b/channels/rdpsnd/client/alsa/rdpsnd_alsa.c @@ -32,7 +32,7 @@ #include #include -#include +#include #include #include "rdpsnd_main.h" @@ -44,7 +44,7 @@ struct rdpsnd_alsa_plugin rdpsndDevicePlugin device; char* device_name; - snd_pcm_t* out_handle; + snd_pcm_t* pcm_handle; snd_mixer_t* mixer_handle; UINT32 source_rate; UINT32 actual_rate; @@ -58,20 +58,25 @@ struct rdpsnd_alsa_plugin BYTE* audio_data; UINT32 audio_data_size; UINT32 audio_data_left; - snd_pcm_uframes_t chunk_size; + snd_pcm_uframes_t period_size; + snd_async_handler_t* pcm_callback; FREERDP_DSP_CONTEXT* dsp_context; }; +void rdpsnd_alsa_async_handler(snd_async_handler_t* pcm_callback); + static void rdpsnd_alsa_set_params(rdpsndAlsaPlugin* alsa) { int status; snd_pcm_hw_params_t* hw_params; snd_pcm_sw_params_t* sw_params; - snd_pcm_uframes_t frames; snd_pcm_uframes_t start_threshold; + snd_pcm_uframes_t buffer_size; - snd_pcm_drop(alsa->out_handle); + snd_pcm_drop(alsa->pcm_handle); + + snd_async_add_pcm_handler(&alsa->pcm_callback, alsa->pcm_handle, rdpsnd_alsa_async_handler, (void*) alsa); status = snd_pcm_hw_params_malloc(&hw_params); @@ -81,24 +86,25 @@ static void rdpsnd_alsa_set_params(rdpsndAlsaPlugin* alsa) return; } - snd_pcm_hw_params_any(alsa->out_handle, hw_params); - snd_pcm_hw_params_set_access(alsa->out_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED); - snd_pcm_hw_params_set_format(alsa->out_handle, hw_params, alsa->format); - snd_pcm_hw_params_set_rate_near(alsa->out_handle, hw_params, &alsa->actual_rate, NULL); - snd_pcm_hw_params_set_channels_near(alsa->out_handle, hw_params, &alsa->actual_channels); - snd_pcm_hw_params_get_period_size(hw_params, &alsa->chunk_size, 0); + snd_pcm_hw_params_any(alsa->pcm_handle, hw_params); + snd_pcm_hw_params_set_access(alsa->pcm_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED); + snd_pcm_hw_params_set_format(alsa->pcm_handle, hw_params, alsa->format); + snd_pcm_hw_params_set_rate_near(alsa->pcm_handle, hw_params, &alsa->actual_rate, NULL); + snd_pcm_hw_params_set_channels_near(alsa->pcm_handle, hw_params, &alsa->actual_channels); + snd_pcm_hw_params_get_period_size(hw_params, &alsa->period_size, 0); alsa->audio_data_left = 0; if (alsa->latency < 0) - frames = alsa->actual_rate * 4 / 10; /* Default to 400ms buffer */ + buffer_size = alsa->actual_rate * 4 / 10; /* Default to 400ms buffer */ else - frames = alsa->latency * alsa->actual_rate * 2 / 1000; /* Double of the latency */ + buffer_size = alsa->latency * alsa->actual_rate * 2 / 1000; /* Double of the latency */ - if (frames < alsa->actual_rate / 2) - frames = alsa->actual_rate / 2; /* Minimum 0.5-second buffer */ + if (buffer_size < alsa->actual_rate / 2) + buffer_size = alsa->actual_rate / 2; /* Minimum 0.5-second buffer */ - snd_pcm_hw_params_set_buffer_size_near(alsa->out_handle, hw_params, &frames); - snd_pcm_hw_params(alsa->out_handle, hw_params); + snd_pcm_hw_params_set_buffer_size_near(alsa->pcm_handle, hw_params, &buffer_size); + //snd_pcm_hw_params_set_period_size_near(alsa->out_handle, hw_params, &alsa->period_size, NULL); + snd_pcm_hw_params(alsa->pcm_handle, hw_params); snd_pcm_hw_params_free(hw_params); status = snd_pcm_sw_params_malloc(&sw_params); @@ -109,21 +115,21 @@ static void rdpsnd_alsa_set_params(rdpsndAlsaPlugin* alsa) return; } - snd_pcm_sw_params_current(alsa->out_handle, sw_params); + snd_pcm_sw_params_current(alsa->pcm_handle, sw_params); if (alsa->latency == 0) start_threshold = 0; else - start_threshold = frames / 2; + start_threshold = buffer_size / 2; - snd_pcm_sw_params_set_start_threshold(alsa->out_handle, sw_params, start_threshold); - snd_pcm_sw_params(alsa->out_handle, sw_params); + snd_pcm_sw_params_set_start_threshold(alsa->pcm_handle, sw_params, start_threshold); + snd_pcm_sw_params(alsa->pcm_handle, sw_params); snd_pcm_sw_params_free(sw_params); - snd_pcm_prepare(alsa->out_handle); + snd_pcm_prepare(alsa->pcm_handle); DEBUG_SVC("hardware buffer %d frames, playback buffer %.2g seconds", - (int) frames, (double) frames / 2.0 / (double) alsa->actual_rate); + (int) buffer_size, (double) buffer_size / 2.0 / (double) alsa->actual_rate); if ((alsa->actual_rate != alsa->source_rate) || (alsa->actual_channels != alsa->source_channels)) { @@ -134,7 +140,7 @@ static void rdpsnd_alsa_set_params(rdpsndAlsaPlugin* alsa) static void rdpsnd_alsa_set_format(rdpsndDevicePlugin* device, rdpsndFormat* format, int latency) { - rdpsndAlsaPlugin* alsa = (rdpsndAlsaPlugin*)device; + rdpsndAlsaPlugin* alsa = (rdpsndAlsaPlugin*) device; if (format != NULL) { @@ -148,10 +154,14 @@ static void rdpsnd_alsa_set_format(rdpsndDevicePlugin* device, rdpsndFormat* for case WAVE_FORMAT_PCM: switch (format->wBitsPerSample) { + case 4: + break; + case 8: alsa->format = SND_PCM_FORMAT_S8; alsa->bytes_per_channel = 1; break; + case 16: alsa->format = SND_PCM_FORMAT_S16_LE; alsa->bytes_per_channel = 2; @@ -220,15 +230,19 @@ static void rdpsnd_alsa_open_mixer(rdpsndAlsaPlugin* alsa) static void rdpsnd_alsa_open(rdpsndDevicePlugin* device, rdpsndFormat* format, int latency) { + int mode; int status; rdpsndAlsaPlugin* alsa = (rdpsndAlsaPlugin*) device; - if (alsa->out_handle != 0) + if (alsa->pcm_handle != 0) return; DEBUG_SVC("opening"); - status = snd_pcm_open(&alsa->out_handle, alsa->device_name, SND_PCM_STREAM_PLAYBACK, 0); + mode = 0; + //mode |= SND_PCM_NONBLOCK; + + status = snd_pcm_open(&alsa->pcm_handle, alsa->device_name, SND_PCM_STREAM_PLAYBACK, mode); if (status < 0) { @@ -246,12 +260,12 @@ static void rdpsnd_alsa_close(rdpsndDevicePlugin* device) { rdpsndAlsaPlugin* alsa = (rdpsndAlsaPlugin*)device; - if (alsa->out_handle != 0) + if (alsa->pcm_handle != 0) { DEBUG_SVC("close"); - snd_pcm_drain(alsa->out_handle); - snd_pcm_close(alsa->out_handle); - alsa->out_handle = 0; + snd_pcm_drain(alsa->pcm_handle); + snd_pcm_close(alsa->pcm_handle); + alsa->pcm_handle = 0; } if (alsa->mixer_handle) @@ -344,6 +358,18 @@ static void rdpsnd_alsa_set_volume(rdpsndDevicePlugin* device, UINT32 value) } } +void rdpsnd_alsa_async_handler(snd_async_handler_t* pcm_callback) +{ + snd_pcm_t* pcm_handle; + snd_pcm_sframes_t avail; + rdpsndAlsaPlugin* alsa; + + pcm_handle = snd_async_handler_get_pcm(pcm_callback); + alsa = (rdpsndAlsaPlugin*) snd_async_handler_get_callback_private(pcm_callback); + + avail = snd_pcm_avail_update(pcm_handle); +} + static void rdpsnd_alsa_play(rdpsndDevicePlugin* device, BYTE* data, int size) { BYTE* src; @@ -356,17 +382,17 @@ static void rdpsnd_alsa_play(rdpsndDevicePlugin* device, BYTE* data, int size) BYTE* end; rdpsndAlsaPlugin* alsa = (rdpsndAlsaPlugin*) device; - if (alsa->out_handle == 0) + if (alsa->pcm_handle == 0) return; - if (alsa->wformat == 2) + if (alsa->wformat == WAVE_FORMAT_ADPCM) { alsa->dsp_context->decode_ms_adpcm(alsa->dsp_context, data, size, alsa->source_channels, alsa->block_size); size = alsa->dsp_context->adpcm_size; src = alsa->dsp_context->adpcm_buffer; } - else if (alsa->wformat == 0x11) + else if (alsa->wformat == WAVE_FORMAT_DVI_ADPCM) { alsa->dsp_context->decode_ima_adpcm(alsa->dsp_context, data, size, alsa->source_channels, alsa->block_size); @@ -411,27 +437,29 @@ static void rdpsnd_alsa_play(rdpsndDevicePlugin* device, BYTE* data, int size) alsa->audio_data_size = alsa->audio_data_left + size; } - memcpy(alsa->audio_data + alsa->audio_data_left, src, size); + CopyMemory(alsa->audio_data + alsa->audio_data_left, src, size); alsa->audio_data_left += size; pindex = alsa->audio_data; end = pindex + alsa->audio_data_left; - while (pindex + alsa->chunk_size * rbytes_per_frame <= end) + printf("audio_data_left: %d\n", alsa->audio_data_left); + + while (pindex + alsa->period_size * rbytes_per_frame <= end) { len = end - pindex; - status = snd_pcm_writei(alsa->out_handle, pindex, alsa->chunk_size); + status = snd_pcm_writei(alsa->pcm_handle, pindex, alsa->period_size); if (status == -EPIPE) { - snd_pcm_recover(alsa->out_handle, status, 0); + snd_pcm_recover(alsa->pcm_handle, status, 0); status = 0; } else if (status < 0) { - DEBUG_WARN("status %d", status); - snd_pcm_close(alsa->out_handle); - alsa->out_handle = 0; + DEBUG_WARN("snd_pcm_writei status %d", status); + snd_pcm_close(alsa->pcm_handle); + alsa->pcm_handle = 0; rdpsnd_alsa_open(device, NULL, alsa->latency); break; } @@ -441,7 +469,7 @@ static void rdpsnd_alsa_play(rdpsndDevicePlugin* device, BYTE* data, int size) if ((pindex <= end) && (pindex != alsa->audio_data)) { - memcpy(alsa->audio_data, pindex, end - pindex); + CopyMemory(alsa->audio_data, pindex, end - pindex); alsa->audio_data_left = end - pindex; } } @@ -450,10 +478,10 @@ static void rdpsnd_alsa_start(rdpsndDevicePlugin* device) { rdpsndAlsaPlugin* alsa = (rdpsndAlsaPlugin*) device; - if (alsa->out_handle == 0) + if (!alsa->pcm_handle) return; - snd_pcm_start(alsa->out_handle); + snd_pcm_start(alsa->pcm_handle); } COMMAND_LINE_ARGUMENT_A rdpsnd_alsa_args[] = @@ -519,7 +547,7 @@ int freerdp_rdpsnd_client_subsystem_entry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pE if (!alsa->device_name) alsa->device_name = _strdup("default"); - alsa->out_handle = 0; + alsa->pcm_handle = 0; alsa->source_rate = 22050; alsa->actual_rate = 22050; alsa->format = SND_PCM_FORMAT_S16_LE; diff --git a/channels/rdpsnd/client/mac/rdpsnd_mac.c b/channels/rdpsnd/client/mac/rdpsnd_mac.c index eb82d2bc1..86d0cc020 100644 --- a/channels/rdpsnd/client/mac/rdpsnd_mac.c +++ b/channels/rdpsnd/client/mac/rdpsnd_mac.c @@ -32,7 +32,7 @@ #include #include -#include +#include #include #include diff --git a/channels/rdpsnd/client/pulse/rdpsnd_pulse.c b/channels/rdpsnd/client/pulse/rdpsnd_pulse.c index 783534123..694007b58 100644 --- a/channels/rdpsnd/client/pulse/rdpsnd_pulse.c +++ b/channels/rdpsnd/client/pulse/rdpsnd_pulse.c @@ -31,7 +31,7 @@ #include #include -#include +#include #include #include "rdpsnd_main.h" diff --git a/channels/rdpsnd/client/rdpsnd_main.c b/channels/rdpsnd/client/rdpsnd_main.c index ff1401412..e0b07ae87 100644 --- a/channels/rdpsnd/client/rdpsnd_main.c +++ b/channels/rdpsnd/client/rdpsnd_main.c @@ -188,6 +188,7 @@ static void rdpsnd_process_message_formats(rdpsndPlugin* rdpsnd, STREAM* data_in stream_seek_BYTE(data_in); /* bPad */ DEBUG_SVC("wNumberOfFormats %d wVersion %d", wNumberOfFormats, wVersion); + if (wNumberOfFormats < 1) { DEBUG_WARN("wNumberOfFormats is 0"); @@ -232,26 +233,32 @@ static void rdpsnd_process_message_formats(rdpsndPlugin* rdpsnd, STREAM* data_in if (rdpsnd->fixed_format > 0 && rdpsnd->fixed_format != format->wFormatTag) continue; + if (rdpsnd->fixed_channel > 0 && rdpsnd->fixed_channel != format->nChannels) continue; + if (rdpsnd->fixed_rate > 0 && rdpsnd->fixed_rate != format->nSamplesPerSec) continue; + if (rdpsnd->device && rdpsnd->device->FormatSupported(rdpsnd->device, format)) { DEBUG_SVC("format supported."); stream_check_size(data_out, 18 + format->cbSize); stream_write(data_out, format_mark, 18 + format->cbSize); + if (format->cbSize > 0) { format->data = malloc(format->cbSize); - memcpy(format->data, data_mark, format->cbSize); + CopyMemory(format->data, data_mark, format->cbSize); } + n_out_formats++; } } rdpsnd->n_supported_formats = n_out_formats; + if (n_out_formats > 0) { rdpsnd->supported_formats = out_formats; @@ -354,7 +361,7 @@ static void rdpsnd_process_message_wave(rdpsndPlugin* rdpsnd, STREAM* data_in) rdpsnd->expectingWave = 0; - memcpy(stream_get_head(data_in), rdpsnd->waveData, 4); + CopyMemory(stream_get_head(data_in), rdpsnd->waveData, 4); if (stream_get_size(data_in) != rdpsnd->waveDataSize) { diff --git a/channels/rdpsnd/client/winmm/rdpsnd_winmm.c b/channels/rdpsnd/client/winmm/rdpsnd_winmm.c index dc4bd7f14..8c92f817c 100644 --- a/channels/rdpsnd/client/winmm/rdpsnd_winmm.c +++ b/channels/rdpsnd/client/winmm/rdpsnd_winmm.c @@ -33,7 +33,7 @@ #include #include -#include +#include #include #include "rdpsnd_main.h" diff --git a/channels/rdpsnd/server/rdpsnd.c b/channels/rdpsnd/server/rdpsnd.c index 0b499f929..0215369e7 100644 --- a/channels/rdpsnd/server/rdpsnd.c +++ b/channels/rdpsnd/server/rdpsnd.c @@ -27,7 +27,7 @@ #include -#include +#include #include #include #include diff --git a/channels/tsmf/client/alsa/tsmf_alsa.c b/channels/tsmf/client/alsa/tsmf_alsa.c index 393f62ea8..74c78a744 100644 --- a/channels/tsmf/client/alsa/tsmf_alsa.c +++ b/channels/tsmf/client/alsa/tsmf_alsa.c @@ -32,7 +32,7 @@ #include #include -#include +#include #include "tsmf_audio.h" diff --git a/include/freerdp/utils/dsp.h b/include/freerdp/codec/dsp.h similarity index 95% rename from include/freerdp/utils/dsp.h rename to include/freerdp/codec/dsp.h index e2e209059..301eb2651 100644 --- a/include/freerdp/utils/dsp.h +++ b/include/freerdp/codec/dsp.h @@ -17,8 +17,8 @@ * limitations under the License. */ -#ifndef FREERDP_UTILS_DSP_H -#define FREERDP_UTILS_DSP_H +#ifndef FREERDP_CODEC_DSP_H +#define FREERDP_CODEC_DSP_H #include @@ -40,6 +40,7 @@ union _ADPCM typedef union _ADPCM ADPCM; typedef struct _FREERDP_DSP_CONTEXT FREERDP_DSP_CONTEXT; + struct _FREERDP_DSP_CONTEXT { BYTE* resampled_buffer; @@ -81,5 +82,5 @@ FREERDP_API void freerdp_dsp_context_free(FREERDP_DSP_CONTEXT* context); } #endif -#endif /* FREERDP_UTILS_DSP_H */ +#endif /* FREERDP_CODEC_DSP_H */ diff --git a/libfreerdp/codec/CMakeLists.txt b/libfreerdp/codec/CMakeLists.txt index 3e7717977..6c9615125 100644 --- a/libfreerdp/codec/CMakeLists.txt +++ b/libfreerdp/codec/CMakeLists.txt @@ -19,6 +19,7 @@ set(MODULE_NAME "freerdp-codec") set(MODULE_PREFIX "FREERDP_CODEC") set(${MODULE_PREFIX}_SRCS + dsp.c bitmap.c color.c rfx_bitstream.h diff --git a/libfreerdp/utils/dsp.c b/libfreerdp/codec/dsp.c similarity index 99% rename from libfreerdp/utils/dsp.c rename to libfreerdp/codec/dsp.c index 881d969a8..e4b1a9725 100644 --- a/libfreerdp/utils/dsp.c +++ b/libfreerdp/codec/dsp.c @@ -28,7 +28,8 @@ #include #include -#include + +#include static void freerdp_dsp_resample(FREERDP_DSP_CONTEXT* context, const BYTE* src, int bytes_per_sample, diff --git a/libfreerdp/utils/CMakeLists.txt b/libfreerdp/utils/CMakeLists.txt index ba14e9e42..73b37e78a 100644 --- a/libfreerdp/utils/CMakeLists.txt +++ b/libfreerdp/utils/CMakeLists.txt @@ -19,7 +19,6 @@ set(MODULE_NAME "freerdp-utils") set(MODULE_PREFIX "FREERDP_UTILS") set(${MODULE_PREFIX}_SRCS - dsp.c event.c bitmap.c list.c