[modules] Use voice volume control while in call. Contributes to JB#7560

This commit is contained in:
Juho Hämäläinen 2013-07-19 23:21:49 +03:00
parent 0f91f8cf1a
commit d20d11ee4c
3 changed files with 49 additions and 10 deletions

View file

@ -78,6 +78,8 @@ struct userdata {
audio_devices_t primary_devices;
audio_devices_t enabled_devices;
pa_bool_t use_hw_volume;
pa_droid_config_audio *config; /* Only used when used without card */
pa_droid_hw_module *hw_module;
struct audio_stream_out *stream_out;
@ -407,33 +409,44 @@ static void sink_set_volume_cb(pa_sink *s) {
float val = pa_sw_volume_to_linear(r.values[0]);
pa_log_debug("Set hw volume %f", val);
if (u->stream_out->set_volume(u->stream_out, val, val) < 0)
return;
pa_log_warn("Failed to set hw volume.");
} else if (r.channels == 2) {
float val[2];
for (unsigned i = 0; i < 2; i++)
val[i] = pa_sw_volume_to_linear(r.values[i]);
pa_log_debug("Set hw volume %f : %f", val[0], val[1]);
if (u->stream_out->set_volume(u->stream_out, val[0], val[1]) < 0)
return;
pa_log_warn("Failed to set hw volume.");
}
}
static void sink_set_voice_volume_cb(pa_sink *s) {
struct userdata *u = s->userdata;
pa_cvolume r;
float val;
/* Shift up by the base volume */
pa_sw_cvolume_divide_scalar(&r, &s->real_volume, s->base_volume);
val = pa_sw_volume_to_linear(pa_cvolume_avg(&r));
pa_log_debug("Set voice volume %f", val);
if (u->hw_module->device->set_voice_volume(u->hw_module->device, val) < 0)
pa_log_warn("Failed to set voice volume.");
}
static void update_volumes(struct userdata *u) {
int ret = -1;
/* set_volume returns 0 if hw volume control is implemented, < 0 otherwise. */
if (u->stream_out->set_volume) {
pa_log_debug("Probe hw volume support for %s", u->sink->name);
ret = u->stream_out->set_volume(u->stream_out, 1.0f, 1.0f);
}
/* Use hardware volume */
if (ret == 0) {
pa_log_debug("Using hardware volume control for %s", u->sink->name);
pa_sink_set_set_volume_callback(u->sink, sink_set_volume_cb);
} else {
pa_log_debug("Using software volume control for %s", u->sink->name);
pa_sink_set_set_volume_callback(u->sink, NULL);
}
u->use_hw_volume = (ret == 0);
/* Apply callbacks */
pa_droid_sink_set_voice_control(u->sink, FALSE);
}
static void set_sink_name(pa_modargs *ma, pa_sink_new_data *data, const char *module_id) {
@ -454,6 +467,26 @@ static void set_sink_name(pa_modargs *ma, pa_sink_new_data *data, const char *mo
}
}
void pa_droid_sink_set_voice_control(pa_sink* sink, pa_bool_t enable) {
struct userdata *u = sink->userdata;
pa_assert(u);
pa_assert(sink);
if (enable) {
pa_log_debug("Using voice volume control for %s", u->sink->name);
pa_sink_set_set_volume_callback(u->sink, sink_set_voice_volume_cb);
} else {
if (u->use_hw_volume) {
pa_log_debug("Using hardware volume control for %s", u->sink->name);
pa_sink_set_set_volume_callback(u->sink, sink_set_volume_cb);
} else {
pa_log_debug("Using software volume control for %s", u->sink->name);
pa_sink_set_set_volume_callback(u->sink, NULL);
}
}
}
pa_sink *pa_droid_sink_new(pa_module *m,
pa_modargs *ma,
const char *driver,

View file

@ -52,4 +52,6 @@ pa_sink *pa_droid_sink_new(pa_module *m,
pa_card *card);
void pa_droid_sink_free(pa_sink *s);
void pa_droid_sink_set_voice_control(pa_sink* sink, pa_bool_t enable);
#endif

View file

@ -292,11 +292,15 @@ static int card_set_profile(pa_card *c, pa_card_profile *new_profile) {
/* Transfer ownership of sinks and sources to
* call profile */
u->call_profile.old_profile = od->profile;
pa_droid_sink_set_voice_control(u->call_profile.old_profile->output->sink, TRUE);
return 0;
}
if (od->profile == u->call_profile.profile) {
pa_assert(u->call_profile.old_profile);
set_call_mode(u, AUDIO_MODE_NORMAL);
pa_droid_sink_set_voice_control(u->call_profile.old_profile->output->sink, FALSE);
/* If new profile is the same as from which we switched to
* call profile, transfer ownership back to that profile.