-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
FEAT(client, server): Implement loopback while still sending to others #6445
base: master
Are you sure you want to change the base?
FEAT(client, server): Implement loopback while still sending to others #6445
Conversation
…the data The function that already existed took the index instead of the data, making it susceptible to errors because the data could be passed instead of the index. Also, with this new iteration of loadComboBox() we can reorder the items shown to the user as desired.
2e47e0f
to
1730f39
Compare
1730f39
to
d4dd9c2
Compare
@@ -992,7 +992,8 @@ void AudioInput::encodeAudioFrame(AudioChunk chunk) { | |||
|
|||
ClientUser *p = ClientUser::get(Global::get().uiSession); | |||
bool bTalkingWhenMuted = false; | |||
if (Global::get().s.bMute || ((Global::get().s.lmLoopMode != Settings::Local) && p && (p->bMute || p->bSuppress)) | |||
if (Global::get().s.bMute | |||
|| ((Global::get().s.lmLoopMode != Settings::LocalOnly) && p && (p->bMute || p->bSuppress)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I find this if
now even harder to comprehend. Let's maybe create some bool
s before the if
and compare that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed.
break; | ||
case Settings::LocalRegular: | ||
LoopUser::lpLoopy.addFrame(audioData); | ||
[[fallthrough]]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[[fallthrough]]
is apparently a C++17 thing and therefore the Windows and OSX CI build fails (?)
} | ||
} else if (u->qmTargets.contains(static_cast< int >(audioData.targetOrContext))) { // Whisper/Shout |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens when clients implementing this feature are connected to old servers? When they are using "server (send to others)" their packets will be dropped entirely, correct? Or will they be whisper/shout to some channel or user?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They are requesting the audio to be sent to a non-registered whisper-target, which should lead to the packet just being dropped.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new loopback mode should probably only be used/offered to the user whilst connected to a server that actually supports this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking about only showing the option in the combobox when available (i.e. the server supports it), but the idea implies that:
- It would not appear when not connected to a server.
- It would be confusing as the user may think their client version doesn't provide the feature.
I think we should show a warning in the log box explaining that the selected loopback method is not supported due to the server not implementing it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think hiding the option if the server doesn't support it makes sense. Only issue would be that it'd be confusing for users who configure loopback while disconnected and once they connect their chosen option is gone.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure hiding would be a good UX. Either change the text of the combobox entries to add (unsupported by server)
or use the log
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The log will be overlooked in like 90% of cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, but hiding will create us a dozen bug reports xD
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
True :)
We could make use of the mute-cue in cases where the user has selected loopback+broadcast but the server doesn't support it - because as far as other clients are concerned, you are muted (more or less). So maybe mute-cue + indicating in the settings window that the server doesn't support the selected loopback+broadcast would be an idea?
constexpr unsigned int REGULAR_SPEECH = 0; | ||
constexpr unsigned int SERVER_LOOPBACK = 31; | ||
constexpr unsigned int REGULAR_SPEECH = 0; | ||
constexpr unsigned int SERVER_LOOPBACK_REGULAR = 30; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the naming "regular" is not very helpful in this case. Maybe SERVER_LOOPBACK_ADDITIONAL
or something in that direction makes things a bit more expressive? 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SERVER_LOOPBACK_BROADCAST
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SERVER_LOOPBACK_AND_BROADCAST
<- that would nicely describe what's going on
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually thought about using "broadcast", but ended up with "regular" because shorter. I agree that the former would be clearer.
qcbLoopback->addItem(tr("Local (don't send to others)"), Settings::LocalOnly); | ||
qcbLoopback->addItem(tr("Local (send to others)"), Settings::LocalRegular); | ||
qcbLoopback->addItem(tr("Server (don't send to others)"), Settings::ServerOnly); | ||
qcbLoopback->addItem(tr("Server (send to others)"), Settings::ServerRegular); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
qcbLoopback->addItem(tr("Local (don't send to others)"), Settings::LocalOnly); | |
qcbLoopback->addItem(tr("Local (send to others)"), Settings::LocalRegular); | |
qcbLoopback->addItem(tr("Server (don't send to others)"), Settings::ServerOnly); | |
qcbLoopback->addItem(tr("Server (send to others)"), Settings::ServerRegular); | |
qcbLoopback->addItem(tr("Local only"), Settings::LocalOnly); | |
qcbLoopback->addItem(tr("Local + Broadcast"), Settings::LocalRegular); | |
qcbLoopback->addItem(tr("Server only"), Settings::ServerOnly); | |
qcbLoopback->addItem(tr("Server + Broadcast"), Settings::ServerRegular); |
I feel like my suggestion can still be improved upon 🤔
Either way, I think we need tooltips for all of these that explain in more detail what is meant by that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, absolutely.
default: | ||
break; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should not include default
cases when switching over enums as that will prevent compiler warnings once new enum values are added.
case Settings::LocalRegular: | ||
LoopUser::lpLoopy.addFrame(audioData); | ||
[[fallthrough]]; | ||
default: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above
if (c->currentIndex() != index) { | ||
c->setCurrentIndex(index); | ||
} else { | ||
connect(this, SIGNAL(intSignal(int)), c, SIGNAL(currentIndexChanged(int))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Old signal/slot syntax should no longer be used - prefer the version with explicit function pointers where the compiler can actually do type-checking for us.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I only did this for consistency with the rest of the file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think consistency is important for this 🤷
@@ -188,7 +188,7 @@ struct OverlaySettings { | |||
struct Settings { | |||
enum AudioTransmit { Continuous, VAD, PushToTalk }; | |||
enum VADSource { Amplitude, SignalToNoise }; | |||
enum LoopMode { None, Local, Server }; | |||
enum LoopMode { None, LocalOnly, ServerOnly, LocalRegular, ServerRegular }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As before, I don't think "regular" is descriptive - should be adapted in unison with the special whisper target.
break; | ||
case Mumble::Protocol::ReservedTargetIDs::SERVER_LOOPBACK_REGULAR: | ||
buffer.forceAddReceiver(*u, Mumble::Protocol::AudioContext::NORMAL, audioData.containsPositionalData); | ||
[[fallthrough]]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another C++17 usage
cachedListeners = cache.listeningTargets; | ||
} else { | ||
ZoneScopedN(TracyConstants::AUDIO_WHISPER_CACHE_CREATE); | ||
default: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No default-cases in enum switches
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just realized another important thing: We will have to take echo cancellation into account. Because we might effectively cancel the user speech entirely, if not careful.
BTW, you are effectively implementing #3408 |
I would assume this isn't an issue as the loopback variants already exist and work - the only changes of this PR are not visible to the local client. |
Correct. |
No description provided.