【问题标题】:Web Audio - Oscillator AnalyserNode网络音频 - 振荡器分析器节点
【发布时间】:2020-07-12 09:06:11
【问题描述】:

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

完整代码在这里:https://jsfiddle.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

【问题讨论】:

    标签: web canvas audio web-audio-api


    【解决方案1】:

    您创建一个Sound 对象以及一个连接到您的AnalyserNodemasterGain。但我看不到声音连接到masterGain 的位置。没有它,您的分析器节点就会变得沉默。

    【讨论】:

    • 那么,我应该删除 masterGain 对象并使用声音对象代替分析仪吗?对不起,但我是新手,我有点(实际上很多)困惑。我尝试了以下方法,但没有奏效:``` var analyzer = context.createAnalyser(); 1) sound.gainNode.connect(分析器); 2) sound.oscillator.connect(分析器);```
    • 从简单的东西开始,没有类之类的东西。创建一个振荡器,将其连接到分析仪节点并制作动画以绘制波形。 WebAudio 部分应该非常简单。然后从那里往上走。
    【解决方案2】:

    这是完整的工作脚本代码:

    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();
            // connect analyser to the gainedSource
            this.gainNode.connect(analyser);
            // for the non gainedSource
            //this.gainNode.connect(analyser);
        }
        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);
    };
    
    
    // analyser node
    var analyser = context.createAnalyser();
    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 = 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();
    }());
    

    【讨论】:

      猜你喜欢
      • 2013-09-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多