2

For a broadcast setup I would like to mix audio from an input device with audio from a .wav file. The .wav file contains an intro, wait or exit music that I would like to add to the music at some point in time during the broadcast.

The following setup is the goal: enter image description here

There are multiple steps needed:

  1. add/mix two streams
  2. convert to mono (or maybe this should have been done first)
  3. split the streams for a broadcast stream and a VU meter
  4. send the stream to the local audio output

I am pretty sure this must be possible, but i couldn't find any solution on the internet yet. Digging into alsa's .asoundrc did not yield any result yet. It seems that alsa dmix does some mixing, but not what i want here....

I really don't know where to start.

Can someone please shed some light on this? A partial solution would be fine too!

1

Easiest way is using Pulseaudio. (You can do it with ALSA, but it will be painful to configure.)

Everything that produces sound is automatically mixed on the current output ("sink" in Pulseaudio terms), so you needn't worry about mixing. You can control volumes with pavucontrol, and it remembers the last volume by application name. You can use paplay to play wav files from the commandline, but any other audioplayer will also do.

Converting to mono will be done automatically if your sink is mono. If you can't configure the local RaspPi sink for that (I don't know, I don't own a RaspPi), you can add a "pseudo" sink with

pactl load-module module-null-sink sink_name=whatever

or if it turns out you need to remap in Pulseaudio, module-remap-sink (see below, haven't tried this myself yet).

This sink or the local RaspPi sink will have an associated .monitor source which you can use to distribute it to icecast etc.

You can setup a permanent feed of the hw:1 input into your chosen sinks with

pacmd load-module module-loopback source="alsa_input.name_of_hw_1" sink="whatever_or_local_sink"

You can list the available sink names with

pacmd list-sinks | grep name:

As arguments, use the name without the angular brackets.

I think that's the basics. Read about the available Pulseaudio modules, and pacmd help will tell you what you can do from the commandline, if you don't want to use pavucontrol.

Edit for ALSA:

First, read about the available plugins. You will need a "virtual soundcard" to route the audio to darkice etc. That's a kernel module, so do something like

sudo modprobe snd-aloop pcm_substreams=2

for testing, and put a file in /etc/modprobe.d when it works. Say the loopback is hw:3,*,*.

On the input side of the virtual soundcard, you'll need something like

dmix "main_in" --> plug (slave.channels = 1) --> hw:3,0,0

Then you can aplay -D main_in sound.wav, and run

alsaloop -C hw:0 -P main_in

to connect it to the audio grabber.

On the output side of the virtual soundcard, something like

hw:3,1,0 --> dsnoop "main_out"

and to monitor it on local audio out, again

alsaloop -C main_out -P local_audio_out

You can then run darkice and the VU meter directly on main_out. BTW, arecord -D main_out -d 0 -vv /dev/null is a nice VU-meter for testing.

Read up details on the syntax in the link above, I'm not going to try this out. The --> arrows indicate the master/slave relations of the plugin. The latency will probably be horrible, with one loopback through kernel space, and lots of userspace applications.

If Pulseaudio doesn't work for you, an alternative is jack, but I've no experience configuring it.

  • Pulsaudio happens to be definitely not stable on a raspberry pi. I tried it, but there were way too many problems that werent there without pulsaudio. After starting 'pulsaudio -D' all trouble started, and the trouble stopped on killing pulseaudio and restarting.... So I hope to get some advice on how to do this with Alsa alone. – Arnold Apr 11 '17 at 17:57
  • I am trying to implement the ALSA solution. The modprobing works. The outcome of aplay -l is shown here. After that I updated the .asoundrc file to this. Then this alsaloop -C hw:1,0 -P main_in was executed without errors, apart from some buffer underruns. When testing with aplay -D plug:main_in 1.wav nothing was heard, but thats expected. Now comes the part that does not work yet: alsaloop -C main_out -P local_audio_out: aLSA lib pcm_direct.c:1071:(snd_pcm_direct_initialize_slave) unable to start PCM stream. Any Ideas? – Arnold Apr 22 '17 at 7:01
  • You need a PCM stream from the "virtual" sound card, so the first alsaloop should be running when you start the second alsaloop, and you should start them immediately after each other. Did you do it that way? – dirkt Apr 22 '17 at 7:39
  • i did alsaloop -C hw:1,0 -P main_in <enter> alsaloop -b main_out -P hw:0,0 from the same command prompt. But the latter gives the error. – Arnold Apr 22 '17 at 7:54
  • when issueing the second alsaloop command this is the output: ALSA lib pcm_direct.c:1071:(snd1_pcm_direct_initialize_slave) unable to start PCM stream ALSA lib pcm_dsnoop.c:629:(snd_pcm_dsnoop_open) unable to initialize slave capture main_out open error: Input/output error Loopback initialization failure. Sounds like a dsnoop config error, but i don't see it. – Arnold Apr 22 '17 at 9:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.