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:51 UTC
[1/6] incubator-guacamole-client git commit: GUACAMOLE-25: Migrate to
Lanczos interpolation (a = 3).
Repository: incubator-guacamole-client
Updated Branches:
refs/heads/master cc9af8ed2 -> a6ccb36bd
GUACAMOLE-25: Migrate to Lanczos interpolation (a = 3).
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/c1373129
Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/tree/c1373129
Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/diff/c1373129
Branch: refs/heads/master
Commit: c137312963aa084b54b46b8ffaa710971be5b24d
Parents: 0c0ee96
Author: Michael Jumper <mj...@apache.org>
Authored: Sun May 1 00:23:15 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Mon May 23 15:00:00 2016 -0700
----------------------------------------------------------------------
.../src/main/webapp/modules/AudioRecorder.js | 84 +++++++++++++++++---
1 file changed, 75 insertions(+), 9 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/c1373129/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 38e2cad..1f7c83d 100644
--- a/guacamole-common-js/src/main/webapp/modules/AudioRecorder.js
+++ b/guacamole-common-js/src/main/webapp/modules/AudioRecorder.js
@@ -127,6 +127,17 @@ Guacamole.RawAudioRecorder = function RawAudioRecorder(stream, mimetype) {
var BUFFER_SIZE = 512;
/**
+ * The window size to use when applying Lanczos interpolation, commonly
+ * denoted by the variable "a".
+ * See: https://en.wikipedia.org/wiki/Lanczos_resampling
+ *
+ * @private
+ * @contant
+ * @type Number
+ */
+ var LANCZOS_WINDOW_SIZE = 3;
+
+ /**
* The format of audio this recorder will encode.
*
* @private
@@ -219,11 +230,64 @@ Guacamole.RawAudioRecorder = function RawAudioRecorder(stream, mimetype) {
var processor = null;
/**
+ * The normalized sinc function. The normalized sinc function is defined as
+ * 1 for x=0 and sin(PI * x) / (PI * x) for all other values of x.
+ *
+ * See: https://en.wikipedia.org/wiki/Sinc_function
+ *
+ * @private
+ * @param {Number} x
+ * The point at which the normalized sinc function should be computed.
+ *
+ * @returns {Number}
+ * The value of the normalized sinc function at x.
+ */
+ var sinc = function sinc(x) {
+
+ // The value of sinc(0) is defined as 1
+ if (x === 0)
+ return 1;
+
+ // Otherwise, normlized sinc(x) is sin(PI * x) / (PI * x)
+ var piX = Math.PI * x;
+ return Math.sin(piX) / piX;
+
+ };
+
+ /**
+ * Calculates the value of the Lanczos kernal at point x for a given window
+ * size. See: https://en.wikipedia.org/wiki/Lanczos_resampling
+ *
+ * @private
+ * @param {Number} x
+ * The point at which the value of the Lanczos kernel should be
+ * computed.
+ *
+ * @param {Number} a
+ * The window size to use for the Lanczos kernel.
+ *
+ * @returns {Number}
+ * The value of the Lanczos kernel at the given point for the given
+ * window size.
+ */
+ var lanczos = function lanczos(x, a) {
+
+ // Lanczos is sinc(x) * sinc(x / a) for -a < x < a ...
+ if (-a < x && x < a)
+ return sinc(x) * sinc(x / a);
+
+ // ... and 0 otherwise
+ return 0;
+
+ };
+
+ /**
* 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.
*
+ * @private
* @param {Float32Array} audioData
* An array of audio data, as returned by AudioBuffer.getChannelData().
*
@@ -241,17 +305,19 @@ Guacamole.RawAudioRecorder = function RawAudioRecorder(stream, mimetype) {
// 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);
+ // Determine the start and end points for the summation used by the
+ // Lanczos interpolation algorithm (see: https://en.wikipedia.org/wiki/Lanczos_resampling)
+ var start = Math.floor(index) - LANCZOS_WINDOW_SIZE + 1;
+ var end = Math.floor(index) + LANCZOS_WINDOW_SIZE;
- // Pull the values of the closest samples
- var leftValue = audioData[left];
- var rightValue = audioData[right];
+ // Calculate the value of the Lanczos interpolation function for the
+ // required range
+ var sum = 0;
+ for (var i = start; i <= end; i++) {
+ sum += (audioData[i] || 0) * lanczos(index - i, LANCZOS_WINDOW_SIZE);
+ }
- // 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);
+ return sum;
};
[4/6] incubator-guacamole-client git commit: GUACAMOLE-25: Compensate
for underflow/overflow induced by rounding error.
Posted by jm...@apache.org.
GUACAMOLE-25: Compensate for underflow/overflow induced by rounding error.
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/8442f7c3
Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/tree/8442f7c3
Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/diff/8442f7c3
Branch: refs/heads/master
Commit: 8442f7c33f7afdb348c362536468c8d1258b3aab
Parents: b36a955
Author: Michael Jumper <mj...@apache.org>
Authored: Fri Apr 29 18:20:25 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Mon May 23 15:00:00 2016 -0700
----------------------------------------------------------------------
.../src/main/webapp/modules/AudioRecorder.js | 31 ++++++++++++++++++--
1 file changed, 29 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/8442f7c3/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 f64e6ee..704d7e7 100644
--- a/guacamole-common-js/src/main/webapp/modules/AudioRecorder.js
+++ b/guacamole-common-js/src/main/webapp/modules/AudioRecorder.js
@@ -184,6 +184,24 @@ Guacamole.RawAudioRecorder = function RawAudioRecorder(stream, mimetype) {
var maxSampleValue = (format.bytesPerSample === 1) ? 128 : 32768;
/**
+ * The total number of audio samples read from the local audio input device
+ * over the life of this audio recorder.
+ *
+ * @private
+ * @type {Number}
+ */
+ var readSamples = 0;
+
+ /**
+ * The total number of audio samples written to the underlying Guacamole
+ * connection over the life of this audio recorder.
+ *
+ * @private
+ * @type {Number}
+ */
+ var writtenSamples = 0;
+
+ /**
* 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
@@ -237,9 +255,18 @@ Guacamole.RawAudioRecorder = function RawAudioRecorder(stream, mimetype) {
*/
var toSampleArray = function toSampleArray(audioBuffer) {
- // Calculate the number of samples in both input and output
+ // Track overall amount of data read
var inSamples = audioBuffer.length;
- var outSamples = Math.floor(audioBuffer.duration * format.rate);
+ readSamples += inSamples;
+
+ // Calculate the total number of samples that should be written as of
+ // the audio data just received and adjust the size of the output
+ // packet accordingly
+ var expectedWrittenSamples = Math.round(readSamples * format.rate / audioBuffer.sampleRate);
+ var outSamples = expectedWrittenSamples - writtenSamples;
+
+ // Update number of samples written
+ writtenSamples += outSamples;
// Get array for raw PCM storage
var data = new SampleArray(outSamples * format.channels);
[2/6] incubator-guacamole-client git commit: GUACAMOLE-25: Use linear
interpolation for resampling input audio.
Posted by jm...@apache.org.
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;
-
}
}
[5/6] incubator-guacamole-client git commit: GUACAMOLE-25: Increase
audio recording buffer to 2048 bytes.
Posted by jm...@apache.org.
GUACAMOLE-25: Increase audio recording buffer to 2048 bytes.
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/efa6bf3c
Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/tree/efa6bf3c
Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/diff/efa6bf3c
Branch: refs/heads/master
Commit: efa6bf3c72000af95ae91a939442ab40205aa779
Parents: c137312
Author: Michael Jumper <mj...@apache.org>
Authored: Mon May 2 01:48:16 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Mon May 23 15:06:46 2016 -0700
----------------------------------------------------------------------
guacamole-common-js/src/main/webapp/modules/AudioRecorder.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/efa6bf3c/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 1f7c83d..a75dbe1 100644
--- a/guacamole-common-js/src/main/webapp/modules/AudioRecorder.js
+++ b/guacamole-common-js/src/main/webapp/modules/AudioRecorder.js
@@ -124,7 +124,7 @@ Guacamole.RawAudioRecorder = function RawAudioRecorder(stream, mimetype) {
* @constant
* @type {Number}
*/
- var BUFFER_SIZE = 512;
+ var BUFFER_SIZE = 2048;
/**
* The window size to use when applying Lanczos interpolation, commonly
[3/6] incubator-guacamole-client git commit: GUACAMOLE-25: Clean up
media source and processor node on end. Keep reference while streaming
(prevent faulty garbage collection of the nodes).
Posted by jm...@apache.org.
GUACAMOLE-25: Clean up media source and processor node on end. Keep reference while streaming (prevent faulty garbage collection of the nodes).
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/0c0ee96a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/tree/0c0ee96a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/diff/0c0ee96a
Branch: refs/heads/master
Commit: 0c0ee96aaa18d70502f063e734d701597d11e800
Parents: 8442f7c
Author: Michael Jumper <mj...@apache.org>
Authored: Fri Apr 29 19:09:12 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Mon May 23 15:00:00 2016 -0700
----------------------------------------------------------------------
.../src/main/webapp/modules/AudioRecorder.js | 35 ++++++++++++++++++--
1 file changed, 33 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/0c0ee96a/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 704d7e7..38e2cad 100644
--- a/guacamole-common-js/src/main/webapp/modules/AudioRecorder.js
+++ b/guacamole-common-js/src/main/webapp/modules/AudioRecorder.js
@@ -202,6 +202,23 @@ Guacamole.RawAudioRecorder = function RawAudioRecorder(stream, mimetype) {
var writtenSamples = 0;
/**
+ * The source node providing access to the local audio input device.
+ *
+ * @private
+ * @type {MediaStreamAudioSourceNode}
+ */
+ var source = null;
+
+ /**
+ * The script processing node which receives audio input from the media
+ * stream source node as individual audio buffers.
+ *
+ * @private
+ * @type {ScriptProcessorNode}
+ */
+ var processor = null;
+
+ /**
* 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
@@ -294,15 +311,29 @@ Guacamole.RawAudioRecorder = function RawAudioRecorder(stream, mimetype) {
// Abort stream if rejected
if (status.code !== Guacamole.Status.Code.SUCCESS) {
+
+ // Disconnect media source node from script processor
+ if (source)
+ source.disconnect();
+
+ // Disconnect associated script processor node
+ if (processor)
+ processor.disconnect();
+
+ // Remove references to now-unneeded components
+ processor = null;
+ source = null;
+
writer.sendEnd();
return;
+
}
// Attempt to retrieve an audio input stream from the browser
getUserMedia({ 'audio' : true }, function streamReceived(mediaStream) {
// Create processing node which receives appropriately-sized audio buffers
- var processor = context.createScriptProcessor(BUFFER_SIZE, format.channels, format.channels);
+ processor = context.createScriptProcessor(BUFFER_SIZE, format.channels, format.channels);
processor.connect(context.destination);
// Send blobs when audio buffers are received
@@ -311,7 +342,7 @@ Guacamole.RawAudioRecorder = function RawAudioRecorder(stream, mimetype) {
};
// Connect processing node to user's audio input source
- var source = context.createMediaStreamSource(mediaStream);
+ source = context.createMediaStreamSource(mediaStream);
source.connect(processor);
}, function streamDenied() {
[6/6] incubator-guacamole-client git commit: Merge Lanczos changes
for front end.
Posted by jm...@apache.org.
Merge Lanczos changes for front end.
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/a6ccb36b
Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/tree/a6ccb36b
Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/diff/a6ccb36b
Branch: refs/heads/master
Commit: a6ccb36bdb31e69d67e62e0638b71c3d27550bc0
Parents: cc9af8e efa6bf3
Author: James Muehlner <ja...@guac-dev.org>
Authored: Mon May 23 20:26:40 2016 -0700
Committer: James Muehlner <ja...@guac-dev.org>
Committed: Mon May 23 20:26:40 2016 -0700
----------------------------------------------------------------------
.../src/main/webapp/modules/AudioRecorder.js | 178 +++++++++++++++++--
1 file changed, 167 insertions(+), 11 deletions(-)
----------------------------------------------------------------------