Skip to content

Commit

Permalink
FLUT-259: Added noise cancellation feature (#1739)
Browse files Browse the repository at this point in the history
* Added krisp changes

* Added noise cancellation controller

* Added noise cancellation in prebuilt

* 🤖 Automated Format and Fix

* Added requested changes

* 🤖 Automated Format and Fix

---------

Co-authored-by: Decoder07 <[email protected]>
  • Loading branch information
Decoder07 and Decoder07 authored Mar 26, 2024
1 parent 4f1d52f commit 75a2d4f
Show file tree
Hide file tree
Showing 31 changed files with 583 additions and 96 deletions.
10 changes: 9 additions & 1 deletion packages/hms_room_kit/lib/src/assets/icons/music_wave.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
65 changes: 31 additions & 34 deletions packages/hms_room_kit/lib/src/common/utility_functions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -390,40 +390,37 @@ class Utilities {
}
}

static HMSTrackSetting getTrackSetting(
{required bool isAudioMixerDisabled,
required bool joinWithMutedVideo,
required bool joinWithMutedAudio,
required bool isSoftwareDecoderDisabled,
HMSAudioMode? audioMode}) {
return isAudioMixerDisabled
? HMSTrackSetting(
audioTrackSetting: HMSAudioTrackSetting(
trackInitialState: joinWithMutedAudio
? HMSTrackInitState.MUTED
: HMSTrackInitState.UNMUTED,
audioMode: audioMode),
videoTrackSetting: HMSVideoTrackSetting(
trackInitialState: joinWithMutedVideo
? HMSTrackInitState.MUTED
: HMSTrackInitState.UNMUTED,
forceSoftwareDecoder: isSoftwareDecoderDisabled))
: HMSTrackSetting(
audioTrackSetting: HMSAudioTrackSetting(
audioSource: HMSAudioMixerSource(node: [
HMSAudioFilePlayerNode("audioFilePlayerNode"),
HMSMicNode(),
HMSScreenBroadcastAudioReceiverNode(),
]),
trackInitialState: joinWithMutedAudio
? HMSTrackInitState.MUTED
: HMSTrackInitState.UNMUTED,
audioMode: audioMode),
videoTrackSetting: HMSVideoTrackSetting(
trackInitialState: joinWithMutedVideo
? HMSTrackInitState.MUTED
: HMSTrackInitState.UNMUTED,
forceSoftwareDecoder: isSoftwareDecoderDisabled));
static HMSTrackSetting getTrackSetting({
required bool isAudioMixerDisabled,
required bool joinWithMutedVideo,
required bool joinWithMutedAudio,
required bool isSoftwareDecoderDisabled,
required bool isNoiseCancellationEnabled,
HMSAudioMode? audioMode,
}) {
return HMSTrackSetting(
audioTrackSetting: HMSAudioTrackSetting(

///If audio mixer is disabled we set the audio source as null
///Note that this is only required for iOS
audioSource: isAudioMixerDisabled
? null
: HMSAudioMixerSource(node: [
HMSAudioFilePlayerNode("audioFilePlayerNode"),
HMSMicNode(),
HMSScreenBroadcastAudioReceiverNode(),
]),
trackInitialState: joinWithMutedAudio
? HMSTrackInitState.MUTED
: HMSTrackInitState.UNMUTED,
audioMode: audioMode,
enableNoiseCancellation: isNoiseCancellationEnabled),
videoTrackSetting: HMSVideoTrackSetting(
trackInitialState: joinWithMutedVideo
? HMSTrackInitState.MUTED
: HMSTrackInitState.UNMUTED,
forceSoftwareDecoder: isSoftwareDecoderDisabled,
));
}

static String getTimedMetadataEmojiFromId(String emojiId) {
Expand Down
8 changes: 7 additions & 1 deletion packages/hms_room_kit/lib/src/hms_prebuilt_options.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import 'package:hms_room_kit/hms_room_kit.dart';
///[endPoints] - The token and init endpoints
///[debugInfo] - To enable the debug mode for the prebuilt
///[iOSScreenshareConfig] - Screen share Config, to enable screen share for iOS
///[enableNoiseCancellation] - To enable noise cancellation in prebuilt
class HMSPrebuiltOptions {
//The name of the user
final String? userName;
Expand All @@ -28,11 +29,16 @@ class HMSPrebuiltOptions {
//this config
final HMSIOSScreenshareConfig? iOSScreenshareConfig;

///To enable noise cancellation in prebuilt.
///Default value is true
final bool enableNoiseCancellation;

///[HMSPrebuiltOptions] is a class that is used to pass the options to the prebuilt
HMSPrebuiltOptions(
{this.userName,
this.userId,
this.endPoints,
this.debugInfo = false,
this.iOSScreenshareConfig});
this.iOSScreenshareConfig,
this.enableNoiseCancellation = false});
}
24 changes: 22 additions & 2 deletions packages/hms_room_kit/lib/src/hmssdk_interactor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import 'package:hms_room_kit/src/common/utility_functions.dart';
///[isAudioMixerDisabled] - This is used to disable the audio mixer for iOS. By default it's true.
///[audioMode] - This is used to set the audio mode. By default it's VOICE.
///[isPrebuilt] - This is used to set the prebuilt mode. By default it's false.
///[isNoiseCancellationEnabled] - This is used to set the noise cancellation status in a call. Default value is false
class HMSSDKInteractor {
/// [hmsSDK] is the instance of the HMSSDK class which is used to interact with the SDK.
late HMSSDK hmsSDK;
Expand All @@ -28,14 +29,16 @@ class HMSSDKInteractor {
/// Remove [iOSScreenshareConfig] if your app does not implements Screen Share on iOS.
/// [joinWithMutedAudio] & [joinWithMutedVideo] are required to set the initial audio/video state i.e what should be camera and mic
/// state while room is joined. By default both audio and video are kept as unmute.
/// [isNoiseCancellationEnabled] - By default it's false and is used to enable noise cancellation in the call
HMSSDKInteractor(
{HMSIOSScreenshareConfig? iOSScreenshareConfig,
bool joinWithMutedAudio = false,
bool joinWithMutedVideo = false,
bool isSoftwareDecoderDisabled = true,
bool isAudioMixerDisabled = true,
HMSAudioMode audioMode = HMSAudioMode.VOICE,
bool isPrebuilt = false}) {
bool isPrebuilt = false,
bool isNoiseCancellationEnabled = false}) {
HMSLogSettings hmsLogSettings = HMSLogSettings(
maxDirSizeInBytes: 1000000,
isLogStorageEnabled: true,
Expand All @@ -46,7 +49,8 @@ class HMSSDKInteractor {
joinWithMutedVideo: joinWithMutedVideo,
joinWithMutedAudio: joinWithMutedAudio,
isSoftwareDecoderDisabled: isSoftwareDecoderDisabled,
audioMode: audioMode);
audioMode: audioMode,
isNoiseCancellationEnabled: isNoiseCancellationEnabled);

hmsSDK = HMSSDK(
iOSScreenshareConfig: iOSScreenshareConfig,
Expand Down Expand Up @@ -475,4 +479,20 @@ class HMSSDKInteractor {
Future<dynamic> getPollResults({required HMSPoll hmsPoll}) {
return HMSPollInteractivityCenter.getPollResults(hmsPoll: hmsPoll);
}

void enableNoiseCancellation() {
HMSNoiseCancellationController.enable();
}

void disableNoiseCancellation() {
HMSNoiseCancellationController.disable();
}

Future<bool> isNoiseCancellationAvailable() {
return HMSNoiseCancellationController.isAvailable();
}

Future<bool> isNoiseCancellationEnabled() {
return HMSNoiseCancellationController.isEnabled();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import 'package:provider/provider.dart';
import 'package:tuple/tuple.dart';

///Project imports
import 'package:hms_room_kit/hms_room_kit.dart';
import 'package:hms_room_kit/src/enums/meeting_mode.dart';
import 'package:hms_room_kit/src/meeting/meeting_navigation_visibility_controller.dart';
import 'package:hms_room_kit/src/meeting/meeting_store.dart';
Expand Down
8 changes: 7 additions & 1 deletion packages/hms_room_kit/lib/src/meeting/meeting_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,13 @@ import 'package:hms_room_kit/src/widgets/common_widgets/hms_left_room_screen.dar
class MeetingPage extends StatefulWidget {
final bool isRoomMute;
final HMSAudioDevice currentAudioDeviceMode;
final bool isNoiseCancellationEnabled;

const MeetingPage(
{Key? key, this.isRoomMute = true, required this.currentAudioDeviceMode})
{Key? key,
this.isRoomMute = true,
required this.currentAudioDeviceMode,
this.isNoiseCancellationEnabled = false})
: super(key: key);

@override
Expand All @@ -61,6 +65,8 @@ class _MeetingPageState extends State<MeetingPage> {
}
context.read<MeetingStore>().currentAudioDeviceMode =
widget.currentAudioDeviceMode;
context.read<MeetingStore>().isNoiseCancellationEnabled =
widget.isNoiseCancellationEnabled;
}

bool showError(int? errorCode) {
Expand Down
29 changes: 29 additions & 0 deletions packages/hms_room_kit/lib/src/meeting/meeting_store.dart
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,12 @@ class MeetingStore extends ChangeNotifier
///List of bottom sheets currently open
List<BuildContext> bottomSheets = [];

///Boolean to check whether noise cancellation is available
bool isNoiseCancellationAvailable = false;

///Boolean to track whether noise cancellation is enabled or not
bool isNoiseCancellationEnabled = false;

Future<HMSException?> join(String userName, String? tokenData) async {
late HMSConfig joinConfig;

Expand Down Expand Up @@ -837,6 +843,7 @@ class MeetingStore extends ChangeNotifier
streamingType["hls"] =
room.hmshlsStreamingState?.state ?? HMSStreamingState.none;

checkNoiseCancellationAvailability();
setParticipantsList(roles);
toggleAlwaysScreenOn();
for (HMSPeer each in room.peers!) {
Expand Down Expand Up @@ -2365,6 +2372,28 @@ class MeetingStore extends ChangeNotifier
}
}

///Noise cancellation Methods
void toggleNoiseCancellation() {
if (isNoiseCancellationEnabled) {
_hmsSDKInteractor.disableNoiseCancellation();
} else {
_hmsSDKInteractor.enableNoiseCancellation();
}
isNoiseCancellationEnabled = !isNoiseCancellationEnabled;
notifyListeners();
}

void checkNoiseCancellationAvailability() async {
isNoiseCancellationAvailable =
await _hmsSDKInteractor.isNoiseCancellationAvailable();
if (isNoiseCancellationAvailable) {
isNoiseCancellationEnabled =
await _hmsSDKInteractor.isNoiseCancellationEnabled();
}
notifyListeners();
}

//Get onSuccess or onException callbacks for HMSActionResultListenerMethod
@override
void onSuccess(
Expand Down
7 changes: 6 additions & 1 deletion packages/hms_room_kit/lib/src/meeting_screen_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ class MeetingScreenController extends StatefulWidget {
///[hmsSDKInteractor] is used to interact with the SDK
final HMSSDKInteractor hmsSDKInteractor;

final bool isNoiseCancellationEnabled;

const MeetingScreenController(
{Key? key,
required this.user,
Expand All @@ -68,7 +70,8 @@ class MeetingScreenController extends StatefulWidget {
this.currentAudioDeviceMode = HMSAudioDevice.AUTOMATIC,
this.options,
this.tokenData,
required this.hmsSDKInteractor})
required this.hmsSDKInteractor,
this.isNoiseCancellationEnabled = false})
: super(key: key);

@override
Expand Down Expand Up @@ -141,6 +144,8 @@ class _MeetingScreenControllerState extends State<MeetingScreenController> {
: MeetingPage(
isRoomMute: widget.isRoomMute,
currentAudioDeviceMode: widget.currentAudioDeviceMode,
isNoiseCancellationEnabled:
widget.isNoiseCancellationEnabled,
);
}),
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,25 @@ class PreviewBottomButtonSection extends StatelessWidget {
),
Row(
children: [
if (previewStore.isNoiseCancellationAvailable &&
previewStore.isAudioOn)
Padding(
padding: const EdgeInsets.only(right: 8.0),
child: HMSEmbeddedButton(
onTap: () {
previewStore.toggleNoiseCancellation();
},
isActive: previewStore.isNoiseCancellationEnabled,
child: SvgPicture.asset(
'packages/hms_room_kit/lib/src/assets/icons/music_wave.svg',
colorFilter: ColorFilter.mode(
HMSThemeColors.onSurfaceHighEmphasis,
BlendMode.srcIn),
fit: BoxFit.scaleDown,
semanticsLabel: "noise_cancellation_button",
)),
),

///This renders the [Audio Device Selection Button] only if the
///Peer role has the permission to publish audio
///and the Peer is not null
Expand Down
2 changes: 2 additions & 0 deletions packages/hms_room_kit/lib/src/preview/preview_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ class _PreviewPageState extends State<PreviewPage> {
currentAudioDeviceMode: currentAudioDeviceMode,
tokenData: widget.tokenData,
hmsSDKInteractor: previewStore.hmsSDKInteractor,
isNoiseCancellationEnabled:
previewStore.isNoiseCancellationEnabled,
)));
}

Expand Down
25 changes: 25 additions & 0 deletions packages/hms_room_kit/lib/src/preview/preview_store.dart
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ class PreviewStore extends ChangeNotifier

int peerCount = 0;

bool isNoiseCancellationAvailable = false;

bool isNoiseCancellationEnabled = false;

@override
void onHMSError({required HMSException error}) {
this.error = error;
Expand All @@ -61,6 +65,7 @@ class PreviewStore extends ChangeNotifier
void onPreview({required HMSRoom room, required List<HMSTrack> localTracks}) {
log("onPreview-> room: ${room.toString()}");
this.room = room;
checkNoiseCancellationAvailablility();
for (HMSPeer each in room.peers!) {
if (each.isLocal) {
HMSRoomLayout.resetLayout(each.role.name);
Expand Down Expand Up @@ -203,6 +208,26 @@ class PreviewStore extends ChangeNotifier
}
}

void checkNoiseCancellationAvailablility() async {
isNoiseCancellationAvailable =
await hmsSDKInteractor.isNoiseCancellationAvailable();
if (isNoiseCancellationAvailable) {
isNoiseCancellationEnabled =
await hmsSDKInteractor.isNoiseCancellationEnabled();
}
notifyListeners();
}

void toggleNoiseCancellation() async {
if (isNoiseCancellationEnabled) {
hmsSDKInteractor.disableNoiseCancellation();
} else {
hmsSDKInteractor.enableNoiseCancellation();
}
isNoiseCancellationEnabled = !isNoiseCancellationEnabled;
notifyListeners();
}

void addLogsListener(HMSLogListener hmsLogListener) {
hmsSDKInteractor.addLogsListener(hmsLogListener);
}
Expand Down
2 changes: 2 additions & 0 deletions packages/hms_room_kit/lib/src/screen_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,8 @@ class _ScreenControllerState extends State<ScreenController> {
joinWithMutedVideo: true,
isSoftwareDecoderDisabled: AppDebugConfig.isSoftwareDecoderDisabled,
isAudioMixerDisabled: AppDebugConfig.isAudioMixerDisabled,
isNoiseCancellationEnabled:
widget.options?.enableNoiseCancellation ?? false,
isPrebuilt: true);
await _hmsSDKInteractor.build();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,26 @@ class _AppUtilitiesBottomSheetState extends State<AppUtilitiesBottomSheet> {
HMSRecordingState.started))
? "Recording"
: "Record",
)
),
if (meetingStore.isNoiseCancellationAvailable &&
meetingStore.isMicOn)
MoreOptionItem(
onTap: () async {
Navigator.pop(context);
meetingStore.toggleNoiseCancellation();
},
isActive: meetingStore.isNoiseCancellationEnabled,
optionIcon: SvgPicture.asset(
"packages/hms_room_kit/lib/src/assets/icons/music_wave.svg",
height: 20,
width: 20,
colorFilter: ColorFilter.mode(
HMSThemeColors.onSurfaceHighEmphasis,
BlendMode.srcIn),
),
optionText: meetingStore.isNoiseCancellationEnabled
? "Noise Reduced"
: "Reduce Noise"),
],
),
],
Expand Down
Loading

0 comments on commit 75a2d4f

Please sign in to comment.