Skip to content

Comments

Client: Add support for input gain control#1222

Merged
hoffie merged 1 commit intojamulussoftware:masterfrom
hoffie:autobuild/add-clientgain-ui-1030
Mar 31, 2021
Merged

Client: Add support for input gain control#1222
hoffie merged 1 commit intojamulussoftware:masterfrom
hoffie:autobuild/add-clientgain-ui-1030

Conversation

@hoffie
Copy link
Member

@hoffie hoffie commented Mar 10, 2021

This adds a new client-only UI setting to apply a gain value on all audio input.

This solves the problem that some (internal?) microphones cannot be made to output louder signals using operating system mechanisms (Windows sound settings). Multiple people in my choir use builds with this code included.

This approach solves the problem as close to the source and as simple as possible. I would have preferred to permit extending the fader range in the mixer board, but this would have been a way more intrusive change (introduction of new protocol messages, etc.).

Related to: #1030

@hoffie hoffie added the feature request Feature request label Mar 10, 2021
@hoffie hoffie added this to the Release 3.7.1 milestone Mar 10, 2021
@ann0see
Copy link
Member

ann0see commented Mar 10, 2021

Ok. Just tested the artifact.

An immediate thought I had after installing it: why isn't it a slider? But probably that's ok if it's a one time setting.

@hoffie
Copy link
Member Author

hoffie commented Mar 10, 2021

An immediate thought I had after installing it: why isn't it a slider? But probably that's ok if it's a one time setting.

That's a deliberate choice. This is supposed to be a one-time setting. Changing this repeatedly or on-the-fly would be really annoying for other participants who would have to constantly update the person's level in their mix.

@ghost
Copy link

ghost commented Mar 11, 2021

Internal computer microphones will pick up extraneous noises and are basically junk. Jamulus cannot make up for hardware shortcomings. Get a better microphone ... I did!
Moreover, amplifying a digital signal requires that a stream of data has to be tapped into and every sample must have a multiply operation done ... This decreases the resolution of the data which increases quantization noise (as if that matters, but that's what you get for your trouble). Now everybody who doesn't have a crappy microphone has to put up with more bloat and less preformance for the sake of someone who insists on using an internal microphone which can only be improved marginally by adding gain and noise gates (throwing good money after bad). I'm also blown away that 7 files need to be touched for this change.
Code added to Jamulus for bad microphones should be added to a special build.
Maybe there should be a beginners version of Jamulus.

@gene96817
Copy link

Also, a cheap gamer headset with a mic is much better than the internal microphone (that picks up the fan noise).

@hoffie
Copy link
Member Author

hoffie commented Mar 11, 2021

Thanks for your comments, @DavidSavinkoff!

Internal computer microphones will pick up extraneous noises and are basically junk.

I agree.

Jamulus cannot make up for hardware shortcomings.

It can improve things in some cases, at least.

Get a better microphone ... I did!

I did. Not everyone can or wants to affort that.

Moreover, amplifying a digital signal requires that a stream of data has to be tapped into and every sample must have a multiply operation done ... This decreases the resolution of the data which increases quantization noise (as if that matters, but that's what you get for your trouble). Now everybody who doesn't have a crappy microphone has to put up with more bloat and less preformance

Yes, the relevant change is in the audio processing path. I would not call a multiply operation bloat or a relevant performance degration unless proven. Might make sense to run a benchmark though.

for the sake of someone who insists on using an internal microphone which can only be improved marginally by adding gain

I don't agree here. Adding gain decides about being able to use Jamulus or not in such cases.

. I'm also blown away that 7 files need to be touched for this change.

This is due to the organization of UI code. Adding anything with a UI setting is going to touch these files.

Code added to Jamulus for bad microphones should be added to a special build.

If it is decided not to accept this PR for main stream Jamulus, then this will continue to be my workaround: Distributing a special build to the users who need it. I'm doing this already. I have opened this PR because the code has been developed, has proven to work and has helped making Jamulus usable for those persons.

A previous version of your comment suggested guarding such new code by ifdefs. This wouldn't help as the users affected by such problems would certainly not build their own Jamulus versions.

Maybe there should be a beginners version of Jamulus.

I see you have already opened a discussion for that, thanks!
#1227

Please also note that this is still a Pull Request, so it is not decided yet whether to have this in Jamulus or not.

@pljones
Copy link
Collaborator

pljones commented Mar 11, 2021

This has been discussed before and my stance hasn't changed: input audio processing happens outside Jamulus.

@ann0see
Copy link
Member

ann0see commented Mar 11, 2021

Although in general I agree that audio processing should take place on OS level if possible, we also need to keep usability in mind. This feature seems simple and I do see value with it.

@gene96817
Copy link

For uses having trouble with their internal microphone, do we consider a set of earbuds with a microphone from their smartphone a good step? It does seem everyone has a smartphone and, by extension, earbuds and microphone too. This could be a quick (temporary) fix for the internal microphone noise.

@npostavs
Copy link
Contributor

npostavs commented Mar 11, 2021

I notice that I need to click outside of the text field in order for the newly entered setting to take effect. I think it would be useful to mention this in the help text. Alternatively, maybe there's a different signal than QLineEdit::editingFinished that would work better?

a microphone from their smartphone a good step?

I'd be surprised if this gave reasonable latency. Has anyone tried it?

@gene96817
Copy link

a microphone from their smartphone a good step?
I'd be surprised if this gave reasonable latency. Has anyone tried it?

I wasn't clear. Many people have a wired set of earbuds with microphone for their smartphone. We can hate the reposnse curve of that microphone. Seems to me that would be better than the builtin notebook microphone. That won't introduce any latency issues; its wired.

@npostavs
Copy link
Contributor

I wasn't clear. Many people have a wired set of earbuds with microphone for their smartphone.

Oh I see. It's not common in my experience so I didn't think of that. I don't know whether it would generally produce better results, but if someone has access to multiple microphones they may as well try them all to see which one sounds best.

Internal computer microphones will pick up extraneous noises and are basically junk. Jamulus cannot make up for hardware shortcomings.

This is sometimes true, but other times not. I play with 3 other people using internal sound cards and builtin/not great microphones. For 2 of them, there is quite a bit of background noise coming from their microphones, and this feature would not help them. But the 3rd person's built-in microphone actually sounds perfectly fine, it's just kind of quiet (I could hear them almost okay with both the Jamulus slider and audio interface volume set to max, but the others had trouble). I got them to test out this build yesterday, and it worked quite well. Thanks for posting it @hoffie!

This has been discussed before and my stance hasn't changed: input audio processing happens outside Jamulus.

As far as I can tell, when using ASIO4ALL, there is no way to adjust microphone gain. The standard OS audio settings don't affect the sound level. So while this position seems logical, I don't think it corresponds to the reality.

@hoffie hoffie force-pushed the autobuild/add-clientgain-ui-1030 branch from 22a4081 to 39cafd8 Compare March 17, 2021 14:27
@hoffie
Copy link
Member Author

hoffie commented Mar 17, 2021

Thanks for the feedback so far. Although I'm not sure if this has a chance of being accepted, people do use it and I have therefore fixed two bugs in 39cafd8:

  • As @npostavs pointed out, a gain change was not applied immediately. I have changed this by using a textChanged event instead (and ensuring the number is valid).
  • The actual input gain was not restored properly upon Jamulus restart (but confusingly, the settings field was). This is now fixed as well.

@hoffie hoffie force-pushed the autobuild/add-clientgain-ui-1030 branch from 39cafd8 to ca8d93c Compare March 18, 2021 19:43
@hoffie hoffie removed this from the Release 3.7.1 milestone Mar 18, 2021
@gilgongo
Copy link
Member

My two cents is that while I agree with @pljones, I think this issue has become a "will of the people" thing. If we oppose it, we will forever more be explaining why. So I'm OK not spending the energy on that, and instead accepting what is in reality a pretty minor UI change.

@hoffie hoffie force-pushed the autobuild/add-clientgain-ui-1030 branch from ca8d93c to e847ecd Compare March 27, 2021 15:05
@hoffie hoffie requested a review from softins March 27, 2021 22:38
@softins
Copy link
Member

softins commented Mar 28, 2021

Just fetched this to build it and try it, and noticed it said it was building "3.7.0 (release)".

It looks like this was branched from 03bc4c1 (tag r3_7_0). We ought never to branch from a tagged release. In this case the branch point should be the 3.7.0dev commit immediately afterwards fabe41c or later.

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.

The code as it is looks fine, and does what it was intended to, but I have some comments and suggestions:

  1. I noticed that changing the value did not affect the input level meter. It would probably help the user determine the optimum setting if the input level meter was driven from the scaled input.
  2. I imagine the user does not need a very fine resolution in the setting, and I wonder if it would be better to have a drop-down offering multiples of 100% (or multiples of 2dB?)
  3. For people who have a microphone in one channel and an instrument in the other, might they want to set the input gain independently for each channel?

@softins
Copy link
Member

softins commented Mar 28, 2021

In fact, since 100% is the lowest accepted value, maybe it should be called Input Boost, rather than Input Gain? That might make its purpose clearer?

@hoffie
Copy link
Member Author

hoffie commented Mar 29, 2021

We ought never to branch from a tagged release. In this case the branch point should be the 3.7.0dev commit immediately afterwards fabe41c or later.

Uhm, you are right. This shouldn't have happened. I've rebased on master now. Sorry for that.

Thanks for your other suggestions, I'll look at them later.

@hoffie hoffie force-pushed the autobuild/add-clientgain-ui-1030 branch 2 times, most recently from 79ecd44 to d0faac3 Compare March 29, 2021 21:49
@hoffie
Copy link
Member Author

hoffie commented Mar 29, 2021

  1. I noticed that changing the value did not affect the input level meter. It would probably help the user determine the optimum setting if the input level meter was driven from the scaled input.

This sounds like a good idea. I have adapted the code by moving the gain application right before the input level meter update.

  1. I imagine the user does not need a very fine resolution in the setting, and I wonder if it would be better to have a drop-down offering multiples of 100% (or multiples of 2dB?)
  • Yes, makes sense. Will do that tomorrow.
  1. For people who have a microphone in one channel and an instrument in the other, might they want to set the input gain independently for each channel?

Hrm, good point. This would require more UI space and more logic though. I wonder if we should just wait if someone comes and requests this feature? It might not be that common to have a bad, low-gain microphone in addition to having an instrument attached (probably via some interface)? I'd tend to not add it now to keep it as simple as possible.

In fact, since 100% is the lowest accepted value, maybe it should be called Input Boost, rather than Input Gain? That might make its purpose clearer?

Good idea, I have renamed all variables, functions, comments and labels accordingly.

Copy link

@ghost ghost left a comment

Choose a reason for hiding this comment

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

In:
src/client.cpp
The following code is inefficient:
if ( iInputBoost != 100 ) {
// apply a general gain boost to all audio input:
for ( i = 0, j = 0; i < iMonoBlockSizeSam; i++, j += 2 )
{
vecsStereoSndCrd[j + 1] = static_cast<int16_t> ( iInputBoost * vecsStereoSndCrd[j + 1] / 100);
vecsStereoSndCrd[j] = static_cast<int16_t> ( iInputBoost * vecsStereoSndCrd[j] / 100);
}
Fix before for loop:
Boost=iInputBoost*0.01;

Then use Boost instead of iInputBoost, and get rid of the /100

@hoffie hoffie force-pushed the autobuild/add-clientgain-ui-1030 branch from d0faac3 to 56a28b2 Compare March 30, 2021 22:37
@hoffie
Copy link
Member Author

hoffie commented Mar 30, 2021

I imagine the user does not need a very fine resolution in the setting, and I wonder if it would be better to have a drop-down offering multiples of 100% (or multiples of 2dB?)

I have turned this into a combo box with factors ranging from "None" for no boost to 10x. What do you think?

The following code is inefficient:

Thanks for the pointer. I have incorporated this into the latest state of this PR. Due to the change from percentages to factors, the division by 100 is eliminated completely.

@hoffie hoffie requested a review from softins March 30, 2021 22:40
Copy link

@ghost ghost left a comment

Choose a reason for hiding this comment

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

Audio processing code in src/client.cpp is efficient and minimally invasive.Good.

@gene96817
Copy link

(or multiples of 2dB?)

The smallest useful increment is 3dB. However, most people cannot hear that difference. If a coarse adjustment is enough then 10dB is a common increment.

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.

There are a couple of unneeded .qm file updates here too, but it doesn't matter, as they will be updated when rebuilding anyway.
Code looks good, and the feature operates as intended.

@hoffie hoffie added this to the Release 3.7.1 milestone Mar 31, 2021
@hoffie hoffie force-pushed the autobuild/add-clientgain-ui-1030 branch 2 times, most recently from e278811 to f501e85 Compare March 31, 2021 13:59
This adds a new client-only UI setting to apply a gain boost
on all audio input.

Related to: jamulussoftware#1030

Signed-off-by: Christian Hoffmann <[email protected]>
@hoffie hoffie force-pushed the autobuild/add-clientgain-ui-1030 branch from f501e85 to c5db1b2 Compare March 31, 2021 15:01
@ann0see
Copy link
Member

ann0see commented Mar 31, 2021

Just a small question (didn't test the new code here): Why don't we support lowering the input gain too?

@hoffie
Copy link
Member Author

hoffie commented Mar 31, 2021

Just a small question (didn't test the new code here): Why don't we support lowering the input gain too?

I don't see a use case for this. Reasoning:

  • If a client is loud, but not clipping, then this is optimal because it uses the full range to express details of the audio. Other clients can simply turn the fader down in their mix.
  • If a client is too loud and is clipping, reducing gain will not help. While this technically removes clipping, it does not remove the distortion introduced by it ("Garbage in, garbage out"). Even worse, it will probably prevent Jamulus' clipping indicator from working at all.

I also tried explaining this in the What's this text.

Let me know if you think otherwise. :)

@ann0see
Copy link
Member

ann0see commented Mar 31, 2021

If a client is too loud and is clipping, reducing gain will not help. While this technically removes clipping, it does not remove the distortion introduced by it ("Garbage in, garbage out"). Even worse, it will probably prevent Jamulus' clipping indicator from working at all.

I usually have problems with people clipping not being to quiet. Therefore I tell them to reduce their input gain on OS level (if they don't have an interface). The question for me is where clipping occurs: If it happens before it comes into Jamulus, sure it wouldn't help. If it occurs in Jamulus, adding this feature does help. At least that's my understanding.

@hoffie
Copy link
Member Author

hoffie commented Mar 31, 2021

I usually have problems with people clipping not being to quiet. Therefore I tell them to reduce their input gain on OS level (if they don't have an interface).

Yes, and this is the right thing to do. Clipping may occur due to Windows' microphone gain/boost. If it happens there, this is the place to fix (and Jamulus would not be able to fix it).

The question for me is where clipping occurs: If it happens before it comes into Jamulus, sure it wouldn't help.

Yep.

If it occurs in Jamulus, adding this feature does help. At least that's my understanding.

I don't think Jamulus does have any features which could cause clipping on the input (maybe the reverb could, but only if the input signal is really close to clipping to begin with). Mixing could clip (I think), but this is usually more of a problem if choosing a mix which is too loud, I think?
I also suppose this would seldomly happen with ensembles with very different instruments and small numbers of participants. The likeliness of it would increase though as the number of participants increase and if multiple participants contribute very similar audio (i.e.: a choir ;)). But I think this should rather be solved at the mixing level (which is realdy possible).

@hoffie
Copy link
Member Author

hoffie commented Mar 31, 2021

As discussed with @ann0see via chat, we can merge this as-is for now and look if permitting lowering of input gain should be implemented.

@hoffie hoffie merged commit e5bc010 into jamulussoftware:master Mar 31, 2021
@DetlefHennings
Copy link

DetlefHennings commented Apr 1, 2021

In a build of the currrent 3.7.1 state I noticed the implementation of the microphone boost. Certainly this is a very useful feature whenever the hardware microphone gain is insufficient. But the current implementation using equispaced numeric gain factors may not be adequate to human loudness perception. To match better with human perception gain factors should be spaced by equal factors, or even better, replaced by equispaced dB steps. These steps could either be
0dB, +5dB, +10dB, +15dB, +20dB or, at a higher resolution,
0dB, +2.5dB, +5dB, +7.5dB, +10dB, +12.5dB , +15dB, +17.5dB, +20dB
The suggested steps result in an unchanged boost range, as 0dB and +20dB correspond to factors of 1 and 10 respectively.

@softins
Copy link
Member

softins commented Apr 1, 2021

For a setting that will be adjusted frequently in use, I would agree with you. But when I reviewed and tested this PR, with a low-level input, I did find a noticeable change with each boost factor. This feature is designed for set-and-forget use, and typically the user will just choose the setting appropriate to their input device and leave it there.

@ghost
Copy link

ghost commented Apr 1, 2021

There are already too many Gain levels... +6dB=2 +12dB=4 +20dB=10 are abundantly generous.
Attenuation is accomplished by right shifting a signed integer: -6dB=1/2 -12dB=1/4 -18dB=1/8
This hack (feature) will be abused and create more problems than it solves. Get a proper setup.

@softins softins mentioned this pull request Apr 1, 2021
@hoffie hoffie deleted the autobuild/add-clientgain-ui-1030 branch March 19, 2022 20:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature request Feature request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants