Tonejs / Tone.js

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

Clearing reverb buffer #1125

Closed cryptozachary closed 4 months ago

cryptozachary commented 1 year ago

Hello Everyone,

I'm having the issue of app memory increasing dramatically when I modify the reverb decay in real-time via a knob. I believe I need to clear some impulse response buffers that are generated each time the decay changes? Below is the code i use to change the decay on the reverb. Any guidance on how I would clear these buffers would be much appreciated.

Thanks,

Zachary

import React, { useRef, useState, useEffect } from 'react'
//import { effectParams } from "./effects2"

function Effects(props) {

    const { effectsToggle, onChange, effArr, effectParams, setEffectParams } = props

    const reverbRangeInput = useRef()

    const reverbRangeDiv = useRef()

    const setValue = () => {
        const newValue = Number((reverbRangeInput.current.value - reverbRangeInput.current.min) * 2 / (reverbRangeInput.current.max - reverbRangeInput.current.min))
        const newPosition = 10 - (newValue * 0.2);
        reverbRangeDiv.current.innerHTML = `<span>${reverbRangeInput.current.value}</span>`;
        reverbRangeDiv.current.style.left = `calc(${newValue}% + (${newPosition}px))`;
        setEffectParams(prev => {
            return { ...prev, verbDecay: Math.floor(newValue + 1) }
        })
        console.log(effectParams.verbDecay)
    };

    useEffect(() => {
        setValue()
    }, [])

    // toggle switches for effects
    return (
        <div>

            <div className='slider-flex-container'>
                <label htmlFor="reverb" className="switch">
                    <input className="effect" name="reverb" id="reverb" type="checkbox" checked={effectsToggle[0].state} onChange={() => onChange(0)}></input>
                    <span className="slider round"></span>
                </label>
                <p>Reverb</p>
                <div className="reverb-tag range-wrap">
                    <div ref={reverbRangeDiv} className="range-value" id="rangeV"></div>
                    <input type="range" ref={reverbRangeInput} defaultValue='1' name="reverb-range" id="reverb-range" className="range-slider" min="1" max="2" step='0.1' onInput={setValue}></input>
                </div>
            </div >
marcelblum commented 1 year ago

The convolution reverb decay won't change in realtime because the impulse response buffer creation is asynchronous. When you set a new decay, the previous IR buffer will get GCed eventually but I think the way you have it set up it's probably firing a zillion times a second not giving enough time for the gc to happen quick enough. So if you're using the input event on your range slider try using change instead or setting up a debounce timer so the decay is not being modified so frequently.

cryptozachary commented 1 year ago

Thank you Marcel - I will setup a debounce timer.