当我播放一个音调然后将其停止时,会听到不愉快的“裂纹”,以及开始和结束。我搜索了一个解决方案,发现随着时间的推移减小音量可以解决该问题。
因此,我使用AudioGainMode
上下倾斜,而不是突然剪切音频:
controlGain.gain.exponentialRampToValueAtTime(
1,
gAudioCtx.currentTime+time_milliseconds/1000
);
// and later...
controlGain.gain.exponentialRampToValueAtTime(
0.0001,
gAudioCtx.currentTime+time_milliseconds/1000
);
因为没有在0
上定义指数函数,所以使用0.0001
。
但是,在Firefox中,我仍然可以听到讨厌的声音。我还注意到,使用更长的延迟没有效果-增益会立即达到目标值。
function sleep(ms) {
return new Promise(function (resolve, reject) {
setTimeout(resolve, ms);
});
}
function play() {
const AUDIO_RAMP_DELAY = 50;
var gAudioCtx = new AudioContext();
const controlGain = gAudioCtx.createGain();
controlGain.gain.value = 0.00001;
/// Full volume at t+50ms
controlGain.gain.exponentialRampToValueAtTime(
1,
gAudioCtx.currentTime+AUDIO_RAMP_DELAY/1000
);
controlGain.connect(gAudioCtx.destination);
var osc = gAudioCtx.createOscillator();
// create a tone around 440hz
const length = 1024;
var real = new Float32Array(length);
var imag = new Float32Array(length);
real[440]=1;
//real[512]=1;
var wave = gAudioCtx.createPeriodicWave(real, imag, {disableNormalization: true});
osc.frequency.value = 1;
osc.setPeriodicWave(wave);
osc.connect(controlGain);
osc.start();
(async function() {
await sleep(AUDIO_RAMP_DELAY+1);
// now we're at full volume, wait another 2 seconds
await sleep(2000);
controlGain.gain.exponentialRampToValueAtTime(
0.00001,
gAudioCtx.currentTime+50/1000
);
await sleep(2000);
osc.stop();
document.querySelector("button").disabled = false;
})();
}
<h2>Warning: this demo makes loud sounds!</h2>
<button onclick="play(); this.disabled=true">Click to play</button>
如何使其也可以在Firefox中使用?
答案 0 :(得分:0)
我也注意到exponentialRampToValueAtTime()
似乎在Firefox中无法正常工作。对我来说,这似乎是一个错误的实现。
一种解决方法是改为使用linearRampToValueAtTime
。
或者,您也可以使用setValueCurveAtTime
定义自己的曲线。