DekGenius.com
[ Team LiB ] Previous Section Next Section

Recipe 13.15 Fading Out a Sound

13.15.1 Problem

You want to fade out a sound over a span of a number of milliseconds.

13.15.2 Solution

Create and invoke a fadeOut( ) method.

13.15.3 Discussion

As with fading in a sound, there is no built-in functionality for fading out a sound. However, you can create a custom fadeOut( ) method to handle this task. Our custom fadeOut( ) method is slightly longer than the fadeIn( ) method, but it utilizes similar logic. In addition, the fadeOut( ) method allows you to use two callback functions: one that is called when the sound begins to fade out, and another that is called when the fade out has completed. This can be useful in situations in which you want a particular action or actions to occur when the fade out begins and/or ends. For example, you may want to begin the playback of a second sound when the first begins to fade out. As the second sound fades in, you achieve a cross-fade effect.

As with the fadeIn( ) method, the fadeOut( ) method works only with sounds that are created using our custom createNewSound( ) method.

The fadeOut( ) method accepts up to five parameters:

millis

The number of milliseconds over which the sound should fade out.

minVol

The volume percentage to which the sound should fade (default is 0).

maxVol

The volume percentage from which the sound should start fading (default is current volume).

startTime

The point (in milliseconds) in the sound that the fade out should begin. If no value is specified, the fade out begins millis milliseconds before the end of the sound (so that it completes when the sound ends).

stopSound

A Boolean indicating whether the sound should stop when the fade is done (default is false).

Add the following custom fadeOut( ) method to your external Sound.as file for easy inclusion in other projects:

Sound.prototype.fadeOut = function (millis, minVol, maxVol, startTime, stopSound) {

  // If startTime is undefined, fade the sound out at the very end.
  startFadePos = (startTime == undefined) ? this.duration - millis : startTime;

  minVol = (minVol == undefined) ? 0 : minVol;
  maxVol = (maxVol == undefined) ? this.getVolume(  ) : maxVol;
  
  // The madeCallback property is initialized to false. This property is set to true 
  // when the fade-out-start callback function has been invoked. It ensures that the
  // callback is called once and only once, when the fade out begins.
  this.madeCallback = false;
  
  // Invoke the custom monitorFadeOut(  ) method every 100 milliseconds.
  this.monitorFadeOutInterval = setInterval(this, "monitorFadeOut", 100, millis,
                                     startFadePos, minVol, maxVol, stopSound);
};

Sound.prototype.monitorFadeOut = function (fadeOutMillis, startFadePos, minVol,
                                            maxVol, stopSound) {
  var pos = this.position;
  var dur = this.duration;

  // Execute the fade out once the desired point in the sound is reached.
  if (pos >= startFadePos) {

    // Call the fade-out-start callback function if it has not been called yet.
    if (!this.madeCallback) {
      this.madeCallback = true;
      this.onFadeOutStartPath[this.onFadeOutStartCB](  );
    }

    // If the ending fade out position has been reached, clear the interval so as 
    // not to needlessly monitor the sound anymore.
    if (pos >= dur || pos >= startFadePos + fadeOutMillis) {

      // Make sure the volume is set to the minVol before terminating the fade.
      this.setVolume(minVol);
      clearInterval(this.monitorFadeOutInterval);
    }

    // Set the volume based on the current sound position, fading to minVol over the
    // specified time span. The fade occurs relative to maxVol.
    var volumePercent = ((startFadePos + fadeOutMillis) - pos) / 
                          fadeOutMillis * maxVol;

    // If the volume reaches minVol, call the fade-out-stop callback, clear the
    // interval, and, if appropriate, stop the sound.
    if (volumePercent <= minVol) {
      volumePercent = minVol;
      this.onFadeOutStopPath[this.onFadeOutStopCB](  );
      clearInterval(this.monitorFadeOutInterval);
      if (stopSound) {
        this.stop(  );
      }
    }

    // Set the volume of the sound.
    this.setVolume(volumePercent);
  }
};

// The setOnFadeOutStop(  ) and setOnFadeOutStart(  ) methods allow you to define
// callback functions to invoke when the fade starts and stops. The parameters are a
// string specifying the function name and an optional path to the function. If path 
// is undefined, the Sound object's parent property is used instead. The parent 
// property is defined only if you use the custom createNewSound(  ) method to create
// the sound.
Sound.prototype.setOnFadeOutStop = function (functionName, path) {
  this.onFadeOutStopPath = (path == undefined) ? this.parent : path;
  this.onFadeOutStopCB = functionName;
};

Sound.prototype.setOnFadeOutStart = function (functionName, path) {
  this.onFadeOutStartPath = (path == undefined) ? this.parent : path;
  this.onFadeOutStartCB = functionName;
};

You can use the fadeOut( ) method to fade out any sound created using our custom createNewSound( ) method. Note that the fadeOut( ) method merely queues the sound to fade. You must start the sound using Sound.start( ).

#include "Sound.as"

mySound_sound = Sound.createNewSound(  );

// Attach a sound from the Library.
mySound_sound.attachSound("MySoundSymbol");

// Fade out the sound over 5,000 milliseconds (5 seconds) at the end of the sound.
mySound_sound.fadeOut(5000);

// Start the playback of the sound.
mySound_sound.start(  );

The preceding example does not use the callback functions. Here is an example that uses callbacks, which will be notified when the sound fade out begins and ends:

#include "Sound.as"

mySound_sound = Sound.createNewSound(  );

mySound_sound.attachSound("MySoundSymbol");

// Tell the sound to fade out over 5000 milliseconds (5 seconds) starting when the
// sound's playback position is at 20,000 milliseconds (20 seconds).
mySound_sound.fadeOut(5000, 0, 100, 20000);

// Define callback functions.
function doWhenFadeOutStart(  ) {
  trace("Sound fade out has begun");
}

function doWhenFadeOutStop(  ) {
  trace("Sound fade out has completed");
}

// Set the callback functions for the sound.
mySound_sound.setOnFadeOutStart("doWhenFadeOutStart");
mySound_sound.setOnFadeOutStop("doWhenFadeOutStop");

// Start the playback of the sound.
mySound_sound.start(  );

13.15.4 See Also

Recipe 13.14

    [ Team LiB ] Previous Section Next Section