# Asterisk MusicOnHold Notes (Streaming and Classic Hold)
# Asterisk MusicOnHold Notes (Streaming and Classic Hold)
The way custom applications work with Asterisk, from my very very basic functional perspective is it expects 8khz PCM on stdin. So if you had a binary called "audioplayer" that played audio to stdout as raw 8khz PCM samples; then you'd just have to call that binary as a custom application in your musiconhold configuration:
The way custom applications work with Asterisk, from my very very basic functional perspective is it expects 8khz audio on stdin. So if you had a binary called "audioplayer" that played audio to stdout as raw 8khz samples; then you'd just have to call that binary as a custom application in your musiconhold configuration: (Actually if you don't use format=mulaw with mplayer...it breaks)
## Classic Hold Version 2: Less Complex, ***More Headache***
## Classic Hold Version 2: Less Complex, ***More Headache***
### ***This entire thing winds up using entirely too much CPU. It's not just more than the above method, it's entirely too much for the task (in my opinion). The above method uses less than 1% CPU per stream; the below method uses about 15% per stream.***
Let me start by saying this: getting this to work started out as medium-hard; before going full fledged pull-my-hair-out. This is because there's a *number* of additional steps we have to do that are much more involved than setting up and configuring icecast and ices2. Most of these steps weren't documented and I had to piece them together. This was on top of the fact that debugging on a headless machine for sound problems posed limitations. I had to test things on a local VM before attempting to implement them on the remote machine.
Let me start by saying this: getting this to work started out as medium-hard; before going full fledged pull-my-hair-out. This is because there's a *number* of additional steps we have to do that are much more involved than setting up and configuring icecast and ices2. Most of these steps weren't documented and I had to piece them together. This was on top of the fact that debugging on a headless machine for sound problems posed limitations. I had to test things on a local VM before attempting to implement them on the remote machine.
The concept sounds simple; just play some files from a playlist to a pipe; pipe it around; pipe it in to Asterisk. Okay, hold up. It sounds easy; but is it? There's a little issue in that if you tell most players you want to play back to a file and not a sound device; they decode, not play. We don't want, need, or can handle this. We need to simulate real-time playback. The only way to get this done effectively...was pulseaudio. I tried ALSA but this broke on ubuntu; they don't actually include the stuff to configure it. So you'll have a working alsa system; install alsa-utils, and lose it all.
The concept sounds simple; just play some files from a playlist to a pipe; pipe it around; pipe it in to Asterisk. Okay, hold up. It sounds easy; but is it? There's a little issue in that if you tell most players you want to play back to a file and not a sound device; they decode, not play. We don't want, need, or can handle this. We need to simulate real-time playback. The only way to get this done effectively...was pulseaudio. I tried ALSA but this broke on ubuntu; they don't actually include the stuff to configure it. So you'll have a working alsa system; install alsa-utils, and lose it all.
@ -106,7 +108,9 @@ ogg123 randomly plays from the playlist to sink:moh as well as stdout. The playb
After that we pipe it in to sox, which resamples it from it's 16khz to 8khz and spits it to stdout. You can totally do this with just mplayer in a similar manner as above, just swapping your icecast playlist for the local one; keeping the same named pipe method. The problem I had with this (and went down this cliff of a different method); really nasty clicks between tracks. It was something between one player and the pipe.
After that we pipe it in to sox, which resamples it from it's 16khz to 8khz and spits it to stdout. You can totally do this with just mplayer in a similar manner as above, just swapping your icecast playlist for the local one; keeping the same named pipe method. The problem I had with this (and went down this cliff of a different method); really nasty clicks between tracks. It was something between one player and the pipe.
Now I cannot say which method is "better". Ultimately I'm going to judge this by which method uses fewer cpu cycles. I'll run one method for a week, document how much CPU time it used; switch to the other for a week and compare. There may be a lot of additional overhead with pulseaudio, or ogg123 and sox may not be the most efficient way. I will update this later with my findings.
When I originally came up with this ogg123/sox pipe; I had the hopes that it would be less CPU intensive. Fewer processes running, less complex, more streamline. But the reality was entirely different. After a couple of days I checked my load averages; they were somewhere between .38 and .48 over that period. This was pretty high, espeically compared to what the icecast/ices/mplayer method pulled...even with that one process constantly slamming for 100% CPU. Without running any of the MOH streams, the system load was back down to .01 over the course of about a half hour. I did some debugging and fixed that misbehaving mplayer setup, loaded it all up, and checked the load average after a few hours. It was only .02.
The Icecast2/ices2/mplayer method mentioned above is much more efficient CPU wise than the other method. But it's still something I'll keep up as an option.
Your MOH streams may "skip" or have other minor defects for the first few minutes. Mine cleared up after a few minutes and sounded like they had less buffer issues than the icecast.
Your MOH streams may "skip" or have other minor defects for the first few minutes. Mine cleared up after a few minutes and sounded like they had less buffer issues than the icecast.