Initial commit: RHINE LAB · ANALYSIS OS:三维界面与动效实验(本仓库不含个人归档索引数据)

This commit is contained in:
WpyQwq
2026-09-19 13:04:56 +08:00
commit 3f422218a5
1098 changed files with 39410 additions and 0 deletions
+66
View File
@@ -0,0 +1,66 @@
// Read the local source only; emit measured levels, not a subjective listening report.
// node scripts/analyze-reference-audio.mjs path/to/ffmpeg.exe
import fs from "node:fs";
import { execFileSync } from "node:child_process";
const video = fs.readdirSync(".").find((x) => x.endsWith(".mp4"));
if (!video || !process.argv[2])
throw Error("Local reference video and ffmpeg path required");
const rate = 24000;
const pcm = execFileSync(
process.argv[2],
[
"-v",
"error",
"-ss",
"6.76",
"-i",
video,
"-t",
"33.24",
"-vn",
"-af",
"pan=mono|c0=0.5*c0+0.5*c1",
"-ac",
"1",
"-ar",
String(rate),
"-f",
"f32le",
"pipe:1",
],
{ maxBuffer: 16 * 1024 * 1024 },
);
const samples = new Float32Array(pcm.buffer, pcm.byteOffset, pcm.length / 4);
const bounds = [6.76, 9.16, 11.12, 19.48, 22.76, 26.92, 30.68, 33.3, 40];
const stages = bounds.slice(0, -1).map((start, i) => {
const data = samples.subarray(
Math.round((start - 6.76) * rate),
Math.round((bounds[i + 1] - 6.76) * rate),
);
let peak = 0,
sum = 0;
for (const x of data) {
peak = Math.max(peak, Math.abs(x));
sum += x * x;
}
return {
start,
end: bounds[i + 1],
peakDb: +(20 * Math.log10(peak)).toFixed(2),
rmsDb: +(10 * Math.log10(sum / data.length)).toFixed(2),
};
});
fs.writeFileSync(
"reference/audio-analysis.json",
JSON.stringify(
{
video,
scope:
"6.76–40 s, mono downmix; not a transcription or melody identification",
stages,
},
null,
2,
) + "\n",
);
console.log(stages);