RNBO JS - functional website but no sound from buffer when onclick

Spoonmaniac's icon

Hello,

I'm new to Max and RNBO, and I need some help to understand what I do wrong.

I would like clicking a button on the website to trigger a sound from a buffer.

The audio files are loading, as are the buffers, but there seems to be a communication error with the patch <inport>.

Below is the JavaScript code, along with a screenshot of my patch.

let device = null

async function loadRNBO() {
    const patchExportURL = "export/NuitsBassins_dodgeweb.export.json";

    // Create Audio Context
    const WAContext = window.AudioContext || window.webkitAudioContext;
    const context = new WAContext();

    // Create gain node and connect it to audio output
    const outputNode = context.createGain();
    outputNode.connect(context.destination);
    outputNode.gain.value = 1; //gain ouvert

    //Fetch the exported patcher
    let response, patcher;
    try {
        response = await fetch(patchExportURL);
        patcher = await response.json();

        if (!window.RNBO) {
            await loadRNBOScript(patcher.desc.meta.rnboversion);
        }
    } catch (err) {
        console.error("Erreur lors du chargement du patcher RNBO", err);
        return;
    }

    // Fetch the dependencies
    let dependencies = [];
    try {
        const dependenciesResponse = await fetch("export/dependencies.json");
        dependencies = await dependenciesResponse.json();

        // Prepend "export" to any file dependenciies
        dependencies = dependencies.map(d => d.file ? Object.assign({}, d, { file: "export/" + d.file }) : d);
    } catch (e) { }

    // Create the device
    let device;
    try {
        device = await RNBO.createDevice({ context, patcher });
    } catch (err) {
        if (typeof guardrails === "function") {
            guardrails({ error: err });
        } else {
            throw err;
        }
        return;
    }

    // Load the samples
    const results = await device.loadDataBufferDependencies(dependencies);
    results.forEach(result => {
        if (result.type === "success") {
            console.log(`Successfully loaded buffer with id ${result.id}`);
        } else {
            console.log(`Failed to load buffer with id ${result.id}, ${result.error}`);
        }
    });

    device.node.connect(outputNode);
    //    attachOutports(rnboDevice);

    document.body.onclick = () => {
        if (context.state === "running") return;
        context.resume();
        console.log("Audio context resumed");
    };

    // Bouton utilisateur
    document.getElementById("btnAction").addEventListener("click", async () => {
        if (!context || context.state === "suspended") {
            await context?.resume();
        }

        if (!device) {
            await loadRNBO();
        }

        triggerEvent("bouclier", device);
        console.log("🛡️ Bouclier déclenché");
    });


}

/*
function clamp(val, min, max) {
    return Math.max(min, Math.min(val, max));
}
*/

function loadRNBOScript(version) {
    return new Promise((resolve, reject) => {
        if (/^\d+\.\d+\.\d+-dev$/.test(version)) {
            throw new Error("Version RNBO exportée en mode debug !");
        }

        const el = document.createElement("script");
        el.src = `https://c74-public.nyc3.digitaloceanspaces.com/rnbo/${encodeURIComponent(version)}/rnbo.min.js`;
        el.onload = resolve;
        el.onerror = err => reject(new Error("Erreur de chargement RNBO : " + version));
        document.body.append(el);
    });
}

function triggerEvent(type, device) {
    if (!RNBO.BaseDevice) {
        console.warn("RNBO non initialisé");
        return;
    }
    /*
        if (!["mur", "joueur", "bouclier"].includes(type)) {
            console.warn("Type non reconnu :", type);
            return;
        }
    */
    const now = RNBO.TimeNow;
    //    const pan = clamp(x, 0, 1) * 2 - 1;

    //    device.scheduleEvent(new RNBO.MessageEvent(now, `pan_${type}`, [pan]));
    //    console.log("🎯 Event envoyé :", `${type}`, `${pan}`);
    device.scheduleEvent(new RNBO.MessageEvent(now, type, [1]));
    console.log("🎯 Event envoyé :", `${type}`);
}

window.addEventListener("DOMContentLoaded", () => {
    loadRNBO();
});
// Receive Outport Message for Inport Feedback
device.messageEvent.subscribe((ev) => {
    console.log(`Receive message ${ev.tag}: ${ev.payload}`);

    if (ev.tag === "5") console.log("from the bouclier inport");
});

Thanks in advance for your help.

Spoonmaniac's icon

UP please
I can't figure it out, it may be something dumb or stupid but I can't see it

Alex Van Gils's icon

Hi there Spoonmaniac, thank you for reaching out! I see that you made a support ticket as well, I will respond there so we can walk through it.