Skip to content

Instantly share code, notes, and snippets.

@daxaxelrod
Last active June 17, 2019 17:47
Show Gist options
  • Save daxaxelrod/c2aac8ced2c8cf8c66d67ee224435cf1 to your computer and use it in GitHub Desktop.
Save daxaxelrod/c2aac8ced2c8cf8c66d67ee224435cf1 to your computer and use it in GitHub Desktop.
import os
import struct
import logging
def PrintWavHeader(strWAVFile):
""" Extracts data in the first 44 bytes in a WAV file and writes it
out in a human-readable format
"""
def DumpHeaderOutput(structHeaderFields):
for key in structHeaderFields.keys():
print("%s: " % (key), structHeaderFields[key])
# end for
# Open file
try:
fileIn = open(strWAVFile, 'rb')
except Exception:
print("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] != b"RIFF") or \
(bufHeader[12:16] != b"fmt "):
print("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])
@daxaxelrod
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment