exponentialRampToValueAtTime не предотвращает взлом в Firefox - PullRequest
0 голосов
/ 23 октября 2018

Когда я играю тональный сигнал и затем останавливаю его, слышен неприятный «треск» и начало, и конец.Я искал решение и обнаружил, что уменьшение громкости с течением времени должно решить эту проблему.

Поэтому я использую 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?

1 Ответ

0 голосов
/ 01 марта 2019

Я также заметил, что exponentialRampToValueAtTime() не работает так, как задумано в Firefox.Слишком мне это кажется неправильной реализацией.

В качестве обходного пути можно использовать linearRampToValueAtTime.

В качестве альтернативы вы также можете использовать setValueCurveAtTime для определения собственной кривой.

...