UNPKG

dsp-collection

Version:

A collection of JavaScript modules for digital signal processing (written in TypeScript)

195 lines 6.75 kB
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