mardi 31 mars 2020

Oscillator AnalyserNode

I'm trying to add AnalyserNode and visualize the output sound to a web audio example that I made but I can't figure out how. I think I am not passing the right source to the analyser (?)

Here for the full code : 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>

Could anyone help me to identify what I'm doing wrong? Thank in advance!

PS: Open it with Firefox. Does not work on Chromium based browsers for me.

Here is a working example: https://codepen.io/dennisgaebel/pen/YEwLaL




Aucun commentaire:

Enregistrer un commentaire