Skip to content

Instantly share code, notes, and snippets.

@eevee
Created Jul 4, 2018
Embed
What would you like to do?
anise aowr bitcrusher
import wave
TARGET_RATE = 16384
with wave.open('aowr2.wav') as w:
with wave.open('aowrcrush2.wav', 'wb') as wout:
nchannels, sample_width, framerate, nframes, _, _ = w.getparams()
wout.setparams(w.getparams())
outdata = bytearray()
gbdata = bytearray()
frames_per_note = framerate // TARGET_RATE
nybble = None
while True:
data = w.readframes(frames_per_note)
if not data:
break
n = 0
total = 0
for i in range(0, len(data), nchannels * sample_width):
frame = int.from_bytes(data[i : i + sample_width], 'little', signed=True)
n += 1
total += frame
crushed_frame = round(total / n / (1 << (sample_width * 8 - 4)))
encoded_crushed_frame = (crushed_frame << (sample_width * 8 - 4)).to_bytes(2, 'little', signed=True)
outdata.extend(encoded_crushed_frame * (nchannels * frames_per_note))
print(f"{n} {total / n:5.0f} {crushed_frame:2d} {(crushed_frame << (sample_width * 8 - 4)):5.0f}")
#next_nybble = crushed_frame % 16
next_nybble = crushed_frame + 8
if nybble is None:
nybble = next_nybble
else:
byte = (nybble << 4) | next_nybble
gbdata.append(byte)
nybble = None
wout.writeframes(outdata)
with open('build/aowr.dat', 'wb') as f:
f.write(gbdata)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment