Smooth Fading in WebAudio

HTML

CurrentTime : <span id='count'>0</span>

<p> Fade in the oscillator and then fade out the oscillator</p>

<p> Just using linearRampToValueAtTime </p>

<button id="in1">Fade In</button>
<button id="out1">Fade Out</button>

<p> Adding cancelScheduledValues </p>

<button id="in2">Fade In</button>
<button id="out2">Fade Out</button>

<p> Adding setValueAtTime </p>

<button id="in3">Fade In</button>
<button id="out3">Fade Out</button>

<p> Adding MATH </p>

<button id="in4">Fade In</button>
<button id="out4">Fade Out</button>

JavaScript

window.AudioContext = window.AudioContext || window.webkitAudioContext;

var context = new AudioContext();

var osc = context.createOscillator();
var gain = context.createGain();
osc.connect(gain);
gain.connect(context.destination);
osc.start(0);
gain.gain.setValueAtTime(0.001, context.currentTime);

document.getElementById('in1').addEventListener('click', function(){
   gain.gain.linearRampToValueAtTime(1,context.currentTime + 10);
});

document.getElementById('out1').addEventListener('click', function(){
   gain.gain.linearRampToValueAtTime(0.001,context.currentTime + 10);
});

document.getElementById('in2').addEventListener('click', function(){
   gain.gain.cancelScheduledValues(context.currentTime);
   gain.gain.linearRampToValueAtTime(1,context.currentTime + 10);
});

document.getElementById('out2').addEventListener('click', function(){
   gain.gain.cancelScheduledValues(context.currentTime);
   gain.gain.linearRampToValueAtTime(0.001,context.currentTime + 10);
});

document.getElementById('in3').addEventListener('click', function(){
   gain.gain.cancelScheduledValues(context.currentTime);
   gain.gain.setValueAtTime(0.001, context.currentTime);
   gain.gain.linearRampToValueAtTime(1,context.currentTime + 10);
});

document.getElementById('out3').addEventListener('click', function(){
   gain.gain.cancelScheduledValues(context.currentTime);
   gain.gain.setValueAtTime(1, context.currentTime);
   gain.gain.linearRampToValueAtTime(0.001,context.currentTime + 10);
});

var prevStartTime = 0;
var prevEndTime = 0;
var prevStartValue = 0
var prevTargetValue = 0


document.getElementById('in4').addEventListener('click', function(){
   var currentValue = 0.001;
   var endTime = context.currentTime + 0.5;
   if (prevEndTime > context.currentTime){
       currentValue =  prevStartValue + (prevTargetValue - prevStartValue) * ((context.currentTime - prevStartTime) / (prevEndTime - prevStartTime));
   }
   gain.gain.cancelScheduledValues(context.currentTime);
  ...