This repository has been archived by the owner on Feb 17, 2023. It is now read-only.
forked from chris-rudmin/opus-recorder
-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathresampler.js
48 lines (39 loc) · 1.63 KB
/
resampler.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
"use strict";
var Resampler = function( config ){
this.originalSampleRate = config.originalSampleRate;
this.numberOfChannels = config.numberOfChannels;
this.resampledRate = config.resampledRate;
this.lastSampleCache = [];
for ( var i = 0; i < this.numberOfChannels; i++ ){
this.lastSampleCache[i] = [0,0];
}
if ( this.resampledRate === this.originalSampleRate ) {
this.resample = function( buffer ) { return buffer; };
}
};
// From http://johncostella.webs.com/magic/
Resampler.prototype.magicKernel = function( x ) {
if ( x < -0.5 ) {
return 0.5 * ( x + 1.5 ) * ( x + 1.5 );
}
else if ( x > 0.5 ) {
return 0.5 * ( x - 1.5 ) * ( x - 1.5 );
}
return 0.75 - ( x * x );
};
Resampler.prototype.resample = function( buffer, channel ) {
var resampledBufferLength = Math.round( buffer.length * this.resampledRate / this.originalSampleRate );
var resampleRatio = buffer.length / resampledBufferLength;
var outputData = new Float32Array( resampledBufferLength );
for ( var i = 0; i < resampledBufferLength - 1; i++ ) {
var resampleValue = ( resampleRatio - 1 ) + ( i * resampleRatio );
var nearestPoint = Math.round( resampleValue );
for ( var tap = -1; tap < 2; tap++ ) {
var sampleValue = buffer[ nearestPoint + tap ] || this.lastSampleCache[ channel ][ 1 + tap ] || buffer[ nearestPoint ];
outputData[ i ] += sampleValue * this.magicKernel( resampleValue - nearestPoint - tap );
}
}
this.lastSampleCache[ channel ][ 0 ] = buffer[ buffer.length - 2 ];
this.lastSampleCache[ channel ][ 1 ] = outputData[ resampledBufferLength - 1 ] = buffer[ buffer.length - 1 ];
return outputData;
};