Thursday, February 17, 2011

Solving ALSA and WavePlugin for SqueezeBoxServer

I'm trying to get the WaveInput plugin for SqueezeBox Server working. So I'm trying to sort out ALSA and all its implications. I have figured out the schematic  below based on a number of experiments and other research (click on the figure to get a larger image):
Several notes:
  • All the stuff in blue are functions and controls provided by ALSA.With the advent of the Linux 2.6 kernel, ALSA (the Advanced Linux Sound Architecture) has become the standard sound system for Linux. ALSA comprises both  the base, which provides sound card drivers and firmware, and alsa-utils for user tools. The main application in alsa-utils  is alsamixer. alsamixer is an ncurses-based mixer for controlling your audio interfaces, both playback and recording. There are a number of GUI front-ends for the ncurses (terminal-based) alsamixer, including kmix and a host of others. All of these present the functions embodied in alsamixer. So if, for example, your version of alsamixer does not have a channel for MicIn then none of these front-ends can display such a thing.
  • The diagram shows what alsamixer shows me on my system (OpenSuSE 11.3).

  • The ALSA term for microphone input is MicIn - "low-level, mono microphone input". This does not exist on my system and this is what I need to be able to mute.

  • The red x indicates that there is a MUTE button available for that control. Not all the controls have a MUTE function. In particular, the microphone inputs do not have a mute function. You can set the volume to zero and the sound still is picked up. I have found that the only way to mute the built-in PC microphone is to plug a dead plug into the headset microphone socket. As indicated by the ganged microphone switches in the diagram, this will disable the internal microphone.

  • The Headphone and Speaker outputs also are served by a ganged switch: each of these channels has its own volume control but plugging in a headset blocks the output to the PC Speaker.

  • I don't know where the First Mic Boost Capture channel goes. My assumption is that it is a volume control on the microphone stream, which is then fed back into the sound card to be distributed normally (i.e., to Headphone, Speaker, or Capture channels). But that is a guess...

  • The output Capture channel fills a Buffer. This presumably is read  by some device to then be served to WaveInput. It has an activation checkbox, indicated by the red checkmark. The preferred "device" has been said to be a recording device such as krecord. It turns out that krecord is totally unnecessary, unless you are trying to record the channel. All You Have To Do ... is the detail at the end of this post.

  •  The channel names are those provided by alsamixer (and consequently by all the various GUI frontends for it, e.g., kamix, kmix, gmix, and so forth. These differ from those presented quasi-officially by http://alsa.opensrc.org/Main_Page. I have therefore inferred the following correspondence:

    + The ALSA term for microphone input is MicIn - "low-level, mono microphone input". This does not exist on my system and this is what I need to mute. Instead, my system shows Front Mic Boost, which does not have a mute control.

    + The ALSA term for digital stream input is PCM playback - "digital stream from software". This does exist on my system as PCM.

    + The ALSA term for digital stream output is PCM Capture - "digital stream to software". This does exist on my system as Capture.

    + The link cites synthesizer as one of the ALSA channels. This may be what we are seeing as Digital and may be the MIDI input.

    + The link cites Line Out - "analog output to external device" as one of the ALSA channels. This does exist on my system as Headset and controls the analog stereo connection.

  • I am testing all this with streamtuner2. Its feeds happily go to the PC headset (if plugged in) or the PC speaker. But to date, they do not get to the Capture channel and therefore do not get to the Buffer or WaveInput.
OK. So after some reflection and refraction, we hit it again.

The solution was found with the following protocol:
  • Start StreamTuner2
  • Start a stream. This starts kaffeine in Playback mode.
  • Go to kmix, zero and mute all the settings, then open them one by one and wait a long time before the next one. "Long time" turns out to be 34.5 seconds on my system, but YMMV.
Actually the latency is the key impediment to analysis: it takes 34.5 seconds on my system from making a change in kmix before it is reflected in the sound.

Sparing you the details, although if you email an address I'll give you more details, it turns out that (at least on my system) you must:
  • Unmute, max volume the Headphone control
  • Unmute, max volume the Digital control
  • Plug in to the PC headphone socket to disconnect the PC speaker. It has to be a real headset it seems, I tried various other plugs without success.
  • And of course unmute and max volume Master and PCM.
So this is where I am for now:
  • I need a more elegant way of muting the PC microphone than plugging in a blank plug.
  • I need a more elegant way of disabling the PC Speaker than plugging in the headphone.
There are of course many questions remaining to which we may attend in due course. At the top of the list are:
  • Why does it need Headphone when the feed is Digital?
  • Why is not simply muting Speaker enough, rather than requiring a headphone plug?
  • What does it take to actually mute the PC microphone, other than plugging it out?
I suspect these all have to do with impedances and other mysteries. Tomorrow (or next week, or next month) is another day...

For now, very pleased. The sound is beautiful...

So very good work to the author of WaveInput. It now works a charm. I hope this is helpful to others.

No comments: