Web Audio API: проблемы с производительностью? - PullRequest
2 голосов
/ 14 февраля 2020

У меня тут маленький колокольчик. Он генерирует несколько обертонов одновременно и использует переменное усиление для каждого обертона для получения насыщенного звука. Я вызываю функцию, чтобы воспроизвести серию из них по очереди. Но если я быстро нажму кнопку несколько раз, вывод звука прекращается, как будто ему не хватает памяти:

https://codepen.io/ophello/pen/OJVRMQe

function ding(freq) {
    var toneGen = new AudioContext()
    var duration = 15
    var T = toneGen.currentTime
    var overtones = [1,2.76,5.4,8.93,13.34,18.64]
    overtones.forEach(function(overtone,i) {
        var osc = toneGen.createOscillator()
        osc.type = "sine"
        var freqVal = freq * overtone
        if (freqVal <= 22050) {
            osc.frequency.value = freq * overtone
            var envelope = toneGen.createGain()
            osc.connect(envelope)
            envelope.gain.setValueAtTime(0.1/Math.pow((i+1),5), T)
            envelope.gain.exponentialRampToValueAtTime(0.00001, T + duration)
            envelope.connect(toneGen.destination)
            osc.start(T)
            osc.stop(T + duration)
        }
    })
}

var hzValues = [216, 288, 324, 405, 432, 648]

$("#b1").mousedown(() => { 
    hzValues.forEach((thisHz,i) => { 
        setTimeout(() => { ding(thisHz) }, 100 * i); 
    })
})

Почему это перестало работать после нескольких нажатий? Я что-то здесь упускаю? Я не знаю, где в консоли искать какие-либо проблемы с этим. Это проблема с памятью?

1 Ответ

1 голос
/ 14 февраля 2020

Благодаря вышеперечисленному dandavis, я получил эту работу, добавив функцию тайм-аута:

setTimeout(toneGen.close.bind(toneGen), duration*1000);

Обновление: улучшено за счет перемещения звукового контекста за пределы основной функции!

...