Articles Archive
Articles Search
Director Wiki
 

Creating your own sound controls

February 12, 2001
by Will Turnage

Dear Multimedia Handyman,

I have this project coming up where I need to control MP3 files. I only need simple controls like play, pause and stop. Also, it needs a slider bar that automatically moves as the song is playing. Thanks,

Andrew Akeroyd

Dear Andrew,

In previous versions of Director, controlling sounds in Lingo was often an imprecise and frustrating art. However, Director 8 offers some new sound functions that allow you to control sounds with more ease and precision.

The first thing you should do in your code is prepare the sound you want to play. The Lingo function queue preloads your sound into memory so that it can be played instantly when necessary.

sound (1).queue (member "mysound")

You can also find out what's going on with the sound channel at any time by checking the Lingo property status. This property is helpful in determining if a sound is present, preloaded, playing, paused, or stopped.

put sound (1).status
-- 2

There are five possible values for the status of a sound.

0 - The sound channel is idle; no sounds are queued or playing.

1 - The queued sound is being preloaded into the sound channel, but is not yet playing.

2 - The queued sound is finished loading into memory, but the sound has not been played yet.

3 - The queued sound is playing in the sound channel.

4 - The queued sound is paused in the sound channel.

Once your sound has been preloaded into the sound channel, then there are four different lingo commands you can use to control the sound: play, pause, rewind and stop.

sound (1).play ()
plays the first queued sound in sound channel 1.
sound (1).pause ()
if a sound is playing in sound channel 1, then this pauses the sound.
sound (1).rewind ()
rewinds the sound in sound channel 1 to the beginning. This function works if the sound is playing or if the sound is paused.
sound (1).stop ()
stops the sound in sound channel 1 from playing. This command also removes the sound from the queue.

So now that you've got the basics on preloading and playing a sound in the sound channel, you can start building the slider bar for your audio player. You can start with a simple slider like this

The slider bar has two tasks. First, the ball (also known as a thumb) should move along the slider as the sound plays. Second, the user should be able to drag the ball anywhere along the slider, then have the sound play from that approximate point.

To make the ball move along the slider as the sound plays, you'll need to use the currentTime property of the sound channel. This property returns a millisecond value of the exact point where the sound is playing. So a simple behavior could contain code like this:

on prepareFrame me
  if sound (1).isBusy () then
    percentPlayed = sound (1).currentTime / member ("mySound").duration
    newLocH = ((sprite (1).right - sprite (1).left) * percentPlayed) + sprite (1).left
    sprite (2).locH = newLocH
  end if
end

This code checks every frame to see if sound channel 1 is busy. The isBusy () function will return true if a sound is playing or paused in the sound channel, and will return false if no sound is queued or a sound is stopped. If a sound is playing or paused in sound channel 1, then the code divides the currentTime by the total duration of the sound. This number is the percentage of the sound that has played so far. Once you have that percentage, you can use it to calculate how far along the slider the ball should be displayed.

To make the ball move and back and forth on the slider, you would just use code in your behavior similar to this:

property pMouseFlag


on beginSprite me

  pMouseFlag = false

end


on prepareFrame me

  if pMouseFlag then
    tempH = the mouseH
    if tempH < sprite (1).left then tempH = sprite (1).left
    if tempH > sprite (1).right then tempH = sprite (1).right
    sprite (me.spriteNum).locH = tempH
  end if

end


on mouseDown me

  sound (1).stop()
  pMouseFlag = true

end


on mouseUp me

  pMouseFlag = false
  percentPlayed = float(sprite (me.spriteNum) - sprite (1).left) / float(sprite (1).right - sprite (1).left)
  pCurrentTime = percentPlayed * member ("mySound").duration
  sound (1).queue ([#member: member ("mySound"), #startTime: pCurrentTime])

end

This behavior stops the sound completely when you click on the ball. On every frame, it checks to see if the mouse is being held down. If so, then it moves the ball along the slider within the constraints of the sprite's left and right boundaries. Finally, when you release the mouse button, the code calculates the percentage of how far the ball is along the slider. It multiplies this percentage by the total duration of your sound, and it determines a new currentTime.

Finally, it queues your sound in the sound channel, but this time it specifies the exact startTime at which the sound should begin. In addition to the startTime, you can also specify an endTime and even define sound loops to play over and over. For more information on those functions, read the Director help section on the Lingo function queue.

A sample Director 8 movie is available for download in Macintosh or Windows format.

Will Turnage is a multimedia programmer based in New York City. In addition to his weekly role as Director Online's Multimedia Handyman, he is also the Technology Director for Sony Music's Client Side Technologies Group. You can read more about his work at http://will.turnage.com/.

Copyright 1997-2024, Director Online. Article content copyright by respective authors.