Setting Up Music On Hold

Most probably, the music on hold that you will want to use will come as an MP3 file. This is definitely not what you want Asterisk to use for playing music on hold. Asterisk will use up a whole bunch of cycles converting the MP3 file to the proper format for the codec in use on the caller's line. The volume may be too low or too high and/or the dynamic range may be too large. The sampling rate will undoubtedly be more than the 8 kBps that is optimum for telephony and the high frequency components will be clipped. So, the best approach is to convert all of the MP3 files into the proper format and "tune them up" along the way.

In the nothing is ever simple department, we begin this process with lame. We'll use it to convert the MP3 files to WAV files. But, before we can do that, we have to install it on the system. But, before we can do that, we have to add the repository where it lives to the yum repository list. To do that, fire up your favorite text editor, as the super-dooper user, and edit the repository list. Add the ATrpms 3rd party repository to the end.

/etc/yum.repos.d/CentOS-Base.repo:

.

       .

#atrpms - ATrpms 3rd party RPMs - Only the stable RPMs are used. [atrpms]
name=CentOS-$releasever - ATrpms
baseurl=http://dl.atrpms.net/el$releasever-$basearch/atrpms/stable gpgcheck=1
gpgkey=http://ATrpms.net/RPM-GPG-KEY.atrpms

Now, we can install lame:

     su
     yum install lame

Next, try converting an MP3 to a WAV file.

     lame --decode AceInTheHole.mp3 AceInTheHole.temp.wav

Once we have it converted to a WAV file, we can use sox to resample it to 8 kHz and apply the compander to limit the dynamic range and cut down the volume (note that we're using a slightly different compander function than used for IVR menus in the Converting Recorded Sounds For Use By Asterisk section because music has more potential to blow one's ears off). The (Butterworth) lowpass filter rolls off the higher notes (above 4 kHz) which is desirable for telephony:

     sox AceInTheHole.temp.wav -r 8000 -c 1 -s -w AceInTheHole.wav \
         lowpass 4000 \
         compand 0.02,0.05 -60,-60,-30,-12,-20,-10,-5,-10,-2,-10 -10 -9 0.05 \
         resample -ql

You can test out your new music on hold file by copying it to Asterisk's moh directory (by default, /var/lib/asterisk/moh), and restarting Asterisk:

     su
     cp AceInTheHole.wav /var/lib/asterisk/moh
     /etc/init.d/asterisk restart

This should get you started with music on hold. If you make a call an place it on hold, you should hear the music. The output volume (if too loud) can be adjusted by reducing all of the compand filter results by a couple of dB, like this, for example:

     sox AceInTheHole.temp.wav -r 8000 -c 1 -s -w AceInTheHole.wav \
         lowpass 4000 \
         compand 0.02,0.05 -60,-60,-30,-14,-20,-12,-5,-12,-2,-12 -12 -11 0.05 \
         resample -ql

If you have a boat load of hold music that you wish to convert, this script should prove useful.

MP3ToMoH:

     #!/bin/sh
     # Process all of the MP3 files.
     for i in *.mp3; do
         mohfile=`basename $i .mp3`
      # Pass each MP3 through lame.
      echo Preprocessing $i
      lame --decode $i ${mohfile}.temp.wav
      # Pass each converted WAV file through sox.
      echo Converting to ${mohfile}.wav
      sox ${mohfile}.temp.wav -r 8000 -c 1 -s -w ${mohfile}.wav \
          lowpass 4000 \
          compand 0.02,0.05 -60,-60,-30,-12,-20,-10,-5,-10,-2,-10 -10 -9 0.05 \
          resample -ql
      # Clean up.
      rm -f ${mohfile}.temp.wav

done

After you change the permit-skis on the new script to allow it to be executed, change to the directory where all of the music on hold files are found and run the script (here, we assume the script and the files are in the same directory):

     chmod ugo+x MP3ToMoH
     ./MP3ToMoH

If you have many files, go for a serious cup of coffee. Converting them will take a long, long time. Once the conversions are all done, copy all of the new music on hold files to Asterisk's moh directory:

     su
     cp *.wav /var/lib/asterisk/moh

Edit the music on hold configuration file to change the sort order to random. Otherwise, there's not much point to having multiple music on hold files, since Asterisk will always start with the first one (which is all most users will ever hear). This is pretty much the only change needed to the music on hold configuration.

/etc/asterisk/musiconhold.conf:

.

       .

[default]
mode=files
directory=moh
sort=random

Once you've saved thise changes, restart Asterisk so that it will read all of the music on hold files into its internal list:

     /etc/init.d/asterisk restart