Using a sound card as a Music on Hold source in Asterisk
Using the line-in port with Trixbox or PBX-in-a-Flash (PiaF)
Asterisk is a fantastic piece of software. You get world class PBX functionality for free, in a package that you can reliably run on a desktop computer.
One area that Asterisk isn’t as world class in is Music on Hold (MoH). Sure, it’s there and it works, but it starts playing a file from the beginning whenever someone is placed on hold. If you have customers who call regularly, they’re hearing the same part of the same files all the time – not ideal.
What I wanted to do was use my MP3 player as a MoH source, feeding through the line-in port of the computer’s sound card. This way, I could have the MP3 player playing whatever music or promotional material I wanted in a continuous loop. Customers wouldn’t hear the same 30-60 seconds of the same files all the time. If I wanted to change or rearrange things, I would’t need to touch Asterisk at all – just disconnect the MP3 player, change whatever I needed and plug it back in and press play.
So I went looking for how to do this. I’ve been playing around with Asterisk for a little while, but hadn’t really messed around with Music on Hold very much. What I found was this page on the voip-info wiki, which talks about how to do it waaayyy down at the bottom of the page. The problem was that the solution provided didn’t work “out of the box”, so I had to do a bit of tweaking to finally get it working.
These are the details of how I got it working on my test box (aka “Play PBX”). It’s a desktop PC running PBX in a Flash, an ISO based asterisk distro from the fine folks at Nerd Vittles. PiaF is based on CentOS 5 – you may need to adjust some of these steps accordingly if you’re using a different *nix distro.
- You have a sound card in your Asterisk / Trixbox / PiaF machine.
- The sound card is recognized by the operating system.
- You have an external MoH source (MP3 player, radio, etc).
- You have some basic knowledge of how to move around in the operating system and edit files.
- The program arecord is installed on your system (probably in /usr/bin).
- The program alsamixer is installed on your system (probably in /usr/bin) and compatible with your sound card.
The instructions on the voip-info wiki say to start with editing musiconhold.conf thusly:
The [default] section may or may not already exist. If so, you can edit it accordingly, or you can create a new section named whatever you choose. If you do that, make sure you know how to specify it so your callers will hear that source, instead of the [default]. I won’t go into how to do that, so if you don’t, stick with using [default].
The wiki also states that you should have at least one .mp3 file in /var/lib/asterisk/mohmp3 (or whatever directory was specified in your config). I don’t know why this is, but it’s true, and a .wav isn’t good enough – you have to have an .mp3 there.
Next, you need to create the ast-playlinein script. This is a one-liner bash script that is what actually gets the sound from the sound card and feeds it to asterisk on request. This is where the wiki and I diverged – the script they proposed didn’t work for me. It also had a couple of options that were redundant, as they were explicitly specifying arecord defaults. Anyway, here’s the contents of the suggested script, and the one that worked for me.
The one they suggested (DID NOT WORK for me):
/usr/bin/arecord -q -c 1 -r 8000 –buffer-size=2048 -f S16_LE -t raw
The one that works (for me):
/usr/bin/arecord -q –buffer-size=2048 -f S16_LE
The ‘-c 1‘ and ‘-r 8000‘ options were redundant, as they’re just specifying the same values that my version of arecord uses by default, so I took them out. If the script doesn’t work as-is, you should double check whether or not they’re the default in your version of arecord (man arecord). I think the big difference is the ‘-t raw‘ option. The default output format for arecord is WAV, which is apparently what we want, as it works. I’m not well versed on audio file formats, so I’ll leave the reasoning behind all of this to those that are, but dropping the ‘-t’ option seemed to make the difference for me. YMMV.
Now, make sure that the ast-playlinein script is executable – issue the following command as root:
chmod 755 /usr/sbin/ast-playlinein
Next, we need to configure the mixer to use the line-in port to capture the audio we want. We use the alsamixer program for this. When you run it, you should see something like this:
Assuming you have something that looks kind of like that, press F4. This tells alsamixer to only show the controls for capturing. You should now have something like this:
Using the arrow keys, navigate to the line-in control (marked Line). The selected control will have < and > surrounding it: . Now press the space bar, and CAPTUR should appear above it (see image above), indicating that it’s now the selected audio source.
Now navigate to the Capture control (on the far right in the above image). This is the input volume, or gain, for the selected source (Line). You may (probably will) need to adjust this later, to get the right volume for your MoH. Remember how to get here – alsamixer, then F4. For now, set it somewhere around 50-75% using the up/down arrow keys.
You’re done with alsamixer (for now), so press the Esc key to exit.
You’re almost done!
Finally, we probably need to tweak some permissions a little. If you run asterisk as root (why would you do that?!), then you can most likely skip this step. Otherwise, read on…
Look at /dev/snd and see what the permissions are. Most likely, you have something like this:
drwxr-xr-x 2 root root 180 Dec 8 10:51 snd
That’s read/write/execute for root, and read/execute for everyone else. Not good enough, my friend! The user running asterisk needs to be able to write to that directory, too. In our case (using PiaF – Trixbox is the same), that user is asterisk. The default group for the user asterisk is also asterisk.
We’re going to need to change the ownership and permissions for that directory, and everything inside it. Since it all gets reset every time we reboot, we’re also going to need to set it up so that the necessary changes happen every time the system comes up, too. The easiest way to accomplish that is to add the necessary commands to /etc/rc.d/rc.local, which is a script that runs after all the other init scripts (in /etc/rc.d/init.d) have finished running.
Add these commands to rc.local:
/bin/chown -R .asterisk /dev/snd
/bin/chmod 775 /dev/snd
/bin/chmod g+rw /dev/snd/*
The first one changes group ownership of the directory and everything in it. The second allows the group (asterisk) to write to the directory. The 3rd allows the group read/write permission to everything inside the directory. Save the file and exit your editor.
That’s it! Now reboot and when everything loads up, you should be able to put yourself on hold and hear your external audio source (you did remember to plug it into the line-in port of your sound card, right?). Don’t forget that you’ll probably need to adjust the volume coming from your device, as well as in alsamixer. Play around with both of those settings until you find a happy medium.