Last active
June 17, 2019 17:47
-
-
Save daxaxelrod/c2aac8ced2c8cf8c66d67ee224435cf1 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Credit goes to https://blog.theroyweb.com/extracting-wav-file-header-information-using-a-python-script