Tonejs / Tone.js

A Web Audio framework for making interactive music in the browser.
https://tonejs.github.io
MIT License
13.45k stars 977 forks source link

Help: Uncaught Error: buffer is either not set or not loaded #1167

Closed KarthikNayak closed 5 months ago

KarthikNayak commented 1 year ago

Hello,

I want to create a metronome which plays at a particular BPM and uses a static sound. So far this is my code.

import { Box, Button, Heading } from "@chakra-ui/react"
import { useState } from "react";
import * as Tone from "tone";
import { Seconds } from "tone/build/esm/core/type/Units";

const BPM = (props: { bpm: number }) => {
    const [isPlaying, setIsPlaying] = useState(false);
    const [disabled, setDisabled] = useState(true);

    const player = new Tone.Sampler({
        C3: 'woodblock.wav'
    }, () => { setDisabled(false) }).toDestination()

    const loop = new Tone.Loop((time: Seconds) => {
        player.triggerAttackRelease('C3', time);
    }, '4n').start(0);
    Tone.Transport.bpm.value = props.bpm;

    const handleClick = async () => {
        await Tone.start();

        if (isPlaying) {
            Tone.Transport.stop();
        } else {
            Tone.Transport.start();
        }
        setIsPlaying(!isPlaying);
    }

    return <Box>
        <Button onClick={handleClick} disabled={disabled}>
            <Heading color="gray.500" size="lg" >
                {props.bpm} BPM
            </Heading>
        </Button>
    </Box >
}

export default BPM;

It works, but everytime I click the button it also throws the following error, also each successive start the sound gets amplified.

Uncaught Error: buffer is either not set or not loaded
    assert Debug.js:8
    start ToneBufferSource.js:93
    triggerAttack Sampler.js:130
    triggerAttack Sampler.js:112
    triggerAttackRelease Sampler.js:202
    loop bpm.tsx:16
    _tick Loop.js:75
    _tick ToneEvent.js:206
    invoke TransportEvent.js:35
    invoke TransportRepeatEvent.js:54
    invoke TransportEvent.js:35
    _processTick Transport.js:138
    forEachAtTime Timeline.js:337
    _iterate Timeline.js:242
    forEachAtTime Timeline.js:336
    _processTick Transport.js:138
    _loop Clock.js:222
    forEachTickBetween TickSource.js:259
    _loop Clock.js:221
    emit Emitter.js:88
    _createWorker Ticker.js:37
    _createClock Ticker.js:55
    Ticker Ticker.js:11
    Context Context.js:57
    getContext Global.js:22
    <anonymous> index.js:29
    NextJS 4
    <anonymous> bpm.tsx:7
    NextJS 4
    <anonymous> sidebar.tsx:6
    NextJS 4
    <anonymous> learn.tsx:5
    NextJS 4
    <anonymous> (index):5
    onEntrypoint route-loader.js:211
    promise callback*onEntrypoint route-loader.js:211
    register index.js:166
    <anonymous> (index):2
    NextJS 9

I already went through the earlier issues on this topic, that why I introduced the disabled state, but I'm a bit stuck now, any help would be appreciated.

For context, my tone version:

❯ yarn list | grep tone
├─ tone@14.7.77
tambien commented 5 months ago

Didn't try to run it, but seems like it should work. I think react handles URLs in different ways, so maybe the file is never actually loaded