dsp-collection
Version:
A collection of JavaScript modules for digital signal processing (written in TypeScript)
195 lines • 6.75 kB
JavaScript
import * as MiscUtils from "../utils/MiscUtils.js";
export const windowFunctionIndex = [
{ name: "Blackman", id: "blackman", f: blackmanWindow, fNorm: blackmanWindowNorm, firstMinPos: 3, cpuCost: 2 },
{ name: "Blackman-Harris", id: "blackmanHarris", f: blackmanHarrisWindow, fNorm: blackmanHarrisWindowNorm, firstMinPos: 4, cpuCost: 3 },
{ name: "Blackman-Nuttall", id: "blackmanNuttall", f: blackmanNuttallWindow, fNorm: blackmanNuttallWindowNorm, firstMinPos: 4, cpuCost: 3 },
{ name: "Flat top", id: "flatTop", f: flatTopWindow, fNorm: flatTopWindowNorm, firstMinPos: 5, cpuCost: 4 },
{ name: "Hamming", id: "hamming", f: hammingWindow, fNorm: hammingWindowNorm, firstMinPos: 2, cpuCost: 1 },
{ name: "Hann", id: "hann", f: hannWindow, fNorm: hannWindowNorm, firstMinPos: 2, cpuCost: 1 },
{ name: "Nuttall", id: "nuttall", f: nuttallWindow, fNorm: nuttallWindowNorm, firstMinPos: 4, cpuCost: 3 },
{ name: "Parabolic", id: "parabolic", f: parabolicWindow, fNorm: parabolicWindowNorm, firstMinPos: 1.43, cpuCost: 0 },
{ name: "Rectangular", id: "rect", f: rectangularWindow, fNorm: rectangularWindow, firstMinPos: 1, cpuCost: 0 },
{ name: "Triangular", id: "triangular", f: triangularWindow, fNorm: triangularWindowNorm, firstMinPos: 2, cpuCost: 0 },
];
export function getFunctionDescrById(id) {
for (const descr of windowFunctionIndex) {
if (descr.id == id) {
return descr;
}
}
throw new Error("Undefined window function id \"" + id + "\".");
}
export function getFunctionbyId(id, { normalize = true, valueCacheCostLimit = 0, tableCacheCostLimit = 0 } = {}) {
const descr = getFunctionDescrById(id);
let f = normalize ? descr.fNorm : descr.f;
const origF = f;
if (valueCacheCostLimit && descr.cpuCost >= valueCacheCostLimit) {
f = MiscUtils.createMapBackedFunction(f);
}
if (tableCacheCostLimit && descr.cpuCost >= tableCacheCostLimit) {
if (f == origF) {
const tempF = f;
f = (x) => tempF(x);
}
f.windowTableCache = new Map();
}
return f;
}
export function getWindowTable(windowFunction, n) {
const windowTableCache = windowFunction.windowTableCache;
if (windowTableCache) {
const oldTable = windowTableCache.get(n);
if (oldTable) {
return oldTable;
}
}
const newTable = createWindowTable(windowFunction, n);
if (windowTableCache) {
windowTableCache.set(n, newTable);
}
return newTable;
}
function createWindowTable(windowFunction, n) {
const a = new Float64Array(n);
for (let i = 0; i < n; i++) {
a[i] = windowFunction(i / n);
}
return a;
}
export function applyWindow(a, windowFunction) {
const a2 = new Float64Array(a.length);
if (windowFunction.windowTableCache) {
const table = getWindowTable(windowFunction, a.length);
for (let i = 0; i < a.length; i++) {
a2[i] = a[i] * table[i];
}
}
else {
for (let i = 0; i < a.length; i++) {
a2[i] = a[i] * windowFunction(i / a.length);
}
}
return a2;
}
export function applyWindowById(a, windowFunctionId) {
const windowFunction = getFunctionbyId(windowFunctionId);
return applyWindow(a, windowFunction);
}
export function calculateCoherentGain(windowFunction, n) {
let sum = 0;
for (let i = 0; i < n; i++) {
sum += windowFunction(i / n);
}
return sum / n;
}
export function blackmanWindowNorm(x) { return blackmanWindow(x) / 0.42; }
export function blackmanHarrisWindowNorm(x) { return blackmanHarrisWindow(x) / 0.35875; }
export function blackmanNuttallWindowNorm(x) { return blackmanNuttallWindow(x) / 0.3635819; }
export function flatTopWindowNorm(x) { return flatTopWindow(x) / 0.21557895; }
export function hammingWindowNorm(x) { return hammingWindow(x) / 0.53836; }
export function hannWindowNorm(x) { return hannWindow(x) / 0.5; }
export function nuttallWindowNorm(x) { return nuttallWindow(x) / 0.355768; }
export function parabolicWindowNorm(x) { return parabolicWindow(x) / (2 / 3); }
export function triangularWindowNorm(x) { return triangularWindow(x) / 0.5; }
export function chdh1WindowNorm(x) { return chdh1Window(x) / 0.497595; }
export function rectangularWindow(x) {
if (x < 0 || x >= 1) {
return 0;
}
return 1;
}
export function triangularWindow(x) {
if (x < 0 || x >= 1) {
return 0;
}
if (x <= 0.5) {
return x * 2;
}
else {
return (1 - x) * 2;
}
}
export function parabolicWindow(x) {
if (x < 0 || x >= 1) {
return 0;
}
return 1 - (2 * x - 1) ** 2;
}
export function hammingWindow(x) {
if (x < 0 || x >= 1) {
return 0;
}
const w = 2 * Math.PI * x;
return 0.53836 - 0.46164 * Math.cos(w);
}
export function hannWindow(x) {
if (x < 0 || x >= 1) {
return 0;
}
const w = 2 * Math.PI * x;
return 0.5 - 0.5 * Math.cos(w);
}
export function blackmanWindow(x) {
if (x < 0 || x >= 1) {
return 0;
}
const a = 0.16;
const a0 = (1 - a) / 2;
const a1 = 0.5;
const a2 = a / 2;
const w = 2 * Math.PI * x;
return a0 - a1 * Math.cos(w) + a2 * Math.cos(2 * w);
}
export function blackmanHarrisWindow(x) {
if (x < 0 || x >= 1) {
return 0;
}
const a0 = 0.35875;
const a1 = 0.48829;
const a2 = 0.14128;
const a3 = 0.01168;
const w = 2 * Math.PI * x;
return a0 - a1 * Math.cos(w) + a2 * Math.cos(2 * w) - a3 * Math.cos(3 * w);
}
export function blackmanNuttallWindow(x) {
if (x < 0 || x >= 1) {
return 0;
}
const a0 = 0.3635819;
const a1 = 0.4891775;
const a2 = 0.1365995;
const a3 = 0.0106411;
const w = 2 * Math.PI * x;
return a0 - a1 * Math.cos(w) + a2 * Math.cos(2 * w) - a3 * Math.cos(3 * w);
}
export function nuttallWindow(x) {
if (x < 0 || x >= 1) {
return 0;
}
const a0 = 0.355768;
const a1 = 0.487396;
const a2 = 0.144232;
const a3 = 0.012604;
const w = 2 * Math.PI * x;
return a0 - a1 * Math.cos(w) + a2 * Math.cos(2 * w) - a3 * Math.cos(3 * w);
}
export function flatTopWindow(x) {
if (x < 0 || x >= 1) {
return 0;
}
const a0 = 0.21557895;
const a1 = 0.41663158;
const a2 = 0.277263158;
const a3 = 0.083578947;
const a4 = 0.006947368;
const w = 2 * Math.PI * x;
return a0 - a1 * Math.cos(w) + a2 * Math.cos(2 * w) - a3 * Math.cos(3 * w) + a4 * Math.cos(4 * w);
}
export function chdh1Window(x) {
if (x < 0 || x >= 1) {
return 0;
}
const p = 1 - Math.abs(1 - 2 * x);
return p ** (2 * (1 - p));
}
//# sourceMappingURL=WindowFunctions.js.map