Wednesday, December 25, 2013

PulseAudio reconsidered - hail OSS, ALSA

Links: arch wiki pulseaudio :: record system in pulseaudio (GUI) ::
record system in pulseaudio (CLI) :: ALSA configuration :: best disable link so far (3/2014)

Linux sound management and the changing nature of Linux initialization schemes are the bad things about Linux. In this post, it's about sound. PulseAudio, on the scene since perhaps 2009, but currently (2014) prevalent, has made the sound kludge even worse1.

OSS - still good

My Linux use began when OSS was the only sound daemon communicating with hardware. OSS had bugs, but it was straightforward, and therefore was a good foundation which should have been developed further instead of dumped.

I'm not a recording engineer, but I never encountered the two main purported limitation of OSS, 1) an inability to process simultaneous sound sources (, eg. capture a mic input at the same time as a music stream) nor 2) a supposed incapacity to split a single sound source into multiple types of files simultaneously.

When I wanted to listen to several files through the speakers and to, simultaneously, capture the output (stdout) into a single WAV file, I piped them through sox. For example, in this case, I created a script which played several audio files in sequence, and I used sox to collate the output into a single file:
$ somescript.sh | sox -t ossdsp -w -s -r 44100 -c 2 /dev/dsp foobarout.wav
That's all there was to it.

ALSA - meh

When ALSA became common, the the simple approach of /dev/dsp was gone. In ALSA, we had to locate soundcard info with aplay-l, aplay -L, /proc/asound/pcm AND /dev/sound/. Some software couldn't handle the ALSA layer, and we'd have to name the device. Only now it wasn't generically, /dev/dsp. So we'd have to research its PCI values and provide literal device information such as "hw:0,0". Another problem was lost hours configuring daemons. As users, we'd sort of have to choose between OSS or ALSA and be certain we'd blackballed the modules of the other. It's unclear what benefit ALSA provided, in other words.

Consider the play/capture scenario I described above. Under ALSA, a similar effect should have been available by researching ALSA commands. That's already wasted time (duplication of effort) to achieve the same outcome, but it also turns-out the the ALSA commands were not as reliable. For example...
$ somescript.sh | arecord -D hw:0,0 -f cd foobarout.wav
... often would result in a string of error messages regarding "playback only", even though capturing had been enabled in ALSA, etc. To me, it seemed that ALSA, and not OSS, had multiplexing limitations.

Further, the C code of the ALSA "dmix" lib, which one would think was created exactly to solve this problem gives no respite...
ALSA lib pcm_dmix.c:961:(snd_pcm_dmix_open) The dmix plugin supports only playback stream
Lol. In the end, the only helpful plugin (of course with nearly zero documentation and an unintuitive name), is the asym plugin. For this you'd have to become aware of it in the first place, not so easy, nor will you escape having to build and tweak an /etc/asound.conf and/or an .asound.rc. Have fun.

PulseAudio

Instead of simply developing either ALSA or OSS more completely, some group developed PulseAudio. PulseAudio purported to make muxing easier than ALSA which purported to make muxing easier than OSS. "Lol". Lol because ALSA and/or OSS continue to be layers underneath PulseAudio. So now we add PulseAudio memory and CPU loads to those of both the OSS or ALSA modules running beneath PulseAudio. These three different directions at once also raise the potential for errors. And if you think PulseAudio makes configuration any easier, take a look here.

After PulseAudio configuration, recording my script requires the same steps as capturing streaming. It's too much information to regurgitate entirely here, but the shorthand is:
$ pavucontrol (set "Record Stream from" to "Monitor of Internal Audio Analog Stereo")
$ somescript.sh | parec --format=s16le --device=(from "pactl list") | oggenc --raw --quiet -o dump.ogg -
There is also hypothetically an OSS emulator called "padsp" (install ossp in Arch) with which one could use sox again. That is, PulseAudio apparently uses an emulator instead of just accessing a real OSS module. I haven't tried "padsp", but it may work.
$ padsp sox -r 44100 -t ossdsp /dev/dsp foobarout.wav

PulseAudio crippleware effect

Once PussAudio has ever been installed, even inadvertently as a dependency for some other application, and even when you're sure its daemon is not running (), one's soundcard will likely be reduced to analog mode. Eg, after Puss Audio was installed, but its daemon not running, I observe...
$ aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: SB [HDA ATI SB], device 0: ALC268 Analog [ALC268 Analog]
Subdevices: 1/1
Subdevice #0: subdevice #0
...when I should instead see...
$ aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: SB [HDA ATI SB], device 0: ALC268 Analog [ALC268 Analog]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 0: SB [HDA ATI SB], device 1: ALC268 Digital [ALC268 Digital]
Subdevices: 1/1
Subdevice #0: subdevice #0
Results will be similar in $ arecord -l. There's no way to capture one's system in ALSA properly again until it detects the entire soundcard. If we'd like, we can even see the problem more clearly:
$ aplay -L
null
Discard all samples (playback) or generate zero samples (capture)
default
Default ALSA Output (currently PulseAudio Sound Server)
sysdefault:CARD=SB
HDA ATI SB, ALC268 Analog
Default Audio Device
front:CARD=SB,DEV=0
HDA ATI SB, ALC268 Analog
Front speakers
[remaining 4 entries, all analog dev=0, snipped]
That is, even with PussAudio disabled, ALSA remains infected with the PulseAudio Sound Server, and analog limitations.

PulseAudio disabling

Link: excellent disabling instructions
We'd like to disable PulseAudio, but we'd prefer not to uninstall PulseAudio --- for example, it's understood that some Gnome sound functions with hooks in PulseAudio libs may not otherwise work. We know from above that it's not enough to simply disable its daemon.
file note
/etc/pulse/ dir: pulse audio config files
/etc/modprobe.d/alsa-base configuration for ALSA modules
/usr/share/alsa/ dir: alsa config files
/etc/asound.conf alsa config file for pulse
/usr/share/alsa/default.pa change ALSA hooks
/etc/pulse/default.pa change PulseAudio hooks

1. $ pulseaudio -k
2. # pacman -r pulseaudio-alsa
3. # rename /usr/share/alsa/alsa.conf.d/*.conf /usr/share/alsa/alsa.conf.d/*.bak
...to be continued.

1 Some configurations even include a Music Player Daemon ("MPD"), and/or a Simple Direct MediaLayer ("SDL"), ridiculous 4th and 5th possible layers.

Saturday, December 21, 2013

fbxkb - multi-language keyboard

Fbxkb does a simple job: sits in one's system tray and displays language status with a national flag. It's a GUI interface to bypass keystrokes for keyboard language switching.

One might guess fbxkb would be a 10MB app, but htop revealed fbxkb uses 156MB to do its thing. Luckily, my friend's system (on which it was needed) uses the relatively lean icewm Windows Manager. I found that 156MB did not affect performance. Additionally, the visual cue of a flag in the system tray saves guesswork. All told, satisfaction with fbxkb probably depends on a person's available RAM and their preference for a visual cue. Otherwise, just bind setxkbmap keystrokes (see below) and forgo fbxkb.

installation

The system onto which fbxkb was installed runs ArchLinux so I used yaourt to put it in.
$ yaourt -S fbxkb

configure

This friend wanted US and German keyboard options. I looked into /usr/share/X11/xkb/ for configuring, but we don't need to configure so deeply for a simple installation. Instead, add two lines to .xinitrc, and then invoke fbxkb with a single line in .icewm/startup:
$ nano .xinitrc
setxkbmap -layout us,de
# optional keystroke for shifting without GUI
setxkbmap -option grp:alt_shift_toggle 'us,de'

$ nano .icewm/startup
fbxkb &

This arrangement gave him the option to switch languages with Alt+Shift, or to switch using the fbxkb icon in the tray. Just click on the flag and it will toggle to the other flag, indicating the other keyboard mapping is operational. This also works for more than two languages. Although I just needed US and DE layouts, more options can be found here.

Saturday, December 14, 2013

xdm - installing and customizing

Links: Linux Journal 1999(!)

I strongly agree with this post's comment that kdm and gdm are lib-laden and overall bloated. To simply login, we just might want a different background photo than the the standard x box, but that's all the customization I need. In fact, I prefer runlevel 3 at startup, but if I'm helping someone with Linux that prefers a window-esque GUI right from the start, then it's got to be runlevel 5.

install - file changes

One can just download xdm with pacman. There are only two important file changes: 1) xdm (and all display managers) read .xsession instead of .xinitrc. 2) changing to runlevel 5 means altering /etc/inittab I organized a working xdm on a friends system with the following...
# nano /etc/inittab
x:5:respawn:/usr/X11R6/bin/xdm -nodaemon -config /etc/X11/xdm/archlinux/xdm-config

$ cp .xinitrc .xsession

customizing

One of the best instructions on this remains from 1999 (link at top). XDM goes way back.

Thursday, December 12, 2013

yaourt - tarball installation

Most like to use yaourt and it's typically easy to install it from the French repo. But documentation is lacking if it has to be installed from the tarball.

the repo site...

Append these lines to /etc/pacman.conf, and then request pacman to retrieve yaourt...
# nano /etc/pacman.conf
[archlinuxfr]
SigLevel = Never
Server = http://repo.archlinux.fr/$arch

# pacman -Sy yaourt

...but some require the tarball

It appears the method above is the common install method, since I could find very little good information for those forced to use the tarball (eg, on my friend's system). Here is the official page which was little help, and here is the only site with details I could follow nearly verbatim.

packagebuild note

Installing yaourt uses packagebuild. The sites I found describing packagebuild, were adamant about running it as a user and it even has a warning prompt inside the program. They say it will ask you for authentication at the right time, blah blah blah. This cost me a lot of time. Permissions are a critical step in Linux, as we all know and I found that packagebuild did not prompt me in a helpful way for authentication. In my view, it's much better to manually level up or down manually when using packagebuild, the same way we we do with "make" and "make install".

what worked

Here is what (finally) worked:

Sunday, December 8, 2013

power management - hibernation key(s)

I recently encountered a HP Pavilion for which a good friend wanted hibernation capacity. Ideally, hibernation would result from an idle state (eg., when a user steps away from their system for a number of minutes) and/or when hibernation was selected by the user (a menu item or a hotkey). The process gave me a chance to step through key bindings and power management configuration.

overview

I expected hibernation to really be two functions - hibernation, and resuming from hibernation, equally important. And both could have subsections which might include: 1) hardware settings (eg. having a swap file for suspending to a disk), 2) boot settings (eg. grub/lilo), 3) daemon settings for whatever daemon alerted the kernel (possibly many options), 4) key bindings 5) inactivity time-out.
NB: Currently having hardware issues with full hibernation, so this entry ends with "suspending". Upgrade to full hibernation downstream.

1. swap

For hibernation, a swap partition is the easiest, though supposedly a swap file can be configured with enough work. I checked in cfdisk, and noted that my friend had more than two gigs of swap partition on /dev/sda2. /Etc/fstab was properly configured as well. Otherwise, mkswap and swapon, possibly followed by a fresh genfstab, would be accomplished in this step.

2. boot

This guy is running ArchLinux with grub, so I looked here, followed by:
# nano /etc/default/grub
GRUB_CMDLINE_LINUX="resume=/dev/sda2"

# grub-mkconfig -o /boot/grub/grub.cfg
I got a couple of errors when updating grub, thanks apparently to this bug, but these cleared with an update to his system (pacman -Syu) the following day.

3. daemon

What to use to notify the kernel? Certainly, acpid and/or pm-utils are what most will choose. However, it's not necessary in this case. Arch's use of systemd already handles some power events without another daemon. Per this helpful page, I changed the login process, uncommenting the relevant hibernation line and restarting systemd:
# nano /etc/systemd/logind.conf
HandleHibernateKey=hibernate

# systemctl restart systemd-logind
No other daemons than systemd are needed with systemd installed. What's accomplished at this step is hibernate service enablement, but not activation. To activate through systemd we need a systemd service file telling it what to do, possibly a cron job, and possibly a key binding. Properly configured, the command to initiate hibernation is $ systemctl hibernate, and for suspension $ systemctl suspend. Select one of these to go through the configuration steps -- binding to a key, possibly, to a cron job, possibly a systemd service file, etc.

3a. privileges

One expects privilege confusion with users taking daemon actions, so a check of group membership is wise. On the other hand, according to this page about systemd, polkit is required for user privileges to run hibernation or suspend --- adding users to groups such as "disk" can actually cause conflicts. YMMV, it appears. In lieu of polkit, simply granting ourselves a specific privilege in /etc/sudoers, eg "username ALL=NOPASSWD: /usr/bin/systemctl", also should work.

4. keys

A non-standard KB-0630 enhanced keyboard with a separate hibernation key, so pretty sweet. Per this page, installed xbindkeys and hit the hibernation key.
$ xbindkeys -k
[hit the hibernate key]
"(Scheme function)"
m:0x0 + c:150
XF86Sleep

$ nano .xbindkeysrc
# Suspend system
"systemctl suspend"
XF86Sleep

$ nano .xinitrc (or .icewm/startup)
xbindkeys &

5. idle time


# nano /etc/systemd/logind.conf
IdleAction=suspend
IdleActionSec=20min

# systemctl restart systemd-logind

This worked, except that it would go to sleep in 20 minutes, idle or not.