Foreword
Storing all the sound contents of your web site inside a Flash movie is a very efficient way to sonify a site. The main advantage of this approach is that you have a single resource to extract sound data from, thus simplifying programming. What you are going to learn in this document is how to create a framework that eases the update of the sound contents and allows you to keep up with layout and content changes made to a web site.
To follow this document it is strongly recommended that you have a working knowledge of JavaScript programming, Flash movie creation and HTML syntax. Although this document is not intended to provide you with copy and paste JavaScript code, the essential code needed to create this framework is provided and the logic behind it is explained. Of course this document is not for the casual programmer but, we think that the explanations given here will give you a good jumpstart to sonify and maintain sonified web sites easily.
Another thing, the code provided here is given as an example without warranties to be useful, accurate, concise, elegant or fit your programming needs. Use it at your own risk without Soundtown or me being liable for any loss of data, malfunctioning of your computer or code or whatever bad thing happens to you or your equipment. This code is given free for educational purposes only and should not be used in commercial applications. Also, all trademarks in this text are property of their respective owners and Soundtown does not claim any right on them. That¡¯s enough for a foreword, let¡¯s get to work.
Overview
It is not new that a single Flash Movie can be employed to sonify a web site; usually you assign each link and image in a web page a start frame number inside the Flash movie and play the movie from the selected frame in response to a mouse (or keyboard) event. This method involves calling the Flash movie from an event handler and passing the frame number from which you want to start playing.
One caveat of this approach is that whenever you modify the Flash movie to incorporate new sounds or replace or modify existing sounds you might experience that the frame numbers you are referencing from your code are no longer valid and you have to modify your calls. This could be very annoying in big web sites and a huge waste of time.
Our approach is to use Movie Clips inside a Flash movie to store sounds and use scripting for the Flash ActiveX control or Plug-In to start and stop those sounds. Also, these Movie Clips will not be referenced by frame number but instead will be referenced by name and the whole idea is to have a unique name for each movie clip that naturally relates to some attribute in the HTML tags (in this case <A> and <IMG> tags).
In case you have to add sounds or modify the existing sounds, the relationship between the HTML elements and the Movie Clips won¡¯t be broken and you won¡¯t have to worry about frames misplaced.
We think that our approach is more natural than referencing frame numbers and, using attributes from HTML tags eases updates. Also you will see the benefits of storing programming logic inside external code libraries so the amount of modifications to the HTML code is minimal.
The basic framework
To sonify a site we will need the following elements:
- An invisible frame to hold the Flash embed(s).
- A JavaScript code library to hold all of the sonification code.
- A Flash movie to hold the sounds.
- Functions inside the code library to make the sound start and stop.
- Simple event handlers to call the sound functions.
Inside the Flash movie we will insert all the sounds needed for the web site, using this movie as a ¡®soundbank¡¯ that holds the sound resources. The JavaScript code library will serve as a repository for the code, allowing us to make any changes needed in a single place. The functions will enable sound, basically the functions will play and stop sounds when called. The invisible frame will help to avoid embedding multiple instances of the Flash movie and will allow smooth sound transitions between pages. The event handlers will call the sound functions when an event is triggered, these event handlers will be simple and easy to integrate with the HTML code.
Creating the Invisible Frame
You are asking yourself, Why use an invisible frame?. The answer is: it is not mandatory but, an invisible frame allows to keep the Flash Movie(s) in a single place and avoids the need to embed movies in every single web page that needs sound. Also, the invisible frame makes it easy to control the loading process for the sounds and eliminates the case when you load a sonified web page without the sounds ready to play, which leads in the best case to your users not being able to enjoy your sound work and in the worst case your users get ugly error messages.
Keep in mind that some problems arise when you use this method, for example, you have to be careful with the target property for your pages so your frame doesn't get overwritten and, if you are linking to pages outside your web site, you have to make sure that your frame does not ¡®parasite¡¯ them.
Both minor difficulties can be easily solved with a bit of JavaScript and examination of the HTML code.
To create an invisible frame you'll use HTML code like this:
<html>
<head></head>
<frameset framespacing="0" border="false" rows="2,*" frameborder="0">
<frame name="soundtown" src="soundtown.htm" scrolling="no" target="contents"> THIS IS THE SOUND PAGE = frames[0] (see below)
<frame name="webpages" src="YourWebPage.htm" target="main" scrolling="auto"> THESE ARE THE OTHER PAGES = frames[1] (see below)
<noframes>
<body>
<p>This page uses frames, but your browser doesn't support them.</p>
</body>
</noframes>
</frameset>
<frameset>
<noframes>
<body>
<p>This page uses frames, but your browser doesn't support them.</p>
</body>
</noframes>
</frameset>
</html>
Your actual code may vary but, what I am trying to show here is that you need to create a small (invisible) frame which will load a web page you'll be creating exclusively for sound purposes and a normal frame that will hold the other pages that make up the site.
From a scripting standpoint, remember that all the frames that compose a web page can be referenced using the FRAMES array. Internet Explorer and Netscape differ slightly in the way each reference frames and in the following sections I will show you how to cope with those differences.
The FRAMES array is an array of frame window objects and is a property of the WINDOW object. This FRAMES array has a LENGTH property that allows the programmer to know how many frames are inside the window. In the above case, the LENGTH property equals 2 since we've created two frames, frames[0] and frames[1] and our invisible frame is frames[0] since we´ve created it first.
Every new frame you create will simply add to the FRAMES array like frames[2], frames[3] and so on. So referencing them should be no problem.
To further simplify things, you can reference frames by name. If you don't know which element in the FRAMES array holds the page you wish to access, you can reference that page by using the frame name. In this tutorial we will be using name references.
Remember that to reference a frame by its name you should give it a name using the NAME attribute of the <FRAME> tag.
There are minor differences between Internet Explorer and Netscape when it comes to reference frames so please check the suggested syntax below:
Internet Explorer:
parent.frames['soundtown']
Netscape:
top.soundtown
Both examples return a reference to the frame named 'soundtown', after that you could use the document object on both browsers to access the web page inside the frame.
Whenever your user browses to a new page, it will be loaded inside frames[1] or, in our case, the 'webpages' frame; provided that the TARGET property for that page is correctly set. This allows to have the invisible frame at hand any time we need it. Be careful, don¡¯t let new pages overwrite your frame.
Now we have the invisible frame, so what?. Well, the page that will load inside our frame (not to be shown in the browser window) will have a pair of <OBJECT><EMBED> tags to insert the Flash Movie that holds the sounds.
When you want your sounds to be played or stopped your sound functions will ask the Flash Movie in the invisible frame to do it, since that movie will always be there, you can call it from anywhere within your web site.
To create the page that goes into the invisible frame you have two choices:
- Use the Publish function inside Flash.
- Use a custom function.
Whatever method you choose, remember that its output should be a valid web page that embeds a Flash Movie file (.swf extension). If you choose method (a), your page should look similar to this:
<html>
<head>
<title></title>
<base target="main">
</head>
<body>
<p>
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://active.macromedia.com/flash2/cabs/swflash.cab#version=4,0,0,0" ID="misonido" WIDTH="1" HEIGHT="1">
<param name="movie" value="misonido.swf">
<param name="play" value="false">
<param name="loop" value="false">
<param name="menu" value="false">
<param name="quality" value="high">
<param name="bgcolor" value="#FFFFFF">
<embed name="misonido" src="misonido.swf" play="false" loop="false" menu="false" quality="high" WIDTH="2" HEIGHT="2" TYPE="application/x-shockwave-flash" PLUGINSPAGE="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash" MAYSCRIPT SWLIVECONNECT="TRUE">
</object>
</p>
</body>
</html>
Two important things to note here. First, be sure to assign values for the WIDTH and HEIGHT attributes of the <EMBED> tag greater than 1 pixel because Netscape can not use an embed smaller than that. Second, be sure to add 'MAYSCRIPT SWLIVECONNECT="TRUE" ' to the <EMBED> tag so Netscape allows you to script the Plug-In.
Using a custom function is beyond the scope of this tutorial, but, it is important to say that the custom function should generate HTML code like the shown above.
Now we have the invisible frame and the page that will embed the Flash Movie, it's time to move on and create our 'soundbank'.
Outline of the whole process and creation of the Flash Movie
As you certainly know, to create a hyperlink in a web page you use the <A> tag. An image can also be used to link another page using the <IMG> tag combined with an <A> tag.
Knowing this, we are ready to outline the process of firing sounds kept inside a Flash Movie using attributes of the HTML links to call them by name.
The process would be as follows:
- Select those links and/or images you want to be sonified and write down the name of the HTML file they reference, i.e. default.htm.
- Choose the sound files you want to use with every link and/or image you want sonified.
- Create a Flash movie and create a Movie Clip for each different sound. Insert instances of the Movie Clips inside the movie and give each instance of the Movie Clip the name of the page that will load when the user clicks the link and/or image.
- Export the movie as a .swf file.
- Embed the Flash movie in your page.
- Create a function that retrieves the target URL of the HTML tag that fired the event that called the function.
- Add event handlers for the links and/or images that call the above function.
- Use the target URL to determine the Movie Clip to play
- Play the Movie Clip.
We will go into each step in order.
Browse the HTML code of the pages you want to be sonified and select the links and/or images you want to add sound to. Use your tools of choice to achieve that. Regardless of the tool you use, write down the name of the HTML file referenced by the links for reference.
Remember that <A> tags look like this:
<A href="agenda.htm" target="principal"></A>
And <A><IMG> tags combined look like this:
<A href="agenda.htm" target="principal"><IMG border="0" src="images/m_agenda.gif" width="65" height="43" name="m_agenda"></A>
In any case what we are looking for is the href= part of the tag; in the above cases, you¡¯d write down ¡®agenda¡¯ without the .htm extension.
Give the same treatment to each link and/or image and go to the next step.
- Choose the sound files you want to use, use your favorite sound editing program to get them ready to be inserted inside the Flash movie. Then go to the next step.
This step is a bit more complicated so we will build slowly until the end.
Fire up Flash and create a new movie. Insert a blank keyframe at frame 1. Double click on that frame and go to the Actions tab. Insert a Stop there.
Import the sounds you will be using in your web site. Remember to import all the sounds for the site since all of them will be contained inside the movie you just created.
Create a new Symbol choosing New Symbol from the Insert menu. In the dialog box that appears, give the symbol the name you want and set Behavior to Movie Clip. When done you will see the timeline for the Movie Clip you just created.
In the Movie Clip¡¯s timeline insert a keyframe at frame one, insert a Stop action in the newly created keyframe.
Insert blank frames at frames two and three.
Insert a keyframe at frame four, double click it and using the Sound tab insert one of your imported sounds. Set the Effect as Custom, Sync as Stream and Loops = 0.
Use the volume envelope as you feel it enhances your sound.
Now add blank frames until you can see the whole soundwave on the timeline, there is no need to add frames beyond the soundwave¡¯s duration.
Now you have your first movie clip. Repeat this process for each sound you want to have inside the movie and when done switch back to the main scene.
Now you should be able to see all the Movie Clips in the Library window. Drag them into the main scene¡¯s frame one.
After dragging a Movie Clip into the Scene, double click it and give it an instance name. The instance name should be one of the names you wrote down in step (a.) complete with uppercase and lowercase letters if appropriate.
Using the names you collected at step (a.), you will make a connection between that link and the Movie Clip, this connection will be used by the JavaScript code to play them.
This is a crucial step, please be careful giving names, if you give the Movie Clip a bad name you won¡¯t be able to play it and will have to go back to the Flash project and change the name.
If two or more links and/or images point to the same page, just drag as many Movie Clip instances as you need inside the scene and give each one the proper name.
After all these steps you should have a one frame scene with many movie clips inside it and each movie clip should have a different name. Keep in mind that the name of the symbol does not need to be related to anything but, the name of the Movie Clip instance should.
After all this work, export the movie with whatever name you want. Please remember that ¡®whatever name you want¡¯ really means the same name you employed when embedding the Flash Movie inside the invisible frame.
If you completed the above steps you have a ¡®soundbank¡¯ inside the Flash movie that after embedding in a web page is ready to be called and played.
The use of the Stop action inside the first frame of the scene and the first frame of each Movie Clip is to avoid the movie from playing sounds when embedded. The blank frames inside each Movie Clip are meant to avoid clipping (no pun intended) of the first part of the sounds when the Flash Player gets instructed to play the Movie Clip.
After all this work we are only missing the JavaScript code that will act as the glue for all these different components. This is the main subject of the following section.
Controlling sound playback from JavaScript
First of all let¡¯s create an external JavaScript library to store our code. Using external code libraries is a must if you want to avoid filling your HTML with lots of <SCRIPT> tags. Remember that a JavaScript library is a text file with a .js extension. In this case our library will be named ¡®soundtown.js¡¯.
The JavaScript libraries may be created using a simple text editor, or pick your favorite code editor to accomplish the task.
A big advantage of using external code libraries is that whenever you need to make a change to the code, no matter if it is an update or a correction, there is a single place to modify, which greatly eases the task and preserves your sanity. This doesn't mean that you don¡¯t need to test your code after modifications, it means that modifications are easier and don¡¯t involve editing lots of web pages.
Once the library is created you'll need to reference it from HTML so the functions and data that contains can be called from your HTML code. To reference an external code library use:
<script SRC="soundtown.js">
Remember that the text between quotes should contain the relative or absolute path to your library and the name of the .js file that contains your code.
If your code library is written in a language other that JavaScript i.e. VBScript, you can add LANGUAGE="VBScript" to the <SCRIPT> tag so the browser loads the VBScript interpreter. There is no need to use LANGUAGE="JavaScript" since the browser assumes all code to be JavaScript code as default. Remember that (in Internet Explorer) mixing JavaScript code and VBScript code leads to longer load times for your pages because the browser needs to load the VBScript interpreter which takes time and consumes memory. As a rule of thumb, stick to only one scripting language and it will go fine.
Also bear in mind that it is recommended to insert references like the shown above between <HEAD></HEAD> tags to ensure your code is available as soon as possible.
To control sound playback from JavaScript we will need two functions, one to play the sound and a second one to stop the sound, all the code needed to implement this will go inside the code library we just created.
To simplify things we will have the code to play and stop sounds inside the same function so we use a simple function call but, depending on the parameters sent to the function it will play or stop sounds.
The function will be called ¡®sound¡¯ and will take two arguments:
- An event object. This is an object.
- A play or stop flag. This argument is a string and can take a ¡®true¡¯ value or can be an empty string meaning ¡®false¡¯ or a different string meaning ¡®false¡¯ too.
The logic behind the function is as follows:
- First detect the browser. This will help to branch the code to support NE and IE.
- Using the Event object, retrieve the URL that is referenced by the HTML tag that called the function upon an event.
- Use a JavaScript Regular Expression to split the URL you retrieved and pick up the part you¡¯ll use. In our case you will use the name of the HTML file without the .htm or .html extension in the same way you acted when giving names to the Movie Clips.
- Check if the play flag equals ¡®true¡¯ if the answer is yes, see next step. Else see step f.
- Once you have the name of the web page, instruct the Flash ActiveX control or plug-in to play the Movie Clip whose name matches with the web page.
- Stop the Movie Clip and move to its first frame.
Before diving into the code, I think that it is fair to note that it was tested only on the following browsers and platforms:
Internet Explorer 5.5 on Intel PCs.
Netscape Communicator 4.5 on Intel PCs.
Netscape Communicator 4.7 on Power Macintosh.
No further testing of the code was performed since its writing (several months ago) so I am almost sure that this will break under Netscape 6 or older versions of each browser. Also keep in mind that as I said in the foreword, only the essential code is provided. It is up to you to tailor it to your needs. In fact the original code was much more complex but, it dealt with issues specific to the project it was developed for, so It has no place here.
This is the code for the function.
function sound (netscape_event,play){
var browser = initialCheck();
var soundTag = '';The variable 'browser' is an array that holds values returned by the function initialCheck(). The function initialCheck detects browsers and languages. I will provide it in a 'clipped' version in the downloadable source code.
The only thing that matters here is that browser[1] holds 'IE' if it is Internet Explorer,'NE' if it is Netscape and 'NN' if other.
Use your favorite function to detect the browser. The important thing is that the code should be branched for IE or NE.
The var 'soundTag' will hold the text that references the name of the Movie Clip
var reg = /\W/; The var 'reg' stores a Regular Expression. This regular expression will help parse the URL of the HTML element that called the function.
Remember that the syntax of /\W/ means a range of any non-alphanumerical character with the exception of the underscore.
if (browser[1]=='NE')soundTag = netscape_event.target.toString(); if (browser[1]=='IE'&&window.event.srcElement.getAttribute('pathname')!=null){
soundTag = window.event.srcElement.getAttribute('pathname');
}
else if(browser[1]=='IE'){
soundTag = window.event.srcElement.parentElement.getAttribute('pathname');
}soundTag=soundTag.split(reg);
Here we get to our first branch. Depending on which browser is being used we will retrieve the HREF attribute of the <A> or <IMG> tag that fired this function in different ways.
In case of Netscape we will use the TARGET property of the EVENT object to achieve this.
If it is Internet Explorer we will use the EVENT object too, but due to events 'bubbling up', the syntax is a bit more complex.
We use the split function (from the string object) plus the Regular Expression to parse the URL and split it every time we find a non-alphanumeric character. Here's an example:
original URL: www.mysite.com/web/mypage.htm after splitting the string we get an array that looks like 0=www 1=mysite 2=com 3=web 4=mypage 5=htm The length for this array is 6 so, we will use array.length-2 so we get at array[4] which equals 'mypage'. This array element is the tag that has the same value as the name of one of the Movie Clips inside the Flash Movie
if (arguments[1]=='true'){
if(browser[1]=='NE'&&top.soundtown.document.embeds.misonido.PercentLoaded()!=0){
top.soundtown.document.embeds.misonido.TPlay(soundTag[soundTag.length-2])
}
if (browser[1]=='IE'&&parent.soundtown.document.misonido.PercentLoaded()!=0){
parent.frames['soundtown'].document.misonido.TPlay(soundTag[soundTag.length-2]);
}}
If the array arguments[1] (the arguments of the function) equals 'true' it means that the sound should play. Notice that we are checking the browser and whether the Flash Movie loaded at least 1%. This is a good place to insert error handling code since these checks are useless if the invisible frame cannot load its page.
PercentLoaded () is a method of the Flash Player that returns a number indicating the percentage of the movie that has been downloaded so far. If the movie loaded at least 1% it means that no problems arose while embedding the movie. This does not mean that the movie is ready to play, so you could check if the movie is 100% loaded before trying to play it.
TPlay (target as String) is a method of the Flash Player that lets you play a Movie Clip by passing the method a string with the name of the target (Movie Clip). See how the method gets its target name from the URL already parsed.
Also notice that to access the Flash Embed you have to use the EMBEDS array in Netscape or the name of the embed in IE.if (arguments[1]!='true'){ if (browser[1]=='NE'&& top.soundtown.document.embeds.misonido.PercentLoaded()!=0){ top.soundtown.document.embeds.misonido.TStopPlay(etiqueta[etiqueta.length-2]); top.soundtown.document.embeds.misonido.TGotoFrame(etiqueta[etiqueta.length-2],1); }
if (browser[1]=='IE'&&parent.soundtown.document.misonido.PercentLoaded()!=0){ parent.frames['soundtown'].document.misonido.TStopPlay(etiqueta[etiqueta.length-2]); parent.frames['soundtown'].document.misonido.TGotoFrame(etiqueta[etiqueta.length-2],1);
} }
return; }
You can call the function using the play flag as an empty string and be sure that it will be assumed by the function to be a Stop order. The TStopPlay(target as String) method instructs the player to stop playing a Movie Clip, accepting a string as the Movie Clip name.
After stopping the player we go to Frame #1 using the TGotoFrame (target as String, frame as Integer) method which accepts a string as a Movie Clip name and an integer as a frame number. The TGotoFrame method makes sure that every time we play the Movie Clip it will start from the beginning.
As you can see the code is pretty straightforward. In the next section we will see how to call this function from HTML using event handlers.
Linking page elements to sounds
This is the easy part, if you read through this document you have your invisible frame, your web page inside the invisible frame that embeds the Flash Movie, the Flash Movie with sounds as Movie Clips, your JavaScript code library and the web pages that you want sonified.
Now we will see how to create the event handlers needed to sonify links and/or images.
To use the sound function from a web page:
a. Reference the JavaScript library ¡®soundtown.js¡¯ from HTML like this:
<script SRC="soundtown.js">
It is important (as I said before) that you reference the external library from every web page that will have sounds so the sound functions are available to be called from event handlers.
b. Insert the function call inside a onmouseover event handler like this.
<a href="agenda.htm" onmouseover="sound(event,'true');" target="principal"><img border="0" src="images/m_agenda.gif" width="65" height="43" name="m_agenda"></a>
When the onmouseover event fires, it will call the function and the sound will start.
If you want the sounds to stop when the user moves the mouse pointer away from the link and/or image you can add a function call to a onmouseout event. Like this:
Onmouseout="sonido(event,'');" Notice the play flag as an empty string
In this case, the sound inside the Movie Clip will stop. It really is a matter of taste, I mean, if you want sounds to ¡®bleed¡¯ into each other don¡¯t use the onmouseout event. Personally I think that stopping sounds when the user leaves the link and/or image allows a much controlled sound experience, but again, it is a matter of taste.
Final thoughts
This method to sonify web sites may seem a bit odd at first sight but, after you implement it, it will allow you to keep up with changes to the contents of a web site. We at Soundtown used a slight variation of it to sonify an entire web site where we were required to make as little changes to the HTML code as possible since HTML code was already finished when we started sonifying .
Notice that you only need to be aware of frames, referencing the JavaScript library in all the pages and add calls to sound functions inside event handlers. All of them easy tasks that don¡¯t modify radically the HTML code.
As further enhancements I might suggest some simple error handling routines, checking for the Flash player before embedding a Flash movie, keeping an eye on the size of the Flash movies and detecting Internet Explorer on Macintoshes since this method won¡¯t work with this combination of browser and platform (at least the Internet Explorer we have) due to the impossibility of scripting the Flash player inside IE for Mac and modifying the sound functions so you can uses multiple Flash Movies.
Don¡¯t be afraid to experiment and remember to have fun while doing it. I certainly had a great time developing this.
Soundtown is Argentina´s leader in sound solutions for business and entertainment web sites. Born as a new division for Hit&Post, a twelve years old music production and sound post-production company for TV, radio and advertising; is currently developing business solutions that incorporate sound, voice and music, helping Internet companies to serve their customers better and generate revenues. Also, Soundtown is creating tools to take the design of interactive sound into the future.
Gonzalo Alustiza is head of development and technologies at Soundtown. After working many years as a systems consultant and designer and implementing several world-class ERP packages for Food and Beverages companies, he joined Soundtown to help bridge the gap among software developers, sound engineers and musicians.
» Level Intermediate
Added: : 2001-02-20
Rating: 6.21 Votes: 28
Hits: 4505» Author My name is Gonzalo Alustiza and I work as a chief developer at Soundtown Argentina. Soundtown is a ten year old music production company specializing in music for advertising and TV which started to develop sonification solutions for the Internet. » Download Download the files used in this tutorial. Download (89 kb)
discuss this topic to forum






