rdpsnd/alsa: support volume change.
This commit is contained in:
parent
106b20cbb0
commit
229d4e0d3c
@ -36,6 +36,7 @@ struct rdpsnd_alsa_plugin
|
|||||||
|
|
||||||
char* device_name;
|
char* device_name;
|
||||||
snd_pcm_t* out_handle;
|
snd_pcm_t* out_handle;
|
||||||
|
snd_mixer_t* mixer_handle;
|
||||||
uint32 source_rate;
|
uint32 source_rate;
|
||||||
uint32 actual_rate;
|
uint32 actual_rate;
|
||||||
snd_pcm_format_t format;
|
snd_pcm_format_t format;
|
||||||
@ -153,6 +154,42 @@ static void rdpsnd_alsa_set_format(rdpsndDevicePlugin* device, rdpsndFormat* for
|
|||||||
rdpsnd_alsa_set_params(alsa);
|
rdpsnd_alsa_set_params(alsa);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void rdpsnd_alsa_open_mixer(rdpsndAlsaPlugin* alsa)
|
||||||
|
{
|
||||||
|
int error;
|
||||||
|
snd_mixer_t* handle;
|
||||||
|
|
||||||
|
error = snd_mixer_open(&handle, 0);
|
||||||
|
if (error < 0)
|
||||||
|
{
|
||||||
|
DEBUG_WARN("snd_mixer_open failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
error = snd_mixer_attach(handle, alsa->device_name);
|
||||||
|
if (error < 0)
|
||||||
|
{
|
||||||
|
DEBUG_WARN("snd_mixer_attach failed");
|
||||||
|
snd_mixer_close(handle);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
error = snd_mixer_selem_register(handle, NULL, NULL);
|
||||||
|
if (error < 0)
|
||||||
|
{
|
||||||
|
DEBUG_WARN("snd_mixer_selem_register failed");
|
||||||
|
snd_mixer_close(handle);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
error = snd_mixer_load(handle);
|
||||||
|
if (error < 0)
|
||||||
|
{
|
||||||
|
DEBUG_WARN("snd_mixer_load failed");
|
||||||
|
snd_mixer_close(handle);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
alsa->mixer_handle = handle;
|
||||||
|
}
|
||||||
|
|
||||||
static void rdpsnd_alsa_open(rdpsndDevicePlugin* device, rdpsndFormat* format, int latency)
|
static void rdpsnd_alsa_open(rdpsndDevicePlugin* device, rdpsndFormat* format, int latency)
|
||||||
{
|
{
|
||||||
rdpsndAlsaPlugin* alsa = (rdpsndAlsaPlugin*)device;
|
rdpsndAlsaPlugin* alsa = (rdpsndAlsaPlugin*)device;
|
||||||
@ -173,6 +210,7 @@ static void rdpsnd_alsa_open(rdpsndDevicePlugin* device, rdpsndFormat* format, i
|
|||||||
{
|
{
|
||||||
freerdp_dsp_context_reset_adpcm(alsa->dsp_context);
|
freerdp_dsp_context_reset_adpcm(alsa->dsp_context);
|
||||||
rdpsnd_alsa_set_format(device, format, latency);
|
rdpsnd_alsa_set_format(device, format, latency);
|
||||||
|
rdpsnd_alsa_open_mixer(alsa);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,6 +225,11 @@ static void rdpsnd_alsa_close(rdpsndDevicePlugin* device)
|
|||||||
snd_pcm_close(alsa->out_handle);
|
snd_pcm_close(alsa->out_handle);
|
||||||
alsa->out_handle = 0;
|
alsa->out_handle = 0;
|
||||||
}
|
}
|
||||||
|
if (alsa->mixer_handle)
|
||||||
|
{
|
||||||
|
snd_mixer_close(alsa->mixer_handle);
|
||||||
|
alsa->mixer_handle = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rdpsnd_alsa_free(rdpsndDevicePlugin* device)
|
static void rdpsnd_alsa_free(rdpsndDevicePlugin* device)
|
||||||
@ -228,6 +271,32 @@ static boolean rdpsnd_alsa_format_supported(rdpsndDevicePlugin* device, rdpsndFo
|
|||||||
|
|
||||||
static void rdpsnd_alsa_set_volume(rdpsndDevicePlugin* device, uint32 value)
|
static void rdpsnd_alsa_set_volume(rdpsndDevicePlugin* device, uint32 value)
|
||||||
{
|
{
|
||||||
|
rdpsndAlsaPlugin* alsa = (rdpsndAlsaPlugin*)device;
|
||||||
|
long left;
|
||||||
|
long right;
|
||||||
|
long volume_min;
|
||||||
|
long volume_max;
|
||||||
|
long volume_left;
|
||||||
|
long volume_right;
|
||||||
|
snd_mixer_elem_t* elem;
|
||||||
|
|
||||||
|
if (!alsa->mixer_handle)
|
||||||
|
return;
|
||||||
|
|
||||||
|
left = (value & 0xFFFF);
|
||||||
|
right = ((value >> 16) & 0xFFFF);
|
||||||
|
|
||||||
|
for (elem = snd_mixer_first_elem(alsa->mixer_handle); elem; elem = snd_mixer_elem_next(elem))
|
||||||
|
{
|
||||||
|
if (snd_mixer_selem_has_playback_volume(elem))
|
||||||
|
{
|
||||||
|
snd_mixer_selem_get_playback_volume_range(elem, &volume_min, &volume_max);
|
||||||
|
volume_left = volume_min + (left * (volume_max - volume_min)) / 0xFFFF;
|
||||||
|
volume_right = volume_min + (right * (volume_max - volume_min)) / 0xFFFF;
|
||||||
|
snd_mixer_selem_set_playback_volume(elem, SND_MIXER_SCHN_FRONT_LEFT, volume_left);
|
||||||
|
snd_mixer_selem_set_playback_volume(elem, SND_MIXER_SCHN_FRONT_RIGHT, volume_right);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rdpsnd_alsa_play(rdpsndDevicePlugin* device, uint8* data, int size)
|
static void rdpsnd_alsa_play(rdpsndDevicePlugin* device, uint8* data, int size)
|
||||||
|
@ -172,8 +172,8 @@ static void rdpsnd_process_message_formats(rdpsndPlugin* rdpsnd, STREAM* data_in
|
|||||||
stream_write_uint8(data_out, SNDC_FORMATS); /* msgType */
|
stream_write_uint8(data_out, SNDC_FORMATS); /* msgType */
|
||||||
stream_write_uint8(data_out, 0); /* bPad */
|
stream_write_uint8(data_out, 0); /* bPad */
|
||||||
stream_seek_uint16(data_out); /* BodySize */
|
stream_seek_uint16(data_out); /* BodySize */
|
||||||
stream_write_uint32(data_out, TSSNDCAPS_ALIVE); /* dwFlags */
|
stream_write_uint32(data_out, TSSNDCAPS_ALIVE | TSSNDCAPS_VOLUME); /* dwFlags */
|
||||||
stream_write_uint32(data_out, 0); /* dwVolume */
|
stream_write_uint32(data_out, 0xFFFFFFFF); /* dwVolume */
|
||||||
stream_write_uint32(data_out, 0); /* dwPitch */
|
stream_write_uint32(data_out, 0); /* dwPitch */
|
||||||
stream_write_uint16_be(data_out, 0); /* wDGramPort */
|
stream_write_uint16_be(data_out, 0); /* wDGramPort */
|
||||||
stream_seek_uint16(data_out); /* wNumberOfFormats */
|
stream_seek_uint16(data_out); /* wNumberOfFormats */
|
||||||
|
Loading…
Reference in New Issue
Block a user