-
Notifications
You must be signed in to change notification settings - Fork 25
Add Noise Suppression (#1264) #1287
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
base: main
Are you sure you want to change the base?
Conversation
d70fb99
to
dde9297
Compare
lib/domain/model/ongoing_call.dart
Outdated
await track.getTrack().setNoiseSuppressionEnabled( | ||
_noiseSuppressionEnabled!, | ||
); |
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.
@ChabanovX, I've noticed that CI fails to build Web platform due to NoiseSuppressionLevel
enum not being available there. And that seems to be true, if we talk about NoiseSuppressionLevel
from the medea_flutter_webrtc
. I've discussed this matter with guys from medea_flutter_webrtc
and they told me that we shouldn't use this enum from that package - instead the NoiseSuppressionLevel
from medea_jason
should be used. Can you please try that?
And in that case the proper method to change the noise suppression settings would be to call this method over track
directly:
await track.getTrack().setNoiseSuppressionEnabled( | |
_noiseSuppressionEnabled!, | |
); | |
await track.setNoiseSuppressionEnabled( | |
_noiseSuppressionEnabled!, | |
); |
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.
Okay, got it!
1610adf
to
05968e1
Compare
dc4ec3a
to
5a0c024
Compare
assets/l10n/en-US.ftl
Outdated
label_media_settings = Media settings | ||
label_voice_processing = Voice processing | ||
label_noise_suppression = Noise suppression | ||
label_low = Low | ||
label_medium = Moderate | ||
label_high = High | ||
label_very_high = Very high | ||
label_message = Message |
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.
Can you please sort these l10n keys alphabetically? You may install a sort extension to your IDE so that it can be easier.
lib/domain/model/ongoing_call.dart
Outdated
import 'package:medea_flutter_webrtc/medea_flutter_webrtc.dart' as webrtc; | ||
import 'package:medea_flutter_webrtc/medea_flutter_webrtc.dart' | ||
as webrtc | ||
hide NoiseSuppressionLevel; |
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.
If this import is prefixed with webrtc
, then Dart shouldn't confuse webrtc.NoiseSuppressionLevel
from medea_flutter_webrtc
with NoiseSuppressionLevel
from medea_jason
, since the first one requires a prefix to be specified. Thus this hide NoiseSuppressionLevel
may be removed? Or not?
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, it might be removed, but if we leave it as it is, then other developers might be hinted, that webrtc version of NoiseSuppressionLevel should be avoided. Might not be important though. Should I remove 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.
@ChabanovX, this approach seems to be true for every enum present both in medea_jason
and medea_flutter_webrtc
. Not sure that we will be able to address all of those in such way with hide
.
lib/domain/model/ongoing_call.dart
Outdated
@@ -2154,7 +2164,56 @@ class OngoingCall { | |||
devices.firstWhereOrNull( | |||
(e) => e.deviceId() == track.getTrack().deviceId(), | |||
); | |||
|
|||
_addNoiseSuppression(track); |
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.
Can we await this call? Or shouldn't we?
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 - yes, there is no reason for not awaiting this call
/// Simulate [ProfileController]. | ||
class _NoiseController extends GetxController { | ||
final media = Rx(MediaSettings(noiseSuppressionEnabled: false)); | ||
|
||
void setNoiseSuppressionEnabled(bool enabled) { | ||
media.update((m) { | ||
m ??= MediaSettings(); | ||
m.noiseSuppressionEnabled = enabled; | ||
}); | ||
} | ||
|
||
void setNoiseSuppressionLevelValue(NoiseSuppressionLevel level) { | ||
media.update((m) { | ||
m ??= MediaSettings(); | ||
m.noiseSuppressionLevel = level; | ||
}); | ||
} | ||
} | ||
|
||
class _NoiseSuppressionView extends StatelessWidget { | ||
const _NoiseSuppressionView(this.c); | ||
|
||
final _NoiseController c; | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
final style = Theme.of(context).style; |
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.
It seems like this test only tests the widgets defined and implemented in the test itself and not the application. Developers may forget the fact that whenever MyProfile
pages is changed this code should be changed as well. It's easy to lose track of. Can't be just test the MyProfile
page itself?
CHANGELOG.md
Outdated
[#1263]: /../../issue/1263 | ||
[#1264]: /../../issue/1264 | ||
[#1268]: /../../issue/1268 | ||
[#1280]: /../../pull/1280 | ||
[#1285]: /../../pull/1285 | ||
[#1285]: /../../pull/1287 |
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 can see the links being added, but no actual change entry?
lib/ui/page/home/widget/block.dart
Outdated
child: ClipPath( | ||
clipper: _BottomEdgeClipper(), | ||
child: AnimatedSize( |
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.
Won't this clipping applied to every single Block
affect performance? https://docs.flutter.dev/release/breaking-changes/clip-behavior#summary
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, very good notice, I will add optional parameter for applying the clipping
lib/ui/page/home/widget/block.dart
Outdated
class _BottomEdgeClipper extends CustomClipper<Path> { | ||
@override | ||
Path getClip(Size size) { | ||
const double kBig = 1e6; |
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.
lib/ui/page/home/widget/block.dart
Outdated
@override | ||
Path getClip(Size size) { | ||
const double kBig = 1e6; | ||
return Path()..addRect(Rect.fromLTRB(-kBig, 0, kBig, size.height)); |
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.
Can't we use double.maxFinite
here in this case?
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.
Sure
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've been debugging and noticed a problem using infinite values. I checked how rect is added to path and noticed this check:
bool _rectIsValid(Rect rect) {
assert(!rect.hasNaN, 'Rect argument contained a NaN value.');
return true;
}
double.infinity converts to NotANumber value and assertion happens. Hence, we cannot deal with infinite values and should leave finite number
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.
@ChabanovX, why would you use a double.infinity
then?
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.
My mistake, read as infinity, maxFinite is working just fine and should be used here
aa02b35
to
806543e
Compare
4d20d13
to
806543e
Compare
Should we remove widget test since we in the future we are going to introduce e2e test? |
Ok, let's remove 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.
@ChabanovX, be sure to read thoughtfully your code before sending it for a review, please.
label_user_removed_user3 = {" "}{$user} | ||
label_user_removed_user3 = { " "}{$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.
?
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.
Will be fixed, I will never trust AI again to do the sorting and will write my own script to do it. So far I did not find a sorting extension, that would manage file with multicolumn labels.
@@ -1048,4 +1054,4 @@ question_mark = ? | |||
space = {" "} | |||
F438 | space_or_space = {" "}or{" "} | ||
space_plus_space = {" "}+{" "} | |||
space_vertical_space = {" "}|{" "} | |||
space_vertical_space = {" "}|{" "} |
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.
This file has no newline character at the end despite .editorconfig
specified to have one:
[*]
...
end_of_line = lf
...
You should install an extension that would respect .editorconfig
files and apply the settings specified in there.
label_no_limit = ∞ | ||
label_no_messages = No messages | ||
label_noise_suppression = Noise suppression | ||
label_no_updates_are_available_subtitle = You have the latest version installed. | ||
label_no_updates_are_available_title = No updates are available |
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.
Doesn't seem sorted. #1287 (comment)
Why did you place this label between two label_no_*
labels? What is the reasoning behind 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.
That is a poor sorting algorithm and will be fixed.
// Currently works only on Desktop | ||
if (PlatformUtils.isWeb || !PlatformUtils.isDesktop) { | ||
Log.debug( | ||
'❌ Noise suppression is not supported on this platform', | ||
'$runtimeType', | ||
); | ||
return; | ||
} | ||
|
||
final enabled = _noiseSuppressionEnabled; | ||
if (enabled == null) { | ||
Log.debug('❌ _noiseSuppressionEnabled is null', '$runtimeType'); | ||
return; | ||
} |
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 any logs should be printed if noise suppression is disabled or are unavailable for the current platform.
if (!track.isAudioProcessingAvailable()) { | ||
Log.debug( | ||
'❌ Audio processing not available for this track $track', | ||
'$runtimeType', | ||
); | ||
return; | ||
10000 | } |
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 guess this should be checked only if noise suppression is enabled and the current platform is supported. Otherwise I don't see any reason to check it.
|
||
final level = _noiseSuppressionLevel; | ||
if (level == null) { | ||
Log.debug('❌ _noiseSuppressionLevel is null', '$runtimeType'); |
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.
This emoji makes it look like an error. Is it an error?
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.
That is not an error, should be removed.
Log.debug('✅ set level to $level', '$runtimeType'); | ||
await track.setNoiseSuppressionLevel(level); | ||
} catch (e, _) { | ||
Log.error('💥 Failed to configure noise suppression: $e', '$runtimeType'); |
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.
This log should contain the track that failed to set the suppression for.
/// Whether to clip overflowing content in height, but not width. | ||
/// Defaults to `false` to avoid extra GPU work. | ||
final bool clipHeight; |
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.
This documentation doesn't follow Effective Dart Documentation guidelines. https://dart.dev/effective-dart/documentation#do-separate-the-first-sentence-of-a-doc-comment-into-its-own-paragraph
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.
Once again I carefully read the following paragraph; will be fixed.
LineDivider('label_voice_processing'.l10n), | ||
const SizedBox(height: 16), | ||
Obx(() { | ||
// False by 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.
Comments should have trailing dot. https://dart.dev/effective-dart/documentation#do-format-comments-like-sentences
// Values of NoiseSuppressionLevel | ||
final values = NoiseSuppressionLevel.values; |
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.
Comments should cover only parts that aren't obvious, I suppose. Otherwise those can make code less readable despite its purpose to make it more readable. Don't you think?
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 agree, will be removed.
Resolves #1264
Synopsis
Add user-configurable noise suppression now that medea_flutter_webrtc 0.14.0
exposes the feature (Desktop). Users need to toggle it in My Profile ▸ Media.
Solution
Upgrade deps. Extend MediaSettings. Migrate DB. Add API in repository. Paint UI. Write tests
Checklist
k::
labels applied