speaker-calibration 2.2.6 → 2.2.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "speaker-calibration",
3
- "version": "2.2.6",
3
+ "version": "2.2.8",
4
4
  "description": "Speaker calibration library for auditory testing",
5
5
  "main": "dist/main.js",
6
6
  "directories": {
@@ -1,5 +1,4 @@
1
1
  import AudioCalibrator from '../audioCalibrator';
2
- import MlsGenInterface from './mlsGen/mlsGenInterface';
3
2
 
4
3
  import {sleep, csvToArray, saveToCSV} from '../../utils';
5
4
  import database from '../../config/firebase';
@@ -150,6 +149,10 @@ class Combination extends AudioCalibrator {
150
149
 
151
150
  #currentConvolution = [];
152
151
 
152
+ mode = 'unfiltered';
153
+
154
+ sourceNode;
155
+
153
156
  /**generate string template that gets reevaluated as variable increases */
154
157
  generateTemplate = () => {
155
158
  if (this.percent_complete > 100) {
@@ -186,8 +189,6 @@ class Combination extends AudioCalibrator {
186
189
  const filteredComputedIRs = computedIRs.filter(element => {
187
190
  return element != undefined;
188
191
  });
189
- //const componentIRGains = this.componentIR['Gain'];
190
- //const componentIRFreqs = this.componentIR['Freq'];
191
192
  const mls = this.#mls;
192
193
  const lowHz = this.#lowHz;
193
194
  const highHz = this.#highHz;
@@ -215,12 +216,9 @@ class Combination extends AudioCalibrator {
215
216
  this.emit('update', {message: this.status});
216
217
  this.systemInvertedImpulseResponse = res['iir'];
217
218
  this.systemIR = res['ir'];
218
- //this.componentIR['Gain'] = res['ir'];
219
- //this.componentIR['Freq'] = res['frequencies'];
220
219
  this.systemConvolution = res['convolution'];
221
220
  })
222
221
  .catch(err => {
223
- // this.emit('InvertedImpulseResponse', {res: false});
224
222
  console.error(err);
225
223
  });
226
224
  };
@@ -343,31 +341,22 @@ class Combination extends AudioCalibrator {
343
341
  console.log('await desired length ' + this.stepNum);
344
342
  this.status =
345
343
  `All Hz Calibration: sampling the calibration signal...`.toString() +
346
- `\n iteration Count: ${this.stepNum}` +
344
+ `\niteration ${this.stepNum}` +
347
345
  this.generateTemplate();
348
346
  this.emit('update', {
349
347
  message: this.status,
350
348
  });
351
- let time_to_wait = (this.#mls.length / this.sourceSamplingRate) * this.numMLSPerCapture;
352
- await sleep(time_to_wait);
353
- };
354
-
355
- #awaitDesiredMLSLengthConvolved = async () => {
356
- // seconds per MLS = P / SR
357
- // await N * P / SR
358
- this.stepNum += 1;
359
- console.log('await desired length ' + this.stepNum);
360
- this.status =
361
- `All Hz Calibration: sampling the calibration signal...`.toString() +
362
- `\n iteration Count: ${this.stepNum}`;
363
- +this.generateTemplate();
364
-
365
- this.emit('update', {
366
- message: this.status,
367
- });
368
- let time_to_wait =
349
+ let time_to_wait = 0;
350
+ if (this.mode === 'unfiltered'){
351
+ time_to_wait = (this.#mls.length / this.sourceSamplingRate) * this.numMLSPerCapture;
352
+ }else if (this.mode === 'filtered'){
353
+ time_to_wait =
369
354
  (this.#currentConvolution.length / this.sourceSamplingRate) * this.numMLSPerCapture;
370
- await sleep(time_to_wait);
355
+ }else{
356
+ throw new Error("Mode broke in awaitDesiredMLSLength");
357
+ }
358
+
359
+ await sleep(time_to_wait*1.1);
371
360
  };
372
361
 
373
362
  /** .
@@ -387,23 +376,14 @@ class Combination extends AudioCalibrator {
387
376
  message: this.status,
388
377
  });
389
378
  let number_of_bursts_to_skip = this.num_mls_to_skip;
390
- let time_to_sleep = this.#mls.length / this.sourceSamplingRate;
391
- //await sleep(this.TAPER_SECS);
392
- await sleep(time_to_sleep);
393
- };
394
-
395
- #awaitSignalOnsetConvolved = async () => {
396
- this.stepNum += 1;
397
- console.log('await signal onset ' + this.stepNum);
398
- this.status =
399
- `All Hz Calibration: waiting for the signal to stabilize...`.toString() +
400
- this.generateTemplate();
401
- this.emit('update', {
402
- message: this.status,
403
- });
404
- let number_of_bursts_to_skip = this.num_mls_to_skip;
405
- let time_to_sleep = this.#currentConvolution.length / this.sourceSamplingRate;
406
- //await sleep(this.TAPER_SECS);
379
+ let time_to_sleep = 0;
380
+ if (this.mode === 'unfiltered'){
381
+ time_to_sleep = this.#mls.length / this.sourceSamplingRate;
382
+ }else if (this.mode === 'filtered'){
383
+ time_to_sleep = this.#currentConvolution.length / this.sourceSamplingRate;
384
+ }else{
385
+ throw new Error("Mode broke in awaitSignalOnset");
386
+ }
407
387
  await sleep(time_to_sleep);
408
388
  };
409
389
 
@@ -465,28 +445,6 @@ class Combination extends AudioCalibrator {
465
445
  return curve;
466
446
  };
467
447
 
468
- /**
469
- * Construct a Calibration Node with the calibration parameters.
470
- *
471
- * @param CALIBRATION_TONE_FREQUENCY
472
- * @private
473
- * @example
474
- */
475
- #createPureTonenNode = CALIBRATION_TONE_FREQUENCY => {
476
- const audioContext = this.makeNewSourceAudioContext();
477
- const oscilator = audioContext.createOscillator();
478
- const gainNode = audioContext.createGain();
479
-
480
- oscilator.frequency.value = CALIBRATION_TONE_FREQUENCY;
481
- oscilator.type = 'sine';
482
- gainNode.gain.value = 0.04;
483
-
484
- oscilator.connect(gainNode);
485
- gainNode.connect(audioContext.destination);
486
-
487
- this.addCalibrationNode(oscilator);
488
- };
489
-
490
448
  /**
491
449
  * Construct a Calibration Node with the calibration parameters.
492
450
  *
@@ -495,11 +453,16 @@ class Combination extends AudioCalibrator {
495
453
  * @example
496
454
  */
497
455
  #createCalibrationNodeFromBuffer = dataBuffer => {
498
- const audioContext = this.makeNewSourceAudioContext();
499
- const buffer = audioContext.createBuffer(
456
+ console.log('databuffer');
457
+ console.log(dataBuffer);
458
+ if (!this.sourceAudioContext){
459
+ this.makeNewSourceAudioContext();
460
+ }
461
+
462
+ const buffer = this.sourceAudioContext.createBuffer(
500
463
  1, // number of channels
501
464
  dataBuffer.length,
502
- audioContext.sampleRate // sample rate
465
+ this.sourceAudioContext.sampleRate // sample rate
503
466
  );
504
467
 
505
468
  const data = buffer.getChannelData(0); // get data
@@ -511,19 +474,16 @@ class Combination extends AudioCalibrator {
511
474
  } catch (error) {
512
475
  console.error(error);
513
476
  }
514
- const onsetGainNode = audioContext.createGain();
515
- this.offsetGainNode = audioContext.createGain();
516
- const source = audioContext.createBufferSource();
517
-
518
- source.buffer = buffer;
519
- source.loop = true;
520
- source.connect(onsetGainNode);
521
- onsetGainNode.connect(this.offsetGainNode);
522
- this.offsetGainNode.connect(audioContext.destination);
523
-
524
- const onsetCurve = Combination.createSCurveBuffer(this.sourceSamplingRate, Math.PI / 2);
525
- onsetGainNode.gain.setValueCurveAtTime(onsetCurve, 0, this.TAPER_SECS);
526
- this.addCalibrationNode(source);
477
+
478
+ this.sourceNode = this.sourceAudioContext.createBufferSource();
479
+
480
+
481
+
482
+ this.sourceNode.buffer = buffer;
483
+ this.sourceNode.loop = true;
484
+ this.sourceNode.connect(this.sourceAudioContext.destination);
485
+
486
+ this.addCalibrationNode(this.sourceNode);
527
487
  };
528
488
 
529
489
  /**
@@ -608,34 +568,32 @@ class Combination extends AudioCalibrator {
608
568
  * @example
609
569
  */
610
570
  #playCalibrationAudio = () => {
611
- this.calibrationNodes[0].start(0);
612
- console.log('sink sampling rate');
613
- console.log(this.sinkSamplingRate);
614
- console.log('source sampling rate');
615
- console.log(this.sourceSamplingRate);
616
- this.#mls = this.calibrationNodes[0].buffer.getChannelData(0);
617
- this.stepNum += 1;
618
- console.log('play calibration audio ' + this.stepNum);
619
- this.status =
571
+ if (this.mode === 'unfiltered'){
572
+ this.calibrationNodes[0].start(0);
573
+ this.#mls = this.calibrationNodes[0].buffer.getChannelData(0);
574
+ console.log('play calibration audio ' + this.stepNum);
575
+ this.status =
620
576
  `All Hz Calibration: playing the calibration tone...`.toString() +
621
577
  this.generateTemplate().toString();
622
- this.emit('update', {message: this.status});
623
- };
624
-
625
- #playCalibrationAudioConvolved = () => {
626
- this.calibrationNodesConvolved[0].start(0);
578
+ this.emit('update', {message: this.status});
579
+ } else if (this.mode === 'filtered'){
580
+ this.calibrationNodes[0].start(0);
581
+ console.log('play convolved audio ' + this.stepNum);
582
+ this.status =
583
+ `All Hz Calibration: playing the convolved calibration tone...`.toString() +
584
+ this.generateTemplate().toString();
585
+ this.emit('update', {message: this.status});
586
+ } else{
587
+ throw new Error("Mode is incorrect");
588
+ }
589
+ this.stepNum += 1;
627
590
  console.log('sink sampling rate');
628
591
  console.log(this.sinkSamplingRate);
629
592
  console.log('source sampling rate');
630
593
  console.log(this.sourceSamplingRate);
631
- this.stepNum += 1;
632
- console.log('play convolved audio ' + this.stepNum);
633
- this.status =
634
- `All Hz Calibration: playing the convolved calibration tone...`.toString() +
635
- this.generateTemplate().toString();
636
- this.emit('update', {message: this.status});
637
594
  };
638
595
 
596
+
639
597
  /** .
640
598
  * .
641
599
  * .
@@ -644,14 +602,10 @@ class Combination extends AudioCalibrator {
644
602
  * @example
645
603
  */
646
604
  #stopCalibrationAudio = () => {
647
- this.offsetGainNode.gain.setValueAtTime(
648
- this.offsetGainNode.gain.value,
649
- this.sourceAudioContext.currentTime
650
- );
651
605
 
652
- this.offsetGainNode.gain.setTargetAtTime(0, this.sourceAudioContext.currentTime, 0.5);
653
606
  this.calibrationNodes[0].stop(0);
654
- this.sourceAudioContext.close();
607
+ this.calibrationNodes = [];
608
+ this.sourceNode.disconnect();
655
609
  this.stepNum += 1;
656
610
  console.log('stop calibration audio ' + this.stepNum);
657
611
  this.status =
@@ -660,52 +614,21 @@ class Combination extends AudioCalibrator {
660
614
  this.emit('update', {message: this.status});
661
615
  };
662
616
 
663
- #stopCalibrationAudioConvolved = () => {
664
- this.offsetGainNode.gain.setValueAtTime(
665
- this.offsetGainNode.gain.value,
666
- this.sourceAudioContextConvolved.currentTime
667
- );
668
-
669
- this.offsetGainNode.gain.setTargetAtTime(0, this.sourceAudioContextConvolved.currentTime, 0.5);
670
- //this.calibrationNodesConvolved[0].stop(0);
671
- console.log('right before closing volved audio context');
672
- this.sourceAudioContextConvolved.close();
673
- this.stepNum += 1;
674
- console.log('stop convolved calibration audio ' + this.stepNum);
675
- this.status =
676
- `All Hz Calibration: stopping the convolved calibration tone...`.toString() +
677
- this.generateTemplate().toString();
678
- this.emit('update', {message: this.status});
679
- };
680
-
681
617
  playMLSwithIIR = async (stream, iir) => {
618
+ this.mode = 'filtered';
682
619
  console.log('play mls with iir');
683
620
  this.invertedImpulseResponse = iir;
684
- // initialize the MLSGenInterface object with it's factory method
685
-
686
- await MlsGenInterface.factory(
687
- this.#mlsOrder,
688
- this.sinkSamplingRate,
689
- this.sourceSamplingRate
690
- ).then(mlsGenInterface => {
691
- this.#mlsGenInterface = mlsGenInterface;
692
- //this.#mlsBufferView = this.#mlsGenInterface.getMLS();
693
- });
694
621
 
695
- // after intializating, start the calibration steps with garbage collection
696
- await this.#mlsGenInterface.withGarbageCollection([
697
- () =>
698
- this.calibrationSteps(
699
- stream,
700
- this.#playCalibrationAudioConvolved, // play audio func (required)
701
- this.#putInPythonConv, // before play func
702
- this.#awaitSignalOnsetConvolved, // before record
703
- () => this.numSuccessfulCaptured < 1,
704
- this.#awaitDesiredMLSLengthConvolved, // during record
705
- this.#afterMLSwIIRRecord, // after record
706
- 'filtered'
707
- ),
708
- ]);
622
+ await this.calibrationSteps(
623
+ stream,
624
+ this.#playCalibrationAudio, // play audio func (required)
625
+ this.#createCalibrationNodeFromBuffer(this.#currentConvolution), // before play func
626
+ this.#awaitSignalOnset, // before record
627
+ () => this.numSuccessfulCaptured < 1,
628
+ this.#awaitDesiredMLSLength, // during record
629
+ this.#afterMLSwIIRRecord, // after record
630
+ this.mode
631
+ )
709
632
  };
710
633
 
711
634
  /**
@@ -718,15 +641,6 @@ class Combination extends AudioCalibrator {
718
641
  * @example
719
642
  */
720
643
  startCalibrationImpulseResponse = async stream => {
721
- // initialize the MLSGenInterface object with it's factory method
722
- await MlsGenInterface.factory(
723
- this.#mlsOrder,
724
- this.sinkSamplingRate,
725
- this.sourceSamplingRate
726
- ).then(mlsGenInterface => {
727
- this.#mlsGenInterface = mlsGenInterface;
728
- //this.#mlsBufferView = this.#mlsGenInterface.getMLS();
729
- });
730
644
 
731
645
  let desired_time = this.desired_time_per_mls;
732
646
 
@@ -742,21 +656,16 @@ class Combination extends AudioCalibrator {
742
656
  // this.emit('InvertedImpulseResponse', {res: false});
743
657
  console.error(err);
744
658
  });
745
-
746
- // after intializating, start the calibration steps with garbage collection
747
- await this.#mlsGenInterface.withGarbageCollection([
748
- () =>
749
- this.calibrationSteps(
750
- stream,
751
- this.#playCalibrationAudio, // play audio func (required)
752
- this.#setCalibrationNodesFromBuffer, // before play func
753
- this.#awaitSignalOnset, // before record
754
- () => this.numSuccessfulCaptured < this.numCaptures, // loop while true
755
- this.#awaitDesiredMLSLength, // during record
756
- this.#afterMLSRecord, // after record
757
- 'unfiltered'
758
- ),
759
- ]);
659
+ await this.calibrationSteps(
660
+ stream,
661
+ this.#playCalibrationAudio, // play audio func (required)
662
+ this.#createCalibrationNodeFromBuffer(this.#mlsBufferView), // before play func
663
+ this.#awaitSignalOnset, // before record
664
+ () => this.numSuccessfulCaptured < this.numCaptures, // loop while true
665
+ this.#awaitDesiredMLSLength, // during record
666
+ this.#afterMLSRecord, // after record
667
+ this.mode
668
+ ),
760
669
 
761
670
  this.#stopCalibrationAudio();
762
671
 
@@ -767,13 +676,17 @@ class Combination extends AudioCalibrator {
767
676
  await this.sendComponentImpulseResponsesToServerForProcessing();
768
677
 
769
678
  this.numSuccessfulCaptured = 0;
770
- // debugging function, use to test the result of the IIR
771
679
 
772
- //if goal == loudspeaker etc,
773
680
  let iir_ir_and_plots;
774
681
  if (this._calibrateSoundCheck != 'none') {
682
+ if (this._calibrateSoundCheck != 'system') {
683
+ this.#currentConvolution = this.componentConvolution;
684
+ }else{
685
+ this.#currentConvolution = this.systemConvolution;
686
+ }
775
687
  await this.playMLSwithIIR(stream, this.invertedImpulseResponse);
776
- this.#stopCalibrationAudioConvolved();
688
+ this.#stopCalibrationAudio();
689
+ this.sourceAudioContext.close();
777
690
  let conv_recs = this.getAllFilteredRecordedSignals();
778
691
  let recs = this.getAllRecordedSignals();
779
692
  let unconv_rec = recs[0];
@@ -913,7 +826,6 @@ class Combination extends AudioCalibrator {
913
826
  throw new Error(`Unknown data type: ${data.type}`);
914
827
  }
915
828
  };
916
-
917
829
  createSCurveBuffer = (onSetBool = true) => {
918
830
  const curve = new Float32Array(this.TAPER_SECS * this.sourceSamplingRate + 1);
919
831
  const frequency = 1 / (4 * this.TAPER_SECS);
@@ -926,8 +838,8 @@ class Combination extends AudioCalibrator {
926
838
  j += 1 / this.sourceSamplingRate;
927
839
  }
928
840
  return curve;
929
- };
930
-
841
+ };
842
+
931
843
  #getTruncatedSignal = (left = 3.5, right = 4.5) => {
932
844
  const start = Math.floor(left * this.sourceSamplingRate);
933
845
  const end = Math.floor(right * this.sourceSamplingRate);
@@ -1268,17 +1180,6 @@ class Combination extends AudioCalibrator {
1268
1180
 
1269
1181
  this.oldComponentIR = this.componentIR;
1270
1182
 
1271
- //TODO:
1272
- //if *1000 is in, lcalib is that value and componentGainDBSPL is that value converted to dB
1273
- //this value (lcalib) is 1000 hz offset so it must be added to every gain
1274
- //if *1000 is not in, interpolate to get gain at 1000 hz (lcalib) and obtain componentGainDBSPL by converting lCalib to dB
1275
-
1276
- //lCalib is gain at 1000 hz, componentGainDBSPL is gain at 1000 hz converted to db
1277
- //TODO: get this parameter from DB
1278
- // lCalib = -37.4;
1279
- // this.componentGainDBSPL = -30;
1280
- // componentGainDBSPL = -30;
1281
-
1282
1183
  let volumeResults = await this.startCalibrationVolume(
1283
1184
  stream,
1284
1185
  gainValues,
@@ -1287,7 +1188,6 @@ class Combination extends AudioCalibrator {
1287
1188
  );
1288
1189
 
1289
1190
  let impulseResponseResults = await this.startCalibrationImpulseResponse(stream);
1290
- //TODO: if needed, insert componentIR into db
1291
1191
 
1292
1192
  if (componentIR != null) {
1293
1193
  //insert Freq and Gain from this.componentIR into db