perf: stream propagation working sets

This commit is contained in:
2026-08-29 10:56:51 +09:00
parent de0053eae3
commit 044be3cf92
13 changed files with 1532 additions and 267 deletions
+21 -41
View File
@@ -4,6 +4,10 @@ import {
MAX_PRECISE_ANALOG_FREQUENCY_HZ,
observeFrequencyBand,
} from "../acoustics-core/sampling.js";
import {
DEFAULT_MAXIMUM_SYNTHESIS_BUFFER_BYTES,
estimateSynthesisWorkingSet,
} from "../acoustics-core/propagation.js";
export const INPUT_SCHEMA_VERSION = "1.0.0";
export const RESULT_SCHEMA_VERSION = "1.1.0";
@@ -554,51 +558,27 @@ function validateExperimentRelationships(value, context = {}) {
"gcc-phat에는 서로 다른 두 개 이상의 마이크가 필요합니다.",
);
}
const sampledSourceCount = context.scene.sources
.filter((source) => source.signal?.type !== "tone")
.length;
const hasSampledAmbient = (context.scene.ambient ?? [])
.some((ambient) => ambient.signal?.type !== "tone");
const retainedBufferCount =
context.arrayDefinition.microphones.length +
sampledSourceCount +
(hasSampledAmbient ? 1 : 0);
const sampleCount = Math.ceil(context.scene.duration * context.scene.sampleRate);
let maximumDelaySamples = 0;
for (const source of context.scene.sources) {
const sourcePositions = Array.isArray(source.trajectory)
? source.trajectory.map((keyframe) => keyframe.position)
: [source.position];
for (const sourcePosition of sourcePositions) {
for (const microphone of context.arrayDefinition.microphones) {
const distance = Math.hypot(
sourcePosition[0] - microphone.position[0],
sourcePosition[1] - microphone.position[1],
sourcePosition[2] - microphone.position[2],
);
maximumDelaySamples = Math.max(
maximumDelaySamples,
(distance / context.scene.speedOfSound) * context.scene.sampleRate,
);
}
try {
const workingSet = estimateSynthesisWorkingSet({
scene: context.scene,
arrayDefinition: context.arrayDefinition,
minimumDistance: value.beamforming?.minimumDistance ?? 0.01,
});
if (
workingSet.estimatedBufferBytes >
DEFAULT_MAXIMUM_SYNTHESIS_BUFFER_BYTES
) {
addIssue(
issues,
"$",
`source-streaming signal buffer 예상 크기 ${(workingSet.estimatedBufferBytes / 1024 ** 2).toFixed(1)} MiB가 512 MiB 한도를 넘습니다.`,
);
}
}
let delayFftSize = 1;
const hasSampledSignal = sampledSourceCount > 0 || hasSampledAmbient;
if (hasSampledSignal) {
while (delayFftSize < sampleCount + Math.ceil(maximumDelaySamples) + 2) {
delayFftSize *= 2;
}
}
const delayWorkingBytes = hasSampledSignal ? delayFftSize * 8 * 4 : 0;
const estimatedBytes =
retainedBufferCount * sampleCount * 4 + delayWorkingBytes;
const maximumBytes = 512 * 1024 * 1024;
if (estimatedBytes > maximumBytes) {
} catch (error) {
addIssue(
issues,
"$",
`현재 비스트리밍 CPU 모델의 signal buffer 예상 크기 ${(estimatedBytes / 1024 ** 2).toFixed(1)} MiB가 512 MiB 한도를 넘습니다.`,
`signal synthesis preflight failed: ${error.message}`,
);
}
}