Files
ep-133-project-export/scripts/reaper_generate_vst_state.mjs

136 lines
4.4 KiB
JavaScript
Executable File

const VST_HEADER = [
109, 111, 115, 114, 238, 94, 237, 254, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0,
0, 0, 0, 0, 90, 1, 0, 0, 1, 0, 0, 0, 0, 0, 16, 0,
];
const VST_BODY = [
0, 0, 0, 0, 0, 0, 240, 63, 0, 0, 0, 0, 0, 0, 224, 63, 0, 0, 0, 0, 0, 0, 240, 63, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 240, 63, 154, 153, 153, 153, 153, 153, 177, 63, 205, 204, 204, 204, 204,
204, 235, 63, 0, 0, 0, 0, 0, 0, 0, 0, 28, 199, 113, 28, 199, 113, 220, 63, 252, 169, 241, 210, 77,
98, 64, 63, 252, 169, 241, 210, 77, 98, 64, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 240, 63, 0, 0, 0, 0, 0, 0, 224, 63, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 240, 63, 64, 0, 0, 0, 85, 85, 85, 85, 85, 85, 197, 63, 255, 255,
255, 255, 8, 4, 2, 129, 64, 32, 128, 63, 0, 0, 0, 0, 0, 0, 240, 63, 0, 0, 0, 0, 0, 0, 240, 63, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 206,
164, 33, 33, 26, 101, 144, 63, 0, 0, 0, 0, 0, 0, 240, 63, 252, 169, 241, 210, 77, 98, 48, 63, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0,
];
function int32ToLEBytes(value) {
const bytes = new Uint8Array(4);
bytes[0] = value & 0xff;
bytes[1] = (value >> 8) & 0xff;
bytes[2] = (value >> 16) & 0xff;
bytes[3] = (value >> 24) & 0xff;
return bytes;
}
function bytesToDouble(bytes) {
if (bytes.length !== 8) {
throw new Error('Expected 8 bytes');
}
const buffer = new ArrayBuffer(8);
const view = new DataView(buffer);
bytes.forEach((b, i) => view.setUint8(i, b));
return view.getFloat64(0, true);
}
function doubleToBytes(num) {
const buffer = new ArrayBuffer(8);
const view = new DataView(buffer);
view.setFloat64(0, num, true);
const bytes = [];
for (let i = 0; i < 8; i++) {
bytes.push(view.getUint8(i));
}
return bytes;
}
function paramToBytes(paramValue) {
const normalizedValue = paramValue / 250.0;
const buffer = new ArrayBuffer(8);
const view = new DataView(buffer);
view.setFloat64(0, normalizedValue, true);
const bytes = [];
for (let i = 0; i < 8; i++) {
bytes.push(view.getUint8(i));
}
return bytes;
}
function dbToBytes(dbValue) {
const linearGain = Math.pow(10, dbValue / 20);
const buffer = new ArrayBuffer(8);
const view = new DataView(buffer);
view.setFloat64(0, linearGain, true);
const bytes = [];
for (let i = 0; i < 8; i++) {
bytes.push(view.getUint8(i));
}
return bytes;
}
function msToBytes(msValue, sampleLengthMs) {
const normalizedValue = msValue / sampleLengthMs;
const buffer = new ArrayBuffer(8);
const view = new DataView(buffer);
view.setFloat64(0, normalizedValue, true);
const bytes = [];
for (let i = 0; i < 8; i++) {
bytes.push(view.getUint8(i));
}
return bytes;
}
function bytesToString(bytes) {
return bytes.reduce((acc, byte, index) => {
return `${acc + String(index).padStart(3, '0')} ${byte}\n`;
}, '');
}
function buildVstState({ filePath, volume = -6, attack = 10, release = 10 }) {
const encoder = new TextEncoder();
const bufferHeader = VST_HEADER;
const bufferBody = [...VST_BODY];
// console.log(cut.length);
// console.dir(bufferHeader, { maxArrayLength: null, compact: false });
// console.dir(Buffer.from(bufferBody).toString('utf8'), { maxArrayLength: null, compact: fal 6y5a -O0se });
// const decoder = new TextDecoder('utf-8'); // Specify the encoding, e.g., 'utf-8'
// console.log(decoder.decode(new Uint8Array(VST_BODY)));
// console.log(decoder.decode(new Uint8Array(cut)));
bufferBody.splice(0, 8, ...dbToBytes(volume));
// bufferBody.splice(8, 8, ...dbToBytes(5));
// bufferBody.splice(16, 8, ...dbToBytes()); // min volume
bufferBody.splice(72, 8, ...msToBytes(attack, 920)); // atack
bufferBody.splice(80, 8, ...msToBytes(release, 920)); // release
// console.dir(bufferBody, { maxArrayLength: null, compact: false });
console.log(bytesToString(bufferBody));
const fullBody = [...encoder.encode(filePath), 0, ...bufferBody];
bufferHeader.splice(32, 4, ...int32ToLEBytes(fullBody.length));
return {
header: Buffer.from(bufferHeader).toString('base64'),
body: Buffer.from(fullBody).toString('base64'),
};
}
const result = buildVstState({
filePath: 'Media/BD B 808 Decay C 02.wav',
// filePath: 'Media/600 veh2 percussive .wav',
});
console.log(' ' + result.header);
console.log(' ' + result.body);