import JSZip from 'jszip' import { compileFormula } from '../domain/audio/BytebeatCompiler' import { generateSamples } from '../domain/audio/SampleGenerator' import { exportToWav } from '../domain/audio/WavExporter' import type { BitDepth } from '../domain/audio/WavExporter' export interface DownloadOptions { sampleRate?: number duration?: number bitDepth?: BitDepth } export class DownloadService { private downloadBlob(blob: Blob, filename: string): void { const url = URL.createObjectURL(blob) const a = document.createElement('a') a.href = url a.download = filename a.click() URL.revokeObjectURL(url) } downloadFormula( formula: string, filename: string, options: DownloadOptions = {} ): boolean { const { sampleRate = 8000, duration = 10, bitDepth = 8 } = options const result = compileFormula(formula) if (!result.success || !result.compiledFormula) { console.error('Failed to compile formula:', result.error) return false } try { const buffer = generateSamples(result.compiledFormula, { sampleRate, duration }) const blob = exportToWav(buffer, { sampleRate, bitDepth }) this.downloadBlob(blob, filename) return true } catch (error) { console.error('Failed to download formula:', error) return false } } async downloadAll( formulas: string[][], options: DownloadOptions = {} ): Promise { const { sampleRate = 8000, duration = 10, bitDepth = 8 } = options const zip = new JSZip() formulas.forEach((row, i) => { row.forEach((formula, j) => { const result = compileFormula(formula) if (!result.success || !result.compiledFormula) { console.error(`Failed to compile ${i}_${j}:`, result.error) return } try { const buffer = generateSamples(result.compiledFormula, { sampleRate, duration }) const blob = exportToWav(buffer, { sampleRate, bitDepth }) zip.file(`bytebeat_${i}_${j}.wav`, blob) } catch (error) { console.error(`Failed to generate ${i}_${j}:`, error) } }) }) const content = await zip.generateAsync({ type: 'blob' }) this.downloadBlob(content, 'bytebeats.zip') } }