【问题标题】:Frequency Cutoff Using AnalyserNode使用 AnalyserNode 进行频率截止
【发布时间】:2015-06-09 01:16:30
【问题描述】:

我正在使用 Web API 创建一个音频条可视化工具,我希望这些条只显示 ~ 40Hz 到 ~10kHz。我发现的唯一东西是频域,但这并没有为我提供我正在寻找的东西(AnalyserNode.fftSize)。有没有办法只可视化该频率?这是我的代码:

.controller('PlayerCtrl', function(PlayerService, $scope){
        $scope.title = PlayerService.songName;
        $scope.art = PlayerService.songArt;
        $scope.url = PlayerService.songUrl + '?client_id=54970813fe2081a104a874f0f870bcfe';

        if (! window.AudioContext) {
            if (! window.webkitAudioContext) {
                alert('no audiocontext found, update your browser yo');
            }
            window.AudioContext = window.webkitAudioContext;
        }
        var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
        var analyser = audioCtx.createAnalyser();
        analyser.minDecibels = -60;
        analyser.maxDecibels = 0;
        analyser.smoothingTimeConstant = 0.85;

        var audioBuffer;
        var sourceNode;
        var javascriptNode;

        var canvas = document.querySelector('.visualizer');
        var canvasCtx = canvas.getContext("2d");

        var intendedWidth = document.querySelector('.now-playing').clientWidth;

        canvas.setAttribute('width',intendedWidth);

        var visualSelect = document.getElementById("visual");

        var drawVisual;

        setupAudioNodes();
        loadSound($scope.url); //music file

        function loadSound(url) {
            var request = new XMLHttpRequest();
            request.open('GET', url, true);
            request.responseType = 'arraybuffer';

            request.onload = function() {
                audioCtx.decodeAudioData(request.response, function(buffer) {
                    playSound(buffer);
                }, function(error){
                    console.log(error)
                });
            };
            request.send();
        }

        function playSound(buffer) {
            sourceNode.buffer = buffer;
            sourceNode.start(0);
            $(".content").show();
            $("#hue").hide();
        }


        function setupAudioNodes() {
            console.log('audio nodes')
            javascriptNode = audioCtx.createScriptProcessor(2048, 1, 1);
            javascriptNode.connect(audioCtx.destination);

            sourceNode = audioCtx.createBufferSource();
            sourceNode.connect(analyser);
            analyser.connect(javascriptNode);

            sourceNode.connect(audioCtx.destination);

            visualize();
        }

        function visualize() {
            console.log('viz');
            WIDTH = canvas.width;
            HEIGHT = canvas.height;

            analyser.fftSize = 64;
            var bufferLength = analyser.frequencyBinCount;
            console.log(bufferLength);
            var dataArray = new Uint8Array(bufferLength);

            canvasCtx.clearRect(0, 0, WIDTH, HEIGHT);

            function draw() {
                drawVisual = requestAnimationFrame(draw);

                analyser.getByteFrequencyData(dataArray);

                canvasCtx.fillStyle = 'rgb(0, 0, 0)';
                canvasCtx.fillRect(0, 0, WIDTH, HEIGHT);

                var barWidth = (WIDTH / bufferLength) * 2.5;
                var barHeight;
                var x = 0;

                for (var i = 0; i < bufferLength; i++) {
                    barHeight = dataArray[i];

                    canvasCtx.fillStyle = 'rgb(' + (barHeight + 100) + ',50,50)';
                    canvasCtx.fillRect(i*17, HEIGHT - barHeight / 2, 10, barHeight);

                    x += barWidth + 1;
                }
            }
            draw()
        }

    })

【问题讨论】:

    标签: javascript webkit web-audio-api webkitaudiocontext audiocontext


    【解决方案1】:

    只是不要使用分析仪计算的较高频率。执行此操作的简单方法是将 bufferLength 设置为小于 analyser.frequencyBinCount 的值。分析器将为您提供尽可能多的数据,因为它可以容纳在数组中,并丢弃其余的。

    这些 bin 从零到采样率的一半均匀分布,因此在典型的采样率 (44kHz) 下,您需要大约一半的 bin。更一般地说,Math.ceil(analyser.frequencyBinCount * 10000 / (audioCtx.sampleRate / 2)) 应该会给你你想要的号码。

    【讨论】:

    • 我会试试这个。谢谢!
    【解决方案2】:

    您需要计算频率分辨率:sampleRate/fftSize。这将为您提供getByteFrequencyData 给您的每个数字的频率范围。当然,如果您依赖默认的 sampleRate,这个比率很难知道。像这样覆盖它:

    let audio_context = new AudioContext({
        sampleRate: 44000,
    });
    

    【讨论】:

      【解决方案3】:

      我解释了@mehmet 的回答

      频率分辨率:sampleRate/fftSize

      表示 总数除以显示的 eq 波段。

      calcFreqs(sampleRate, fftSize) {
          const bands = fftSize/2; // bands are half the fftSize
          const fqRange = sampleRate / bands;
          let allocated = [];
      
          for ( let i = 0, j = bands; i < j; i++ ) {
              sampleRate = Math.round(sampleRate - fqRange);
              allocated.push(sampleRate);
          }
          // console.log(allocated.slice().reverse());
          return allocated.slice().reverse();
      }
      

      因此对于超过 48,000Hz 的 16 个频段样本:

      [0, 3000, 6000, 9000, 12000, 15000, 18000, 21000, 24000, 27000, 30000, 33000, 36000, 39000, 42000, 45000]

      我想请专家澄清一下,但这里是这样做的方法。 我的项目在Github

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-09-22
        • 1970-01-01
        • 2014-08-29
        • 2016-11-25
        • 2017-04-03
        • 1970-01-01
        • 1970-01-01
        • 2019-02-23
        相关资源
        最近更新 更多