Files
bruitiste/src/services/PlaybackManager.ts
2025-09-30 14:20:50 +02:00

81 lines
2.0 KiB
TypeScript

import { compileFormula } from '../domain/audio/BytebeatCompiler'
import { generateSamples } from '../domain/audio/SampleGenerator'
import { AudioPlayer } from '../domain/audio/AudioPlayer'
import type { EffectValues } from '../types/effects'
export interface PlaybackOptions {
sampleRate: number
duration: number
}
export class PlaybackManager {
private player: AudioPlayer
private currentFormula: string | null = null
private currentBuffer: Float32Array | null = null
private queuedCallback: (() => void) | null = null
constructor(options: PlaybackOptions) {
this.player = new AudioPlayer(options)
}
updateOptions(options: Partial<PlaybackOptions>): void {
this.player.updateOptions(options)
this.currentBuffer = null
}
setEffects(values: EffectValues): void {
this.player.setEffects(values)
}
play(formula: string, sampleRate: number, duration: number): boolean {
const result = compileFormula(formula)
if (!result.success || !result.compiledFormula) {
console.error('Failed to compile formula:', result.error)
return false
}
try {
this.currentBuffer = generateSamples(result.compiledFormula, { sampleRate, duration })
this.currentFormula = formula
this.player.setLooping(true)
this.player.play(this.currentBuffer)
return true
} catch (error) {
console.error('Failed to generate samples:', error)
return false
}
}
stop(): void {
this.player.stop()
this.currentFormula = null
this.queuedCallback = null
}
scheduleNextTrack(callback: () => void): void {
this.queuedCallback = callback
this.player.scheduleNextTrack(() => {
if (this.queuedCallback) {
this.queuedCallback()
this.queuedCallback = null
}
})
}
getPlaybackPosition(): number {
return this.player.getPlaybackPosition()
}
isPlaying(): boolean {
return this.currentFormula !== null
}
getCurrentFormula(): string | null {
return this.currentFormula
}
dispose(): void {
this.player.dispose()
}
}