dither4/pack-vocoder.js
2024-10-27 12:22:09 -07:00

102 lines
2.3 KiB
JavaScript

import wavefile from 'wavefile';
let WaveFile = wavefile.WaveFile;
import {default as dct} from 'dct';
const sampleRate = 15000;
let frameRate = 60;
let samplesPerFrame = sampleRate / frameRate;
import {
readFileSync,
writeFileSync
} from 'fs';
function audio2voices(samples) {
let voices = [];
let floatSamples = samples.map((byte) => ((byte / 256) - 0.5) * 2);
let transformed = dct(floatSamples);
console.log('audio2voices');
console.log(floatSamples);
console.log(transformed);
//throw new Error('xxxxx');
let freqs = transformed.map((_f, i) => i * frameRate);
let bands = new Float64Array(256);
for (let i = 0; i < transformed.length; i++) {
let amplitude = transformed[i];
let freq = freqs[i];
if (freq == 0) {
continue;
}
let divisor = Math.floor(sampleRate / freq) - 1;
if (divisor > 255) {
continue;
}
bands[divisor] += amplitude;
}
console.log(bands);
for (let i = 0; i < 4; i++) {
let divisor = 0;
let max = 0;
for (let j = 0; j < bands.length; j++) {
if (bands[j] > max) {
divisor = j;
max = bands[j];
}
}
let amplitude16 = Math.floor(max * 7) + 8;
voices.push(divisor, amplitude16);
}
return voices;
}
function byte2byte(arr) {
let lines = [];
for (let i=0; i < arr.length; i++) {
lines.push(`.byte ${arr[i]}`);
}
return lines.join('\n');
}
function output2assembly(output) {
return `
.segment "AUDIO"
.export audio_samples
.export audio_samples_end
audio_samples:
${byte2byte(output)}
audio_samples_end:
.byte 24
`;
}
function wav2assembly(buffer) {
let wav = new WaveFile(buffer);
let samples = wav.getSamples();
let seconds = samples.length / sampleRate;
let frames = Math.floor(seconds * frameRate);
let output = [];
for (let i = 0; i < frames * samplesPerFrame; i += samplesPerFrame) {
let voices = audio2voices(samples.slice(i, i + samplesPerFrame));
output.push(...voices);
}
console.log(output);
return output2assembly(output);
}
let infile = process.argv[2];
let outfile = process.argv[3];
let buffer = readFileSync(infile);
let asm = wav2assembly(buffer);
writeFileSync(outfile, asm, 'utf-8');