UNPKG

murmuraba

Version:

Real-time audio noise reduction with advanced chunked processing for web applications

100 lines (99 loc) 3.48 kB
/** * Infrastructure Layer - Web Audio API Implementation * Handles the technical details of applying gain to audio nodes */ import { GainValue, MEDICAL_GAIN_POLICY } from '../../domain/gain/gain-domain'; export class WebAudioGainRepository { constructor(audioContext, options = {}) { this.audioContext = audioContext; this.presets = new Map(); this.options = { smoothingTimeConstant: options.smoothingTimeConstant ?? 0.01, enableSmoothing: options.enableSmoothing ?? true, policy: options.policy ?? MEDICAL_GAIN_POLICY }; this.currentGain = GainValue.create(this.options.policy.defaultGain, this.options.policy); this.createGainNode(); } async getCurrentGain() { return this.currentGain; } async setGain(gain) { this.currentGain = gain; if (!this.gainNode) { this.createGainNode(); } if (this.options.enableSmoothing) { this.gainNode.gain.setTargetAtTime(gain.getValue(), this.audioContext.currentTime, this.options.smoothingTimeConstant); } else { this.gainNode.gain.value = gain.getValue(); } } async savePreset(name, gain) { this.presets.set(name, gain); // Persist to localStorage for persistence across sessions try { const serializedPresets = JSON.stringify(Array.from(this.presets.entries()).map(([key, value]) => [key, value.getValue()])); localStorage.setItem('murmuraba-gain-presets', serializedPresets); } catch (error) { console.warn('Failed to persist gain preset to localStorage:', error); } } async loadPreset(name) { // Try memory cache first const cachedPreset = this.presets.get(name); if (cachedPreset) { return cachedPreset; } // Try localStorage try { const serializedPresets = localStorage.getItem('murmuraba-gain-presets'); if (serializedPresets) { const presetEntries = JSON.parse(serializedPresets); const presetValue = presetEntries.find(([key]) => key === name)?.[1]; if (presetValue !== undefined) { const gainValue = GainValue.create(presetValue, this.options.policy); this.presets.set(name, gainValue); return gainValue; } } } catch (error) { console.warn('Failed to load gain preset from localStorage:', error); } return null; } /** * Get the actual Web Audio API gain node for connection to audio graph */ getGainNode() { if (!this.gainNode) { this.createGainNode(); } return this.gainNode; } /** * Connect this gain repository to an audio processing chain */ connectTo(sourceNode, destinationNode) { const gainNode = this.getGainNode(); sourceNode.connect(gainNode); gainNode.connect(destinationNode); } /** * Clean up resources */ destroy() { if (this.gainNode) { this.gainNode.disconnect(); this.gainNode = undefined; } this.presets.clear(); } createGainNode() { this.gainNode = this.audioContext.createGain(); this.gainNode.gain.value = this.currentGain.getValue(); } }