Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to play a sound continuously without break?

I am trying to play a vehicle driven sound in a browser based game (continuously without break).
My .wav file length is 1 second and has same frequency from beginning to end. But sound takes a little break before next iteration.
Here is code:

function playSound()
{
    //alert("");
    myAudio = new Audio('http://ithmbwp.com/feedback/SoundsTest/sounds/tank_driven.wav'); 
    if (typeof myAudio.loop == 'boolean')
    {
        myAudio.loop = true;
    }
    else
    {
        myAudio.addEventListener('ended', function() {
            this.currentTime = 0;
            this.play();
        }, false);
    }
    myAudio.volume = 0.3;
    myAudio.play();
}

Can anyone help me to play the sound continuously?

Edition

You can visit my page here to observe the problem.

window.onload = function() {
  playSound();
};

function playSound()
{
	//alert("");
	myAudio = new Audio('http://ithmbwp.com/feedback/SoundsTest/sounds/tank_driven.wav'); 
	if (typeof myAudio.loop == 'boolean')
	{
		myAudio.loop = true;
	}
	else
	{
		myAudio.addEventListener('ended', function() {
			this.currentTime = 0;
			this.play();
		}, false);
	}
	myAudio.volume = 0.3;
	myAudio.play();
}
<h3 style="font-family:verdana;">Please listen the sound break.</h3>
<h3 style="font-family:verdana;">It should be continuous.</h3>
like image 649
Rashid Avatar asked Mar 23 '17 06:03

Rashid


2 Answers

Use the AudioContext API and its bufferSourceNode interface, to have seamlessly looped sounds.

Note that you'll also need your audio to be correctly edited to avoid crackles and sound clips, but yours seems good.

const aCtx = new AudioContext();
let source = aCtx.createBufferSource();
let buf;
fetch('https://dl.dropboxusercontent.com/s/knpo4d2yooe2u4h/tank_driven.wav') // can be XHR as well
  .then(resp => resp.arrayBuffer())
  .then(buf => aCtx.decodeAudioData(buf)) // can be callback as well
  .then(decoded => {
    source.buffer = buf = decoded;
    source.loop = true;
    source.connect(aCtx.destination);
    check.disabled = false;
  });

check.onchange = e => {
  if (check.checked) {
    source.start(0); // start our bufferSource
  } else {
    source.stop(0); // this destroys the buffer source
    source = aCtx.createBufferSource(); // so we need to create a new one
    source.buffer = buf;
    source.loop = true;
    source.connect(aCtx.destination);
  }
};
<label>play audioBuffer</label>
<input type="checkbox" id="check" disabled><br><br>
Just to compare <audio src="https://dl.dropboxusercontent.com/s/knpo4d2yooe2u4h/tank_driven.wav" loop controls>

Or with your snippet :

window.onload = function() {
  playSound();
};

function playSound() {
  if (AudioContext) {
    out.textContent = "yeah now it's continuous !!!";
    playAsAudioBuffer();
  } else {
    out.textContent = "you should consider updating your browser...";
    playNormally();
  }
}

function playAsAudioBuffer() {
  var aCtx = new AudioContext();
  // here is the real audioBuffer to sound part
  function ondecoded(buf) {
    var source = aCtx.createBufferSource();
    source.buffer = buf;
    source.loop = true;
    var gainNode = aCtx.createGain();
    gainNode.gain.value = .3; // here you set the volume
    source.connect(gainNode);
    gainNode.connect(aCtx.destination);
    source.start(0);
  }

  var xhr = new XMLHttpRequest();
  xhr.onload = function() {
    aCtx.decodeAudioData(this.response, ondecoded);
  };
  xhr.onerror = playNormally;
  xhr.responseType = 'arraybuffer';
  xhr.open('get', 'https://dl.dropboxusercontent.com/s/knpo4d2yooe2u4h/tank_driven.wav');
  xhr.send();
}

// An ugly workaround in case of old browsers
function playNormally() {
  var myAudios = [new Audio('https://dl.dropboxusercontent.com/s/knpo4d2yooe2u4h/tank_driven.wav')];
  myAudios.push(new Audio(myAudios[0].src));
  myAudios.forEach(function(a){
    a.addEventListener('timeupdate', checkTime);
    a.volume = 0.3;
    });
   
  function checkTime(){
    if(this.currentTime > this.duration - 0.4){
      startNext(this);
      }
    }
  var current = 0;
  function startNext(el){
    current = (current + 1) % 2;
    myAudios[current].play();
    el.currentTime = 0;
    el.pause();
    }
  myAudios[0].play();
}
<h3 id="out"></h3>
like image 120
Kaiido Avatar answered Nov 01 '22 13:11

Kaiido


Bee Cool, just use few lines code

window.onload = function() {
  playSound();
};

function playSound()
{
var myAudio = new Audio('http://ithmbwp.com/feedback/SoundsTest/sounds/tank_driven.wav'); 

myAudio.volume = 0.3 ;

var tank_driven_sound = setInterval(function()
{
	myAudio.currentTime = 0;
	myAudio.play();
}, 800);

}
<h3 style="font-family:verdana;">Please listen, it's continuous.</h3>
like image 40
Andle Avatar answered Nov 01 '22 14:11

Andle