Howler.js: Seamless looping not working

Created on 10 Oct 2015  Â·  18Comments  Â·  Source: goldfire/howler.js

Good day, i created a series of seamless loops, that play perfectly seamless in Adobe Audition but when on the web with your wonderful library and the browsers, a terrible gap appears, check here:

http://torchprinciple.com/looptest/test.html

and the code

var mysound = new Howl({
urls: ["atmosphere-loop-mono-1.mp3"],
volume: 1,
loop:1,
buffer: false,
onend: function() {
},
onplay: function() {},
onload: function() {
console.log ("loaded");
}

});
mysound.play();

how can i solve this? i need seamless loops, and im using your library which should be using web audio api which should work
thanks so much :)

All 18 comments

in this article
http://www.flightarcade.com/learn/webaudio?WT.mc_id=13407-DEV-sitepoint-article31
the author says:
Fortunately, gapless audio playback with the Web Audio API is really straightforward. It's just a matter of setting a timestamp for the beginning and end of the looping portion of the audio (note that these values are relative to the audio source itself and not the AudioContext clock).
engineAudioSource.source.loopStart = 0.5;
engineAudioSource.source.loopEnd = 1.5;

i dont know if that's too overoptimistic from that writer :)

i have now used loopStart and loopEnd and that will reduce the gap but still a click remains, it doesnt solve the problem fully, i did manage in google chrome desktop with some specific loopStart and loopEnd values to make it seamless gapless, but same values wont work in firefox, Edge, or chrome for android , really so much for an amazing web audio api that cant even create seamless loops, unbelievable....... And thank you again for creating this wonderful howler.js, it is only thanks to people like you that we can experiment quickly; as for the issue with the loops... as an engineer myself, i am just speechless...

latest update, using source.loopStart and source.loopEnd i have improved a lot the gaps in loops,
how can use these 2 parameters loopStart and loopEnd in Howler.js? :) thank you :)

Thank you for adding this to the 2.0 milestone, using loopStart and loopEnd i have now managed to create fantastic loops using the web audio api in raw state, hope to be able to access these parameters in howler.js soon, thank you :)

You technically already have access to them with sprites. Even if you are just playing one sound, you can define a sprint for it and adjust the start and length, which then get used with loopStart and loopEnd internally.

thank you James, but in my web app i use lots of sounds, and i dont need
neither want to use sprites.... so having to create sprites for each sound
where i need to control loopStart/loopEnd sounds very inefficient.. ;)

Javier ideami
Ideami Studios
San Francisco / Barcelona
+1 408 634 9071
http://torchprinciple.com
http://ideami.com
http://posterini.com
http://incredivid.com
http://torchprinciple.com

On Thu, Oct 15, 2015 at 7:37 AM, James Simpson [email protected]
wrote:

You technically already have access to them with sprites. Even if you are
just playing one sound, you can define a sprint for it and adjust the start
and length, which then get used with loopStart and loopEnd internally.

—
Reply to this email directly or view it on GitHub
https://github.com/goldfire/howler.js/issues/360#issuecomment-148406045.

You don't change anything about your sound files for it to work.

interesting, thank you James, let me see if i understand, do you refer to
something like this:

var sound = new Howl({
src: ['whatever.mp3'],
loop:1,
sprite: {
main: [100, 1000]
}
});

sound.play('main');

is that how i would control loopStart and loopEnd?
so those 100 and 1000 would be the values of loopStart and loopEnd?

Javier ideami
Ideami Studios
San Francisco / Barcelona
+1 408 634 9071
http://torchprinciple.com
http://ideami.com
http://posterini.com
http://incredivid.com
http://torchprinciple.com

On Thu, Oct 15, 2015 at 7:46 AM, James Simpson [email protected]
wrote:

You don't change anything about your sound files for it to work.

—
Reply to this email directly or view it on GitHub
https://github.com/goldfire/howler.js/issues/360#issuecomment-148408611.

That is pretty close to right, but you'd want to define the sprite as [100, 1000, true] so that it is looping. Also, the way it is defined is [start, length, loop]. I'm going to reopen this for now so I can keep thinking about this one for the 2.0 release.

very cool, thanks a lot, i will make a test, so i will:

src: ['whatever.mp3'],
loop:1,
sprite: {
main: [100, 1000, true]
}

will test it right now

Javier ideami
Ideami Studios
San Francisco / Barcelona
+1 408 634 9071
http://torchprinciple.com
http://ideami.com
http://posterini.com
http://incredivid.com
http://torchprinciple.com

On Thu, Oct 15, 2015 at 7:55 AM, James Simpson [email protected]
wrote:

That is pretty close to right, but you'd want to define the sprite as [100,
1000, true] so that it is looping. Also, the way it is defined is [start,
length, loop]. I'm going to reopen this for now so I can keep thinking
about this one for the 2.0 release.

—
Reply to this email directly or view it on GitHub
https://github.com/goldfire/howler.js/issues/360#issuecomment-148410912.

tested and it works to perfection ;)
i have a loop of 12 seconds, before using this there was still a clear gap,
after using the sprite thing with limits of 0 and 12000 (12 seconds loop) ,
the gap has disappeared and plays perfectly, so your suggestion does work,
thank you ;)

Javier ideami
Ideami Studios
San Francisco / Barcelona
+1 408 634 9071
http://torchprinciple.com
http://ideami.com
http://posterini.com
http://incredivid.com
http://torchprinciple.com

On Thu, Oct 15, 2015 at 7:59 AM, Javier Ideami [email protected] wrote:

very cool, thanks a lot, i will make a test, so i will:

src: ['whatever.mp3'],
loop:1,
sprite: {
main: [100, 1000, true]
}

will test it right now

Javier ideami
Ideami Studios
San Francisco / Barcelona
+1 408 634 9071
http://torchprinciple.com
http://ideami.com
http://posterini.com
http://incredivid.com
http://torchprinciple.com

On Thu, Oct 15, 2015 at 7:55 AM, James Simpson [email protected]
wrote:

That is pretty close to right, but you'd want to define the sprite as [100,
1000, true] so that it is looping. Also, the way it is defined is [start,
length, loop]. I'm going to reopen this for now so I can keep thinking
about this one for the 2.0 release.

—
Reply to this email directly or view it on GitHub
https://github.com/goldfire/howler.js/issues/360#issuecomment-148410912
.

Hey guys!

I made this for a project I'm working on. I did everything you mentioned above. Would you mind taking a look and seeing if you see anything wrong? I am still getting a massive break in my loop. However, it is intermittent. It loops fine and then it doesn't. Not sure why. Thanks for the help!

// //<><><><><><>ALL SOUNDS IN THEIR BASIC FORM<><><><><><><><><><>//

// KICK
var kick = new Howl({
src: ['assets/audio/kick-mm.mp3'],
html5:true,
preload:true,
loop:1,
sprite:{
kick:[0,10000,true]
}
});
kick.play("kick");

// SNARE
var snare = new Howl({
src: ['assets/audio/snare-mm.mp3'],

html5:true,
preload:true,
loop:1,
    sprite:{
        snare:[0,10000,true]
    }

});
snare.play("snare");

// HATS
var hats = new Howl({
src: ['assets/audio/hats-mm.mp3'],
html5:true,
preload:true,
volume:0.4,
loop:1,
sprite:{
hats:[0,10000,true]
}
});
hats.play("hats");

// PERCUSSION
var percussion = new Howl({
src: ['assets/audio/percussion-mm.mp3'],
html5:true,
preload:true,
loop:1,

    sprite:{
        percussion:[0,10000,true]
    }

});
percussion.play("percussion");

// ARPEGIATOR
var arp = new Howl({
src: ['assets/audio/arp-mm.mp3'],
html5:true,
preload:true,
volume:0.3,
loop:1,
sprite:{
arp:[0,10000,true]
}
});
arp.play("arp");

// BASS
var bass = new Howl({
src: ['assets/audio/bass-mm.mp3'],
html5:true,
preload:true,
loop:1,
sprite:{
bass:[0,10000,true]
}
});
bass.play("bass");

// //<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>//

This was my solution

let gasLooper;
let gasSound = new Howl({
    preload:true
  , src: require('./assets/audio/Gas-loop.mp3')
  , autoplay: true
  , volume: 0.5
  , onplay: ()=>{
    gasLooper = setTimeout(()=>{
      gasSound.play();
    },450);
  }
  , onstop: ()=>{
    clearTimeout(gasLooper);
  }
});

using sprites for looping works great. Thank you for the suggestion @goldfire!

Wanted to offer a further iteration for those who need to loop when using sprites:

   sprites = {
      "bleep": [0, 1592],
      "boop": [0, 1509]
    }
    let looper = (type: AudioType, iterations: number = 1) => {
      sound.play(type);
      setTimeout(() => {
        sound.stop();
      }, (sprites[type][1] * iterations))
    };

This still does not work in any browser with any file format in either html5 or web audio mode.

I would disagree. Looping works fine here in m4a and ogg using WebAudio

That's a big nope. Tried all of the above suggestions. The only thing that appears to work with any kind of success is @huwllewellyn's suggestion. Out of the box, Howler (v2.1.3) plays the loop (ogg) with a half second delay. The behavior is the same across latest versions of Firefox, Chrome and Edge.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

FFankias picture FFankias  Â·  3Comments

indexofrefraction picture indexofrefraction  Â·  4Comments

Glutch picture Glutch  Â·  3Comments

rowild picture rowild  Â·  3Comments

joshbruce picture joshbruce  Â·  4Comments