Using Director to Create Interactive Multimedia Examples
for the Music Classroom

©Dr. Scott D. Lipscomb, Associate Professor

Northwestern University School of Music
lipscomb@northwestern.edu

Web Site Related to this Presentation:
http://faculty-web.at.northwestern.edu/music/lipscomb/imea2002/

Using Director’s Built-in “Behaviors”

Basic Director Terminology
Playing a Sound (use “PlaySoundTemplate.dir”)
Rollovers (use “MouseOverTemplate.dir”)

Fundamentals of Digital Sound

File Formats
Sample Rate

§         For best results and to ensure cross-platform compatibility, use sounds that have 16-bit depth and a sampling rate of 44.1, 22.050, or 11.025 kHz.  The higher the sampling rate, the better the sound quality.

Sound Bit Depth

§         For best results, use 16-bit sounds only

Stereo vs. Mono

§         Reducing a sound to mono immediately reduces the file size by half; this is a good idea unless you have special requirements for which the stereo image is necessary

Calculating Audio File Size (in bytes)
Audio Compression

As you will find when using the calculator referenced above, files can become very large quickly.  In order to reduce the file size, you may wish to consider the possibility of using some form of compression.  Just like with graphic formats like JPEG, there is always a trade-off between the resulting quality of the compressed file and its size.  Small file sizes can equate to terrible sounding audio.

Another possibility you may wish to consider is streaming the audio to your listeners instead of having them wait for an entire file to download.  For details on this process and to find a comparison of the various file formats and streaming media, you can access the resource created for my recent presentation at the Conference of the Association for Technology in Music Instruction at: http://faculty-web.at.northwestern.edu/music/lipscomb/atmi2001/

Adding a Background Sound (use “BackgroundSoundTemplate.dir”)

Triggering Sound

puppetSound command

When using this method, a sound channel is made a “puppet,” allowing Lingo (Director’s scripting language) to “pull the strings,” overriding instructions in the Score.  To play a sound, you use the following syntax:  the command followed by two parameters (sound channel number and either the number or name of the sound cast member)

puppetSound 1, “Beep” -- where “Beep” is the name of a cast member

puppetSound 1, 4 -- where 4 is the number of the sound cast member

To cause a sound to stop playing, send the puppetSound command with the sound channel number and “0” as the second parameter

puppetSound 1, 0

Adding puppetSound to Your Movie  (Use “puppetSoundTemplate.dir”)

end

o       This script causes the cast member named “Bach” to play on sound channel number 3

Now, let’s add the behavior to stop playback of the sound file (less details will be provided for this process … if necessary, refer to the more detailed instructions above)

§         Click on the sprite labeled “Stop Sound

o       The Behavior Inspector should still be open; if not, follow directions above

§         From the “Behavior Popup” menu, select “New Behavior…” and type “Stop” into the text entry box

§         From the “Event Popup” menu, select “mouseUp

§         From the “Action Popup” menu, select Sound®Play Cast Member

o       I know, I know … you’re wondering “Why should I select “Play Cast Member,” when what I really want to do is stop the sound file from playing?”  We’ll take care of it in the next step …

§         Double-click on the cast member named “Stop” so the Behavior script opens.

on mouseUp me

  puppetSound 3, 0

end

You will notice as you play around with this movie that every time you click on the “Start Sound” button, Bach’s Toccata and Fugue in D minor starts playing at the beginning … in fact, it might be just repetitive enough to drive you absolutely bats within a couple of minutes.  What if, instead, you want the sound file to pause when the”Stop” button is pressed and resume playback when the “Play “button is pressed?  You’re undoubtedly thinking … “There’s got to be an easy way” … and you’re almost right.  It’s not exactly easy, but it’s not that hard either … so let’s do it …

§         Using the file you created in the previous section as a starting point, we need to make a couple of minor adjustments, requiring that you actually type some code into a script.  Don’t be intimidated … just roll up your sleeves and take a deep breath.  Remember, you learned to play a musical instrument … you can do anything!!!  [It may help to keep saying that over and over throughout the next section.]

§         First, double-click on the cast member named “Play”.  When the script window opens, edit the text, so that it reads exactly as follows:

on mouseUp me

  sound(3).play()

end

on mouseUp me

  sound(3).pause()

end

on startMovie

  puppetSound 3, "Bach"

  sound(3).pause()

end

Types of Scripts (or “Why Do I Need to Know This Stuff?”)

Sometimes the type of script you create can mean the difference between a working movie and one that almost works!  For example, if the “startMovie” script you created above were a Behavior script instead of a Movie script, the sound would not have played … though the buttons would happily perform their mouseOver and mouseDown image functions.  [Go ahead, try it … I’ll wait.]  As a result, it is a fairly important topic to understand.  Outlined below, are the basic differences between the script types (in Director 8.5).  For the sake of clarity—I tend toward verbosity, if you haven’t noticed—I have extracted these definitions verbatim from the Director documentation and provide them here for your convenience:

 

**********************************

Director uses four types of scripts: behaviors, movie scripts, parent scripts, and scripts attached to cast members. Behaviors, movie scripts, and parent scripts all appear as cast members in the Cast window.

 

Behaviors—are scripts that are attached to sprites or frames in the Score, and are referred to as sprite behaviors or frame behaviors. The Cast window thumbnail for each behavior contains a behavior icon (“ ”) in the lower right corner.  When used in [the Director documentation], the term "behavior" refers to any Lingo script that you attach to a sprite or a frame. This differs from the behaviors that come in Director's Library Palette.  All behaviors that have been added to the cast appear in the Behavior Inspector's Behavior pop-up menu. (Other types of scripts don't appear there.) You can attach the same behavior to more than one location in the Score. When you edit a behavior, the edited version is applied everywhere the behavior is attached in the Score.

 

Movie scripts—respond to events such as key presses and mouse clicks, and can control what happens when a movie starts, stops, or pauses. Handlers in a movie script can be called from other scripts in the movie as the movie plays.  A movie script icon (“ ”) appears in the lower right corner of the movie script's Cast window thumbnail.  Movie scripts are available to the entire movie, regardless of which frame the movie is in or which sprites the user is interacting with. When a movie plays in a window or as a linked movie, a movie script is available only to its own movie.

 

Parent scripts—special scripts that contain Lingo used to create child objects. You can use parent scripts to generate script objects that behave and respond similarly yet can still operate independently of each other. A parent script icon (“ ”) appears in the lower right corner of the Cast window thumbnail.

 

Scripts attached to cast members are attached directly to a cast member, independent of the Score. Whenever the cast member is assigned to a sprite, the cast member's script is available.  Unlike behaviors, movie scripts, and parent scripts, cast member scripts don't appear in the Cast window. However, if Show Cast Member Script Icons is selected in the Cast Window Preferences dialog box, cast members that have a script attached display a small script icon (“ ”) in the lower left corner of their thumbnails in the Cast window.

**********************************

soundBusy command (use “soundBusyTemplate.dir”)

At times, you may want elements (sprites) of your movie to behave differently when a sound is playing than they do when no sound is present.  Lingo provides a way to determine if a specific sound channel is currently occupied with a sound file (in addition to actually playing the file, it could be temporarily paused, i.e., still “busy”).  The soundBusy command allows you to easily test for this property.

§         Open the “soundBusyTemplate.dir” file

§         Double-click on Frame 1 of the Score’s Script channel

o       In the empty script window that appears, type the following text:

on exitFrame me

  if soundBusy(3) then

    --Play button

    sprite(1).visible = FALSE

    --Play label

    sprite(3).visible = FALSE

    --Stop button

    sprite(2).visible = TRUE

    --Stop label

    sprite(4).visible = TRUE

  else

    --Play button

    sprite(1).visible = TRUE

    --Play label

    sprite(3).visible = TRUE

    --Stop button

    sprite(2).visible = FALSE

    --Stop label

    sprite(4).visible = FALSE

  end if

end

o       Notice that, each time the score’s playback head exits frame 1, this If … then statement tests whether the sound file is currently “in action” by using the soundBusy command.  If the sound channel is currently in use [i.e., soundBusy(3) = TRUE], then the visible property of both the Play button and the Play button label are set to FALSE, while the visible property of both the Stop button and the Stop button label are set to TRUE.  If the sound channel is not currently in use (i.e., the sound file has been stopped, the visible property of both the Play button and the Play button label are set to TRUE, while the visible property of both the Stop button and the Stop button label are set to FALSE.

This command is also useful if you need to have more than one sound playing simultaneously.  Director allows up to eight sounds to be playing simultaneously.  However, if a sound is playing in a given channel and another sound is played using the same channel, the first sound file is interrupted.  The first sound file will not begin playing again, even after the second file stops.  As a result, it may be wise to create a routine that provides you with the capability to perform a search for a channel that is not busy (see “soundBusyFindChannel.dir”):

on getChannel

  repeat with channel = 8 down to 0

    if soundBusy(channel) then

      --do nothing

    else

      exit repeat

    end if

  end repeat

 

  --You, of course, will want to do something more useful

  --  with this information.

  if channel = 0 then

    alert "All channels are busy ... please, try back later."

  else

    alert "You may use channel " & channel & "."

  end if 

end

soundDevice and soundDeviceList commands

In most cases, you can leave the soundDevice setting at its default setting.  On Macintosh computers, in fact, there is only a single soundDevice … the MacSoundManager (the only one you need).  Windows computers might have as many as three devices available.  In order of preference due to the quality of reproduction, these are DirectSound, QT3Mix, and MacroMix.  If you wish to see which devices are available on your computer, simply type the following into the Message window:

put the soundDeviceList

Adjusting the Loudness of Your Sound Files

Director allows you to change the volume during playback in two ways: a global adjustment that alters the sound level of all sounds on your computer (the soundLevel) or setting the level for a specific sound channel in Director (the volume).  You can also use the soundEnabled property to turn all sounds on or off.

the soundLevel

If your movie makes a global adjustment to the sound level, it is wise to save the current level when your movie starts, so you can return the system to the same level when your movie completes

on startMovie

  --save the current system sound level

  currentLevel = the soundLevel

 

  --set the level for your movie (from 1 to 7)

  the soundLevel = 5

end

on stopMovie

  --return the system to its previous level

  the soundLevel = currentLevel

end

the volume

The volume level for a sound channel can be set to any value between 0 and 255.  You can use either the verbose or dot-syntax version:

the volume of sound 3 = 225

or

sound(3).volume = 225

As you develop cross-platform applications you should be aware that sound levels are nowhere near consistent across—or even within—platform.

fadeIn and fadeOut commands (use “FadeInFadeOutTemplate.dir”)

These two commands allow you to effectively blend sounds by fading them in and out.  You simply identify the channel you wish to operate upon and the amount of time (in milliseconds [7] ) that you want the fadeIn or fadeOut to take.  Let’s add this capability to our Start & Stop button movie.

sound(3).fadeIn(5000)

Synchronizing Sound (use “SonataFormTemplate.dir”)

One of the most impressive ways that the sound capabilities of Director can be utilized in an educational context is the synchronization of the audio and visual components.  In order to take advantage of these capabilities, you must use an external sound editor (Sound Forge or Cool Edit on the Windows platform or SoundEdit 16 or Peak on the Macintosh) to add “markers” to the sound file.  Taking full advantage of these markers—or “cuePoints,” as they are called in Director—will be much easier if you assign meaningful names.  [Demo Sound Forge]

Once you have added markers to your sound file and saved it (preferably in either AIFF or WAV format), import the sound file into your Director movie.  You can now use some powerful techniques to access your sound file, navigate to a specific location, or cause events to occur based on the position of the playback head within the sound file.  The primary tools provided for this purpose are:

on cuePassed—this message is sent each time a cuePoint is passed.  The parameters passed by the message include the channel number, the cue number (i.e., the nth marker contained in the sound file), and the current marker name.  The “SonataFormTemplate.dir” movie uses this message to great advantage, as you will see below.

mostRecentCuePoint—this property gives you access to the name of the cuePoint passed most recently, using the following syntax to save this information in a variable named “marker”:

marker = sound(3).mostRecentCuePoint

isPastCuePoint—this function can be used in two ways, using an integer or name to represent the cuePoint:

--using an integer results in a value of TRUE if the

--  cuePoint has been passed or FALSE if not

sound(3).isPastCuePoint(1)

--using a cuePoint name, the function returns the number

--  of times the cuePoint has been passed

sound(3).isPastCuePoint("Introduction")

In the excerpted script below, each text item representing a section of the sonata form movement on the stage is set to black italic font, except for the text referencing the current marker position which is set to red bold-faced type:

on cuePassed channel, cueNumber, cueName

  --set all headings to normal text

  --  cast members 7-21 are text labels for

  --  each section of the sonata form movement

  repeat with counter = 7 to 21

    if member(counter).color = rgb(170,170,170) then

      --do nothing

    else 

      member(counter).fontStyle = [#italic]

      member(counter).color = rgb(0,0,0)

    end if

  end repeat

 

  --set color of current section to red, bold-face font

  if cueName <> "End" then

    member(cueName).fontStyle = [#bold]

    member(cuename).color = rgb(255,0,0)

  end if

end

The cuePointNames and cuePointTimes properties provide easy access to a list of all of the marker names and times contained in a sound file.  These can easily be stored in a list for later access, as shown below for a sound in channel 1:

gListMarkerNames = member(1).cuePointNames

gListMarkerTimes = member(1).cuePointTimes

When any text item representing a section of the sonata form movement on the stage receives a mouse click, the following script simply cycles through the list of marker names contained in the global list of marker names (gListMarkerNames) until it finds the one that matches the MarkerName argument.  This argument is simply the cast member name associated with the sprite that was clicked … a result of careful planning.  Once a match is found, the “counter” value is retained by “exiting” the repeat structure and that same value is used to access the appropriate time value from the global list of marker times (gListMarkerTimes).  This time value is then used as the #StartTime parameter of the sound object’s play() function. [9]

global gListMarkerNames, gListMarkerTimes

on setPlaybackPos MarkerName

  repeat with counter = 1 to gListMarkerNames.count

    tmp = getAt(gListMarkerNames, counter)

    if tmp = MarkerName then exit repeat

  end repeat

 

  MarkerTime = getAt(gListMarkerTimes, counter)

 

  sound(1).play([#member: member(1), #StartTime: MarkerTime])

end

Using “SonataFormTemplate.dir

Templates are a valuable time saver.  If you ever create something that you intend to use over & over, consider creating a template that allows you to create alternate versions in a matter of minutes.  One example is provided below.  The sonata form template is available to you online at: http://faculty-web.at.northwestern.edu/music/lipscomb/imea2002/.

Follow these simple steps:

Introduction

ExpPrimaryTheme

ExpTransition

ExpSecondThemeGroup

ExpClosingTheme

ExpPrimaryTheme2

ExpTransition2

ExpSecondThemeGroup2

ExpClosingTheme2

Development

RecapPrimaryTheme

RecapTransition

RecapSecondThemeGroup

RecapClosingTheme

Coda

End

Creating a Shockwave Version of Your Movie

It takes only a single mouse click and a filename!!

 

Contact Information:

Dr. Scott D. Lipscomb

Northwestern University

School of Music, MAB 119

711 Elgin Road

Evanston, IL  60208

lipscomb@northwestern.edu

http://faculty-web.at.northwestern.edu/music/lipscomb/


Useful References

Books

Gross, Phil (1999). Macromedia Director 7 and Ligo Authorized. Berkeley, CA: Macromedia Press.

Roberts, Jason & Gross, Phil (1999). Director 7 Demystified: The Official Guide to Macromedia Director, Lingo, and Shockwave. Berkeley, CA: Macromedia Press.

Steinhauer, Lauren (1997). Macromedia Director 6 for Dummies. Chicago, IL: IDG Books Worldwide

Web Sites & Listservs

Chinwag Discussion List for Developers Using Shockwave and Director Tools
http://www.Chinwag.com/html/mailing_lists_o.html

Direct-L Listserv
To subscribe, send an email message consisting of solely the following two lines (no subject and no signature file) to: listserv@uafsysb.uark.edu
SUBSCRIBE DIRECT-L [your name and email address]
SET DIRECT-L DIGEST

Director Demystified Web Site
http://www.demystified.com

Director Online
http://www.xtramedia.com/lingoTips.shtml

Director Technotes
http://www.macromedia.com/support/director/ts/nav/
http://www.macromedia.com/support/director/dev_index.fhtml

Director Web
http://www.mcli.dist.maricopa.edu/director/

Lingo Help: DaLingoKid
http://www.jervo.com/pages/dalingokid.html

Lingo-L Listserv
http://www.penworks.com/LUJ/lingo-l.cgi

Lingo Users Journal
http://www.penworks.com/LUJ/index.html

ShockRave
http://www.Shockrave.com

UpdateStage
http://www.updatestage.com



[1] There are problems with using external files about which you, as a creator, must be aware.  First, there are cross-platform issues due to the use of “\” on the PC and “:” on the Mac in the path to the file.  Second, the external file must exist on any computer upon which your movie is played … in the exact same location on the hard drive.  Generally, it is much wiser to use internal sounds unless you are using extremely large sound files that will be distributed with your movie and/or you are an advanced user who clearly understands the processes involved.

[2] Though there is an image called “Button-over.gif” in the template created for this presentation, when you create your own movies, you will need to create versions of each image for each interactive feature you wish to incorporate (e.g., mouseovers, mouse down, etc.).  There are several programs that make this process extremely easy, e.g., Macromedia Fireworks, Adobe ImageReady, etc.

[3] It is important that you use sound channel number 2, since the button sounds we created previously are in sound channel number 1.  If you also place the background sound in sound channel 1, then it will be interrupted when any of the mouse sounds occur

[4] This is generally a better idea than using the mouseDown event, since it allows the user to change her/his mind after clicking the mouse by moving the mouse away from the sprite before releasing the mouse button.

[5] To view the contents of the Behavior Script, simply double-click on the cast member named “Play”

[6] You should be aware that there is a “sissy” way to write many scripts using what Lingo refers to as its “verbose” form.  For example, instead of writing sound(3).volume = 150, to change the loudness level of sound channel 3, you could write set the volume of sound 3 to 150.  However, as you begin to utilize more advanced capabilities, there is rarely a verbose alternative.  Learning the “dot syntax” described above will pay off.

[7] Previous versions of Director used “ticks” (1/60th of a second) instead of milliseconds.

[8] okay, okay … the verbose version would be sound fadeIn 3, 300.  Notice that, instead of milliseconds, when using this version you must calculate the number of “ticks” (1/60th of a second).

[9] The play() function used previously has many optional parameters, providing a great deal of control of sound playback, including StartTime and EndTime.  The complete list of parameters is: sound(channelNum).play([#member: member(whichmember), {#startTime: milliseconds, #endTime: milliseconds, #loopStartTime: milliseconds, #loopEndTime: milliseconds, #loopCount: numberOfLoops, #preloadTime: milliseconds, #rateshift: shiftAmount}])