I solved this issue as follows:
First, load the snd-aloop
module:
sudo modprobe snd-aloop
This will create a new device called Loopback
:
± % cat /proc/asound/cards !10017
0 [PCH ]: HDA-Intel - HDA Intel PCH
HDA Intel PCH at 0xc1814000 irq 60
1 [HDMI ]: HDA-Intel - HDA Intel HDMI
HDA Intel HDMI at 0xc1810000 irq 61
2 [Loopback ]: Loopback - Loopback
Loopback 1
From the information shown above we have to create two hw
devices:
hw:0,0
(PCH is my main sound card).
hw:2,1
(The Loopback
virtual device).
Normally, hw
devices have the form: hw:X,Y
. For our purposes, it seems that Y
for the main card is always 0
while for the Loopback
we have Y
equals 1
.
Now, in order to make all of this work, we need a ~/.asoundrc
file with the following:
pcm.!default {
type asym
playback.pcm "LoopAndReal"
#capture.pcm "looprec"
capture.pcm "hw:X1,Y1"
}
pcm.looprec {
type hw
card "Loopback"
device 1
subdevice 0
}
pcm.LoopAndReal {
type plug
slave.pcm mdev
route_policy "duplicate"
}
pcm.mdev {
type multi
slaves.a.pcm pcm.MixReale
slaves.a.channels 2
slaves.b.pcm pcm.MixLoopback
slaves.b.channels 2
bindings.0.slave a
bindings.0.channel 0
bindings.1.slave a
bindings.1.channel 1
bindings.2.slave b
bindings.2.channel 0
bindings.3.slave b
bindings.3.channel 1
}
pcm.MixReale {
type dmix
ipc_key 1024
slave {
pcm "hw:X1,Y1"
rate 48000
#rate 44100
periods 128
period_time 0
period_size 1024 # must be power of 2
buffer_size 8192
}
}
pcm.MixLoopback {
type dmix
ipc_key 1025
slave {
pcm "hw:Loopback,0,0"
rate 48000
#rate 44100
periods 128
period_time 0
period_size 1024 # must be power of 2
buffer_size 8192
}
}
Modify hw:X1,Y1
with the values for your main card (in my case hw:0,0
).
You can test that this configuration works by playing something in your computer. If you hear it, so it is fine. Now let's play something in the computer, and record it from this virtual device with ffmpeg
:
ffmpeg -f alsa -i hw:X2,Y2 -c:a libmp3lame -b:a 256k -vn capture.mp3
Where hw:X2,Y2
has to be replaced by the Loopback
device, in this case
hw:2,1
.
I suppose that using arecord
should work too.
Best Answer
Just define a device named
hw
, but use!
to ensure that the built-in definition is overridden, and use@args
to allow parameters (which are ignored if you don't use them in the definition):