AudioBridge audio limiter#3593
Conversation
|
@m08pvv @lminiero FYI we tried this in our production environment and got very good results. 1) users with very sensitive mics and loud voices now sounds much better; 2) if they speak at the same time it sounds better too. Overall I think this can be very good PR for audio bridge, especially for rooms where everybody can speak, not just one speaker. |
|
So, @lminiero how it's going? |
|
It's Easter holidays here, I'll bring it to the rest of the team when we get back. Study of the code apart, we'll need to set it up internally for some specific testing, since as I mentioned it's a very fundamental part of our products, so I won't merge it until I'm 100% sure it won't cause issues. I'm half thinking of putting it on the demo server, and set up one room with and one without: if we set it up so that the default room (1234) uses it, we'll have data in case people using it crash it for any reason. |
|
Waiting for test results and hope they'll be ok. |
|
@m08pvv the current plan is:
This will allow me to 1. evaluate the general stability of the code, since random people from random networks doing random things will use it, and 2. by adding different rooms (some with limiting enabled, others not) me and my team can make some more tests related to the audio quality. Does that make sense for you as a way forward? |
|
@lminiero, good plan. Looking forward for upcoming merges! |
|
@m08pvv FYI I've merged both the PRs I mentioned. When you have some time, could you align to the latest changes there? Hopefully it won't be too complicated, since I see some conflicts there. Thanks! |
|
@lminiero, will update my branch today hopefully |
# Conflicts: # src/plugins/janus_audiobridge.c
|
Merged, will check for any issues after merge (just in case) a bit later |
|
@m08pvv thanks! I'm out for a conference for a few days, but as soon as I'm back I'll update the demo server as we discussed (which whould also give you time to double check everything's still ok). |
|
@lminiero, I'll check today that merge didn't break anything (it was a pretty simple merge, but just in case) |
|
So, tested with 5 participants, all works fine |
|
@lminiero I'm just curious how it's going? Is it already on your demo server? Hope everything is ok (keeping my fingers crossed🤞) |
|
My apologies, it's not on the demo server yet... It's been a brutal couple of weeks, as I was to two separate conferences the past two weeks. I'll switch the demo server base to that in the next couple of days 🙏 |
|
I've just updated the demo server to use your branch. There are two rooms configured:
The second room can be accessed passing the https://janus.conf.meetecho.com/demos/audiobridge?room=4321 Both rooms are configured to use 16000 as a sampling rate, as it's probably the most used. We collect core dumps when the server crashes, so that should help identify potential causes of issues. A couple of notes from while I was upgrading. There's a warning when building: Besides, I see the "list" request hasn't been updated to return info on whether the limiter is enabled for specific rooms. That may be helpful, as right now for instance I have no idea if how I configured the rooms actually did the trick or not. I see there are other features we may need to add to "list" (like denoise and others) so that's on me too. You also didn't update the sample configuration file, but only the description in the Audiobridge doxygen section. The configuration sample does need to list use_limiter as an option, as in the docs, as most people only read what's written there and not the documentation (sad but true). |
|
Will check and fix all points mentioned. Not sure when (this/next week I hope) |
|
@m08pvv sorry for the radio silence! I finally found some time to properly test your patch, with the help of a colleague. We focused on our own conversation and many other fake participants chiming in at different times. I have to say the results were much better than I expected: as I mentioned in previous comments, I was afraid that just unmuting could cause drastic lowerings of the volume, but we didn't experience any of that, and the audio, while chaotic (but that was normal due to the fake participant's audio that was out of context), was always quite good. The end result was even more impressive when we did the same test on the "regular" AudioBridge, where clipping and artifacts were indeed brutal. I want to make some more tests involving my other colleagues (for a "proper" test with "proper" audio), but I think it's safe to say that I definitely see this as a valid improvement, and so there's a practical plan for merging sooner rather than later! One area where we think the current patch may be improved would be addressing overflow mixing in general, as in louder scenarios we were still getting very close to the maximum levels. I think that simply integrating the overflow mixing done in #3601 may be enough, were the cap is not INT16_MAX but about 0.9 of that. That would provide some nice limiting to stay away from saturation territory. While we plan for more internal testing, could you address this and the other notes I mentioned in previous comments? I think what's left to be done is mainly:
More may come to mind but I think this is mostly what's missing right now before we get to a mergeable state. Looking forward to your thoughts, and thanks again for your work (and most importantly patience 😆 ) |
|
@lminiero, thanks for all the tests and a review. I'm back from vacation and hope will find some time sooner rather than later 😉 to fix all mentioned points. |
…n (and remove duplicated piece of docs)
|
@lminiero, I pushed some of the changes (added janus_audiobridge_ prefix to functions, added info to 'list' command and it's documentation, added use_limiter option to the audiobridge sample configuration) |
|
And regarding saturation - can you attach some audio samples that cause issues? Because a simple cut-off for a complex audio signal might sound much worse than an audio that almost reaches maximum 🤷♂️ |
There's no actual issue: the whole idea was to avoid that the mix ever gets to samples with the loudest value possible, hence limiting the max value we accept to ~0.9 the actual max value (INT16_MAX). This is what some audio solutions do in order to avoid problems with playback. So I'm not proposing a hard cut-off, but a smaller max that your code should take into account when limiting. I guess it would be hard to enforce the same when the limiter is not active, though, i.e., when there's just a couple of people in the room. |
|
Basically the limiter itself limits the mix and it almost never gets to such high values (except some cases when volume changes in some non-linear way that it's hard for the algorithm to smoothly catch). If you have an example of such audio I can take a look what we can do to avoid it. Maybe we can just add some 0.9 gain if we encounter such case, but anyway have to see an example. |
|
@lminiero, let's sync what's left before the merge? |
|
The current plan is to merge after the summer break: I'll go to the IETF meeting in a few days, and when I'll be back I'll only have a few days before a bit of a holiday break. When back, unless the testing on the public demo says otherwise, I think we can merge. |
Worked a bit with AudioBridge and it was painful to hear all crackling noises when multiple streams summed up, so I decided to implement an audio limiter. I took AGC2 from Google's WebRTC (BSD 3-clause license that allows modifications and usage as long as license file stays in repo) and translated it to C (didn't write in C since school, so it might be not clean enough), adapted it for AudioBridge and also added SSE 4.2 and AVX2 versions (with proper initialization from available at runtime).
Also added a parameter to AudioBridge: use_limiter (boolean, default=false), which enables limiter. If limiter is disabled - only clamping (saturation to int16 boundaries) applied.
Here are some results of many participants speaking (5 participants speaking and the record is from incoming ab track):

Top - current Janus release with AudioBridge
Bottom - version with limiter and use_limiter = true
Full-spectrum lines - artifacts (crackling noise and clipping)
As you can see, current Janus AB implementation (just sum up all tracks) results in artifacts (values outside int16 range) whereas limiter reduces volume dynamically to normal level.
How it works:
Usage:
By default limiter is disabled and only clamping is applied.
Set
use_limiterproperty increateaudiobridge request totrueto enable limiter.Any suggestions are welcome!