From 05581d22320cd726eb1cccd1f7881f6679cc8e56 Mon Sep 17 00:00:00 2001 From: James Prevett Date: Tue, 5 Nov 2024 22:03:29 -0600 Subject: [PATCH] Moved DSP worklet to another file Added some types and stuff --- src/dsp.ts | 62 ++++++++-------------------------------------- src/dsp.worklet.ts | 35 ++++++++++++++++++++++++++ src/framebuffer.ts | 10 ++++++-- tsconfig.json | 2 +- 4 files changed, 54 insertions(+), 55 deletions(-) create mode 100644 src/dsp.worklet.ts diff --git a/src/dsp.ts b/src/dsp.ts index dd8a5fe..3953c4e 100644 --- a/src/dsp.ts +++ b/src/dsp.ts @@ -1,79 +1,37 @@ -/* eslint-disable @typescript-eslint/no-unused-vars */ - import type { DeviceDriver, DeviceFile } from '@zenfs/core'; interface DspOptions { audioContext?: AudioContext; } -// I inline worker, so no separate file is needed. -const workletUrl = URL.createObjectURL( - new Blob( - [ - ` - -/* global AudioWorkletProcessor, registerProcessor, currentFrame, currentTime, sampleRate */ - -class ZenFSDsp extends AudioWorkletProcessor { - constructor (...args) { - super(...args) - this.port.onmessage = e => this.buffer = e.data - } - - process (inputs, outputs, parameters) { - if (this.buffer) { - const c = currentFrame % sampleRate - outputs[0][0].set(this.buffer.slice(c, c+128)) - } - return true - } - - static get parameterDescriptors () { - return [ - { - name: 'gain', - defaultValue: 1, - minValue: 0, - maxValue: 1, - automationRate: 'a-rate' - } - ] - } -} - -registerProcessor('zenfs-dsp', ZenFSDsp) - -`, - ], - { type: 'application/javascript' } - ) -); - -export async function dsp(options: DspOptions = {}): Promise { +export async function dsp(options: DspOptions = {}): Promise> { const context = options.audioContext || new AudioContext(); const audioBuffer = new ArrayBuffer(context.sampleRate * 4); - await context.audioWorklet.addModule(workletUrl); + await context.audioWorklet.addModule(new URL('./dsp.worklet.js', import.meta.url).href); - const dsp = new AudioWorkletNode(context, 'zenfs-dsp'); + const dsp = new AudioWorkletNode(context, 'zenfs:dsp'); dsp.connect(context.destination); - dsp.port?.postMessage(audioBuffer); + dsp.port.postMessage(audioBuffer); // add a click-handler to resume (due to web security) https://goo.gl/7K7WLu document.addEventListener('click', () => { - if (context.state !== 'running') { - context.resume().catch(e => {}); + if (context.state != 'running') { + void context.resume().catch(() => {}); } }); return { name: 'dsp', + init() { + return { data: dsp, major: 14, minor: 3 }; + }, read() { return 0; }, write(file: DeviceFile, data: Uint8Array): number { new Uint8Array(audioBuffer).set(data); - dsp.port?.postMessage(new Float32Array(audioBuffer)); + dsp.port.postMessage(new Float32Array(audioBuffer)); return data.byteLength; }, }; diff --git a/src/dsp.worklet.ts b/src/dsp.worklet.ts new file mode 100644 index 0000000..ccfaac8 --- /dev/null +++ b/src/dsp.worklet.ts @@ -0,0 +1,35 @@ +/* eslint-env:node */ +/// + +class Dsp extends AudioWorkletProcessor { + protected buffer?: Float32Array; + + public constructor() { + super(); + this.port.onmessage = ({ data }: MessageEvent) => { + this.buffer = data; + }; + } + + public process(inputs: Float32Array[][], outputs: Float32Array[][]): boolean { + if (this.buffer) { + const c = currentFrame % sampleRate; + outputs[0][0].set(this.buffer.slice(c, c + 128)); + } + return true; + } + + public static get parameterDescriptors() { + return [ + { + name: 'gain', + defaultValue: 1, + minValue: 0, + maxValue: 1, + automationRate: 'a-rate', + }, + ]; + } +} + +registerProcessor('zenfs:dsp', Dsp); diff --git a/src/framebuffer.ts b/src/framebuffer.ts index c69397b..b7a726a 100644 --- a/src/framebuffer.ts +++ b/src/framebuffer.ts @@ -1,10 +1,13 @@ -import { Errno, ErrnoError, type DeviceDriver, type DeviceFile } from '@zenfs/core'; +import { Errno, ErrnoError } from '@zenfs/core'; +import type { DeviceDriver, DeviceFile } from '@zenfs/core'; interface FramebufferOptions { canvas?: HTMLCanvasElement; } -export function framebuffer({ canvas }: FramebufferOptions = {}): DeviceDriver { +let framebufferN = 0; + +export function framebuffer({ canvas }: FramebufferOptions = {}): DeviceDriver { if (!canvas) { canvas = document.createElement('canvas'); document.body.appendChild(canvas); @@ -17,6 +20,9 @@ export function framebuffer({ canvas }: FramebufferOptions = {}): DeviceDriver { return { name: 'framebuffer', + init() { + return { data: ctx, major: 29, minor: framebufferN++ }; + }, read() { return 0; }, diff --git a/tsconfig.json b/tsconfig.json index 05985a6..59a4602 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,7 +3,7 @@ "module": "NodeNext", "target": "ES2020", "outDir": "dist", - "lib": ["ESNext", "ESNext.Disposable", "dom"], + "lib": ["ESNext", "ESNext.Disposable", "DOM"], "moduleResolution": "NodeNext", "declaration": true, "strict": true,