So you’ve heard there is now an Opus codec for Asterisk that’s been released. However, you are having problems with poor audio quality due to packets being dropped or lost. You’ve also heard or read that Opus can do something called FEC, but are not sure how do get it work with Asterisk. You’re in luck since since this post is exactly about that!
For start, and with nothing else configured, the Opus codec for Asterisk uses the native packet loss concealment (PLC) employed internally by the Opus library. This in and of itself can be capable of mitigating some audio problems due to packets being lost. However, in some situations this is not enough. When packets are dropped a tick, pop, or other audio anomalies can sometimes still be heard. Luckily, Opus has another option in its toolbox, namely FEC.
What is FEC?
FEC is an acronym that stands for forward error correction. With regards to audio/telecommunications, it’s a capability that some systems employ to help mitigate errors when unstable transmissions occur. While implementation and handling algorithms can differ, an Opus encoder can embed redundant data about the preceding packet in-band in the current packet. This extra information can be crucial on the receiving side when a packet has been lost. For instance, when a packet of audio has been dropped an Opus decoder can rebuild that lost packet from the FEC data it obtains in the next packet it receives. This of course can help alleviate gaps in the audio stream.
At this point you might now be saying, “That sounds great! How do I get Asterisk to do that?”. First let’s take a look at how to get the encoder to include FEC data.
As mentioned FEC, is added in-band by an Opus encoder, but only after being configured to do so. A previous post already discusses all the available options you can set on the encoder, so be sure to check that out if you haven’t already. Here though we’ll discuss some of those options and how they work in combination to make it so the encoder includes FEC data. As stated in the Opus FAQ several conditions must be met before the encoder will add error correction to frames:
- The feature must be enabled. The “fec” option must be set for a defined format (note, options for codec Opus for Asterisk can be set in in codecs.conf ). This option defaults to “no”, so if you don’t specifically enable it Asterisk will not include FEC data when encoding.
- The encoder must be told to expect loss. This means an estimated packet loss percentage must also be specified. Setting this shifts the threshold at which the encoder will start to include FEC data. The higher the number the lower the threshold.
- The codec must be operating in a mode conducive to lower bandwidths. Make sure the maximum bandwidth is set to narrow or medium. This can be achieved by adjusting the “max_bandwidth” option. You can do this either directly by setting the option itself, or indirectly by setting the “max_playback_rate” option to 16khz or less.
Don’t forget to make sure both sides have negotiated for FEC. If everything is properly set up, but one side does not offer FEC (“useinbandfec=yes“) then it will not be enabled.
Now that encoding is configured correctly, and working, let’s take a look at the decoding side.
Unlike all the other options that are used only for encoding, setting the “fec” option also enables it for decoding. When enabled this means that upon noticing packet loss, and then receiving a packet containing FEC data the Opus codec for Asterisk will decode the data. It then inserts it into the audio stream where the previously missing audio segment existed. It should be noted that only a single missing audio frame can be reconstructed for each packet received. So if two or more sequential packets have been dropped then only the last one missing (or received packet minus one) can rebuilt.
Again, both sides must negotiate for FEC in order for it to be enabled. But, if FEC is disabled in Asterisk, and packets containing FEC data are received by the decoder it will simply ignore the included in-band error correction information. However, the accompanying regular audio is still appropriately decoded.
There is one slight drawback to enabling FEC. The quality of the audio may be lower. This of course is better than no audio. However, in the case where FEC data is being encoded, but no packets are being dropped then this might not be ideal. This is why you don’t necessarily want to enable it and then set “packet_loss” to 100, thinking why not just always have it “on”.
There you have it. Now if you are having a problem with poor audio due to dropped packets, and are using the Opus codec for Asterisk, this situation can be potentially improved by easily modifying a few configuration options.