You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript重启oscillator时如何保留频率、波形等原有配置

核心问题排查

你遇到的配置不生效问题由以下几个原因导致:

  • 没有全局持久化存储用户选择的波形类型和频率值,每次新建振荡器实例时没有主动继承现有配置
  • 多次重复为频率滑动条绑定input事件监听器,每次启停操作都会新增监听器,不仅会造成内存泄漏,还会导致逻辑冲突
  • 新建振荡器后仅绑定了滑动条监听逻辑,没有主动将当前滑动条的已有值、已选择的波形配置同步到新实例
  • 存在大量未实际调用的冗余函数,干扰正常逻辑运行

修正后完整代码

<html>
<head>
    <title>Session 4 - AudioAPI Objects</title>
    <link rel="stylesheet" href="oscstylesheet.css">
</head>
<body>
    <button onclick="myStart()" type="button">Start</button><br>
    <button onclick="togglePlay()" type="button">Mute/Unmute</button><br>
    <button onclick="setWave('sine')" type="button">Sine</button><br>
    <button onclick="setWave('square')" type="button">Square</button><br>
    <button onclick="setWave('triangle')" type="button">Triangle</button><br>
    <input autocomplete="off" id="freqSlider" type="range" min="100" max="5000" value="440">
    <input autocomplete="off" id="volumeSlider" type="range" min="0" max="1" value="0.5" step="0.01">

    <script>
        var isPlaying = false;
        // 全局存储当前配置
        var currentFreq = 440;
        var currentWaveType = 'sine';
        //Create audio context
        let audioCtx = new (window.AudioContext || window.webkitAudioContext)();

        //Create a gain node 全局复用增益节点,所以音量配置天然继承
        var volumeNode = audioCtx.createGain();
        volumeNode.gain.value = 0.5;
        volumeNode.connect(audioCtx.destination);

        let oscillator = null;

        // 只绑定一次滑动条监听
        freqSlider.addEventListener('input', (e) => {
            currentFreq = e.target.valueAsNumber;
            if (oscillator && isPlaying) {
                oscillator.frequency.value = currentFreq;
            }
        });

        volumeSlider.addEventListener('input', (e) => {
            volumeNode.gain.value = e.target.valueAsNumber;
        });

        // 初始化振荡器
        function initOscillator() {
            oscillator = audioCtx.createOscillator();
            // 继承现有配置
            oscillator.frequency.value = currentFreq;
            oscillator.type = currentWaveType;
            oscillator.connect(volumeNode);
        }

        function myStart(){
            if (!oscillator) initOscillator();
            oscillator.start();
            isPlaying = true;
        }

        function togglePlay() {
            if (isPlaying) {
                isPlaying = false;
                oscillator.stop();
                oscillator = null;
            } else {
                initOscillator();
                oscillator.start();
                isPlaying = true;
            }
        }

        // 统一的波形设置函数
        function setWave(type) {
            currentWaveType = type;
            if (oscillator && isPlaying) {
                oscillator.type = type;
            }
        }
    </script>
</body>
</html>

关键优化点

  • 全局变量存储用户配置,不管实例怎么新建都不会丢失配置
  • 只绑定一次事件监听,避免逻辑冲突
  • 抽离振荡器初始化逻辑,每次新建时自动继承当前存储的所有配置
  • 统一波形设置逻辑,不管振荡器是否在运行都能正常更新配置

内容的提问来源于stack exchange,提问作者ongunumutyelbasi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 05:45:05