mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-07 05:31:22 +00:00
GUACAMOLE-25: Use linear interpolation for resampling input audio.
This commit is contained in:
@@ -183,6 +183,43 @@ Guacamole.RawAudioRecorder = function RawAudioRecorder(stream, mimetype) {
|
|||||||
*/
|
*/
|
||||||
var maxSampleValue = (format.bytesPerSample === 1) ? 128 : 32768;
|
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
|
* Converts the given AudioBuffer into an audio packet, ready for streaming
|
||||||
* along the underlying output stream. Unlike the raw audio packets used by
|
* along the underlying output stream. Unlike the raw audio packets used by
|
||||||
@@ -215,13 +252,8 @@ Guacamole.RawAudioRecorder = function RawAudioRecorder(stream, mimetype) {
|
|||||||
// Fill array with data from audio buffer channel
|
// Fill array with data from audio buffer channel
|
||||||
var offset = channel;
|
var offset = channel;
|
||||||
for (var i = 0; i < outSamples; i++) {
|
for (var i = 0; i < outSamples; i++) {
|
||||||
|
data[offset] = interpolateSample(audioData, i / (outSamples - 1)) * maxSampleValue;
|
||||||
// Apply naiive resampling
|
|
||||||
var inOffset = Math.floor(i / outSamples * inSamples);
|
|
||||||
data[offset] = Math.floor(audioData[inOffset] * maxSampleValue);
|
|
||||||
|
|
||||||
offset += format.channels;
|
offset += format.channels;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user