[PATCH 4/4] alsa-mixer: Attempt to detect and then drop redundant paths in the path set.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



'Twas brillig, and David Henningsson at 02/07/11 20:17 did gyre and gimble:
> On 2011-07-02 19:27, Colin Guthrie wrote:
>> This should solve a problem case with some USB Headsets which result in
>> two paths both using the 'Speaker' element when no 'Master' element
>> exists
>> (and even in this case, one of those two paths wouldn't really work
>> anyway due to not actually having h/w volume control due to the absense
>> of 'Master')
> 
> Ehm, are you sure this is working? "Analog output" does not control
> "Speaker" whereas "Analog speaker" does, so how can they turn out to be
> equal in the code below?

Depends what you mean by "working" :p

It "works" in this case, but after thinking about it, it's clearly
broken in a couple ways.

The first is that the terminology I used is wrong... the comment says
they are "redundant" but that's not really what I want to be checking
for.... it's more "pointless".

They turn out to be equal due to this:

D: alsa-sink.c: Probed mixer paths:
D: alsa-mixer.c: Path Set 0x2050c20, direction=1, probed=yes
D: alsa-mixer.c: Path analog-output (Analog Output), direction=1,
priority=99, probed=yes, supported=yes, has_mute=yes, has_volume=no,
has_dB=no, min_volume=0, max_volume=0, min_dB=inf, max_dB=-inf
D: alsa-mixer.c: Element Speaker, direction=1, switch=1, volume=2,
volume_limit=-1, enumeration=0, required=0, required_any=0,
required_absent=0, mask=0x6, n_channels=2, override_map=no
D: alsa-mixer.c: Path analog-output-speaker (Analog Speakers),
direction=1, priority=100, probed=yes, supported=yes, has_mute=yes,
has_volume=yes, has_dB=yes, min_volume=0, max_volume=255, min_dB=-47.87,
max_dB=-0.06
D: alsa-mixer.c: Element Speaker, direction=1, switch=1, volume=1,
volume_limit=-1, enumeration=0, required=4, required_any=0,
required_absent=0, mask=0x3600000000f66, n_channels=2, override_map=yes
D: alsa-mixer.c: Added 2 ports


As you can see both have the same switch status which is all the naive
algorithm checks for (along with the element name).

This is clearly not enough however.


But the primary problem is I don't (but really should) check the
volume_use, but in the Analog Output setup it's set to OFF vs. MERGE for
the Analog Speakers path.

So really the path to be nuked should also have a volume_use of OFF, and
all it's other volume_uses should be OFF too...

Should there be anything else checked? The other variations are the
"required" flag, the mask and the override_map. Are these relevant for
the working out which one to nuke?


Or perhaps it's all simpler than this. Should I just nuke any paths
where all their elements have volume_use==OFF when other paths exist
which don't? This is much simpler and achieves the same result in this case.

Such a check would be:

static void path_set_condense(pa_alsa_path_set *ps) {
    pa_alsa_path *p, *np;

    /* If we only have one path, then don't bother */
    if (!ps->paths || !ps->paths->next)
        return;

    for (p = ps->paths; p; p = np) {
        np = p->next;

        /* Check this current one to see if all elements have volume_off ==
         * PA_ALSA_VOLUME_OFF and if so, nuke 'em */
        if (p->elements) {
            pa_bool_t all_off = TRUE;
            pa_alsa_element *e, *ne;

            for (e = p->elements; e; e = ne) {
                ne = e->next;
                if (e->volume_use != PA_ALSA_VOLUME_OFF) {
                    all_off = FALSE;
                    break;
                }
            }

            if (all_off) {
                pa_log_debug("Removing path '%s' as it does not actively
control any volume elements.", p->name);
                PA_LLIST_REMOVE(pa_alsa_path, ps->paths, p);
                pa_alsa_path_free(p);
            }
        }
    }
}



This works for me, but I dunno if it's too simple or not considering
certain combinations.... my h/w is really simple here so I'd really need
to get debug from other paths... perhaps some don't have any real volume
controls (and thus volume_switch == OFF by default - tho' I'd expect
IGNORE would be more likely); or perhaps OFF and ZERO should both be
considered for nuking? I don't really have enough experience of the
various different h/w to know what's best so perhaps you could make some
more informed suggestions here?

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/]


[Index of Archives]     [Linux Audio Users]     [AMD Graphics]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux