Music on Hold with Native Formats

Getting Started -- Last reviewed 2026-06-15 music-on-hold audio configuration performance Found this useful? Upvote it. ×

Music on Hold with Native Formats

The default MOH setup on many Asterisk installs pipes MP3 files through mpg123, an external decoder. It works, but it launches a separate process for every music class, eats CPU for real-time decoding, sometimes fails to loop, and occasionally decides to consume an entire core for no reason.

The fix is simple: convert your MP3s to native audio formats and let Asterisk play them directly. No external process, no decoding overhead, no mysterious CPU spikes.

On this page

Setting up native MOH

Create a directory for your hold music and convert your files:

mkdir -p /var/lib/asterisk/moh-default

# Convert each MP3 to 8kHz mono WAV
for f in /path/to/your/mp3s/*.mp3; do
    base=$(basename "${f%.*}")
    sox "$f" -r 8000 -c 1 -b 16 "/var/lib/asterisk/moh-default/$base.wav"
done

Back up your configuration files

Before editing any Asterisk configuration file, make a backup copy: bash sudo cp /etc/asterisk/musiconhold.conf /etc/asterisk/musiconhold.conf.bak.$(date +%s) If a typo prevents Asterisk from reloading, you can restore the working version immediately.

Edit /etc/asterisk/musiconhold.conf:

[default]
mode = files
directory = /var/lib/asterisk/moh-default
sort = random

mode = files tells Asterisk to read audio files directly instead of launching an external player. sort = random shuffles the playlist so callers do not always hear the same opening track.

Reload:

asterisk -rx "moh reload"

Verify it loaded:

asterisk -rx "moh show classes"
asterisk -rx "moh show files"

You should see your class listed with the files in it. If the file list is empty, check directory permissions. Asterisk needs read access.

Avoiding transcoding entirely

When Asterisk plays MOH, it checks what codec the caller's channel is using and looks for a file in that format. If it finds song.ulaw and the caller is on G.711 ulaw, it plays the file directly with zero transcoding. If it only finds song.wav, it transcodes from signed linear to whatever the channel needs. That transcoding is cheap, but on a system with 50 concurrent calls on hold, it adds up.

Provide files in multiple formats so Asterisk can skip transcoding:

for f in /var/lib/asterisk/moh-default/*.wav; do
    base="${f%.*}"

    # GSM (for GSM codec endpoints)
    sox "$f" -r 8000 -c 1 "${base}.gsm"

    # ULAW (for G.711 ulaw endpoints)
    sox "$f" -r 8000 -c 1 -t ul "${base}.ulaw"

    # ALAW (for G.711 alaw endpoints)
    sox "$f" -r 8000 -c 1 -t al "${base}.alaw"
done

Now Asterisk has four versions of each track and picks the one that matches the channel codec. No transcoding, no CPU cost.

Multiple music classes

Different contexts can play different music. A support queue might get jazz, a sales queue might get upbeat pop:

[default]
mode = files
directory = /var/lib/asterisk/moh-default
sort = random

[support-hold]
mode = files
directory = /var/lib/asterisk/moh-support
sort = random

[sales-hold]
mode = files
directory = /var/lib/asterisk/moh-sales
sort = random

In the dialplan, specify which class to use:

; Set MOH class before entering a queue
exten => s,1,Set(CHANNEL(musicclass)=support-hold)
same => n,Queue(support,t,,,120)

Or in queues.conf:

[support]
musicclass = support-hold

Common problems

No sound plays. Check moh show files. If the class is listed but has no files, the directory path is wrong or Asterisk cannot read it. Run ls -la /var/lib/asterisk/moh-default/ and check ownership.

Sound is garbled or too fast. The source file was not converted to 8kHz mono. Re-convert with sox input.mp3 -r 8000 -c 1 -b 16 output.wav.

MOH works for some phones but not others. If certain endpoints hear silence while others hear music, the issue is codec negotiation. Run pjsip show endpoint <name> to see which codecs the endpoint is configured to allow, then provide files in those formats. To see the actual negotiated codec on a live call, use core show channel <channel>.

User Notes

Know a tip or gotcha for this topic? Share it below and help others.

Contribute a note

Share a tip, gotcha, or practical example. Keep it under 2000 characters. No questions (use the Asterisk community forums for support). Wrap code in backticks.

Moderated before publishing. Email never shown.
Related Snippets