Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trying to cross-fade audio clips #146

Closed
mknowlton opened this issue Apr 23, 2014 · 3 comments
Closed

Trying to cross-fade audio clips #146

mknowlton opened this issue Apr 23, 2014 · 3 comments

Comments

@mknowlton
Copy link

Hi there - I just recently started using howler.js and am really digging it. Great audio framework! I'm trying to work out a nice way to cross fade two different background audio files. So for instance when file1.mp3 is 1 second from being done, I start to play the file2.mp3.

I saw there is a method for getting the position of the audio being played but I can't figure out how to implement something like this. Do you have any advice or examples you would point me towards? Thanks in advance.

@christophemarois
Copy link

Hi! You will no choice but to manipulate the volumes of two Howler instances in a recursive function. The use case you described in your issue could be addressed that way:

var crossfadeDuration = 5000,
    volume            = 0.7;

var instance1, instance2, soundDuration;

// Singleton helper to build similar instances
var createHowlerInstance = function (urls, onload) {
  return new Howl({
    urls: urls,
    loop: false,
    volume: 0,
    onload: onload
  });
};

// Create "slave" instance. This instance is meant
// to be played after the first one is done.
instance2 = createHowlerInstance(['file2.mp3']);

// Create "master" instance. The onload function passed to
// the singleton creator will coordinate the crossfaded loop
instance1 = createHowlerInstance(['file1.mp3'], function(){

  // Get the sound duration in ms from the Howler engine
  soundDuration = Math.floor(instance1._duration * 1000);

  (function crossfadedLoop(enteringInstance, leavingInstance){

    // Fade in entering instance
    enteringInstance.pos(0).play().fade(0, volume, crossfadeDuration);

    // Wait for the audio end to fade out entering instance
    // white fading in leaving instance
    setTimeout(function(){

      enteringInstance.fade(volume, 0, crossfadeDuration);
      crossfadedLoop(leavingInstance, enteringInstance);

    }, soundDuration - crossfadeDuration);

  })(instance1, instance2);

});

@mknowlton
Copy link
Author

Thanks so much! Appreciate it.

@circus2271
Copy link

circus2271 commented Apr 19, 2022

maybe using a window.requestAnimationFrame function would also work. It's the same "recursion" idea
something like this:

var sound1 = new Howl({
  src: ["sound1.mp3"],
  volume: 0.15,
  onplay() {
    const crossfadingDuration = 5000;
    const crossfadeStartSecond =
      Math.round(this.duration()) -
      Math.round(crossfadingDuration / 1000);
    const currentSecondPlaying = () => Math.round(this.seek());
    let currentVolume = this.volume();
    //  sound1.seek(140); // optionally rewind 140 sec forward (to skip waiting until crossfade actually starts)
    const handleCrossfading = () => {
      const shouldCrossfade = currentSecondPlaying() >= crossfadeStartSecond;
      console.log({
        shouldCrossfade,
        currentSecondPlaying: currentSecondPlaying(),
        crossfadeStartSecond
      });

      if (shouldCrossfade) {
        sound1.fade(currentVolume, 0, crossfadingDuration);
        sound2.fade(0, currentVolume, crossfadingDuration);
        sound2.play();
        return; // end of this function
      }

      window.requestAnimationFrame(handleCrossfading);
    };

    handleCrossfading();
  },
  onfade() {
    this.stop();
    console.log("First song just ended");
  }
});

don't know, hope this is somewhat helpful

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants