@@ -30,19 +30,19 @@ class Crepe {
30
30
31
31
// perform resampling the audio to 16000 Hz, on which the model is trained.
32
32
// setting a sample rate in AudioContext is not supported by most browsers at the moment.
33
- resample ( audioBuffer , onComplete ) {
33
+ static resample ( audioBuffer , onComplete ) {
34
34
const interpolate = ( audioBuffer . sampleRate % 16000 !== 0 ) ;
35
35
const multiplier = audioBuffer . sampleRate / 16000 ;
36
36
const original = audioBuffer . getChannelData ( 0 ) ;
37
37
const subsamples = new Float32Array ( 1024 ) ;
38
- for ( let i = 0 ; i < 1024 ; i ++ ) {
38
+ for ( let i = 0 ; i < 1024 ; i += 1 ) {
39
39
if ( ! interpolate ) {
40
40
subsamples [ i ] = original [ i * multiplier ] ;
41
41
} else {
42
42
// simplistic, linear resampling
43
43
const left = Math . floor ( i * multiplier ) ;
44
44
const right = left + 1 ;
45
- const p = i * multiplier - left ;
45
+ const p = ( i * multiplier ) - left ;
46
46
subsamples [ i ] = ( ( ( 1 - p ) * original [ left ] ) + ( p * original [ right ] ) ) ;
47
47
}
48
48
}
@@ -53,14 +53,14 @@ class Crepe {
53
53
this . results = { } ;
54
54
// bin number -> cent value mapping
55
55
const centMapping = tf . add ( tf . linspace ( 0 , 7180 , 360 ) , tf . tensor ( 1997.3794084376191 ) ) ;
56
- this . resample ( event . inputBuffer , ( resampled ) => {
56
+ Crepe . resample ( event . inputBuffer , ( resampled ) => {
57
57
tf . tidy ( ( ) => {
58
58
this . running = true ;
59
59
60
60
// run the prediction on the model
61
61
const frame = tf . tensor ( resampled . slice ( 0 , 1024 ) ) ;
62
62
const zeromean = tf . sub ( frame , tf . mean ( frame ) ) ;
63
- const framestd = tf . tensor ( tf . norm ( zeromean ) . dataSync ( ) / Math . sqrt ( 1024 ) ) ;
63
+ const framestd = tf . tensor ( tf . norm ( zeromean ) . dataSync ( ) / Math . sqrt ( 1024 ) ) ;
64
64
const normalized = tf . div ( zeromean , framestd ) ;
65
65
const input = normalized . reshape ( [ 1 , 1024 ] ) ;
66
66
const activation = this . model . predict ( [ input ] ) . reshape ( [ 360 ] ) ;
@@ -81,12 +81,12 @@ class Crepe {
81
81
const productSum = products . dataSync ( ) . reduce ( ( a , b ) => a + b , 0 ) ;
82
82
const weightSum = weights . dataSync ( ) . reduce ( ( a , b ) => a + b , 0 ) ;
83
83
const predictedCent = productSum / weightSum ;
84
- const predictedHz = 10 * Math . pow ( 2 , predictedCent / 1200.0 ) ;
84
+ const predictedHz = 10 * ( ( predictedCent / 1200.0 ) ** 2 ) ;
85
85
86
86
// update
87
- let result = ( confidence > 0.5 ) ? predictedHz . toFixed ( 3 ) + ' Hz' : 'no voice' ;
88
- const strlen = result . length ;
89
- for ( let i = 0 ; i < 11 - strlen ; i ++ ) result = result ;
87
+ const result = ( confidence > 0.5 ) ? ` ${ predictedHz . toFixed ( 3 ) } + Hz` : 'no voice' ;
88
+ // const strlen = result.length;
89
+ // for (let i = 0; i < 11 - strlen; i += 1 ) result = result;
90
90
this . results . result = result ;
91
91
} ) ;
92
92
} ) ;
@@ -98,16 +98,17 @@ class Crepe {
98
98
99
99
processStream ( stream ) {
100
100
console . log ( 'Setting up AudioContext ...' ) ;
101
- console . log ( ' Audio context sample rate = ' + this . audioContext . sampleRate ) ;
101
+ console . log ( ` Audio context sample rate = + ${ this . audioContext . sampleRate } ` ) ;
102
102
const mic = this . audioContext . createMediaStreamSource ( stream ) ;
103
103
104
104
// We need the buffer size that is a power of two
105
105
// and is longer than 1024 samples when resampled to 16000 Hz.
106
106
// In most platforms where the sample rate is 44.1 kHz or 48 kHz,
107
107
// this will be 4096, giving 10-12 updates/sec.
108
- const minBufferSize = this . audioContext . sampleRate / 16000 * 1024 ;
109
- for ( var bufferSize = 4 ; bufferSize < minBufferSize ; bufferSize *= 2 ) ;
110
- console . log ( 'Buffer size = ' + bufferSize ) ;
108
+ const minBufferSize = ( this . audioContext . sampleRate / 16000 ) * 1024 ;
109
+ let bufferSize = 4 ;
110
+ while ( bufferSize < minBufferSize ) bufferSize *= 2 ;
111
+ console . log ( `Buffer size = ${ bufferSize } ` ) ;
111
112
const scriptNode = this . audioContext . createScriptProcessor ( bufferSize , 1 , 1 ) ;
112
113
scriptNode . onaudioprocess = this . processMicrophoneBuffer . bind ( this ) ;
113
114
// It seems necessary to connect the stream to a sink
0 commit comments