import wavefile from 'wavefile'; let WaveFile = wavefile.WaveFile; import { readFileSync, writeFileSync } from 'fs'; function byte2byte(arr) { let lines = []; for (let i=0; i < arr.length; i++) { lines.push(`.byte ${arr[i]}`); } return lines.join('\n'); } class Dither { constructor() { this.err = 0; } to4bit(val8) { let val = (val8 / 255) + this.err; if (val < 0) { val = 0; } if (val > 1) { val = 1; } let val4 = Math.round(val * 15); let dithered = (val4 / 15); this.err = (val - dithered); return val4; } } function pack(audio) { let packed = []; let dither = new Dither(); for (let i = 0; i < audio.length; i += 2) { // little-endian 4-bit samples let low = dither.to4bit(audio[i]); let high = dither.to4bit(audio[i + 1]); let byte = low | (high << 4); packed.push(byte); } /* // raw push bytes for (let i = 0; i < audio.length; i += 2) { let val = to4bit(audio[i]); let byte = val | 0x10; packed.push(byte); } */ return packed; } function audio2assembly(audio) { return ` .segment "AUDIO" .export audio_samples .export audio_samples_end audio_samples: ${byte2byte(pack(audio))} audio_samples_end: .byte 24 `; } function wav2assembly(buffer) { let wav = new WaveFile(buffer); let samples = wav.getSamples(); let n = samples.length - (samples.length % 131); return audio2assembly(samples.slice(0, n)); } let infile = process.argv[2]; let outfile = process.argv[3]; let buffer = readFileSync(infile); let asm = wav2assembly(buffer); writeFileSync(outfile, asm, 'utf-8');