mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-06 13:29:56 -05:00
move flat volume logic into the core. while doing so add n_volume_steps field to sinks/sources
This commit is contained in:
parent
4bfa5d7d13
commit
d5f46e824e
32 changed files with 562 additions and 361 deletions
|
|
@ -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.");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue