当前位置: 首页 > 知识库问答 >
问题:

Web音频振荡器分析器节点

慕容劲
2023-03-14

我正在尝试添加AnalyserNode并将输出声音可视化到我制作的web音频示例中,但我不知道如何实现。我想我没有将正确的源传递给分析器(?)

完整代码如下:https://jsfidle.net/kepin95043/1ub0sjo3/

    <script>
        var fs = 2000;
        var gain = 0.2;

        class Sound {
            constructor(context) {
                this.context = context;
            }

            init() {
                this.oscillator = this.context.createOscillator();
                this.oscillator.frequency.value = fs;
                this.gainNode = this.context.createGain();
                this.oscillator.connect(this.gainNode);
                this.gainNode.connect(this.context.destination);

            }

            play(value) {
                this.init();
                this.gainNode.gain.setValueAtTime(gain, this.context.currentTime);
                this.oscillator.start();
            }

            stop() {
                this.gainNode.gain.exponentialRampToValueAtTime(0.001, this.context.currentTime + 1);
                this.oscillator.stop(this.context.currentTime + 1);
            }

        }

        var context = new AudioContext();
        var sound = new Sound(context);
        sound.init();
        var wave = 'sine';
        var state = 'paused';

        var waveSelectors = document.querySelectorAll('.waveform');
        var playBtn = document.querySelector('#play');
        var container = document.querySelector('.container');
        waveSelectors.forEach(function(button) {
            button.addEventListener('click', function() {
                cleanClass('active');
                wave = button.dataset.wave;
                sound.oscillator.type = wave;
                button.classList.add('active');
            })
        })

        playBtn.addEventListener('click', function() {

            context.resume().then(() => {
                console.log('Playback resumed successfully');
            });
            if (playBtn.text == 'Play') {
                sound.play();
                sound.oscillator.type = wave;
                playBtn.text = 'Pause';
            } else {
                sound.stop();
                playBtn.text = 'Play';
            }
        })

        function cleanClass(rclass) {
            waveSelectors.forEach(function(button) {
                button.classList.remove(rclass);
            })
        }

        function changeFs(val) {
            fs = val;
            var output = document.getElementById("fsValue");
            output.innerHTML = val;
            sound.stop();
            sound.play();
            console.log(val);
        };

        function changeGain(val) {
            gain = val;
            var output = document.getElementById("gainValue");
            output.innerHTML = val;
            sound.stop();
            sound.play();
            console.log(val);
        };

    var masterGain;
    masterGain = context.createGain();
    masterGain.connect(context.destination);

    // analyser
    var analyser = context.createAnalyser();
    masterGain.connect(analyser);

    var waveform = new Float32Array(analyser.frequencyBinCount);
    analyser.getFloatTimeDomainData(waveform);

    (function updateWaveform() {
      requestAnimationFrame(updateWaveform);
      analyser.getFloatTimeDomainData(waveform);
    }());

    var spectrum = new Uint8Array(analyser.frequencyBinCount);
    (function updateSpectrum() {
      requestAnimationFrame(updateSpectrum);
      analyser.getByteFrequencyData(spectrum);
    }());


    // oscilloscope
    var scopeCanvas = document.getElementById('canvas');
    scopeCanvas.width = waveform.length;
    //scopeCanvas.height = 200;
    scopeCanvas.height = scopeCanvas.width * 0.33;
    var scopeContext = scopeCanvas.getContext('2d');

    (function drawOscilloscope() {
      requestAnimationFrame(drawOscilloscope);
      scopeContext.clearRect(0, 0, scopeCanvas.width, scopeCanvas.height);
      scopeContext.strokeStyle="white"; // Green path
      scopeContext.beginPath();
      for (var i = 0; i < waveform.length; i++) {
        var x = i;
        var y = (0.5 + waveform[i] / 2) * scopeCanvas.height;
        if (i === 0) {
          scopeContext.moveTo(x, y);
        } else {
          scopeContext.lineTo(x, y);
        }
      }
      scopeContext.stroke();
    }());

    </script>

谁能帮我找出我做错了什么?提前感谢!

PS:用火狐打开吧。对我来说在基于Chromium的浏览器上不起作用。

下面是一个工作示例:https://codepen.io/dennisgaebel/pen/yewlal

共有1个答案

邓仲卿
2023-03-14

您可以创建一个Sound对象,以及一个连接到AnalyserNodeMasterGain。但我看不出声音与mastergain有什么联系。没有它,您的分析器节点只是静默。

 类似资料:
  • 在下面的代码中,我希望在每次按下按钮元素时创建一个分配给o的新振荡器节点,允许多次按下,从而在440处产生多个1秒音调。然而,我发现这个按钮只能按一次以产生一个音调,之后它就会消失,就好像我没有创建新的振荡器节点一样。我正在学习JavaScript,我怀疑它一定是一些微不足道的东西。有人有主意吗? 编辑: 刚找到这个问题解决了这个问题。解决方案是将audio_context.currentTime

  • 在执行此代码时,我会得到这样的错误:“Uncattle TypeError:Failed to execute'linear ramptoValueAtTime'on'AudioParam':The provided double value is non-finite”。 &如果替换ac.endTime只是endTime-“endTime未定义”,则发生错误。也许有人能解释为什么会这样?谢谢

  • 当使用web audio API制作振荡器时,我总是听到当停止它时的咔嗒声。我四处寻找,但没有一个解决办法对我有效。我尝试了所有的实现从我如何避免这种‘咔哒’声音时,我停止播放一个声音?和更多 我读到一个解决方案是等待下一个零振幅值,然后立即停止播放。有没有一种方法可以使用web audio API做到这一点? 我正在考虑为我的项目切换到Tone.js,因为声音不需要点击就可以播放。他们是如何解决

  • 仅仅是我,还是振荡器即使在0.5增益下也听起来疯狂的响亮?我不能增加我的电脑的体积超过5%。 现在,当我将增益设置为0.001时,音量似乎“归一化”了,但这不对?我希望能有一些关于控制振荡器音量的见解。

  • 在使用Opera44.0时,我正在摆弄音频API,并尝试了一个简单的示例: 它按预期工作,声音播放2秒,然后停止。 然后我试着往上走一点,当一个按钮被点击时播放一个声音: 不管用.单击按钮时调用函数(我在函数中使用进行了检查),但不播放任何声音。我尝试刷新页面,重新启动浏览器..什么都没有。 经过一些研究,我发现当调用时,振荡器会被丢弃,因此每次都必须创建一个新的振荡器。我发现的几乎所有示例都围绕

  • 这一节,让我们试着制造一些声音,我们将需要完成以下任务: 创建Web Audio API context 在context中创振荡器节点 选择波形类型 设定频率 把振荡器连接到目标上 启动振荡器 让我们把这些步骤写成代码 var context = new (window.AudioContext || window.webkitAudioContext)(); var oscillator