Документация
Документацию о том, что вы пытаетесь сделать, можно найти в BaseAudioContext
, в частности, метод BaseAudioContext.createGain()
.
Документация MDN немного не хватает в том, что она содержит только фрагменты, которые не будут работать как есть.Таким образом, ниже приведен слишком упрощенный пример с учетом того, что это не может быть наилучшей практикой.
Пояснение
Генератор и регулировка усиления являются аудио узлами.Таким образом, вы должны представить их в виде цепочки сигналов, как показано ниже.
Узел осциллятора проходит через узел усиления, который проходит через аудиоконтент.
Решение
Использование вашего текущего формата, так как самодостаточный фрагмент приведен ниже ( см. Jsfiddle здесь )
<!DOCTYPE html>
<html>
<head>
<script>
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
var gainNode = audioCtx.createGain();
gainNode.connect(audioCtx.destination);
var gain = 0.1;
//---------------------------------------------------------------------
gainNode.gain.setValueAtTime(gain, audioCtx.currentTime);
</script>
</head>
<!-- ===================================================================== -->
<body>
<div>
<button onclick="myFunction()">
Click me
</button>
</div>
<script>
function myFunction()
{
//---------------------------------------------------------------------
var duration = 0.5; // in seconds
//---------------------------------------------------------------------
var oscillator = audioCtx.createOscillator();
oscillator.type = 'square';
oscillator.frequency.value = 500;
oscillator.connect(gainNode);
oscillator.start(audioCtx.currentTime);
oscillator.stop(audioCtx.currentTime + duration);
//---------------------------------------------------------------------
}
</script>
</body>
<!-- ===================================================================== -->
</html>
Лучшая практика
Для лучшей практики, я бы посоветовал вам избегать повторного создания узлов снова и снова.Скорее, я бы просто увеличивал усиление на короткое время, а затем понижал его, пример которого приведен ниже.Насколько я могу судить, для WebAudio нет узла генератора конвертов, но вы можете использовать .linearRampToValueAtTime()
, если необходимо.
ПРИМЕЧАНИЕ. В настоящее время это не работает в Safari.( см. Jsfiddle здесь )
<!DOCTYPE html>
<html>
<head>
<script>
//---------------------------------------------------------------------
// Edit These
var gain = 0.1;
var duration = 1000;
//---------------------------------------------------------------------
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
var gainNode = audioCtx.createGain();
//---------------------------------------------------------------------
var oscillator = audioCtx.createOscillator();
oscillator.type = 'square';
oscillator.frequency.value = 500;
//---------------------------------------------------------------------
oscillator.connect(gainNode);
gainNode.connect(audioCtx.destination);
//---------------------------------------------------------------------
gainNode.gain.setValueAtTime(0.0, audioCtx.currentTime); // turned off by default
oscillator.start(audioCtx.currentTime);
//---------------------------------------------------------------------
</script>
</head>
<!-- ===================================================================== -->
<body>
<div>
<button onclick="soundOn()">
Click me
</button>
</div>
<script>
function mute()
{
gainNode.gain.setValueAtTime(0.0, audioCtx.currentTime);
}
function soundOn()
{
gainNode.gain.setValueAtTime(gain, audioCtx.currentTime);
setTimeout(mute,duration);
}
</script>
</body>
<!-- ===================================================================== -->
</html>
Дополнительные ресурсы
Если вы боретесь с взаимодействием со звуковым контекстом в этом, я бы предложил попробовать такую библиотеку, как p5.js и библиотека p5.sound .
Посмотрите на https://p5js.org/reference/#/p5.Oscillator, чтобы увидеть, является ли это более интуитивным подходом.