@@ -30,9 +30,7 @@ export class BoardAudio {
30
30
currentSoundExpressionCallback : undefined | ( ( ) => void ) ;
31
31
private stopActiveRecording : ( ( ) => void ) | undefined ;
32
32
33
- constructor (
34
- private microphoneEl : SVGElement
35
- ) { }
33
+ constructor ( private microphoneEl : SVGElement ) { }
36
34
37
35
initializeCallbacks ( {
38
36
defaultAudioCallback,
@@ -142,9 +140,9 @@ export class BoardAudio {
142
140
setSensitivity ( sensitivity : number ) {
143
141
this . sensitivityNode ! . gain . setValueAtTime (
144
142
// check if this is correct
145
- sensitivity ,
143
+ sensitivity ,
146
144
this . context ! . currentTime
147
- )
145
+ ) ;
148
146
}
149
147
150
148
setVolume ( volume : number ) {
@@ -206,7 +204,7 @@ export class BoardAudio {
206
204
this . stopRecording ( ) ;
207
205
return ;
208
206
}
209
- this . microphoneEl . style . display = "unset"
207
+ this . microphoneEl . style . display = "unset" ;
210
208
211
209
const source = this . context ! . createMediaStreamSource ( micStream ) ;
212
210
source . connect ( this . sensitivityNode ! ) ;
@@ -241,8 +239,8 @@ export class BoardAudio {
241
239
recorder . disconnect ( ) ;
242
240
this . sensitivityNode ! . disconnect ( ) ;
243
241
source . disconnect ( ) ;
244
- micStream . getTracks ( ) . forEach ( track => track . stop ( ) )
245
- this . microphoneEl . style . display = "none"
242
+ micStream . getTracks ( ) . forEach ( ( track ) => track . stop ( ) ) ;
243
+ this . microphoneEl . style . display = "none" ;
246
244
this . stopActiveRecording = undefined ;
247
245
} ;
248
246
}
@@ -274,8 +272,9 @@ class BufferedAudio {
274
272
) { }
275
273
276
274
init ( sampleRate : number ) {
275
+ // This is called for each new audio source so don't reset nextStartTime
276
+ // or we start to overlap audio
277
277
this . sampleRate = sampleRate ;
278
- this . nextStartTime = - 1 ;
279
278
}
280
279
281
280
createBuffer ( length : number ) {
@@ -291,20 +290,24 @@ class BufferedAudio {
291
290
// Use createBufferSource instead of new AudioBufferSourceNode to support Safari 14.0.
292
291
const source = this . context . createBufferSource ( ) ;
293
292
source . buffer = buffer ;
294
- source . onended = this . callback ;
293
+ source . onended = this . callCallback ;
295
294
source . connect ( this . destination ) ;
296
295
const currentTime = this . context . currentTime ;
297
296
const first = this . nextStartTime < currentTime ;
298
297
const startTime = first ? currentTime : this . nextStartTime ;
299
298
this . nextStartTime = startTime + buffer . length / buffer . sampleRate ;
300
- // For audio frames, we're frequently out of data. Speech is smooth.
301
299
if ( first ) {
302
300
// We're just getting started so buffer another frame.
303
301
this . callback ( ) ;
304
302
}
305
303
source . start ( startTime ) ;
306
304
}
307
305
306
+ private callCallback = ( ) => {
307
+ // Indirect so we can clear callback later
308
+ this . callback ( ) ;
309
+ } ;
310
+
308
311
dispose ( ) {
309
312
// Prevent calls into WASM when the buffer nodes finish.
310
313
this . callback = ( ) => { } ;
0 commit comments