Seite 1 von 1

Verständnisproblem bei Nutzung einer Bitmaske

Verfasst: Dienstag 8. September 2009, 14:45
von snafu
Hi,

ich schreibe im Moment an einem Modul, das die Nutzung der Mixereigenschaften von [mod]ossaudiodev[/mod] vereinfachen soll. Sofern ich denn durchhalte, soll daraus später mal eine kleine Bibliothek speziell für Python-Programme, die Mixer-Interfaces bieten wollen, entstehen.

Mein Problem ist gerade das Testen auf Verfügbarkeit von einem "Control". Hierzu möchte ich unter Verwendung von oss_mixer_device.controls() einen Wahrheitswert zurückgeben. Aus dem Beispiel in der Doku werde ich nicht so recht schlau. IMHO ist dort die Ausgabe von controls() gar nicht mit dem anderen Test verknüpft. Es wird in dem Fall einfach 16 zurückgegeben. Um ehrlich zu sein: Ich weiß überhaupt nicht, was man an dieser Stelle tun soll. :(

Das habe ich bisher:

Code: Alles auswählen

import ossaudiodev

# Wrapper dictionary around the SOUND_MIXER_* constants defined by the
# ossaudiodev module.
# E.g.: CONTROLS['VOLUME'] -> value of ossaudiodev.SOUND_MIXER_VOLUME

CONTROLS = dict(
    (
        (name.split('_')[2], getattr(ossaudiodev, name))
        for name in dir(ossaudiodev)
        if name.startswith('SOUND_MIXER')
    )
)


class Mixer(object):

    def __init__(self, device_path='/dev/mixer'):
        self.device = ossaudiodev.openmixer(device_path)

    def close(self):
        self.device.close()

    def get_fileno(self):
        return self.device.fileno()

    def has_control(self, control):
        return self.device.controls() and (1 << control)

Verfasst: Dienstag 8. September 2009, 15:12
von EyDu
Dein "and" muss ein "&" sein. Schau dir mal den Unterschied zwischen "logischem Und" und "bitweisem Und" an. Dann verstehst du vielleicht auch schon dein Problem.

Verfasst: Dienstag 8. September 2009, 15:43
von snafu
Danke. Das war echt noch Neuland für mich...

Ich mache jetzt:

Code: Alles auswählen

return bool(self.device.controls() & (1 << control))

Re: Verständnisproblem bei Nutzung einer Bitmaske

Verfasst: Dienstag 8. September 2009, 15:50
von Leonidas
snafu hat geschrieben:Es wird in dem Fall einfach 16 zurückgegeben. Um ehrlich zu sein: Ich weiß überhaupt nicht, was man an dieser Stelle tun soll. :(
Binärdarstellung ansehen:

Dezimal 16 entspricht in Binär 10000, d.h. da ist ein Bit gesetzt. Wenn man jetzt etwa rausfinden will ob ``ossaudiodev.SOUND_MIXER_PCM`` gesetzt ist nimmt man 1 und shiftet es es viermal nach rechts (also quasi verdoppelt man den Wert vier mal). Dadurch bekommt man 16 oder eben 10000. Jetzt will man prüfen ob die Bits gesetzt sind: 10000 & 10000 gibt 10000, da 1 & 1 = 0 und 0 & 0 = 0 ist. Das Ergebnis ist also 10000, was positiv ist also True.

Angenommen du hättest statt der 16 die 15, dann wäre die Binärdarstellung 1111 und das mit 10000 verundet gibt dann 00000 was dezimal der Null entspricht, also False.

Verfasst: Dienstag 8. September 2009, 17:03
von snafu
So ganz zuverlässig scheint es bei mir nicht zu funktionieren:

Code: Alles auswählen

In [1]: import pymixer

In [2]: mixer = pymixer.Mixer()

In [3]: mixer.get_controls()
Out[3]: 
['MIC',
 'VOLUME',
 'SPEAKER',
 'PCM',
 'PHONEOUT',
 'LINE',
 'IGAIN',
 'VIDEO',
 'DIGITAL1',
 'CD',
 'LINE1',
 'PHONEIN']

In [4]: mixer.get_volume('LINE3')
Out[4]: (100, 100)
Normalerweise soll die erste Funktion die verfügbaren Controls ausgeben, indem der besagte Test angwendet wird. Anschließend müsste mir das OSS-Modul laut Doku eine Exception werfen, wenn ich auf nicht unterstützte Controls zugreife. Das passiert allerdings nicht.

Code