Browse Source

Use procfs to get list of ALSA PCM devices

pull/118/head
Christopher Arndt 9 years ago
parent
commit
9796a3d192
2 changed files with 92 additions and 23 deletions
  1. +85
    -0
      src/alsainfo.py
  2. +7
    -23
      src/jacksettings.py

+ 85
- 0
src/alsainfo.py View File

@@ -0,0 +1,85 @@
# -*- coding: utf-8 -*-
"""Get ALSA card and device list."""

import re

from io import open
from collections import namedtuple
from functools import partial
from os.path import exists

__all__ = (
'AlsaCardInfo',
'AlsaPcmInfo',
'get_cards',
'get_capture_devices',
'get_playback_devices',
'get_pcm_devices'
)

PROC_CARDS = '/proc/asound/cards'
PROC_DEVICES = '/proc/asound/pcm'

AlsaCardInfo = namedtuple('AlsaCardInfo', 'card_num id name')
AlsaPcmInfo = namedtuple('AlsaPcmInfo',
'card_num dev_num id name playback capture')


def get_cards():
"""Get card info from /proc/asound/cards."""

if not exists(PROC_CARDS):
raise IOError("'%s' does not exist. ALSA not loaded?" % PROC_CARDS)

with open(PROC_CARDS, 'r', encoding='utf-8') as procfile:
# capture card number, id and name
cardline = re.compile(
r'^\s*(?P<num>\d+)\s*' # card number
r'\[(?P<id>\w+)\s*\]:' # card ID
r'.*-\s(?P<name>.*)$') # card name

for line in procfile:
match = cardline.match(line)

if match:
yield AlsaCardInfo(card_num=int(match.group('num')),
id=match.group('id').strip(),
name=match.group('name').strip())


def get_pcm_devices():
"""Get PCM device numbers and names from /proc/asound/pcm."""

if not exists(PROC_DEVICES):
raise IOError("'%s' does not exist. ALSA not loaded?" % PROC_DEVICES)

with open(PROC_DEVICES, 'r', encoding='utf-8') as procfile:
devnum = re.compile(r'(?P<card_num>\d+)-(?P<dev_num>\d+)')

for line in procfile:
fields = [l.strip() for l in line.split(':')]

if len(fields) >= 3:
match = devnum.match(fields[0])

if match:
yield AlsaPcmInfo(card_num=int(match.group('card_num')),
dev_num=int(match.group('dev_num')),
id=fields[1],
name=fields[2],
playback='playback 1' in fields,
capture='capture 1' in fields)


def get_devices(playback=True, capture=True):
"""Return iterable of (device string, card name, device name) tuples."""
cards = {c.card_num: c for c in get_cards()}

for dev in get_pcm_devices():
card = cards[dev.card_num]
if (playback and dev.playback) or (capture and dev.capture):
yield ("hw:%s,%i" % (card.id, dev.dev_num), card.name, dev.name)


get_playback_devices = partial(get_devices, capture=False)
get_capture_devices = partial(get_devices, playback=False)

+ 7
- 23
src/jacksettings.py View File

@@ -33,6 +33,7 @@ else:
# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Imports (Custom Stuff) # Imports (Custom Stuff)


import alsainfo
import ui_settings_jack import ui_settings_jack


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
@@ -700,26 +701,9 @@ class JackSettingsW(QDialog):
# ----------------------------------------------------------------- # -----------------------------------------------------------------
# Helper functions # Helper functions


def getAlsaDeviceList(self):
alsaDeviceList = []

aplay_out = getoutput("env LANG=C LC_ALL=C aplay -l").split("\n")
for line in aplay_out:
line = line.strip()
if line.startswith("card "):
cardInfo = line.split(", ", 1)[0].split(": ")
cardIndex = cardInfo[0].replace("card ", "")
cardName = cardInfo[1].split(" [")[0]

deviceInfo = line.split(", ", 1)[1].split(": ")
deviceIndex = deviceInfo[0].replace("device ", "")
deviceName = deviceInfo[1].split(" [")[0]

if cardName != "Loopback":
fullName = "hw:%s,%s [%s]" % (cardName, deviceIndex, deviceName)
alsaDeviceList.append(fullName)

return alsaDeviceList
def getAlsaDeviceList(self, **kwargs):
return ["%s [%s - %s]" % dev
for dev in alsainfo.get_devices(**kwargs)]


def setComboBoxValue(self, box, text, split=False): def setComboBoxValue(self, box, text, split=False):
for i in range(box.count()): for i in range(box.count()):
@@ -786,10 +770,10 @@ class JackSettingsW(QDialog):
self.ui.obj_driver_playback.addItem("none") self.ui.obj_driver_playback.addItem("none")


if LINUX: if LINUX:
dev_list = self.getAlsaDeviceList()
for dev in dev_list:
self.ui.obj_driver_capture.addItem(dev)
for dev in self.getAlsaDeviceList(capture=False):
self.ui.obj_driver_playback.addItem(dev) self.ui.obj_driver_playback.addItem(dev)
for dev in self.getAlsaDeviceList(playback=False):
self.ui.obj_driver_capture.addItem(dev)
else: else:
dev_list = gJackctl.GetParameterConstraint(["driver", "device"])[3] dev_list = gJackctl.GetParameterConstraint(["driver", "device"])[3]
for i in range(len(dev_list)): for i in range(len(dev_list)):


Loading…
Cancel
Save