[pulseaudio-discuss] [PATCH 03/11] alsa: Reinitialise the mixer on port change.
Colin Guthrie
gmane at colin.guthr.ie
Wed Jul 20 13:37:01 PDT 2011
'Twas brillig, and Tanu Kaskinen at 20/07/11 19:18 did gyre and gimble:
> On Mon, 2011-07-18 at 11:36 +0100, Colin Guthrie wrote:
>> This allows us to flip from software to hardware volume control as the port's
>> mixer path dictates.
>> ---
>> src/modules/alsa/alsa-sink.c | 114 +++++++++++++++-----------
>> src/modules/alsa/alsa-source.c | 113 +++++++++++++++-----------
>> src/modules/echo-cancel/module-echo-cancel.c | 4 +-
>> src/modules/module-equalizer-sink.c | 2 +-
>> src/modules/module-ladspa-sink.c | 2 +-
>> src/modules/module-virtual-sink.c | 5 +-
>> src/modules/module-virtual-source.c | 5 +-
>> src/pulsecore/sink.c | 87 ++++++++++++++++++--
>> src/pulsecore/sink.h | 2 +
>> src/pulsecore/source.c | 87 ++++++++++++++++++--
>> src/pulsecore/source.h | 2 +
>> 11 files changed, 305 insertions(+), 118 deletions(-)
>>
>> diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c
>> index 0dd1840..cbf75b4 100644
>> --- a/src/modules/alsa/alsa-sink.c
>> +++ b/src/modules/alsa/alsa-sink.c
>> @@ -130,7 +130,7 @@ struct userdata {
>> char *device_name; /* name of the PCM device */
>> char *control_device; /* name of the control device */
>>
>> - pa_bool_t use_mmap:1, use_tsched:1;
>> + pa_bool_t use_mmap:1, use_tsched:1, sync_volume:1;
>>
>> pa_bool_t first, after_rewind;
>>
>> @@ -1372,6 +1372,54 @@ static void sink_set_mute_cb(pa_sink *s) {
>> pa_alsa_path_set_mute(u->mixer_path, u->mixer_handle, s->muted);
>> }
>>
>> +static void mixer_volume_init(struct userdata *u) {
>> + pa_assert(u);
>> +
>> + if (!u->mixer_path->has_volume) {
>> + pa_sink_set_get_volume_callback(u->sink, NULL);
>> + pa_sink_set_set_volume_callback(u->sink, NULL);
>> + pa_sink_set_write_volume_callback(u->sink, NULL);
>
> I think this can crash due to the assertion in
> pa_sink_set_set_volume_callback(). The write_volume callback should be
> set to NULL before setting the set_volume callback to NULL.
>
> Same for source.
ACK. Good catch. I remember keeping this in mind and thinking "I must
make sure I get the order right", but clearly I didn't.
>> +
>> + pa_log_info("Driver does not support hardware volume control, falling back to software volume control.");
>> + } else {
>> + pa_sink_set_get_volume_callback(u->sink, sink_get_volume_cb);
>> + pa_sink_set_set_volume_callback(u->sink, sink_set_volume_cb);
>> + pa_sink_set_write_volume_callback(u->sink, NULL);
>
> I'd rather set the write_volume callback only once, after we know what
> we should set it to. The reason is that this can probably eventually
> trigger a dbus signal, and if the callback is set again a few lines
> later, there will be another signal.
>
> Same for source.
ACK
>> diff --git a/src/modules/module-virtual-sink.c b/src/modules/module-virtual-sink.c
>> index a880df4..5aa6e4f 100644
>> --- a/src/modules/module-virtual-sink.c
>> +++ b/src/modules/module-virtual-sink.c
>> @@ -554,8 +554,7 @@ int pa__init(pa_module*m) {
>> }
>>
>> u->sink = pa_sink_new(m->core, &sink_data, (master->flags & (PA_SINK_LATENCY|PA_SINK_DYNAMIC_LATENCY))
>> - | (use_volume_sharing ? PA_SINK_SHARE_VOLUME_WITH_MASTER : 0)
>> - | (force_flat_volume ? PA_SINK_FLAT_VOLUME : 0));
>> + | (use_volume_sharing ? PA_SINK_SHARE_VOLUME_WITH_MASTER : 0));
>> pa_sink_new_data_done(&sink_data);
>>
>> if (!u->sink) {
>> @@ -569,6 +568,8 @@ int pa__init(pa_module*m) {
>> u->sink->request_rewind = sink_request_rewind_cb;
>> pa_sink_set_set_volume_callback(u->sink, use_volume_sharing ? NULL : sink_set_volume_cb);
>> pa_sink_set_set_mute_callback(u->sink, sink_set_mute_cb);
>> + if (force_flat_volume)
>> + pa_sink_enable_flat_volume(u->sink, TRUE);
>
> Given the implementation of pa_sink_enable_flat_volume, I don't think
> this works. pa_sink_enable_flat_volume only enables flat volume if it's
> enabled in the daemon configuration, and the point of forcing flat
> volume is to enable flat volume even if it's disabled in the daemon
> configuration.
Oh, crap. Sorry I mustn't have read the code properly initially and just
made some assumptions. Sorry and thanks for catching.
> Also, if volume sharing is not used, then decibel volume should be
> explicitly enabled because the set_volume callback is set.
Ahh good point too.
>> diff --git a/src/pulsecore/sink.h b/src/pulsecore/sink.h
>> index c725e88..e6367bc 100644
>> --- a/src/pulsecore/sink.h
>> +++ b/src/pulsecore/sink.h
>> @@ -347,6 +347,8 @@ void pa_sink_set_set_volume_callback(pa_sink *s, pa_sink_cb_t cb);
>> void pa_sink_set_write_volume_callback(pa_sink *s, pa_sink_cb_t cb);
>> void pa_sink_set_get_mute_callback(pa_sink *s, pa_sink_cb_t cb);
>> void pa_sink_set_set_mute_callback(pa_sink *s, pa_sink_cb_t cb);
>> +void pa_sink_enable_decibel_volume(pa_sink *s, pa_bool_t enable);
>> +void pa_sink_enable_flat_volume(pa_sink *s, pa_bool_t enable);
>
> Just a reminder: depending on how you solve the flat volume forcing
> problem, pa_sink_enable_flat_volume() may become unused outside sink.c.
> If that happens, I'd move the function to sink.c and make it static.
>
> Same for source.
Yup, I just gave up and made module-virtual-* set the flat volume flag
manually... Not IMO the most elegant solution but it'll have to do for
now as I can't really stomach it :D
Cheers
Col
--
Colin Guthrie
gmane(at)colin.guthr.ie
http://colin.guthr.ie/
Day Job:
Tribalogic Limited [http://www.tribalogic.net/]
Open Source:
Mageia Contributor [http://www.mageia.org/]
PulseAudio Hacker [http://www.pulseaudio.org/]
Trac Hacker [http://trac.edgewall.org/]
More information about the pulseaudio-discuss
mailing list