@audio/synth-wavetable 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +29 -0
  2. package/wavetable.js +25 -0
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "@audio/synth-wavetable",
3
+ "version": "1.0.0",
4
+ "description": "Morphing wavetable oscillator — scan a bank of single-cycle tables (WaveEdit class)",
5
+ "type": "module",
6
+ "sideEffects": false,
7
+ "main": "wavetable.js",
8
+ "exports": {
9
+ ".": "./wavetable.js",
10
+ "./package.json": "./package.json"
11
+ },
12
+ "files": [
13
+ "wavetable.js"
14
+ ],
15
+ "keywords": [
16
+ "audio",
17
+ "dsp",
18
+ "synth",
19
+ "wavetable"
20
+ ],
21
+ "license": "MIT",
22
+ "author": "Dmitry Iv. <dfcreative@gmail.com>",
23
+ "engines": {
24
+ "node": ">=18"
25
+ },
26
+ "publishConfig": {
27
+ "access": "public"
28
+ }
29
+ }
package/wavetable.js ADDED
@@ -0,0 +1,25 @@
1
+ // Morphing wavetable oscillator (WaveEdit class) — crossfade through a bank of
2
+ // single-cycle tables while scanning position 0..1; linear interp within and between tables.
3
+
4
+ export default function wavetable (freq, { tables, position = 0, duration = 1, fs = 44100, amp = 0.8 } = {}) {
5
+ if (!tables?.length) throw new RangeError('wavetable: opts.tables required (array of single-cycle Float32Arrays)')
6
+ let n = Math.round(duration * fs)
7
+ let out = new Float32Array(n)
8
+ let posFn = typeof position === 'function' ? position : () => position
9
+ let t = 0, dt = freq / fs
10
+ for (let i = 0; i < n; i++) {
11
+ let p = Math.min(1, Math.max(0, posFn(i / n))) * (tables.length - 1)
12
+ let ti = Math.min(tables.length - 2, Math.floor(p))
13
+ let tf = tables.length > 1 ? p - ti : 0
14
+ let read = tbl => {
15
+ let x = t * tbl.length
16
+ let i0 = x | 0, frac = x - i0
17
+ return tbl[i0 % tbl.length] * (1 - frac) + tbl[(i0 + 1) % tbl.length] * frac
18
+ }
19
+ let a = read(tables[ti])
20
+ let b = tables.length > 1 ? read(tables[ti + 1]) : a
21
+ out[i] = amp * (a * (1 - tf) + b * tf)
22
+ t = (t + dt) % 1
23
+ }
24
+ return out
25
+ }