feat: add physically explicit narrowband MUSIC
This commit is contained in:
@@ -52,6 +52,17 @@ export function getFrameCount(sampleCount, fftSize, hopSize) {
|
||||
return Math.max(1, 1 + Math.ceil(Math.max(0, sampleCount - fftSize) / hopSize));
|
||||
}
|
||||
|
||||
export function getCompleteFrameCount(sampleCount, fftSize, hopSize) {
|
||||
if (!Number.isInteger(hopSize) || hopSize < 1 || hopSize > fftSize) {
|
||||
throw new Error("hopSize는 1 이상 fftSize 이하여야 합니다.");
|
||||
}
|
||||
if (!Number.isInteger(sampleCount) || sampleCount < 0) {
|
||||
throw new RangeError("sampleCount must be a non-negative integer.");
|
||||
}
|
||||
if (sampleCount < fftSize) return 0;
|
||||
return 1 + Math.floor((sampleCount - fftSize) / hopSize);
|
||||
}
|
||||
|
||||
export async function extractStftBins(channels, options) {
|
||||
const {
|
||||
fftSize,
|
||||
@@ -61,6 +72,8 @@ export async function extractStftBins(channels, options) {
|
||||
onProgress,
|
||||
transformBatchSize = 32,
|
||||
workspace: providedWorkspace,
|
||||
spectrumPrecision = "float32",
|
||||
includePartialFrame = true,
|
||||
} = options;
|
||||
if (!Array.isArray(channels) || channels.length === 0) throw new Error("마이크 채널이 필요합니다.");
|
||||
const sampleCount = channels[0].length;
|
||||
@@ -70,16 +83,27 @@ export async function extractStftBins(channels, options) {
|
||||
if (!Number.isInteger(bin) || bin < 0 || bin > fftSize / 2) throw new Error(`유효하지 않은 FFT bin: ${bin}`);
|
||||
}
|
||||
|
||||
const frameCount = getFrameCount(sampleCount, fftSize, hopSize);
|
||||
if (typeof includePartialFrame !== "boolean") {
|
||||
throw new TypeError("includePartialFrame must be boolean.");
|
||||
}
|
||||
const frameCount = includePartialFrame
|
||||
? getFrameCount(sampleCount, fftSize, hopSize)
|
||||
: getCompleteFrameCount(sampleCount, fftSize, hopSize);
|
||||
const microphoneCount = channels.length;
|
||||
if (!Number.isInteger(transformBatchSize) || transformBatchSize < 1) {
|
||||
throw new Error("transformBatchSize는 1 이상의 정수여야 합니다.");
|
||||
}
|
||||
if (spectrumPrecision !== "float32" && spectrumPrecision !== "float64") {
|
||||
throw new RangeError('spectrumPrecision must be "float32" or "float64".');
|
||||
}
|
||||
const SpectrumArray = spectrumPrecision === "float64"
|
||||
? Float64Array
|
||||
: Float32Array;
|
||||
const spectra = new Map();
|
||||
for (const bin of uniqueBins) {
|
||||
spectra.set(bin, {
|
||||
real: new Float32Array(frameCount * microphoneCount),
|
||||
imaginary: new Float32Array(frameCount * microphoneCount),
|
||||
real: new SpectrumArray(frameCount * microphoneCount),
|
||||
imaginary: new SpectrumArray(frameCount * microphoneCount),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -116,7 +140,7 @@ export async function extractStftBins(channels, options) {
|
||||
}
|
||||
onProgress?.({ completedTransforms, totalTransforms });
|
||||
throwIfAborted(signal);
|
||||
return { frameCount, microphoneCount, spectra };
|
||||
return { frameCount, microphoneCount, spectra, spectrumPrecision };
|
||||
}
|
||||
|
||||
export function binsForBand(band, sampleRate, fftSize) {
|
||||
|
||||
Reference in New Issue
Block a user