86 lines
1.7 KiB
JavaScript
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');
|
|
|