Chapter Twenty
Playing and Controlling
Sound Files from JavaScript


Deciding Which Sound Files to Use

One of the ways to make a page at your site more exciting for visitors is to add sound. There are many functions that you can control from JavaScript pertaining to that sound.

The problem, of course, is how confoundedly big those darn sound files can be. A minute or two of digitized sound can quickly rise to a megabyte or more of download -- clearly impractical for all but the most dedicated dial-up user.

Real Audio® and others have developed "streaming audio" that addresses this problem somewhat, and for voice, this approach is probably the best technology to use.

Music is another situation altogether. Although you could still use your .au and .wav files for this purpose -- again, they are really big.

An "old" technology on the web, however, offers a very pleasing solution to providing music without huge downloads.

That is the ubiquitous MIDI file. The folks at Netscape® have developed LiveAudio® and the folks at Apple® have developed a QuickTime® Instrument library that "lives" on your computer.

And this is no minimalistic library. Composers can pick from such esoteric instruments as bagpipes, shagahuchi, kogo, metal drums, sci-fi and more, in addition to more conventional instruments.

Why the sales pitch? Simple. A 60 second playing time MIDI file with lots of channels of instrumentation and orchestration may require less than 4 or 5k of data. You read that right. That is a tiny file! (A corresponding .au or .wav file would easily consume 200 to 500k of download)

Why should you care? The dial-up visitor to your pages with, say, a 14.4 modem can receive the MIDI file in 2 or 3 seconds, while the bigger sound files will take 2 to 5 minutes under optimum net conditions.

It's your call, of course, but using unnecessary extra bandwidth will cost you in more ways than one.

The control of sound files from JavaScript won't change, regardless of your decision. The script doesn't care if you call a .mid, an .aif, an .au or a .wav file, etc.

Refamiliarizing Yourself With the HTML Calls Needed for Playing Sound Files

Yeah, I know. You are so doggone familiar with HTML that you already know this stuff that follows.

Why am I wasting your time with HTML for audio? Well, because the truth is that you haven't used it much and may have "forgotten" some of it.

Audio Controls

If you specify a direct link to a sound file, Netscape LiveAudio® opens a new window by default. It is a tiny window 60 pixels high by 144 pixels wide, that exactly contains the Console. You don't have to specify anything. If the user has another plug-in configured, such as Crescendo!®, the visual will change, but not the dimensions.

<A HREF="yourname.mid">My Song</A>

That HTML is all that is needed. If the user clicks on the link, everything happens automatically.

The CONSOLE contains a start button, a stop button, a pause button and a volume control slider.


Big Console HEIGHT=60 WIDTH=144


Big Console in Automatically Opened Window

There is also a more compact console that I prefer to use, which is referred to in HTML as "smallConsole". It does not include a pause button, but does contain the play, stop and volume slider controls.


Small Console HEIGHT=15 WIDTH=144

Although it would seem intuitive what the buttons control on the smallConsole, a bit of confusion on the part of some users has led me to always include a small font size "legend" on the line below the smallConsole to "describe" the functions of the buttons:


Small Console with added Legend Line


The HTML calls to use in the <EMBED SRC=etc. tag.

To display the consoles on your own pages is similar to calling any other image. The difference is the <EMBED SRC= tag.

<EMBED SRC="my.mid" (+ calls here)>

ALIGN=position  As with image calls, you can specify the alignment position of the console images with ABSBOTTOM, ABSMIDDLE, BASELINE, BOTTOM, CENTER, LEFT, MIDDLE, RIGHT, TEXTTOP or TOP.

AUTOSTART=TRUE will cause the sound to begin as soon as the sound file has been loaded. You may use the AUTOSTART=FALSE call if you wish, but it is totally unnecessary, since this is the default. If you leave the call AUTOSTART out of your tag, it won't start playing until you call it from JavaScript or the user clicks the Play button.

CONTROLS=CONSOLE will cause the big console to display,

CONTROLS=smallConsole will display the small one. There are also calls to display individual components of the console. The calls for these are: PLAYBUTTON, PAUSEBUTTON, STOPBUTTON and VOLUMELEVER respectively. See the section on custom consoles below for a bit more detail.

HEIGHT=60 - CONSOLE

HEIGHT=15 - smallConsole

(These are default heights, so need not always be specified. However, for some reason, on some platforms, it helps to specify heights. Notice that there are no quotes around the numbers. Yeah, the HTML specs say there should be quotes -- but don't use 'em in your EMBED calls)

HIDDEN=TRUE is specified only if you want no display of a controller on screen. Caution: do not use HIDDEN=FALSE, since even though it shouldn't matter, because this is the default, it is a definitely bad call that may cause errors. Note: although Microsoft Internet Explorer® will experience no problems with the HTML call <BACKGROUND SRC="my.mid"> Netscape® browsers may on some platforms. So the <EMBED SRC=etc. will probably serve you better for hidden sound files.

LOOP=TRUE will cause your sound file to repeat endlessly once it has started playing. (If you have a console, the Stop button will override this call and stop the sound. But if the Play button is clicked again, the sound will again repeat endlessly until the Stop button is clicked) LOOP=FALSE is an unnecessary call, since it is the default. (When the Play button is clicked, the sound file will play through just once and stop automatically) There is one extra LOOP call that you can make: LOOP=x where x is any whole number integer. With this call, the sound file will be played the number of times you specify with x, and then will stop.

WIDTH=144 - CONSOLE and SMALLCONSOLE

(These are default widths, so need not always be specified. However, for some reason, on some platforms, it helps to specify widths. Notice that there are no quotes around the numbers)

Combining the desired attributes might result in HTML like the following:

<EMBED SRC="my.mid" AUTOSTART=TRUE
 CONTROLS=CONSOLE LOOP=TRUE
 WIDTH=144 HEIGHT=60>

Master Sound and Distributed Buttons

In addition to the large and small consoles, LiveAudio® permits you to use the components of the consoles to create custom consoles.

At the heart of this is the MASTERSOUND and NAME calls. Without going into great detail, you can control a number of sound files with just one volume control, etc., by giving them a common NAME such as "custom" and then adding the MASTERSOUND call to the volume lever, for example.

This requires the use of so-called "stub" files, which is beyond the scope of this work. Visit Netscape® for details, if desired.

However, if you wish to use individual buttons for your own console, here are the heights and widths:

HEIGHT=22 - PAUSEBUTTON
HEIGHT=22 - PLAYBUTTON
HEIGHT=22 - STOPBUTTON
HEIGHT=20 - VOLUMELEVER

WIDTH=37 - PAUSEBUTTON
WIDTH=37 - PLAYBUTTON
WIDTH=37 - STOPBUTTON
WIDTH=144 - VOLUMELEVER

VOLUME=x

This call lets you specify the system sound volume - useful if you are not including a volume slide of one kind or another.

x is any value from 1 to 100 (indicating per cent of maximum volume)

If you don't call a volume=percentage, i.e., leave out the volume call altogether, the default is whatever the user currently has set his/her system volume to - probably the polite thing to do if you aren't giving your visitor a control. STARTTIME=00:00 (Minutes:Seconds)

This call lets you delay the commencement of playing for a sound file. If, for example, you wanted to wait two and a half minutes, you would set it to 02:30 Note: at present, this is a valid call only on Macintosh®, Windows 95® and NT® platforms.

ENDTIME=00:00 (Minutes:Seconds)

This call lets you specify the duration of playing for a sound file. If, for example, you wanted it to play for two and a half minutes, you would set it to 02:30 Note: at present, this is a valid call only on Macintosh®, Windows 95® and NT® platforms.

If the NAME=MASTERSOUND call is included with the VOLUMELEVER, it will control a number of different sound files on that page without displaying a volume lever for each.

However, if several Consoles or Small Consoles appear on the same page, the built-in volume slide will control system sound, even if the lever which is moved is not presently "active" because a different sound file is playing in a different console.

A Script Using the smallConsole

Because changing selections on the present document screen would require a reload of the page, it is usually better to create a frameset document and simply direct the selections to a small pane of that frame.

In addition, you may wish to "spool" sequential songs to the visitor's speakers, so that feature is also incorporated in the following parent and two child documents script. A link to see them follows the last.

Parent Document - s31.htm

<HTML><HEAD>
<TITLE>Playing Sound Files</TITLE>
</HEAD>
<FRAMESET FRAMEBORDER=0
 BORDERCOLOR="white" ROWS="30,*">
  <FRAME SRC="s53.htm" SCROLLING="no"
   NAME="music" MARGINHEIGHT=3
   MARGINWIDTH=3>
  <FRAME SRC="s54.htm" SCROLLING="yes"
 NAME="main">
</FRAMESET>
</HTML>

First Child Document - s53.htm

<HTML> <BODY BGCOLOR="white"> </BODY> </HTML>

Second Child Document - s54.htm

<HTML><HEAD>
<SCRIPT LANGUAGE="JavaScript">
<!-- Hide from JS-Impaired Browsers
var hlt=0;
locnm=location.href;
locnm=locnm.substring(0,locnm.indexOf("s54.htm"));
ts= " rc ag cc cl df do ds fj ga gr jw lm na "
+"ng ra rc sf tb tp";
tsc="57 39 29 71 37 37 22 44 49 62 30 "
+"60 66 56 56 57 29 48 50 ";
var song=new Array();
song[0]="What a Friend We Have in"
+" Jesus!fj";
song[1]="The Doxology (Faith of Our"+" Fathers!)do";
song[2]="Shall We Gather at the River?gr";
song[3]="Lonely Manlm";
song[4]="Nearer My God to Thee!ng";
song[5]="Come Ye Thankful People"+" Come!tp";
song[6]="Amazing Graceag";
song[7]="Rock of Ages (Cleft for Me!)ra";
song[8]="The Old Rugged Crossrc";
song[9]="I Come to the Garden Alonega";
song[10]="Were You There?cl";
song[11]="The Star Spangled Bannerna";
 
function bgnIt(){
 ls="";
 sng="";
 for (var i=0;i<12;i++){
  if (document.images[i+ad].src==locnm
  +"in/ckx.gif"){
   ls+=song[i].substring(song[i].length-2,song[i].length);
   sng+=song[i].substring(0,song[i].length-2)+"* "
   }
  }
 if (ls!=""){
  sls=ls;
  ssng=sng;
  playIt();
  }
 }
 
function playIt(){
 if (ls.length>0&&hlt==0){
  document.a.src="in/rbd.gif";
  document.b.src="in/rbl.gif";
  lsp=ls.substring(0,2);
  ls=ls.substring(2,ls.length)
  oneSong();
  }
 else{
  if (hlt!=1){
   ls=sls;
   sng=ssng;
   playIt();
   }
  }
 }
 
function oneSong(){
  parent.music.document.close();
  parent.music.document.open();
  parent.music.document.write("<HTML>"
  +"<BODY BGCOLOR='white'>"
  +"<CENTER><EMBED SRC='in/"+lsp
  +".mid' WIDTH=144 HEIGHT="
  +"15 AUTOSTART=TRUE CONTROLS"
  +"='smallConsole'"
  +"LOOP=FALSE>"+"<FONT SIZE=4> "
  +" <B>Selection Now Playing: "
  +sng.substring(0,sng.indexOf("*"))
  +"</B></FONT></BODY></HTML><P>");
  sng=sng.substring(sng.indexOf("*")+1,sng.length);
  if (lsp!="kill"){
   pos=ts.indexOf(" "+lsp);
   nr=eval(tsc.substring(pos,pos+2))*1000;
   stpNm=setTimeout("playIt()",nr);
  }
 }
 
function stpIt(){
 if (stpNm){
  clearTimeout(stpNm);
  }
 lsp="kill";
 sng=" - Music Stopped -* ";
 oneSong();
 for (var i=0;i<12;i++){
  document.images[i+ad].src="in/ckb.gif";
  }
  document.a.src="in/rbl.gif";
  document.b.src="in/rbd.gif";
 }
/* This little routine is simply used to
     count the number of images you
     may place on your web page
     prior to the checkboxes. Just
     makes the routine independent
     of how you lay your page out. */
function getImgAdd(){
 for (var i=0;i<20;i++){
  if (document.images[i].src.indexOf("ckb.gif")>-1){
   ad=i;
   i=20;
   }
  }
 }
 
function checkIt(){
 if (document.images[flg+ad].src==locnm+"in/ckb.gif"){
  document.images[flg+ad].src="in/ckx.gif";
  }
 else{
  document.images[flg+ad].src="in/ckb.gif";
  }
 mouseIt();
 }
 
function mouseIt(){
 nm=(document.images[flg+ad].src==locnm+"in/ckb.gif"?
"Select ":"Deselect ");
 parent.window.status=nm
 +song[flg].substring(0,song[flg].length-2);
 }
 
// End Hiding -->
</SCRIPT>
</HEAD>
<BODY BGCOLOR="white"><CENTER>
<TABLE BORDER=0 WIDTH=486
 CELLPADDING=0 CELLSPACING=0>
<TR><TD COLSPAN=2 ALIGN=CENTER>
<BR><B>JavaScript to Play Sound
 Files</B><P></FONT></TD></TR>
<SCRIPT LANGUAGE="JavaScript">
<!-- Hide from JS-Impaired Browsers
document.write("<TR><TD BGCOLOR='cyan'>");
for (var i=0;i<12;i++){
 if (i!=0&&i!=6){
  document.write("<BR>");
  }
 document.write("  <A HREF='inspin."
  +"htm' onClick='flg="+i
  +";checkIt();return false;' onMouse"
  +"over='flg="+i+";mouseIt();return true;'>"
  +"<IMG SRC='in/ckb.gif' WIDTH="
  +"12 HEIGHT=12 BORDER=0></A> "
  +song[i].substring(0,song[i].length-2));
 if (i==5){
  document.write("</TD><TD BGCOLOR"
  +"='cyan'>");
  }
 }
document.write("</TD></TR>");
// End Hiding -->
</SCRIPT>
<TR><TD BGCOLOR="cyan"
 COLSPAN=2> </TD></TR>
<TR><TD VALIGN=TOP> 
<A HREF="s54.htm"
 onClick="hlt=1;stpIt();return false;"
 onMouseover="parent.window.status=
 'Click to Stop and Reselect';return true;">
<IMG SRC="in/rbl.gif" WIDTH=15
 HEIGHT=15 BORDER=0 NAME="a"></A>
 Stop and/or Reselect</TD>
<TD VALIGN=TOP> 
<A HREF="s54.htm"
 onClick="hlt=0;bgnIt();return false;"
 onMouseover="parent.window.status=
'Click to Start Selections';return true;">
<IMG SRC="in/rbd.gif" WIDTH=15
 HEIGHT=15 BORDER=0 NAME="b">
</A> Start Selections</TD></TR>
<TR><TD COLSPAN=2> </TD></TR>
<TR><TD COLSPAN=2 BGCOLOR="cyan">
<B>Instructions:</B> Simply check all songs
you would like to hear. Then click the Start
Selections button. The list of songs you select
will play and then repeat until you click the
stop button. If you wish to continue listening
after departing this page, just select "New Web
Browser" under "File" at the top of your screen.</TD></TR>
</TABLE>
<SCRIPT LANGUAGE="JavaScript">
<!-- Hide JavaScript from Java-Impaired Browsers
getImgAdd();
// End Hiding -->
</SCRIPT>
</BODY>
</HTML>

Click Here to See These Scripts.



© Copyright 1997, John H. Keyes john.keyes@intellink.net