网络音频 API 最佳实践、简单合成器、系统优化/垃圾收集

Web Audio API Best Practice, simple synth, system optimisation / garbage collection

我来自 max/msp 并试图从优化我的代码/获得更好的性能方面找出网络音频编程的最佳实践。

我读到这样一个事实,即出于优化原因,不能在振荡器上先调用 .start(),然后调用 .stop(),然后调用 .start()。如果我想制作一个简单的 1 振荡器合成器,我想知道最好的设计模式是什么 class。

我想在需要播放之前实例化合成器。这样我想我得到了最好的时机,如果我想在以后播放合成器,那么系统就不必在我每次点击 'play note'.[= 时创建振荡器/合成器模式。 12=]

但是最好不要在我听不到的振荡器上使用处理能力,因为例如幅度包络未打开。

这是一个简单的合成器,没有振幅包络。我怎样才能做出类似的模式,我只在合成器实际播放时才使用处理能力?

最好的,拉瑟

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>How to optimize CPU usage</title>
</head>
<body>

  <a href="#" id="playButton">Play Note</a> <br><br>
  <a href="#" id="stopButton">Stop Note</a>

  <script>
    class Synth {
      constructor () {
        this.context = new AudioContext();
        this.osc = this.context.createOscillator();
        this.osc.connect(this.context.destination);
      }

      play(freq) {
        this.osc.frequency.value = freq;
        this.osc.start(0);
      }

      stop() {
        this.osc.stop(0);
      }
    }

    let synth = new Synth();

    const playButton = document.getElementById('playButton')
      .addEventListener('click', () => {synth.play(440)});
    
      const stopButton = document.getElementById('stopButton')
      .addEventListener('click', () => {synth.stop()}); 
  </script>
</body>
</html>

我觉得这更接近你想要的:

let context = new AudioContext();

class Synth {
  constructor () {}

  play(freq) {
    this.osc = context.createOscillator();
    this.osc.connect(context.destination);
    this.osc.frequency.value = freq;
    this.osc.start(0);
  }

  stop() {
    this.osc.stop(0);
  }
}

首先,你只需要一个audioContext。您不应该在每次振荡器播放时都创建一个新的。至于您对性能的担忧,我不会太担心。振荡器被设计成便宜且一次性的。即时创建它们很好,玩一次就忘记它们。