speaker-calibration 2.2.7 → 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/dist/example/i18n.js +5803 -5743
- package/dist/example/listener.js +5 -1
- package/dist/main.js +2 -13
- package/package.json +1 -1
- package/src/tasks/combination/combination.js +90 -190
package/package.json
CHANGED
|
@@ -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
|
};
|
|
@@ -348,26 +346,17 @@ class Combination extends AudioCalibrator {
|
|
|
348
346
|
this.emit('update', {
|
|
349
347
|
message: this.status,
|
|
350
348
|
});
|
|
351
|
-
let time_to_wait =
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
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
|
-
`\niteration ${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
|
-
|
|
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 =
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
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
|
-
|
|
499
|
-
|
|
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
|
-
|
|
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
|
-
|
|
515
|
-
this.
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
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.
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
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
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
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.
|
|
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
|
-
|
|
696
|
-
|
|
697
|
-
()
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
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
|
-
|
|
747
|
-
|
|
748
|
-
()
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
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.#
|
|
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
|