speechrecorderng 3.10.13 → 3.11.0
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/README.md +1 -1
- package/fesm2022/speechrecorderng.mjs +204 -201
- package/fesm2022/speechrecorderng.mjs.map +1 -1
- package/lib/audio/ui/audio_canvas_layer_comp.d.ts +2 -2
- package/lib/spr.module.version.d.ts +1 -1
- package/lib/ui/canvas_layer_comp.d.ts +1 -1
- package/lib/ui/responsive_component.d.ts +1 -1
- package/package.json +13 -15
- package/esm2022/lib/action/action.mjs +0 -73
- package/esm2022/lib/audio/array_audio_buffer.mjs +0 -164
- package/esm2022/lib/audio/array_audio_buffer_input_stream.mjs +0 -86
- package/esm2022/lib/audio/array_audio_buffer_random_access_stream.mjs +0 -16
- package/esm2022/lib/audio/audio_data_holder.mjs +0 -264
- package/esm2022/lib/audio/audio_display.mjs +0 -118
- package/esm2022/lib/audio/audio_player.mjs +0 -238
- package/esm2022/lib/audio/capture/capture.mjs +0 -855
- package/esm2022/lib/audio/context.mjs +0 -79
- package/esm2022/lib/audio/dsp/level_measure.mjs +0 -517
- package/esm2022/lib/audio/format.mjs +0 -20
- package/esm2022/lib/audio/impl/wavformat.mjs +0 -7
- package/esm2022/lib/audio/impl/wavreader.mjs +0 -144
- package/esm2022/lib/audio/impl/wavwriter.mjs +0 -191
- package/esm2022/lib/audio/inddb_audio_buffer.mjs +0 -508
- package/esm2022/lib/audio/io/stream.mjs +0 -59
- package/esm2022/lib/audio/net_audio_buffer.mjs +0 -293
- package/esm2022/lib/audio/persistor.mjs +0 -81
- package/esm2022/lib/audio/playback/array_audio_buffer_source_node.mjs +0 -126
- package/esm2022/lib/audio/playback/audio_source_node.mjs +0 -18
- package/esm2022/lib/audio/playback/audio_source_worklet_module_loader.mjs +0 -167
- package/esm2022/lib/audio/playback/inddb_audio_buffer_source_node.mjs +0 -167
- package/esm2022/lib/audio/playback/net_audio_buffer_source_node.mjs +0 -218
- package/esm2022/lib/audio/playback/player.mjs +0 -402
- package/esm2022/lib/audio/ui/audio_canvas_layer_comp.mjs +0 -347
- package/esm2022/lib/audio/ui/audio_display_control.mjs +0 -150
- package/esm2022/lib/audio/ui/audio_display_scroll_pane.mjs +0 -146
- package/esm2022/lib/audio/ui/audiosignal.mjs +0 -533
- package/esm2022/lib/audio/ui/common.mjs +0 -19
- package/esm2022/lib/audio/ui/container.mjs +0 -414
- package/esm2022/lib/audio/ui/livelevel.mjs +0 -361
- package/esm2022/lib/audio/ui/scroll_pane_horizontal.mjs +0 -11
- package/esm2022/lib/audio/ui/sonagram.mjs +0 -900
- package/esm2022/lib/db/inddb.mjs +0 -120
- package/esm2022/lib/dsp/utils.mjs +0 -48
- package/esm2022/lib/environment/environment.defaults.mjs +0 -9
- package/esm2022/lib/io/BinaryReader.mjs +0 -93
- package/esm2022/lib/io/BinaryWriter.mjs +0 -80
- package/esm2022/lib/io/stream.mjs +0 -259
- package/esm2022/lib/math/2d/geometry.mjs +0 -28
- package/esm2022/lib/math/complex.mjs +0 -58
- package/esm2022/lib/math/dft.mjs +0 -196
- package/esm2022/lib/media/utils.mjs +0 -14
- package/esm2022/lib/net/uploader.mjs +0 -367
- package/esm2022/lib/recorder_component.mjs +0 -65
- package/esm2022/lib/speechrecorder/project/project.mjs +0 -54
- package/esm2022/lib/speechrecorder/project/project.service.mjs +0 -64
- package/esm2022/lib/speechrecorder/recording.mjs +0 -124
- package/esm2022/lib/speechrecorder/recordings/basic_recording.service.mjs +0 -221
- package/esm2022/lib/speechrecorder/recordings/recordings.service.mjs +0 -1014
- package/esm2022/lib/speechrecorder/script/script.mjs +0 -114
- package/esm2022/lib/speechrecorder/script/script.service.mjs +0 -47
- package/esm2022/lib/speechrecorder/session/audiorecorder.mjs +0 -1179
- package/esm2022/lib/speechrecorder/session/basicrecorder.mjs +0 -676
- package/esm2022/lib/speechrecorder/session/controlpanel.mjs +0 -416
- package/esm2022/lib/speechrecorder/session/item.mjs +0 -30
- package/esm2022/lib/speechrecorder/session/progress.mjs +0 -135
- package/esm2022/lib/speechrecorder/session/prompting.mjs +0 -639
- package/esm2022/lib/speechrecorder/session/recorder_combi_pane.mjs +0 -88
- package/esm2022/lib/speechrecorder/session/recording_file_cache.mjs +0 -195
- package/esm2022/lib/speechrecorder/session/recording_list.mjs +0 -188
- package/esm2022/lib/speechrecorder/session/recordingfile/recording-file-meta.component.mjs +0 -128
- package/esm2022/lib/speechrecorder/session/recordingfile/recording-file-navi.component.mjs +0 -114
- package/esm2022/lib/speechrecorder/session/recordingfile/recording-file-u-i.component.mjs +0 -146
- package/esm2022/lib/speechrecorder/session/recordingfile/recording-file-view.component.mjs +0 -424
- package/esm2022/lib/speechrecorder/session/recordingfile/recording-file.mjs +0 -68
- package/esm2022/lib/speechrecorder/session/recordingfile/recordingfile-service.mjs +0 -288
- package/esm2022/lib/speechrecorder/session/session.mjs +0 -2
- package/esm2022/lib/speechrecorder/session/session.service.mjs +0 -69
- package/esm2022/lib/speechrecorder/session/session_finished_dialog.mjs +0 -46
- package/esm2022/lib/speechrecorder/session/sessionmanager.mjs +0 -1385
- package/esm2022/lib/speechrecorder/session/warning_bar.mjs +0 -33
- package/esm2022/lib/speechrecorder/spruploader.mjs +0 -22
- package/esm2022/lib/speechrecorder/startstopsignal/startstopsignal.mjs +0 -2
- package/esm2022/lib/speechrecorder/startstopsignal/ui/simpletrafficlight.mjs +0 -57
- package/esm2022/lib/speechrecorderng.component.mjs +0 -392
- package/esm2022/lib/speechrecorderng.module.mjs +0 -97
- package/esm2022/lib/spr.config.mjs +0 -27
- package/esm2022/lib/spr.module.version.mjs +0 -2
- package/esm2022/lib/ui/canvas_layer_comp.mjs +0 -38
- package/esm2022/lib/ui/intersection-observer.directive.mjs +0 -32
- package/esm2022/lib/ui/message_dialog.mjs +0 -51
- package/esm2022/lib/ui/recordingitem_display.mjs +0 -253
- package/esm2022/lib/ui/responsive_component.mjs +0 -24
- package/esm2022/lib/utils/scrollIntoViewToBottom.mjs +0 -23
- package/esm2022/lib/utils/ua-parser.mjs +0 -190
- package/esm2022/lib/utils/utils.mjs +0 -132
- package/esm2022/lib/utils/wake_lock.mjs +0 -114
- package/esm2022/lib/utils/wake_lock_media.mjs +0 -2
- package/esm2022/public-api.mjs +0 -35
- package/esm2022/speechrecorderng.mjs +0 -5
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
export class WavFileFormat {
|
|
2
|
-
static { this.RIFF_KEY = 'RIFF'; }
|
|
3
|
-
static { this.WAV_KEY = 'WAVE'; }
|
|
4
|
-
static { this.PCM = 0x0001; }
|
|
5
|
-
static { this.WAVE_FORMAT_IEEE_FLOAT = 0x0003; }
|
|
6
|
-
}
|
|
7
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2F2Zm9ybWF0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc3BlZWNocmVjb3JkZXJuZy9zcmMvbGliL2F1ZGlvL2ltcGwvd2F2Zm9ybWF0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVFLE1BQU0sT0FBTyxhQUFhO2FBQ04sYUFBUSxHQUFVLE1BQU0sQ0FBQzthQUN6QixZQUFPLEdBQVUsTUFBTSxDQUFDO2FBQ3hCLFFBQUcsR0FBVyxNQUFNLENBQUM7YUFDckIsMkJBQXNCLEdBQVUsTUFBTSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiXHJcblxyXG4gIGV4cG9ydCBjbGFzcyBXYXZGaWxlRm9ybWF0IHtcclxuICAgICAgc3RhdGljIHJlYWRvbmx5IFJJRkZfS0VZOnN0cmluZyA9ICdSSUZGJztcclxuICAgICAgc3RhdGljIHJlYWRvbmx5IFdBVl9LRVk6c3RyaW5nID0gJ1dBVkUnO1xyXG4gICAgICBzdGF0aWMgcmVhZG9ubHkgUENNOm51bWJlciA9ICAweDAwMDE7XHJcbiAgICAgIHN0YXRpYyByZWFkb25seSBXQVZFX0ZPUk1BVF9JRUVFX0ZMT0FUOm51bWJlciA9IDB4MDAwMztcclxuICAgIH1cclxuXHJcblxyXG5cclxuXHJcbiJdfQ==
|
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
import { WavFileFormat } from './wavformat';
|
|
2
|
-
import { PCMAudioFormat } from '../format';
|
|
3
|
-
import { BinaryByteReader } from '../../io/BinaryReader';
|
|
4
|
-
export class WavReader {
|
|
5
|
-
constructor(data) {
|
|
6
|
-
this.format = null;
|
|
7
|
-
this.totalLength = 0;
|
|
8
|
-
this.dataChunkLength = null;
|
|
9
|
-
this.br = new BinaryByteReader(data);
|
|
10
|
-
}
|
|
11
|
-
readHeader() {
|
|
12
|
-
const rh = this.br.readAscii(4);
|
|
13
|
-
if (rh !== WavFileFormat.RIFF_KEY) {
|
|
14
|
-
const errMsg = "Expected RIFF header, not: " + rh;
|
|
15
|
-
throw new Error(errMsg);
|
|
16
|
-
}
|
|
17
|
-
const cl = this.br.readUint32LE();
|
|
18
|
-
if (this.br.pos + cl !== this.br.length()) {
|
|
19
|
-
throw new Error("Wrong chunksize in RIFF header: " + cl + " (expected: " + (this.br.length() - this.br.pos) + " )");
|
|
20
|
-
}
|
|
21
|
-
this.totalLength = cl;
|
|
22
|
-
const rt = this.br.readAscii(4);
|
|
23
|
-
if (rt !== WavFileFormat.WAV_KEY) {
|
|
24
|
-
const errMsg = "Expected " + WavFileFormat.WAV_KEY + " not: " + rt;
|
|
25
|
-
throw new Error(errMsg);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
readFormat() {
|
|
29
|
-
this.br.pos = 0;
|
|
30
|
-
this.readHeader();
|
|
31
|
-
const s = this.navigateToChunk('fmt ');
|
|
32
|
-
if (!s) {
|
|
33
|
-
let errMsg = "WAV file does not contain a fmt chunk";
|
|
34
|
-
throw new Error(errMsg);
|
|
35
|
-
}
|
|
36
|
-
this.format = this.parseFmtChunk();
|
|
37
|
-
return this.format;
|
|
38
|
-
}
|
|
39
|
-
_frameLength() {
|
|
40
|
-
let fl = null;
|
|
41
|
-
if (this.format && this.dataChunkLength != null) {
|
|
42
|
-
fl = this.dataChunkLength / this.format.channelCount / this.format.sampleSize;
|
|
43
|
-
}
|
|
44
|
-
return fl;
|
|
45
|
-
}
|
|
46
|
-
frameLength() {
|
|
47
|
-
let fl = this._frameLength();
|
|
48
|
-
if (fl === null) {
|
|
49
|
-
this.readFormat();
|
|
50
|
-
this.dataChunkLength = this.navigateToChunk('data');
|
|
51
|
-
fl = this._frameLength();
|
|
52
|
-
}
|
|
53
|
-
return fl;
|
|
54
|
-
}
|
|
55
|
-
// Not tested yet!!!
|
|
56
|
-
read() {
|
|
57
|
-
this.br.pos = 0;
|
|
58
|
-
let ab = null;
|
|
59
|
-
this.readHeader();
|
|
60
|
-
let s = this.navigateToChunk('fmt ');
|
|
61
|
-
if (!s) {
|
|
62
|
-
let errMsg = "WAV file does not contain a fmt chunk";
|
|
63
|
-
throw new Error(errMsg);
|
|
64
|
-
}
|
|
65
|
-
this.format = this.parseFmtChunk();
|
|
66
|
-
this.dataChunkLength = this.navigateToChunk('data');
|
|
67
|
-
let chsArr = this.readData();
|
|
68
|
-
let sr = this.format?.sampleRate;
|
|
69
|
-
let nChs = this.format?.channelCount;
|
|
70
|
-
if (sr && chsArr && nChs && nChs > 0 && nChs == chsArr?.length) {
|
|
71
|
-
ab = new AudioBuffer({
|
|
72
|
-
length: chsArr[0].length,
|
|
73
|
-
numberOfChannels: this.format?.channelCount,
|
|
74
|
-
sampleRate: sr
|
|
75
|
-
});
|
|
76
|
-
for (let ch = 0; ch < nChs; ch++) {
|
|
77
|
-
ab.copyToChannel(chsArr[ch], ch);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
return ab;
|
|
81
|
-
}
|
|
82
|
-
navigateToChunk(chunkString) {
|
|
83
|
-
// position after RIFF header
|
|
84
|
-
// TODO assumes no other chunks except 'data'
|
|
85
|
-
this.br.pos = 12;
|
|
86
|
-
let chkStr = null;
|
|
87
|
-
let chkLen = -1;
|
|
88
|
-
while (!this.br.eof()) {
|
|
89
|
-
chkStr = this.br.readAscii(4);
|
|
90
|
-
chkLen = this.br.readUint32LE();
|
|
91
|
-
if (chunkString === chkStr) {
|
|
92
|
-
return chkLen;
|
|
93
|
-
}
|
|
94
|
-
this.br.pos += chkLen;
|
|
95
|
-
}
|
|
96
|
-
return chkLen;
|
|
97
|
-
}
|
|
98
|
-
parseFmtChunk() {
|
|
99
|
-
let pcmAf = null;
|
|
100
|
-
const fmt = this.br.readUint16LE();
|
|
101
|
-
if (fmt === WavFileFormat.PCM || fmt == WavFileFormat.WAVE_FORMAT_IEEE_FLOAT) {
|
|
102
|
-
const channels = this.br.readUint16LE();
|
|
103
|
-
const sampleRate = this.br.readUint32LE();
|
|
104
|
-
// skip bandwidth
|
|
105
|
-
this.br.skip(4);
|
|
106
|
-
// frame size
|
|
107
|
-
const frameSize = this.br.readUint16LE();
|
|
108
|
-
// sample size in bits (PCM format only)
|
|
109
|
-
const sampleSizeInBits = this.br.readUint16LE();
|
|
110
|
-
pcmAf = new PCMAudioFormat(sampleRate, channels, frameSize / channels, sampleSizeInBits, (fmt === WavFileFormat.WAVE_FORMAT_IEEE_FLOAT));
|
|
111
|
-
}
|
|
112
|
-
return pcmAf;
|
|
113
|
-
}
|
|
114
|
-
readData() {
|
|
115
|
-
let chsArr = null;
|
|
116
|
-
if (this.format) {
|
|
117
|
-
chsArr = new Array(this.format.channelCount);
|
|
118
|
-
const sampleCount = this.totalLength / this.format.channelCount / this.format.sampleSize;
|
|
119
|
-
for (let ch = 0; ch < this.format.channelCount; ch++) {
|
|
120
|
-
chsArr[ch] = new Float32Array(sampleCount);
|
|
121
|
-
}
|
|
122
|
-
if (this.format.encodingFloat) {
|
|
123
|
-
// Not tested yet!
|
|
124
|
-
for (let i = 0; i < this.totalLength / 4; i++) {
|
|
125
|
-
for (let ch = 0; ch < this.format.channelCount; ch++) {
|
|
126
|
-
chsArr[ch][i] = this.br.readFloat32();
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
else {
|
|
131
|
-
if (this.format.sampleSize == 2) {
|
|
132
|
-
for (let i = 0; i < this.totalLength / 2; i++) {
|
|
133
|
-
for (let ch = 0; ch < this.format.channelCount; ch++) {
|
|
134
|
-
const s16Ampl = this.br.readInt16LE();
|
|
135
|
-
chsArr[ch][i] = s16Ampl / 32768;
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
return chsArr;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2F2cmVhZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc3BlZWNocmVjb3JkZXJuZy9zcmMvbGliL2F1ZGlvL2ltcGwvd2F2cmVhZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxhQUFhLENBQUE7QUFDM0MsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLFdBQVcsQ0FBQTtBQUMxQyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQTtBQUVwRCxNQUFNLE9BQU8sU0FBUztJQU9sQixZQUFZLElBQWdCO1FBSnBCLFdBQU0sR0FBdUIsSUFBSSxDQUFDO1FBQ2xDLGdCQUFXLEdBQVEsQ0FBQyxDQUFDO1FBQ3JCLG9CQUFlLEdBQWEsSUFBSSxDQUFDO1FBR3JDLElBQUksQ0FBQyxFQUFFLEdBQUcsSUFBSSxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBRU8sVUFBVTtRQUNkLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2hDLElBQUksRUFBRSxLQUFLLGFBQWEsQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUNoQyxNQUFNLE1BQU0sR0FBQyw2QkFBNkIsR0FBRSxFQUFFLENBQUM7WUFDL0MsTUFBTSxJQUFJLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUM1QixDQUFDO1FBQ0QsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUNsQyxJQUFJLElBQUksQ0FBQyxFQUFFLENBQUMsR0FBRyxHQUFHLEVBQUUsS0FBSyxJQUFJLENBQUMsRUFBRSxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUM7WUFDeEMsTUFBTSxJQUFJLEtBQUssQ0FBQyxrQ0FBa0MsR0FBQyxFQUFFLEdBQUMsY0FBYyxHQUFDLENB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QUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsT0FBTyxHQUFHLEtBQUssQ0FBQzt3QkFDbEMsQ0FBQztvQkFDSCxDQUFDO2dCQUNILENBQUM7WUFDSCxDQUFDO1FBQ0gsQ0FBQztRQUNELE9BQU8sTUFBTSxDQUFDO0lBQ2xCLENBQUM7Q0FDSiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFdhdkZpbGVGb3JtYXQgfSBmcm9tICcuL3dhdmZvcm1hdCdcclxuaW1wb3J0IHsgUENNQXVkaW9Gb3JtYXQgfSBmcm9tICcuLi9mb3JtYXQnXHJcbmltcG9ydCB7IEJpbmFyeUJ5dGVSZWFkZXIgfSBmcm9tICcuLi8uLi9pby9CaW5hcnlSZWFkZXInXHJcblxyXG4gICAgZXhwb3J0IGNsYXNzIFdhdlJlYWRlciB7XHJcblxyXG4gICAgICAgIHByaXZhdGUgYnI6QmluYXJ5Qnl0ZVJlYWRlcjtcclxuICAgICAgICBwcml2YXRlIGZvcm1hdDpQQ01BdWRpb0Zvcm1hdCB8IG51bGw9bnVsbDtcclxuICAgICAgICBwcml2YXRlIHRvdGFsTGVuZ3RoOm51bWJlcj0wO1xyXG4gICAgICAgIHByaXZhdGUgZGF0YUNodW5rTGVuZ3RoOm51bWJlcnxudWxsPW51bGw7XHJcblxyXG4gICAgICAgIGNvbnN0cnVjdG9yKGRhdGE6QXJyYXlCdWZmZXIpIHtcclxuICAgICAgICAgICAgdGhpcy5iciA9IG5ldyBCaW5hcnlCeXRlUmVhZGVyKGRhdGEpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcHJpdmF0ZSByZWFkSGVhZGVyKCl7XHJcbiAgICAgICAgICAgIGNvbnN0IHJoID0gdGhpcy5ici5yZWFkQXNjaWkoNCk7XHJcbiAgICAgICAgICAgIGlmIChyaCAhPT0gV2F2RmlsZUZvcm1hdC5SSUZGX0tFWSkge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgZXJyTXNnPVwiRXhwZWN0ZWQgUklGRiBoZWFkZXIsIG5vdDogXCIrIHJoO1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGVyck1zZyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY29uc3QgY2wgPSB0aGlzLmJyLnJlYWRVaW50MzJMRSgpO1xyXG4gICAgICAgICAgICBpZiAodGhpcy5ici5wb3MgKyBjbCAhPT0gdGhpcy5ici5sZW5ndGgoKSkge1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiV3JvbmcgY2h1bmtzaXplIGluIFJJRkYgaGVhZGVyOiBcIitjbCtcIiAoZXhwZWN0ZWQ6IFwiKyh0aGlzLmJyLmxlbmd0aCgpIC0gdGhpcy5ici5wb3MpKyBcIiApXCIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRoaXMudG90YWxMZW5ndGggPSBjbDtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IHJ0ID0gdGhpcy5ici5yZWFkQXNjaWkoNCk7XHJcbiAgICAgICAgICAgIGlmIChydCAhPT0gV2F2RmlsZUZvcm1hdC5XQVZfS0VZKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBlcnJNc2c9XCJFeHBlY3RlZCBcIitXYXZGaWxlRm9ybWF0LldBVl9LRVkrXCIgbm90OiBcIisgcnQ7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXJyTXNnKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmVhZEZvcm1hdCgpOlBDTUF1ZGlvRm9ybWF0fG51bGx7XHJcbiAgICAgICAgICAgIHRoaXMuYnIucG9zPTA7XHJcbiAgICAgICAgICAgIHRoaXMucmVhZEhlYWRlcigpO1xyXG4gICAgICAgICAgY29uc3QgcyA9IHRoaXMubmF2aWdhdGVUb0NodW5rKCdmbXQgJyk7XHJcbiAgICAgICAgICBpZiAoIXMpIHtcclxuICAgICAgICAgICAgbGV0IGVyck1zZz1cIldBViBmaWxlIGRvZXMgbm90IGNvbnRhaW4gYSBmbXQgY2h1bmtcIjtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGVyck1zZyk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRoaXMuZm9ybWF0ID0gdGhpcy5wYXJzZUZtdENodW5rKCk7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmZvcm1hdDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHByaXZhdGUgX2ZyYW1lTGVuZ3RoKCk6bnVtYmVyfG51bGx7XHJcbiAgICAgICAgICBsZXQgZmw6bnVtYmVyfG51bGw9bnVsbDtcclxuICAgICAgICAgIGlmKHRoaXMuZm9ybWF0ICYmIHRoaXMuZGF0YUNodW5rTGVuZ3RoIT1udWxsKSB7XHJcbiAgICAgICAgICAgIGZsID0gdGhpcy5kYXRhQ2h1bmtMZW5ndGggLyB0aGlzLmZvcm1hdC5jaGFubmVsQ291bnQgLyB0aGlzLmZvcm1hdC5zYW1wbGVTaXplO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgcmV0dXJuIGZsO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZnJhbWVMZW5ndGgoKTpudW1iZXJ8bnVsbCB7XHJcbiAgICAgICAgICBsZXQgZmw6bnVtYmVyfG51bGw9dGhpcy5fZnJhbWVMZW5ndGgoKTtcclxuICAgICAgICAgIGlmKGZsPT09bnVsbCl7XHJcbiAgICAgICAgICAgIHRoaXMucmVhZEZvcm1hdCgpO1xyXG4gICAgICAgICAgICB0aGlzLmRhdGFDaHVua0xlbmd0aD10aGlzLm5hdmlnYXRlVG9DaHVuaygnZGF0YScpO1xyXG4gICAgICAgICAgICBmbD10aGlzLl9mcmFtZUxlbmd0aCgpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgcmV0dXJuIGZsO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gTm90IHRlc3RlZCB5ZXQhISFcclxuICAgICAgICByZWFkKCk6QXVkaW9CdWZmZXIgfCBudWxse1xyXG4gICAgICAgICAgICB0aGlzLmJyLnBvcz0wO1xyXG4gICAgICAgICAgICBsZXQgYWI6QXVkaW9CdWZmZXJ8bnVsbD1udWxsO1xyXG4gICAgICAgICAgICB0aGlzLnJlYWRIZWFkZXIoKTtcclxuICAgICAgICAgICAgbGV0IHMgPSB0aGlzLm5hdmlnYXRlVG9DaHVuaygnZm10ICcpO1xyXG4gICAgICAgICAgICBpZiAoIXMpIHtcclxuICAgICAgICAgICAgICAgIGxldCBlcnJNc2c9XCJXQVYgZmlsZSBkb2VzIG5vdCBjb250YWluIGEgZm10IGNodW5rXCI7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXJyTXNnKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB0aGlzLmZvcm1hdCA9IHRoaXMucGFyc2VGbXRDaHVuaygpO1xyXG4gICAgICAgICAgICB0aGlzLmRhdGFDaHVua0xlbmd0aCA9IHRoaXMubmF2aWdhdGVUb0NodW5rKCdkYXRhJyk7XHJcbiAgICAgICAgICAgIGxldCBjaHNBcnIgPSB0aGlzLnJlYWREYXRhKCk7XHJcbiAgICAgICAgICAgIGxldCBzcj10aGlzLmZvcm1hdD8uc2FtcGxlUmF0ZTtcclxuICAgICAgICAgICAgbGV0IG5DaHM9dGhpcy5mb3JtYXQ/LmNoYW5uZWxDb3VudDtcclxuICAgICAgICAgICAgaWYoc3IgJiYgY2hzQXJyICYmIG5DaHMgJiYgbkNocz4wICYmIG5DaHM9PWNoc0Fycj8ubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgICAgICBhYiA9IG5ldyBBdWRpb0J1ZmZlcih7XHJcbiAgICAgICAgICAgICAgICAgICAgbGVuZ3RoOiBjaHNBcnJbMF0ubGVuZ3RoLFxyXG4gICAgICAgICAgICAgICAgICAgIG51bWJlck9mQ2hhbm5lbHM6IHRoaXMuZm9ybWF0Py5jaGFubmVsQ291bnQsXHJcbiAgICAgICAgICAgICAgICAgICAgc2FtcGxlUmF0ZTogc3JcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgZm9yKGxldCBjaD0wO2NoPG5DaHM7Y2grKykge1xyXG4gICAgICAgICAgICAgICAgICAgIGFiLmNvcHlUb0NoYW5uZWwoY2hzQXJyW2NoXSwgY2gpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiBhYjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHByaXZhdGUgbmF2aWdhdGVUb0NodW5rKGNodW5rU3RyaW5nOnN0cmluZyk6bnVtYmVyIHtcclxuICAgICAgICAgICAgLy8gcG9zaXRpb24gYWZ0ZXIgUklGRiBoZWFkZXJcclxuICAgICAgICAgIC8vIFRPRE8gYXNzdW1lcyBubyBvdGhlciBjaHVua3MgZXhjZXB0ICdkYXRhJ1xyXG4gICAgICAgICAgICB0aGlzLmJyLnBvcyA9IDEyO1xyXG4gICAgICAgICAgICBsZXQgY2hrU3RyID0gbnVsbDtcclxuICAgICAgICAgICAgbGV0IGNoa0xlbiA9IC0xO1xyXG4gICAgICAgICAgICB3aGlsZSAoIXRoaXMuYnIuZW9mKCkpIHtcclxuICAgICAgICAgICAgICAgIGNoa1N0ciA9IHRoaXMuYnIucmVhZEFzY2lpKDQpO1xyXG4gICAgICAgICAgICAgICAgY2hrTGVuID0gdGhpcy5ici5yZWFkVWludDMyTEUoKTtcclxuICAgICAgICAgICAgICAgIGlmIChjaHVua1N0cmluZyA9PT0gY2hrU3RyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNoa0xlbjtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHRoaXMuYnIucG9zICs9IGNoa0xlbjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gY2hrTGVuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcHJpdmF0ZSBwYXJzZUZtdENodW5rKCk6UENNQXVkaW9Gb3JtYXQgfCBudWxsIHtcclxuICAgICAgICAgICAgbGV0IHBjbUFmOlBDTUF1ZGlvRm9ybWF0fG51bGw9bnVsbDtcclxuICAgICAgICAgICAgY29uc3QgZm10ID0gdGhpcy5ici5yZWFkVWludDE2TEUoKTtcclxuICAgICAgICAgICAgaWYgKGZtdCA9PT0gV2F2RmlsZUZvcm1hdC5QQ00gfHwgZm10PT1XYXZGaWxlRm9ybWF0LldBVkVfRk9STUFUX0lFRUVfRkxPQVQpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGNoYW5uZWxzID0gdGhpcy5ici5yZWFkVWludDE2TEUoKTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHNhbXBsZVJhdGUgPSB0aGlzLmJyLnJlYWRVaW50MzJMRSgpO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vIHNraXAgYmFuZHdpZHRoXHJcbiAgICAgICAgICAgICAgICB0aGlzLmJyLnNraXAoNCk7XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gZnJhbWUgc2l6ZVxyXG4gICAgICAgICAgICAgICAgY29uc3QgZnJhbWVTaXplID0gdGhpcy5ici5yZWFkVWludDE2TEUoKTtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBzYW1wbGUgc2l6ZSBpbiBiaXRzIChQQ00gZm9ybWF0IG9ubHkpXHJcbiAgICAgICAgICAgICAgICBjb25zdCBzYW1wbGVTaXplSW5CaXRzID0gdGhpcy5ici5yZWFkVWludDE2TEUoKTtcclxuXHJcbiAgICAgICAgICAgICAgICBwY21BZj1uZXcgUENNQXVkaW9Gb3JtYXQoc2FtcGxlUmF0ZSwgY2hhbm5lbHMsIGZyYW1lU2l6ZSAvIGNoYW5uZWxzLCBzYW1wbGVTaXplSW5CaXRzLChmbXQ9PT1XYXZGaWxlRm9ybWF0LldBVkVfRk9STUFUX0lFRUVfRkxPQVQpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gcGNtQWY7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBwcml2YXRlIHJlYWREYXRhKCk6QXJyYXk8RmxvYXQzMkFycmF5PiB8IG51bGx7XHJcbiAgICAgICAgICAgIGxldCBjaHNBcnI9bnVsbDtcclxuICAgICAgICAgICAgaWYodGhpcy5mb3JtYXQpIHtcclxuICAgICAgICAgICAgICBjaHNBcnIgPSBuZXcgQXJyYXk8RmxvYXQzMkFycmF5Pih0aGlzLmZvcm1hdC5jaGFubmVsQ291bnQpO1xyXG4gICAgICAgICAgICAgIGNvbnN0IHNhbXBsZUNvdW50ID0gdGhpcy50b3RhbExlbmd0aCAvIHRoaXMuZm9ybWF0LmNoYW5uZWxDb3VudCAvIHRoaXMuZm9ybWF0LnNhbXBsZVNpemU7XHJcbiAgICAgICAgICAgICAgZm9yIChsZXQgY2ggPSAwOyBjaCA8IHRoaXMuZm9ybWF0LmNoYW5uZWxDb3VudDsgY2grKykge1xyXG4gICAgICAgICAgICAgICAgY2hzQXJyW2NoXSA9IG5ldyBGbG9hdDMyQXJyYXkoc2FtcGxlQ291bnQpO1xyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICBpZih0aGlzLmZvcm1hdC5lbmNvZGluZ0Zsb2F0KXtcclxuICAgICAgICAgICAgICAgIC8vIE5vdCB0ZXN0ZWQgeWV0IVxyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnRvdGFsTGVuZ3RoIC8gNDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgIGZvciAobGV0IGNoID0gMDsgY2ggPCB0aGlzLmZvcm1hdC5jaGFubmVsQ291bnQ7IGNoKyspIHtcclxuICAgICAgICAgICAgICAgICAgICBjaHNBcnJbY2hdW2ldPXRoaXMuYnIucmVhZEZsb2F0MzIoKTtcclxuICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIH1lbHNlIHtcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmZvcm1hdC5zYW1wbGVTaXplID09IDIpIHtcclxuICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnRvdGFsTGVuZ3RoIC8gMjsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgY2ggPSAwOyBjaCA8IHRoaXMuZm9ybWF0LmNoYW5uZWxDb3VudDsgY2grKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgY29uc3QgczE2QW1wbCA9IHRoaXMuYnIucmVhZEludDE2TEUoKTtcclxuICAgICAgICAgICAgICAgICAgICAgIGNoc0FycltjaF1baV0gPSBzMTZBbXBsIC8gMzI3Njg7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiBjaHNBcnI7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuXHJcblxyXG5cclxuIl19
|
|
@@ -1,191 +0,0 @@
|
|
|
1
|
-
import { WavFileFormat } from './wavformat';
|
|
2
|
-
import { BinaryByteWriter } from '../../io/BinaryWriter';
|
|
3
|
-
import { WorkerHelper } from "../../utils/utils";
|
|
4
|
-
export var SampleSize;
|
|
5
|
-
(function (SampleSize) {
|
|
6
|
-
SampleSize[SampleSize["INT16"] = 16] = "INT16";
|
|
7
|
-
SampleSize[SampleSize["INT32"] = 32] = "INT32";
|
|
8
|
-
})(SampleSize || (SampleSize = {}));
|
|
9
|
-
export class WavWriter {
|
|
10
|
-
static { this.DEFAULT_SAMPLE_SIZE = SampleSize.INT16; }
|
|
11
|
-
constructor(encodingFloat, sampleSize) {
|
|
12
|
-
this.sampleSizeInBytes = WavWriter.DEFAULT_SAMPLE_SIZE.valueOf() / 8;
|
|
13
|
-
this.encodingFloat = false;
|
|
14
|
-
this.sampleSize = WavWriter.DEFAULT_SAMPLE_SIZE;
|
|
15
|
-
this.sampleSizeInBits = this.sampleSize.valueOf();
|
|
16
|
-
this.workerURL = null;
|
|
17
|
-
//console.debug("WavWriter: "+encodingFloat+", "+sampleSize);
|
|
18
|
-
if (encodingFloat !== undefined && encodingFloat !== null) {
|
|
19
|
-
this.encodingFloat = encodingFloat;
|
|
20
|
-
if (encodingFloat === true) {
|
|
21
|
-
this.sampleSize = SampleSize.INT32;
|
|
22
|
-
}
|
|
23
|
-
else {
|
|
24
|
-
if (sampleSize) {
|
|
25
|
-
this.sampleSize = sampleSize;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
else if (sampleSize) {
|
|
30
|
-
this.sampleSize = sampleSize;
|
|
31
|
-
}
|
|
32
|
-
this.sampleSizeInBits = this.sampleSize.valueOf();
|
|
33
|
-
this.sampleSizeInBytes = Math.round(this.sampleSizeInBits / 8);
|
|
34
|
-
this.bw = new BinaryByteWriter();
|
|
35
|
-
}
|
|
36
|
-
/*
|
|
37
|
-
* Method used as worker code.
|
|
38
|
-
*/
|
|
39
|
-
workerFunction() {
|
|
40
|
-
self.onmessage = function (msg) {
|
|
41
|
-
const valView = new DataView(msg.data.buf, msg.data.bufPos);
|
|
42
|
-
const sampleSizeInbytes = Math.round(msg.data.sampleSizeInBits / 8);
|
|
43
|
-
let bufPos = 0;
|
|
44
|
-
const hDynIntRange = 1 << (msg.data.sampleSizeInBits - 1);
|
|
45
|
-
for (let s = 0; s < msg.data.frameLength; s++) {
|
|
46
|
-
// interleaved channel data
|
|
47
|
-
for (let ch = 0; ch < msg.data.chs; ch++) {
|
|
48
|
-
const srcPos = (ch * msg.data.frameLength) + s;
|
|
49
|
-
const valFlt = msg.data.audioData[srcPos];
|
|
50
|
-
if (msg.data.encodingFloat === true) {
|
|
51
|
-
valView.setFloat32(bufPos, valFlt, true);
|
|
52
|
-
bufPos += 4;
|
|
53
|
-
}
|
|
54
|
-
else {
|
|
55
|
-
const valInt = Math.round(valFlt * hDynIntRange);
|
|
56
|
-
if (msg.data.sampleSizeInBits === 32) {
|
|
57
|
-
valView.setInt32(bufPos, valInt, true);
|
|
58
|
-
}
|
|
59
|
-
else {
|
|
60
|
-
valView.setInt16(bufPos, valInt, true);
|
|
61
|
-
}
|
|
62
|
-
bufPos += sampleSizeInbytes;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
postMessage({ buf: msg.data.buf }, [msg.data.buf]);
|
|
67
|
-
//self.close()
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
writeFmtChunk(audioBuffer) {
|
|
71
|
-
if (this.encodingFloat === true) {
|
|
72
|
-
this.bw.writeUint16(WavFileFormat.WAVE_FORMAT_IEEE_FLOAT, true);
|
|
73
|
-
}
|
|
74
|
-
else {
|
|
75
|
-
this.bw.writeUint16(WavFileFormat.PCM, true);
|
|
76
|
-
}
|
|
77
|
-
const frameSize = this.sampleSizeInBytes * audioBuffer.numberOfChannels;
|
|
78
|
-
this.bw.writeUint16(audioBuffer.numberOfChannels, true);
|
|
79
|
-
this.bw.writeUint32(audioBuffer.sampleRate, true);
|
|
80
|
-
// dwAvgBytesPerSec
|
|
81
|
-
this.bw.writeUint32(frameSize * audioBuffer.sampleRate, true);
|
|
82
|
-
this.bw.writeUint16(frameSize, true);
|
|
83
|
-
// sample size in bits (PCM format only)
|
|
84
|
-
this.bw.writeUint16(this.sampleSizeInBits, true);
|
|
85
|
-
if (this.encodingFloat === true) {
|
|
86
|
-
this.bw.writeUint16(0, true);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
writeFactChunk(audioBuffer) {
|
|
90
|
-
const ch0 = audioBuffer.getChannelData(0);
|
|
91
|
-
let sampleLen = 0;
|
|
92
|
-
if (ch0) {
|
|
93
|
-
sampleLen = ch0.length;
|
|
94
|
-
}
|
|
95
|
-
this.bw.writeUint32(sampleLen, true);
|
|
96
|
-
}
|
|
97
|
-
writeDataChunk(audioBuffer) {
|
|
98
|
-
const chData0 = audioBuffer.getChannelData(0);
|
|
99
|
-
const dataLen = chData0.length;
|
|
100
|
-
if (this.encodingFloat === true) {
|
|
101
|
-
for (let s = 0; s < dataLen; s++) {
|
|
102
|
-
// interleaved channel data
|
|
103
|
-
for (let ch = 0; ch < audioBuffer.numberOfChannels; ch++) {
|
|
104
|
-
const chData = audioBuffer.getChannelData(ch);
|
|
105
|
-
const valFlt = chData[s];
|
|
106
|
-
this.bw.writeFloat(valFlt);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
else {
|
|
111
|
-
const hDynIntRange = 1 << ((this.sampleSizeInBits) - 1);
|
|
112
|
-
for (let s = 0; s < dataLen; s++) {
|
|
113
|
-
// interleaved channel data
|
|
114
|
-
for (let ch = 0; ch < audioBuffer.numberOfChannels; ch++) {
|
|
115
|
-
const chData = audioBuffer.getChannelData(ch);
|
|
116
|
-
const valFlt = chData[s];
|
|
117
|
-
const valInt = Math.round(valFlt * hDynIntRange);
|
|
118
|
-
if (this.sampleSize === SampleSize.INT16) {
|
|
119
|
-
this.bw.writeInt16(valInt, true);
|
|
120
|
-
}
|
|
121
|
-
else if (this.sampleSize === SampleSize.INT32) {
|
|
122
|
-
this.bw.writeInt32(valInt, true);
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
writeChunkHeader(name, chkLen) {
|
|
129
|
-
this.bw.writeAscii(name);
|
|
130
|
-
this.bw.writeUint32(chkLen, true);
|
|
131
|
-
}
|
|
132
|
-
writeAsync(audioBuffer, callback) {
|
|
133
|
-
const dataChkByteLen = this.writeHeader(audioBuffer);
|
|
134
|
-
if (!this.workerURL) {
|
|
135
|
-
this.workerURL = WorkerHelper.buildWorkerBlobURL(this.workerFunction);
|
|
136
|
-
}
|
|
137
|
-
const wo = new Worker(this.workerURL);
|
|
138
|
-
const chs = audioBuffer.numberOfChannels;
|
|
139
|
-
const frameLength = audioBuffer.getChannelData(0).length;
|
|
140
|
-
const ad = new Float32Array(chs * frameLength);
|
|
141
|
-
for (let ch = 0; ch < chs; ch++) {
|
|
142
|
-
ad.set(audioBuffer.getChannelData(ch), ch * frameLength);
|
|
143
|
-
}
|
|
144
|
-
// ensureCapacity blocks !!!
|
|
145
|
-
this.bw.ensureCapacity(dataChkByteLen);
|
|
146
|
-
wo.onmessage = (me) => {
|
|
147
|
-
callback(me.data.buf);
|
|
148
|
-
wo.terminate();
|
|
149
|
-
};
|
|
150
|
-
wo.postMessage({ encodingFloat: this.encodingFloat, sampleSizeInBits: this.sampleSizeInBits, chs: chs, frameLength: frameLength, audioData: ad, buf: this.bw.buf, bufPos: this.bw.pos }, [ad.buffer, this.bw.buf]);
|
|
151
|
-
}
|
|
152
|
-
write(audioBuffer) {
|
|
153
|
-
this.writeHeader(audioBuffer);
|
|
154
|
-
this.writeDataChunk(audioBuffer);
|
|
155
|
-
return this.bw.finish();
|
|
156
|
-
}
|
|
157
|
-
writeHeader(audioBuffer) {
|
|
158
|
-
this.bw.writeAscii(WavFileFormat.RIFF_KEY);
|
|
159
|
-
let dataChkByteLen = 0;
|
|
160
|
-
//const dataChkByteLen=audioBuffer.getChannelData(0).length*WavWriter.DEFAULT_SAMPLE_SIZE_BYTES*audioBuffer.numberOfChannels;
|
|
161
|
-
const abChs = audioBuffer.numberOfChannels;
|
|
162
|
-
if (abChs > 0) {
|
|
163
|
-
const abCh0 = audioBuffer.getChannelData(0);
|
|
164
|
-
dataChkByteLen = abCh0.length * this.sampleSizeInBytes * abChs;
|
|
165
|
-
}
|
|
166
|
-
let headerCnts = 3; //Wave,fmt and data
|
|
167
|
-
let fmtChunkSize = 16;
|
|
168
|
-
let factChunkSize = 4;
|
|
169
|
-
if (this.encodingFloat === true) {
|
|
170
|
-
fmtChunkSize = 18;
|
|
171
|
-
headerCnts++; // fact
|
|
172
|
-
} // Float encoding requires fmt extension (with zero length)
|
|
173
|
-
let wavChunkByteLen = (4 + 4) * headerCnts;
|
|
174
|
-
wavChunkByteLen += fmtChunkSize;
|
|
175
|
-
wavChunkByteLen += factChunkSize;
|
|
176
|
-
wavChunkByteLen += dataChkByteLen;
|
|
177
|
-
console.debug("Write WAV header: Wav chunk len: " + wavChunkByteLen);
|
|
178
|
-
this.bw.writeUint32(wavChunkByteLen, true); // must be set to file length-8 later
|
|
179
|
-
this.bw.writeAscii(WavFileFormat.WAV_KEY);
|
|
180
|
-
this.writeChunkHeader('fmt ', fmtChunkSize);
|
|
181
|
-
this.writeFmtChunk(audioBuffer);
|
|
182
|
-
if (this.encodingFloat === true) {
|
|
183
|
-
console.debug("Write WAV header: Write 'fact' chunk.");
|
|
184
|
-
this.writeChunkHeader('fact', 4);
|
|
185
|
-
this.writeFactChunk(audioBuffer);
|
|
186
|
-
}
|
|
187
|
-
this.writeChunkHeader('data', dataChkByteLen);
|
|
188
|
-
return dataChkByteLen;
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2F2d3JpdGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc3BlZWNocmVjb3JkZXJuZy9zcmMvbGliL2F1ZGlvL2ltcGwvd2F2d3JpdGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxhQUFhLENBQUE7QUFDM0MsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sdUJBQXVCLENBQUE7QUFDeEQsT0FBTyxFQUFDLFlBQVksRUFBQyxNQUFNLG1CQUFtQixDQUFDO0FBSS9DLE1BQU0sQ0FBTixJQUFZLFVBQThCO0FBQTFDLFdBQVksVUFBVTtJQUFFLDhDQUFRLENBQUE7SUFBQyw4Q0FBUSxDQUFBO0FBQUEsQ0FBQyxFQUE5QixVQUFVLEtBQVYsVUFBVSxRQUFvQjtBQUN2QyxNQUFNLE9BQU8sU0FBUzthQUVKLHdCQUFtQixHQUFjLFVBQVUsQ0FBQyxLQUFLLEFBQTlCLENBQStCO0lBUWxFLFlBQVksYUFBc0IsRUFBQyxVQUFzQjtRQVB4QyxzQkFBaUIsR0FBUSxTQUFTLENBQUMsbUJBQW1CLENBQUMsT0FBTyxFQUFFLEdBQUMsQ0FBQyxDQUFDO1FBQzVFLGtCQUFhLEdBQVMsS0FBSyxDQUFDO1FBQzVCLGVBQVUsR0FBQyxTQUFTLENBQUMsbUJBQW1CLENBQUM7UUFDekMscUJBQWdCLEdBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUUzQyxjQUFTLEdBQWMsSUFBSSxDQUFDO1FBR2xDLDZEQUE2RDtRQUM3RCxJQUFHLGFBQWEsS0FBRyxTQUFTLElBQUksYUFBYSxLQUFHLElBQUksRUFBQyxDQUFDO1lBQ3BELElBQUksQ0FBQyxhQUFhLEdBQUMsYUFBYSxDQUFDO1lBQ2pDLElBQUcsYUFBYSxLQUFHLElBQUksRUFBRSxDQUFDO2dCQUN4QixJQUFJLENBQUMsVUFBVSxHQUFHLFVBQVUsQ0FBQyxLQUFLLENBQUM7WUFDckMs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bUMsR0FBQyxlQUFlLENBQUMsQ0FBQztRQUNuRSxJQUFJLENBQUMsRUFBRSxDQUFDLFdBQVcsQ0FBQyxlQUFlLEVBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxxQ0FBcUM7UUFDaEYsSUFBSSxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRTFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLEVBQUMsWUFBWSxDQUFDLENBQUM7UUFDM0MsSUFBSSxDQUFDLGFBQWEsQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUNoQyxJQUFHLElBQUksQ0FBQyxhQUFhLEtBQUcsSUFBSSxFQUFDLENBQUM7WUFDNUIsT0FBTyxDQUFDLEtBQUssQ0FBQyx1Q0FBdUMsQ0FBQyxDQUFDO1lBQ3ZELElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLEVBQUMsQ0FBQyxDQUFDLENBQUM7WUFDaEMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUNuQyxDQUFDO1FBQ0QsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sRUFBQyxjQUFjLENBQUMsQ0FBQztRQUM3QyxPQUFPLGNBQWMsQ0FBQztJQUN4QixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgV2F2RmlsZUZvcm1hdCB9IGZyb20gJy4vd2F2Zm9ybWF0J1xyXG5pbXBvcnQgeyBCaW5hcnlCeXRlV3JpdGVyIH0gZnJvbSAnLi4vLi4vaW8vQmluYXJ5V3JpdGVyJ1xyXG5pbXBvcnQge1dvcmtlckhlbHBlcn0gZnJvbSBcIi4uLy4uL3V0aWxzL3V0aWxzXCI7XHJcbmRlY2xhcmUgZnVuY3Rpb24gcG9zdE1lc3NhZ2UgKG1lc3NhZ2U6YW55LCB0cmFuc2ZlcjpBcnJheTxhbnk+KTp2b2lkO1xyXG5cclxuXHJcbmV4cG9ydCBlbnVtIFNhbXBsZVNpemUge0lOVDE2PTE2LElOVDMyPTMyfVxyXG4gICBleHBvcnQgY2xhc3MgV2F2V3JpdGVyIHtcclxuXHJcbiAgICAgc3RhdGljIHJlYWRvbmx5IERFRkFVTFRfU0FNUExFX1NJWkU6U2FtcGxlU2l6ZSA9IFNhbXBsZVNpemUuSU5UMTY7XHJcbiAgICAgcHJpdmF0ZSByZWFkb25seSBzYW1wbGVTaXplSW5CeXRlczpudW1iZXI9V2F2V3JpdGVyLkRFRkFVTFRfU0FNUExFX1NJWkUudmFsdWVPZigpLzg7XHJcbiAgICAgcHJpdmF0ZSBlbmNvZGluZ0Zsb2F0OmJvb2xlYW49ZmFsc2U7XHJcbiAgICAgcHJpdmF0ZSBzYW1wbGVTaXplPVdhdldyaXRlci5ERUZBVUxUX1NBTVBMRV9TSVpFO1xyXG4gICAgIHByaXZhdGUgc2FtcGxlU2l6ZUluQml0cz10aGlzLnNhbXBsZVNpemUudmFsdWVPZigpO1xyXG4gICAgIHByaXZhdGUgYnc6QmluYXJ5Qnl0ZVdyaXRlcjtcclxuICAgICBwcml2YXRlIHdvcmtlclVSTDogc3RyaW5nfG51bGw9bnVsbDtcclxuXHJcbiAgICAgY29uc3RydWN0b3IoZW5jb2RpbmdGbG9hdD86Ym9vbGVhbixzYW1wbGVTaXplPzpTYW1wbGVTaXplKSB7XHJcbiAgICAgICAvL2NvbnNvbGUuZGVidWcoXCJXYXZXcml0ZXI6IFwiK2VuY29kaW5nRmxvYXQrXCIsIFwiK3NhbXBsZVNpemUpO1xyXG4gICAgICAgaWYoZW5jb2RpbmdGbG9hdCE9PXVuZGVmaW5lZCAmJiBlbmNvZGluZ0Zsb2F0IT09bnVsbCl7XHJcbiAgICAgICAgIHRoaXMuZW5jb2RpbmdGbG9hdD1lbmNvZGluZ0Zsb2F0O1xyXG4gICAgICAgICBpZihlbmNvZGluZ0Zsb2F0PT09dHJ1ZSkge1xyXG4gICAgICAgICAgIHRoaXMuc2FtcGxlU2l6ZSA9IFNhbXBsZVNpemUuSU5UMzI7XHJcbiAgICAgICAgIH1lbHNle1xyXG4gICAgICAgICAgIGlmKHNhbXBsZVNpemUpIHtcclxuICAgICAgICAgICAgIHRoaXMuc2FtcGxlU2l6ZSA9IHNhbXBsZVNpemU7XHJcbiAgICAgICAgICAgfVxyXG4gICAgICAgICB9XHJcbiAgICAgICB9ZWxzZSBpZihzYW1wbGVTaXplKXtcclxuICAgICAgICAgdGhpcy5zYW1wbGVTaXplPXNhbXBsZVNpemU7XHJcbiAgICAgICB9XHJcbiAgICAgICB0aGlzLnNhbXBsZVNpemVJbkJpdHM9dGhpcy5zYW1wbGVTaXplLnZhbHVlT2YoKTtcclxuICAgICAgIHRoaXMuc2FtcGxlU2l6ZUluQnl0ZXM9TWF0aC5yb3VuZCh0aGlzLnNhbXBsZVNpemVJbkJpdHMvOCk7XHJcblxyXG4gICAgICAgdGhpcy5idyA9IG5ldyBCaW5hcnlCeXRlV3JpdGVyKCk7XHJcbiAgICAgfVxyXG5cclxuICAgICAvKlxyXG4gICAgICAqICBNZXRob2QgdXNlZCBhcyB3b3JrZXIgY29kZS5cclxuICAgICAgKi9cclxuICAgICB3b3JrZXJGdW5jdGlvbigpIHtcclxuICAgICAgIHNlbGYub25tZXNzYWdlID0gZnVuY3Rpb24gKG1zZzpNZXNzYWdlRXZlbnQpIHtcclxuXHJcbiAgICAgICAgIGNvbnN0IHZhbFZpZXcgPSBuZXcgRGF0YVZpZXcobXNnLmRhdGEuYnVmLG1zZy5kYXRhLmJ1ZlBvcyk7XHJcbiAgICAgICAgIGNvbnN0IHNhbXBsZVNpemVJbmJ5dGVzPU1hdGgucm91bmQobXNnLmRhdGEuc2FtcGxlU2l6ZUluQml0cy84KTtcclxuICAgICAgICAgbGV0IGJ1ZlBvcyA9IDA7XHJcbiAgICAgICAgIGNvbnN0IGhEeW5JbnRSYW5nZSA9IDEgPDwgKG1zZy5kYXRhLnNhbXBsZVNpemVJbkJpdHMgLSAxKTtcclxuICAgICAgICAgZm9yIChsZXQgcyA9IDA7IHMgPCBtc2cuZGF0YS5mcmFtZUxlbmd0aDsgcysrKSB7XHJcbiAgICAgICAgICAgLy8gaW50ZXJsZWF2ZWQgY2hhbm5lbCBkYXRhXHJcblxyXG4gICAgICAgICAgIGZvciAobGV0IGNoID0gMDsgY2ggPCBtc2cuZGF0YS5jaHM7IGNoKyspIHtcclxuICAgICAgICAgICAgIGNvbnN0IHNyY1Bvcz0oY2gqbXNnLmRhdGEuZnJhbWVMZW5ndGgpK3M7XHJcbiAgICAgICAgICAgICBjb25zdCB2YWxGbHQgPSBtc2cuZGF0YS5hdWRpb0RhdGFbc3JjUG9zXTtcclxuICAgICAgICAgICAgIGlmKG1zZy5kYXRhLmVuY29kaW5nRmxvYXQ9PT10cnVlKXtcclxuICAgICAgICAgICAgICAgdmFsVmlldy5zZXRGbG9hdDMyKGJ1ZlBvcyx2YWxGbHQsdHJ1ZSk7XHJcbiAgICAgICAgICAgICAgIGJ1ZlBvcys9NDtcclxuICAgICAgICAgICAgIH1lbHNlIHtcclxuICAgICAgICAgICAgICAgY29uc3QgdmFsSW50ID0gTWF0aC5yb3VuZCh2YWxGbHQgKiBoRHluSW50UmFuZ2UpO1xyXG4gICAgICAgICAgICAgICBpZiAobXNnLmRhdGEuc2FtcGxlU2l6ZUluQml0cyA9PT0gMzIpIHtcclxuICAgICAgICAgICAgICAgICB2YWxWaWV3LnNldEludDMyKGJ1ZlBvcywgdmFsSW50LCB0cnVlKTtcclxuICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICB2YWxWaWV3LnNldEludDE2KGJ1ZlBvcywgdmFsSW50LCB0cnVlKTtcclxuICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICBidWZQb3MrPXNhbXBsZVNpemVJbmJ5dGVzO1xyXG4gICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICB9XHJcbiAgICAgICAgIH1cclxuICAgICAgICAgcG9zdE1lc3NhZ2Uoe2J1Zjptc2cuZGF0YS5idWZ9LCBbbXNnLmRhdGEuYnVmXSk7XHJcbiAgICAgICAgIC8vc2VsZi5jbG9zZSgpXHJcbiAgICAgICB9XHJcbiAgICAgfVxyXG5cclxuXHJcbiAgICAgd3JpdGVGbXRDaHVuayhhdWRpb0J1ZmZlcjpBdWRpb0J1ZmZlcil7XHJcblxyXG4gICAgICAgaWYodGhpcy5lbmNvZGluZ0Zsb2F0PT09dHJ1ZSl7XHJcbiAgICAgICAgIHRoaXMuYncud3JpdGVVaW50MTYoV2F2RmlsZUZvcm1hdC5XQVZFX0ZPUk1BVF9JRUVFX0ZMT0FULCB0cnVlKTtcclxuICAgICAgIH1lbHNlIHtcclxuICAgICAgICAgdGhpcy5idy53cml0ZVVpbnQxNihXYXZGaWxlRm9ybWF0LlBDTSwgdHJ1ZSk7XHJcbiAgICAgICB9XHJcbiAgICAgICBjb25zdCBmcmFtZVNpemU9dGhpcy5zYW1wbGVTaXplSW5CeXRlcyphdWRpb0J1ZmZlci5udW1iZXJPZkNoYW5uZWxzO1xyXG4gICAgICAgdGhpcy5idy53cml0ZVVpbnQxNihhdWRpb0J1ZmZlci5udW1iZXJPZkNoYW5uZWxzLHRydWUpO1xyXG4gICAgICAgdGhpcy5idy53cml0ZVVpbnQzMihhdWRpb0J1ZmZlci5zYW1wbGVSYXRlLHRydWUpO1xyXG4gICAgICAgICAvLyBkd0F2Z0J5dGVzUGVyU2VjXHJcbiAgICAgICB0aGlzLmJ3LndyaXRlVWludDMyKGZyYW1lU2l6ZSphdWRpb0J1ZmZlci5zYW1wbGVSYXRlLHRydWUpO1xyXG4gICAgICAgdGhpcy5idy53cml0ZVVpbnQxNihmcmFtZVNpemUsdHJ1ZSk7XHJcbiAgICAgICAvLyBzYW1wbGUgc2l6ZSBpbiBiaXRzIChQQ00gZm9ybWF0IG9ubHkpXHJcbiAgICAgICB0aGlzLmJ3LndyaXRlVWludDE2KHRoaXMuc2FtcGxlU2l6ZUluQml0cyx0cnVlKTtcclxuICAgICAgIGlmKHRoaXMuZW5jb2RpbmdGbG9hdD09PXRydWUpe1xyXG4gICAgICAgICB0aGlzLmJ3LndyaXRlVWludDE2KDAsdHJ1ZSk7XHJcbiAgICAgICB9XHJcbiAgICAgfVxyXG5cclxuICAgICB3cml0ZUZhY3RDaHVuayhhdWRpb0J1ZmZlcjpBdWRpb0J1ZmZlcil7XHJcbiAgICAgICBjb25zdCBjaDA9YXVkaW9CdWZmZXIuZ2V0Q2hhbm5lbERhdGEoMCk7XHJcbiAgICAgICBsZXQgc2FtcGxlTGVuPTA7XHJcbiAgICAgICBpZihjaDApe1xyXG4gICAgICAgICBzYW1wbGVMZW49Y2gwLmxlbmd0aDtcclxuICAgICAgIH1cclxuICAgICAgICB0aGlzLmJ3LndyaXRlVWludDMyKHNhbXBsZUxlbix0cnVlKTtcclxuICAgICB9XHJcblxyXG4gICAgIHdyaXRlRGF0YUNodW5rKGF1ZGlvQnVmZmVyOkF1ZGlvQnVmZmVyKXtcclxuXHJcbiAgICAgICBjb25zdCBjaERhdGEwPWF1ZGlvQnVmZmVyLmdldENoYW5uZWxEYXRhKDApO1xyXG4gICAgICAgY29uc3QgZGF0YUxlbj1jaERhdGEwLmxlbmd0aDtcclxuICAgICAgIGlmKHRoaXMuZW5jb2RpbmdGbG9hdD09PXRydWUpe1xyXG4gICAgICAgICBmb3IgKGxldCBzID0gMDsgcyA8IGRhdGFMZW47IHMrKykge1xyXG4gICAgICAgICAgIC8vIGludGVybGVhdmVkIGNoYW5uZWwgZGF0YVxyXG4gICAgICAgICAgIGZvciAobGV0IGNoID0gMDsgY2ggPCBhdWRpb0J1ZmZlci5udW1iZXJPZkNoYW5uZWxzOyBjaCsrKSB7XHJcbiAgICAgICAgICAgICBjb25zdCBjaERhdGEgPSBhdWRpb0J1ZmZlci5nZXRDaGFubmVsRGF0YShjaCk7XHJcbiAgICAgICAgICAgICBjb25zdCB2YWxGbHQgPSBjaERhdGFbc107XHJcbiAgICAgICAgICAgICB0aGlzLmJ3LndyaXRlRmxvYXQodmFsRmx0KTtcclxuICAgICAgICAgICB9XHJcbiAgICAgICAgIH1cclxuICAgICAgIH1lbHNlIHtcclxuICAgICAgICAgY29uc3QgaER5bkludFJhbmdlID0gMSA8PCAoKHRoaXMuc2FtcGxlU2l6ZUluQml0cykgLSAxKTtcclxuICAgICAgICAgZm9yIChsZXQgcyA9IDA7IHMgPCBkYXRhTGVuOyBzKyspIHtcclxuICAgICAgICAgICAvLyBpbnRlcmxlYXZlZCBjaGFubmVsIGRhdGFcclxuICAgICAgICAgICBmb3IgKGxldCBjaCA9IDA7IGNoIDwgYXVkaW9CdWZmZXIubnVtYmVyT2ZDaGFubmVsczsgY2grKykge1xyXG4gICAgICAgICAgICAgY29uc3QgY2hEYXRhID0gYXVkaW9CdWZmZXIuZ2V0Q2hhbm5lbERhdGEoY2gpO1xyXG4gICAgICAgICAgICAgY29uc3QgdmFsRmx0ID0gY2hEYXRhW3NdO1xyXG4gICAgICAgICAgICAgY29uc3QgdmFsSW50ID0gTWF0aC5yb3VuZCh2YWxGbHQgKiBoRHluSW50UmFuZ2UpO1xyXG4gICAgICAgICAgICAgaWYgKHRoaXMuc2FtcGxlU2l6ZSA9PT0gU2FtcGxlU2l6ZS5JTlQxNikge1xyXG4gICAgICAgICAgICAgICB0aGlzLmJ3LndyaXRlSW50MTYodmFsSW50LCB0cnVlKTtcclxuICAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5zYW1wbGVTaXplID09PSBTYW1wbGVTaXplLklOVDMyKSB7XHJcbiAgICAgICAgICAgICAgIHRoaXMuYncud3JpdGVJbnQzMih2YWxJbnQsIHRydWUpO1xyXG4gICAgICAgICAgICAgfVxyXG4gICAgICAgICAgIH1cclxuICAgICAgICAgfVxyXG4gICAgICAgfVxyXG5cclxuICAgICB9XHJcblxyXG4gICAgIHdyaXRlQ2h1bmtIZWFkZXIobmFtZTpzdHJpbmcsY2hrTGVuOm51bWJlcil7XHJcbiAgICAgICB0aGlzLmJ3LndyaXRlQXNjaWkobmFtZSk7XHJcbiAgICAgICB0aGlzLmJ3LndyaXRlVWludDMyKGNoa0xlbix0cnVlKTtcclxuICAgICB9XHJcblxyXG4gICAgIHdyaXRlQXN5bmMoYXVkaW9CdWZmZXI6QXVkaW9CdWZmZXIsY2FsbGJhY2s6ICh3YXZGaWxlRGF0YTpVaW50OEFycmF5KT0+IGFueSl7XHJcblxyXG4gICAgICAgY29uc3QgZGF0YUNoa0J5dGVMZW49dGhpcy53cml0ZUhlYWRlcihhdWRpb0J1ZmZlcik7XHJcbiAgICAgICBpZiAoIXRoaXMud29ya2VyVVJMKSB7XHJcbiAgICAgICAgIHRoaXMud29ya2VyVVJMID0gV29ya2VySGVscGVyLmJ1aWxkV29ya2VyQmxvYlVSTCh0aGlzLndvcmtlckZ1bmN0aW9uKVxyXG4gICAgICAgIH1cclxuICAgICAgIGNvbnN0IHdvID0gbmV3IFdvcmtlcih0aGlzLndvcmtlclVSTCk7XHJcblxyXG4gICAgICAgY29uc3QgY2hzID0gYXVkaW9CdWZmZXIubnVtYmVyT2ZDaGFubmVscztcclxuXHJcbiAgICAgICBjb25zdCBmcmFtZUxlbmd0aCA9IGF1ZGlvQnVmZmVyLmdldENoYW5uZWxEYXRhKDApLmxlbmd0aDtcclxuICAgICAgIGNvbnN0IGFkID0gbmV3IEZsb2F0MzJBcnJheShjaHMgKiBmcmFtZUxlbmd0aCk7XHJcbiAgICAgICBmb3IgKGxldCBjaCA9IDA7IGNoIDwgY2hzOyBjaCsrKSB7XHJcbiAgICAgICAgIGFkLnNldChhdWRpb0J1ZmZlci5nZXRDaGFubmVsRGF0YShjaCksIGNoICogZnJhbWVMZW5ndGgpO1xyXG4gICAgICAgfVxyXG4gICAgICAgICAvLyBlbnN1cmVDYXBhY2l0eSBibG9ja3MgISEhXHJcbiAgICAgICB0aGlzLmJ3LmVuc3VyZUNhcGFjaXR5KGRhdGFDaGtCeXRlTGVuKTtcclxuICAgICAgIHdvLm9ubWVzc2FnZSA9IChtZSkgPT4ge1xyXG4gICAgICAgICBjYWxsYmFjayhtZS5kYXRhLmJ1Zik7XHJcbiAgICAgICAgIHdvLnRlcm1pbmF0ZSgpO1xyXG4gICAgICAgfVxyXG5cclxuXHJcbiAgICAgICB3by5wb3N0TWVzc2FnZSh7ZW5jb2RpbmdGbG9hdDp0aGlzLmVuY29kaW5nRmxvYXQsc2FtcGxlU2l6ZUluQml0czp0aGlzLnNhbXBsZVNpemVJbkJpdHMsIGNoczogY2hzLCBmcmFtZUxlbmd0aDogZnJhbWVMZW5ndGgsIGF1ZGlvRGF0YTogYWQsYnVmOnRoaXMuYncuYnVmLGJ1ZlBvczp0aGlzLmJ3LnBvc30sIFthZC5idWZmZXIsdGhpcy5idy5idWZdKTtcclxuXHJcbiAgICAgfVxyXG5cclxuICAgICB3cml0ZShhdWRpb0J1ZmZlcjpBdWRpb0J1ZmZlcik6VWludDhBcnJheXtcclxuICAgICAgIHRoaXMud3JpdGVIZWFkZXIoYXVkaW9CdWZmZXIpO1xyXG4gICAgICAgdGhpcy53cml0ZURhdGFDaHVuayhhdWRpb0J1ZmZlcik7XHJcbiAgICAgICByZXR1cm4gdGhpcy5idy5maW5pc2goKTtcclxuICAgICB9XHJcblxyXG5cclxuICAgICAgd3JpdGVIZWFkZXIoYXVkaW9CdWZmZXI6QXVkaW9CdWZmZXIpOm51bWJlcntcclxuICAgICAgICB0aGlzLmJ3LndyaXRlQXNjaWkoV2F2RmlsZUZvcm1hdC5SSUZGX0tFWSk7XHJcbiAgICAgICAgbGV0IGRhdGFDaGtCeXRlTGVuPTA7XHJcbiAgICAgICAgLy9jb25zdCBkYXRhQ2hrQnl0ZUxlbj1hdWRpb0J1ZmZlci5nZXRDaGFubmVsRGF0YSgwKS5sZW5ndGgqV2F2V3JpdGVyLkRFRkFVTFRfU0FNUExFX1NJWkVfQllURVMqYXVkaW9CdWZmZXIubnVtYmVyT2ZDaGFubmVscztcclxuICAgICAgICBjb25zdCBhYkNocz1hdWRpb0J1ZmZlci5udW1iZXJPZkNoYW5uZWxzO1xyXG4gICAgICAgIGlmKGFiQ2hzPjApe1xyXG4gICAgICAgICAgY29uc3QgYWJDaDA9YXVkaW9CdWZmZXIuZ2V0Q2hhbm5lbERhdGEoMCk7XHJcbiAgICAgICAgICBkYXRhQ2hrQnl0ZUxlbj1hYkNoMC5sZW5ndGgqdGhpcy5zYW1wbGVTaXplSW5CeXRlcyphYkNocztcclxuICAgICAgICB9XHJcbiAgICAgICAgbGV0IGhlYWRlckNudHM9MzsgLy9XYXZlLGZtdCBhbmQgZGF0YVxyXG5cclxuICAgICAgICBsZXQgZm10Q2h1bmtTaXplPTE2O1xyXG4gICAgICAgIGxldCBmYWN0Q2h1bmtTaXplPTQ7XHJcbiAgICAgICAgaWYodGhpcy5lbmNvZGluZ0Zsb2F0PT09dHJ1ZSl7XHJcbiAgICAgICAgICBmbXRDaHVua1NpemU9MTg7XHJcbiAgICAgICAgICBoZWFkZXJDbnRzKys7IC8vIGZhY3RcclxuICAgICAgICB9Ly8gRmxvYXQgZW5jb2RpbmcgcmVxdWlyZXMgZm10IGV4dGVuc2lvbiAod2l0aCB6ZXJvIGxlbmd0aClcclxuICAgICAgICBsZXQgd2F2Q2h1bmtCeXRlTGVuPSg0KzQpKmhlYWRlckNudHM7XHJcblxyXG4gICAgICAgIHdhdkNodW5rQnl0ZUxlbis9Zm10Q2h1bmtTaXplO1xyXG4gICAgICAgIHdhdkNodW5rQnl0ZUxlbis9ZmFjdENodW5rU2l6ZTtcclxuICAgICAgICB3YXZDaHVua0J5dGVMZW4rPWRhdGFDaGtCeXRlTGVuO1xyXG5cclxuICAgICAgICBjb25zb2xlLmRlYnVnKFwiV3JpdGUgV0FWIGhlYWRlcjogV2F2IGNodW5rIGxlbjogXCIrd2F2Q2h1bmtCeXRlTGVuKTtcclxuICAgICAgICB0aGlzLmJ3LndyaXRlVWludDMyKHdhdkNodW5rQnl0ZUxlbix0cnVlKTsgLy8gbXVzdCBiZSBzZXQgdG8gZmlsZSBsZW5ndGgtOCBsYXRlclxyXG4gICAgICAgIHRoaXMuYncud3JpdGVBc2NpaShXYXZGaWxlRm9ybWF0LldBVl9LRVkpO1xyXG5cclxuICAgICAgICB0aGlzLndyaXRlQ2h1bmtIZWFkZXIoJ2ZtdCAnLGZtdENodW5rU2l6ZSk7XHJcbiAgICAgICAgdGhpcy53cml0ZUZtdENodW5rKGF1ZGlvQnVmZmVyKTtcclxuICAgICAgICBpZih0aGlzLmVuY29kaW5nRmxvYXQ9PT10cnVlKXtcclxuICAgICAgICAgIGNvbnNvbGUuZGVidWcoXCJXcml0ZSBXQVYgaGVhZGVyOiBXcml0ZSAnZmFjdCcgY2h1bmsuXCIpO1xyXG4gICAgICAgICAgdGhpcy53cml0ZUNodW5rSGVhZGVyKCdmYWN0Jyw0KTtcclxuICAgICAgICAgIHRoaXMud3JpdGVGYWN0Q2h1bmsoYXVkaW9CdWZmZXIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLndyaXRlQ2h1bmtIZWFkZXIoJ2RhdGEnLGRhdGFDaGtCeXRlTGVuKTtcclxuICAgICAgICByZXR1cm4gZGF0YUNoa0J5dGVMZW47XHJcbiAgICAgIH1cclxuXHJcbiAgIH1cclxuXHJcblxyXG5cclxuIl19
|