You are not logged in.

#1 2013-03-27 05:36:56

jwatte
Member
Registered: 2012-06-22
Posts: 58

How to automatically share/mix the audio device?

I'm using Arch with LXDE on a Core i5. The sound card is an Intel 6 series / C200 controller (just a DMA engine, really.)  Most programs these days seem to use ALSA. This includes some simple programs I write, as well as utilities like "espeak."

If a program I've written happens to be playing some sound, while I try to use another program (say, "espeak") that also uses ALSA, only the first program works, and the second program errors out. This has all the convenience of using a Sound Blaster under Windows 3.1! :-)

Surely, there exists some configuration option or package or kernel module I can install to make the system mix any and all programs that use ALSA to play sounds? What am I missing?

Offline

#2 2013-03-27 06:08:31

brebs
Member
Registered: 2007-04-03
Posts: 3,406

Re: How to automatically share/mix the audio device?

See my sig, for a proper dmix.

The ALSA API still allows programs to try to open the soundcard in a non-sharing mode, though. So some apps need to be configured to be unselfish, also.

Offline

#3 2013-03-27 17:59:10

jwatte
Member
Registered: 2012-06-22
Posts: 58

Re: How to automatically share/mix the audio device?

Thanks for the link.

Pardon me saying this, but why isn't this automatic? It's not a problem on MacOS or Windows. Also, when I worked on BeOS 15 years ago, we made this Just Work (tm) and I'd expect Linux to have caught up by now :-(

What can be done to make the defaults Just Work (tm) ? I imagine that would help everybody in the community. I might be able to help if this is possible.

Offline

#4 2013-03-27 18:20:11

brebs
Member
Registered: 2007-04-03
Posts: 3,406

Re: How to automatically share/mix the audio device?

jwatte wrote:

why isn't this automatic?

In the name of flexibility, I suppose.

we made this Just Work

What special tricks did ya use? Probably the same ones that my config uses, e.g. always opening all speakers (for e.g. surround51 to work when 2-speaker sound is already playing), and forcing a standard, sane config, so that audio mixing can work.

What can be done to make the defaults Just Work (tm) ?

There's too much variety in soundcard hardware. So we won't get agreement on what the "default" should be.

Offline

#5 2013-03-27 19:20:27

jwatte
Member
Registered: 2012-06-22
Posts: 58

Re: How to automatically share/mix the audio device?

What special tricks did ya use? Probably the same ones that my config uses,

BeOS was not Linux. It was another hobbyist/multimedia OS, built as an alternative to Windows, started back when Linux was at version 1.2 or so. However, Linux was zero cost, and we tried to charge for BeOS, so hobbyists went to Linux. Separately, Microsoft killed our OEM bundling deals (there was a litigation settlement later) and that's now ancient history.

The "tricks" we used were simple: Make it work by default, and then let the user customize it if necessary. We always did software mixing and sample rate conversion. When the program material had different channels than hardware, we did down/up-mixing. Because it Just Worked (tm) users were happy.

I guess my beef is with the ALSA system itself. It's not "A" in any remotely credible interpretation of the word. Compare to Windows, and MacOS X, Linux audio is yet another one of those horribly broken things that keep normal people from ever considering it.

Note that no static configuration can ever be a "sensible default" because "sensible defaults" depend on what the actual hardware is, and what the actual programs requests, so it requires smarts on the inside to Do The Right-ish Thing. Where Do The Right-ish Thing means play the sound that the application provides to the device that the user has, and adhering to bit-perfect reproduction if (and only if) possible.

Offline

#6 2013-03-27 20:06:17

progandy
Member
Registered: 2012-05-17
Posts: 2,146

Re: How to automatically share/mix the audio device?

Note that no static configuration can ever be a "sensible default" because "sensible defaults" depend on what the actual hardware is, and what the actual programs requests, so it requires smarts on the inside to Do The Right-ish Thing. Where Do The Right-ish Thing means play the sound that the application provides to the device that the user has, and adhering to bit-perfect reproduction if (and only if) possible.

This and more:
AFAIK archlinux has no dmix configuration since
1) some people like to use pulseaudio which makes best-guess assumptions for your config.
2) there are actually soundcards with a working hardware mixer which makes dmix unnecessary.
3) there are people who want to upmix stereo to 5.1 and there are some who want to downmix.
4) there are e.g soundcards for 2.0, 2.1, 5.1, 7.1, ...
5) the amount of speakers does not have to match the available output.

Offline

#7 2013-03-27 21:02:52

brebs
Member
Registered: 2007-04-03
Posts: 3,406

Re: How to automatically share/mix the audio device?

jwatte wrote:

adhering to bit-perfect reproduction if (and only if) possible.

Yes but there's gotchas in there which you're ignoring. E.g., be playing music when a movie starts. If following the "bit-perfect" style, this could require the soundcard to be re-initialized, both to switch the number of speakers from 2 to 6, and to switch the rate from 44100 to 48000. So, that would require a sub-second burst of silence, and if we're unlucky, a nasty click or pop from the speakers.

This would require a "sound manager" process to be controlling the audio at a higher level than ALSA, e.g. pulseaudio.

Now, in reality, my config works. You can bitch about having to get your hands dirty with it, but this is Arch - a DIY distro. You are expected to LOVE this sort of textual configuration, both for the system and for individual apps wink

The solution I prefer, is to have a hardware-mixing soundcard.

Offline

#8 2013-03-28 00:37:22

jwatte
Member
Registered: 2012-06-22
Posts: 58

Re: How to automatically share/mix the audio device?

I used to love hardware mixing sound cards ten years ago, but as CPUs get faster, it's gotten to the point where it doesn't matter, and certain things (like echo cancellation supported at the OS level) really require the OS to be in control.

Regarding re-initializing the device: I don't see why it would take a full second. DMA is fast, codecs are fast. I've written probably ten different sound card drivers in my life, and none has been even close to a second in setup time. However, I'd be perfectly happy if the only cause for going bit perfect is needing to output AC3 to the SPDIF output. For everything else, run the card at 48 (or whatever is preferred) and however many speakers are connected, and convert all the incoming audio. If the card can't detect speakers connected vs not, default to stereo, and let the user configure it if it's wrong. This will make things Just Work (tm)!

To be clear, a reasonable default behavior might be:
0) The lowest-numbered sound card is default, if not user-configured differently.
1) If the default card can detect speakers plugged in, configure itself for that set of speakers. If not, configure itself for stereo, if not user-configured differently.
2) Set the default playback frequency to 48 kHz if supported, else the highest frequency that's supported, if not user-configured differently.
3) When applications open the device, just say "yes" to whatever is requested, and do software re-sampling/mixing to the default format, if not user-configured differently.
4) If applications ask for formats, propose the default playback frequency at the default playback number of channels at floating-point sample format.
5) Use a 7-tap polyphase filter for resampling if not configured differently; this gives a great quality/performance trade-off using SIMD implementations. (15 years ago, we used a 4-tap Hermite interpolator, which had higher distortion and lower runtime cost on Pentium II, but time has moved on :-)
6) If a USB audio device or other hotplug device (such as bluetooth) is plugged in, switch to that device, if not user-configured differently. Note that with software mixing, nothing needs to change for applications that are already playing.

Pulseaudio? That would work, if it actually emulated the device driver interface that most applications actually use to play back sound. And it doesn't *have* to be a user-level process; doing mixing/converting in kernel space is perfectly fine assuming we have decent real-time support now. We don't even need to have interrupts disabled while doing it. Double buffers of 512 samples would be plenty for most cases and still have sufficiently low latency to not annoy game players or movie watchers.
Alternatively, the problem is that Linux applications still use the ALSA audio API rather than PulseAudio. But, given that that's the case, there are totally possible solutions that would make life a lot better on average, and no worse in the corner cases.

This is not rocket science -- it's technology that should have existed 15 years ago, and the fact that the Linux community at large hasn't bothered to solve it is a symptom of an attitude that's a barrier to meaningful desktop Linux adoption in the mainstream. And I'm saying this with love :-)

Is there a shim /dev/audio driver which can re-mix/re-route audio to a real hardware device, based on that device's capabilities? Or would the right dmix setting for alsa actually be able to accomplish this? (I imagine such a dmix wouldn't be able to adapt to things like detecting plugged in speakers/headphones, though)

Last edited by jwatte (2013-03-28 00:45:36)

Offline

#9 2013-03-28 01:53:19

brebs
Member
Registered: 2007-04-03
Posts: 3,406

Re: How to automatically share/mix the audio device?

I said sub-second. I'm sure the time will vary hugely, along with the extremity of the speaker click/pop, with the hardware.

There's extremely few ALSA devs, so if you're able and willing, please dive in. I think they have their hands full, simply trying to keep up with all the hda-intel undocumented quirks on new laptop models sad

Interestingly, Takashi Iwai seems to be the most active dev, and he's at SuSe, which is why opensuse's alsa package (in dir) has got tons (54-ish) of patches.

To detect whether my headphones are connected, I use this horrendous hack, after comparing the state of /proc/asound/card0/codec#0 when in versus out:

function headphones_in {
    if [ `grep "Pin-ctls: 0x40: OUT VREF_HIZ" /proc/asound/card0/codec#0 | wc -l` -eq 3 ] ; then
        # Surround, false
        return 1
    fi

    # Headphones, true
    return 0
}

I believe there is ongoing ALSA work in trying to get official headphone recognition - check out CONFIG_SND_HDA_INPUT_JACK.

Don't forget that this is Arch, not Ubuntu. I believe Ubuntu etc. do a much better job of "just working", by putting lotsa love into pulseaudio and automatic hardware detection.

Is there a shim /dev/audio driver which can re-mix/re-route audio to a real hardware device, based on that device's capabilities?

Nope. I think apps are *meant* to give such choices. Of course, this being Linux, any such configuration is through text files only wink

My speakers-headphones script is:

#!/bin/sh

diff -q ~/.asoundrc ~/.asoundrc-headphones > /dev/null
if [ "$?" -eq 0 ] ; then
	# Files are identical - nothing to do
	exit 0
fi

cp ~/.asoundrc-headphones ~/.asoundrc

sed -i -e "s:sndpcm surround51:sndpcm default:" ~/bin/darkplaces
sed -i -e "s:^snd_channels 6:snd_channels 2:" ~/.darkplaces/id1/autoexec.cfg

sed -i -e 's:^\(pcm=\).*:\1headphones:' ~/.config/audacious/config

sed -i -e "/^af=/s/.*/#af=/" -e "/ao=alsa/s/.*/ao=alsa:device=headphones/" ~/.mplayer/config ~/.mpv/mpv.conf

sed -i -e "/^set dsp\.alsa\.device=/s/.*/set dsp.alsa.device=headphones/" ~/.cmus/rc

My speakers-surround script is:

#!/bin/sh

diff -q ~/.asoundrc ~/.asoundrc-surround > /dev/null
if [ "$?" -eq 0 ] ; then
	# Files are identical - nothing to do
	exit 0
fi

cp ~/.asoundrc-surround ~/.asoundrc

sed -i -e "s:sndpcm default:sndpcm surround51:" ~/bin/darkplaces
sed -i -e "s:snd_channels 2:snd_channels 6:" ~/.darkplaces/id1/autoexec.cfg

sed -i -e 's:^\(pcm=\).*:\1upmix_20to51:' ~/.config/audacious/config

sed -i -e "/^#af=/s/.*/af=/" -e "/^af=/s/.*/af=volnorm=2:0.8,channels=6/" -e "/ao=alsa/s/.*/ao=alsa/" ~/.mplayer/config
# mpv doesn't use volnorm
sed -i -e "/^#af=/s/.*/af=/" -e "/^af=/s/.*/af=drc,channels=6,volume=2/" -e "/ao=alsa/s/.*/ao=alsa/" ~/.mpv/mpv.conf

sed -i -e "/^set dsp\.alsa\.device=/s/.*/set dsp.alsa.device=upmix_20to51/" ~/.cmus/rc

Edit: Removed useless less-than sign, before /proc.
Edit2: Removed pointless BASHism.

Last edited by brebs (2014-12-14 23:47:21)

Offline

#10 2013-03-28 06:01:38

jwatte
Member
Registered: 2012-06-22
Posts: 58

Re: How to automatically share/mix the audio device?

this being Linux, any such configuration is through text files only

Hence, the world will be run by iOS and Android devices. (Android is Linux, although "not really" :-)
Personally, I think working out of the box should be a priority upstream -- all the way up to the kernel folks.
If a good way can be found to insert a shim/delegating/mixing driver, that would solve this problem once and for all. Maybe that's where I should start looking!

Offline

Board footer

Powered by FluxBB