Skip to content

Commit e0d10b5

Browse files
committed
Make analyse-wav.py work with 2-channel and floating-point WAV files
1 parent cd2a8b9 commit e0d10b5

File tree

1 file changed

+23
-23
lines changed

1 file changed

+23
-23
lines changed

tools/analyse-wav.py

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
#!/usr/bin/env python3
2+
from struct import unpack
23
import sys
34
import argparse
45

6+
INT = 1
7+
FLOAT = 3
8+
FORMATS = {INT: 'PCM (int)', FLOAT: 'PCM (float)'}
9+
SAMPLE_FORMATS = {INT: {1: '<h', 2: '<hh'}, FLOAT: {1: '<f', 2: '<ff'}}
10+
511
class WaveError(Exception):
612
pass
713

@@ -13,7 +19,7 @@ def __init__(self, data):
1319
chunk_id = _to_chars(data[i:i + 4])
1420
if chunk_id != 'RIFF':
1521
raise WaveError('"RIFF" chunk not found')
16-
length = _to_int(data[i + 4:i + 8])
22+
length = unpack('<I', data[i + 4:i + 8])[0]
1723
self.chunks[chunk_id] = (i, length)
1824
i += 8
1925

@@ -24,7 +30,7 @@ def __init__(self, data):
2430

2531
while i < len(data):
2632
chunk_id = _to_chars(data[i:i + 4])
27-
length = _to_int(data[i + 4:i + 8])
33+
length = unpack('<I', data[i + 4:i + 8])[0]
2834
self.chunks[chunk_id] = (i, data[i + 8:i + 8 + length])
2935
i += 8 + length
3036

@@ -34,29 +40,21 @@ def __init__(self, data):
3440

3541
self.samples = self.chunks['data'][1]
3642
fmt = self.chunks['fmt '][1]
37-
self.audio_format = _to_int(fmt[0:2])
38-
self.num_channels = _to_int(fmt[2:4])
39-
self.sample_rate = _to_int(fmt[4:8])
40-
self.byte_rate = _to_int(fmt[8:12])
41-
self.bytes_per_sample = _to_int(fmt[12:14])
42-
self.bits_per_sample = _to_int(fmt[14:16])
43+
self.audio_format = unpack('<H', fmt[0:2])[0]
44+
self.num_channels = unpack('<H', fmt[2:4])[0]
45+
self.sample_rate = unpack('<I', fmt[4:8])[0]
46+
self.byte_rate = unpack('<I', fmt[8:12])[0]
47+
self.bytes_per_sample = unpack('<H', fmt[12:14])[0]
48+
self.bits_per_sample = unpack('<H', fmt[14:16])[0]
4349
self.num_samples = len(self.samples) // self.bytes_per_sample
44-
self.duration = self.num_samples / (self.num_channels * self.sample_rate)
50+
self.duration = self.num_samples / self.sample_rate
4551

4652
def _to_chars(data):
4753
return ''.join(chr(b) for b in data)
4854

49-
def _to_int(data, signed=False):
50-
if len(data) == 4:
51-
return 16777216 * data[3] + 65536 * data[2] + 256 * data[1] + data[0]
52-
value = 256 * data[1] + data[0]
53-
if value < 32768 or not signed:
54-
return value
55-
return value - 65536
56-
5755
def dump_wav(data):
5856
wav = WaveFile(data)
59-
print(f'audio format: {wav.audio_format}')
57+
print(f'audio format: {wav.audio_format} ({FORMATS[wav.audio_format]})')
6058
print(f'channels: {wav.num_channels}')
6159
print(f'sample rate: {wav.sample_rate}')
6260
print(f'byte rate: {wav.byte_rate}')
@@ -66,8 +64,9 @@ def dump_wav(data):
6664
n = 0
6765
sample_size = wav.bytes_per_sample
6866
samples = wav.samples
67+
fmt = SAMPLE_FORMATS[wav.audio_format][wav.num_channels]
6968
for i in range(0, len(samples), sample_size):
70-
sample = _to_int(samples[i:i + sample_size], True)
69+
sample = ', '.join(str(j) for j in unpack(fmt, samples[i:i + sample_size]))
7170
print(f'{n:>7} {sample}')
7271
n += 1
7372

@@ -94,11 +93,12 @@ def show_diffs(fname1, data1, fname2, data2):
9493
else:
9594
sample_size = wav1.bytes_per_sample
9695
index = 1
96+
fmt = SAMPLE_FORMATS[wav.audio_format][wav.num_channels]
9797
for i in range(0, len(wav1.samples), sample_size):
98-
sample1 = _to_int(wav1.samples[i:i + sample_size], True)
99-
sample2 = _to_int(wav2.samples[i:i + sample_size], True)
98+
sample1 = ', '.join(str(j) for j in unpack(fmt, wav1.samples[i:i + sample_size]))
99+
sample2 = ', '.join(str(j) for j in unpack(fmt, wav2.samples[i:i + sample_size]))
100100
if sample1 != sample2:
101-
diffs.append('sample {}/{}: {}, {}'.format(index, wav1.num_samples, sample1, sample2))
101+
diffs.append(f'sample {index}/{wav1.num_samples}: {sample1}; {sample2}')
102102
index += 1
103103

104104
if diffs:
@@ -128,7 +128,7 @@ def show_diffs(fname1, data1, fname2, data2):
128128
files = []
129129
for fname in namespace.wavfiles[:2]:
130130
with open(fname, 'rb') as f:
131-
files.append(list(f.read()))
131+
files.append(f.read())
132132

133133
try:
134134
if namespace.diff:

0 commit comments

Comments
 (0)