music-metadata 7.11.3 → 7.11.7
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 +432 -432
- package/lib/ParserFactory.d.ts +49 -49
- package/lib/ParserFactory.js +251 -251
- package/lib/aiff/AiffParser.d.ts +15 -15
- package/lib/aiff/AiffParser.js +85 -85
- package/lib/aiff/AiffToken.d.ts +22 -22
- package/lib/aiff/AiffToken.js +43 -43
- package/lib/apev2/APEv2Parser.d.ts +30 -30
- package/lib/apev2/APEv2Parser.js +162 -162
- package/lib/apev2/APEv2TagMapper.d.ts +4 -4
- package/lib/apev2/APEv2TagMapper.js +87 -86
- package/lib/apev2/APEv2Token.d.ts +100 -100
- package/lib/apev2/APEv2Token.js +127 -126
- package/lib/asf/AsfObject.d.ts +319 -319
- package/lib/asf/AsfObject.js +384 -384
- package/lib/asf/AsfParser.d.ts +17 -17
- package/lib/asf/AsfParser.js +135 -135
- package/lib/asf/AsfTagMapper.d.ts +7 -7
- package/lib/asf/AsfTagMapper.js +96 -95
- package/lib/asf/AsfUtil.d.ts +13 -13
- package/lib/asf/AsfUtil.js +40 -40
- package/lib/asf/GUID.d.ts +86 -86
- package/lib/asf/GUID.js +123 -123
- package/lib/common/BasicParser.d.ts +17 -17
- package/lib/common/BasicParser.js +18 -18
- package/lib/common/CaseInsensitiveTagMap.d.ts +10 -10
- package/lib/common/CaseInsensitiveTagMap.js +22 -21
- package/lib/common/CombinedTagMapper.d.ts +19 -19
- package/lib/common/CombinedTagMapper.js +52 -51
- package/lib/common/FourCC.d.ts +6 -6
- package/lib/common/FourCC.js +29 -28
- package/lib/common/GenericTagMapper.d.ts +51 -51
- package/lib/common/GenericTagMapper.js +56 -55
- package/lib/common/GenericTagTypes.d.ts +33 -33
- package/lib/common/GenericTagTypes.js +132 -131
- package/lib/common/MetadataCollector.d.ts +76 -76
- package/lib/common/MetadataCollector.js +276 -274
- package/lib/common/RandomFileReader.d.ts +20 -20
- package/lib/common/RandomFileReader.js +37 -37
- package/lib/common/RandomUint8ArrayReader.d.ts +18 -18
- package/lib/common/RandomUint8ArrayReader.js +25 -25
- package/lib/common/Util.d.ts +58 -57
- package/lib/common/Util.js +163 -169
- package/lib/core.d.ts +48 -48
- package/lib/core.js +90 -90
- package/lib/dsdiff/DsdiffParser.d.ts +14 -14
- package/lib/dsdiff/DsdiffParser.js +143 -143
- package/lib/dsdiff/DsdiffToken.d.ts +9 -9
- package/lib/dsdiff/DsdiffToken.js +21 -21
- package/lib/dsf/DsfChunk.d.ts +86 -86
- package/lib/dsf/DsfChunk.js +54 -54
- package/lib/dsf/DsfParser.d.ts +9 -9
- package/lib/dsf/DsfParser.js +56 -56
- package/lib/flac/FlacParser.d.ts +28 -28
- package/lib/flac/FlacParser.js +175 -175
- package/lib/id3v1/ID3v1Parser.d.ts +13 -13
- package/lib/id3v1/ID3v1Parser.js +134 -134
- package/lib/id3v1/ID3v1TagMap.d.ts +4 -4
- package/lib/id3v1/ID3v1TagMap.js +23 -22
- package/lib/id3v2/AbstractID3Parser.d.ts +17 -17
- package/lib/id3v2/AbstractID3Parser.js +60 -60
- package/lib/id3v2/FrameParser.d.ts +32 -32
- package/lib/id3v2/FrameParser.js +329 -323
- package/lib/id3v2/ID3v22TagMapper.d.ts +9 -9
- package/lib/id3v2/ID3v22TagMapper.js +56 -54
- package/lib/id3v2/ID3v24TagMapper.d.ts +14 -14
- package/lib/id3v2/ID3v24TagMapper.js +194 -193
- package/lib/id3v2/ID3v2Parser.d.ts +29 -29
- package/lib/id3v2/ID3v2Parser.js +194 -194
- package/lib/id3v2/ID3v2Token.d.ts +73 -73
- package/lib/id3v2/ID3v2Token.js +106 -106
- package/lib/iff/index.d.ts +33 -33
- package/lib/iff/index.js +19 -19
- package/lib/index.d.ts +45 -34
- package/lib/index.js +74 -64
- package/lib/lyrics3/Lyrics3.d.ts +3 -3
- package/lib/lyrics3/Lyrics3.js +17 -17
- package/lib/matroska/MatroskaDtd.d.ts +8 -8
- package/lib/matroska/MatroskaDtd.js +279 -279
- package/lib/matroska/MatroskaParser.d.ts +37 -37
- package/lib/matroska/MatroskaParser.js +235 -234
- package/lib/matroska/MatroskaTagMapper.d.ts +4 -4
- package/lib/matroska/MatroskaTagMapper.js +36 -35
- package/lib/matroska/types.d.ts +175 -175
- package/lib/matroska/types.js +32 -32
- package/lib/mp4/Atom.d.ts +16 -16
- package/lib/mp4/Atom.js +70 -70
- package/lib/mp4/AtomToken.d.ts +395 -395
- package/lib/mp4/AtomToken.js +406 -406
- package/lib/mp4/MP4Parser.d.ts +30 -30
- package/lib/mp4/MP4Parser.js +511 -511
- package/lib/mp4/MP4TagMapper.d.ts +5 -5
- package/lib/mp4/MP4TagMapper.js +116 -115
- package/lib/mpeg/ExtendedLameHeader.d.ts +27 -27
- package/lib/mpeg/ExtendedLameHeader.js +31 -31
- package/lib/mpeg/MpegParser.d.ts +49 -49
- package/lib/mpeg/MpegParser.js +529 -529
- package/lib/mpeg/ReplayGainDataFormat.d.ts +55 -55
- package/lib/mpeg/ReplayGainDataFormat.js +69 -69
- package/lib/mpeg/XingTag.d.ts +45 -45
- package/lib/mpeg/XingTag.js +69 -69
- package/lib/musepack/index.d.ts +5 -5
- package/lib/musepack/index.js +32 -32
- package/lib/musepack/sv7/BitReader.d.ts +13 -13
- package/lib/musepack/sv7/BitReader.js +54 -54
- package/lib/musepack/sv7/MpcSv7Parser.d.ts +8 -8
- package/lib/musepack/sv7/MpcSv7Parser.js +46 -46
- package/lib/musepack/sv7/StreamVersion7.d.ts +28 -28
- package/lib/musepack/sv7/StreamVersion7.js +41 -41
- package/lib/musepack/sv8/MpcSv8Parser.d.ts +6 -6
- package/lib/musepack/sv8/MpcSv8Parser.js +55 -55
- package/lib/musepack/sv8/StreamVersion8.d.ts +40 -40
- package/lib/musepack/sv8/StreamVersion8.js +80 -80
- package/lib/ogg/Ogg.d.ts +72 -72
- package/lib/ogg/Ogg.js +2 -2
- package/lib/ogg/OggParser.d.ts +23 -23
- package/lib/ogg/OggParser.js +126 -126
- package/lib/ogg/opus/Opus.d.ts +48 -48
- package/lib/ogg/opus/Opus.js +28 -28
- package/lib/ogg/opus/OpusParser.d.ts +25 -25
- package/lib/ogg/opus/OpusParser.js +56 -56
- package/lib/ogg/speex/Speex.d.ts +36 -36
- package/lib/ogg/speex/Speex.js +31 -31
- package/lib/ogg/speex/SpeexParser.d.ts +22 -22
- package/lib/ogg/speex/SpeexParser.js +35 -35
- package/lib/ogg/theora/Theora.d.ts +20 -20
- package/lib/ogg/theora/Theora.js +23 -23
- package/lib/ogg/theora/TheoraParser.d.ts +28 -28
- package/lib/ogg/theora/TheoraParser.js +44 -44
- package/lib/ogg/vorbis/Vorbis.d.ts +79 -79
- package/lib/ogg/vorbis/Vorbis.js +78 -78
- package/lib/ogg/vorbis/VorbisDecoder.d.ts +12 -12
- package/lib/ogg/vorbis/VorbisDecoder.js +32 -32
- package/lib/ogg/vorbis/VorbisParser.d.ts +36 -36
- package/lib/ogg/vorbis/VorbisParser.js +128 -128
- package/lib/ogg/vorbis/VorbisTagMapper.d.ts +7 -7
- package/lib/ogg/vorbis/VorbisTagMapper.js +133 -132
- package/lib/riff/RiffChunk.d.ts +16 -16
- package/lib/riff/RiffChunk.js +32 -32
- package/lib/riff/RiffInfoTagMap.d.ts +10 -10
- package/lib/riff/RiffInfoTagMap.js +38 -37
- package/lib/type.d.ts +599 -599
- package/lib/type.js +14 -13
- package/lib/wav/WaveChunk.d.ts +64 -64
- package/lib/wav/WaveChunk.js +65 -65
- package/lib/wav/WaveParser.d.ts +24 -24
- package/lib/wav/WaveParser.js +144 -144
- package/lib/wavpack/WavPackParser.d.ts +14 -14
- package/lib/wavpack/WavPackParser.js +105 -105
- package/lib/wavpack/WavPackToken.d.ts +64 -64
- package/lib/wavpack/WavPackToken.js +76 -76
- package/package.json +142 -142
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { BasicParser } from '../common/BasicParser';
|
|
2
|
-
/**
|
|
3
|
-
* WavPack Parser
|
|
4
|
-
*/
|
|
5
|
-
export declare class WavPackParser extends BasicParser {
|
|
6
|
-
private audioDataSize;
|
|
7
|
-
parse(): Promise<void>;
|
|
8
|
-
parseWavPackBlocks(): Promise<void>;
|
|
9
|
-
/**
|
|
10
|
-
* Ref: http://www.wavpack.com/WavPack5FileFormat.pdf, 3.0 Metadata Sub-blocks
|
|
11
|
-
* @param remainingLength
|
|
12
|
-
*/
|
|
13
|
-
private parseMetadataSubBlock;
|
|
14
|
-
}
|
|
1
|
+
import { BasicParser } from '../common/BasicParser';
|
|
2
|
+
/**
|
|
3
|
+
* WavPack Parser
|
|
4
|
+
*/
|
|
5
|
+
export declare class WavPackParser extends BasicParser {
|
|
6
|
+
private audioDataSize;
|
|
7
|
+
parse(): Promise<void>;
|
|
8
|
+
parseWavPackBlocks(): Promise<void>;
|
|
9
|
+
/**
|
|
10
|
+
* Ref: http://www.wavpack.com/WavPack5FileFormat.pdf, 3.0 Metadata Sub-blocks
|
|
11
|
+
* @param remainingLength
|
|
12
|
+
*/
|
|
13
|
+
private parseMetadataSubBlock;
|
|
14
|
+
}
|
|
@@ -1,105 +1,105 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.WavPackParser = void 0;
|
|
4
|
-
const Token = require("token-types");
|
|
5
|
-
const APEv2Parser_1 = require("../apev2/APEv2Parser");
|
|
6
|
-
const FourCC_1 = require("../common/FourCC");
|
|
7
|
-
const BasicParser_1 = require("../common/BasicParser");
|
|
8
|
-
const WavPackToken_1 = require("./WavPackToken");
|
|
9
|
-
const initDebug = require("debug");
|
|
10
|
-
const debug = initDebug('music-metadata:parser:WavPack');
|
|
11
|
-
/**
|
|
12
|
-
* WavPack Parser
|
|
13
|
-
*/
|
|
14
|
-
class WavPackParser extends BasicParser_1.BasicParser {
|
|
15
|
-
async parse() {
|
|
16
|
-
this.audioDataSize = 0;
|
|
17
|
-
// First parse all WavPack blocks
|
|
18
|
-
await this.parseWavPackBlocks();
|
|
19
|
-
// try to parse APEv2 header
|
|
20
|
-
return APEv2Parser_1.APEv2Parser.tryParseApeHeader(this.metadata, this.tokenizer, this.options);
|
|
21
|
-
}
|
|
22
|
-
async parseWavPackBlocks() {
|
|
23
|
-
do {
|
|
24
|
-
const blockId = await this.tokenizer.peekToken(FourCC_1.FourCcToken);
|
|
25
|
-
if (blockId !== 'wvpk')
|
|
26
|
-
break;
|
|
27
|
-
const header = await this.tokenizer.readToken(WavPackToken_1.WavPack.BlockHeaderToken);
|
|
28
|
-
if (header.BlockID !== 'wvpk')
|
|
29
|
-
throw new Error('Invalid WavPack Block-ID');
|
|
30
|
-
debug(`WavPack header blockIndex=${header.blockIndex}, len=${WavPackToken_1.WavPack.BlockHeaderToken.len}`);
|
|
31
|
-
if (header.blockIndex === 0 && !this.metadata.format.container) {
|
|
32
|
-
this.metadata.setFormat('container', 'WavPack');
|
|
33
|
-
this.metadata.setFormat('lossless', !header.flags.isHybrid);
|
|
34
|
-
// tagTypes: this.type,
|
|
35
|
-
this.metadata.setFormat('bitsPerSample', header.flags.bitsPerSample);
|
|
36
|
-
if (!header.flags.isDSD) {
|
|
37
|
-
// In case isDSD, these values will ne set in ID_DSD_BLOCK
|
|
38
|
-
this.metadata.setFormat('sampleRate', header.flags.samplingRate);
|
|
39
|
-
this.metadata.setFormat('duration', header.totalSamples / header.flags.samplingRate);
|
|
40
|
-
}
|
|
41
|
-
this.metadata.setFormat('numberOfChannels', header.flags.isMono ? 1 : 2);
|
|
42
|
-
this.metadata.setFormat('numberOfSamples', header.totalSamples);
|
|
43
|
-
this.metadata.setFormat('codec', header.flags.isDSD ? 'DSD' : 'PCM');
|
|
44
|
-
}
|
|
45
|
-
const ignoreBytes = header.blockSize - (WavPackToken_1.WavPack.BlockHeaderToken.len - 8);
|
|
46
|
-
if (header.blockIndex === 0) {
|
|
47
|
-
// Meta-data block
|
|
48
|
-
await this.parseMetadataSubBlock(header, ignoreBytes);
|
|
49
|
-
}
|
|
50
|
-
else {
|
|
51
|
-
await this.tokenizer.ignore(ignoreBytes);
|
|
52
|
-
}
|
|
53
|
-
if (header.blockSamples > 0) {
|
|
54
|
-
this.audioDataSize += header.blockSize; // Count audio data for bit-rate calculation
|
|
55
|
-
}
|
|
56
|
-
} while (!this.tokenizer.fileInfo.size || this.tokenizer.fileInfo.size - this.tokenizer.position >= WavPackToken_1.WavPack.BlockHeaderToken.len);
|
|
57
|
-
this.metadata.setFormat('bitrate', this.audioDataSize * 8 / this.metadata.format.duration);
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* Ref: http://www.wavpack.com/WavPack5FileFormat.pdf, 3.0 Metadata Sub-blocks
|
|
61
|
-
* @param remainingLength
|
|
62
|
-
*/
|
|
63
|
-
async parseMetadataSubBlock(header, remainingLength) {
|
|
64
|
-
while (remainingLength > WavPackToken_1.WavPack.MetadataIdToken.len) {
|
|
65
|
-
const id = await this.tokenizer.readToken(WavPackToken_1.WavPack.MetadataIdToken);
|
|
66
|
-
const dataSizeInWords = await this.tokenizer.readNumber(id.largeBlock ? Token.UINT24_LE : Token.UINT8);
|
|
67
|
-
const data = Buffer.alloc(dataSizeInWords * 2 - (id.isOddSize ? 1 : 0));
|
|
68
|
-
await this.tokenizer.readBuffer(data);
|
|
69
|
-
debug(`Metadata Sub-Blocks functionId=0x${id.functionId.toString(16)}, id.largeBlock=${id.largeBlock},data-size=${data.length}`);
|
|
70
|
-
switch (id.functionId) {
|
|
71
|
-
case 0x0: // ID_DUMMY: could be used to pad WavPack blocks
|
|
72
|
-
break;
|
|
73
|
-
case 0xe: // ID_DSD_BLOCK
|
|
74
|
-
debug('ID_DSD_BLOCK');
|
|
75
|
-
// https://github.com/dbry/WavPack/issues/71#issuecomment-483094813
|
|
76
|
-
const mp = 1 << data.readUInt8(0);
|
|
77
|
-
const samplingRate = header.flags.samplingRate * mp * 8; // ToDo: second factor should be read from DSD-metadata block https://github.com/dbry/WavPack/issues/71#issuecomment-483094813
|
|
78
|
-
if (!header.flags.isDSD)
|
|
79
|
-
throw new Error('Only expect DSD block if DSD-flag is set');
|
|
80
|
-
this.metadata.setFormat('sampleRate', samplingRate);
|
|
81
|
-
this.metadata.setFormat('duration', header.totalSamples / samplingRate);
|
|
82
|
-
break;
|
|
83
|
-
case 0x24: // ID_ALT_TRAILER: maybe used to embed original ID3 tag header
|
|
84
|
-
debug('ID_ALT_TRAILER: trailer for non-wav files');
|
|
85
|
-
break;
|
|
86
|
-
case 0x26: // ID_MD5_CHECKSUM
|
|
87
|
-
this.metadata.setFormat('audioMD5', data);
|
|
88
|
-
break;
|
|
89
|
-
case 0x2f: // ID_BLOCK_CHECKSUM
|
|
90
|
-
debug(`ID_BLOCK_CHECKSUM: checksum=${data.toString('hex')}`);
|
|
91
|
-
break;
|
|
92
|
-
default:
|
|
93
|
-
debug(`Ignore unsupported meta-sub-block-id functionId=0x${id.functionId.toString(16)}`);
|
|
94
|
-
break;
|
|
95
|
-
}
|
|
96
|
-
remainingLength -= WavPackToken_1.WavPack.MetadataIdToken.len + (id.largeBlock ? Token.UINT24_LE.len : Token.UINT8.len) + dataSizeInWords * 2;
|
|
97
|
-
debug(`remainingLength=${remainingLength}`);
|
|
98
|
-
if (id.isOddSize)
|
|
99
|
-
this.tokenizer.ignore(1);
|
|
100
|
-
}
|
|
101
|
-
if (remainingLength !== 0)
|
|
102
|
-
throw new Error('metadata-sub-block should fit it remaining length');
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
exports.WavPackParser = WavPackParser;
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WavPackParser = void 0;
|
|
4
|
+
const Token = require("token-types");
|
|
5
|
+
const APEv2Parser_1 = require("../apev2/APEv2Parser");
|
|
6
|
+
const FourCC_1 = require("../common/FourCC");
|
|
7
|
+
const BasicParser_1 = require("../common/BasicParser");
|
|
8
|
+
const WavPackToken_1 = require("./WavPackToken");
|
|
9
|
+
const initDebug = require("debug");
|
|
10
|
+
const debug = initDebug('music-metadata:parser:WavPack');
|
|
11
|
+
/**
|
|
12
|
+
* WavPack Parser
|
|
13
|
+
*/
|
|
14
|
+
class WavPackParser extends BasicParser_1.BasicParser {
|
|
15
|
+
async parse() {
|
|
16
|
+
this.audioDataSize = 0;
|
|
17
|
+
// First parse all WavPack blocks
|
|
18
|
+
await this.parseWavPackBlocks();
|
|
19
|
+
// try to parse APEv2 header
|
|
20
|
+
return APEv2Parser_1.APEv2Parser.tryParseApeHeader(this.metadata, this.tokenizer, this.options);
|
|
21
|
+
}
|
|
22
|
+
async parseWavPackBlocks() {
|
|
23
|
+
do {
|
|
24
|
+
const blockId = await this.tokenizer.peekToken(FourCC_1.FourCcToken);
|
|
25
|
+
if (blockId !== 'wvpk')
|
|
26
|
+
break;
|
|
27
|
+
const header = await this.tokenizer.readToken(WavPackToken_1.WavPack.BlockHeaderToken);
|
|
28
|
+
if (header.BlockID !== 'wvpk')
|
|
29
|
+
throw new Error('Invalid WavPack Block-ID');
|
|
30
|
+
debug(`WavPack header blockIndex=${header.blockIndex}, len=${WavPackToken_1.WavPack.BlockHeaderToken.len}`);
|
|
31
|
+
if (header.blockIndex === 0 && !this.metadata.format.container) {
|
|
32
|
+
this.metadata.setFormat('container', 'WavPack');
|
|
33
|
+
this.metadata.setFormat('lossless', !header.flags.isHybrid);
|
|
34
|
+
// tagTypes: this.type,
|
|
35
|
+
this.metadata.setFormat('bitsPerSample', header.flags.bitsPerSample);
|
|
36
|
+
if (!header.flags.isDSD) {
|
|
37
|
+
// In case isDSD, these values will ne set in ID_DSD_BLOCK
|
|
38
|
+
this.metadata.setFormat('sampleRate', header.flags.samplingRate);
|
|
39
|
+
this.metadata.setFormat('duration', header.totalSamples / header.flags.samplingRate);
|
|
40
|
+
}
|
|
41
|
+
this.metadata.setFormat('numberOfChannels', header.flags.isMono ? 1 : 2);
|
|
42
|
+
this.metadata.setFormat('numberOfSamples', header.totalSamples);
|
|
43
|
+
this.metadata.setFormat('codec', header.flags.isDSD ? 'DSD' : 'PCM');
|
|
44
|
+
}
|
|
45
|
+
const ignoreBytes = header.blockSize - (WavPackToken_1.WavPack.BlockHeaderToken.len - 8);
|
|
46
|
+
if (header.blockIndex === 0) {
|
|
47
|
+
// Meta-data block
|
|
48
|
+
await this.parseMetadataSubBlock(header, ignoreBytes);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
await this.tokenizer.ignore(ignoreBytes);
|
|
52
|
+
}
|
|
53
|
+
if (header.blockSamples > 0) {
|
|
54
|
+
this.audioDataSize += header.blockSize; // Count audio data for bit-rate calculation
|
|
55
|
+
}
|
|
56
|
+
} while (!this.tokenizer.fileInfo.size || this.tokenizer.fileInfo.size - this.tokenizer.position >= WavPackToken_1.WavPack.BlockHeaderToken.len);
|
|
57
|
+
this.metadata.setFormat('bitrate', this.audioDataSize * 8 / this.metadata.format.duration);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Ref: http://www.wavpack.com/WavPack5FileFormat.pdf, 3.0 Metadata Sub-blocks
|
|
61
|
+
* @param remainingLength
|
|
62
|
+
*/
|
|
63
|
+
async parseMetadataSubBlock(header, remainingLength) {
|
|
64
|
+
while (remainingLength > WavPackToken_1.WavPack.MetadataIdToken.len) {
|
|
65
|
+
const id = await this.tokenizer.readToken(WavPackToken_1.WavPack.MetadataIdToken);
|
|
66
|
+
const dataSizeInWords = await this.tokenizer.readNumber(id.largeBlock ? Token.UINT24_LE : Token.UINT8);
|
|
67
|
+
const data = Buffer.alloc(dataSizeInWords * 2 - (id.isOddSize ? 1 : 0));
|
|
68
|
+
await this.tokenizer.readBuffer(data);
|
|
69
|
+
debug(`Metadata Sub-Blocks functionId=0x${id.functionId.toString(16)}, id.largeBlock=${id.largeBlock},data-size=${data.length}`);
|
|
70
|
+
switch (id.functionId) {
|
|
71
|
+
case 0x0: // ID_DUMMY: could be used to pad WavPack blocks
|
|
72
|
+
break;
|
|
73
|
+
case 0xe: // ID_DSD_BLOCK
|
|
74
|
+
debug('ID_DSD_BLOCK');
|
|
75
|
+
// https://github.com/dbry/WavPack/issues/71#issuecomment-483094813
|
|
76
|
+
const mp = 1 << data.readUInt8(0);
|
|
77
|
+
const samplingRate = header.flags.samplingRate * mp * 8; // ToDo: second factor should be read from DSD-metadata block https://github.com/dbry/WavPack/issues/71#issuecomment-483094813
|
|
78
|
+
if (!header.flags.isDSD)
|
|
79
|
+
throw new Error('Only expect DSD block if DSD-flag is set');
|
|
80
|
+
this.metadata.setFormat('sampleRate', samplingRate);
|
|
81
|
+
this.metadata.setFormat('duration', header.totalSamples / samplingRate);
|
|
82
|
+
break;
|
|
83
|
+
case 0x24: // ID_ALT_TRAILER: maybe used to embed original ID3 tag header
|
|
84
|
+
debug('ID_ALT_TRAILER: trailer for non-wav files');
|
|
85
|
+
break;
|
|
86
|
+
case 0x26: // ID_MD5_CHECKSUM
|
|
87
|
+
this.metadata.setFormat('audioMD5', data);
|
|
88
|
+
break;
|
|
89
|
+
case 0x2f: // ID_BLOCK_CHECKSUM
|
|
90
|
+
debug(`ID_BLOCK_CHECKSUM: checksum=${data.toString('hex')}`);
|
|
91
|
+
break;
|
|
92
|
+
default:
|
|
93
|
+
debug(`Ignore unsupported meta-sub-block-id functionId=0x${id.functionId.toString(16)}`);
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
96
|
+
remainingLength -= WavPackToken_1.WavPack.MetadataIdToken.len + (id.largeBlock ? Token.UINT24_LE.len : Token.UINT8.len) + dataSizeInWords * 2;
|
|
97
|
+
debug(`remainingLength=${remainingLength}`);
|
|
98
|
+
if (id.isOddSize)
|
|
99
|
+
this.tokenizer.ignore(1);
|
|
100
|
+
}
|
|
101
|
+
if (remainingLength !== 0)
|
|
102
|
+
throw new Error('metadata-sub-block should fit it remaining length');
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
exports.WavPackParser = WavPackParser;
|
|
@@ -1,64 +1,64 @@
|
|
|
1
|
-
import { IGetToken } from 'strtok3/lib/core';
|
|
2
|
-
/**
|
|
3
|
-
* WavPack Block Header
|
|
4
|
-
*
|
|
5
|
-
* 32-byte little-endian header at the front of every WavPack block
|
|
6
|
-
*
|
|
7
|
-
* Ref:
|
|
8
|
-
* http://www.wavpack.com/WavPack5FileFormat.pdf (page 2/6: 2.0 "Block Header")
|
|
9
|
-
*/
|
|
10
|
-
export interface IBlockHeader {
|
|
11
|
-
BlockID: string;
|
|
12
|
-
blockSize: number;
|
|
13
|
-
version: number;
|
|
14
|
-
blockIndex: number;
|
|
15
|
-
totalSamples: number;
|
|
16
|
-
blockSamples: number;
|
|
17
|
-
flags: {
|
|
18
|
-
bitsPerSample: number;
|
|
19
|
-
isMono: boolean;
|
|
20
|
-
isHybrid: boolean;
|
|
21
|
-
isJointStereo: boolean;
|
|
22
|
-
crossChannel: boolean;
|
|
23
|
-
hybridNoiseShaping: boolean;
|
|
24
|
-
floatingPoint: boolean;
|
|
25
|
-
samplingRate: number;
|
|
26
|
-
isDSD: boolean;
|
|
27
|
-
};
|
|
28
|
-
crc: Uint8Array;
|
|
29
|
-
}
|
|
30
|
-
export interface IMetadataId {
|
|
31
|
-
/**
|
|
32
|
-
* metadata function id
|
|
33
|
-
*/
|
|
34
|
-
functionId: number;
|
|
35
|
-
/**
|
|
36
|
-
* If true, audio-decoder does not need to understand the metadata field
|
|
37
|
-
*/
|
|
38
|
-
isOptional: boolean;
|
|
39
|
-
/**
|
|
40
|
-
* actual data byte length is 1 less
|
|
41
|
-
*/
|
|
42
|
-
isOddSize: boolean;
|
|
43
|
-
/**
|
|
44
|
-
* large block (> 255 words)
|
|
45
|
-
*/
|
|
46
|
-
largeBlock: boolean;
|
|
47
|
-
}
|
|
48
|
-
export declare class WavPack {
|
|
49
|
-
/**
|
|
50
|
-
* WavPack Block Header
|
|
51
|
-
*
|
|
52
|
-
* 32-byte little-endian header at the front of every WavPack block
|
|
53
|
-
*
|
|
54
|
-
* Ref: http://www.wavpack.com/WavPack5FileFormat.pdf (page 2/6: 2.0 "Block Header")
|
|
55
|
-
*/
|
|
56
|
-
static BlockHeaderToken: IGetToken<IBlockHeader>;
|
|
57
|
-
/**
|
|
58
|
-
* 3.0 Metadata Sub-Blocks
|
|
59
|
-
* Ref: http://www.wavpack.com/WavPack5FileFormat.pdf (page 4/6: 3.0 "Metadata Sub-Block")
|
|
60
|
-
*/
|
|
61
|
-
static MetadataIdToken: IGetToken<IMetadataId>;
|
|
62
|
-
private static isBitSet;
|
|
63
|
-
private static getBitAllignedNumber;
|
|
64
|
-
}
|
|
1
|
+
import { IGetToken } from 'strtok3/lib/core';
|
|
2
|
+
/**
|
|
3
|
+
* WavPack Block Header
|
|
4
|
+
*
|
|
5
|
+
* 32-byte little-endian header at the front of every WavPack block
|
|
6
|
+
*
|
|
7
|
+
* Ref:
|
|
8
|
+
* http://www.wavpack.com/WavPack5FileFormat.pdf (page 2/6: 2.0 "Block Header")
|
|
9
|
+
*/
|
|
10
|
+
export interface IBlockHeader {
|
|
11
|
+
BlockID: string;
|
|
12
|
+
blockSize: number;
|
|
13
|
+
version: number;
|
|
14
|
+
blockIndex: number;
|
|
15
|
+
totalSamples: number;
|
|
16
|
+
blockSamples: number;
|
|
17
|
+
flags: {
|
|
18
|
+
bitsPerSample: number;
|
|
19
|
+
isMono: boolean;
|
|
20
|
+
isHybrid: boolean;
|
|
21
|
+
isJointStereo: boolean;
|
|
22
|
+
crossChannel: boolean;
|
|
23
|
+
hybridNoiseShaping: boolean;
|
|
24
|
+
floatingPoint: boolean;
|
|
25
|
+
samplingRate: number;
|
|
26
|
+
isDSD: boolean;
|
|
27
|
+
};
|
|
28
|
+
crc: Uint8Array;
|
|
29
|
+
}
|
|
30
|
+
export interface IMetadataId {
|
|
31
|
+
/**
|
|
32
|
+
* metadata function id
|
|
33
|
+
*/
|
|
34
|
+
functionId: number;
|
|
35
|
+
/**
|
|
36
|
+
* If true, audio-decoder does not need to understand the metadata field
|
|
37
|
+
*/
|
|
38
|
+
isOptional: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* actual data byte length is 1 less
|
|
41
|
+
*/
|
|
42
|
+
isOddSize: boolean;
|
|
43
|
+
/**
|
|
44
|
+
* large block (> 255 words)
|
|
45
|
+
*/
|
|
46
|
+
largeBlock: boolean;
|
|
47
|
+
}
|
|
48
|
+
export declare class WavPack {
|
|
49
|
+
/**
|
|
50
|
+
* WavPack Block Header
|
|
51
|
+
*
|
|
52
|
+
* 32-byte little-endian header at the front of every WavPack block
|
|
53
|
+
*
|
|
54
|
+
* Ref: http://www.wavpack.com/WavPack5FileFormat.pdf (page 2/6: 2.0 "Block Header")
|
|
55
|
+
*/
|
|
56
|
+
static BlockHeaderToken: IGetToken<IBlockHeader>;
|
|
57
|
+
/**
|
|
58
|
+
* 3.0 Metadata Sub-Blocks
|
|
59
|
+
* Ref: http://www.wavpack.com/WavPack5FileFormat.pdf (page 4/6: 3.0 "Metadata Sub-Block")
|
|
60
|
+
*/
|
|
61
|
+
static MetadataIdToken: IGetToken<IMetadataId>;
|
|
62
|
+
private static isBitSet;
|
|
63
|
+
private static getBitAllignedNumber;
|
|
64
|
+
}
|
|
@@ -1,76 +1,76 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.WavPack = void 0;
|
|
4
|
-
const Token = require("token-types");
|
|
5
|
-
const FourCC_1 = require("../common/FourCC");
|
|
6
|
-
const SampleRates = [6000, 8000, 9600, 11025, 12000, 16000, 22050, 24000, 32000, 44100,
|
|
7
|
-
48000, 64000, 88200, 96000, 192000, -1];
|
|
8
|
-
class WavPack {
|
|
9
|
-
static isBitSet(flags, bitOffset) {
|
|
10
|
-
return WavPack.getBitAllignedNumber(flags, bitOffset, 1) === 1;
|
|
11
|
-
}
|
|
12
|
-
static getBitAllignedNumber(flags, bitOffset, len) {
|
|
13
|
-
return (flags >>> bitOffset) & (0xffffffff >>> (32 - len));
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
exports.WavPack = WavPack;
|
|
17
|
-
/**
|
|
18
|
-
* WavPack Block Header
|
|
19
|
-
*
|
|
20
|
-
* 32-byte little-endian header at the front of every WavPack block
|
|
21
|
-
*
|
|
22
|
-
* Ref: http://www.wavpack.com/WavPack5FileFormat.pdf (page 2/6: 2.0 "Block Header")
|
|
23
|
-
*/
|
|
24
|
-
WavPack.BlockHeaderToken = {
|
|
25
|
-
len: 32,
|
|
26
|
-
get: (buf, off) => {
|
|
27
|
-
const flags = Token.UINT32_LE.get(buf, off + 24);
|
|
28
|
-
const res = {
|
|
29
|
-
// should equal 'wvpk'
|
|
30
|
-
BlockID: FourCC_1.FourCcToken.get(buf, off),
|
|
31
|
-
// 0x402 to 0x410 are valid for decode
|
|
32
|
-
blockSize: Token.UINT32_LE.get(buf, off + 4),
|
|
33
|
-
// 0x402 (1026) to 0x410 are valid for decode
|
|
34
|
-
version: Token.UINT16_LE.get(buf, off + 8),
|
|
35
|
-
// 40-bit total samples for entire file (if block_index == 0 and a value of -1 indicates an unknown length)
|
|
36
|
-
totalSamples: /* replace with bigint? (Token.UINT8.get(buf, off + 11) << 32) + */ Token.UINT32_LE.get(buf, off + 12),
|
|
37
|
-
// 40-bit block_index
|
|
38
|
-
blockIndex: /* replace with bigint? (Token.UINT8.get(buf, off + 10) << 32) + */ Token.UINT32_LE.get(buf, off + 16),
|
|
39
|
-
// 40-bit total samples for entire file (if block_index == 0 and a value of -1 indicates an unknown length)
|
|
40
|
-
blockSamples: Token.UINT32_LE.get(buf, off + 20),
|
|
41
|
-
// various flags for id and decoding
|
|
42
|
-
flags: {
|
|
43
|
-
bitsPerSample: (1 + WavPack.getBitAllignedNumber(flags, 0, 2)) * 8,
|
|
44
|
-
isMono: WavPack.isBitSet(flags, 2),
|
|
45
|
-
isHybrid: WavPack.isBitSet(flags, 3),
|
|
46
|
-
isJointStereo: WavPack.isBitSet(flags, 4),
|
|
47
|
-
crossChannel: WavPack.isBitSet(flags, 5),
|
|
48
|
-
hybridNoiseShaping: WavPack.isBitSet(flags, 6),
|
|
49
|
-
floatingPoint: WavPack.isBitSet(flags, 7),
|
|
50
|
-
samplingRate: SampleRates[WavPack.getBitAllignedNumber(flags, 23, 4)],
|
|
51
|
-
isDSD: WavPack.isBitSet(flags, 31)
|
|
52
|
-
},
|
|
53
|
-
// crc for actual decoded data
|
|
54
|
-
crc: new Token.Uint8ArrayType(4).get(buf, off + 28)
|
|
55
|
-
};
|
|
56
|
-
if (res.flags.isDSD) {
|
|
57
|
-
res.totalSamples *= 8;
|
|
58
|
-
}
|
|
59
|
-
return res;
|
|
60
|
-
}
|
|
61
|
-
};
|
|
62
|
-
/**
|
|
63
|
-
* 3.0 Metadata Sub-Blocks
|
|
64
|
-
* Ref: http://www.wavpack.com/WavPack5FileFormat.pdf (page 4/6: 3.0 "Metadata Sub-Block")
|
|
65
|
-
*/
|
|
66
|
-
WavPack.MetadataIdToken = {
|
|
67
|
-
len: 1,
|
|
68
|
-
get: (buf, off) => {
|
|
69
|
-
return {
|
|
70
|
-
functionId: WavPack.getBitAllignedNumber(buf[off], 0, 6),
|
|
71
|
-
isOptional: WavPack.isBitSet(buf[off], 5),
|
|
72
|
-
isOddSize: WavPack.isBitSet(buf[off], 6),
|
|
73
|
-
largeBlock: WavPack.isBitSet(buf[off], 7)
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
};
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WavPack = void 0;
|
|
4
|
+
const Token = require("token-types");
|
|
5
|
+
const FourCC_1 = require("../common/FourCC");
|
|
6
|
+
const SampleRates = [6000, 8000, 9600, 11025, 12000, 16000, 22050, 24000, 32000, 44100,
|
|
7
|
+
48000, 64000, 88200, 96000, 192000, -1];
|
|
8
|
+
class WavPack {
|
|
9
|
+
static isBitSet(flags, bitOffset) {
|
|
10
|
+
return WavPack.getBitAllignedNumber(flags, bitOffset, 1) === 1;
|
|
11
|
+
}
|
|
12
|
+
static getBitAllignedNumber(flags, bitOffset, len) {
|
|
13
|
+
return (flags >>> bitOffset) & (0xffffffff >>> (32 - len));
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
exports.WavPack = WavPack;
|
|
17
|
+
/**
|
|
18
|
+
* WavPack Block Header
|
|
19
|
+
*
|
|
20
|
+
* 32-byte little-endian header at the front of every WavPack block
|
|
21
|
+
*
|
|
22
|
+
* Ref: http://www.wavpack.com/WavPack5FileFormat.pdf (page 2/6: 2.0 "Block Header")
|
|
23
|
+
*/
|
|
24
|
+
WavPack.BlockHeaderToken = {
|
|
25
|
+
len: 32,
|
|
26
|
+
get: (buf, off) => {
|
|
27
|
+
const flags = Token.UINT32_LE.get(buf, off + 24);
|
|
28
|
+
const res = {
|
|
29
|
+
// should equal 'wvpk'
|
|
30
|
+
BlockID: FourCC_1.FourCcToken.get(buf, off),
|
|
31
|
+
// 0x402 to 0x410 are valid for decode
|
|
32
|
+
blockSize: Token.UINT32_LE.get(buf, off + 4),
|
|
33
|
+
// 0x402 (1026) to 0x410 are valid for decode
|
|
34
|
+
version: Token.UINT16_LE.get(buf, off + 8),
|
|
35
|
+
// 40-bit total samples for entire file (if block_index == 0 and a value of -1 indicates an unknown length)
|
|
36
|
+
totalSamples: /* replace with bigint? (Token.UINT8.get(buf, off + 11) << 32) + */ Token.UINT32_LE.get(buf, off + 12),
|
|
37
|
+
// 40-bit block_index
|
|
38
|
+
blockIndex: /* replace with bigint? (Token.UINT8.get(buf, off + 10) << 32) + */ Token.UINT32_LE.get(buf, off + 16),
|
|
39
|
+
// 40-bit total samples for entire file (if block_index == 0 and a value of -1 indicates an unknown length)
|
|
40
|
+
blockSamples: Token.UINT32_LE.get(buf, off + 20),
|
|
41
|
+
// various flags for id and decoding
|
|
42
|
+
flags: {
|
|
43
|
+
bitsPerSample: (1 + WavPack.getBitAllignedNumber(flags, 0, 2)) * 8,
|
|
44
|
+
isMono: WavPack.isBitSet(flags, 2),
|
|
45
|
+
isHybrid: WavPack.isBitSet(flags, 3),
|
|
46
|
+
isJointStereo: WavPack.isBitSet(flags, 4),
|
|
47
|
+
crossChannel: WavPack.isBitSet(flags, 5),
|
|
48
|
+
hybridNoiseShaping: WavPack.isBitSet(flags, 6),
|
|
49
|
+
floatingPoint: WavPack.isBitSet(flags, 7),
|
|
50
|
+
samplingRate: SampleRates[WavPack.getBitAllignedNumber(flags, 23, 4)],
|
|
51
|
+
isDSD: WavPack.isBitSet(flags, 31)
|
|
52
|
+
},
|
|
53
|
+
// crc for actual decoded data
|
|
54
|
+
crc: new Token.Uint8ArrayType(4).get(buf, off + 28)
|
|
55
|
+
};
|
|
56
|
+
if (res.flags.isDSD) {
|
|
57
|
+
res.totalSamples *= 8;
|
|
58
|
+
}
|
|
59
|
+
return res;
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* 3.0 Metadata Sub-Blocks
|
|
64
|
+
* Ref: http://www.wavpack.com/WavPack5FileFormat.pdf (page 4/6: 3.0 "Metadata Sub-Block")
|
|
65
|
+
*/
|
|
66
|
+
WavPack.MetadataIdToken = {
|
|
67
|
+
len: 1,
|
|
68
|
+
get: (buf, off) => {
|
|
69
|
+
return {
|
|
70
|
+
functionId: WavPack.getBitAllignedNumber(buf[off], 0, 6),
|
|
71
|
+
isOptional: WavPack.isBitSet(buf[off], 5),
|
|
72
|
+
isOddSize: WavPack.isBitSet(buf[off], 6),
|
|
73
|
+
largeBlock: WavPack.isBitSet(buf[off], 7)
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
};
|