У меня есть 3d пространство с разными зонами, каждая зона имеет свои звуки.Моя цель - сделать плавные переходы звука, когда пользователь перемещается из одной зоны в другую, в основном делая перекрестные помехи между звуковыми дорожками.Также я бы хотел изящно обработать случай, когда пользователь передумал и внезапно вернулся в только что оставленную зону, это означает, что отменяются новые аудиопереходы и постепенно возвращается к предыдущему состоянию.
Для этого я использую веб-аудио API , в частности linearRampToValueAtTime и cancelScheduledValues , чтобы определить функции входа / выхода фейдов:
const fadeIn = (sound, time = 4, gain = 1.0) => {
sound.gainNode.gain.cancelScheduledValues(sound.context.currentTime)
!sound.isPlaying && sound.play()
sound.gainNode.gain.linearRampToValueAtTime(gain, sound.context.currentTime + time)
}
const fadeOut = (sound, time = 4, gain = 0.0) => {
sound.gainNode.gain.cancelScheduledValues(sound.context.currentTime)
sound.gainNode.gain.linearRampToValueAtTime(gain, sound.context.currentTime + time)
}
Я тестирую это только на одном звуке, нажатие клавиши «I» запускает fadeIn, а клавиша «O» запускает fadeOut:
document.addEventListener("keyup", e => {
switch (e.keyCode) {
// I key
case 73:
fadeIn(mySound)
break
// O key
case 79:
fadeOut(mySound)
break
})
Я получил противоречивые результаты.Иногда звук исчезает правильно, в других случаях он начинается внезапно в fadeIn или обрывается в fadeOut.Кажется, что вызов cancelScheduledValues , когда переход не завершен, приводит к ошибочному поведению.Я хотел бы, чтобы это работало гладко даже при запуске fadeOut, когда fadeIn еще не завершена и наоборот.Я также пытался немного отложить linearRamps с помощью setTimeout, что-то вроде
setTimeout(() => sound.gainNode.gain.linearRampToValueAtTime(gain, sound.context.currentTime + time), 0.1)
, но получил одинаково неверные результаты.Я использую API неправильно?Любое предложение?