Checkpoint 2
parent
db73d04f0d
commit
8c5cfd88d9
@ -1,65 +1,88 @@
|
|||||||
const graph_density = 1000;
|
import findLoudness, { SwapPoint } from "./find-loudness";
|
||||||
|
|
||||||
|
const graph_density = 8000;
|
||||||
|
|
||||||
const threshold_at_point = 1;
|
const threshold_at_point = 1;
|
||||||
|
|
||||||
const inertia_s = 0.1;
|
const inertia_s = 0.3;
|
||||||
const inertia_samples = inertia_s * graph_density;
|
const inertia_samples = inertia_s * graph_density;
|
||||||
|
|
||||||
let position = 0;
|
const s = (n: number) => n / graph_density;
|
||||||
let last_swap_position = 0;
|
|
||||||
|
|
||||||
const s = (n: number) => Math.round(n / graph_density);
|
|
||||||
|
|
||||||
const minutes = (units: number) => Math.floor(s(units) / 60);
|
const minutes = (units: number) => Math.floor(s(units) / 60);
|
||||||
|
|
||||||
|
const hours = (units: number) => Math.floor(units / graph_density / 60 / 60);
|
||||||
|
|
||||||
const formatTime = (units: number) =>
|
const formatTime = (units: number) =>
|
||||||
`${minutes(units)}:${Math.floor(s(units) % 60)}`;
|
`${hours(units)}:${minutes(units)}:${Math.floor(s(units) % 60)}`;
|
||||||
|
|
||||||
let keep_loud_until = 0;
|
type Mode = { left: boolean; right: boolean };
|
||||||
|
|
||||||
let total_speaking = 0;
|
async function run() {
|
||||||
|
const [left_breaks, right_breaks] = await Promise.all([
|
||||||
|
findLoudness(
|
||||||
|
"/tmp/leftraw",
|
||||||
|
threshold_at_point,
|
||||||
|
inertia_samples,
|
||||||
|
"left"
|
||||||
|
),
|
||||||
|
findLoudness(
|
||||||
|
"/tmp/rightraw",
|
||||||
|
threshold_at_point,
|
||||||
|
inertia_samples,
|
||||||
|
"right"
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
|
||||||
|
const merged = [...left_breaks, ...right_breaks].sort((a, b) =>
|
||||||
|
a.position_start < b.position_start
|
||||||
|
? -1
|
||||||
|
: a.position_start > b.position_start
|
||||||
|
? 1
|
||||||
|
: 0
|
||||||
|
);
|
||||||
|
|
||||||
const results: [string, number][] = [];
|
// console.log("left breaks:", left_breaks);
|
||||||
|
// console.log(`right_breaks`, right_breaks);
|
||||||
|
// console.log(`merged`, merged);
|
||||||
|
|
||||||
process.stdin.on("readable", () => {
|
function new_mode(m: Mode, s: SwapPoint): Mode {
|
||||||
let chunk: Buffer | null;
|
return { ...m, [s.label]: s.loud };
|
||||||
let was_loud_last_time = false;
|
|
||||||
while ((chunk = process.stdin.read()) !== null) {
|
|
||||||
for (let i = 0; i < chunk.byteLength; i++) {
|
|
||||||
position++;
|
|
||||||
const byte = chunk[i];
|
|
||||||
const volume = Math.abs(byte - 128);
|
|
||||||
const is_loud: boolean =
|
|
||||||
volume > threshold_at_point || position < keep_loud_until;
|
|
||||||
if (is_loud) {
|
|
||||||
total_speaking++;
|
|
||||||
}
|
}
|
||||||
if (is_loud != was_loud_last_time) {
|
|
||||||
results.push([
|
function mode_to_string(mode: Mode) {
|
||||||
is_loud ? "silence" : "speaking",
|
if (mode.left && mode.right) {
|
||||||
position - last_swap_position,
|
return "both";
|
||||||
]);
|
|
||||||
last_swap_position = position;
|
|
||||||
was_loud_last_time = is_loud;
|
|
||||||
}
|
}
|
||||||
if (volume > threshold_at_point) {
|
for (const side of ["left", "right"]) {
|
||||||
keep_loud_until = position + inertia_samples;
|
if (mode[side as keyof Mode]) {
|
||||||
|
return side;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return "none";
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
const mode_to_image = (mode: string) => {
|
|
||||||
return mode === "silence" ? "pics/cisza.png" : "pics/kuba.png";
|
|
||||||
};
|
|
||||||
|
|
||||||
process.stdin.on("end", () => {
|
|
||||||
results.forEach(([mode, duration_units]) => {
|
|
||||||
console.log("file", `'${mode_to_image(mode)}'`);
|
|
||||||
console.log("duration", (duration_units / graph_density).toFixed(4));
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log("file", `'${mode_to_image(results[results.length - 1][0])}'`);
|
console.log("file", `${process.cwd()}/pics/none.png`);
|
||||||
|
let last_point = 0;
|
||||||
// console.log(formatTime(total_speaking), formatTime(position));
|
let mode: Mode = { left: false, right: false };
|
||||||
});
|
let last_file;
|
||||||
|
let total = 0;
|
||||||
|
for (let i = 2; i < merged.length; i++) {
|
||||||
|
const point = merged[i];
|
||||||
|
mode = new_mode(mode, point);
|
||||||
|
const file = `${process.cwd()}/pics/${mode_to_string(mode)}.png`;
|
||||||
|
const duration = (point.position_start - last_point) / graph_density;
|
||||||
|
console.log(
|
||||||
|
"duration",
|
||||||
|
(point.position_start - last_point) / graph_density
|
||||||
|
);
|
||||||
|
console.log("file", file);
|
||||||
|
last_point = point.position_start;
|
||||||
|
last_file = file;
|
||||||
|
total += duration * graph_density;
|
||||||
|
}
|
||||||
|
console.log("duration", merged[merged.length - 1].duration / graph_density);
|
||||||
|
console.log("file", last_file);
|
||||||
|
console.error(total, formatTime(total));
|
||||||
|
}
|
||||||
|
run();
|
||||||
|
Loading…
Reference in New Issue