Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/tensorflow/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Webaudio同时播放两个振荡器声音会导致振动声音_Javascript_Web Audio Api - Fatal编程技术网

Javascript Webaudio同时播放两个振荡器声音会导致振动声音

Javascript Webaudio同时播放两个振荡器声音会导致振动声音,javascript,web-audio-api,Javascript,Web Audio Api,使用网络音频,我产生了一种声音,但听起来很糟糕(振动)。如果我使用非常低的增益,那就更好了,但是太安静了。与使用具有非常低值的低通滤波器相同。在同一时间播放多个频率的正确方法是什么 您可以看到,单击“播放1”按钮可以获得“A”注释。 “播放2”按钮适用于“C”音符。 当两个按钮同时播放时,“播放两个”按钮听起来很糟糕 <html> <head> <title>Audio</title> <script&

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

您可以看到,单击“播放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>

音频
var-context=null;
var oscillatorNode1=零;
var oscillatorNode2=零;
函数停止(){
如果(振荡模式1!=null){
振荡模式1.停止(context.currentTime);
振荡器NODE1=零;
}
如果(振荡模式2!=null){
振荡模式2.停止(context.currentTime);
振荡器NODE2=零;
}
}
函数play1(){
停止();
如果(上下文===null){
上下文=新的AudioContext();
}
oscillatorNode1=context.createOscillator();
oscillatorNode1.type='sine';
振荡器NODE1.frequency.value=220;
连接(context.destination);
oscillatorNode1.start();
oscillatorNode2=context.createOscillator();
oscillatorNode2.type='sine';
振荡器NODE2.frequency.value=261.6255653050986;
连接(context.destination);
oscillatorNode2.start();
}
函数play2(){
停止();
如果(上下文===null){
上下文=新的AudioContext();
}
oscillatorNode1=context.createOscillator();
oscillatorNode1.type='sine';
振荡器NODE1.frequency.value=220;
连接(context.destination);
oscillatorNode1.start();
}
函数play3(){
停止();
如果(上下文===null){
上下文=新的AudioContext();
}
oscillatorNode2=context.createOscillator();
oscillatorNode2.type='sine';
振荡器NODE2.frequency.value=261.6255653050986;
连接(context.destination);
oscillatorNode2.start();
}

我猜您描述的振动是由剪切引起的。当两个振荡器同时演奏时,可能分别产生+2或-2的值。将以下代码段粘贴到的编辑器中时,可以直观地看到它

可以通过添加值为
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();

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

你肯定想把音量调低。考虑不同的声音:把较少的工作放在单独的扬声器上会发出更清晰的声音。

我几乎同时使用了几十个振荡器。我制作的这个应用让你疯狂吧。以下是两个振荡器的示例:

使用我上面提到的“立体声”概念,我使用context.createchannelmerge,然后将每个正弦波连接到每个输出通道,效果非常好。 它似乎在一对扬声器上比在另一对扬声器上工作得更好。这在电话里不太管用。然而,加上增益使它在我测试过的所有扬声器和手机上都非常好。我仍然希望有一个很好的解决方案来合并这些,使之听起来像真正的空气合并

我还试着把更新后的代码粘贴到树冠上,但听起来不太好。一个原因是音频上下文已经创建,创建一个新的上下文效果很好。因此,现有的一个在该页面上不能很好地工作

                context = new AudioContext();
                oscillatorNode1 = context.createOscillator();
                oscillatorNode1.type = 'sine';
                oscillatorNode1.frequency.value = 220;

                var merger = context.createChannelMerger(2);
                merger.connect(context.destination);

                oscillatorNode1.connect(merger, 0, 0);
                oscillatorNode1.start();

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

                oscillatorNode2.connect(merger, 0, 1);
                oscillatorNode2.start();

我在上面提到,增加低增益会有所帮助,但并不能解决这个问题。您的增益示例代码也没有修复它,它有帮助。添加具有非常低值的低通滤波器似乎可行,但非常安静,因此基本上增益非常小。谢谢你的帮助。为每个振荡器创建一个增益节点。@vdu在这种情况下,我误解了这个问题。我认为您可能使用了高于0.5的增益值,因为您说它会产生非常安静的信号。如果低通滤波器有帮助的话,我想你所说的振动就是叠加两个正弦波所产生的伪影。我不确定到底是什么帮助解决了这个问题。这是非常主观的。如果你想保留纯音的声音,你可以在其他两个音调之间的频率播放一个振荡器,而不是叠加两个振荡器。@MikeHelland两种方法的声音应该相同。Web音频API中没有内部剪辑。至少只要这些数字保持在JavaScript可表示的范围内,就不会发生变化。:-)@chrisguttandin在试验叠加两个正弦波的效果时,我用上面的测试打开了两个浏览器窗口。然后,我在每个屏幕上播放一个声音,结果是一样的。我尝试了Chrome和Firefox,结果都一样。但是,当在电脑上播放1个声音(播放1)和在我手机的扬声器手机上播放另一个声音(播放2)并更改两者的音量以匹配时,声音正常。你可以轻松一下
                context = new AudioContext();
                oscillatorNode1 = context.createOscillator();
                oscillatorNode1.type = 'sine';
                oscillatorNode1.frequency.value = 220;

                var merger = context.createChannelMerger(2);
                merger.connect(context.destination);

                oscillatorNode1.connect(merger, 0, 0);
                oscillatorNode1.start();

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

                oscillatorNode2.connect(merger, 0, 1);
                oscillatorNode2.start();