You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@guacamole.apache.org by jm...@apache.org on 2016/05/24 03:27:52 UTC

[2/6] incubator-guacamole-client git commit: GUACAMOLE-25: Use linear interpolation for resampling input audio.

GUACAMOLE-25: Use linear interpolation for resampling input audio.


Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/commit/b36a955d
Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/tree/b36a955d
Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/diff/b36a955d

Branch: refs/heads/master
Commit: b36a955d207a47e4df9947bd54cb2d288213e38a
Parents: cc9af8e
Author: Michael Jumper <mj...@apache.org>
Authored: Fri Apr 29 17:33:05 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Mon May 23 15:00:00 2016 -0700

----------------------------------------------------------------------
 .../src/main/webapp/modules/AudioRecorder.js    | 44 +++++++++++++++++---
 1 file changed, 38 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/b36a955d/guacamole-common-js/src/main/webapp/modules/AudioRecorder.js
----------------------------------------------------------------------
diff --git a/guacamole-common-js/src/main/webapp/modules/AudioRecorder.js b/guacamole-common-js/src/main/webapp/modules/AudioRecorder.js
index f9de4dc..f64e6ee 100644
--- a/guacamole-common-js/src/main/webapp/modules/AudioRecorder.js
+++ b/guacamole-common-js/src/main/webapp/modules/AudioRecorder.js
@@ -184,6 +184,43 @@ Guacamole.RawAudioRecorder = function RawAudioRecorder(stream, mimetype) {
     var maxSampleValue = (format.bytesPerSample === 1) ? 128 : 32768;
 
     /**
+     * Determines the value of the waveform represented by the audio data at
+     * the given location. If the value cannot be determined exactly as it does
+     * not correspond to an exact sample within the audio data, the value will
+     * be derived through interpolating nearby samples.
+     *
+     * @param {Float32Array} audioData
+     *     An array of audio data, as returned by AudioBuffer.getChannelData().
+     *
+     * @param {Number} t
+     *     The relative location within the waveform from which the value
+     *     should be retrieved, represented as a floating point number between
+     *     0 and 1 inclusive, where 0 represents the earliest point in time and
+     *     1 represents the latest.
+     *
+     * @returns {Number}
+     *     The value of the waveform at the given location.
+     */
+    var interpolateSample = function getValueAt(audioData, t) {
+
+        // Convert [0, 1] range to [0, audioData.length - 1]
+        var index = (audioData.length - 1) * t;
+
+        // Get the closest whole integer samples indices
+        var left = Math.floor(index);
+        var right = Math.ceil(index);
+
+        // Pull the values of the closest samples
+        var leftValue = audioData[left];
+        var rightValue = audioData[right];
+
+        // Determine the value of the sample at the given non-integer location
+        // through linear interpolation of the nearest samples
+        return leftValue + (rightValue - leftValue) / (right - left) * (index - left);
+
+    };
+
+    /**
      * Converts the given AudioBuffer into an audio packet, ready for streaming
      * along the underlying output stream. Unlike the raw audio packets used by
      * this audio recorder, AudioBuffers require floating point samples and are
@@ -215,13 +252,8 @@ Guacamole.RawAudioRecorder = function RawAudioRecorder(stream, mimetype) {
             // Fill array with data from audio buffer channel
             var offset = channel;
             for (var i = 0; i < outSamples; i++) {
-
-                // Apply naiive resampling
-                var inOffset = Math.floor(i / outSamples * inSamples);
-                data[offset] = Math.floor(audioData[inOffset] * maxSampleValue);
-
+                data[offset] = interpolateSample(audioData, i / (outSamples - 1)) * maxSampleValue;
                 offset += format.channels;
-
             }
 
         }