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.
*/