This is a proof of concept demonstration using just alsa, the alsa loopback module, and sox
to detect silence. The loopback module provides you with an output device that you can play sound into, and then record back from it. So, for example, you could direct mplayer
to use the loopback for sound output, then run sox
to record from the loopback, detect silence, and output to the original hardware output device.
Load the module with
sudo modprobe snd-aloop
(It was in my list of available kernel modules). aplay -l
will now list a new card with 2 devices. Device 0 is to play into, device 1 to record from. There are 8 independent "subdevice" channels, and it is easiest to use number 0 as often it can be then be omitted. (I found aplay
in package alsa-utils
).
$ aplay -l
...
card 1: Loopback [Loopback], device 0: Loopback PCM [Loopback PCM]
Subdevices: 8/8
Subdevice #0: subdevice #0
Subdevice #1: subdevice #1
...
Subdevice #7: subdevice #7
card 1: Loopback [Loopback], device 1: Loopback PCM [Loopback PCM]
Subdevices: 8/8
Subdevice #0: subdevice #0
Subdevice #1: subdevice #1
...
Subdevice #7: subdevice #7
You can now use another utility from the package to generate a continuous tone into the loopback device 0 (subdevice 0):
speaker-test -t sine -D hw:Loopback
or for example tell mplayer
to use the device with option -ao alsa:device=hw=Loopback
You will hear nothing until you also run sox
getting it to read the other side of the device and write it to the real hardware, assuming this is card 0:
sox -q -t alsa hw:Loopback,1 -t alsa hw:0 silence 0 1 10.0 2%
(I saw quite a few warnings sox WARN alsa: under-run). If you stop the speaker test, after 10 seconds of silence the sox
command will stop.
Note, if you mute mplayer
you get silence but this seems to be independent of the data level (which you can visualise if you remove the -q
from sox
). You need to pause or lower the sound level of mplayer
to have the silence detected. sox
may also introduce a second or two of delay in the audio. You should be able to configure alsa to make the Loopback device the default instead of your card 0.
A more satisfactory solution is to let the kernel sound drivers handle the real-time audio, and use sox
only to detect the silence, throwing away its output. This seems to be possible, but with just alsa it is also a bit complicated and needs knowledge I don't have, though you can find examples of duplicating sound to two devices, your original audio card, and a virtual device which sox
can then read.
A simpler solution using pulseaudio to enable monitoring is possible, using pactl load-module module-combine-sink
which I will probably investigate.
sox
has an effect which can detect silence, and stop, but you would have to pipe your sound data through it. Aren't you using pulseaudio? – meuh Aug 07 '17 at 17:19