Auto-adjustment of channel faders#1071
Conversation
|
I love the idea of this feature. 1- when is this computation and adjustment done? |
|
OK, the code looks pretty good. I reviewed the code, of course. It needs just a few changes to capture what you've put in the (very good) description here. (Plus a couple of minor tweaks.) |
It is done via a menu currently called
Since this feature is run once, you will not have a continuous adaptation.
Good point! You could group the voices and adjust whole groups at once. We could also think about considering groups in the computation of the levels. However, I am not sure whether this might add a kind a secret logic which leads to confusion!? |
It would be useful if the grouping feature could be taken into account. (So "per group" and "all groups" options, if groups are set?)
People using grouping probably understand what they're using it for. People not using it won't be affected. |
|
#4 is hard. Very useful for choirs, especially barbershop. I've never noticed/seen the Auto-Adjust all Faders. I'll have to give it a try. |
You'll need to build JohannesBrx/jamulus/AutoAdjustChannelFaders to get it. Oh, or here |
It will be important to gain some experience of the approach in practice, especially whether the accuracy using the current 4 bit level meter values is sufficient. Up to know I verified the correctness of the implementation by using a sine wave input signal at different (specified) amplitude levels, applying the method and then recording the output in Audacity. I also did a quick test during our choir rehearsal. The adjusted faders looked at least plausible to me ;-) I currently plan doing other tests with voice samples at different well-defined amplitude levels. |
It should be available for 31 days according to the build log ( |
|
Important note: For live tests please use https://github.com/jamulussoftware/jamulus/actions/runs/583730608, which contains an important bug fix. I performed a controlled test with multiple sine wave blocks at 440Hz and various amplitude levels. I fed this signal into Jamulus as the input or microphone signal (see figure below). The amplitudes range from 0dB down to -40dB in steps of -2dB and each amplitude level lasts for 5 seconds. Jamulus was run in a special mode where the fader adjustment is constantly applied -- note that this is just for testing. Finally, I recorded the output signal (earphone signal) from Jamulus. The amplitude ranges are also denoted in the label track. One can see that the input signal is constantly being adapted and the output signal remains in a certain corridor, which is limited by the quantization of the levels from the server. For approximately three neighboring amplitude level blocks (spanning 6dB) the level meter value is the same. Therefore, the fader cannot be adjusted in this small range. However, in practice, the accuracy might be better because typical music or voice signals will exhibit a larger amplitude range. Averaging the resulting different level meter values might then improve the accuracy. |
|
@JohannesBrx Thanks for your work! Your tests look really thorough, I'll give this a try with my choir later today and will report back how it works in practice. |
Great! I'm looking forward to your feedback. Be sure to get the latest version with the bug fix under https://github.com/jamulussoftware/jamulus/actions/runs/583730608. |
|
As I understand the past discussion, this auto-adjustment is manually triggered. Q1: how long is the sampling period? Q2: What kind of "warm up" is best for the auto-adjustment? |
There is no explicit sampling period. Instead, I use an exponential moving average (I updated the first comment for the PR with a figure). In extreme cases where you start from silence to full signal it would take 5 seconds for the average to be converged or stable. In practice I would assume that 2 seconds should be sufficient.
At the moment I would suggest that the whole choir sings an Ahhh vocal for at least 3 seconds and the auto-adjustment is triggered a bit before the end of the sequence. The frequency should not play an important role for the adjustment itself. However, it should be a tone pitch which is comfortable for each singer. Applying the auto-adjustment at a non-uniform section of the music will most probably not work correctly. |
|
Thanks for the suggestion for giving the auto-adjustment a sample.
You do have an implied start time from the beginning of the moving average window. It sounds like the process would be: |
|
I think Auto-adjustment for volume would be a great thing to have, but aren't you trying to solve it at the wrong side ?? And a simple 1.5 or 3dB Step volume control would be easy to implement with just a few shift and add instructions. |
|
@JohannesBrx So, the test went really well! We were some 16 singers and I tried the auto-adjustment multiple times within a (homophonic) piece (so, not even deliberate Aaahs or something). I'm not saying that I can confirm that it works flawlessly (did not have the time to check during singing). I'm merely saying it works and it is a huge improvement over the status quo. I'm pretty sure this will be a welcome addition especially for larger groups. @pgScorpio |
Please note that the averaging is done continuously. When you start the auto-adjustment, the current average is taken. Therefore, the averaging considers audio samples before starting the auto-adjustment. The advantage is that you have already heard the sequence which the auto-adjustment operates on. (It also makes implementation in this case easier.) |
I agree with you that having access to the microphone level at the client side would be a great improvement since this is a topic we stumble across each choir rehearsal session. As @hoffie mentioned, this would be a topic to be discussed in #1030. However, I would not count on every choir (or band) member correctly setting up the microphone level when some of the less experienced participants even need help installing the software. Doing it automatically would require that everyone sings approximately the same calibration tone. In my opinion it would not fit into the concept of Jamulus to automatically trigger the microphone level calibration at client side for all clients. Finally, several audio interfaces have a hardware control knob to adjust the microphone level. |
|
@JohannesBrx I was trying to be very careful. Note:
Here you say "done continuously". I wanted to know the bounds of the measurements. In an earlier message, it was said it was manually triggered. Also said, "considers audio samples before starting the auto-adjustment". I want to know how long before the start. The reason I made explicit what I thought would be the process for a chorus, you can't turn on the sound and amplitude instantly and accurately. So, I expect to ask the chorus to produce the sound they want to use for setting the levels starting before the samples used by the algorithm and held stably past the end of the measurement. The less expert the chorus, the longer it takes for turning on and off the desired sound.d Thanks. |
"Doing it automatically would require that everyone sings approximately the same calibration tone" |
There are two scenarios. In the more complicated case, the user wants their mic volume set relative to the whole ensemble because later in the music with lots of texture and mood changes, each section has a different volume relative to other sections. To get the right relative volume, you need to hear the relative volume. In Zoom the control is more like a vox. You are on or off. If you try to speak softer relative to another speaker, Zoom will ignore you. In music, there is a lot of magic in the changes of relative volume. |
@gene96817: At the moment where you start the channel adjustment, the current averaging level is taken and the faders are then directly adjusted. You could say that the current status is frozen and used for adjustment. Only audio samples before starting the adjustment are considered by doing so. However, there is no distinct time period from when the samples are taken. I tried to visualize that in the following figure: The blue curve is the input level from the server, where dots indicate the discrete sampling interval of 266ms. The orange curve is the averaged level value. You can see that the noise of the input values is reduced but it takes approximately 5 seconds to reach the final value. Roughly speaking, when you press CTRL-F or use the menu entry, samples from the last 5 seconds are taken. In practice, I would let the choir sing a phrase with different tones and perform the adjustment at the end of the sequence. The phrase should be at least 5 seconds long. |
How would we indicate the user calling the adjustment which channels have been adjusted and which ones not? Currently the faders of channels which cannot be adjusted will be at their maximum range. (It is the best we can do.)
I would choose (1). Visitors, instructors, streaming clients etc. could have no group assignment to skip adjustments. |
|
I used this in the last two rehearsals and it works good. The only problem might be the missing accuracy but I'd say that's an improvement for a new PR. Better to have this feature than not having it at all. |
66aa3fc to
6baa05f
Compare
|
Would this also be ready to be merged? |
I think so. However, a second review is still missing. |
|
Ok. I'll look into it tomorrow. BTW: thank you for all your input and PRs! |
(Proof of concept)
Do not adjust channels without group in group mode.
6baa05f to
c071234
Compare
ann0see
left a comment
There was a problem hiding this comment.
From my tests and a quick look over the code, I'll approve (but not merge) it yet. Softins or someone else should have a look at the code too before a merge.
I will look through the code and review asap. |
softins
left a comment
There was a problem hiding this comment.
I haven't studied the algorithm in detail, but the code looks good, and I have built and tested it on my Pi.
hoffie
left a comment
There was a problem hiding this comment.
I finally took the time to scan the code and it looks good to me. I've already used it multiple times im practice and it does provide a huge benefit. A huge thanks for doing this!
@JohannesBrx Do you want to add yourself as a contributor in src/util.cpp as part of this PR?
Not merging yet for this reason, other than that, I think this can go in. :)
I have added myself to the list. I am glad to be able to give something back in this great project. |
|
I think you should also edit the changelog and give a shot description there? Afterwards this can be merged. |


This pull request (for issue #966) adds an automatic adjustment of the channel faders depending on the volume of each channel via a new menu entry
Auto-Adjust all Faders. This shall specifically support larger choirs to get a reasonable mixer setting, although individual adjustments might still be necessary. The function could be called during voice warm up or a uniform part of the music piece. Adjusting the large number of channels manually is quite tedious and might be required for each session because the participants might not use the same microphone levels each time.Latest demo version: https://github.com/jamulussoftware/jamulus/actions/runs/627676186
(Updated Mar, 6th 2021)
Application
The channel adjustment is best used right before the end of a warm-up singing phrase. When being called, approximately the previous 5 seconds are considered for channel adjustment. The shortcut CTRL+F or CMD+F is handy for quick access.
When using channel groups, all groups are equalized such that their contribution is equal. In addition to that, individual channels within a group are also equalized to contribute equally to the group.
Implementation details
The method averages the level meters for each channel, which get their input from the server. Averaging is particularly necessary to overcome the coarse quantization of the server values: The 4 bit meter level values are given in decibels ranging from -50dB to 0dB in 9 steps from 0...8, while each step is 6.25dB. (The meter value 9 is reserved for indicating clipping.)
The adjustment computes the channel fader positions for a target volume of -30dB. Therefore, the channel fader for a channel with -30dB original volume is set to its maximum, thus not reducing its original volume. Louder channels are attenuated accordingly. Channels quieter than -30dB are too weak for a full compensation: Although the channel fader will be set its maximum for these channels, they cannot be fully compensated.
Averaging the meter level
Averaging the current meter level
channelLevelis currently done with code likewhere
alpha=0.2andavgLevelis the averaged level. The update ofavgLevelcan be seen in the following figure. The dots indicate the update intervals of 266 milliseconds. In practice, convergence might be faster because you would probably not start from silence.Accuracy improvement
So far, this implementation only affects the client.
However, the accuracy of this approach is negatively influenced by the low accuracy (4 bit) of the level meter value from the server, which has a resolution of 6.25dB. While (currently) not being implemented in this PR, I investigated using 8 bit instead 4 bit for the level value, resulting in a much better precision. However, this would also increase the data stream: The level is sent every 200 audio frames. Typical Jamulus UDP packages (medium quality, mono, 128 bytes audio buffer) are 88 bytes according to Wireshark. The channel level list package is 60 bytes for one channel. For a typical choir of 40 persons, the data rate would increase from 88200+59+40/2=17679 to 88200+59+40/2=17699, which means 0.11% increase. The bandwidth for one channel would increase from 369kbps to 369.42kbps, when I computed everything correctly.
Alternatively, one could think about a new protocol message which is used to request recommended channel fader values from the server, which would only be sent on demand.