dsp-collection
Version:
A collection of JavaScript modules for digital signal processing (written in TypeScript)
58 lines • 3.16 kB
JavaScript
import Complex from "../math/Complex.js";
import * as Goertzel from "./Goertzel.js";
import * as WindowFunctions from "./WindowFunctions.js";
export function getSingle_relWindow(samples, roughFrequency, roughWindowCenterPosition, relWindowWidth, windowFunction) {
if (roughFrequency <= 0 || roughFrequency >= 0.5 || relWindowWidth < 1) {
return;
}
if (!Number.isInteger(relWindowWidth)) {
throw new Error("Parameter relWindowWidth is not an integer.");
}
const windowWidth = Math.round(relWindowWidth / roughFrequency);
const windowStartPosition = Math.round(roughWindowCenterPosition - windowWidth / 2);
if (windowStartPosition < 0 || windowStartPosition + windowWidth > samples.length) {
return;
}
const windowSamples = samples.subarray(windowStartPosition, windowStartPosition + windowWidth);
const windowedSamples = windowFunction ? WindowFunctions.applyWindow(windowSamples, windowFunction) : windowSamples;
const component0 = Goertzel.goertzelSingle(windowedSamples, relWindowWidth);
const componentNormalized = component0.mulReal(2 / windowWidth);
const componentPhaseAdjusted = (relWindowWidth % 2 == 1) ? componentNormalized.neg() : componentNormalized;
return {
component: componentPhaseAdjusted,
frequency: relWindowWidth / windowWidth,
windowStartPosition: windowStartPosition,
windowWidth: windowWidth
};
}
export function getSingle_maxWindow(samples, roughFrequency, roughWindowCenterPosition, maxWindowWidth, windowFunction) {
const relWindowWidth = Math.floor(maxWindowWidth * roughFrequency);
return getSingle_relWindow(samples, roughFrequency, roughWindowCenterPosition, relWindowWidth, windowFunction);
}
export function getSingle(samples, roughFrequency, windowFunction) {
const r = getSingle_maxWindow(samples, roughFrequency, samples.length / 2, samples.length, windowFunction);
return r ? r.component : Complex.NaN;
}
export function getHarmonicAmplitudes(samples, windowCenterPosition, f0, harmonics, relWindowWidth = 7, windowFunction = WindowFunctions.flatTopWindowNorm) {
if (!isFinite(f0) || f0 <= 0 || harmonics <= 0) {
return;
}
if (!Number.isInteger(relWindowWidth)) {
throw new Error("Parameter relWindowWidth is not an integer.");
}
const windowWidth = Math.round(relWindowWidth / f0);
const windowStartPosition = Math.round(windowCenterPosition - windowWidth / 2);
if (windowStartPosition < 0 || windowStartPosition + windowWidth > samples.length || windowWidth <= 0) {
return;
}
const windowSamples = samples.subarray(windowStartPosition, windowStartPosition + windowWidth);
const windowedSamples = WindowFunctions.applyWindow(windowSamples, windowFunction);
const amplitudes = new Float64Array(harmonics);
for (let harmonic = 1; harmonic <= harmonics; harmonic++) {
const c = Goertzel.goertzelSingle(windowedSamples, harmonic * relWindowWidth);
const amplitude = c.abs() * 2 / windowWidth;
amplitudes[harmonic - 1] = amplitude;
}
return amplitudes;
}
//# sourceMappingURL=AdaptiveStft.js.map