agdi 3.3.6 → 3.3.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.
Files changed (36) hide show
  1. package/README.md +13 -0
  2. package/dist/APEv2Parser-EU45AV6X.js +14 -0
  3. package/dist/AiffParser-FOX7GQ42.js +189 -0
  4. package/dist/AsfParser-HD5CSGIO.js +610 -0
  5. package/dist/DsdiffParser-OJREDMBI.js +188 -0
  6. package/dist/DsfParser-2YL4ARJ7.js +110 -0
  7. package/dist/FlacParser-IVV4RYF6.js +15 -0
  8. package/dist/MP4Parser-NLX4A2YN.js +1140 -0
  9. package/dist/MatroskaParser-4OEK43GF.js +654 -0
  10. package/dist/MpegParser-PXKEUF2B.js +642 -0
  11. package/dist/MusepackParser-54QGYRLY.js +322 -0
  12. package/dist/OggParser-KRV5QCGZ.js +435 -0
  13. package/dist/WavPackParser-XPZSQFVS.js +203 -0
  14. package/dist/WaveParser-27IS2RAI.js +294 -0
  15. package/dist/chunk-2B4QMSZW.js +311 -0
  16. package/dist/chunk-3JKZUGPJ.js +70 -0
  17. package/dist/chunk-4VNS5WPM.js +42 -0
  18. package/dist/chunk-65JVFJ3X.js +729 -0
  19. package/dist/chunk-6OKLAJRQ.js +0 -0
  20. package/dist/chunk-AGSFUVRG.js +439 -0
  21. package/dist/chunk-GD35BJSH.js +177 -0
  22. package/dist/chunk-HNLU36CC.js +702 -0
  23. package/dist/{chunk-M2FF7ETI.js → chunk-J6OLLWVT.js} +1 -1
  24. package/dist/chunk-LREP5CZP.js +146 -0
  25. package/dist/chunk-M54HVABG.js +34 -0
  26. package/dist/{chunk-S45VXJEO.js → chunk-OPFFFAQC.js} +19 -1
  27. package/dist/chunk-VGOIHW7D.js +1529 -0
  28. package/dist/chunk-YIHDW7JC.js +314 -0
  29. package/dist/config-D3QBUN2Y.js +13 -0
  30. package/dist/{config-ZFU7TSU2.js → config-K2XM6D4Z.js} +3 -2
  31. package/dist/{event-bus-Q3WCETQQ.js → event-bus-MO5SFUME.js} +1 -0
  32. package/dist/index.js +3966 -1203
  33. package/dist/lib-2XISBYT3.js +144950 -0
  34. package/dist/lib-HCGLI2GJ.js +4161 -0
  35. package/dist/{telemetry-service-OHU5NKON.js → telemetry-service-76YPOPDM.js} +8 -4
  36. package/package.json +5 -2
@@ -0,0 +1,435 @@
1
+ import {
2
+ BlockHeader,
3
+ BlockStreamInfo,
4
+ BlockType,
5
+ FlacParser,
6
+ VorbisPictureToken,
7
+ VorbisStream
8
+ } from "./chunk-AGSFUVRG.js";
9
+ import "./chunk-3JKZUGPJ.js";
10
+ import "./chunk-65JVFJ3X.js";
11
+ import "./chunk-2B4QMSZW.js";
12
+ import {
13
+ FourCcToken
14
+ } from "./chunk-YIHDW7JC.js";
15
+ import {
16
+ EndOfStreamError
17
+ } from "./chunk-HNLU36CC.js";
18
+ import "./chunk-LREP5CZP.js";
19
+ import {
20
+ getBit,
21
+ trimRightNull
22
+ } from "./chunk-GD35BJSH.js";
23
+ import {
24
+ BasicParser,
25
+ INT32_LE,
26
+ StringType,
27
+ UINT16_BE,
28
+ UINT16_LE,
29
+ UINT24_BE,
30
+ UINT32_LE,
31
+ UINT64_LE,
32
+ UINT8,
33
+ Uint8ArrayType,
34
+ makeUnexpectedFileContentError,
35
+ require_src
36
+ } from "./chunk-VGOIHW7D.js";
37
+ import {
38
+ __toESM
39
+ } from "./chunk-4VNS5WPM.js";
40
+
41
+ // ../../node_modules/.pnpm/music-metadata@11.12.0/node_modules/music-metadata/lib/ogg/OggParser.js
42
+ var import_debug4 = __toESM(require_src(), 1);
43
+
44
+ // ../../node_modules/.pnpm/music-metadata@11.12.0/node_modules/music-metadata/lib/ogg/opus/Opus.js
45
+ var OpusContentError = class extends makeUnexpectedFileContentError("Opus") {
46
+ };
47
+ var IdHeader = class {
48
+ constructor(len) {
49
+ if (len < 19) {
50
+ throw new OpusContentError("ID-header-page 0 should be at least 19 bytes long");
51
+ }
52
+ this.len = len;
53
+ }
54
+ get(buf, off) {
55
+ return {
56
+ magicSignature: new StringType(8, "ascii").get(buf, off + 0),
57
+ version: UINT8.get(buf, off + 8),
58
+ channelCount: UINT8.get(buf, off + 9),
59
+ preSkip: UINT16_LE.get(buf, off + 10),
60
+ inputSampleRate: UINT32_LE.get(buf, off + 12),
61
+ outputGain: UINT16_LE.get(buf, off + 16),
62
+ channelMapping: UINT8.get(buf, off + 18)
63
+ };
64
+ }
65
+ };
66
+
67
+ // ../../node_modules/.pnpm/music-metadata@11.12.0/node_modules/music-metadata/lib/ogg/opus/OpusStream.js
68
+ var OpusStream = class extends VorbisStream {
69
+ constructor(metadata, options, tokenizer) {
70
+ super(metadata, options);
71
+ this.idHeader = null;
72
+ this.lastPos = -1;
73
+ this.tokenizer = tokenizer;
74
+ this.durationOnLastPage = true;
75
+ }
76
+ /**
77
+ * Parse first Opus Ogg page
78
+ * @param {IPageHeader} header
79
+ * @param {Uint8Array} pageData
80
+ */
81
+ parseFirstPage(_header, pageData) {
82
+ this.metadata.setFormat("codec", "Opus");
83
+ this.idHeader = new IdHeader(pageData.length).get(pageData, 0);
84
+ if (this.idHeader.magicSignature !== "OpusHead")
85
+ throw new OpusContentError("Illegal ogg/Opus magic-signature");
86
+ this.metadata.setFormat("sampleRate", this.idHeader.inputSampleRate);
87
+ this.metadata.setFormat("numberOfChannels", this.idHeader.channelCount);
88
+ this.metadata.setAudioOnly();
89
+ }
90
+ async parseFullPage(pageData) {
91
+ const magicSignature = new StringType(8, "ascii").get(pageData, 0);
92
+ switch (magicSignature) {
93
+ case "OpusTags":
94
+ await this.parseUserCommentList(pageData, 8);
95
+ this.lastPos = this.tokenizer.position - pageData.length;
96
+ break;
97
+ default:
98
+ break;
99
+ }
100
+ }
101
+ calculateDuration(enfOfStream) {
102
+ if (this.lastPageHeader && (enfOfStream || this.lastPageHeader.headerType.lastPage) && this.metadata.format.sampleRate && this.lastPageHeader.absoluteGranulePosition >= 0) {
103
+ const pos_48bit = this.lastPageHeader.absoluteGranulePosition - this.idHeader.preSkip;
104
+ this.metadata.setFormat("numberOfSamples", pos_48bit);
105
+ this.metadata.setFormat("duration", pos_48bit / 48e3);
106
+ if (this.lastPos !== -1 && this.tokenizer.fileInfo.size && this.metadata.format.duration) {
107
+ const dataSize = this.tokenizer.fileInfo.size - this.lastPos;
108
+ this.metadata.setFormat("bitrate", 8 * dataSize / this.metadata.format.duration);
109
+ }
110
+ }
111
+ }
112
+ };
113
+
114
+ // ../../node_modules/.pnpm/music-metadata@11.12.0/node_modules/music-metadata/lib/ogg/speex/SpeexStream.js
115
+ var import_debug = __toESM(require_src(), 1);
116
+
117
+ // ../../node_modules/.pnpm/music-metadata@11.12.0/node_modules/music-metadata/lib/ogg/speex/Speex.js
118
+ var Header = {
119
+ len: 80,
120
+ get: (buf, off) => {
121
+ return {
122
+ speex: new StringType(8, "ascii").get(buf, off + 0),
123
+ version: trimRightNull(new StringType(20, "ascii").get(buf, off + 8)),
124
+ version_id: INT32_LE.get(buf, off + 28),
125
+ header_size: INT32_LE.get(buf, off + 32),
126
+ rate: INT32_LE.get(buf, off + 36),
127
+ mode: INT32_LE.get(buf, off + 40),
128
+ mode_bitstream_version: INT32_LE.get(buf, off + 44),
129
+ nb_channels: INT32_LE.get(buf, off + 48),
130
+ bitrate: INT32_LE.get(buf, off + 52),
131
+ frame_size: INT32_LE.get(buf, off + 56),
132
+ vbr: INT32_LE.get(buf, off + 60),
133
+ frames_per_packet: INT32_LE.get(buf, off + 64),
134
+ extra_headers: INT32_LE.get(buf, off + 68),
135
+ reserved1: INT32_LE.get(buf, off + 72),
136
+ reserved2: INT32_LE.get(buf, off + 76)
137
+ };
138
+ }
139
+ };
140
+
141
+ // ../../node_modules/.pnpm/music-metadata@11.12.0/node_modules/music-metadata/lib/ogg/speex/SpeexStream.js
142
+ var debug = (0, import_debug.default)("music-metadata:parser:ogg:speex");
143
+ var SpeexStream = class extends VorbisStream {
144
+ constructor(metadata, options, _tokenizer) {
145
+ super(metadata, options);
146
+ }
147
+ /**
148
+ * Parse first Speex Ogg page
149
+ * @param {IPageHeader} header
150
+ * @param {Uint8Array} pageData
151
+ */
152
+ parseFirstPage(_header, pageData) {
153
+ debug("First Ogg/Speex page");
154
+ const speexHeader = Header.get(pageData, 0);
155
+ this.metadata.setFormat("codec", `Speex ${speexHeader.version}`);
156
+ this.metadata.setFormat("numberOfChannels", speexHeader.nb_channels);
157
+ this.metadata.setFormat("sampleRate", speexHeader.rate);
158
+ if (speexHeader.bitrate !== -1) {
159
+ this.metadata.setFormat("bitrate", speexHeader.bitrate);
160
+ }
161
+ this.metadata.setAudioOnly();
162
+ }
163
+ };
164
+
165
+ // ../../node_modules/.pnpm/music-metadata@11.12.0/node_modules/music-metadata/lib/ogg/theora/TheoraStream.js
166
+ var import_debug2 = __toESM(require_src(), 1);
167
+
168
+ // ../../node_modules/.pnpm/music-metadata@11.12.0/node_modules/music-metadata/lib/ogg/theora/Theora.js
169
+ var IdentificationHeader = {
170
+ len: 42,
171
+ get: (buf, off) => {
172
+ return {
173
+ id: new StringType(7, "ascii").get(buf, off),
174
+ vmaj: UINT8.get(buf, off + 7),
175
+ vmin: UINT8.get(buf, off + 8),
176
+ vrev: UINT8.get(buf, off + 9),
177
+ vmbw: UINT16_BE.get(buf, off + 10),
178
+ vmbh: UINT16_BE.get(buf, off + 17),
179
+ nombr: UINT24_BE.get(buf, off + 37),
180
+ nqual: UINT8.get(buf, off + 40)
181
+ };
182
+ }
183
+ };
184
+
185
+ // ../../node_modules/.pnpm/music-metadata@11.12.0/node_modules/music-metadata/lib/ogg/theora/TheoraStream.js
186
+ var debug2 = (0, import_debug2.default)("music-metadata:parser:ogg:theora");
187
+ var TheoraStream = class {
188
+ constructor(metadata, _options, _tokenizer) {
189
+ this.durationOnLastPage = false;
190
+ this.metadata = metadata;
191
+ }
192
+ /**
193
+ * Vorbis 1 parser
194
+ * @param header Ogg Page Header
195
+ * @param pageData Page data
196
+ */
197
+ async parsePage(header, pageData) {
198
+ if (header.headerType.firstPage) {
199
+ await this.parseFirstPage(header, pageData);
200
+ }
201
+ }
202
+ calculateDuration() {
203
+ debug2("duration calculation not implemented");
204
+ }
205
+ /**
206
+ * Parse first Theora Ogg page. the initial identification header packet
207
+ */
208
+ async parseFirstPage(_header, pageData) {
209
+ debug2("First Ogg/Theora page");
210
+ this.metadata.setFormat("codec", "Theora");
211
+ const idHeader = IdentificationHeader.get(pageData, 0);
212
+ this.metadata.setFormat("bitrate", idHeader.nombr);
213
+ this.metadata.setFormat("hasVideo", true);
214
+ }
215
+ flush() {
216
+ return Promise.resolve();
217
+ }
218
+ };
219
+
220
+ // ../../node_modules/.pnpm/music-metadata@11.12.0/node_modules/music-metadata/lib/ogg/OggToken.js
221
+ var PageHeader = {
222
+ len: 27,
223
+ get: (buf, off) => {
224
+ return {
225
+ capturePattern: new StringType(4, "latin1").get(buf, off),
226
+ version: UINT8.get(buf, off + 4),
227
+ headerType: {
228
+ continued: getBit(buf, off + 5, 0),
229
+ firstPage: getBit(buf, off + 5, 1),
230
+ lastPage: getBit(buf, off + 5, 2)
231
+ },
232
+ // packet_flag: Token.UINT8.get(buf, off + 5),
233
+ absoluteGranulePosition: Number(UINT64_LE.get(buf, off + 6)),
234
+ streamSerialNumber: UINT32_LE.get(buf, off + 14),
235
+ pageSequenceNo: UINT32_LE.get(buf, off + 18),
236
+ pageChecksum: UINT32_LE.get(buf, off + 22),
237
+ page_segments: UINT8.get(buf, off + 26)
238
+ };
239
+ }
240
+ };
241
+ var SegmentTable = class _SegmentTable {
242
+ static sum(buf, off, len) {
243
+ const dv = new DataView(buf.buffer, 0);
244
+ let s = 0;
245
+ for (let i = off; i < off + len; ++i) {
246
+ s += dv.getUint8(i);
247
+ }
248
+ return s;
249
+ }
250
+ constructor(header) {
251
+ this.len = header.page_segments;
252
+ }
253
+ get(buf, off) {
254
+ return {
255
+ totalPageSize: _SegmentTable.sum(buf, off, this.len)
256
+ };
257
+ }
258
+ };
259
+
260
+ // ../../node_modules/.pnpm/music-metadata@11.12.0/node_modules/music-metadata/lib/ogg/flac/FlacStream.js
261
+ var import_debug3 = __toESM(require_src(), 1);
262
+ var debug3 = (0, import_debug3.default)("music-metadata:parser:ogg:theora");
263
+ var FlacStream = class {
264
+ constructor(metadata, options, tokenizer) {
265
+ this.durationOnLastPage = false;
266
+ this.metadata = metadata;
267
+ this.options = options;
268
+ this.tokenizer = tokenizer;
269
+ this.flacParser = new FlacParser(this.metadata, this.tokenizer, options);
270
+ }
271
+ /**
272
+ * Vorbis 1 parser
273
+ * @param header Ogg Page Header
274
+ * @param pageData Page data
275
+ */
276
+ async parsePage(header, pageData) {
277
+ if (header.headerType.firstPage) {
278
+ await this.parseFirstPage(header, pageData);
279
+ }
280
+ }
281
+ calculateDuration() {
282
+ debug3("duration calculation not implemented");
283
+ }
284
+ /**
285
+ * Parse first Theora Ogg page. the initial identification header packet
286
+ */
287
+ async parseFirstPage(_header, pageData) {
288
+ debug3("First Ogg/FLAC page");
289
+ const fourCC = await FourCcToken.get(pageData, 9);
290
+ if (fourCC.toString() !== "fLaC") {
291
+ throw new Error("Invalid FLAC preamble");
292
+ }
293
+ const blockHeader = await BlockHeader.get(pageData, 13);
294
+ await this.parseDataBlock(blockHeader, pageData.subarray(13 + BlockHeader.len));
295
+ }
296
+ async parseDataBlock(blockHeader, pageData) {
297
+ debug3(`blockHeader type=${blockHeader.type}, length=${blockHeader.length}`);
298
+ switch (blockHeader.type) {
299
+ case BlockType.STREAMINFO: {
300
+ const streamInfo = BlockStreamInfo.get(pageData, 0);
301
+ return this.flacParser.processsStreamInfo(streamInfo);
302
+ }
303
+ case BlockType.PADDING:
304
+ break;
305
+ case BlockType.APPLICATION:
306
+ break;
307
+ case BlockType.SEEKTABLE:
308
+ break;
309
+ case BlockType.VORBIS_COMMENT:
310
+ return this.flacParser.parseComment(pageData);
311
+ case BlockType.PICTURE:
312
+ if (!this.options.skipCovers) {
313
+ const picture = new VorbisPictureToken(pageData.length).get(pageData, 0);
314
+ return this.flacParser.addPictureTag(picture);
315
+ }
316
+ break;
317
+ default:
318
+ this.metadata.addWarning(`Unknown block type: ${blockHeader.type}`);
319
+ }
320
+ return this.tokenizer.ignore(blockHeader.length).then();
321
+ }
322
+ flush() {
323
+ return Promise.resolve();
324
+ }
325
+ };
326
+
327
+ // ../../node_modules/.pnpm/music-metadata@11.12.0/node_modules/music-metadata/lib/ogg/OggParser.js
328
+ var OggContentError = class extends makeUnexpectedFileContentError("Ogg") {
329
+ };
330
+ var debug4 = (0, import_debug4.default)("music-metadata:parser:ogg");
331
+ var OggStream = class {
332
+ constructor(metadata, streamSerial, options) {
333
+ this.pageNumber = 0;
334
+ this.closed = false;
335
+ this.metadata = metadata;
336
+ this.streamSerial = streamSerial;
337
+ this.options = options;
338
+ }
339
+ async parsePage(tokenizer, header) {
340
+ this.pageNumber = header.pageSequenceNo;
341
+ debug4("serial=%s page#=%s, Ogg.id=%s", header.streamSerialNumber, header.pageSequenceNo, header.capturePattern);
342
+ const segmentTable = await tokenizer.readToken(new SegmentTable(header));
343
+ debug4("totalPageSize=%s", segmentTable.totalPageSize);
344
+ const pageData = await tokenizer.readToken(new Uint8ArrayType(segmentTable.totalPageSize));
345
+ debug4("firstPage=%s, lastPage=%s, continued=%s", header.headerType.firstPage, header.headerType.lastPage, header.headerType.continued);
346
+ if (header.headerType.firstPage) {
347
+ this.metadata.setFormat("container", "Ogg");
348
+ const idData = pageData.subarray(0, 7);
349
+ const asciiId = Array.from(idData).filter((b) => b >= 32 && b <= 126).map((b) => String.fromCharCode(b)).join("");
350
+ switch (asciiId) {
351
+ case "vorbis":
352
+ debug4(`Set Ogg stream serial ${header.streamSerialNumber}, codec=Vorbis`);
353
+ this.pageConsumer = new VorbisStream(this.metadata, this.options);
354
+ break;
355
+ case "OpusHea":
356
+ debug4("Set page consumer to Ogg/Opus");
357
+ this.pageConsumer = new OpusStream(this.metadata, this.options, tokenizer);
358
+ break;
359
+ case "Speex ":
360
+ debug4("Set page consumer to Ogg/Speex");
361
+ this.pageConsumer = new SpeexStream(this.metadata, this.options, tokenizer);
362
+ break;
363
+ case "fishead":
364
+ case "theora":
365
+ debug4("Set page consumer to Ogg/Theora");
366
+ this.pageConsumer = new TheoraStream(this.metadata, this.options, tokenizer);
367
+ break;
368
+ case "FLAC":
369
+ debug4("Set page consumer to Vorbis");
370
+ this.pageConsumer = new FlacStream(this.metadata, this.options, tokenizer);
371
+ break;
372
+ default:
373
+ throw new OggContentError(`Ogg codec not recognized (id=${asciiId}`);
374
+ }
375
+ }
376
+ if (header.headerType.lastPage) {
377
+ this.closed = true;
378
+ }
379
+ if (this.pageConsumer) {
380
+ await this.pageConsumer.parsePage(header, pageData);
381
+ } else
382
+ throw new Error("pageConsumer should be initialized");
383
+ }
384
+ };
385
+ var OggParser = class extends BasicParser {
386
+ constructor() {
387
+ super(...arguments);
388
+ this.streams = /* @__PURE__ */ new Map();
389
+ }
390
+ /**
391
+ * Parse page
392
+ * @returns {Promise<void>}
393
+ */
394
+ async parse() {
395
+ this.streams = /* @__PURE__ */ new Map();
396
+ let enfOfStream = false;
397
+ let header;
398
+ try {
399
+ do {
400
+ header = await this.tokenizer.readToken(PageHeader);
401
+ if (header.capturePattern !== "OggS")
402
+ throw new OggContentError("Invalid Ogg capture pattern");
403
+ let stream = this.streams.get(header.streamSerialNumber);
404
+ if (!stream) {
405
+ stream = new OggStream(this.metadata, header.streamSerialNumber, this.options);
406
+ this.streams.set(header.streamSerialNumber, stream);
407
+ }
408
+ await stream.parsePage(this.tokenizer, header);
409
+ if (stream.pageNumber > 12 && !(this.options.duration && [...this.streams.values()].find((stream2) => stream2.pageConsumer?.durationOnLastPage))) {
410
+ debug4("Stop processing Ogg stream");
411
+ break;
412
+ }
413
+ } while (![...this.streams.values()].every((item) => item.closed));
414
+ } catch (err) {
415
+ if (err instanceof EndOfStreamError) {
416
+ debug4("Reached end-of-stream");
417
+ enfOfStream = true;
418
+ } else if (err instanceof OggContentError) {
419
+ this.metadata.addWarning(`Corrupt Ogg content at ${this.tokenizer.position}`);
420
+ } else
421
+ throw err;
422
+ }
423
+ for (const stream of this.streams.values()) {
424
+ if (!stream.closed) {
425
+ this.metadata.addWarning(`End-of-stream reached before reaching last page in Ogg stream serial=${stream.streamSerial}`);
426
+ await stream.pageConsumer?.flush();
427
+ }
428
+ stream.pageConsumer?.calculateDuration(enfOfStream);
429
+ }
430
+ }
431
+ };
432
+ export {
433
+ OggContentError,
434
+ OggParser
435
+ };
@@ -0,0 +1,203 @@
1
+ import {
2
+ FourCcToken,
3
+ tryParseApeHeader
4
+ } from "./chunk-YIHDW7JC.js";
5
+ import "./chunk-HNLU36CC.js";
6
+ import {
7
+ uint8ArrayToHex
8
+ } from "./chunk-GD35BJSH.js";
9
+ import {
10
+ BasicParser,
11
+ UINT16_LE,
12
+ UINT24_LE,
13
+ UINT32_LE,
14
+ UINT8,
15
+ Uint8ArrayType,
16
+ makeUnexpectedFileContentError,
17
+ require_src
18
+ } from "./chunk-VGOIHW7D.js";
19
+ import {
20
+ __toESM
21
+ } from "./chunk-4VNS5WPM.js";
22
+
23
+ // ../../node_modules/.pnpm/music-metadata@11.12.0/node_modules/music-metadata/lib/wavpack/WavPackToken.js
24
+ var SampleRates = [
25
+ 6e3,
26
+ 8e3,
27
+ 9600,
28
+ 11025,
29
+ 12e3,
30
+ 16e3,
31
+ 22050,
32
+ 24e3,
33
+ 32e3,
34
+ 44100,
35
+ 48e3,
36
+ 64e3,
37
+ 88200,
38
+ 96e3,
39
+ 192e3,
40
+ -1
41
+ ];
42
+ var BlockHeaderToken = {
43
+ len: 32,
44
+ get: (buf, off) => {
45
+ const flags = UINT32_LE.get(buf, off + 24);
46
+ const res = {
47
+ // should equal 'wvpk'
48
+ BlockID: FourCcToken.get(buf, off),
49
+ // 0x402 to 0x410 are valid for decode
50
+ blockSize: UINT32_LE.get(buf, off + 4),
51
+ // 0x402 (1026) to 0x410 are valid for decode
52
+ version: UINT16_LE.get(buf, off + 8),
53
+ // 40-bit total samples for entire file (if block_index == 0 and a value of -1 indicates an unknown length)
54
+ totalSamples: (
55
+ /* replace with bigint? (Token.UINT8.get(buf, off + 11) << 32) + */
56
+ UINT32_LE.get(buf, off + 12)
57
+ ),
58
+ // 40-bit block_index
59
+ blockIndex: (
60
+ /* replace with bigint? (Token.UINT8.get(buf, off + 10) << 32) + */
61
+ UINT32_LE.get(buf, off + 16)
62
+ ),
63
+ // 40-bit total samples for entire file (if block_index == 0 and a value of -1 indicates an unknown length)
64
+ blockSamples: UINT32_LE.get(buf, off + 20),
65
+ // various flags for id and decoding
66
+ flags: {
67
+ bitsPerSample: (1 + getBitAllignedNumber(flags, 0, 2)) * 8,
68
+ isMono: isBitSet(flags, 2),
69
+ isHybrid: isBitSet(flags, 3),
70
+ isJointStereo: isBitSet(flags, 4),
71
+ crossChannel: isBitSet(flags, 5),
72
+ hybridNoiseShaping: isBitSet(flags, 6),
73
+ floatingPoint: isBitSet(flags, 7),
74
+ samplingRate: SampleRates[getBitAllignedNumber(flags, 23, 4)],
75
+ isDSD: isBitSet(flags, 31)
76
+ },
77
+ // crc for actual decoded data
78
+ crc: new Uint8ArrayType(4).get(buf, off + 28)
79
+ };
80
+ if (res.flags.isDSD) {
81
+ res.totalSamples *= 8;
82
+ }
83
+ return res;
84
+ }
85
+ };
86
+ var MetadataIdToken = {
87
+ len: 1,
88
+ get: (buf, off) => {
89
+ return {
90
+ functionId: getBitAllignedNumber(buf[off], 0, 6),
91
+ // functionId overlaps with isOptional flag
92
+ isOptional: isBitSet(buf[off], 5),
93
+ isOddSize: isBitSet(buf[off], 6),
94
+ largeBlock: isBitSet(buf[off], 7)
95
+ };
96
+ }
97
+ };
98
+ function isBitSet(flags, bitOffset) {
99
+ return getBitAllignedNumber(flags, bitOffset, 1) === 1;
100
+ }
101
+ function getBitAllignedNumber(flags, bitOffset, len) {
102
+ return flags >>> bitOffset & 4294967295 >>> 32 - len;
103
+ }
104
+
105
+ // ../../node_modules/.pnpm/music-metadata@11.12.0/node_modules/music-metadata/lib/wavpack/WavPackParser.js
106
+ var import_debug = __toESM(require_src(), 1);
107
+ var debug = (0, import_debug.default)("music-metadata:parser:WavPack");
108
+ var WavPackContentError = class extends makeUnexpectedFileContentError("WavPack") {
109
+ };
110
+ var WavPackParser = class extends BasicParser {
111
+ constructor() {
112
+ super(...arguments);
113
+ this.audioDataSize = 0;
114
+ }
115
+ async parse() {
116
+ this.metadata.setAudioOnly();
117
+ this.audioDataSize = 0;
118
+ await this.parseWavPackBlocks();
119
+ return tryParseApeHeader(this.metadata, this.tokenizer, this.options);
120
+ }
121
+ async parseWavPackBlocks() {
122
+ do {
123
+ const blockId = await this.tokenizer.peekToken(FourCcToken);
124
+ if (blockId !== "wvpk")
125
+ break;
126
+ const header = await this.tokenizer.readToken(BlockHeaderToken);
127
+ if (header.BlockID !== "wvpk")
128
+ throw new WavPackContentError("Invalid WavPack Block-ID");
129
+ debug(`WavPack header blockIndex=${header.blockIndex}, len=${BlockHeaderToken.len}`);
130
+ if (header.blockIndex === 0 && !this.metadata.format.container) {
131
+ this.metadata.setFormat("container", "WavPack");
132
+ this.metadata.setFormat("lossless", !header.flags.isHybrid);
133
+ this.metadata.setFormat("bitsPerSample", header.flags.bitsPerSample);
134
+ if (!header.flags.isDSD) {
135
+ this.metadata.setFormat("sampleRate", header.flags.samplingRate);
136
+ this.metadata.setFormat("duration", header.totalSamples / header.flags.samplingRate);
137
+ }
138
+ this.metadata.setFormat("numberOfChannels", header.flags.isMono ? 1 : 2);
139
+ this.metadata.setFormat("numberOfSamples", header.totalSamples);
140
+ this.metadata.setFormat("codec", header.flags.isDSD ? "DSD" : "PCM");
141
+ }
142
+ const ignoreBytes = header.blockSize - (BlockHeaderToken.len - 8);
143
+ await (header.blockIndex === 0 ? this.parseMetadataSubBlock(header, ignoreBytes) : this.tokenizer.ignore(ignoreBytes));
144
+ if (header.blockSamples > 0) {
145
+ this.audioDataSize += header.blockSize;
146
+ }
147
+ } while (!this.tokenizer.fileInfo.size || this.tokenizer.fileInfo.size - this.tokenizer.position >= BlockHeaderToken.len);
148
+ if (this.metadata.format.duration) {
149
+ this.metadata.setFormat("bitrate", this.audioDataSize * 8 / this.metadata.format.duration);
150
+ }
151
+ }
152
+ /**
153
+ * Ref: http://www.wavpack.com/WavPack5FileFormat.pdf, 3.0 Metadata Sub-blocks
154
+ * @param header Header
155
+ * @param remainingLength Remaining length
156
+ */
157
+ async parseMetadataSubBlock(header, remainingLength) {
158
+ let remaining = remainingLength;
159
+ while (remaining > MetadataIdToken.len) {
160
+ const id = await this.tokenizer.readToken(MetadataIdToken);
161
+ const dataSizeInWords = await this.tokenizer.readNumber(id.largeBlock ? UINT24_LE : UINT8);
162
+ const data = new Uint8Array(dataSizeInWords * 2 - (id.isOddSize ? 1 : 0));
163
+ await this.tokenizer.readBuffer(data);
164
+ debug(`Metadata Sub-Blocks functionId=0x${id.functionId.toString(16)}, id.largeBlock=${id.largeBlock},data-size=${data.length}`);
165
+ switch (id.functionId) {
166
+ case 0:
167
+ break;
168
+ case 14: {
169
+ debug("ID_DSD_BLOCK");
170
+ const mp = 1 << UINT8.get(data, 0);
171
+ const samplingRate = header.flags.samplingRate * mp * 8;
172
+ if (!header.flags.isDSD)
173
+ throw new WavPackContentError("Only expect DSD block if DSD-flag is set");
174
+ this.metadata.setFormat("sampleRate", samplingRate);
175
+ this.metadata.setFormat("duration", header.totalSamples / samplingRate);
176
+ break;
177
+ }
178
+ case 36:
179
+ debug("ID_ALT_TRAILER: trailer for non-wav files");
180
+ break;
181
+ case 38:
182
+ this.metadata.setFormat("audioMD5", data);
183
+ break;
184
+ case 47:
185
+ debug(`ID_BLOCK_CHECKSUM: checksum=${uint8ArrayToHex(data)}`);
186
+ break;
187
+ default:
188
+ debug(`Ignore unsupported meta-sub-block-id functionId=0x${id.functionId.toString(16)}`);
189
+ break;
190
+ }
191
+ remaining -= MetadataIdToken.len + (id.largeBlock ? UINT24_LE.len : UINT8.len) + dataSizeInWords * 2;
192
+ debug(`remainingLength=${remaining}`);
193
+ if (id.isOddSize)
194
+ this.tokenizer.ignore(1);
195
+ }
196
+ if (remaining !== 0)
197
+ throw new WavPackContentError("metadata-sub-block should fit it remaining length");
198
+ }
199
+ };
200
+ export {
201
+ WavPackContentError,
202
+ WavPackParser
203
+ };