diff --git a/scripts/tutorials/halfDuplex.js b/scripts/tutorials/halfDuplex.js new file mode 100644 index 0000000000..fe608eedec --- /dev/null +++ b/scripts/tutorials/halfDuplex.js @@ -0,0 +1,68 @@ +// halfDuplex.js +// +// Created by Philip Rosedale on April 21, 2017 +// Copyright 2016 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +// This client script reduces echo by muting the microphone when others nearby are speaking, +// allowing the use of live microphones and speakers. +// NOTE: This will only work where there are no injectors playing sound effects, +// since those will not be muted and will cause feedback. +// +// IMPORTANT: If you use multiple source microphones, you must give the microphone avatars +// the display name 'Microphone' (or change the string below), to prevent feedback. This script +// will mute the other so-named avatars, so that you can have speakers connected to those same +// avatars and in the same room. +// + +var averageLoudness = 0.0; +var AVERAGING_TIME = 0.9; +var LOUDNESS_THRESHOLD = 100; +var HYSTERESIS_GAP = 1.41; // 3db gap +var MICROPHONE_DISPLAY_NAME = "Microphone"; + +var debug = false; +var isMuted = false; + +Script.update.connect(function () { + // + // Check for other people's audio levels, mute if anyone is talking. + // + var othersLoudness = 0; + var avatars = AvatarList.getAvatarIdentifiers(); + avatars.forEach(function (id) { + var avatar = AvatarList.getAvatar(id); + if ((MyAvatar.sessionUUID !== avatar.sessionUUID) && (avatar.displayName.indexOf(MICROPHONE_DISPLAY_NAME) !== 0)) { + othersLoudness += Math.round(avatar.audioLoudness); + } + // Mute other microphone avatars to not feedback with muti-source environment + if (avatar.displayName.indexOf(MICROPHONE_DISPLAY_NAME) === 0) { + if (!Users.getPersonalMuteStatus(avatar.sessionUUID)) { + Users.personalMute(avatar.sessionUUID, true); + } + } + }); + + averageLoudness = AVERAGING_TIME * averageLoudness + (1.0 - AVERAGING_TIME) * othersLoudness; + + if (!isMuted && (averageLoudness > LOUDNESS_THRESHOLD * HYSTERESIS_GAP)) { + if (debug) { + print("Muted!"); + } + isMuted = true; + if (!AudioDevice.getMuted()) { + AudioDevice.toggleMute(); + } + } else if (isMuted && (averageLoudness < LOUDNESS_THRESHOLD)) { + if (debug) { + print("UnMuted!"); + } + isMuted = false; + if (AudioDevice.getMuted()) { + AudioDevice.toggleMute(); + } + } +}); +