javascriptreleaseweb-audio-apienvelopetonejs

Tone.js release/stop sampler


EDIT: Update on other attempts. The key bit of the question below is the line sampler.triggerRelease(["A1"], 'now') which is not working. Other things I've tried include:

The relevant part of the Tone.js docs is here.

What won't work is sampler.dispose(), because it essentially disconnects the sampler instrument from the output. But I need to continue using the sampler to retrigger the same note shortly after turning it off.


I'm trying to use a button press to stop the playing of a 'Sampler' note while it's currently playing. I thought that triggering the release phase would do this (as in my code below) but this doesn't seem to have any effect. I've tried lots of methods. This question doesn't answer mine, partly because it's for the 'Polysynth' not the 'Sampler'. Thanks in advance!

const readyOverlay = document.querySelector('#readyOverlay')
readyOverlay.addEventListener('click', async () => {
    readyOverlay.style.display = 'none'
    await Tone.start()

    const sampler = new Tone.Sampler({
        urls: {
            A1: "A1.mp3"
        },
        baseUrl: "https://tonejs.github.io/audio/casio/",
        onload: () => {
            sampler.triggerAttackRelease(["A1"], 5);
        }
    }).toDestination();
    sampler.release = 0
    document.querySelector('#stop').addEventListener('click', () => {
        sampler.triggerRelease(["A1"], 'now')
    })
})
        #readyOverlay {
    position: absolute;
    z-index: 9;
    width: 100%;
    height: 100%;
    background: white;
    text-align: center;
    display: flex;
    flex-direction: column;
    justify-content: center;
}
<script src="https://unpkg.com/tone@14.7.77/build/Tone.js"></script>
    <div id="readyOverlay">Press anywhere to start!</div>
    <button id="stop" >stop</button>


Solution

  • Replacing triggerAttackRelease with just triggerAttack does work:

    const readyOverlay = document.querySelector('#readyOverlay')
    readyOverlay.addEventListener('click', async () => {
        readyOverlay.style.display = 'none'
        await Tone.start()
    
        const sampler = new Tone.Sampler({
            urls: {
                A1: "A1.mp3"
            },
            baseUrl: "https://tonejs.github.io/audio/casio/",
            onload: () => {
                sampler.triggerAttack(["A1"]);
            }
        }).toDestination();
        sampler.release = 0;
        document.querySelector('#stop').addEventListener('click', () => {
            sampler.triggerRelease(["A1"]);
        })
    })
            #readyOverlay {
        position: absolute;
        z-index: 9;
        width: 100%;
        height: 100%;
        background: white;
        text-align: center;
        display: flex;
        flex-direction: column;
        justify-content: center;
    }
    <script src="https://unpkg.com/tone@14.7.77/build/Tone.js"></script>
        <div id="readyOverlay">Press anywhere to start!</div>
        <button id="stop" >stop</button>

    triggerAttackRelease is just a sequence of triggerAttack and triggerRelease calls. It means you have already scheduled a note release in the onload callback in your initial example.

    Tone.js ignores the second release call because sampler has already marked "A1" as released (this if statement makes sure note is released only once after the attack).