diff --git a/index.html b/index.html index 44a9335..996591b 100644 --- a/index.html +++ b/index.html @@ -4,7 +4,7 @@ - Vite + TS + 9 x single-band rnbo patches
diff --git a/src/audio/context.ts b/src/audio/context.ts new file mode 100644 index 0000000..dc0aa10 --- /dev/null +++ b/src/audio/context.ts @@ -0,0 +1,10 @@ +// audio-app/src/audio/context.ts +let sharedCtx: AudioContext | undefined +let WAContext = window.AudioContext || window.webkitAudioContext + +export function getAudioContext():AudioContext { + if (!sharedCtx) { + sharedCtx = new WAContext() + } + return sharedCtx +} diff --git a/src/composables/Player.ts b/src/composables/Player.ts index 13a36de..9ae4f8d 100644 --- a/src/composables/Player.ts +++ b/src/composables/Player.ts @@ -12,7 +12,10 @@ export function setupPlayButton( button.onclick = () => { const startTime = context.currentTime + 0.1 // 100ms in Zukunft const rampTime = 2 - + // 1️⃣ Master-Gain auf 0 dB hochrampen + master.gain.setValueAtTime(0.001, startTime) + master.gain.exponentialRampToValueAtTime(1.0, startTime + rampTime) + sources.forEach((source, freq) => { const gainNode = gains.get(freq) if (!gainNode) return diff --git a/src/main.ts b/src/main.ts index 6dcad75..f889648 100644 --- a/src/main.ts +++ b/src/main.ts @@ -3,6 +3,8 @@ import { attachDBValueListener } from './dbValueListener' import { fetchOrLoadBuffer, createBufferSource } from './composables/BufferStore' import { setupPlayButton } from './composables/Player'; import { getPreferredDevice } from './lib/microphone'; +import { getAudioContext } from './audio/context' + import patcherUrl from '../public/patches/controlvalue/LAF-Controll-Values_Simple_Band1000.rnbopat.export.json?url' interface DeviceInfo { @@ -17,15 +19,11 @@ interface DeviceInfo { let patcherPromise: Promise // create context & master gain -let WAContext = window.AudioContext || window.webkitAudioContext -const ctx = new WAContext() // match your assets const mobile = /Mobi|Android|iPhone|iPad|iPod/i.test(navigator.userAgent) -console.log("AudioContext created") // // Gains to control the audio // -const masterGain = ctx.createGain() const bands = mobile ? [150, 1500, 8000] : [63, 125, 250, 500, 1000, 2000, 4000, 8000, 16000] const devices = new Map() @@ -56,17 +54,25 @@ async function getPatcher() { } async function init() { + // Schritt 0: Mic-Recht + await initMicrophone() + // Schritt 1: Kontext + const ctx = getAudioContext() + await ctx.suspend() + // Schritt 2: Fetch Patcher await getPatcher() + // Schritt 3: Erstelle alle Devices const newDevices = await Promise.all( bands.map(async (freq, index) => { const device = await createBandDevice(freq, ctx) as DeviceInfo + // Schritt 4 Fetch alle AudioBuffer await fetchOrLoadBuffer(freq.toString(), urlsWebM[index].url, ctx ) const sourceNode = await createBufferSource(freq.toString(),ctx) const bandGainNode = ctx.createGain() - // patch them together + // Schritt 5 Verbinde AudioNodes sourceNode.node?.connect(bandGainNode) bandGainNode.connect(masterGain) //update the source list @@ -77,12 +83,9 @@ async function init() { return {freq, device} } )) - newDevices.forEach(({freq, device}) => { - devices.set(freq, device) - }) + registerDevicesWithListeners(newDevices) console.log("RNBO Devices created") - - await initMicrophone() + devices.forEach((devices, freq)=> { try{ if(devices && devices.device) { @@ -94,9 +97,36 @@ async function init() { }) console.log("Everything is setup, display a play button") setupPlayButton(sources, gains,ctx) + masterGain.connect(ctx.destination) } + + +/** + * Enables the Microphone to use it. + */ + +function registerDevicesWithListeners(newDevices: { freq: number, device: any }[]) { + const devices = new Map() + + newDevices.forEach(({ freq, device }) => { + devices.set(freq, device) + + try { + if (device) { + attachDBValueListener(device, freq) + } + } catch (err) { + console.warn(`Could not attach RNBO listener for ${freq}Hz`, err) + } + }) + + console.log("✅ RNBO Devices registered and listeners attached") + return devices +} + + /** * Enables the Microphone to use it. */