Music on hold choppy when pressing hold button

I have a small asterisk setup with an external SIP trunk and few local agents. When a client calls he is answered by an agent and everything works flawlessly. Sound quality is great. I want the agents to start using ‘hold’ in their phones (Jitsi softphone). However the MOH which plays when client is put on hold using ‘hold’ button in softphone is extremely choppy and garbled. I’m using the default MOH sounds.

The ‘hold’ button in Jitsi works by sending a SIP INVITE from agent to asterisk with ‘sendonly’ flag, this indicates to asterisk that it should start MOH to the client.

It works, but the music is broken:
– Started music on hold, class ‘default’, on channel ‘SIP/uplink24-0000000e’
> Locally RTP bridged ‘SIP/uplink24-0000000e’ and ‘SIP/108-0000000f’ in stack

I tried starting MOH using three other methods:

  1. using Answer + MusicOnHold app in dialplan (instead of Dial, just to test it) - works fine, music is always clear
  2. using Dial with ‘m’ flag (without Answer), this works as well because my SIP provider allows early-media, music is always clear
  3. using AGI and Parking the call with it:

Action: Park
Channel: SIP/uplink24-00000008
Timeout: 0

The client is parked, MOH starts playing clearly and without any issues. Agent leg is obviously dropped. I can resume the call later with AGI Redirect and continue in the call.

In all cases I’m using g722 codec. I have used the standard music in gsm format (which resulted in real-time transcoding) and also manually transcoded it to g722 so there is no real-time transcoding needed. Always same results.

Also I have to add that when I call between two agents and one puts the other one on hold using the ‘hold’ button the music is fine. So this looks to be related just to the uplink SIP peer and only when using the ‘hold’ button.

Why is the MOH choppy and unbearable when put on hold using softphone ‘hold’ button and it works just fine with any of the other three methods?

Thanks for any advice

Exactly same issue here: [jitsi-users] Music on hold issues with stable jitsi as SIP client - Archive - Jitsi Community Forum - developers & users still unresolved.

When running wireshark I noticed that Jitsi still sends RTP packets when the call is on hold. I noticed in the ‘hold’ INVITE packet there is ‘sendonly’ keyword. Apparently this is done so that Jitsi can send some MoH. However Jitsi does not send anything but white noise. The hold is therefore not bidirectional but unidirectional. Then I applied iptables filter to block those RTP packets during one-way hold and the MoH which asterisk sends to client improved to 100% quality - no more stuttering.

My view is that asterisk is somehow trying to mix the white noise Jitsi is sending with the MoH which asterisk is sending (maybe preferring the noise from Jitsi) and that causes breaks. When I blocked the RTP packets from Jitsi the problem went away.

I couldn’t think of easy way how to automate blocking of the RTP packets so instead I looked in the source code of asterisk and I modified the one-way hold to become two-way hold. Very simply said - if one side sends ‘sendonly’ in SDP then I forced asterisk to consider it as ‘inactive’ which means two-way hold. I know this is extremely bad solution but it solves my problem. I can’t modify Jitsi code to not send the white noise or to send ‘inactive’ instead of ‘sendonly’ in SDP.

Here is the patch if anybody is interested:

--- channels/chan_sip.c 2022-04-26 13:02:24.903232145 +0200
+++ channels/chan_sip.c 2022-04-26 13:02:24.987235683 +0200
@@ -10111,7 +10111,7 @@
        ast_clear_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD);
 
        if (sendonly == 1)      /* One directional hold (sendonly/recvonly) */
-               ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ONEDIR);
+               ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_INACTIVE);
        else if (sendonly == 2) /* Inactive stream */
                ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_INACTIVE);
        else

I’m not proposing to include this in asterisk. This is VERY BAD, but it works. However maybe adding an per peer option to force all one-way holds to be two-way holds? Or adding another option to Dial() to do the same thing?

hmm have you testet if this also is a problem for chan_pjsip, as chan_sip will be depreciate next year

chan_sip is deprecated now and has been for many years. The change next year is its complete removal.

I believe chan_pjsip has an option to accept the sendonly stream, rather than trying to replace it.

Also, as far as I can remember, you only get problems if the sendonly stream is being sent as direct media, in which case it the final destination that gets the mixed streams. I can’t remember if chan_sip reinvites the media back during a hold.

The underlying problem is that sendonly is used as a signal for hold, as well as for a true sendonly stream, and when normal phones signal hold, they don’t provide media, so having Asterisk provide media works best when dealing with typical phones.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.