Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve algorithm to find in use channels in O(n) instead O(n²) #2738

Merged

Conversation

ann0see
Copy link
Member

@ann0see ann0see commented Jul 17, 2022

Short description of changes

This replaces the O(n²) approach to find channels in use with a simpler O(n) approach.

Probably there are other places which would benefit from a more efficient approach too.

CHANGELOG: Client: Improve performance of GUI when someone join or leave a server.

Context: Fixes an issue?

Related to: #2737 (comment)

Does this change need documentation? What needs to be documented and how?

No.

Status of this Pull Request

Close performance evaluation and (in depth) testing:

  • Does the ordering get messed up? (it seems ok for me for a small number of clients)
  • Are the faders hidden correctly at all times (didn't test in real world scenario yet)

What is missing until this pull request can be merged?

Testing

Checklist

  • I've verified that this Pull Request follows the general code principles
  • I tested my code and it does what I want (at least I don't see any bad changes on joins/leaves. It must however be tested)
  • My code follows the style guide
  • I waited some time after this Pull Request was opened and all GitHub checks completed without errors.
  • I've filled all the content above

@ann0see ann0see requested review from pljones and hoffie July 17, 2022 18:56
src/audiomixerboard.cpp Show resolved Hide resolved
{
// if current fader is not used, hide it
Copy link
Member Author

Choose a reason for hiding this comment

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

Seems a bit redundant here

@ann0see ann0see added this to Triage in Tracking (old) via automation Jul 17, 2022
@ann0see
Copy link
Member Author

ann0see commented Jul 17, 2022

Own channel first doesn't seem to work correctly at the moment: If we set the own channel checkbox, nothing happens at first. You need to set a ordering first.

It's not reproducible; At least it only appeared on the first launch of the app. Also setting ini files doesn't seem to get the issue back.

src/audiomixerboard.cpp Outdated Show resolved Hide resolved
@pljones
Copy link
Collaborator

pljones commented Jul 18, 2022

Note that a lot of the code in audiomixerboard.cpp (GUI only) needs moving into a non-GUI class, so that state is not being maintained in the GUI. Any large scale restructuring should take that into account as one of its (main) goals.

@ann0see ann0see force-pushed the refactor/ImproveAudioMixBoard branch from 524ff43 to 2e078e4 Compare July 18, 2022 17:30
@pljones
Copy link
Collaborator

pljones commented Jul 18, 2022

Own channel first doesn't seem to work correctly at the moment: If we set the own channel checkbox, nothing happens at first. You need to set a ordering first.

It's not reproducible; At least it only appeared on the first launch of the app. Also setting ini files doesn't seem to get the issue back.

Doesn't surprise me. A lot of the code is impentrable. Hence I'd rather a full refactor than trying to "fix in place".

@ann0see
Copy link
Member Author

ann0see commented Jul 18, 2022

This PR is mainly about implementing the algorithm we used for the gain reset here in the GUI too; not that much about a separation into a second class. I still think it's worth merging this one? However, what exactly do you want to get extracted into another class?

@ann0see
Copy link
Member Author

ann0see commented Jul 18, 2022

Ok. I can confirm that own fader first is broken by this change. This needs more investigation.

// check if this is my own fader and set fader property
if ( i == iMyChannelID )
{
vecpChanFader[i]->SetIsMyOwnFader();
Copy link
Member Author

Choose a reason for hiding this comment

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

I don't quite get why the new approach breaks the own fader first logic.

Copy link
Member

Choose a reason for hiding this comment

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

I don't see it either. The refactoring looks correct to me.

Are you sure that this PR broke it? I've just tested with 3.8.2 and it seems to be broken there as well, unless I'm testing the wrong thing? :o

Copy link
Member Author

Choose a reason for hiding this comment

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

I haven't tested anything before that, but I don't remember that own fader first didn't work.

Copy link
Member

Choose a reason for hiding this comment

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

3.8.2 was the first release which contained it. #1809 was the PR. I'm currently looking into it and will open a separate issue if necessary.

Copy link
Member

Choose a reason for hiding this comment

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

I thought I had reproduced the own-fader-first-breakage with this PR and then with a clean 3.8.2 build. Now I can no longer reproduce it either way. Everything works fine and I'm not sure what I'm doing differently now.

@ann0see Can you share how you made it break?

Copy link
Member Author

Choose a reason for hiding this comment

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

I think it's related to a fresh start without sorting and then enabling own fader first.

Not sure, but the following could lead to the issue (untested):

  1. Connect to a crowded server without sorting
  2. Wait until someone joins
  3. Set own fader first
  4. Observe you aren't first

@hoffie
Copy link
Member

hoffie commented Jul 18, 2022

Note that a lot of the code in audiomixerboard.cpp (GUI only) needs moving into a non-GUI class, so that state is not being maintained in the GUI. Any large scale restructuring should take that into account as one of its (main) goals.

Yep. In the mean time, we should merge any iterative improvements such as this PR (once proven correct... ;)) neverthless, in my opinion.

src/audiomixerboard.cpp Outdated Show resolved Hide resolved
src/audiomixerboard.cpp Outdated Show resolved Hide resolved
@ann0see ann0see force-pushed the refactor/ImproveAudioMixBoard branch 3 times, most recently from 728b2c0 to 0eeae20 Compare July 22, 2022 18:14
@ann0see
Copy link
Member Author

ann0see commented Jul 22, 2022

Now I seem to miss a new join (fader doesn't show up) with the same (empty) name. This clearly needs more testing
Actually also 3.8.2dev-fa204ad4 doesn't show the fader, so it seems to be unrelated to my change...

@ann0see ann0see force-pushed the refactor/ImproveAudioMixBoard branch 2 times, most recently from 6d94d5b to 562acb5 Compare July 22, 2022 18:22
@pljones
Copy link
Collaborator

pljones commented Jul 22, 2022

Now I seem to miss a new join (fader doesn't show up) with the same (empty) name. This clearly needs more testing Actually also 3.8.2dev-fa204ad4 doesn't show the fader, so it seems to be unrelated to my change...

* |   48168a67 2022-07-18 Merge pull request #2737 from hoffie/fix-lost-gain-changes [Christian Hoffmann]

Could it be related to that?

@ann0see
Copy link
Member Author

ann0see commented Jul 23, 2022

Probably they're not related to the change in my PR at all (but still need to be investigated.) Can you reproduce any of them on Linux?
(Connect to a server with totally empty client information), wait, join with another client without client information and observe both mixer boards.

@ann0see
Copy link
Member Author

ann0see commented Jul 23, 2022

Line 1200: why is this not in the mutex? Can we guarantee the number of clients doesn't change before we acquire the lock?

@pljones
Copy link
Collaborator

pljones commented Jul 24, 2022

Actually, reading your "how to reproduce", I don't think own fader first has ever worked. I generally don't use sort and I turned off the own fader first feature once I realised it didn't work.

@ann0see
Copy link
Member Author

ann0see commented Jul 24, 2022

Actually I can’t reproduce it anymore. That’s the issue. Sometimes it works, sometimes it doesn’t. Maybe it’s worth looking at the initial PR again.

@pljones
Copy link
Collaborator

pljones commented Jul 24, 2022

Actually I can’t reproduce it anymore. That’s the issue. Sometimes it works, sometimes it doesn’t. Maybe it’s worth looking at the initial PR again.

Yes, that's the same behaviour I've always had - I see it, then when I try to get a reliable way to reproduce it, I can't.

@ann0see
Copy link
Member Author

ann0see commented Jul 24, 2022

I just re-checked, at least one of both bugs also shows up on the current 3.8.2 release, so it's unrelated.

@ann0see ann0see marked this pull request as ready for review July 27, 2022 19:15
@ann0see ann0see moved this from Triage to Waiting on Team in Tracking (old) Jul 27, 2022
@ann0see
Copy link
Member Author

ann0see commented Jul 30, 2022

@pljones @hoffie I think this PR is ok, the bugs are not related to it.

{
if ( iFaderNumber[iChanID] == INVALID_INDEX )
{
// fader is not used --> hide it
Copy link
Collaborator

@pljones pljones Jul 30, 2022

Choose a reason for hiding this comment

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

1232/1233 could be rewritten to flow better. "Hide it." "Oh wait!! Before that, just one thing - store the levels. Oh!! Only of certain conditions are met."

So first we store the levels (I don't think the "if some..." is needed - that's the concern of the called method - though maybe the method name needs improving at some point), then we hide the fader. The comment should reflect that.

However..! I don't even think the comment is adding to the code here. "Store...; ...Hide()" is fairly self-explanatory (as the vector name is good).

A simple // fader is not used to describe the case would do.

}

// current fader is used
// check if fader was already in use -> preserve gain value
Copy link
Collaborator

@pljones pljones Jul 30, 2022

Choose a reason for hiding this comment

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

This comment (line 1241) should move inside the if. Then the "check if" can be removed (and a "not" added). That makes it more or less a duplicate of line 1244. I'd put the "reset everything" part of 1244 on its own line, though.

Also ... "-> preserve gain value" appears to refer to the code at line 1277 - so really shouldn't be here.

vecpChanFader[iChanID]->Reset();
vecAvgLevels[iChanID] = 0.0f;

// check if this is my own fader and set fader property
Copy link
Collaborator

Choose a reason for hiding this comment

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

Don't say "check if" on an if statement. That's what an if statement is. Inside the if -- if the test doesn't make it clear -- explain the state. Here, a comment of "// this is my own fader" would be present. However, it's pretty redundant.

vecpChanFader[iChanID]->SetIsMyOwnFader();
}

// set and increment the running new client counter needed for sorting (per definition:
Copy link
Collaborator

Choose a reason for hiding this comment

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

This comment doesn't really help...

Something as brief as

// keep track of each new client (for "no sorting" channel sort order, new clients are added to the right-hand side of the mixer)

might do.

}
}

// if current fader is not used, hide it
if ( !bFaderIsUsed )
// restore gain (if new name is different from the current one)
Copy link
Collaborator

Choose a reason for hiding this comment

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

This, again, is a duplicate comment -- the comment should be inside the if describing the state there. There's already a comment which does that in the right place.

@pljones
Copy link
Collaborator

pljones commented Jul 30, 2022

Sorry, just went through in "picky" mode. As there are a lot of changes happening, it might be nice to make the comments clear at the same time.

@ann0see ann0see force-pushed the refactor/ImproveAudioMixBoard branch 2 times, most recently from 00bd916 to e2f4344 Compare July 31, 2022 13:32
@ann0see
Copy link
Member Author

ann0see commented Jul 31, 2022

Sorry, just went through in "picky" mode. As there are a lot of changes happening, it might be nice to make the comments clear at the same time.

No problem. I just added another commit.

@ann0see ann0see force-pushed the refactor/ImproveAudioMixBoard branch from e2f4344 to 997a387 Compare July 31, 2022 14:42
@ann0see ann0see requested a review from pljones July 31, 2022 14:43
@ann0see ann0see added this to the Release 3.9.1 milestone Jul 31, 2022
@@ -1210,92 +1210,97 @@ void CAudioMixerBoard::ApplyNewConClientList ( CVector<CChannelInfo>& vecChanInf

// search for channels with are already present and preserve their gain
Copy link
Collaborator

Choose a reason for hiding this comment

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

^with^which

@pljones
Copy link
Collaborator

pljones commented Jul 31, 2022

Approved but if you want to fix the existing typo, please do.

@ann0see ann0see force-pushed the refactor/ImproveAudioMixBoard branch from 997a387 to 824cfed Compare July 31, 2022 17:11
ann0see and others added 2 commits August 5, 2022 19:55
This replaces the O(n²) approach to find channels in use with a simpler 
O(n) approach.
Co-Authored-By: Peter L Jones <pljones@users.noreply.github.com>
@ann0see ann0see force-pushed the refactor/ImproveAudioMixBoard branch from 824cfed to 603cea1 Compare August 5, 2022 17:55
Tracking (old) automation moved this from Waiting on Team to In Progress Aug 7, 2022
@ann0see ann0see merged commit 707634e into jamulussoftware:master Aug 7, 2022
Tracking (old) automation moved this from In Progress to Done Aug 7, 2022
@ann0see ann0see deleted the refactor/ImproveAudioMixBoard branch August 7, 2022 20:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
No open projects
Development

Successfully merging this pull request may close these issues.

None yet

3 participants