From d5f46e824e3f8a042e6f67dd4c3fc385545edd74 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 27 Jan 2009 04:39:07 +0100 Subject: move flat volume logic into the core. while doing so add n_volume_steps field to sinks/sources --- src/modules/alsa/alsa-sink.c | 43 ++++++++------------- src/modules/alsa/alsa-source.c | 43 +++++++++------------ src/modules/module-lirc.c | 4 +- src/modules/module-mmkbd-evdev.c | 4 +- src/modules/module-position-event-sounds.c | 16 ++++---- src/modules/module-raop-sink.c | 32 ++++++--------- src/modules/module-stream-restore.c | 4 +- src/modules/module-tunnel.c | 16 +++----- src/modules/module-volume-restore.c | 2 +- src/modules/oss/module-oss.c | 62 +++++++++++++----------------- 10 files changed, 94 insertions(+), 132 deletions(-) (limited to 'src/modules') diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c index 5020eac1..3503c4a3 100644 --- a/src/modules/alsa/alsa-sink.c +++ b/src/modules/alsa/alsa-sink.c @@ -757,7 +757,7 @@ static long to_alsa_volume(struct userdata *u, pa_volume_t vol) { return PA_CLAMP_UNLIKELY(alsa_vol, u->hw_volume_min, u->hw_volume_max); } -static int sink_get_volume_cb(pa_sink *s) { +static void sink_get_volume_cb(pa_sink *s) { struct userdata *u = s->userdata; int err; unsigned i; @@ -820,27 +820,24 @@ static int sink_get_volume_cb(pa_sink *s) { if (!pa_cvolume_equal(&u->hardware_volume, &r)) { - u->hardware_volume = s->volume = r; + s->virtual_volume = u->hardware_volume = r; if (u->hw_dB_supported) { pa_cvolume reset; /* Hmm, so the hardware volume changed, let's reset our software volume */ - pa_cvolume_reset(&reset, s->sample_spec.channels); pa_sink_set_soft_volume(s, &reset); } } - return 0; + return; fail: pa_log_error("Unable to read volume: %s", snd_strerror(err)); - - return -1; } -static int sink_set_volume_cb(pa_sink *s) { +static void sink_set_volume_cb(pa_sink *s) { struct userdata *u = s->userdata; int err; unsigned i; @@ -857,7 +854,7 @@ static int sink_set_volume_cb(pa_sink *s) { long alsa_vol; pa_volume_t vol; - vol = s->volume.values[i]; + vol = s->virtual_volume.values[i]; if (u->hw_dB_supported) { @@ -894,7 +891,7 @@ static int sink_set_volume_cb(pa_sink *s) { pa_volume_t vol; long alsa_vol; - vol = pa_cvolume_max(&s->volume); + vol = pa_cvolume_max(&s->virtual_volume); if (u->hw_dB_supported) { alsa_vol = (long) (pa_sw_volume_to_dB(vol) * 100); @@ -911,7 +908,7 @@ static int sink_set_volume_cb(pa_sink *s) { VALGRIND_MAKE_MEM_DEFINED(&alsa_vol, sizeof(alsa_vol)); #endif - pa_cvolume_set(&r, s->volume.channels, pa_sw_volume_from_dB((double) (alsa_vol - u->hw_dB_max) / 100.0)); + pa_cvolume_set(&r, s->sample_spec.channels, pa_sw_volume_from_dB((double) (alsa_vol - u->hw_dB_max) / 100.0)); } else { alsa_vol = to_alsa_volume(u, vol); @@ -932,11 +929,9 @@ static int sink_set_volume_cb(pa_sink *s) { char t[PA_CVOLUME_SNPRINT_MAX]; /* Match exactly what the user requested by software */ + pa_sw_cvolume_divide(&s->soft_volume, &s->virtual_volume, &r); - pa_sw_cvolume_divide(&r, &s->volume, &r); - pa_sink_set_soft_volume(s, &r); - - pa_log_debug("Requested volume: %s", pa_cvolume_snprint(t, sizeof(t), &s->volume)); + pa_log_debug("Requested volume: %s", pa_cvolume_snprint(t, sizeof(t), &s->virtual_volume)); pa_log_debug("Got hardware volume: %s", pa_cvolume_snprint(t, sizeof(t), &u->hardware_volume)); pa_log_debug("Calculated software volume: %s", pa_cvolume_snprint(t, sizeof(t), &r)); @@ -945,17 +940,15 @@ static int sink_set_volume_cb(pa_sink *s) { /* We can't match exactly what the user requested, hence let's * at least tell the user about it */ - s->volume = r; + s->virtual_volume = r; - return 0; + return; fail: pa_log_error("Unable to set volume: %s", snd_strerror(err)); - - return -1; } -static int sink_get_mute_cb(pa_sink *s) { +static void sink_get_mute_cb(pa_sink *s) { struct userdata *u = s->userdata; int err, sw; @@ -964,15 +957,13 @@ static int sink_get_mute_cb(pa_sink *s) { if ((err = snd_mixer_selem_get_playback_switch(u->mixer_elem, 0, &sw)) < 0) { pa_log_error("Unable to get switch: %s", snd_strerror(err)); - return -1; + return; } s->muted = !sw; - - return 0; } -static int sink_set_mute_cb(pa_sink *s) { +static void sink_set_mute_cb(pa_sink *s) { struct userdata *u = s->userdata; int err; @@ -981,10 +972,8 @@ static int sink_set_mute_cb(pa_sink *s) { if ((err = snd_mixer_selem_set_playback_switch_all(u->mixer_elem, !s->muted)) < 0) { pa_log_error("Unable to set switch: %s", snd_strerror(err)); - return -1; + return; } - - return 0; } static void sink_update_requested_latency_cb(pa_sink *s) { @@ -1552,6 +1541,8 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca u->sink->flags |= PA_SINK_HW_VOLUME_CTRL | (u->hw_dB_supported ? PA_SINK_DECIBEL_VOLUME : 0); pa_log_info("Using hardware volume control. Hardware dB scale %s.", u->hw_dB_supported ? "supported" : "not supported"); + if (!u->hw_dB_supported) + u->sink->n_volume_steps = u->hw_volume_max - u->hw_volume_min + 1; } else pa_log_info("Using software volume control."); } diff --git a/src/modules/alsa/alsa-source.c b/src/modules/alsa/alsa-source.c index 96e0d89e..c4d34180 100644 --- a/src/modules/alsa/alsa-source.c +++ b/src/modules/alsa/alsa-source.c @@ -703,7 +703,7 @@ static long to_alsa_volume(struct userdata *u, pa_volume_t vol) { return PA_CLAMP_UNLIKELY(alsa_vol, u->hw_volume_min, u->hw_volume_max); } -static int source_get_volume_cb(pa_source *s) { +static void source_get_volume_cb(pa_source *s) { struct userdata *u = s->userdata; int err; unsigned i; @@ -766,27 +766,24 @@ static int source_get_volume_cb(pa_source *s) { if (!pa_cvolume_equal(&u->hardware_volume, &r)) { - u->hardware_volume = s->volume = r; + s->virtual_volume = u->hardware_volume = r; if (u->hw_dB_supported) { pa_cvolume reset; /* Hmm, so the hardware volume changed, let's reset our software volume */ - pa_cvolume_reset(&reset, s->sample_spec.channels); pa_source_set_soft_volume(s, &reset); } } - return 0; + return; fail: pa_log_error("Unable to read volume: %s", snd_strerror(err)); - - return -1; } -static int source_set_volume_cb(pa_source *s) { +static void source_set_volume_cb(pa_source *s) { struct userdata *u = s->userdata; int err; unsigned i; @@ -803,7 +800,7 @@ static int source_set_volume_cb(pa_source *s) { long alsa_vol; pa_volume_t vol; - vol = s->volume.values[i]; + vol = s->virtual_volume.values[i]; if (u->hw_dB_supported) { @@ -840,7 +837,7 @@ static int source_set_volume_cb(pa_source *s) { pa_volume_t vol; long alsa_vol; - vol = pa_cvolume_max(&s->volume); + vol = pa_cvolume_max(&s->virtual_volume); if (u->hw_dB_supported) { alsa_vol = (long) (pa_sw_volume_to_dB(vol) * 100); @@ -857,7 +854,7 @@ static int source_set_volume_cb(pa_source *s) { VALGRIND_MAKE_MEM_DEFINED(&alsa_vol, sizeof(alsa_vol)); #endif - pa_cvolume_set(&r, s->volume.channels, pa_sw_volume_from_dB((double) (alsa_vol - u->hw_dB_max) / 100.0)); + pa_cvolume_set(&r, s->sample_spec.channels, pa_sw_volume_from_dB((double) (alsa_vol - u->hw_dB_max) / 100.0)); } else { alsa_vol = to_alsa_volume(u, vol); @@ -879,10 +876,9 @@ static int source_set_volume_cb(pa_source *s) { /* Match exactly what the user requested by software */ - pa_sw_cvolume_divide(&r, &s->volume, &r); - pa_source_set_soft_volume(s, &r); + pa_sw_cvolume_divide(&s->soft_volume, &s->virtual_volume, &r); - pa_log_debug("Requested volume: %s", pa_cvolume_snprint(t, sizeof(t), &s->volume)); + pa_log_debug("Requested volume: %s", pa_cvolume_snprint(t, sizeof(t), &s->virtual_volume)); pa_log_debug("Got hardware volume: %s", pa_cvolume_snprint(t, sizeof(t), &u->hardware_volume)); pa_log_debug("Calculated software volume: %s", pa_cvolume_snprint(t, sizeof(t), &r)); @@ -891,17 +887,15 @@ static int source_set_volume_cb(pa_source *s) { /* We can't match exactly what the user requested, hence let's * at least tell the user about it */ - s->volume = r; + s->virtual_volume = r; - return 0; + return; fail: pa_log_error("Unable to set volume: %s", snd_strerror(err)); - - return -1; } -static int source_get_mute_cb(pa_source *s) { +static void source_get_mute_cb(pa_source *s) { struct userdata *u = s->userdata; int err, sw; @@ -910,15 +904,13 @@ static int source_get_mute_cb(pa_source *s) { if ((err = snd_mixer_selem_get_capture_switch(u->mixer_elem, 0, &sw)) < 0) { pa_log_error("Unable to get switch: %s", snd_strerror(err)); - return -1; + return; } s->muted = !sw; - - return 0; } -static int source_set_mute_cb(pa_source *s) { +static void source_set_mute_cb(pa_source *s) { struct userdata *u = s->userdata; int err; @@ -927,10 +919,8 @@ static int source_set_mute_cb(pa_source *s) { if ((err = snd_mixer_selem_set_capture_switch_all(u->mixer_elem, !s->muted)) < 0) { pa_log_error("Unable to set switch: %s", snd_strerror(err)); - return -1; + return; } - - return 0; } static void source_update_requested_latency_cb(pa_source *s) { @@ -1372,6 +1362,9 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p u->source->set_volume = source_set_volume_cb; u->source->flags |= PA_SOURCE_HW_VOLUME_CTRL | (u->hw_dB_supported ? PA_SOURCE_DECIBEL_VOLUME : 0); pa_log_info("Using hardware volume control. Hardware dB scale %s.", u->hw_dB_supported ? "supported" : "not supported"); + + if (!u->hw_dB_supported) + u->source->n_volume_steps = u->hw_volume_max - u->hw_volume_min + 1; } else pa_log_info("Using software volume control."); } diff --git a/src/modules/module-lirc.c b/src/modules/module-lirc.c index bbe4f7c0..9a782cac 100644 --- a/src/modules/module-lirc.c +++ b/src/modules/module-lirc.c @@ -135,7 +135,7 @@ static void io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io_event cv.values[i] = PA_VOLUME_NORM; } - pa_sink_set_volume(s, &cv); + pa_sink_set_volume(s, &cv, TRUE, TRUE); break; case DOWN: @@ -146,7 +146,7 @@ static void io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io_event cv.values[i] = PA_VOLUME_MUTED; } - pa_sink_set_volume(s, &cv); + pa_sink_set_volume(s, &cv, TRUE, TRUE); break; case MUTE: diff --git a/src/modules/module-mmkbd-evdev.c b/src/modules/module-mmkbd-evdev.c index aa6832bf..a379923a 100644 --- a/src/modules/module-mmkbd-evdev.c +++ b/src/modules/module-mmkbd-evdev.c @@ -126,7 +126,7 @@ static void io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io_event cv.values[i] = PA_VOLUME_NORM; } - pa_sink_set_volume(s, &cv); + pa_sink_set_volume(s, &cv, TRUE, TRUE); break; case DOWN: @@ -137,7 +137,7 @@ static void io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io_event cv.values[i] = PA_VOLUME_MUTED; } - pa_sink_set_volume(s, &cv); + pa_sink_set_volume(s, &cv, TRUE, TRUE); break; case MUTE_TOGGLE: diff --git a/src/modules/module-position-event-sounds.c b/src/modules/module-position-event-sounds.c index 90e693a3..e75b1c50 100644 --- a/src/modules/module-position-event-sounds.c +++ b/src/modules/module-position-event-sounds.c @@ -101,23 +101,23 @@ static pa_hook_result_t sink_input_fixate_hook_callback(pa_core *core, pa_sink_i pa_log_debug("Positioning event sound '%s' at %0.2f.", pa_strnull(pa_proplist_gets(data->proplist, PA_PROP_EVENT_ID)), f); - if (!data->volume_is_set) { - pa_cvolume_reset(&data->volume, data->sample_spec.channels); - data->volume_is_set = TRUE; + if (!data->virtual_volume_is_set) { + pa_cvolume_reset(&data->virtual_volume, data->sample_spec.channels); + data->virtual_volume_is_set = TRUE; } for (c = 0; c < data->sample_spec.channels; c++) { if (is_left(data->channel_map.map[c])) - data->volume.values[c] = - pa_sw_volume_multiply(data->volume.values[c], (pa_volume_t) (PA_VOLUME_NORM * (1.0 - f))); + data->virtual_volume.values[c] = + pa_sw_volume_multiply(data->virtual_volume.values[c], (pa_volume_t) (PA_VOLUME_NORM * (1.0 - f))); if (is_right(data->channel_map.map[c])) - data->volume.values[c] = - pa_sw_volume_multiply(data->volume.values[c], (pa_volume_t) (PA_VOLUME_NORM * f)); + data->virtual_volume.values[c] = + pa_sw_volume_multiply(data->virtual_volume.values[c], (pa_volume_t) (PA_VOLUME_NORM * f)); } - pa_log_debug("Final volume %s.", pa_cvolume_snprint(t, sizeof(t), &data->volume)); + pa_log_debug("Final volume %s.", pa_cvolume_snprint(t, sizeof(t), &data->virtual_volume)); return PA_HOOK_OK; } diff --git a/src/modules/module-raop-sink.c b/src/modules/module-raop-sink.c index bb93ca84..02ef2aae 100644 --- a/src/modules/module-raop-sink.c +++ b/src/modules/module-raop-sink.c @@ -255,20 +255,17 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse return pa_sink_process_msg(o, code, data, offset, chunk); } -static int sink_get_volume_cb(pa_sink *s) { +static void sink_get_volume_cb(pa_sink *s) { struct userdata *u = s->userdata; int i; pa_assert(u); - for (i = 0; i < s->sample_spec.channels; i++) { - s->volume.values[i] = u->volume; - } - - return 0; + for (i = 0; i < s->sample_spec.channels; i++) + s->virtual_volume.values[i] = u->volume; } -static int sink_set_volume_cb(pa_sink *s) { +static void sink_set_volume_cb(pa_sink *s) { struct userdata *u = s->userdata; int rv; @@ -276,39 +273,34 @@ static int sink_set_volume_cb(pa_sink *s) { /* If we're muted, we fake it */ if (u->muted) - return 0; + return; pa_assert(s->sample_spec.channels > 0); /* Avoid pointless volume sets */ - if (u->volume == s->volume.values[0]) - return 0; + if (u->volume == s->virtual_volume.values[0]) + return; - rv = pa_raop_client_set_volume(u->raop, s->volume.values[0]); + rv = pa_raop_client_set_volume(u->raop, s->virtual_volume.values[0]); if (0 == rv) - u->volume = s->volume.values[0]; - - return rv; + u->volume = s->virtual_volume.values[0]; } -static int sink_get_mute_cb(pa_sink *s) { +static void sink_get_mute_cb(pa_sink *s) { struct userdata *u = s->userdata; pa_assert(u); s->muted = u->muted; - return 0; } -static int sink_set_mute_cb(pa_sink *s) { +static void sink_set_mute_cb(pa_sink *s) { struct userdata *u = s->userdata; - int rv; pa_assert(u); - rv = pa_raop_client_set_volume(u->raop, (s->muted ? PA_VOLUME_MUTED : u->volume)); + pa_raop_client_set_volume(u->raop, (s->muted ? PA_VOLUME_MUTED : u->volume)); u->muted = s->muted; - return rv; } static void thread_func(void *userdata) { diff --git a/src/modules/module-stream-restore.c b/src/modules/module-stream-restore.c index 734b2c59..464ff2da 100644 --- a/src/modules/module-stream-restore.c +++ b/src/modules/module-stream-restore.c @@ -334,9 +334,9 @@ static pa_hook_result_t sink_input_fixate_hook_callback(pa_core *c, pa_sink_inpu if (u->restore_volume) { - if (!new_data->volume_is_set) { + if (!new_data->virtual_volume_is_set) { pa_log_info("Restoring volume for sink input %s.", name); - pa_sink_input_new_data_set_volume(new_data, pa_cvolume_remap(&e->volume, &e->channel_map, &new_data->channel_map)); + pa_sink_input_new_data_set_virtual_volume(new_data, pa_cvolume_remap(&e->volume, &e->channel_map, &new_data->channel_map)); } else pa_log_debug("Not restoring volume for sink input %s, because already set.", name); } diff --git a/src/modules/module-tunnel.c b/src/modules/module-tunnel.c index 61b9516a..5c7a6e55 100644 --- a/src/modules/module-tunnel.c +++ b/src/modules/module-tunnel.c @@ -1056,10 +1056,10 @@ static void sink_input_info_cb(pa_pdispatch *pd, uint32_t command, uint32_t tag pa_assert(u->sink); if ((u->version < 11 || !!mute == !!u->sink->muted) && - pa_cvolume_equal(&volume, &u->sink->volume)) + pa_cvolume_equal(&volume, &u->sink->virtual_volume)) return; - memcpy(&u->sink->volume, &volume, sizeof(pa_cvolume)); + memcpy(&u->sink->virtual_volume, &volume, sizeof(pa_cvolume)); if (u->version >= 11) u->sink->muted = !!mute; @@ -1621,7 +1621,7 @@ static void on_connection(pa_socket_client *sc, pa_iochannel *io, void *userdata #ifdef TUNNEL_SINK /* Called from main context */ -static int sink_set_volume(pa_sink *sink) { +static void sink_set_volume(pa_sink *sink) { struct userdata *u; pa_tagstruct *t; uint32_t tag; @@ -1634,14 +1634,12 @@ static int sink_set_volume(pa_sink *sink) { pa_tagstruct_putu32(t, PA_COMMAND_SET_SINK_INPUT_VOLUME); pa_tagstruct_putu32(t, tag = u->ctag++); pa_tagstruct_putu32(t, u->device_index); - pa_tagstruct_put_cvolume(t, &sink->volume); + pa_tagstruct_put_cvolume(t, &sink->virtual_volume); pa_pstream_send_tagstruct(u->pstream, t); - - return 0; } /* Called from main context */ -static int sink_set_mute(pa_sink *sink) { +static void sink_set_mute(pa_sink *sink) { struct userdata *u; pa_tagstruct *t; uint32_t tag; @@ -1651,7 +1649,7 @@ static int sink_set_mute(pa_sink *sink) { pa_assert(u); if (u->version < 11) - return -1; + return; t = pa_tagstruct_new(NULL, 0); pa_tagstruct_putu32(t, PA_COMMAND_SET_SINK_INPUT_MUTE); @@ -1659,8 +1657,6 @@ static int sink_set_mute(pa_sink *sink) { pa_tagstruct_putu32(t, u->device_index); pa_tagstruct_put_boolean(t, !!sink->muted); pa_pstream_send_tagstruct(u->pstream, t); - - return 0; } #endif diff --git a/src/modules/module-volume-restore.c b/src/modules/module-volume-restore.c index bdfd3816..e32552c3 100644 --- a/src/modules/module-volume-restore.c +++ b/src/modules/module-volume-restore.c @@ -443,7 +443,7 @@ static pa_hook_result_t sink_input_fixate_hook_callback(pa_core *c, pa_sink_inpu if (r->volume_is_set && data->sample_spec.channels == r->volume.channels) { pa_log_info("Restoring volume for <%s>", r->name); - pa_sink_input_new_data_set_volume(data, &r->volume); + pa_sink_input_new_data_set_virtual_volume(data, &r->volume); } } diff --git a/src/modules/oss/module-oss.c b/src/modules/oss/module-oss.c index 7271a087..eac0c8e6 100644 --- a/src/modules/oss/module-oss.c +++ b/src/modules/oss/module-oss.c @@ -443,7 +443,6 @@ static pa_usec_t io_sink_get_latency(struct userdata *u) { return r; } - static pa_usec_t io_source_get_latency(struct userdata *u) { pa_usec_t r = 0; @@ -527,9 +526,6 @@ static int suspend(struct userdata *u) { return 0; } -static int sink_get_volume(pa_sink *s); -static int source_get_volume(pa_source *s); - static int unsuspend(struct userdata *u) { int m; pa_sample_spec ss, *ss_original; @@ -620,10 +616,10 @@ static int unsuspend(struct userdata *u) { build_pollfd(u); - if (u->sink && u->sink->get_volume) - u->sink->get_volume(u->sink); - if (u->source && u->source->get_volume) - u->source->get_volume(u->source); + if (u->sink) + pa_sink_get_volume(u->sink, TRUE); + if (u->source) + pa_source_get_volume(u->source, TRUE); pa_log_info("Resumed successfully..."); @@ -798,84 +794,76 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t off return ret; } -static int sink_get_volume(pa_sink *s) { +static void sink_get_volume(pa_sink *s) { struct userdata *u; - int r; pa_assert_se(u = s->userdata); pa_assert(u->mixer_devmask & (SOUND_MASK_VOLUME|SOUND_MASK_PCM)); if (u->mixer_devmask & SOUND_MASK_VOLUME) - if ((r = pa_oss_get_volume(u->mixer_fd, SOUND_MIXER_READ_VOLUME, &s->sample_spec, &s->volume)) >= 0) - return r; + if (pa_oss_get_volume(u->mixer_fd, SOUND_MIXER_READ_VOLUME, &s->sample_spec, &s->virtual_volume) >= 0) + return; if (u->mixer_devmask & SOUND_MASK_PCM) - if ((r = pa_oss_get_volume(u->mixer_fd, SOUND_MIXER_READ_PCM, &s->sample_spec, &s->volume)) >= 0) - return r; + if (pa_oss_get_volume(u->mixer_fd, SOUND_MIXER_READ_PCM, &s->sample_spec, &s->virtual_volume) >= 0) + return; pa_log_info("Device doesn't support reading mixer settings: %s", pa_cstrerror(errno)); - return -1; } -static int sink_set_volume(pa_sink *s) { +static void sink_set_volume(pa_sink *s) { struct userdata *u; - int r; pa_assert_se(u = s->userdata); pa_assert(u->mixer_devmask & (SOUND_MASK_VOLUME|SOUND_MASK_PCM)); if (u->mixer_devmask & SOUND_MASK_VOLUME) - if ((r = pa_oss_set_volume(u->mixer_fd, SOUND_MIXER_WRITE_VOLUME, &s->sample_spec, &s->volume)) >= 0) - return r; + if (pa_oss_set_volume(u->mixer_fd, SOUND_MIXER_WRITE_VOLUME, &s->sample_spec, &s->virtual_volume) >= 0) + return; if (u->mixer_devmask & SOUND_MASK_PCM) - if ((r = pa_oss_get_volume(u->mixer_fd, SOUND_MIXER_WRITE_PCM, &s->sample_spec, &s->volume)) >= 0) - return r; + if (pa_oss_get_volume(u->mixer_fd, SOUND_MIXER_WRITE_PCM, &s->sample_spec, &s->virtual_volume) >= 0) + return; pa_log_info("Device doesn't support writing mixer settings: %s", pa_cstrerror(errno)); - return -1; } -static int source_get_volume(pa_source *s) { +static void source_get_volume(pa_source *s) { struct userdata *u; - int r; pa_assert_se(u = s->userdata); pa_assert(u->mixer_devmask & (SOUND_MASK_IGAIN|SOUND_MASK_RECLEV)); if (u->mixer_devmask & SOUND_MASK_IGAIN) - if ((r = pa_oss_get_volume(u->mixer_fd, SOUND_MIXER_READ_IGAIN, &s->sample_spec, &s->volume)) >= 0) - return r; + if (pa_oss_get_volume(u->mixer_fd, SOUND_MIXER_READ_IGAIN, &s->sample_spec, &s->virtual_volume) >= 0) + return; if (u->mixer_devmask & SOUND_MASK_RECLEV) - if ((r = pa_oss_get_volume(u->mixer_fd, SOUND_MIXER_READ_RECLEV, &s->sample_spec, &s->volume)) >= 0) - return r; + if (pa_oss_get_volume(u->mixer_fd, SOUND_MIXER_READ_RECLEV, &s->sample_spec, &s->virtual_volume) >= 0) + return; pa_log_info("Device doesn't support reading mixer settings: %s", pa_cstrerror(errno)); - return -1; } -static int source_set_volume(pa_source *s) { +static void source_set_volume(pa_source *s) { struct userdata *u; - int r; pa_assert_se(u = s->userdata); pa_assert(u->mixer_devmask & (SOUND_MASK_IGAIN|SOUND_MASK_RECLEV)); if (u->mixer_devmask & SOUND_MASK_IGAIN) - if ((r = pa_oss_set_volume(u->mixer_fd, SOUND_MIXER_WRITE_IGAIN, &s->sample_spec, &s->volume)) >= 0) - return r; + if (pa_oss_set_volume(u->mixer_fd, SOUND_MIXER_WRITE_IGAIN, &s->sample_spec, &s->virtual_volume) >= 0) + return; if (u->mixer_devmask & SOUND_MASK_RECLEV) - if ((r = pa_oss_get_volume(u->mixer_fd, SOUND_MIXER_WRITE_RECLEV, &s->sample_spec, &s->volume)) >= 0) - return r; + if (pa_oss_get_volume(u->mixer_fd, SOUND_MIXER_WRITE_RECLEV, &s->sample_spec, &s->virtual_volume) >= 0) + return; pa_log_info("Device doesn't support writing mixer settings: %s", pa_cstrerror(errno)); - return -1; } static void thread_func(void *userdata) { @@ -1417,6 +1405,7 @@ int pa__init(pa_module*m) { u->sink->flags |= PA_SINK_HW_VOLUME_CTRL; u->sink->get_volume = sink_get_volume; u->sink->set_volume = sink_set_volume; + u->sink->n_volume_steps = 101; do_close = FALSE; } @@ -1425,6 +1414,7 @@ int pa__init(pa_module*m) { u->source->flags |= PA_SOURCE_HW_VOLUME_CTRL; u->source->get_volume = source_get_volume; u->source->set_volume = source_set_volume; + u->source->n_volume_steps = 101; do_close = FALSE; } } -- cgit