dither4/pack-wav.js
2024-08-31 10:58:15 -07:00

86 lines
1.7 KiB
JavaScript

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 = (dithered - val);
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');