-
Notifications
You must be signed in to change notification settings - Fork 1
/
WavHeader.py
90 lines (88 loc) · 3.27 KB
/
WavHeader.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# WavHeader.py
# Extract basic header information from a WAV file
# python WavHeader.py start.wav
def PrintWavHeader(strWAVFile):
""" Extracts data in the first 44 bytes in a WAV file and writes it
out in a human-readable format
"""
import os
import struct
import logging
logging.basicConfig(level=logging.DEBUG)
def DumpHeaderOutput(structHeaderFields):
for key in structHeaderFields.keys():
print "%s: " % (key), structHeaderFields[key]
# end for
# Open file
try:
fileIn = open(strWAVFile, 'rb')
except IOError, err:
logging.debug("Could not open input file %s" % (strWAVFile))
return
# end try
# Read in all data
bufHeader = fileIn.read(38)
# Verify that the correct identifiers are present
if (bufHeader[0:4] != "RIFF") or \
(bufHeader[12:16] != "fmt "):
logging.debug("Input file not a standard WAV file")
return
# endif
stHeaderFields = {'ChunkSize' : 0, 'Format' : '',
'Subchunk1Size' : 0, 'AudioFormat' : 0,
'NumChannels' : 0, 'SampleRate' : 0,
'ByteRate' : 0, 'BlockAlign' : 0,
'BitsPerSample' : 0, 'Filename': ''}
# Parse fields
stHeaderFields['ChunkSize'] = struct.unpack('<L', bufHeader[4:8])[0]
stHeaderFields['Format'] = bufHeader[8:12]
stHeaderFields['Subchunk1Size'] = struct.unpack('<L', bufHeader[16:20])[0]
stHeaderFields['AudioFormat'] = struct.unpack('<H', bufHeader[20:22])[0]
stHeaderFields['NumChannels'] = struct.unpack('<H', bufHeader[22:24])[0]
stHeaderFields['SampleRate'] = struct.unpack('<L', bufHeader[24:28])[0]
stHeaderFields['ByteRate'] = struct.unpack('<L', bufHeader[28:32])[0]
stHeaderFields['BlockAlign'] = struct.unpack('<H', bufHeader[32:34])[0]
stHeaderFields['BitsPerSample'] = struct.unpack('<H', bufHeader[34:36])[0]
# Locate & read data chunk
chunksList = []
dataChunkLocation = 0
fileIn.seek(0, 2) # Seek to end of file
inputFileSize = fileIn.tell()
nextChunkLocation = 12 # skip the RIFF header
while 1:
# Read subchunk header
fileIn.seek(nextChunkLocation)
bufHeader = fileIn.read(8)
if bufHeader[0:4] == "data":
dataChunkLocation = nextChunkLocation
# endif
nextChunkLocation += (8 + struct.unpack('<L', bufHeader[4:8])[0])
chunksList.append(bufHeader[0:4])
if nextChunkLocation >= inputFileSize:
break
# endif
# end while
# Dump subchunk list
print "Subchunks Found: "
for chunkName in chunksList:
print "%s, " % (chunkName),
# end for
print "\n"
# Dump data chunk information
if dataChunkLocation != 0:
fileIn.seek(dataChunkLocation)
bufHeader = fileIn.read(8)
print "Data Chunk located at offset [%s] of data length [%s] bytes" % \
(dataChunkLocation, struct.unpack('<L', bufHeader[4:8])[0])
# endif
# Print output
stHeaderFields['Filename'] = os.path.basename(strWAVFile)
DumpHeaderOutput(stHeaderFields)
# Close file
fileIn.close()
if __name__ == "__main__":
import sys
if len(sys.argv) != 2:
print "Invalid argument. Exactly one wave file location required as argument"
else:
PrintWavHeader(sys.argv[1])