feat: add physically explicit narrowband MUSIC
This commit is contained in:
@@ -40,6 +40,8 @@ function resultFrequencyObservation(scene, experiment, band, equivalentBandIds =
|
||||
localizationModel:
|
||||
experiment.beamforming?.algorithm === "gcc-phat"
|
||||
? "band-limited-gcc-phat-geometric-lag"
|
||||
: experiment.beamforming?.algorithm === "music"
|
||||
? "near-field-music-at-positive-adc-bin-frequency"
|
||||
: "spherical-steering-at-positive-adc-bin-frequency",
|
||||
originalCarrierUsed: observation.originalCarrierUsed,
|
||||
aliasOrderResolution: observation.aliased ? "not-attempted" : "not-applicable",
|
||||
@@ -234,17 +236,26 @@ test("단일 tone 장면과 실험이 관계 검증을 통과한다", async () =
|
||||
assertEqual((await validateExperiment(experiment, { arrayDefinition, scene })).length, 0, "experiment issues");
|
||||
});
|
||||
|
||||
test("세 위치 추정 알고리즘과 backend 제약을 계약이 검증한다", async () => {
|
||||
test("네 위치 추정 알고리즘과 backend 제약을 계약이 검증한다", async () => {
|
||||
const [arrayDefinition, scene, baseline] = await Promise.all([
|
||||
loadJson("/assets/array-geometries/rectangular-16x12.array.json"),
|
||||
loadJson("/assets/sample-scenes/single-tone.scene.json"),
|
||||
loadJson("/assets/sample-scenes/single-tone.experiment.json"),
|
||||
]);
|
||||
|
||||
for (const algorithm of ["das", "das-phat", "gcc-phat"]) {
|
||||
for (const algorithm of ["das", "das-phat", "gcc-phat", "music"]) {
|
||||
const experiment = structuredClone(baseline);
|
||||
experiment.beamforming.algorithm = algorithm;
|
||||
experiment.beamforming.backend = algorithm === "gcc-phat" ? "cpu" : "auto";
|
||||
experiment.beamforming.backend =
|
||||
algorithm === "gcc-phat" || algorithm === "music" ? "cpu" : "auto";
|
||||
if (algorithm === "music") {
|
||||
experiment.frequencyBands = [
|
||||
{ id: "single-bin", minHz: 1000, maxHz: 1050, color: "#65f2bf" },
|
||||
];
|
||||
experiment.beamforming.normalization = "none";
|
||||
experiment.beamforming.musicSourceCountMethod = "fixed";
|
||||
experiment.beamforming.musicSourceCount = 1;
|
||||
}
|
||||
assertEqual(
|
||||
(await validateExperiment(experiment, { arrayDefinition, scene })).length,
|
||||
0,
|
||||
@@ -252,6 +263,31 @@ test("세 위치 추정 알고리즘과 backend 제약을 계약이 검증한다
|
||||
);
|
||||
}
|
||||
|
||||
const autoWithStaleK = structuredClone(baseline);
|
||||
autoWithStaleK.frequencyBands = [
|
||||
{ id: "single-bin", minHz: 1000, maxHz: 1050, color: "#65f2bf" },
|
||||
];
|
||||
autoWithStaleK.stft.hopSize = autoWithStaleK.stft.fftSize;
|
||||
Object.assign(autoWithStaleK.beamforming, {
|
||||
algorithm: "music",
|
||||
backend: "cpu",
|
||||
normalization: "none",
|
||||
musicSourceCountMethod: "mdl",
|
||||
musicSourceCount: 8,
|
||||
});
|
||||
const smallArray = {
|
||||
...arrayDefinition,
|
||||
microphones: arrayDefinition.microphones.slice(0, 4),
|
||||
};
|
||||
assertEqual(
|
||||
(await validateExperiment(autoWithStaleK, {
|
||||
arrayDefinition: smallArray,
|
||||
scene,
|
||||
})).length,
|
||||
0,
|
||||
"MDL ignores disabled stale fixed K after an array-size change",
|
||||
);
|
||||
|
||||
const incompatible = structuredClone(baseline);
|
||||
incompatible.beamforming.algorithm = "gcc-phat";
|
||||
incompatible.beamforming.backend = "webgpu";
|
||||
@@ -271,7 +307,7 @@ test("세 위치 추정 알고리즘과 backend 제약을 계약이 검증한다
|
||||
"GCC-PHAT requires two microphones",
|
||||
);
|
||||
|
||||
incompatible.beamforming.algorithm = "music";
|
||||
incompatible.beamforming.algorithm = "invented-localizer";
|
||||
issues = await validateExperiment(incompatible, { arrayDefinition, scene });
|
||||
assert(
|
||||
issues.some(({ path }) => path === "$.beamforming.algorithm"),
|
||||
|
||||
Reference in New Issue
Block a user