/ concept-collection / timeseries-compressibility
Sign in
concept-collection / timeseries-compressibility
timeseries-compressibility / src / model / pipeline.ts
42 lines · 1.4 KBBlameHistoryRaw
1/**
2 * The generating model: x ~ N(0, σ²) i.i.d. → FIR filter → optional additive
3 * uniform dither on [-1/2, 1/2) → round to integers (the quantization step is
4 * the unit, so σ is measured in steps).
5 *
6 * A single streaming implementation feeds both the scrolling display and the
7 * compression block, so what is compressed is exactly what is shown.
8 */
9import { GaussianStream } from './random'
11export class Pipeline {
12 private rng: GaussianStream
13 /** Ring of the last kernel-length inputs; index 0 is the newest. */
14 private history: Float64Array
15 private pos = 0
17 constructor(
18 private kernel: Float64Array,
19 private sigma: number,
20 private dither: boolean,
21 seed: number,
22 ) {
23 this.rng = new GaussianStream(seed)
24 this.history = new Float64Array(kernel.length)
25 }
27 /** Generate the next n quantized samples, clamped into int16 range. */
28 next(n: number): Int16Array {
29 const { kernel, history } = this
30 const L = kernel.length
31 const out = new Int16Array(n)
32 for (let j = 0; j < n; j++) {
33 this.pos = (this.pos + L - 1) % L
34 history[this.pos] = this.sigma * this.rng.normal()
35 let y = 0
36 for (let k = 0; k < L; k++) y += kernel[k] * history[(this.pos + k) % L]
37 if (this.dither) y += this.rng.uniformCentered()
38 out[j] = Math.max(-32768, Math.min(32767, Math.round(y)))
39 }
40 return out
41 }
moveopenescclose