Когда я играю тональный сигнал и затем останавливаю его, слышен неприятный «треск» и начало, и конец.Я искал решение и обнаружил, что уменьшение громкости с течением времени должно решить эту проблему.
Поэтому я использую 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?