music-metadata 10.0.1 → 10.2.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/LICENSE.txt +9 -9
- package/README.md +535 -520
- package/lib/ParserFactory.d.ts +20 -28
- package/lib/ParserFactory.js +204 -207
- package/lib/aiff/AiffParser.js +20 -19
- package/lib/aiff/AiffToken.d.ts +14 -2
- package/lib/aiff/AiffToken.js +12 -0
- package/lib/apev2/APEv2Parser.d.ts +4 -4
- package/lib/apev2/APEv2Parser.js +12 -10
- package/lib/apev2/APEv2Token.d.ts +2 -4
- package/lib/apev2/APEv2Token.js +0 -3
- package/lib/asf/AsfObject.d.ts +7 -16
- package/lib/asf/AsfObject.js +8 -34
- package/lib/asf/AsfParser.js +17 -10
- package/lib/asf/AsfTagMapper.d.ts +1 -1
- package/lib/asf/AsfTagMapper.js +3 -2
- package/lib/asf/AsfUtil.d.ts +3 -11
- package/lib/asf/AsfUtil.js +29 -30
- package/lib/asf/GUID.js +6 -9
- package/lib/common/BasicParser.d.ts +4 -4
- package/lib/common/BasicParser.js +6 -0
- package/lib/common/CaseInsensitiveTagMap.d.ts +1 -1
- package/lib/common/CombinedTagMapper.d.ts +5 -5
- package/lib/common/CombinedTagMapper.js +1 -1
- package/lib/common/FourCC.d.ts +1 -1
- package/lib/common/GenericTagMapper.d.ts +8 -8
- package/lib/common/GenericTagMapper.js +4 -4
- package/lib/common/GenericTagTypes.d.ts +5 -4
- package/lib/common/GenericTagTypes.js +2 -2
- package/lib/common/MetadataCollector.d.ts +9 -9
- package/lib/common/MetadataCollector.js +22 -17
- package/lib/common/RandomFileReader.d.ts +1 -1
- package/lib/common/RandomFileReader.js +1 -1
- package/lib/common/RandomUint8ArrayReader.d.ts +1 -1
- package/lib/common/Util.d.ts +2 -6
- package/lib/common/Util.js +9 -11
- package/lib/core.d.ts +7 -9
- package/lib/core.js +10 -7
- package/lib/dsdiff/DsdiffParser.js +26 -14
- package/lib/dsdiff/DsdiffToken.d.ts +2 -2
- package/lib/dsdiff/DsdiffToken.js +1 -0
- package/lib/dsf/DsfChunk.js +1 -0
- package/lib/dsf/DsfParser.js +4 -2
- package/lib/ebml/EbmlIterator.d.ts +52 -0
- package/lib/ebml/EbmlIterator.js +220 -0
- package/lib/ebml/types.d.ts +36 -0
- package/lib/ebml/types.js +10 -0
- package/lib/flac/FlacParser.d.ts +3 -3
- package/lib/flac/FlacParser.js +9 -12
- package/lib/id3v1/ID3v1Parser.d.ts +1 -1
- package/lib/id3v1/ID3v1Parser.js +7 -4
- package/lib/id3v2/AbstractID3Parser.d.ts +1 -1
- package/lib/id3v2/AbstractID3Parser.js +2 -1
- package/lib/id3v2/FrameParser.d.ts +28 -3
- package/lib/id3v2/FrameParser.js +50 -28
- package/lib/id3v2/ID3v22TagMapper.d.ts +1 -1
- package/lib/id3v2/ID3v24TagMapper.d.ts +2 -1
- package/lib/id3v2/ID3v24TagMapper.js +23 -16
- package/lib/id3v2/ID3v2Parser.d.ts +2 -2
- package/lib/id3v2/ID3v2Parser.js +18 -8
- package/lib/iff/index.js +1 -0
- package/lib/index.d.ts +5 -6
- package/lib/index.js +7 -8
- package/lib/lyrics3/Lyrics3.d.ts +1 -1
- package/lib/lyrics3/Lyrics3.js +1 -1
- package/lib/matroska/MatroskaDtd.d.ts +2 -2
- package/lib/matroska/MatroskaDtd.js +247 -239
- package/lib/matroska/MatroskaParser.d.ts +10 -24
- package/lib/matroska/MatroskaParser.js +120 -205
- package/lib/matroska/types.d.ts +12 -46
- package/lib/matroska/types.js +0 -9
- package/lib/mp4/Atom.d.ts +3 -3
- package/lib/mp4/Atom.js +4 -7
- package/lib/mp4/AtomToken.js +2 -1
- package/lib/mp4/MP4Parser.js +29 -20
- package/lib/mp4/MP4TagMapper.d.ts +2 -2
- package/lib/mp4/MP4TagMapper.js +1 -1
- package/lib/mpeg/ExtendedLameHeader.d.ts +4 -4
- package/lib/mpeg/ExtendedLameHeader.js +2 -1
- package/lib/mpeg/MpegParser.d.ts +1 -1
- package/lib/mpeg/MpegParser.js +145 -96
- package/lib/mpeg/ReplayGainDataFormat.d.ts +1 -1
- package/lib/mpeg/ReplayGainDataFormat.js +1 -0
- package/lib/mpeg/XingTag.d.ts +4 -4
- package/lib/mpeg/XingTag.js +5 -4
- package/lib/musepack/index.js +1 -0
- package/lib/musepack/sv7/BitReader.js +14 -17
- package/lib/musepack/sv7/MpcSv7Parser.js +6 -1
- package/lib/musepack/sv7/StreamVersion7.js +1 -0
- package/lib/musepack/sv8/MpcSv8Parser.js +6 -2
- package/lib/musepack/sv8/StreamVersion8.d.ts +1 -1
- package/lib/musepack/sv8/StreamVersion8.js +1 -0
- package/lib/ogg/Ogg.d.ts +1 -1
- package/lib/ogg/Ogg.js +1 -0
- package/lib/ogg/OggParser.d.ts +3 -3
- package/lib/ogg/OggParser.js +25 -16
- package/lib/ogg/opus/Opus.d.ts +1 -1
- package/lib/ogg/opus/Opus.js +1 -0
- package/lib/ogg/opus/OpusParser.d.ts +4 -4
- package/lib/ogg/opus/OpusParser.js +2 -0
- package/lib/ogg/speex/Speex.js +1 -0
- package/lib/ogg/speex/SpeexParser.d.ts +4 -4
- package/lib/ogg/speex/SpeexParser.js +1 -0
- package/lib/ogg/theora/Theora.js +1 -0
- package/lib/ogg/theora/TheoraParser.d.ts +4 -4
- package/lib/ogg/theora/TheoraParser.js +1 -0
- package/lib/ogg/vorbis/Vorbis.d.ts +3 -3
- package/lib/ogg/vorbis/Vorbis.js +22 -11
- package/lib/ogg/vorbis/VorbisDecoder.d.ts +1 -1
- package/lib/ogg/vorbis/VorbisDecoder.js +1 -0
- package/lib/ogg/vorbis/VorbisParser.d.ts +4 -4
- package/lib/ogg/vorbis/VorbisParser.js +3 -2
- package/lib/ogg/vorbis/VorbisTagMapper.d.ts +2 -2
- package/lib/ogg/vorbis/VorbisTagMapper.js +2 -2
- package/lib/riff/RiffChunk.d.ts +3 -3
- package/lib/riff/RiffChunk.js +1 -0
- package/lib/riff/RiffInfoTagMap.d.ts +1 -1
- package/lib/type.d.ts +44 -25
- package/lib/wav/BwfChunk.js +1 -0
- package/lib/wav/WaveChunk.d.ts +1 -1
- package/lib/wav/WaveChunk.js +1 -0
- package/lib/wav/WaveParser.js +27 -17
- package/lib/wavpack/WavPackParser.d.ts +1 -1
- package/lib/wavpack/WavPackParser.js +22 -13
- package/lib/wavpack/WavPackToken.d.ts +13 -17
- package/lib/wavpack/WavPackToken.js +22 -23
- package/package.json +139 -150
package/lib/wav/WaveParser.js
CHANGED
|
@@ -2,12 +2,12 @@ import * as strtok3 from 'strtok3';
|
|
|
2
2
|
import * as Token from 'token-types';
|
|
3
3
|
import initDebug from 'debug';
|
|
4
4
|
import * as riff from '../riff/RiffChunk.js';
|
|
5
|
-
import * as WaveChunk from '
|
|
5
|
+
import * as WaveChunk from './WaveChunk.js';
|
|
6
6
|
import { ID3v2Parser } from '../id3v2/ID3v2Parser.js';
|
|
7
7
|
import * as util from '../common/Util.js';
|
|
8
8
|
import { FourCcToken } from '../common/FourCC.js';
|
|
9
9
|
import { BasicParser } from '../common/BasicParser.js';
|
|
10
|
-
import { BroadcastAudioExtensionChunk } from '
|
|
10
|
+
import { BroadcastAudioExtensionChunk } from './BwfChunk.js';
|
|
11
11
|
const debug = initDebug('music-metadata:parser:RIFF');
|
|
12
12
|
/**
|
|
13
13
|
* Resource Interchange File Format (RIFF) Parser
|
|
@@ -21,6 +21,10 @@ const debug = initDebug('music-metadata:parser:RIFF');
|
|
|
21
21
|
* ToDo: Split WAVE part from RIFF parser
|
|
22
22
|
*/
|
|
23
23
|
export class WaveParser extends BasicParser {
|
|
24
|
+
constructor() {
|
|
25
|
+
super(...arguments);
|
|
26
|
+
this.blockAlign = 0;
|
|
27
|
+
}
|
|
24
28
|
async parse() {
|
|
25
29
|
const riffHeader = await this.tokenizer.readToken(riff.Header);
|
|
26
30
|
debug(`pos=${this.tokenizer.position}, parse: chunkID=${riffHeader.chunkID}`);
|
|
@@ -59,12 +63,12 @@ export class WaveParser extends BasicParser {
|
|
|
59
63
|
this.metadata.setFormat('lossless', false);
|
|
60
64
|
this.fact = await this.tokenizer.readToken(new WaveChunk.FactChunk(header));
|
|
61
65
|
break;
|
|
62
|
-
case 'fmt ': // The Util Chunk, non-PCM Formats
|
|
66
|
+
case 'fmt ': { // The Util Chunk, non-PCM Formats
|
|
63
67
|
const fmt = await this.tokenizer.readToken(new WaveChunk.Format(header));
|
|
64
68
|
let subFormat = WaveChunk.WaveFormat[fmt.wFormatTag];
|
|
65
69
|
if (!subFormat) {
|
|
66
|
-
debug(
|
|
67
|
-
subFormat =
|
|
70
|
+
debug(`WAVE/non-PCM format=${fmt.wFormatTag}`);
|
|
71
|
+
subFormat = `non-PCM (${fmt.wFormatTag})`;
|
|
68
72
|
}
|
|
69
73
|
this.metadata.setFormat('codec', subFormat);
|
|
70
74
|
this.metadata.setFormat('bitsPerSample', fmt.wBitsPerSample);
|
|
@@ -73,13 +77,15 @@ export class WaveParser extends BasicParser {
|
|
|
73
77
|
this.metadata.setFormat('bitrate', fmt.nBlockAlign * fmt.nSamplesPerSec * 8);
|
|
74
78
|
this.blockAlign = fmt.nBlockAlign;
|
|
75
79
|
break;
|
|
80
|
+
}
|
|
76
81
|
case 'id3 ': // The way Picard, FooBar currently stores, ID3 meta-data
|
|
77
|
-
case 'ID3 ': // The way Mp3Tags stores ID3 meta-data
|
|
82
|
+
case 'ID3 ': { // The way Mp3Tags stores ID3 meta-data
|
|
78
83
|
const id3_data = await this.tokenizer.readToken(new Token.Uint8ArrayType(header.chunkSize));
|
|
79
84
|
const rst = strtok3.fromBuffer(id3_data);
|
|
80
85
|
await new ID3v2Parser().parse(this.metadata, rst, this.options);
|
|
81
86
|
break;
|
|
82
|
-
|
|
87
|
+
}
|
|
88
|
+
case 'data': { // PCM-data
|
|
83
89
|
if (this.metadata.format.lossless !== false) {
|
|
84
90
|
this.metadata.setFormat('lossless', true);
|
|
85
91
|
}
|
|
@@ -94,32 +100,36 @@ export class WaveParser extends BasicParser {
|
|
|
94
100
|
const numberOfSamples = this.fact ? this.fact.dwSampleLength : (chunkSize === 0xffffffff ? undefined : chunkSize / this.blockAlign);
|
|
95
101
|
if (numberOfSamples) {
|
|
96
102
|
this.metadata.setFormat('numberOfSamples', numberOfSamples);
|
|
97
|
-
|
|
103
|
+
if (this.metadata.format.sampleRate) {
|
|
104
|
+
this.metadata.setFormat('duration', numberOfSamples / this.metadata.format.sampleRate);
|
|
105
|
+
}
|
|
98
106
|
}
|
|
99
107
|
if (this.metadata.format.codec === 'ADPCM') { // ADPCM is 4 bits lossy encoding resulting in 352kbps
|
|
100
108
|
this.metadata.setFormat('bitrate', 352000);
|
|
101
109
|
}
|
|
102
|
-
else {
|
|
110
|
+
else if (this.metadata.format.sampleRate) {
|
|
103
111
|
this.metadata.setFormat('bitrate', this.blockAlign * this.metadata.format.sampleRate * 8);
|
|
104
112
|
}
|
|
105
113
|
await this.tokenizer.ignore(header.chunkSize);
|
|
106
114
|
break;
|
|
107
|
-
|
|
115
|
+
}
|
|
116
|
+
case 'bext': { // Broadcast Audio Extension chunk https://tech.ebu.ch/docs/tech/tech3285.pdf
|
|
108
117
|
const bext = await this.tokenizer.readToken(BroadcastAudioExtensionChunk);
|
|
109
118
|
Object.keys(bext).forEach(key => {
|
|
110
|
-
this.metadata.addTag('exif',
|
|
119
|
+
this.metadata.addTag('exif', `bext.${key}`, bext[key]);
|
|
111
120
|
});
|
|
112
121
|
const bextRemaining = header.chunkSize - BroadcastAudioExtensionChunk.len;
|
|
113
122
|
await this.tokenizer.ignore(bextRemaining);
|
|
114
123
|
break;
|
|
124
|
+
}
|
|
115
125
|
case '\x00\x00\x00\x00': // padding ??
|
|
116
126
|
debug(`Ignore padding chunk: RIFF/${header.chunkID} of ${header.chunkSize} bytes`);
|
|
117
|
-
this.metadata.addWarning(
|
|
127
|
+
this.metadata.addWarning(`Ignore chunk: RIFF/${header.chunkID}`);
|
|
118
128
|
await this.tokenizer.ignore(header.chunkSize);
|
|
119
129
|
break;
|
|
120
130
|
default:
|
|
121
131
|
debug(`Ignore chunk: RIFF/${header.chunkID} of ${header.chunkSize} bytes`);
|
|
122
|
-
this.metadata.addWarning(
|
|
132
|
+
this.metadata.addWarning(`Ignore chunk: RIFF/${header.chunkID}`);
|
|
123
133
|
await this.tokenizer.ignore(header.chunkSize);
|
|
124
134
|
}
|
|
125
135
|
if (this.header.chunkSize % 2 === 1) {
|
|
@@ -134,10 +144,9 @@ export class WaveParser extends BasicParser {
|
|
|
134
144
|
switch (listType) {
|
|
135
145
|
case 'INFO':
|
|
136
146
|
return this.parseRiffInfoTags(listHeader.chunkSize - 4);
|
|
137
|
-
case 'adtl':
|
|
138
147
|
default:
|
|
139
|
-
this.metadata.addWarning(
|
|
140
|
-
debug(
|
|
148
|
+
this.metadata.addWarning(`Ignore chunk: RIFF/WAVE/LIST/${listType}`);
|
|
149
|
+
debug(`Ignoring chunkID=RIFF/WAVE/LIST/${listType}`);
|
|
141
150
|
return this.tokenizer.ignore(listHeader.chunkSize - 4).then();
|
|
142
151
|
}
|
|
143
152
|
}
|
|
@@ -150,10 +159,11 @@ export class WaveParser extends BasicParser {
|
|
|
150
159
|
chunkSize -= (8 + valueToken.len);
|
|
151
160
|
}
|
|
152
161
|
if (chunkSize !== 0) {
|
|
153
|
-
throw Error(
|
|
162
|
+
throw new Error(`Illegal remaining size: ${chunkSize}`);
|
|
154
163
|
}
|
|
155
164
|
}
|
|
156
165
|
addTag(id, value) {
|
|
157
166
|
this.metadata.addTag('exif', id, value);
|
|
158
167
|
}
|
|
159
168
|
}
|
|
169
|
+
//# sourceMappingURL=WaveParser.js.map
|
|
@@ -9,7 +9,7 @@ export declare class WavPackParser extends BasicParser {
|
|
|
9
9
|
/**
|
|
10
10
|
* Ref: http://www.wavpack.com/WavPack5FileFormat.pdf, 3.0 Metadata Sub-blocks
|
|
11
11
|
* @param header Header
|
|
12
|
-
* @param remainingLength
|
|
12
|
+
* @param remainingLength Remaining length
|
|
13
13
|
*/
|
|
14
14
|
private parseMetadataSubBlock;
|
|
15
15
|
}
|
|
@@ -2,7 +2,7 @@ import * as Token from 'token-types';
|
|
|
2
2
|
import { APEv2Parser } from '../apev2/APEv2Parser.js';
|
|
3
3
|
import { FourCcToken } from '../common/FourCC.js';
|
|
4
4
|
import { BasicParser } from '../common/BasicParser.js';
|
|
5
|
-
import {
|
|
5
|
+
import { BlockHeaderToken, MetadataIdToken } from './WavPackToken.js';
|
|
6
6
|
import initDebug from 'debug';
|
|
7
7
|
import { uint8ArrayToHex } from 'uint8array-extras';
|
|
8
8
|
const debug = initDebug('music-metadata:parser:WavPack');
|
|
@@ -10,6 +10,10 @@ const debug = initDebug('music-metadata:parser:WavPack');
|
|
|
10
10
|
* WavPack Parser
|
|
11
11
|
*/
|
|
12
12
|
export class WavPackParser extends BasicParser {
|
|
13
|
+
constructor() {
|
|
14
|
+
super(...arguments);
|
|
15
|
+
this.audioDataSize = 0;
|
|
16
|
+
}
|
|
13
17
|
async parse() {
|
|
14
18
|
this.audioDataSize = 0;
|
|
15
19
|
// First parse all WavPack blocks
|
|
@@ -22,10 +26,10 @@ export class WavPackParser extends BasicParser {
|
|
|
22
26
|
const blockId = await this.tokenizer.peekToken(FourCcToken);
|
|
23
27
|
if (blockId !== 'wvpk')
|
|
24
28
|
break;
|
|
25
|
-
const header = await this.tokenizer.readToken(
|
|
29
|
+
const header = await this.tokenizer.readToken(BlockHeaderToken);
|
|
26
30
|
if (header.BlockID !== 'wvpk')
|
|
27
31
|
throw new Error('Invalid WavPack Block-ID');
|
|
28
|
-
debug(`WavPack header blockIndex=${header.blockIndex}, len=${
|
|
32
|
+
debug(`WavPack header blockIndex=${header.blockIndex}, len=${BlockHeaderToken.len}`);
|
|
29
33
|
if (header.blockIndex === 0 && !this.metadata.format.container) {
|
|
30
34
|
this.metadata.setFormat('container', 'WavPack');
|
|
31
35
|
this.metadata.setFormat('lossless', !header.flags.isHybrid);
|
|
@@ -40,22 +44,25 @@ export class WavPackParser extends BasicParser {
|
|
|
40
44
|
this.metadata.setFormat('numberOfSamples', header.totalSamples);
|
|
41
45
|
this.metadata.setFormat('codec', header.flags.isDSD ? 'DSD' : 'PCM');
|
|
42
46
|
}
|
|
43
|
-
const ignoreBytes = header.blockSize - (
|
|
47
|
+
const ignoreBytes = header.blockSize - (BlockHeaderToken.len - 8);
|
|
44
48
|
await (header.blockIndex === 0 ? this.parseMetadataSubBlock(header, ignoreBytes) : this.tokenizer.ignore(ignoreBytes));
|
|
45
49
|
if (header.blockSamples > 0) {
|
|
46
50
|
this.audioDataSize += header.blockSize; // Count audio data for bit-rate calculation
|
|
47
51
|
}
|
|
48
|
-
} while (!this.tokenizer.fileInfo.size || this.tokenizer.fileInfo.size - this.tokenizer.position >=
|
|
49
|
-
|
|
52
|
+
} while (!this.tokenizer.fileInfo.size || this.tokenizer.fileInfo.size - this.tokenizer.position >= BlockHeaderToken.len);
|
|
53
|
+
if (this.metadata.format.duration) {
|
|
54
|
+
this.metadata.setFormat('bitrate', this.audioDataSize * 8 / this.metadata.format.duration);
|
|
55
|
+
}
|
|
50
56
|
}
|
|
51
57
|
/**
|
|
52
58
|
* Ref: http://www.wavpack.com/WavPack5FileFormat.pdf, 3.0 Metadata Sub-blocks
|
|
53
59
|
* @param header Header
|
|
54
|
-
* @param remainingLength
|
|
60
|
+
* @param remainingLength Remaining length
|
|
55
61
|
*/
|
|
56
62
|
async parseMetadataSubBlock(header, remainingLength) {
|
|
57
|
-
|
|
58
|
-
|
|
63
|
+
let remaining = remainingLength;
|
|
64
|
+
while (remaining > MetadataIdToken.len) {
|
|
65
|
+
const id = await this.tokenizer.readToken(MetadataIdToken);
|
|
59
66
|
const dataSizeInWords = await this.tokenizer.readNumber(id.largeBlock ? Token.UINT24_LE : Token.UINT8);
|
|
60
67
|
const data = new Uint8Array(dataSizeInWords * 2 - (id.isOddSize ? 1 : 0));
|
|
61
68
|
await this.tokenizer.readBuffer(data);
|
|
@@ -63,7 +70,7 @@ export class WavPackParser extends BasicParser {
|
|
|
63
70
|
switch (id.functionId) {
|
|
64
71
|
case 0x0: // ID_DUMMY: could be used to pad WavPack blocks
|
|
65
72
|
break;
|
|
66
|
-
case 0xe: // ID_DSD_BLOCK
|
|
73
|
+
case 0xe: { // ID_DSD_BLOCK
|
|
67
74
|
debug('ID_DSD_BLOCK');
|
|
68
75
|
// https://github.com/dbry/WavPack/issues/71#issuecomment-483094813
|
|
69
76
|
const mp = 1 << Token.UINT8.get(data, 0);
|
|
@@ -73,6 +80,7 @@ export class WavPackParser extends BasicParser {
|
|
|
73
80
|
this.metadata.setFormat('sampleRate', samplingRate);
|
|
74
81
|
this.metadata.setFormat('duration', header.totalSamples / samplingRate);
|
|
75
82
|
break;
|
|
83
|
+
}
|
|
76
84
|
case 0x24: // ID_ALT_TRAILER: maybe used to embed original ID3 tag header
|
|
77
85
|
debug('ID_ALT_TRAILER: trailer for non-wav files');
|
|
78
86
|
break;
|
|
@@ -86,12 +94,13 @@ export class WavPackParser extends BasicParser {
|
|
|
86
94
|
debug(`Ignore unsupported meta-sub-block-id functionId=0x${id.functionId.toString(16)}`);
|
|
87
95
|
break;
|
|
88
96
|
}
|
|
89
|
-
|
|
90
|
-
debug(`remainingLength=${
|
|
97
|
+
remaining -= MetadataIdToken.len + (id.largeBlock ? Token.UINT24_LE.len : Token.UINT8.len) + dataSizeInWords * 2;
|
|
98
|
+
debug(`remainingLength=${remaining}`);
|
|
91
99
|
if (id.isOddSize)
|
|
92
100
|
this.tokenizer.ignore(1);
|
|
93
101
|
}
|
|
94
|
-
if (
|
|
102
|
+
if (remaining !== 0)
|
|
95
103
|
throw new Error('metadata-sub-block should fit it remaining length');
|
|
96
104
|
}
|
|
97
105
|
}
|
|
106
|
+
//# sourceMappingURL=WavPackParser.js.map
|
|
@@ -45,20 +45,16 @@ export interface IMetadataId {
|
|
|
45
45
|
*/
|
|
46
46
|
largeBlock: boolean;
|
|
47
47
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
static MetadataIdToken: IGetToken<IMetadataId>;
|
|
62
|
-
private static isBitSet;
|
|
63
|
-
private static getBitAllignedNumber;
|
|
64
|
-
}
|
|
48
|
+
/**
|
|
49
|
+
* WavPack Block Header
|
|
50
|
+
*
|
|
51
|
+
* 32-byte little-endian header at the front of every WavPack block
|
|
52
|
+
*
|
|
53
|
+
* Ref: http://www.wavpack.com/WavPack5FileFormat.pdf (page 2/6: 2.0 "Block Header")
|
|
54
|
+
*/
|
|
55
|
+
export declare const BlockHeaderToken: IGetToken<IBlockHeader>;
|
|
56
|
+
/**
|
|
57
|
+
* 3.0 Metadata Sub-Blocks
|
|
58
|
+
* Ref: http://www.wavpack.com/WavPack5FileFormat.pdf (page 4/6: 3.0 "Metadata Sub-Block")
|
|
59
|
+
*/
|
|
60
|
+
export declare const MetadataIdToken: IGetToken<IMetadataId>;
|
|
@@ -2,14 +2,6 @@ import * as Token from 'token-types';
|
|
|
2
2
|
import { FourCcToken } from '../common/FourCC.js';
|
|
3
3
|
const SampleRates = [6000, 8000, 9600, 11025, 12000, 16000, 22050, 24000, 32000, 44100,
|
|
4
4
|
48000, 64000, 88200, 96000, 192000, -1];
|
|
5
|
-
export class WavPack {
|
|
6
|
-
static isBitSet(flags, bitOffset) {
|
|
7
|
-
return WavPack.getBitAllignedNumber(flags, bitOffset, 1) === 1;
|
|
8
|
-
}
|
|
9
|
-
static getBitAllignedNumber(flags, bitOffset, len) {
|
|
10
|
-
return (flags >>> bitOffset) & (0xffffffff >>> (32 - len));
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
5
|
/**
|
|
14
6
|
* WavPack Block Header
|
|
15
7
|
*
|
|
@@ -17,7 +9,7 @@ export class WavPack {
|
|
|
17
9
|
*
|
|
18
10
|
* Ref: http://www.wavpack.com/WavPack5FileFormat.pdf (page 2/6: 2.0 "Block Header")
|
|
19
11
|
*/
|
|
20
|
-
|
|
12
|
+
export const BlockHeaderToken = {
|
|
21
13
|
len: 32,
|
|
22
14
|
get: (buf, off) => {
|
|
23
15
|
const flags = Token.UINT32_LE.get(buf, off + 24);
|
|
@@ -36,15 +28,15 @@ WavPack.BlockHeaderToken = {
|
|
|
36
28
|
blockSamples: Token.UINT32_LE.get(buf, off + 20),
|
|
37
29
|
// various flags for id and decoding
|
|
38
30
|
flags: {
|
|
39
|
-
bitsPerSample: (1 +
|
|
40
|
-
isMono:
|
|
41
|
-
isHybrid:
|
|
42
|
-
isJointStereo:
|
|
43
|
-
crossChannel:
|
|
44
|
-
hybridNoiseShaping:
|
|
45
|
-
floatingPoint:
|
|
46
|
-
samplingRate: SampleRates[
|
|
47
|
-
isDSD:
|
|
31
|
+
bitsPerSample: (1 + getBitAllignedNumber(flags, 0, 2)) * 8,
|
|
32
|
+
isMono: isBitSet(flags, 2),
|
|
33
|
+
isHybrid: isBitSet(flags, 3),
|
|
34
|
+
isJointStereo: isBitSet(flags, 4),
|
|
35
|
+
crossChannel: isBitSet(flags, 5),
|
|
36
|
+
hybridNoiseShaping: isBitSet(flags, 6),
|
|
37
|
+
floatingPoint: isBitSet(flags, 7),
|
|
38
|
+
samplingRate: SampleRates[getBitAllignedNumber(flags, 23, 4)],
|
|
39
|
+
isDSD: isBitSet(flags, 31)
|
|
48
40
|
},
|
|
49
41
|
// crc for actual decoded data
|
|
50
42
|
crc: new Token.Uint8ArrayType(4).get(buf, off + 28)
|
|
@@ -59,14 +51,21 @@ WavPack.BlockHeaderToken = {
|
|
|
59
51
|
* 3.0 Metadata Sub-Blocks
|
|
60
52
|
* Ref: http://www.wavpack.com/WavPack5FileFormat.pdf (page 4/6: 3.0 "Metadata Sub-Block")
|
|
61
53
|
*/
|
|
62
|
-
|
|
54
|
+
export const MetadataIdToken = {
|
|
63
55
|
len: 1,
|
|
64
56
|
get: (buf, off) => {
|
|
65
57
|
return {
|
|
66
|
-
functionId:
|
|
67
|
-
isOptional:
|
|
68
|
-
isOddSize:
|
|
69
|
-
largeBlock:
|
|
58
|
+
functionId: getBitAllignedNumber(buf[off], 0, 6), // functionId overlaps with isOptional flag
|
|
59
|
+
isOptional: isBitSet(buf[off], 5),
|
|
60
|
+
isOddSize: isBitSet(buf[off], 6),
|
|
61
|
+
largeBlock: isBitSet(buf[off], 7)
|
|
70
62
|
};
|
|
71
63
|
}
|
|
72
64
|
};
|
|
65
|
+
function isBitSet(flags, bitOffset) {
|
|
66
|
+
return getBitAllignedNumber(flags, bitOffset, 1) === 1;
|
|
67
|
+
}
|
|
68
|
+
function getBitAllignedNumber(flags, bitOffset, len) {
|
|
69
|
+
return (flags >>> bitOffset) & (0xffffffff >>> (32 - len));
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=WavPackToken.js.map
|
package/package.json
CHANGED
|
@@ -1,150 +1,139 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "music-metadata",
|
|
3
|
-
"description": "Music metadata parser for Node.js, supporting virtual any audio and tag format.",
|
|
4
|
-
"version": "10.0
|
|
5
|
-
"author": {
|
|
6
|
-
"name": "Borewit",
|
|
7
|
-
"url": "https://github.com/Borewit"
|
|
8
|
-
},
|
|
9
|
-
"funding": [
|
|
10
|
-
{
|
|
11
|
-
"type": "github",
|
|
12
|
-
"url": "https://github.com/sponsors/Borewit"
|
|
13
|
-
},
|
|
14
|
-
{
|
|
15
|
-
"type": "buymeacoffee",
|
|
16
|
-
"url": "https://buymeacoffee.com/borewit"
|
|
17
|
-
}
|
|
18
|
-
],
|
|
19
|
-
"type": "module",
|
|
20
|
-
"exports": {
|
|
21
|
-
".": {
|
|
22
|
-
"node": "./lib/index.js",
|
|
23
|
-
"default": "./lib/core.js"
|
|
24
|
-
}
|
|
25
|
-
},
|
|
26
|
-
"types": "lib/index.d.ts",
|
|
27
|
-
"files": [
|
|
28
|
-
"lib/**/*.js",
|
|
29
|
-
"lib/**/*.d.ts"
|
|
30
|
-
],
|
|
31
|
-
"keywords": [
|
|
32
|
-
"music",
|
|
33
|
-
"metadata",
|
|
34
|
-
"meta",
|
|
35
|
-
"audio",
|
|
36
|
-
"tag",
|
|
37
|
-
"tags",
|
|
38
|
-
"duration",
|
|
39
|
-
"MusicBrainz",
|
|
40
|
-
"Discogs",
|
|
41
|
-
"Picard",
|
|
42
|
-
"ID3",
|
|
43
|
-
"ID3v1",
|
|
44
|
-
"ID3v2",
|
|
45
|
-
"m4a",
|
|
46
|
-
"m4b",
|
|
47
|
-
"mp3",
|
|
48
|
-
"mp4",
|
|
49
|
-
"Vorbis",
|
|
50
|
-
"ogg",
|
|
51
|
-
"flac",
|
|
52
|
-
"Matroska",
|
|
53
|
-
"WebM",
|
|
54
|
-
"EBML",
|
|
55
|
-
"asf",
|
|
56
|
-
"wma",
|
|
57
|
-
"wmv",
|
|
58
|
-
"ape",
|
|
59
|
-
"MonkeyAudio",
|
|
60
|
-
"aiff",
|
|
61
|
-
"wav",
|
|
62
|
-
"WavPack",
|
|
63
|
-
"Opus",
|
|
64
|
-
"speex",
|
|
65
|
-
"musepack",
|
|
66
|
-
"mpc",
|
|
67
|
-
"dsd",
|
|
68
|
-
"dsf",
|
|
69
|
-
"mpc",
|
|
70
|
-
"dff",
|
|
71
|
-
"dsdiff",
|
|
72
|
-
"aac",
|
|
73
|
-
"adts",
|
|
74
|
-
"length",
|
|
75
|
-
"chapter",
|
|
76
|
-
"info",
|
|
77
|
-
"parse",
|
|
78
|
-
"parser",
|
|
79
|
-
"bwf"
|
|
80
|
-
],
|
|
81
|
-
"scripts": {
|
|
82
|
-
"clean": "del-cli 'lib/**/*.js' 'lib/**/*.js.map' 'lib/**/*.d.ts' 'src/**/*.d.ts' 'test/**/*.js' 'test/**/*.js.map' 'test/**/*.js' 'test/**/*.js.map' 'doc-gen/**/*.js' 'doc-gen/**/*.js.map'",
|
|
83
|
-
"compile-src": "tsc -p lib",
|
|
84
|
-
"compile-test": "tsc -p test",
|
|
85
|
-
"compile-doc": "tsc -p doc-gen",
|
|
86
|
-
"compile": "yarn run compile-src && yarn compile-test && yarn compile-doc",
|
|
87
|
-
"
|
|
88
|
-
"lint-md": "yarn run remark -u preset-lint-
|
|
89
|
-
"lint": "yarn run lint-
|
|
90
|
-
"test": "mocha",
|
|
91
|
-
"build": "yarn run clean && yarn compile && yarn run doc-gen",
|
|
92
|
-
"
|
|
93
|
-
"
|
|
94
|
-
"
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
"
|
|
99
|
-
"
|
|
100
|
-
"
|
|
101
|
-
"
|
|
102
|
-
"
|
|
103
|
-
"
|
|
104
|
-
"
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
"@
|
|
109
|
-
"@
|
|
110
|
-
"@
|
|
111
|
-
"@types/
|
|
112
|
-
"@types/
|
|
113
|
-
"@types/
|
|
114
|
-
"@types/
|
|
115
|
-
"
|
|
116
|
-
"
|
|
117
|
-
"
|
|
118
|
-
"
|
|
119
|
-
"
|
|
120
|
-
"
|
|
121
|
-
"
|
|
122
|
-
"
|
|
123
|
-
"
|
|
124
|
-
"
|
|
125
|
-
"
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
"
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
"
|
|
132
|
-
"
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
"
|
|
137
|
-
},
|
|
138
|
-
"
|
|
139
|
-
|
|
140
|
-
},
|
|
141
|
-
"repository": {
|
|
142
|
-
"type": "git",
|
|
143
|
-
"url": "git+https://github.com/borewit/music-metadata.git"
|
|
144
|
-
},
|
|
145
|
-
"license": "MIT",
|
|
146
|
-
"bugs": {
|
|
147
|
-
"url": "https://github.com/Borewit/music-metadata/issues"
|
|
148
|
-
},
|
|
149
|
-
"packageManager": "yarn@4.3.1"
|
|
150
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "music-metadata",
|
|
3
|
+
"description": "Music metadata parser for Node.js, supporting virtual any audio and tag format.",
|
|
4
|
+
"version": "10.2.0",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Borewit",
|
|
7
|
+
"url": "https://github.com/Borewit"
|
|
8
|
+
},
|
|
9
|
+
"funding": [
|
|
10
|
+
{
|
|
11
|
+
"type": "github",
|
|
12
|
+
"url": "https://github.com/sponsors/Borewit"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"type": "buymeacoffee",
|
|
16
|
+
"url": "https://buymeacoffee.com/borewit"
|
|
17
|
+
}
|
|
18
|
+
],
|
|
19
|
+
"type": "module",
|
|
20
|
+
"exports": {
|
|
21
|
+
".": {
|
|
22
|
+
"node": "./lib/index.js",
|
|
23
|
+
"default": "./lib/core.js"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"types": "lib/index.d.ts",
|
|
27
|
+
"files": [
|
|
28
|
+
"lib/**/*.js",
|
|
29
|
+
"lib/**/*.d.ts"
|
|
30
|
+
],
|
|
31
|
+
"keywords": [
|
|
32
|
+
"music",
|
|
33
|
+
"metadata",
|
|
34
|
+
"meta",
|
|
35
|
+
"audio",
|
|
36
|
+
"tag",
|
|
37
|
+
"tags",
|
|
38
|
+
"duration",
|
|
39
|
+
"MusicBrainz",
|
|
40
|
+
"Discogs",
|
|
41
|
+
"Picard",
|
|
42
|
+
"ID3",
|
|
43
|
+
"ID3v1",
|
|
44
|
+
"ID3v2",
|
|
45
|
+
"m4a",
|
|
46
|
+
"m4b",
|
|
47
|
+
"mp3",
|
|
48
|
+
"mp4",
|
|
49
|
+
"Vorbis",
|
|
50
|
+
"ogg",
|
|
51
|
+
"flac",
|
|
52
|
+
"Matroska",
|
|
53
|
+
"WebM",
|
|
54
|
+
"EBML",
|
|
55
|
+
"asf",
|
|
56
|
+
"wma",
|
|
57
|
+
"wmv",
|
|
58
|
+
"ape",
|
|
59
|
+
"MonkeyAudio",
|
|
60
|
+
"aiff",
|
|
61
|
+
"wav",
|
|
62
|
+
"WavPack",
|
|
63
|
+
"Opus",
|
|
64
|
+
"speex",
|
|
65
|
+
"musepack",
|
|
66
|
+
"mpc",
|
|
67
|
+
"dsd",
|
|
68
|
+
"dsf",
|
|
69
|
+
"mpc",
|
|
70
|
+
"dff",
|
|
71
|
+
"dsdiff",
|
|
72
|
+
"aac",
|
|
73
|
+
"adts",
|
|
74
|
+
"length",
|
|
75
|
+
"chapter",
|
|
76
|
+
"info",
|
|
77
|
+
"parse",
|
|
78
|
+
"parser",
|
|
79
|
+
"bwf"
|
|
80
|
+
],
|
|
81
|
+
"scripts": {
|
|
82
|
+
"clean": "del-cli 'lib/**/*.js' 'lib/**/*.js.map' 'lib/**/*.d.ts' 'src/**/*.d.ts' 'test/**/*.js' 'test/**/*.js.map' 'test/**/*.js' 'test/**/*.js.map' 'doc-gen/**/*.js' 'doc-gen/**/*.js.map'",
|
|
83
|
+
"compile-src": "tsc -p lib",
|
|
84
|
+
"compile-test": "tsc -p test",
|
|
85
|
+
"compile-doc": "tsc -p doc-gen",
|
|
86
|
+
"compile": "yarn run compile-src && yarn compile-test && yarn compile-doc",
|
|
87
|
+
"lint-ts": "biome check",
|
|
88
|
+
"lint-md": "yarn run remark -u remark-preset-lint-consistent .",
|
|
89
|
+
"lint": "yarn run lint-ts && yarn run lint-md",
|
|
90
|
+
"test": "mocha",
|
|
91
|
+
"build": "yarn run clean && yarn compile && yarn run doc-gen",
|
|
92
|
+
"test-coverage": "c8 yarn run test",
|
|
93
|
+
"send-codacy": "c8 report --reporter=text-lcov | codacy-coverage",
|
|
94
|
+
"doc-gen": "yarn node doc-gen/gen.js"
|
|
95
|
+
},
|
|
96
|
+
"dependencies": {
|
|
97
|
+
"@tokenizer/token": "^0.3.0",
|
|
98
|
+
"content-type": "^1.0.5",
|
|
99
|
+
"debug": "^4.3.4",
|
|
100
|
+
"file-type": "^19.4.1",
|
|
101
|
+
"media-typer": "^1.1.0",
|
|
102
|
+
"strtok3": "^8.1.0",
|
|
103
|
+
"token-types": "^6.0.0",
|
|
104
|
+
"uint8array-extras": "^1.4.0"
|
|
105
|
+
},
|
|
106
|
+
"devDependencies": {
|
|
107
|
+
"@biomejs/biome": "1.8.3",
|
|
108
|
+
"@types/chai": "^4.3.16",
|
|
109
|
+
"@types/chai-as-promised": "^7.1.8",
|
|
110
|
+
"@types/content-type": "^1.1.8",
|
|
111
|
+
"@types/debug": "^4.1.12",
|
|
112
|
+
"@types/media-typer": "^1.1.3",
|
|
113
|
+
"@types/mocha": "^10.0.7",
|
|
114
|
+
"@types/node": "^22.3.0",
|
|
115
|
+
"c8": "^10.1.2",
|
|
116
|
+
"chai": "^5.1.1",
|
|
117
|
+
"chai-as-promised": "^8.0.0",
|
|
118
|
+
"del-cli": "^5.1.0",
|
|
119
|
+
"mime": "^4.0.4",
|
|
120
|
+
"mocha": "^10.7.3",
|
|
121
|
+
"prettier": "^3.3.3",
|
|
122
|
+
"remark-cli": "^12.0.1",
|
|
123
|
+
"remark-preset-lint-consistent": "^6.0.0",
|
|
124
|
+
"ts-node": "^10.9.2",
|
|
125
|
+
"typescript": "^5.5.3"
|
|
126
|
+
},
|
|
127
|
+
"engines": {
|
|
128
|
+
"node": ">=16.0.0"
|
|
129
|
+
},
|
|
130
|
+
"repository": {
|
|
131
|
+
"type": "git",
|
|
132
|
+
"url": "git+https://github.com/borewit/music-metadata.git"
|
|
133
|
+
},
|
|
134
|
+
"license": "MIT",
|
|
135
|
+
"bugs": {
|
|
136
|
+
"url": "https://github.com/Borewit/music-metadata/issues"
|
|
137
|
+
},
|
|
138
|
+
"packageManager": "yarn@4.3.1"
|
|
139
|
+
}
|