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;
-
}
}