【发布时间】:2021-09-28 10:18:30
【问题描述】:
我正在开发一个 3D 网络应用程序,我想在其中使用位置 3D 音频。
我开始注意到随着声源位置的改变,输出端会出现噼啪声。 最初我认为这可能是编程问题或库问题(我使用的是 howler.js)。
我做了一个基于普通 JS 和 Webaudio API 的非常基本的示例,如下所示
let params={
"xPosition":0,
"zPosition":-1
};
let gui=new dat.GUI( { autoPlace: true, width: 500 });
const AudioContext = window.AudioContext || window.webkitAudioContext;
let audioCtx;
let panner;
let listener;
let source;
let osc;
function initWebAudio(){
audioCtx = new AudioContext();
panner = audioCtx.createPanner();
listener = audioCtx.listener;
osc = audioCtx.createOscillator();
osc.frequency.value = 70;
osc.connect(panner);
osc.start(0);
panner.connect(audioCtx.destination);
panner.panningModel = 'HRTF';
panner.distanceModel = 'linear';
panner.maxDistance = 60;
panner.refDistance = 1;
panner.rolloffFactor = 1;
panner.coneInnerAngle = 360;
panner.coneOuterAngle = 360;
panner.coneOuterGain = 0;
panner.positionX.setValueAtTime(0,audioCtx.currentTime);
panner.positionY.setValueAtTime(1,audioCtx.currentTime);
panner.positionZ.setValueAtTime(1,audioCtx.currentTime);
if(panner.orientationX) {
panner.orientationX.value = 1;
panner.orientationY.value = 0;
panner.orientationZ.value = 0;
} else {
panner.setOrientation(1,0,0);
}
if(listener.forwardX) {
listener.forwardX.value = 0;
listener.forwardY.value = 0;
listener.forwardZ.value = -1;
listener.upX.value = 0;
listener.upY.value = 1;
listener.upZ.value = 0;
} else {
listener.setOrientation(0,0,-1,0,1,0);
}
if(listener.positionX) {
listener.positionX.value = 0;
listener.positionY.value = 0;
listener.positionZ.value = 0;
} else {
listener.setPosition(0,0,0);
}
}
function positionPanner() {
if(panner.positionX) {
panner.positionX.setValueAtTime(params.xPosition, audioCtx.currentTime);
} else {
panner.setPosition(params.xPosition,0,params.zPosition);
}
}
function tick(){
positionPanner();
}
function onClickStart(){
initWebAudio();
gui.add(osc.frequency,"value",50,220).name("frequency");
setInterval(tick,50);
}
function buildMenu(){
gui.add(params,"xPosition",-3,3).step(0.001);
gui.add(window,"onClickStart").name("start");
}
buildMenu();
https://jsfiddle.net/fedeM75/t9vpm8so/23/
按下开始,然后当您更改 xPosition 滑块时,会出现噼啪声。 使用耳机时尤其明显。
我在google上搜索,有人说这与职位的变化率有关。但是我尝试了不同的值范围,但仍然会发生一些小的变化。
顺便说一句,如果使用平移器的条件是位置的变化速度非常慢,那么它在现实世界的情况下似乎没有用。
我使用计时器来更新位置,但使用 requestAnimationFrame() 也会发生同样的情况
有没有人知道为什么会发生这种情况以及如何解决它?
【问题讨论】:
-
您能否简化/自动化音频更改,使它们不会突然?例如。如果我在音频播放器中构建播放/暂停功能,我实际上会快速淡入/淡出,以避免突然变化引起的爆裂声和点击声。想想波形在某个不为 0 的地方被截断……你会听到砰砰声。
-
我尝试使用另一个变量作为 targetValue,因此该位置会慢慢尝试达到目标值,但弹出仍然存在。在现实世界的应用程序中,您将限制源在 3D 空间中的最大速度。在某些情况下,这是一个非常重要的限制,导致 3d 定位音频无法使用。想象一个动作游戏,物体需要非常缓慢地移动以防止那些爆裂声和咔嗒声......
-
不,我仍在寻找解决方案。这似乎是一个错误,但并非 Chrome 独有,因为 Firefox 显示相同的问题
-
我目前正在尝试为此寻找解决方案。我创建了一个 360 度移动声音的基本示例:jsfiddle.net/9pbn587L/98 我现在尝试了很多东西,但还没有找到
-
@NVRM 我实际上首先使用的是 howler.js。当我遇到 panner 的问题时,我意识到 Howler 只是使 WebAudio panner 节点可访问,但不会添加或更改任何功能。因此,我构建了基于 Webaudio 的最简单的示例。我尝试使用不同的更新间隔,但问题仍然存在。在 PC 上,问题发生在 Chrome、Firefox 和 Edge 中,但有人告诉我,在 Safari/Mac 上没有,所以可能是实施问题。这里我做了一个更简单的例子jsfiddle.net/fedeM75/bqtzcokm/1