Skip to content

Commit b486eb6

Browse files
committedJul 4, 2022
Fix WAV parser, sync issue with Broadcast Wave Format (BWF) Audio Extension chunk
Strips null characters from BWF extension strings. Resolves: #1163
1 parent 55344b5 commit b486eb6

File tree

4 files changed

+25
-5
lines changed

4 files changed

+25
-5
lines changed
 

‎lib/wav/BwfChunk.ts

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { IGetToken } from 'strtok3/lib/core';
22
import * as Token from 'token-types';
3+
import { stripNulls } from '../common/Util';
34

45
export interface IBroadcastAudioExtensionChunk {
56
description: string;
@@ -22,11 +23,11 @@ export const BroadcastAudioExtensionChunk: IGetToken<IBroadcastAudioExtensionChu
2223

2324
get: (uint8array, off) => {
2425
return {
25-
description: new Token.StringType(256, 'ascii').get(uint8array, off).trim(),
26-
originator: new Token.StringType(32, 'ascii').get(uint8array, off + 256).trim(),
27-
originatorReference: new Token.StringType(32, 'ascii').get(uint8array, off + 288).trim(),
28-
originationDate: new Token.StringType(10, 'ascii').get(uint8array, off + 320).trim(),
29-
originationTime: new Token.StringType(8, 'ascii').get(uint8array, off + 330).trim(),
26+
description: stripNulls(new Token.StringType(256, 'ascii').get(uint8array, off)).trim(),
27+
originator: stripNulls(new Token.StringType(32, 'ascii').get(uint8array, off + 256)).trim(),
28+
originatorReference: stripNulls(new Token.StringType(32, 'ascii').get(uint8array, off + 288)).trim(),
29+
originationDate: stripNulls(new Token.StringType(10, 'ascii').get(uint8array, off + 320)).trim(),
30+
originationTime: stripNulls(new Token.StringType(8, 'ascii').get(uint8array, off + 330)).trim(),
3031
timeReferenceLow: Token.UINT32_LE.get(uint8array, off + 338),
3132
timeReferenceHigh: Token.UINT32_LE.get(uint8array, off + 342),
3233
version: Token.UINT16_LE.get(uint8array, off + 346),

‎lib/wav/WaveParser.ts

+2
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,8 @@ export class WaveParser extends BasicParser {
128128
Object.keys(bext).forEach(key => {
129129
this.metadata.addTag('exif', 'bext.' + key, bext[key]);
130130
});
131+
const bextRemaining = header.chunkSize - BroadcastAudioExtensionChunk.len;
132+
await this.tokenizer.ignore(bextRemaining);
131133
break;
132134

133135
case '\x00\x00\x00\x00': // padding ??

‎test/samples/wav/issue-1163.bwf

164 KB
Binary file not shown.

‎test/test-file-wav.ts

+17
Original file line numberDiff line numberDiff line change
@@ -178,5 +178,22 @@ describe('Parse RIFF/WAVE audio format', () => {
178178
assert.approximately(format.duration, 2478 / 16000, 5 / 1000, 'format.duration');
179179
});
180180

181+
// https://github.com/Borewit/music-metadata/issues/1163
182+
it('Support chunk size larger then BWF extension', async () => {
183+
// const filePath = path.join(wavSamples, 'unreadable-tags.wav');
184+
const filePath = path.join(wavSamples, 'issue-1163.bwf');
185+
const {format, common, native} = await mm.parseFile(filePath);
186+
187+
assert.strictEqual(format.container, 'WAVE', 'format.container');
188+
assert.strictEqual(format.codec, 'PCM', 'format.codec');
189+
190+
assert.strictEqual(common.artist, 'Some Composer', 'common.artists');
191+
assert.strictEqual(common.title, 'Title Redacted', 'common.title');
192+
assert.deepStrictEqual(common.track, {no: 1, of: 12}, 'common.track');
193+
194+
const exif = mm.orderTags(native.exif);
195+
assert.deepStrictEqual(exif['bext.originator'], ['Pro Tools'], 'BWF: exif.bext.originator');
196+
});
197+
181198
});
182199

0 commit comments

Comments
 (0)
Please sign in to comment.