murmuraba
Version:
Real-time audio noise reduction with advanced chunked processing for web applications
136 lines (135 loc) • 4.54 kB
JavaScript
/**
* Application Layer - Gain Control Use Cases
* Orchestrates domain logic and coordinates with external systems
*/
import { GainController, MEDICAL_GAIN_POLICY } from '../../domain/gain/gain-domain';
export class GainUseCases {
constructor(repository, eventPublisher, events = {}, policy = MEDICAL_GAIN_POLICY) {
this.events = events;
this.controller = new GainController(repository, eventPublisher, policy);
}
async setInputGain(gain) {
try {
const result = await this.controller.setGain(gain);
this.events.onGainChanged?.(result);
return result;
}
catch (error) {
const err = error instanceof Error ? error : new Error('Failed to set gain');
this.events.onError?.(err);
throw err;
}
}
async getCurrentInputGain() {
try {
return await this.controller.getCurrentGain();
}
catch (error) {
const err = error instanceof Error ? error : new Error('Failed to get current gain');
this.events.onError?.(err);
throw err;
}
}
async applyGainPreset(preset) {
try {
const result = await this.controller.applyPreset(preset);
this.events.onPresetApplied?.(preset, result);
return result;
}
catch (error) {
const err = error instanceof Error ? error : new Error('Failed to apply preset');
this.events.onError?.(err);
throw err;
}
}
async incrementGain() {
try {
const result = await this.controller.incrementGain();
this.events.onGainChanged?.(result);
return result;
}
catch (error) {
const err = error instanceof Error ? error : new Error('Failed to increment gain');
this.events.onError?.(err);
throw err;
}
}
async decrementGain() {
try {
const result = await this.controller.decrementGain();
this.events.onGainChanged?.(result);
return result;
}
catch (error) {
const err = error instanceof Error ? error : new Error('Failed to decrement gain');
this.events.onError?.(err);
throw err;
}
}
async saveCurrentGainAsPreset(name) {
try {
await this.controller.saveCurrentAsPreset(name);
}
catch (error) {
const err = error instanceof Error ? error : new Error('Failed to save preset');
this.events.onError?.(err);
throw err;
}
}
async loadNamedPreset(name) {
try {
const result = await this.controller.loadNamedPreset(name);
if (result) {
this.events.onGainChanged?.(result);
}
return result;
}
catch (error) {
const err = error instanceof Error ? error : new Error('Failed to load preset');
this.events.onError?.(err);
throw err;
}
}
/**
* Get gain information for UI display
*/
async getGainDisplayInfo() {
const current = await this.getCurrentInputGain();
return {
current,
dbValue: current.getDbValue(),
description: this.getGainDescription(current),
isNormal: current.isNormalLevel(),
isBoost: current.isBoostLevel()
};
}
getGainDescription(gain) {
const value = gain.getValue();
if (value < 1.0)
return '⬇️ Reduced input level';
if (value === 1.0)
return '✅ Normal input level';
if (value <= 1.5)
return '⬆️ Increased input level';
if (value <= 2.0)
return '📈 High input level';
return '⚠️ Maximum boost - watch for clipping';
}
}
/**
* Factory for creating gain use cases with proper wiring
*/
export class GainUseCaseFactory {
static create(repository, events = {}, policy) {
// Create event publisher that forwards to use case events
const eventPublisher = {
publishGainChanged: (oldGain, newGain) => {
events.onGainChanged?.(newGain);
},
publishPresetApplied: (preset, gain) => {
events.onPresetApplied?.(preset, gain);
}
};
return new GainUseCases(repository, eventPublisher, events, policy);
}
}