You are not logged in.
A fully functional software mixer in ALSA — combining dmix for playback, dsnoop for capture, and asym for full-duplex operation — has been enabled by default for over a decade, especially on common hardware like HDA-Intel.
It started with ALSA 1.0.9rc2 (2005), when dmix became automatic for analog outputs. Since then, multiple apps playing audio at once just works.
While dmix was early, dsnoop and full-duplex lagged — but in Debian, they’ve long been included with "sane defaults" via the libasound2-data package.
Files like:
/usr/share/alsa/alsa.conf
/usr/share/alsa/pcm/dmix.conf
/usr/share/alsa/pcm/dsnoop.conf
/usr/share/alsa/cards/HDA-Intel.confalready define working dmix, dsnoop, and asym setups.
As the Debian Wiki says:
Advanced features such as mixing should already be configured with sane defaults.
_https://wiki.debian.org/ALSA#Configuration
This means:
✅ Multiple playback sources work via dmix.
✅ Microphone sharing works via dsnoop.
✅ Full-duplex is ready via asym.
NOTE: Analog outputs use dmix by default. S/PDIF (digital) usually does not — it may need manual setup.
Today, concurrent audio playback and full-duplex operation work out of the box on most hardware without PulseAudio.
Full duplex is rather essential for video conferencing — one can't very well have a proper conversation if only one person can speak at a time. It’s much like a telephone call, really: both parties need to talk and listen simultaneously for things to flow naturally.
There’s a rather persistent rumour that full duplex works with default ALSA config — as if it were some sort of conspiracy. But it’s easily tested: just run aplay and arecord at the same time. The truth is, it does work — not by magic, but because Debian and Devuan have sensible defaults. It’s not a secret; it’s just quietly reliable.
No config needed. Just follow these steps:
1. Remove any custom ALSA config (if you have one):
rm ~/.asoundrcThis ensures you're testing the default Debian/Devuan setup.
2. Check your sound card name:
cat /proc/asound/cardscat /sys/class/sound/card*/idLook for the name (e.g., PCH, system). You’ll need it if you have more than one card.
3. Set default card (only if multiple cards):
Create ~/.asoundrc with:
defaults.pcm.!card PCH
defaults.ctl.!card PCH
Replace PCH with your card name.
4. Connect a microphone (or use built-in mic).
5. Set mic volume:
alsamixer
Press F4 to switch to capture, then adjust mic level. Press Esc to exit.
6. Test full-duplex — play and record at the same time:
aplay a*test*.wav & arecord --vumeter=mono -f cd recorded.wav
Speak into the mic while the sound plays.
The --vumeter=mono option shows a moving ########+ bar — instant proof that recording works.
Example:
$ aplay a*test*.wav & arecord --vumeter=mono -f cd recorded.wav
Playing WAVE 'audio_test_48kHz_16bit.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Stereo
Recording WAVE 'recorded.wav' : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo
########+ | 14% 7. Stop recording with Ctrl+C, then:
killall aplay
8. Play back what you recorded:
aplay recorded.wav
You should hear the test tone and your voice.
✅ If both played and recorded — full-duplex works.
No PulseAudio. No PipeWire. Just plain ALSA.
There’s a modest suggestion that full duplex functions in Debian and Devuan — nothing flashy, mind you, but it does rather quietly go about its business. One might, with restraint, describe the test arecord -f cd -V mono | aplay as a faintly reliable way to confirm it. The VU meter, when it appears, is best viewed as a polite hint that things are working — not a cause for undue excitement.
$ arecord -f cd -V mono | aplay
Recording WAVE 'stdin' : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo
Playing WAVE 'stdin' : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo
###############+ | 29% Piping arecord into aplay means sending audio from the recorder directly to the player in real time — no file needed, just a live chain. It’s a quiet way to test full duplex: one speaks, the other plays, both at once.
The default ALSA software mixer works well enough, and sound quality — while not exactly a priority — has rarely troubled its users. One might say the standard Linux resamplers — including speexrate — are functional, though perhaps not quite up to the task if one happens to care about audio quality. fftrate remains the sensible choice for those who do.
The default ALSA setup functions well enough, though one might say the audio quality could be… more convincing with a small adjustment.
The method is straightforward:
fftrate: A resampler of noticeably better quality than the standard options.
Precise timing: Helps avoid the faint smearing that lesser resamplers tend to introduce.
Key Settings
defaults.pcm.rate_converter "fftrate"Instructs ALSA to use fftrate for all sample rate conversion — a quiet but meaningful upgrade.
defaults.pcm.period_time 40000 # 40 ms
defaults.pcm.periods 4Sets a buffer of 160 ms total — stable, and just right for fftrate to do its work properly (J: 0.00%).
# defaults.pcm.dmix.rate 192000 # Max for Intel HDA
# defaults.pcm.dmix.rate 96000
# defaults.pcm.dmix.rate 48000 # Default
# defaults.pcm.dmix.rate 44100Uncomment one to match your DAC’s native rate.
All audio is then resampled once, cleanly, before reaching the hardware.
NOTE: fftrate is rather better than most built-in hardware resamplers. While one could leave things at 48kHz, it’s generally best to set defaults.pcm.dmix.rate to the maximum your DAC supports — 192kHz or 384kHz — and leave it. This avoids repeated or low-quality resampling elsewhere. It’s not magic — just a bit of quiet competence.
For Multiple Sound Cards
Uncomment and set:
# defaults.pcm.!card PCH
# defaults.ctl.!card PCHCheck your card name:
cat /proc/asound/cards
cat /sys/class/sound/card*/idA few lines in ~/.asoundrc are sufficient to override the defaults:
defaults.pcm.rate_converter "fftrate"
defaults.pcm.period_time 40000
defaults.pcm.periods 4
# defaults.pcm.dmix.rate 192000
# defaults.pcm.!card PCH
# defaults.ctl.!card PCHThe modified configuration file (dmix & dsnoop) with user defaults:
cat ~/.asoundrc
defaults.pcm.rate_converter "fftrate" # default resampler
defaults.pcm.period_time 40000 # best left as is, really
defaults.pcm.periods 4 # as above — no need to fiddle
# defaults.pcm.dmix.rate 192000 # Max for Intel HDA
# defaults.pcm.dmix.rate 96000
# defaults.pcm.dmix.rate 48000 # Default
# defaults.pcm.dmix.rate 44100
# defaults.pcm.!card PCH # Intel HDA codec.
# defaults.ctl.!card PCH # Intel HDA codec
# defaults.ctl.card 0 # Default
# defaults.pcm.card 0 # Default
# defaults.pcm.device 0 # Default
# defaults.pcm.dmix.channels 2 # Default
# defaults.pcm.dmix.format unchanged # Default
# defaults.pcm.dmix.format S32_LE # Max for Intel HDA
#
# dmix output
#
pcm.!dmix {
@args [ CARD DEV SUBDEV FORMAT RATE CHANNELS ]
@args.CARD {
type string
default {
@func refer
name defaults.pcm.dmix.card
}
}
@args.DEV {
type integer
default {
@func refer
name defaults.pcm.dmix.device
}
}
@args.SUBDEV {
type integer
default 0
}
@args.FORMAT {
type string
default {
@func refer
name defaults.pcm.dmix.format
}
}
@args.RATE {
type integer
default {
@func refer
name defaults.pcm.dmix.rate
}
}
@args.CHANNELS {
type integer
default {
@func refer
name defaults.pcm.dmix.channels
}
}
type dmix
ipc_key {
@func refer
name defaults.pcm.ipc_key
}
ipc_gid {
@func refer
name defaults.pcm.ipc_gid
}
ipc_perm {
@func refer
name defaults.pcm.ipc_perm
}
tstamp_type {
@func refer
name defaults.pcm.tstamp_type
}
slave {
pcm {
type hw
card $CARD
device $DEV
subdevice $SUBDEV
}
format $FORMAT
rate $RATE
channels $CHANNELS
period_size {
@func refer
name {
@func concat
strings [
"defaults.dmix."
{
@func card_id
card $CARD
}
".period_size"
]
}
default -1
}
period_time {
@func refer
name {
@func concat
strings [
"defaults.dmix."
{
@func card_id
card $CARD
}
".period_time"
]
}
default {
@func refer
name defaults.pcm.period_time
}
}
periods {
@func refer
name {
@func concat
strings [
"defaults.dmix."
{
@func card_id
card $CARD
}
".periods"
]
}
default {
@func refer
name defaults.pcm.periods
}
}
}
hint {
show {
@func refer
name defaults.namehint.extended
}
description "Direct sample mixing device"
device_output $DEV
}
}
#
# dsnoop
#
pcm.!dsnoop {
@args [ CARD DEV SUBDEV FORMAT RATE ]
@args.CARD {
type string
default {
@func refer
name defaults.pcm.dsnoop.card
}
}
@args.DEV {
type integer
default {
@func refer
name defaults.pcm.dsnoop.device
}
}
@args.SUBDEV {
type integer
default 0
}
@args.FORMAT {
type string
default {
@func refer
name defaults.pcm.dmix.format
}
}
@args.RATE {
type integer
default {
@func refer
name defaults.pcm.dmix.rate
}
}
type dsnoop
ipc_key {
@func refer
name defaults.pcm.ipc_key
}
ipc_gid {
@func refer
name defaults.pcm.ipc_gid
}
ipc_perm {
@func refer
name defaults.pcm.ipc_perm
}
tstamp_type {
@func refer
name defaults.pcm.tstamp_type
}
slave {
pcm {
type hw
card $CARD
device $DEV
subdevice $SUBDEV
}
format $FORMAT
rate $RATE
period_size {
@func refer
name {
@func concat
strings [
"cards."
{
@func card_id
card $CARD
}
".pcm.dsnoop.period_size"
]
}
default -1
}
period_time {
@func refer
name {
@func concat
strings [
"cards."
{
@func card_id
card $CARD
}
".pcm.dsnoop.period_time"
]
}
default {
@func refer
name defaults.pcm.period_time
}
}
periods {
@func refer
name {
@func concat
strings [
"cards."
{
@func card_id
card $CARD
}
".pcm.dsnoop.periods"
]
}
default {
@func refer
name defaults.pcm.periods
}
}
}
hint {
show {
@func refer
name defaults.namehint.extended
}
description "Direct sample snooping device"
device_input $DEV
}
}Last edited by igorzwx (2025-11-20 18:39:34)
Offline
Good info and very true, it just takes some work figuring out all the particulars, alsa has a language all it's own.
In general my priorities for sound are based on delivering the simplest most basic config to ship with my distro project, leaving it up to the user to customize as they see fit, rather than saddling them with additional mixers and sound servers that they may dislike.
I also never saw a lot of sense in playing simultaneous streams until a gamer friend pointed out that he liked to listen to music while he played, that I can understand, so i'm testing a new .asoundrc that allows the functions Igor spelled out above, it's still very short and simple and needs some more testing (specifically with the mic) as so far i've just tested simultaneous streaming and it's working great on both single and dual card systems that i've tested.
This config assumes a user also has the EQ plugin package, but no additional plugins like fftrate, just posting it here for general info purposes, @Igor feel free to critique as I wouldn't mind hearing thoughts/suggestions but please don't call me demented, lol.
# Default: route through dmix > plug > equalizer > hardware
pcm.!default {
type plug
slave.pcm "dmixed_equal"
}
ctl.!default {
type hw
card 0
}
# Equalizer control (for mxeq GUI)
ctl.equal {
type equal
}
# Final EQ stage: applies to mixed output
pcm.dmixed_equal {
type equal
slave.pcm "dmixed_plug"
}
# Plug wrapper for format/rate conversion after dmix
pcm.dmixed_plug {
type plug
slave.pcm "dmixed"
}
# dmix: allows multiple playback streams > direct to hardware
pcm.dmixed {
type dmix
ipc_key 1024
ipc_key_add_uid false # safer than 0
slave {
pcm "hw:0,0"
period_time 0
period_size 1024
buffer_size 4096
rate 44100 # optional: lock rate if needed
}
bindings {
0 0
1 1
}
}
# Optional: dsnoop for multiple capture (mic) apps
pcm.dsnooped {
type dsnoop
ipc_key 1025
slave.pcm "hw:0,0"
}
# Optional: full duplex (for simultaneous play+capture)
pcm.duplex {
type asym
playback.pcm "dmixed_plug"
capture.pcm "dsnooped"
}
# Legacy: old names for compatibility/scripts
pcm.plugequal {
type equal
slave.pcm "plughw:0,0"
}
pcm.equal {
type plug
slave.pcm "plugequal"
}https://sourceforge.net/projects/vuu-do/ New Vuu-do isos uploaded October 2025!
Vuu-do GNU/Linux, minimal Devuan-based Openbox and Mate systems to build on. Also a max version for OB.
Devuan 5 mate-mini iso, pure Devuan, 100% no-vuu-do.
Devuan 6 version also available for testing.
Please donate to support Devuan and init freedom! https://devuan.org/os/donate
Offline
From a modest point of view, arateconf does rather quietly solve the problem — guiding users to a working ALSA setup without fuss or guesswork. It’s not flashy, but it gets the job done, and that’s what matters.
Offline
@igorzwx Thanks for showing that alsa is actually capable and works without requiring pulseaudio or pipewire
Offline
Hello:
@igorzwx Thanks for showing that alsa is actually capable ...
+1
Best,
A.
Offline
@spliskin You're most kind — and quite right: ALSA does rather quietly get on with the job. It’s not often celebrated, but yes, it can be capable — and even enjoyable, especially with fftrate and arateconf. If it’s not too much trouble, do give them a go. Instructions for compiling and using are here:
How to compile: _https://dev1galaxy.org/viewtopic.php?id=7142
How to use: _https://dev1galaxy.org/viewtopic.php?id=6644
Last edited by igorzwx (2025-11-20 20:28:28)
Offline
@igorzwx No problem. You shined the light there .. I'll check out your apps and let you know.
This alsa point is one I've hammered for a long time. Alsa is actually capable, it's just different api and configuration isn't always obvious. Though comparing to pulseaudio and pipewire saying configuration isn't obvious doesn't matter at all there because it's no where near obvious there either.
Offline
Right, then — if you’re wondering about fftrate and its little helpers like arateconf or pcm_conv, feel free to pop the question. It’s not entirely unpleasant to use ALSA once you’ve got arateconf doing the heavy lifting. Without it? Well, let’s just say it’s not quite a walk in the park. The ALSA API isn’t exactly… charming, but then again, Linux has never gone in for frivolous hand-holding. That said, even the faintly tone-deaf might notice an improvement in sound quality once PulseAudio’s been shown the door. And if you’re still able to hear the difference (lucky you), installing the fftrate plugin and setting it up for high-res playback might just be worth a go. Not that it’s life-changing or anything.
Last edited by igorzwx (Yesterday 13:19:30)
Offline
installing the fftrate plugin and setting it up for high-res playback might just be worth a go. Not that it’s life-changing or anything.
That's one of the major points I'm touching on. A lot of people need / want low latency, high res audio. Some need it, i.e. studios, dj's etc.
Point is, it's been years of people just kicking alsa for no good reason. lol...
Offline
Right, then — the fftrate package comes with two resamplers: fft and dct. The dct one’s a bit quicker, though neither’s likely to raise an eyebrow in everyday use. Mind you, there was that one chap on Gentoo using OSS4 who reckoned he spotted the difference in a blind test — fair play to him.
If you’re after hard numbers, pcm_conv and pcm_mse will give you the lowdown on latency and precision.
_https://dev1galaxy.org/viewtopic.php?id=6722
Offline