perf: stream propagation working sets
This commit is contained in:
@@ -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}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user