Игра с аудиоконтекстом

Вдохновленный таким SO-ответом, у меня есть этот код, и он работает, но он вылетает и звучит не так гладко, как мог бы.

$('.btn').each(initDraggable);
function initDraggable() {
 var param = {}
 param.drag = drag
 param.stop = stopper
 $(this).draggable(param)
}
var Variables = {}
Variables.Frequency = 0
function drag(myEvent,myUI) {
 var Frequency = myUI.position.left + 100
 var Duration = 5000
 if (Math.abs(Variables.Frequency-Frequency) > 25) {
  if (typeof(Variables.osc) === 'undefined') {
  } else {
   Variables.osc.stop(0)
  }
  Variables.Frequency = Frequency
  Oscillator(Frequency,Duration)
 }
}
function stopper() {
 Variables.osc.stop(0)
}


Variables.ctx = new(window.audioContext || window.webkitAudioContext)
function Oscillator(argFrequency,argDuration) {
 Variables.osc = Variables.ctx.createOscillator()
 Variables.osc.type = 0
 Variables.osc.connect(Variables.ctx.destination)
 Variables.osc.frequency.value = argFrequency
 Variables.osc.start(0)
 setTimeout(myTimeout,argDuration)
 function myTimeout() {
  Variables.osc.stop(0)
 }
}
<link rel="stylesheet" href="//cdn.jsdelivr.net/bootstrap/latest/css/bootstrap.css">
<link rel="stylesheet" href="//cdn.jsdelivr.net/jquery.ui/latest/jquery-ui.min.css">
<span class="btn btn-primary">Drag me</span>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="//cdn.jsdelivr.net/bootstrap/latest/js/bootstrap.js"></script>
<script src="//cdn.jsdelivr.net/jquery.ui/latest/jquery-ui.min.js"></script>
<script src="//cdn.jsdelivr.net/jquery.ui.touch-punch/latest/jquery.ui.touch-punch.js"></script>

В: Есть ли простой способ сделать так, чтобы это звучало более плавно?

1 ответ

Решение

Там нет необходимости воссоздавать oscillator на drag Я думаю, что это то, что вызывает популярность. Но вы можете изменить frequency value из начала oscillator, так что вы можете достичь своего результата, создав осциллятор при перетаскивании start, прекрати stopи просто измените значение частоты на drag, Как это:

$('.btn').each(initDraggable);

function initDraggable() {
  var param = {}
  param.drag = drag
  param.stop = stopper
  param.start = startOsc
  $(this).draggable(param)
}
var Variables = {}
Variables.Frequency = 0

function drag(myEvent, myUI) {
  var Frequency = myUI.position.left + 100
  var Duration = 5000
  if (Math.abs(Variables.Frequency - Frequency) > 25) {
    //You could put some validation on creation, but since you're not creating it, it's not necessary here 
    /*if (typeof(Variables.osc) === 'undefined') {
  } else {
   Variables.osc.stop(0)
  }*/

    Variables.Frequency = Frequency;
    //Oscillator(Frequency,Duration)
    Variables.osc.frequency.value = Frequency;
  }
}

function startOsc(myEvent, myUI) {
  var Frequency = myUI.position.left + 100
  Oscillator(Frequency) //Since it plays in continue you don't need duration
}

function stopper() {
  Variables.osc.stop(0)
}


Variables.ctx = new(window.AudioContext || window.webkitAudioContext)

function Oscillator(argFrequency /*,argDuration*/ ) {
  Variables.osc = Variables.ctx.createOscillator()
  Variables.osc.type = 0
  Variables.osc.connect(Variables.ctx.destination)
  Variables.osc.frequency.value = argFrequency
  Variables.osc.start(0)
    /*setTimeout(myTimeout,argDuration)
 function myTimeout() {
  Variables.osc.stop(0)
 }*/
}
<link rel="stylesheet" href="//cdn.jsdelivr.net/bootstrap/latest/css/bootstrap.css">
<link rel="stylesheet" href="//cdn.jsdelivr.net/jquery.ui/latest/jquery-ui.min.css">
<span class="btn btn-primary">Drag me</span>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="//cdn.jsdelivr.net/bootstrap/latest/js/bootstrap.js"></script>
<script src="//cdn.jsdelivr.net/jquery.ui/latest/jquery-ui.min.js"></script>
<script src="//cdn.jsdelivr.net/jquery.ui.touch-punch/latest/jquery.ui.touch-punch.js"></script>

Другие вопросы по тегам