diff --git a/app.js b/app.js index c34a0605c..9cacb7b37 100644 --- a/app.js +++ b/app.js @@ -445,33 +445,23 @@ function muteVideo(pc, unmute) { } /** - * Callback called by {@link StatsCollector} in intervals supplied to it's - * constructor. - * @param statsCollector {@link StatsCollector} source of the event. + * Callback for audio levels changed. + * @param jid JID of the user + * @param audioLevel the audio level value */ -function statsUpdated(statsCollector) +function audioLevelUpdated(jid, audioLevel) { - Object.keys(statsCollector.jid2stats).forEach(function (jid) + var resourceJid; + if(jid === LocalStatsCollector.LOCAL_JID) { - var peerStats = statsCollector.jid2stats[jid]; - Object.keys(peerStats.ssrc2AudioLevel).forEach(function (ssrc) - { - AudioLevels.updateAudioLevel( Strophe.getResourceFromJid(jid), - peerStats.ssrc2AudioLevel[ssrc]); - }); - }); -} + resourceJid = AudioLevels.LOCAL_LEVEL; + } + else + { + resourceJid = Strophe.getResourceFromJid(jid); + } -/** - * Callback called by {@link LocalStatsCollector} in intervals supplied to it's - * constructor. - * @param statsCollector {@link LocalStatsCollector} source of the event. - */ -function localStatsUpdated(statsCollector) -{ - AudioLevels.updateAudioLevel( - AudioLevels.LOCAL_LEVEL, - statsCollector.audioLevel); + AudioLevels.updateAudioLevel(resourceJid, audioLevel); } /** @@ -483,10 +473,7 @@ function startRtpStatsCollector() if (config.enableRtpStats) { statsCollector = new StatsCollector( - getConferenceHandler().peerconnection, 200, statsUpdated); - - stopLocalRtpStatsCollector(); - + getConferenceHandler().peerconnection, 200, audioLevelUpdated); statsCollector.start(); } } @@ -511,7 +498,7 @@ function startLocalRtpStatsCollector(stream) { if(config.enableRtpStats) { - localStatsCollector = new LocalStatsCollector(stream, 200, localStatsUpdated); + localStatsCollector = new LocalStatsCollector(stream, 100, audioLevelUpdated); localStatsCollector.start(); } } @@ -1123,11 +1110,7 @@ function disposeConference(onUnload) { handler.peerconnection.close(); } stopRTPStatsCollector(); - if(!onUnload) { - startLocalRtpStatsCollector(connection.jingle.localAudio); - } - else - { + if(onUnload) { stopLocalRtpStatsCollector(); } focus = null; diff --git a/local_stats.js b/local_stats.js index 6b2c44277..fbefa98c8 100644 --- a/local_stats.js +++ b/local_stats.js @@ -6,13 +6,13 @@ var LocalStatsCollector = (function() { * Size of the webaudio analizer buffer. * @type {number} */ - var WEBAUDIO_ANALIZER_FFT_SIZE = 512; + var WEBAUDIO_ANALIZER_FFT_SIZE = 2048; /** * Value of the webaudio analizer smoothing time parameter. * @type {number} */ - var WEBAUDIO_ANALIZER_SMOOTING_TIME = 0.1; + var WEBAUDIO_ANALIZER_SMOOTING_TIME = 0.8; /** * LocalStatsCollector calculates statistics for the local stream. @@ -54,12 +54,16 @@ var LocalStatsCollector = (function() { this.intervalId = setInterval( function () { var array = new Uint8Array(analyser.frequencyBinCount); - analyser.getByteFrequencyData(array); - self.audioLevel = FrequencyDataToAudioLevel(array); - self.updateCallback(self); + analyser.getByteTimeDomainData(array); + var audioLevel = TimeDomainDataToAudioLevel(array); + if(audioLevel != self.audioLevel) { + self.audioLevel = animateLevel(audioLevel, self.audioLevel); + self.updateCallback(LocalStatsCollectorProto.LOCAL_JID, self.audioLevel); + } }, this.intervalMilis ); + }; /** @@ -73,22 +77,55 @@ var LocalStatsCollector = (function() { }; /** - * Converts frequency data array to audio level. - * @param array the frequency data array. + * Converts time domain data array to audio level. + * @param array the time domain data array. * @returns {number} the audio level */ - var FrequencyDataToAudioLevel = function (array) { + var TimeDomainDataToAudioLevel = function (samples) { + var maxVolume = 0; - var length = array.length; + var length = samples.length; for (var i = 0; i < length; i++) { - if (maxVolume < array[i]) - maxVolume = array[i]; + if (maxVolume < samples[i]) + maxVolume = samples[i]; } - return maxVolume / 255; + return parseFloat(((maxVolume - 127) / 128).toFixed(3)); }; + /** + * Animates audio level change + * @param newLevel the new audio level + * @param lastLevel the last audio level + * @returns {Number} the audio level to be set + */ + function animateLevel(newLevel, lastLevel) + { + var value = 0; + var diff = lastLevel - newLevel; + if(diff > 0.2) + { + value = lastLevel - 0.2; + } + else if(diff < -0.4) + { + value = lastLevel + 0.4; + } + else + { + value = newLevel; + } + + return parseFloat(value.toFixed(3)); + } + + /** + * Indicates that this audio level is for local jid. + * @type {string} + */ + LocalStatsCollectorProto.LOCAL_JID = 'local'; + return LocalStatsCollectorProto; })(); \ No newline at end of file diff --git a/rtp_stats.js b/rtp_stats.js index 8bfdcbc38..dafc04832 100644 --- a/rtp_stats.js +++ b/rtp_stats.js @@ -213,6 +213,8 @@ StatsCollector.prototype.processReport = function () // but it seems to vary between 0 and around 32k. audioLevel = audioLevel / 32767; jidStats.setSsrcAudioLevel(ssrc, audioLevel); + if(jid != connection.emuc.myroomjid) + this.updateCallback(jid, audioLevel); } var key = 'packetsReceived'; @@ -281,7 +283,5 @@ StatsCollector.prototype.processReport = function () // bar indicator //console.info("Loss SMA3: " + outputAvg + " Q: " + quality); } - - self.updateCallback(self); };