Webaudio同时播放两个振荡器声音会引起振动声

问题描述 投票:0回答:3

使用网络音频,我产生了声音,但听起来确实很糟糕(振动)。如果我使用非常低的增益,那就更好了,但是太安静了。与使用极低值的低通滤波器相同。同时播放多个频率的正确方法是什么?

您可以看到单击“播放1”按钮可以很好地处理“ A”音符。播放2按钮适用于“ C”音符。当两者同时播放时,“同时播放”按钮听起来会很糟糕。

<html>
    <head>
        <title>Audio</title>
        <script>

            var context = null;
            var oscillatorNode1 = null;
            var oscillatorNode2 = null;

            function stop() {
                if ( oscillatorNode1 != null ) {
                    oscillatorNode1.stop(context.currentTime);
                    oscillatorNode1 = null;
                }
                if ( oscillatorNode2 != null ) {
                    oscillatorNode2.stop(context.currentTime);
                    oscillatorNode2 = null;
                }
            }

            function play1() {
                stop();
                if ( context === null) {
                    context = new AudioContext();
                }
                oscillatorNode1 = context.createOscillator();
                oscillatorNode1.type = 'sine';
                oscillatorNode1.frequency.value = 220;

                oscillatorNode1.connect(context.destination);
                oscillatorNode1.start();

                oscillatorNode2 = context.createOscillator();
                oscillatorNode2.type = 'sine';
                oscillatorNode2.frequency.value = 261.6255653005986;

                oscillatorNode2.connect(context.destination);
                oscillatorNode2.start();
            }

            function play2() {
                stop();
                if ( context === null) {
                    context = new AudioContext();
                }
                oscillatorNode1 = context.createOscillator();
                oscillatorNode1.type = 'sine';
                oscillatorNode1.frequency.value = 220;

                oscillatorNode1.connect(context.destination);
                oscillatorNode1.start();

            }

            function play3() {
                stop();
                if ( context === null) {
                    context = new AudioContext();
                }

                oscillatorNode2 = context.createOscillator();
                oscillatorNode2.type = 'sine';
                oscillatorNode2.frequency.value = 261.6255653005986;

                oscillatorNode2.connect(context.destination);
                oscillatorNode2.start();
            }

        </script>
    </head>
    <body>
        <form>
            <input type="button" onclick="play1()" value="Play both" />
            <input type="button" onclick="play2()" value="Play 1" />
            <input type="button" onclick="play3()" value="Play 2" />
            <input type="button" onclick="stop()" value="Stop" />
        </form>
    </body>
</html>
javascript web-audio-api
3个回答
0
投票

我想您描述的振动是由于削波引起的。当两个振荡器同时播放时,可能分别导致+2或-2的值。将以下代码段粘贴到Canopy的编辑器中时,您可以直观地看到它。

const osc1 = new OscillatorNode(context, { frequency: 261.6 });
const osc2 = new OscillatorNode(context, { frequency: 222 });

osc1.connect(context.destination);
osc2.connect(context.destination);

osc1.start();
osc2.start();

您可以通过添加一个值为0.5的GainNode来避免这种情况。但是,合并后的信号将被感知为更纯净的静音。这是因为纯音在+1和-1之间不断交替,而组合音并不总是达到极值。

添加GainNode之后,play1()函数的核心部分看起来像这样:

oscillatorNode1 = context.createOscillator();
oscillatorNode1.frequency.value = 220;

oscillatorNode2 = context.createOscillator();
oscillatorNode2.frequency.value = 261.6255653005986;

gainNode = context.createGain();
gainNode.gain.value = 0.5;

oscillatorNode1.connect(gainNode);
oscillatorNode2.connect(gainNode);
gainNode.connect(context.destination);

oscillatorNode1.start();
oscillatorNode2.start();

0
投票

这与数字音频和音频工程有很多关系。


0
投票

使用上面提到的“立体声”概念,我使用context.createChannelMerger,然后将每个正弦波连接到每个输出通道,并且效果很好。一对扬声器似乎效果更好。在手机上效果不佳。但是,增加增益使其在到目前为止我测试过的所有扬声器和电话上都非常出色。我仍然希望在合并这些文件时有一个好的解决方案,这听起来像是真正的空中合并。

© www.soinside.com 2019 - 2024. All rights reserved.