music-metadata 7.12.2 → 7.12.5
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 +434 -434
- package/lib/ParserFactory.d.ts +48 -48
- package/lib/ParserFactory.js +252 -252
- package/lib/aiff/AiffParser.d.ts +14 -14
- package/lib/aiff/AiffParser.js +84 -84
- 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 +164 -164
- package/lib/apev2/APEv2TagMapper.d.ts +4 -4
- package/lib/apev2/APEv2TagMapper.js +86 -86
- package/lib/apev2/APEv2Token.d.ts +100 -100
- package/lib/apev2/APEv2Token.js +126 -126
- package/lib/asf/AsfObject.d.ts +319 -319
- package/lib/asf/AsfObject.js +381 -381
- 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 +95 -95
- package/lib/asf/AsfUtil.d.ts +13 -13
- package/lib/asf/AsfUtil.js +38 -38
- package/lib/asf/GUID.d.ts +84 -84
- package/lib/asf/GUID.js +121 -121
- 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 +21 -21
- package/lib/common/CombinedTagMapper.d.ts +19 -19
- package/lib/common/CombinedTagMapper.js +51 -51
- package/lib/common/FourCC.d.ts +6 -6
- package/lib/common/FourCC.js +28 -28
- package/lib/common/GenericTagMapper.d.ts +51 -51
- package/lib/common/GenericTagMapper.js +55 -55
- package/lib/common/GenericTagTypes.d.ts +33 -33
- package/lib/common/GenericTagTypes.js +131 -131
- package/lib/common/MetadataCollector.d.ts +76 -76
- package/lib/common/MetadataCollector.js +275 -275
- package/lib/common/RandomFileReader.d.ts +22 -22
- package/lib/common/RandomFileReader.js +34 -34
- package/lib/common/RandomUint8ArrayReader.d.ts +18 -18
- package/lib/common/RandomUint8ArrayReader.js +25 -25
- package/lib/common/Util.d.ts +57 -57
- package/lib/common/Util.js +157 -157
- 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 +22 -22
- package/lib/id3v2/AbstractID3Parser.d.ts +17 -17
- package/lib/id3v2/AbstractID3Parser.js +60 -60
- package/lib/id3v2/FrameParser.d.ts +31 -31
- package/lib/id3v2/FrameParser.js +329 -329
- package/lib/id3v2/ID3v22TagMapper.d.ts +9 -9
- package/lib/id3v2/ID3v22TagMapper.js +55 -55
- package/lib/id3v2/ID3v24TagMapper.d.ts +14 -14
- package/lib/id3v2/ID3v24TagMapper.js +193 -193
- package/lib/id3v2/ID3v2Parser.d.ts +28 -28
- package/lib/id3v2/ID3v2Parser.js +182 -182
- 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 -45
- package/lib/index.js +74 -74
- 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 -235
- package/lib/matroska/MatroskaTagMapper.d.ts +4 -4
- package/lib/matroska/MatroskaTagMapper.js +35 -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 +115 -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 +524 -524
- 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 +69 -69
- 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 +132 -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 +37 -37
- package/lib/type.d.ts +592 -592
- package/lib/type.js +5 -5
- package/lib/wav/BwfChunk.d.ts +17 -17
- package/lib/wav/BwfChunk.js +29 -28
- 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 +158 -156
- package/lib/wavpack/WavPackParser.d.ts +14 -14
- package/lib/wavpack/WavPackParser.js +99 -99
- package/lib/wavpack/WavPackToken.d.ts +64 -64
- package/lib/wavpack/WavPackToken.js +76 -76
- package/package.json +152 -150
|
@@ -1,54 +1,54 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.BitReader = void 0;
|
|
4
|
-
const Token = require("token-types");
|
|
5
|
-
class BitReader {
|
|
6
|
-
constructor(tokenizer) {
|
|
7
|
-
this.tokenizer = tokenizer;
|
|
8
|
-
this.pos = 0;
|
|
9
|
-
this.dword = undefined;
|
|
10
|
-
}
|
|
11
|
-
/**
|
|
12
|
-
*
|
|
13
|
-
* @param bits 1..30 bits
|
|
14
|
-
*/
|
|
15
|
-
async read(bits) {
|
|
16
|
-
while (this.dword === undefined) {
|
|
17
|
-
this.dword = await this.tokenizer.readToken(Token.UINT32_LE);
|
|
18
|
-
}
|
|
19
|
-
let out = this.dword;
|
|
20
|
-
this.pos += bits;
|
|
21
|
-
if (this.pos < 32) {
|
|
22
|
-
out >>>= (32 - this.pos);
|
|
23
|
-
return out & ((1 << bits) - 1);
|
|
24
|
-
}
|
|
25
|
-
else {
|
|
26
|
-
this.pos -= 32;
|
|
27
|
-
if (this.pos === 0) {
|
|
28
|
-
this.dword = undefined;
|
|
29
|
-
return out & ((1 << bits) - 1);
|
|
30
|
-
}
|
|
31
|
-
else {
|
|
32
|
-
this.dword = await this.tokenizer.readToken(Token.UINT32_LE);
|
|
33
|
-
if (this.pos) {
|
|
34
|
-
out <<= this.pos;
|
|
35
|
-
out |= this.dword >>> (32 - this.pos);
|
|
36
|
-
}
|
|
37
|
-
return out & ((1 << bits) - 1);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
async ignore(bits) {
|
|
42
|
-
if (this.pos > 0) {
|
|
43
|
-
const remaining = 32 - this.pos;
|
|
44
|
-
this.dword = undefined;
|
|
45
|
-
bits -= remaining;
|
|
46
|
-
this.pos = 0;
|
|
47
|
-
}
|
|
48
|
-
const remainder = bits % 32;
|
|
49
|
-
const numOfWords = (bits - remainder) / 32;
|
|
50
|
-
await this.tokenizer.ignore(numOfWords * 4);
|
|
51
|
-
return this.read(remainder);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
exports.BitReader = BitReader;
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BitReader = void 0;
|
|
4
|
+
const Token = require("token-types");
|
|
5
|
+
class BitReader {
|
|
6
|
+
constructor(tokenizer) {
|
|
7
|
+
this.tokenizer = tokenizer;
|
|
8
|
+
this.pos = 0;
|
|
9
|
+
this.dword = undefined;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
*
|
|
13
|
+
* @param bits 1..30 bits
|
|
14
|
+
*/
|
|
15
|
+
async read(bits) {
|
|
16
|
+
while (this.dword === undefined) {
|
|
17
|
+
this.dword = await this.tokenizer.readToken(Token.UINT32_LE);
|
|
18
|
+
}
|
|
19
|
+
let out = this.dword;
|
|
20
|
+
this.pos += bits;
|
|
21
|
+
if (this.pos < 32) {
|
|
22
|
+
out >>>= (32 - this.pos);
|
|
23
|
+
return out & ((1 << bits) - 1);
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
this.pos -= 32;
|
|
27
|
+
if (this.pos === 0) {
|
|
28
|
+
this.dword = undefined;
|
|
29
|
+
return out & ((1 << bits) - 1);
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
this.dword = await this.tokenizer.readToken(Token.UINT32_LE);
|
|
33
|
+
if (this.pos) {
|
|
34
|
+
out <<= this.pos;
|
|
35
|
+
out |= this.dword >>> (32 - this.pos);
|
|
36
|
+
}
|
|
37
|
+
return out & ((1 << bits) - 1);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
async ignore(bits) {
|
|
42
|
+
if (this.pos > 0) {
|
|
43
|
+
const remaining = 32 - this.pos;
|
|
44
|
+
this.dword = undefined;
|
|
45
|
+
bits -= remaining;
|
|
46
|
+
this.pos = 0;
|
|
47
|
+
}
|
|
48
|
+
const remainder = bits % 32;
|
|
49
|
+
const numOfWords = (bits - remainder) / 32;
|
|
50
|
+
await this.tokenizer.ignore(numOfWords * 4);
|
|
51
|
+
return this.read(remainder);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
exports.BitReader = BitReader;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { BasicParser } from '../../common/BasicParser';
|
|
2
|
-
export declare class MpcSv7Parser extends BasicParser {
|
|
3
|
-
private bitreader;
|
|
4
|
-
private audioLength;
|
|
5
|
-
private duration;
|
|
6
|
-
parse(): Promise<void>;
|
|
7
|
-
private skipAudioData;
|
|
8
|
-
}
|
|
1
|
+
import { BasicParser } from '../../common/BasicParser';
|
|
2
|
+
export declare class MpcSv7Parser extends BasicParser {
|
|
3
|
+
private bitreader;
|
|
4
|
+
private audioLength;
|
|
5
|
+
private duration;
|
|
6
|
+
parse(): Promise<void>;
|
|
7
|
+
private skipAudioData;
|
|
8
|
+
}
|
|
@@ -1,46 +1,46 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MpcSv7Parser = void 0;
|
|
4
|
-
const debug_1 = require("debug");
|
|
5
|
-
const BasicParser_1 = require("../../common/BasicParser");
|
|
6
|
-
const APEv2Parser_1 = require("../../apev2/APEv2Parser");
|
|
7
|
-
const BitReader_1 = require("./BitReader");
|
|
8
|
-
const SV7 = require("./StreamVersion7");
|
|
9
|
-
const debug = (0, debug_1.default)('music-metadata:parser:musepack');
|
|
10
|
-
class MpcSv7Parser extends BasicParser_1.BasicParser {
|
|
11
|
-
constructor() {
|
|
12
|
-
super(...arguments);
|
|
13
|
-
this.audioLength = 0;
|
|
14
|
-
}
|
|
15
|
-
async parse() {
|
|
16
|
-
const header = await this.tokenizer.readToken(SV7.Header);
|
|
17
|
-
if (header.signature !== 'MP+')
|
|
18
|
-
throw new Error('Unexpected magic number');
|
|
19
|
-
debug(`stream-version=${header.streamMajorVersion}.${header.streamMinorVersion}`);
|
|
20
|
-
this.metadata.setFormat('container', 'Musepack, SV7');
|
|
21
|
-
this.metadata.setFormat('sampleRate', header.sampleFrequency);
|
|
22
|
-
const numberOfSamples = 1152 * (header.frameCount - 1) + header.lastFrameLength;
|
|
23
|
-
this.metadata.setFormat('numberOfSamples', numberOfSamples);
|
|
24
|
-
this.duration = numberOfSamples / header.sampleFrequency;
|
|
25
|
-
this.metadata.setFormat('duration', this.duration);
|
|
26
|
-
this.bitreader = new BitReader_1.BitReader(this.tokenizer);
|
|
27
|
-
this.metadata.setFormat('numberOfChannels', header.midSideStereo || header.intensityStereo ? 2 : 1);
|
|
28
|
-
const version = await this.bitreader.read(8);
|
|
29
|
-
this.metadata.setFormat('codec', (version / 100).toFixed(2));
|
|
30
|
-
await this.skipAudioData(header.frameCount);
|
|
31
|
-
debug(`End of audio stream, switching to APEv2, offset=${this.tokenizer.position}`);
|
|
32
|
-
return APEv2Parser_1.APEv2Parser.tryParseApeHeader(this.metadata, this.tokenizer, this.options);
|
|
33
|
-
}
|
|
34
|
-
async skipAudioData(frameCount) {
|
|
35
|
-
while (frameCount-- > 0) {
|
|
36
|
-
const frameLength = await this.bitreader.read(20);
|
|
37
|
-
this.audioLength += 20 + frameLength;
|
|
38
|
-
await this.bitreader.ignore(frameLength);
|
|
39
|
-
}
|
|
40
|
-
// last frame
|
|
41
|
-
const lastFrameLength = await this.bitreader.read(11);
|
|
42
|
-
this.audioLength += lastFrameLength;
|
|
43
|
-
this.metadata.setFormat('bitrate', this.audioLength / this.duration);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
exports.MpcSv7Parser = MpcSv7Parser;
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MpcSv7Parser = void 0;
|
|
4
|
+
const debug_1 = require("debug");
|
|
5
|
+
const BasicParser_1 = require("../../common/BasicParser");
|
|
6
|
+
const APEv2Parser_1 = require("../../apev2/APEv2Parser");
|
|
7
|
+
const BitReader_1 = require("./BitReader");
|
|
8
|
+
const SV7 = require("./StreamVersion7");
|
|
9
|
+
const debug = (0, debug_1.default)('music-metadata:parser:musepack');
|
|
10
|
+
class MpcSv7Parser extends BasicParser_1.BasicParser {
|
|
11
|
+
constructor() {
|
|
12
|
+
super(...arguments);
|
|
13
|
+
this.audioLength = 0;
|
|
14
|
+
}
|
|
15
|
+
async parse() {
|
|
16
|
+
const header = await this.tokenizer.readToken(SV7.Header);
|
|
17
|
+
if (header.signature !== 'MP+')
|
|
18
|
+
throw new Error('Unexpected magic number');
|
|
19
|
+
debug(`stream-version=${header.streamMajorVersion}.${header.streamMinorVersion}`);
|
|
20
|
+
this.metadata.setFormat('container', 'Musepack, SV7');
|
|
21
|
+
this.metadata.setFormat('sampleRate', header.sampleFrequency);
|
|
22
|
+
const numberOfSamples = 1152 * (header.frameCount - 1) + header.lastFrameLength;
|
|
23
|
+
this.metadata.setFormat('numberOfSamples', numberOfSamples);
|
|
24
|
+
this.duration = numberOfSamples / header.sampleFrequency;
|
|
25
|
+
this.metadata.setFormat('duration', this.duration);
|
|
26
|
+
this.bitreader = new BitReader_1.BitReader(this.tokenizer);
|
|
27
|
+
this.metadata.setFormat('numberOfChannels', header.midSideStereo || header.intensityStereo ? 2 : 1);
|
|
28
|
+
const version = await this.bitreader.read(8);
|
|
29
|
+
this.metadata.setFormat('codec', (version / 100).toFixed(2));
|
|
30
|
+
await this.skipAudioData(header.frameCount);
|
|
31
|
+
debug(`End of audio stream, switching to APEv2, offset=${this.tokenizer.position}`);
|
|
32
|
+
return APEv2Parser_1.APEv2Parser.tryParseApeHeader(this.metadata, this.tokenizer, this.options);
|
|
33
|
+
}
|
|
34
|
+
async skipAudioData(frameCount) {
|
|
35
|
+
while (frameCount-- > 0) {
|
|
36
|
+
const frameLength = await this.bitreader.read(20);
|
|
37
|
+
this.audioLength += 20 + frameLength;
|
|
38
|
+
await this.bitreader.ignore(frameLength);
|
|
39
|
+
}
|
|
40
|
+
// last frame
|
|
41
|
+
const lastFrameLength = await this.bitreader.read(11);
|
|
42
|
+
this.audioLength += lastFrameLength;
|
|
43
|
+
this.metadata.setFormat('bitrate', this.audioLength / this.duration);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
exports.MpcSv7Parser = MpcSv7Parser;
|
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
import { IGetToken } from 'strtok3/lib/core';
|
|
2
|
-
/**
|
|
3
|
-
* MusePack stream version 7 format specification
|
|
4
|
-
* http://trac.musepack.net/musepack/wiki/SV7Specification
|
|
5
|
-
*/
|
|
6
|
-
export interface IHeader {
|
|
7
|
-
signature: string;
|
|
8
|
-
streamMinorVersion: number;
|
|
9
|
-
streamMajorVersion: number;
|
|
10
|
-
frameCount: number;
|
|
11
|
-
intensityStereo: boolean;
|
|
12
|
-
midSideStereo: boolean;
|
|
13
|
-
maxBand: number;
|
|
14
|
-
profile: number;
|
|
15
|
-
link: number;
|
|
16
|
-
sampleFrequency: number;
|
|
17
|
-
maxLevel: number;
|
|
18
|
-
titleGain: number;
|
|
19
|
-
titlePeak: number;
|
|
20
|
-
albumGain: number;
|
|
21
|
-
albumPeak: number;
|
|
22
|
-
trueGapless: boolean;
|
|
23
|
-
lastFrameLength: number;
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* BASIC STRUCTURE
|
|
27
|
-
*/
|
|
28
|
-
export declare const Header: IGetToken<IHeader>;
|
|
1
|
+
import { IGetToken } from 'strtok3/lib/core';
|
|
2
|
+
/**
|
|
3
|
+
* MusePack stream version 7 format specification
|
|
4
|
+
* http://trac.musepack.net/musepack/wiki/SV7Specification
|
|
5
|
+
*/
|
|
6
|
+
export interface IHeader {
|
|
7
|
+
signature: string;
|
|
8
|
+
streamMinorVersion: number;
|
|
9
|
+
streamMajorVersion: number;
|
|
10
|
+
frameCount: number;
|
|
11
|
+
intensityStereo: boolean;
|
|
12
|
+
midSideStereo: boolean;
|
|
13
|
+
maxBand: number;
|
|
14
|
+
profile: number;
|
|
15
|
+
link: number;
|
|
16
|
+
sampleFrequency: number;
|
|
17
|
+
maxLevel: number;
|
|
18
|
+
titleGain: number;
|
|
19
|
+
titlePeak: number;
|
|
20
|
+
albumGain: number;
|
|
21
|
+
albumPeak: number;
|
|
22
|
+
trueGapless: boolean;
|
|
23
|
+
lastFrameLength: number;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* BASIC STRUCTURE
|
|
27
|
+
*/
|
|
28
|
+
export declare const Header: IGetToken<IHeader>;
|
|
@@ -1,41 +1,41 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Header = void 0;
|
|
4
|
-
const Token = require("token-types");
|
|
5
|
-
const util = require("../../common/Util");
|
|
6
|
-
/**
|
|
7
|
-
* BASIC STRUCTURE
|
|
8
|
-
*/
|
|
9
|
-
exports.Header = {
|
|
10
|
-
len: 6 * 4,
|
|
11
|
-
get: (buf, off) => {
|
|
12
|
-
const header = {
|
|
13
|
-
// word 0
|
|
14
|
-
signature: Buffer.from(buf).toString('latin1', off, off + 3),
|
|
15
|
-
// versionIndex number * 1000 (3.81 = 3810) (remember that 4-byte alignment causes this to take 4-bytes)
|
|
16
|
-
streamMinorVersion: util.getBitAllignedNumber(buf, off + 3, 0, 4),
|
|
17
|
-
streamMajorVersion: util.getBitAllignedNumber(buf, off + 3, 4, 4),
|
|
18
|
-
// word 1
|
|
19
|
-
frameCount: Token.UINT32_LE.get(buf, off + 4),
|
|
20
|
-
// word 2
|
|
21
|
-
maxLevel: Token.UINT16_LE.get(buf, off + 8),
|
|
22
|
-
sampleFrequency: [44100, 48000, 37800, 32000][util.getBitAllignedNumber(buf, off + 10, 0, 2)],
|
|
23
|
-
link: util.getBitAllignedNumber(buf, off + 10, 2, 2),
|
|
24
|
-
profile: util.getBitAllignedNumber(buf, off + 10, 4, 4),
|
|
25
|
-
maxBand: util.getBitAllignedNumber(buf, off + 11, 0, 6),
|
|
26
|
-
intensityStereo: util.isBitSet(buf, off + 11, 6),
|
|
27
|
-
midSideStereo: util.isBitSet(buf, off + 11, 7),
|
|
28
|
-
// word 3
|
|
29
|
-
titlePeak: Token.UINT16_LE.get(buf, off + 12),
|
|
30
|
-
titleGain: Token.UINT16_LE.get(buf, off + 14),
|
|
31
|
-
// word 4
|
|
32
|
-
albumPeak: Token.UINT16_LE.get(buf, off + 16),
|
|
33
|
-
albumGain: Token.UINT16_LE.get(buf, off + 18),
|
|
34
|
-
// word
|
|
35
|
-
lastFrameLength: (Token.UINT32_LE.get(buf, off + 20) >>> 20) & 0x7FF,
|
|
36
|
-
trueGapless: util.isBitSet(buf, off + 23, 0)
|
|
37
|
-
};
|
|
38
|
-
header.lastFrameLength = header.trueGapless ? (Token.UINT32_LE.get(buf, 20) >>> 20) & 0x7FF : 0;
|
|
39
|
-
return header;
|
|
40
|
-
}
|
|
41
|
-
};
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Header = void 0;
|
|
4
|
+
const Token = require("token-types");
|
|
5
|
+
const util = require("../../common/Util");
|
|
6
|
+
/**
|
|
7
|
+
* BASIC STRUCTURE
|
|
8
|
+
*/
|
|
9
|
+
exports.Header = {
|
|
10
|
+
len: 6 * 4,
|
|
11
|
+
get: (buf, off) => {
|
|
12
|
+
const header = {
|
|
13
|
+
// word 0
|
|
14
|
+
signature: Buffer.from(buf).toString('latin1', off, off + 3),
|
|
15
|
+
// versionIndex number * 1000 (3.81 = 3810) (remember that 4-byte alignment causes this to take 4-bytes)
|
|
16
|
+
streamMinorVersion: util.getBitAllignedNumber(buf, off + 3, 0, 4),
|
|
17
|
+
streamMajorVersion: util.getBitAllignedNumber(buf, off + 3, 4, 4),
|
|
18
|
+
// word 1
|
|
19
|
+
frameCount: Token.UINT32_LE.get(buf, off + 4),
|
|
20
|
+
// word 2
|
|
21
|
+
maxLevel: Token.UINT16_LE.get(buf, off + 8),
|
|
22
|
+
sampleFrequency: [44100, 48000, 37800, 32000][util.getBitAllignedNumber(buf, off + 10, 0, 2)],
|
|
23
|
+
link: util.getBitAllignedNumber(buf, off + 10, 2, 2),
|
|
24
|
+
profile: util.getBitAllignedNumber(buf, off + 10, 4, 4),
|
|
25
|
+
maxBand: util.getBitAllignedNumber(buf, off + 11, 0, 6),
|
|
26
|
+
intensityStereo: util.isBitSet(buf, off + 11, 6),
|
|
27
|
+
midSideStereo: util.isBitSet(buf, off + 11, 7),
|
|
28
|
+
// word 3
|
|
29
|
+
titlePeak: Token.UINT16_LE.get(buf, off + 12),
|
|
30
|
+
titleGain: Token.UINT16_LE.get(buf, off + 14),
|
|
31
|
+
// word 4
|
|
32
|
+
albumPeak: Token.UINT16_LE.get(buf, off + 16),
|
|
33
|
+
albumGain: Token.UINT16_LE.get(buf, off + 18),
|
|
34
|
+
// word
|
|
35
|
+
lastFrameLength: (Token.UINT32_LE.get(buf, off + 20) >>> 20) & 0x7FF,
|
|
36
|
+
trueGapless: util.isBitSet(buf, off + 23, 0)
|
|
37
|
+
};
|
|
38
|
+
header.lastFrameLength = header.trueGapless ? (Token.UINT32_LE.get(buf, 20) >>> 20) & 0x7FF : 0;
|
|
39
|
+
return header;
|
|
40
|
+
}
|
|
41
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { BasicParser } from '../../common/BasicParser';
|
|
2
|
-
export declare class MpcSv8Parser extends BasicParser {
|
|
3
|
-
private audioLength;
|
|
4
|
-
parse(): Promise<void>;
|
|
5
|
-
private parsePacket;
|
|
6
|
-
}
|
|
1
|
+
import { BasicParser } from '../../common/BasicParser';
|
|
2
|
+
export declare class MpcSv8Parser extends BasicParser {
|
|
3
|
+
private audioLength;
|
|
4
|
+
parse(): Promise<void>;
|
|
5
|
+
private parsePacket;
|
|
6
|
+
}
|
|
@@ -1,55 +1,55 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MpcSv8Parser = void 0;
|
|
4
|
-
const debug_1 = require("debug");
|
|
5
|
-
const BasicParser_1 = require("../../common/BasicParser");
|
|
6
|
-
const APEv2Parser_1 = require("../../apev2/APEv2Parser");
|
|
7
|
-
const FourCC_1 = require("../../common/FourCC");
|
|
8
|
-
const SV8 = require("./StreamVersion8");
|
|
9
|
-
const debug = (0, debug_1.default)('music-metadata:parser:musepack');
|
|
10
|
-
class MpcSv8Parser extends BasicParser_1.BasicParser {
|
|
11
|
-
constructor() {
|
|
12
|
-
super(...arguments);
|
|
13
|
-
this.audioLength = 0;
|
|
14
|
-
}
|
|
15
|
-
async parse() {
|
|
16
|
-
const signature = await this.tokenizer.readToken(FourCC_1.FourCcToken);
|
|
17
|
-
if (signature !== 'MPCK')
|
|
18
|
-
throw new Error('Invalid Magic number');
|
|
19
|
-
this.metadata.setFormat('container', 'Musepack, SV8');
|
|
20
|
-
return this.parsePacket();
|
|
21
|
-
}
|
|
22
|
-
async parsePacket() {
|
|
23
|
-
const sv8reader = new SV8.StreamReader(this.tokenizer);
|
|
24
|
-
do {
|
|
25
|
-
const header = await sv8reader.readPacketHeader();
|
|
26
|
-
debug(`packet-header key=${header.key}, payloadLength=${header.payloadLength}`);
|
|
27
|
-
switch (header.key) {
|
|
28
|
-
case 'SH': // Stream Header
|
|
29
|
-
const sh = await sv8reader.readStreamHeader(header.payloadLength);
|
|
30
|
-
this.metadata.setFormat('numberOfSamples', sh.sampleCount);
|
|
31
|
-
this.metadata.setFormat('sampleRate', sh.sampleFrequency);
|
|
32
|
-
this.metadata.setFormat('duration', sh.sampleCount / sh.sampleFrequency);
|
|
33
|
-
this.metadata.setFormat('numberOfChannels', sh.channelCount);
|
|
34
|
-
break;
|
|
35
|
-
case 'AP': // Audio Packet
|
|
36
|
-
this.audioLength += header.payloadLength;
|
|
37
|
-
await this.tokenizer.ignore(header.payloadLength);
|
|
38
|
-
break;
|
|
39
|
-
case 'RG': // Replaygain
|
|
40
|
-
case 'EI': // Encoder Info
|
|
41
|
-
case 'SO': // Seek Table Offset
|
|
42
|
-
case 'ST': // Seek Table
|
|
43
|
-
case 'CT': // Chapter-Tag
|
|
44
|
-
await this.tokenizer.ignore(header.payloadLength);
|
|
45
|
-
break;
|
|
46
|
-
case 'SE': // Stream End
|
|
47
|
-
this.metadata.setFormat('bitrate', this.audioLength * 8 / this.metadata.format.duration);
|
|
48
|
-
return APEv2Parser_1.APEv2Parser.tryParseApeHeader(this.metadata, this.tokenizer, this.options);
|
|
49
|
-
default:
|
|
50
|
-
throw new Error(`Unexpected header: ${header.key}`);
|
|
51
|
-
}
|
|
52
|
-
} while (true);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
exports.MpcSv8Parser = MpcSv8Parser;
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MpcSv8Parser = void 0;
|
|
4
|
+
const debug_1 = require("debug");
|
|
5
|
+
const BasicParser_1 = require("../../common/BasicParser");
|
|
6
|
+
const APEv2Parser_1 = require("../../apev2/APEv2Parser");
|
|
7
|
+
const FourCC_1 = require("../../common/FourCC");
|
|
8
|
+
const SV8 = require("./StreamVersion8");
|
|
9
|
+
const debug = (0, debug_1.default)('music-metadata:parser:musepack');
|
|
10
|
+
class MpcSv8Parser extends BasicParser_1.BasicParser {
|
|
11
|
+
constructor() {
|
|
12
|
+
super(...arguments);
|
|
13
|
+
this.audioLength = 0;
|
|
14
|
+
}
|
|
15
|
+
async parse() {
|
|
16
|
+
const signature = await this.tokenizer.readToken(FourCC_1.FourCcToken);
|
|
17
|
+
if (signature !== 'MPCK')
|
|
18
|
+
throw new Error('Invalid Magic number');
|
|
19
|
+
this.metadata.setFormat('container', 'Musepack, SV8');
|
|
20
|
+
return this.parsePacket();
|
|
21
|
+
}
|
|
22
|
+
async parsePacket() {
|
|
23
|
+
const sv8reader = new SV8.StreamReader(this.tokenizer);
|
|
24
|
+
do {
|
|
25
|
+
const header = await sv8reader.readPacketHeader();
|
|
26
|
+
debug(`packet-header key=${header.key}, payloadLength=${header.payloadLength}`);
|
|
27
|
+
switch (header.key) {
|
|
28
|
+
case 'SH': // Stream Header
|
|
29
|
+
const sh = await sv8reader.readStreamHeader(header.payloadLength);
|
|
30
|
+
this.metadata.setFormat('numberOfSamples', sh.sampleCount);
|
|
31
|
+
this.metadata.setFormat('sampleRate', sh.sampleFrequency);
|
|
32
|
+
this.metadata.setFormat('duration', sh.sampleCount / sh.sampleFrequency);
|
|
33
|
+
this.metadata.setFormat('numberOfChannels', sh.channelCount);
|
|
34
|
+
break;
|
|
35
|
+
case 'AP': // Audio Packet
|
|
36
|
+
this.audioLength += header.payloadLength;
|
|
37
|
+
await this.tokenizer.ignore(header.payloadLength);
|
|
38
|
+
break;
|
|
39
|
+
case 'RG': // Replaygain
|
|
40
|
+
case 'EI': // Encoder Info
|
|
41
|
+
case 'SO': // Seek Table Offset
|
|
42
|
+
case 'ST': // Seek Table
|
|
43
|
+
case 'CT': // Chapter-Tag
|
|
44
|
+
await this.tokenizer.ignore(header.payloadLength);
|
|
45
|
+
break;
|
|
46
|
+
case 'SE': // Stream End
|
|
47
|
+
this.metadata.setFormat('bitrate', this.audioLength * 8 / this.metadata.format.duration);
|
|
48
|
+
return APEv2Parser_1.APEv2Parser.tryParseApeHeader(this.metadata, this.tokenizer, this.options);
|
|
49
|
+
default:
|
|
50
|
+
throw new Error(`Unexpected header: ${header.key}`);
|
|
51
|
+
}
|
|
52
|
+
} while (true);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
exports.MpcSv8Parser = MpcSv8Parser;
|
|
@@ -1,40 +1,40 @@
|
|
|
1
|
-
import { ITokenizer } from 'strtok3/lib/core';
|
|
2
|
-
export interface IPacketHeader {
|
|
3
|
-
key: string;
|
|
4
|
-
payloadLength: number;
|
|
5
|
-
}
|
|
6
|
-
/**
|
|
7
|
-
* Stream Header Packet
|
|
8
|
-
* Ref: http://trac.musepack.net/musepack/wiki/SV8Specification#StreamHeaderPacket
|
|
9
|
-
*/
|
|
10
|
-
interface IStreamHeader1 {
|
|
11
|
-
crc: number;
|
|
12
|
-
streamVersion: number;
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* Stream Header Packet
|
|
16
|
-
* Ref: http://trac.musepack.net/musepack/wiki/SV8Specification#StreamHeaderPacket
|
|
17
|
-
*/
|
|
18
|
-
interface IStreamHeader3 {
|
|
19
|
-
sampleFrequency: number;
|
|
20
|
-
maxUsedBands: number;
|
|
21
|
-
channelCount: number;
|
|
22
|
-
msUsed: boolean;
|
|
23
|
-
audioBlockFrames: number;
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Stream Header Packet
|
|
27
|
-
* Ref: http://trac.musepack.net/musepack/wiki/SV8Specification#StreamHeaderPacket
|
|
28
|
-
*/
|
|
29
|
-
interface IStreamHeader extends IStreamHeader1, IStreamHeader3 {
|
|
30
|
-
sampleCount: number;
|
|
31
|
-
beginningOfSilence: number;
|
|
32
|
-
}
|
|
33
|
-
export declare class StreamReader {
|
|
34
|
-
private tokenizer;
|
|
35
|
-
constructor(tokenizer: ITokenizer);
|
|
36
|
-
readPacketHeader(): Promise<IPacketHeader>;
|
|
37
|
-
readStreamHeader(size: number): Promise<IStreamHeader>;
|
|
38
|
-
private readVariableSizeField;
|
|
39
|
-
}
|
|
40
|
-
export {};
|
|
1
|
+
import { ITokenizer } from 'strtok3/lib/core';
|
|
2
|
+
export interface IPacketHeader {
|
|
3
|
+
key: string;
|
|
4
|
+
payloadLength: number;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Stream Header Packet
|
|
8
|
+
* Ref: http://trac.musepack.net/musepack/wiki/SV8Specification#StreamHeaderPacket
|
|
9
|
+
*/
|
|
10
|
+
interface IStreamHeader1 {
|
|
11
|
+
crc: number;
|
|
12
|
+
streamVersion: number;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Stream Header Packet
|
|
16
|
+
* Ref: http://trac.musepack.net/musepack/wiki/SV8Specification#StreamHeaderPacket
|
|
17
|
+
*/
|
|
18
|
+
interface IStreamHeader3 {
|
|
19
|
+
sampleFrequency: number;
|
|
20
|
+
maxUsedBands: number;
|
|
21
|
+
channelCount: number;
|
|
22
|
+
msUsed: boolean;
|
|
23
|
+
audioBlockFrames: number;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Stream Header Packet
|
|
27
|
+
* Ref: http://trac.musepack.net/musepack/wiki/SV8Specification#StreamHeaderPacket
|
|
28
|
+
*/
|
|
29
|
+
interface IStreamHeader extends IStreamHeader1, IStreamHeader3 {
|
|
30
|
+
sampleCount: number;
|
|
31
|
+
beginningOfSilence: number;
|
|
32
|
+
}
|
|
33
|
+
export declare class StreamReader {
|
|
34
|
+
private tokenizer;
|
|
35
|
+
constructor(tokenizer: ITokenizer);
|
|
36
|
+
readPacketHeader(): Promise<IPacketHeader>;
|
|
37
|
+
readStreamHeader(size: number): Promise<IStreamHeader>;
|
|
38
|
+
private readVariableSizeField;
|
|
39
|
+
}
|
|
40
|
+
export {};
|