Skip to content

Comments

Auto-adjustment of channel faders#1071

Merged
hoffie merged 14 commits intojamulussoftware:masterfrom
JohannesBrx:AutoAdjustChannelFaders
Mar 20, 2021
Merged

Auto-adjustment of channel faders#1071
hoffie merged 14 commits intojamulussoftware:masterfrom
JohannesBrx:AutoAdjustChannelFaders

Conversation

@JohannesBrx
Copy link
Contributor

@JohannesBrx JohannesBrx commented Feb 19, 2021

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.)

image

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 channelLevel is currently done with code like

            avgLevel = (1.0f - alpha) * avgLevel + alpha * channelLevel

where alpha=0.2 and avgLevel is the averaged level. The update of avgLevel can 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.

image

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.

@gene96817
Copy link

I love the idea of this feature.

1- when is this computation and adjustment done?
2- How do we freeze the settings? Some pieces have a wide dynamic range (ppp to fff).
We don't want this to be a continuous adjustment that kills the dynamic range and expression of the music.
3- How do we undo the freeze and get a new adjustment?
4- what is the recommended usage for a chorus where some sections are of different sizes? The balance is made (heard?) by sections and not by singers; meaning, each singer does not have the same weight in sound contribution.

@pljones
Copy link
Collaborator

pljones commented Feb 19, 2021

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.)

@JohannesBrx
Copy link
Contributor Author

1- when is this computation and adjustment done?

It is done via a menu currently called Auto-Adjust all Faders right below the existing Set All Faders to New Client Level. You have to start it manually.

2- How do we freeze the settings? Some pieces have a wide dynamic range (ppp to fff).
We don't want this to be a continuous adjustment that kills the dynamic range and expression of the music.
3- How do we undo the freeze and get a new adjustment?

Since this feature is run once, you will not have a continuous adaptation.

4- what is the recommended usage for a chorus where some sections are of different sizes? The balance is made (heard?) by sections and not by singers; meaning, each singer does not have the same weight in sound contribution.

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!?

@pljones
Copy link
Collaborator

pljones commented Feb 19, 2021

We could also think about considering groups in the computation of the levels.

It would be useful if the grouping feature could be taken into account. (So "per group" and "all groups" options, if groups are set?)

However, I am not sure whether this might add a kind a secret logic which leads to confusion!?

People using grouping probably understand what they're using it for. People not using it won't be affected.

@gene96817
Copy link

#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.

@pljones
Copy link
Collaborator

pljones commented Feb 19, 2021

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
https://github.com/jamulussoftware/jamulus/actions/runs/582519157
(can't remember how long the PR autobuild artifacts live for - 30 days, I think)

@JohannesBrx
Copy link
Contributor Author

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 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.

@JohannesBrx
Copy link
Contributor Author

Oh, or here
https://github.com/jamulussoftware/jamulus/actions/runs/582519157
(can't remember how long the PR autobuild artifacts live for - 30 days, I think)

It should be available for 31 days according to the build log (retention-days: 31). It's a really great thing to automatically get preview versions for all operating systems.

@JohannesBrx
Copy link
Contributor Author

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.
image

@hoffie
Copy link
Member

hoffie commented Feb 20, 2021

@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.

@JohannesBrx
Copy link
Contributor Author

@JohannesBrx Thanks for your work! Your tesst 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.

@gene96817
Copy link

As I understand the past discussion, this auto-adjustment is manually triggered.
It is thought that the adjustment can be made during warm-up.

Q1: how long is the sampling period?

Q2: What kind of "warm up" is best for the auto-adjustment?
Should it be like the stereotypical orchestra all tuning up on A?
Should the chorus have every voice be singing a chord tuning sequence?
If an ensemble plays a section of their music, what happens if not every voice (line in the music) is equally active during the auto-adjustment period? This is a question on the impact of a pause (rest) in the music. What is the impact of the mean power between the voices are not equal?
What is the best sound sample from the ensemble for the auto-adjustment?

@JohannesBrx
Copy link
Contributor Author

Q1: how long is the sampling period?

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.

Q2: What kind of "warm up" is best for the auto-adjustment?
Should it be like the stereotypical orchestra all tuning up on A?
Should the chorus have every voice be singing a chord tuning sequence?
If an ensemble plays a section of their music, what happens if not every voice (line in the music) is equally active during the auto-adjustment period? This is a question on the impact of a pause (rest) in the music. What is the impact of the mean power between the voices are not equal?
What is the best sound sample from the ensemble for the auto-adjustment?

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.

@gene96817
Copy link

gene96817 commented Feb 20, 2021

Thanks for the suggestion for giving the auto-adjustment a sample.

I use an exponential moving average

You do have an implied start time from the beginning of the moving average window.

It sounds like the process would be:
(a) have a chorus tune up a chord at fortissimo
(b) repeat the tuning and adjust the sections for the balance desired
(c) repeat (b) and when the sound is stable, trigger the auto-adjustment and hold for 5 seconds (to ensure a stable 2-second sample).

@pgScorpio
Copy link
Contributor

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 ??
Wouldn't be a (auto) volume control on the client side be a much better (and simpler) solution ?
I think any kind of mic. volume control at the client side would already be a big improvement anyway.

And a simple 1.5 or 3dB Step volume control would be easy to implement with just a few shift and add instructions.

@hoffie
Copy link
Member

hoffie commented Feb 20, 2021

@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
Sounds a bit like #1030, maybe you want to comment there as well?

@JohannesBrx
Copy link
Contributor Author

JohannesBrx commented Feb 21, 2021

It sounds like the process would be:
(a) have a chorus tune up a chord at fortissimo
(b) repeat the tuning and adjust the sections for the balance desired
(c) repeat (b) and when the sound is stable, trigger the auto-adjustment and hold for 5 seconds (to ensure a stable 2-second sample).

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.)

@JohannesBrx
Copy link
Contributor Author

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 ??
Wouldn't be a (auto) volume control on the client side be a much better (and simpler) solution ?
I think any kind of mic. volume control at the client side would already be a big improvement anyway.

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.

@gene96817
Copy link

@JohannesBrx I was trying to be very careful. Note:

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.

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.

@pgScorpio
Copy link
Contributor

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 ??
Wouldn't be a (auto) volume control on the client side be a much better (and simpler) solution ?
I think any kind of mic. volume control at the client side would already be a big improvement anyway.

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.

"Doing it automatically would require that everyone sings approximately the same calibration tone"
I don't get this. what's wrong with just an auto mic level control you can turn on and off?
Turn auto mic level on, sing a few seconds, mic volume is automatically set. turn auto level off and the auto level level stays set but control switches to manual again...
Just like in many other applications like Zoom.

@gene96817
Copy link

"Doing it automatically would require that everyone sings approximately the same calibration tone"
I don't get this. what's wrong with just an auto mic level control you can turn on and off?
Turn auto mic level on, sing a few seconds, mic volume is automatically set. turn auto level off and the auto level level stays set but control switches to manual again...
Just like in many other applications like Zoom.

There are two scenarios.
In the Zoom case, a user just wants to have a convenient way to set their microphone setting.

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.

@JohannesBrx
Copy link
Contributor Author

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

@gene96817:
The sampling and averaging of audio samples is done all the time -- even when you do not activate the adjustment. (It is a cheap operation which does not decrease performance.) This is what I meant with continuously. The averaging is designed in such a way that approximately the previous 5 seconds influence the averaging value.

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.

image

@JohannesBrx
Copy link
Contributor Author

Using the mean level as the reference is good.
It could be a valid choice that any channel outside of one std dev needs to be resolved manually.

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.)

Would instructor = director?

From your discussion, I can see the implication that the person without a group assignment is the instructor. However, what if most attendees have group assignments and a "few" do not? In this case, for my choruses, these few could be visitors. We could choose to say (1) note, no assignment means no adjustments - good or bad, (2) no assignment = a default misc group, (3) no assignment = not a regular participant and treated as a listen-only visitor.

I would choose (1). Visitors, instructors, streaming clients etc. could have no group assignment to skip adjustments.

@ann0see
Copy link
Member

ann0see commented Mar 6, 2021

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.

@JohannesBrx JohannesBrx force-pushed the AutoAdjustChannelFaders branch from 66aa3fc to 6baa05f Compare March 6, 2021 17:05
@ann0see
Copy link
Member

ann0see commented Mar 17, 2021

Would this also be ready to be merged?

@JohannesBrx
Copy link
Contributor Author

Would this also be ready to be merged?

I think so. However, a second review is still missing.

@ann0see
Copy link
Member

ann0see commented Mar 17, 2021

Ok. I'll look into it tomorrow. BTW: thank you for all your input and PRs!

@JohannesBrx JohannesBrx force-pushed the AutoAdjustChannelFaders branch from 6baa05f to c071234 Compare March 18, 2021 18:27
Copy link
Member

@ann0see ann0see left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@ann0see ann0see requested a review from softins March 19, 2021 11:07
@softins
Copy link
Member

softins commented Mar 20, 2021

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.

Copy link
Member

@softins softins left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't studied the algorithm in detail, but the code looks good, and I have built and tested it on my Pi.

Copy link
Member

@hoffie hoffie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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. :)

@JohannesBrx
Copy link
Contributor Author

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?

I have added myself to the list. I am glad to be able to give something back in this great project.

@ann0see
Copy link
Member

ann0see commented Mar 20, 2021

I think you should also edit the changelog and give a shot description there? Afterwards this can be merged.

@hoffie hoffie merged commit 3ef6950 into jamulussoftware:master Mar 20, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature request: Automatic channel fader adjustments

7 participants