Skip to content

Instantly share code, notes, and snippets.

@alkhimey
Last active September 14, 2019 22:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alkhimey/55eb4d4b03b680b1f5742ec513aeb071 to your computer and use it in GitHub Desktop.
Save alkhimey/55eb4d4b03b680b1f5742ec513aeb071 to your computer and use it in GitHub Desktop.
""" Assumes the input WAV file is mono (1 channel) with 16 bit samples """
import sys
if len(sys.argv) != 2:
print("Wrong number of arguments.")
exit();
filename = sys.argv[1]
bytes = []
with open(filename, "br") as f:
bytes = f.read()
# Parse according to format
# Here: http://soundfile.sapp.org/doc/WaveFormat/
chunkID = bytes[0:4].decode()
chunkSize = int.from_bytes(bytes[4:8], byteorder='little')
innerFormat = bytes[8:12].decode()
subchunk1ID = bytes[12:16].decode()
subchunk1Size = int.from_bytes(bytes[16:20], byteorder='little')
audioFormat = int.from_bytes(bytes[20:22], byteorder='little')
numChannels = int.from_bytes(bytes[22:24], byteorder='little')
sampleRate = int.from_bytes(bytes[24:28], byteorder='little')
byteRate = int.from_bytes(bytes[28:32], byteorder='little')
blockAlign = int.from_bytes(bytes[32:34], byteorder='little')
bitsPerSample = int.from_bytes(bytes[34:36], byteorder='little')
subchunk2ID = bytes[36:40].decode()
subchunk2Size = int.from_bytes(bytes[40:44], byteorder='little')
data = []
lastSample = 40 + subchunk2Size
for byte_pair in zip( bytes[40:lastSample:2], bytes[41:lastSample:2]):
data.append( (int.from_bytes(byte_pair, byteorder='little', signed=True)))
print('chunkID\t\t%s' % chunkID)
print('chunkSize\t%d' % chunkSize)
print('innerFormat\t%s' % innerFormat)
print('subchunk1ID\t%s' % subchunk1ID)
print('subchunk1Size\t%d' % subchunk1Size)
print('audioFormat\t%d' % audioFormat)
print('numChannels\t%d' % numChannels)
print('sampleRate\t%d' % sampleRate)
print('byteRate\t%d' % byteRate)
print('blockAlign\t%d' % blockAlign)
print('bitsPerSample\t%d' % bitsPerSample)
print('subchunk2ID\t%s' % subchunk2ID)
print('subchunk2Size\t%d' %subchunk2Size)
print("Actual size of data (16 bit words): %d" % len(data))
assert(chunkSize == 4 + (8 + subchunk1Size) + (8 + subchunk2Size))
assert(byteRate == sampleRate * numChannels * (bitsPerSample / 8))
assert(blockAlign == numChannels * (bitsPerSample / 8))
assert(subchunk2Size == len(data) * numChannels * (bitsPerSample / 8))
def chunks(l, n):
"""Yield successive n-sized chunks from l."""
for i in range(0, len(l), n):
yield l[i:i + n]
with open('wav_data.h', 'w') as f:
f.write(
"""
#ifndef WAV_DATA
#define WAV_DATA
#define NUM_SAMPLES %d
#define SAMPLE_RATE %d
int16_t data[NUM_SAMPLES] PROGMEM = {
""" % (len(data), sampleRate) )
for row in chunks(data, 8):
f.write(" ");
f.write(", ".join(list((str(word) for word in row))))
f.write(",")
f.write("\n")
f.write("};\n")
f.write("#endif\n\n")
try:
import matplotlib.pylab as plt
plt.plot(data)
plt.show()
except:
None
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment