From 92368d981ba6d270b598320b10a077e698d9dea5 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Fri, 21 Apr 2017 18:22:53 -0700 Subject: [PATCH 1/3] Half Duplex script --- scripts/tutorials/halfDuplex.js | 63 +++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 scripts/tutorials/halfDuplex.js diff --git a/scripts/tutorials/halfDuplex.js b/scripts/tutorials/halfDuplex.js new file mode 100644 index 0000000000..f9085661f0 --- /dev/null +++ b/scripts/tutorials/halfDuplex.js @@ -0,0 +1,63 @@ +// 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.1; +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) { + 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(); + } + } +}); + From eaa2102d3fc498d43219a18645a1a0c35c5548c6 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Mon, 24 Apr 2017 21:03:17 -0700 Subject: [PATCH 2/3] Code review fixes --- scripts/tutorials/halfDuplex.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/scripts/tutorials/halfDuplex.js b/scripts/tutorials/halfDuplex.js index f9085661f0..6dc049acc3 100644 --- a/scripts/tutorials/halfDuplex.js +++ b/scripts/tutorials/halfDuplex.js @@ -20,7 +20,7 @@ var averageLoudness = 0.0; var AVERAGING_TIME = 0.9; var LOUDNESS_THRESHOLD = 100; -var HYSTERESIS_GAP = 1.1; +var HYSTERESIS_GAP = 1.41; // 3db gap var MICROPHONE_DISPLAY_NAME = "Microphone"; var debug = false; @@ -40,7 +40,9 @@ Script.update.connect(function () { } // Mute other microphone avatars to not feedback with muti-source environment if (avatar.displayName.indexOf(MICROPHONE_DISPLAY_NAME) == 0) { - Users.personalMute(avatar.sessionUUID, true); + if (!Users.getPersonalMuteStatus(avatar.sessionUUID)) { + Users.personalMute(avatar.sessionUUID, true); + } } }); From 16dd6a2ce1f7c7c032cd29d9f27d6d731be5f0d5 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Tue, 25 Apr 2017 15:37:39 -0700 Subject: [PATCH 3/3] Code review / lint --- scripts/tutorials/halfDuplex.js | 69 +++++++++++++++++---------------- 1 file changed, 36 insertions(+), 33 deletions(-) diff --git a/scripts/tutorials/halfDuplex.js b/scripts/tutorials/halfDuplex.js index 6dc049acc3..fe608eedec 100644 --- a/scripts/tutorials/halfDuplex.js +++ b/scripts/tutorials/halfDuplex.js @@ -20,46 +20,49 @@ var averageLoudness = 0.0; var AVERAGING_TIME = 0.9; var LOUDNESS_THRESHOLD = 100; -var HYSTERESIS_GAP = 1.41; // 3db gap +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. - // + // + // 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); + } + } + }); - 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; - 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(); - } - } + 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(); + } + } });