Modifications

We've successfully created an interface for the playback of random sound clips! We can extend it easily to provide visual feedback about the duration of the loaded track, the play time remaining, the name of the playing clip, and the volume level.

To edit these additions, locate miniplayer-feedback.fla in the code archive.

  • Working from the previous example, add a new layer below the Actions layer, and name it Labels. This will hold our text labels, which provide feedback about what's going on.
  • Select the first frame of the Labels layer and create a new dynamic text field to the right of the volume buttons, as depicted in Figure 5.1. Name the instance volume.
  • With the text box selected, click Character? in the Property Inspector and select Basic Latin (All Characters in Flash MX). Click OK.
  • Referencing Figure 5.1 for placement, create the titles clip length and time remaining using static text areas.
  • Insert three dynamic text fields beside the relevant titles, naming the fields clipname, cliplength and timeleft. Repeat step 3 for each of the text boxes. Make sure each box is large enough to hold the required information.
  • Select the first frame of the Actions layer and replace the existing code with the following. The changes are extensive, but once again I've highlighted them in bold:
  • Example 5.7. miniplayer-feedback.fla Actions : 1

    function roundNumber(toRound, numDecimals) {
            return Math.round(toRound*Math.pow(10, numDecimals))/Math.pow(10, numDecimals);
    }
    function randomBetween(a, b) {
            return Math.min(a, b)+random(Math.abs(a-b)+1);
    }
    _root.createEmptyMovieClip("tracker", 1);
    PlayClip.onPress = function() {
            stopAllSounds();
            _root.orchestra = new Sound();
            var clipnumber = randomBetween(1, 5);
            _root.orchestra.attachSound("choir"+clipnumber);
            _root.orchestra.start();
            _root.tracker.onEnterFrame = function() {
                    _root.timeleft.text = roundNumber((_root.orchestra.duration-_root.orchestra.position)/1000, 2)+" seconds";
            };
            _root.cliplength.text = roundNumber(_root.orchestra.duration/1000, 2)+" seconds";
            _root.clipname.text = "Choir"+clipnumber;
            _root.volume.text = _root.orchestra.getVolume();
    };
    StopClip.onPress = function() {
            stopAllSounds();
            _root.orchestra = null;
            _root.cliplength.text = "";
            _root.clipname.text = "";
            _root.timeleft.text = "";
    };
    VolumeUp.onPress = function() {
            if (_root.orchestra.getVolume()<100) {
                    _root.orchestra.setVolume(_root.orchestra.getVolume()+10);
                    _root.volume.text = _root.orchestra.getVolume();
            }
    };
    VolumeDown.onPress = function() {
            if (_root.orchestra.getVolume()>0) {
                    _root.orchestra.setVolume(_root.orchestra.getVolume()-10);
                    _root.volume.text = _root.orchestra.getVolume();
            }
    };

     

    Let's dissect the changes we've made, so we understand how it all works!

    First, we introduce a new math function, roundNumber, which rounds figures to a specified number of decimal places. This will be used to show both the play time remaining for each clip and the clip's total duration.

    function roundNumber (toRound, numDecimals)
    {
            return Math.round (toRound * Math.pow (10, numDecimals)) /
            Math.pow (10, numDecimals);
    }

     

    We'll be updating the track time remaining with each frame of the movie, so we'll need an onEnterFrame event handler. Unfortunately, we don't have any obvious movie clip to hook that handler to. We could attach it to one of the buttons in our interface, but it's tidier to create an empty movie clip called tracker to host it:

    _root.createEmptyMovieClip ("tracker", 1);

     

    We then add the following code to the PlayClip button's onPress handler that sets up the event handler itself:

     

    _root.tracker.onEnterFrame = function ()
    {
            _root.timeleft.text = roundNumber ((_root.orchestra.duration - _root.orchestra.position) / 1000, 2) + " seconds";
    };

    This continuously updates the timeleft dynamic text field we created earlier. We constantly monitor the position of the sound clip using the duration and position properties of the Sound object, calculating the remaining time in milliseconds. We then convert this to a value in seconds, rounding to two decimal places with the help of our roundNumber function.

    We also update the other dynamic text fields that hold the length of the clip being played, its name, and its volume.

     

    _root.cliplength.text = roundNumber (_root.orchestra.duration / 1000, 2) + " seconds";
    _root.clipname.text = "Choir" + clipnumber;
    _root.volume.text = _root.orchestra.getVolume ();

    Within the StopClip button's onPress event handler, we include the following code, which clears the dynamic text fields of the information associated with the clip played previously:

    _root.cliplength.text = "";
    _root.clipname.text = "";
    _root.timeleft.text = "";

     

    Finally, the VolumeUp and VolumeDown onPress event handlers are updated. This ensures that any changes to the clip's volume are reflected in the volume dynamic text field.

    _root.volume.text = _root.orchestra.getVolume ();

     

    That's it for the code changes.

  • Save your Flash document and preview it.
  • There! We have a fully-fledged random clip player that provides information on the duration of the current clip, its name, and the play time remaining.

    This example can easily be extended through the addition of more clips to the library. Export them for ActionScript reference, and alter the code that selects the clip to play within the PlayClip button's onPress event handler.

    Use an array!
    A useful variation would be to store the linkage names of available clips in an array, so that the number of clips available would not have to be hard-coded.