Last active
November 29, 2017 03:07
-
-
Save jslegendre/7aa79ad79b9e05036fe3c1ba6b394a7d to your computer and use it in GitHub Desktop.
WAV to Plot from scratch in Python. I know this can be done using SciPy or various other libraries but I wanted to learn more about wav data so I did this from scratch. Added bonus to doing this myself is that I could specify how accurately I wanted the data to be in order to speed up time on large files. Currently, this only works on 16bit mono…
This file contains 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 sys | |
import numpy as np | |
import struct | |
import warnings | |
path="sample.wav" | |
#get the file size in bytes | |
fileSize=os.path.getsize(path) | |
f=open(path,"r") | |
#Go to ByteRate at offset 28 | |
f.seek(28) | |
#Read in 4 bytes and convert to signed int | |
b = struct.unpack('i', f.read(4)) | |
byteRate= b[0] | |
#Calculate duration of sound | |
ms=((fileSize-44)*1000)/byteRate | |
#Go to first byte of sound data | |
f.seek(44,0) | |
#secSize or Section Size will allow you to grab a "chunk" of | |
#data and find the average instead of plotting every | |
#individual point.Very useful for a quick analysis of | |
#large files. 1 = 1:1 / 16 = 16:1 | |
secSize = 16 | |
dValue=0 #dataValue | |
dVals = [] #dataValues | |
mVals =[] #meanValues | |
done = 'n' | |
#Generate Y values | |
while (done != 'y') : | |
q=0 | |
while q < secSize : | |
try: | |
#Read 'short' from wav file | |
dValue = struct.unpack('=h', f.read(2)) | |
except struct.error: | |
#If your section size extends past the last byte | |
#just break out of the loop | |
done = 'y' | |
break | |
dVals.append(dValue[0]) | |
q += 1 | |
#Supress NumPys "Nan" warning | |
warnings.simplefilter("ignore") | |
#Find average of section and add it to mVals | |
mVals.append(np.mean(dVals)) | |
dVals=[] | |
dValue = 0 | |
#Find the amount of time each | |
#point will represent | |
xInc = round(float(ms)/len(mVals), 6) | |
x = 0 | |
yInc = 1 | |
y=0 | |
pair=[] | |
pairs = [] | |
#Generate X values for Y counterparts | |
while (x < ms): | |
try: | |
y = round(mVals[yInc], 2) | |
except IndexError: | |
break | |
pair.append(round(x, 6)) | |
pair.append(y) | |
pairs.append(pair) | |
x += xInc | |
yInc += 1 | |
pair=[] | |
#Flush buffer just to be safe | |
sys.stdout.flush() | |
#Print 'x,y' to console. | |
#To write to file: ./ThisScript.py > data.txt | |
h = 0 | |
while (h < len(pairs)): | |
sys.stdout.write(str(pairs[h][0]) + ',' + str(pairs[h][1]) + '\n') | |
#Uncomment next line for '(x,y)' | |
#sys.stdout.write('(' + str(pairs[h][0]) + ',' + str(pairs[h][1]) + ')' + '\n') | |
h+=1 | |
f.close() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment