You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

local_sts.js 3.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. /**
  2. * Provides statistics for the local stream.
  3. */
  4. var LocalStatsCollector = (function() {
  5. /**
  6. * Size of the webaudio analizer buffer.
  7. * @type {number}
  8. */
  9. var WEBAUDIO_ANALIZER_FFT_SIZE = 2048;
  10. /**
  11. * Value of the webaudio analizer smoothing time parameter.
  12. * @type {number}
  13. */
  14. var WEBAUDIO_ANALIZER_SMOOTING_TIME = 0.8;
  15. /**
  16. * <tt>LocalStatsCollector</tt> calculates statistics for the local stream.
  17. *
  18. * @param stream the local stream
  19. * @param interval stats refresh interval given in ms.
  20. * @param {function(LocalStatsCollector)} updateCallback the callback called on stats
  21. * update.
  22. * @constructor
  23. */
  24. function LocalStatsCollectorProto(stream, interval, updateCallback) {
  25. window.AudioContext = window.AudioContext || window.webkitAudioContext;
  26. this.stream = stream;
  27. this.intervalId = null;
  28. this.intervalMilis = interval;
  29. this.audioLevelsUpdateCallback = updateCallback;
  30. this.audioLevel = 0;
  31. }
  32. /**
  33. * Starts the collecting the statistics.
  34. */
  35. LocalStatsCollectorProto.prototype.start = function () {
  36. if (!window.AudioContext)
  37. return;
  38. var context = new AudioContext();
  39. var analyser = context.createAnalyser();
  40. analyser.smoothingTimeConstant = WEBAUDIO_ANALIZER_SMOOTING_TIME;
  41. analyser.fftSize = WEBAUDIO_ANALIZER_FFT_SIZE;
  42. var source = context.createMediaStreamSource(this.stream);
  43. source.connect(analyser);
  44. var self = this;
  45. this.intervalId = setInterval(
  46. function () {
  47. var array = new Uint8Array(analyser.frequencyBinCount);
  48. analyser.getByteTimeDomainData(array);
  49. var audioLevel = TimeDomainDataToAudioLevel(array);
  50. if(audioLevel != self.audioLevel) {
  51. self.audioLevel = animateLevel(audioLevel, self.audioLevel);
  52. self.audioLevelsUpdateCallback(LocalStatsCollectorProto.LOCAL_JID, self.audioLevel);
  53. }
  54. },
  55. this.intervalMilis
  56. );
  57. };
  58. /**
  59. * Stops collecting the statistics.
  60. */
  61. LocalStatsCollectorProto.prototype.stop = function () {
  62. if (this.intervalId) {
  63. clearInterval(this.intervalId);
  64. this.intervalId = null;
  65. }
  66. };
  67. /**
  68. * Converts time domain data array to audio level.
  69. * @param array the time domain data array.
  70. * @returns {number} the audio level
  71. */
  72. var TimeDomainDataToAudioLevel = function (samples) {
  73. var maxVolume = 0;
  74. var length = samples.length;
  75. for (var i = 0; i < length; i++) {
  76. if (maxVolume < samples[i])
  77. maxVolume = samples[i];
  78. }
  79. return parseFloat(((maxVolume - 127) / 128).toFixed(3));
  80. };
  81. /**
  82. * Animates audio level change
  83. * @param newLevel the new audio level
  84. * @param lastLevel the last audio level
  85. * @returns {Number} the audio level to be set
  86. */
  87. function animateLevel(newLevel, lastLevel)
  88. {
  89. var value = 0;
  90. var diff = lastLevel - newLevel;
  91. if(diff > 0.2)
  92. {
  93. value = lastLevel - 0.2;
  94. }
  95. else if(diff < -0.4)
  96. {
  97. value = lastLevel + 0.4;
  98. }
  99. else
  100. {
  101. value = newLevel;
  102. }
  103. return parseFloat(value.toFixed(3));
  104. }
  105. /**
  106. * Indicates that this audio level is for local jid.
  107. * @type {string}
  108. */
  109. LocalStatsCollectorProto.LOCAL_JID = 'local';
  110. return LocalStatsCollectorProto;
  111. })();