11#!/usr/bin/env python3
2+ from struct import unpack
23import sys
34import 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+
511class 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
4652def _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-
5755def 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):
128128files = []
129129for fname in namespace .wavfiles [:2 ]:
130130 with open (fname , 'rb' ) as f :
131- files .append (list ( f .read () ))
131+ files .append (f .read ())
132132
133133try :
134134 if namespace .diff :
0 commit comments