Last active
February 15, 2018 23:26
-
-
Save lborg019/538eb6dbe33206cee5a5cd6584122755 to your computer and use it in GitHub Desktop.
Deinterlace .wav files: $ python2 wav-deinterlacer.py <filename.wav> <samplesize (in bytes)>
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 sys | |
import binascii | |
from itertools import chain, izip, repeat, islice | |
# this program is compatible with python 2.7.8 | |
# interspace function | |
def intersperse(delimiter, seq): | |
return islice(chain.from_iterable(izip(repeat(delimiter), seq)), 1, None) | |
# parse command line arguments | |
if len(sys.argv) != 3: | |
print("Usage: python deinterlacer.py <\"filename\"> <samplesize_bytes>") | |
exit() | |
else: | |
# arguments are okay, check if file exists: | |
found = False | |
files = [f for f in os.listdir('.') if os.path.isfile(f)] # lists all files | |
for f in files: | |
if f == sys.argv[1]: # match | |
# file found | |
found = True | |
# check sample size: | |
''' | |
1 byte = 4 bits | |
2 bytes = 8 bits | |
4 bytes = 16 bits | |
8 bytes = 32 bits | |
''' | |
if sys.argv[2] == "1" or sys.argv[2] == "2" or sys.argv[2] == "4" or sys.argv[2] == "8": | |
# valid sample size: | |
print("File found") | |
# open input file, read it into memory: | |
fin = sys.argv[1] | |
with open(fin, 'rb') as f: | |
content = f.read() | |
f.close() | |
# separate hex header from hex data | |
xcontent = binascii.hexlify(content) | |
xdatadelim = "64617461" | |
delim = xcontent.find(xdatadelim) | |
xdata = xcontent[delim+len(xdatadelim)+8:] | |
header = xcontent[0:144+len(xdatadelim)+8] | |
# print first 30 hex for both header and data | |
print("header: "+header[0:30]) | |
print("data: "+xdata[0:30]) | |
chunksize = int(sys.argv[2]) | |
# group data according to argument passed | |
hexes = [] | |
for index, item in enumerate(xdata): | |
if index % chunksize == 0: | |
concat = xdata[index:index+chunksize] | |
hexes.append(concat) | |
''' | |
print(hexes[0]) | |
print(hexes[1]) | |
print(hexes[2]) | |
print(hexes[3]) | |
print('') | |
''' | |
# clear clear one of the channels | |
leftdata = hexes[0::2] | |
''' | |
in mono, commenting out the previous inline slows | |
down the song by repeating the frequencies lol | |
adding: # hexes = hexes[::3] will speed up song | |
might need to be adjusted for stereo | |
''' | |
# shift and clear the channel | |
rightdata = hexes[1::] # snip first element | |
rightdata = rightdata[0::2] # get every other element | |
''' | |
print("raw left speaker data") | |
print(leftdata[0]) | |
print(leftdata[1]) | |
print(leftdata[2]) | |
print(leftdata[3]) | |
print("raw right speaker data") | |
print(rightdata[0]) | |
print(rightdata[1]) | |
print(rightdata[2]) | |
print(rightdata[3]) | |
''' | |
# now that we have raw audio data, we intersperse it | |
# with 0s in order to silence the other speaker | |
''' slow (unusable solution when interspersing python lists) | |
for index, item in enumerate(hexes): | |
if index % 2 == 0: | |
hexes.insert(index-1, '00000000') | |
''' | |
# we intersperse with the correct amount of 0s: | |
silence = "00000000" # max is 8 bytes of hex data | |
silence = silence[0:chunksize] | |
# badass solution to intersperse python lists: | |
leftspeaker = list(intersperse(silence, leftdata)) | |
rightspeaker = list(intersperse(silence, rightdata)) # intersperse with silence | |
rightspeaker = [silence] + rightspeaker # append silence to head which was previously removed | |
print("left speaker deinterlaced data:") | |
print(leftspeaker[0]) | |
print(leftspeaker[1]) | |
print(leftspeaker[2]) | |
print(leftspeaker[3]) | |
print("right speaker deinterlaced data:") | |
print(rightspeaker[0]) | |
print(rightspeaker[1]) | |
print(rightspeaker[2]) | |
print(rightspeaker[3]) | |
foutr = "right.wav" | |
foutl = "left.wav" | |
# write right speaker file: | |
with open(foutr, 'wb') as fout: | |
# write header: | |
fout.write(binascii.unhexlify(header)) | |
# write data for right speaker on right speaker file: | |
for index, item in enumerate(rightspeaker): | |
fout.write(binascii.unhexlify(item)) | |
fout.close() | |
print("right speaker file written") | |
# write left speaker file: | |
with open(foutl, 'wb') as fout: | |
# write header: | |
fout.write(binascii.unhexlify(header)) | |
# write data for left speaker on left speaker file: | |
for index, item in enumerate(leftspeaker): | |
fout.write(binascii.unhexlify(item)) | |
fout.close() | |
print("left speaker file written") | |
else: | |
print("Sample size must be in bytes.\nSupported sample "+ | |
"sizes: 1, 2, 4, or 8 bytes") | |
exit() | |
if(found == False): | |
print("File requested not available in directory.") | |
exit() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment