Back to Entry Page

Anatomy of the "noisyRoom" Sound Project

Concept

This strange little demo shows how to link the proximity of the cursor to sound volume and the visual features of text fields contained within movie clips. In basic concept, this is a textual simulation of a crowded, noisy room in which many conversations (well, actually, looped soundbites) are going on at once. As you (in the person of the cursor) draw nearer to the title representing one of the sounds, it grows louder and its lettering becomes larger and bolder. So may its neighbors. Thus both the visual and the sonic landscapes change as you move.

Among other things, this little project shows how to create non-binary structures in Flash: states that have values in between the extremes of On or Off.

Architecture

The layer architecture of this project is very simple: there are eleven layers, one for each text/title, plus a twelfth layer for the exit button. Each layer contains one frame. Within that frame is a movie clip.

Each clip contains a static text field into which has been entered a word or phrase representing an associated sound. Each movie clip also has a script containing two handlers.

Scripting

Each movie clip has a handler for the load event to set up and start its sound. For instance:

onClipEvent(load){
  s_lastDay = new Sound(this);
  s_lastDay.attachSound("lastDay");
  s_lastDay.start(0,999);
  startWidth = this._width;
  startHeight = this._height;
}

This handler sets up a new Sound object called s_lastDay, associates the sound clip "lastDay" with it, and starts that clip playing from the top, with 999 repetitions. It's worth noting that, technically speaking, every sound clip in the project begins playing at the start of the movie--though happily, this conditions changes before your sound card can do anything about it.

We also load two variables, startWidth and startHeight, with the initial width and height of the clip. These values are necessary for the visual effects.

Each movie clip in this project also contains an enterFrame handler that executes continually as long as the movie is loaded (since the single-frame movie continually loops back onto itself). For reference, here is the entire handler; we'll go through the various bits below:

onClipEvent(enterFrame){
  //Find cursor distance
  xSide = _root._xmouse - this._x;
  ySide = _root._ymouse - this._y;
  hypo = Math.sqrt((xSide * xSide)+(ySide * ySide));

  //Respond to cursor distance	
  if(hypo>100) 
    {
      deltaV = 0;
      s_lastDay.stop();
      ldStopped = true;
    }
    else
    {
      if(ldStopped == true) 
        {
          s_lastDay.start(0,999);
          ldStopped = false;
        }
      if(hypo<101 && hypo>50) deltaV = 20;
      if(hypo<51 && hypo>25) deltaV = 30;
      if(hypo<26) deltaV = 50;
      s_lastDay.setVolume(deltaV);
    }
    this._width = startWidth + deltaV;
    this._height = startHeight + deltaV;
    this._alpha = 60 + deltaV;
}

Let's take the section labeled "Find cursor distance" first. To compute the distance between any two points, you need to construct a right triangle and apply the Pythagorean theorem: the square of the hypotenuse (the side that represents the distance we're measuring) is equal to the sum of the squares of the other two sides. You solve for the hypotenuse by squaring the lengths of the other sides, adding them, and taking the square root of the sum. That's what these three lines do:

  xSide = _root._xmouse - this._x;
  ySide = _root._ymouse - this._y;
  hypo = Math.sqrt((xSide * xSide)+(ySide * ySide));

Lengths for the two missing sides of the triangle, xSide and ySide, are computed by subtracting the X and Y coordinates of the two points we have. This can of course produce a negative number, which may seem worrisome; but we're going to square this number, and any negative number multiplied by itself yields a positive product.

These three lines of code will allow you to measure cursor distance from any specified point. They can come in very handy.

Now let's consider the rest of the script, labeled "Respond to cursor distance:"

  if(hypo>100) 
    {
      deltaV = 0;
      s_lastDay.stop();
      ldStopped = true;
    }
    else
    {
      if(ldStopped == true) 
        {
          s_lastDay.start(0,999);
          ldStopped = false;
        }
      if(hypo<101 && hypo>50) deltaV = 20;
      if(hypo<51 && hypo>25) deltaV = 30;
      if(hypo<26) deltaV = 50;
      s_lastDay.setVolume(deltaV);
    }
    this._width = startWidth + deltaV;
    this._height = startHeight + deltaV;
    this._alpha = 60 + deltaV;

The first if condition determines whether the cursor distance hypo is greater than 100 pixels. If it is, then we set the variable deltaV to zero and stop the current sound. (By the way, this line is what reduces the potential cacophony at startup to near-silence.) We also set a flag variable, for this script called ldStopped, to true, indicating that the sound attached to this movie clip is no longer playing.

All this means that we shut down any sound if the cursor is more than 100 pixels away from its associated movie clip. The reason we do this is explained in the next section, below.

If the cursor is within 100 pixels, we check the value of the flag variable to see if the sound has been stopped. If it has, we turn it back on and reset the flag variable. This check protects us from starting multiple copies of the sound--not very pleasant to listen to.

The next three if statements configure the variable deltaV depending on the proximity of the mouse. The closer the mouse gets to the center of the movie clip, the greater the value for deltaV. After we've set a value for deltaV, we use this value to set the volume of the sound.

The last three lines of this script adjust the width, height, and alpha of the present object, using deltaV as an increment. If the cursor distance exceeds 100 pixels, deltaV drops to zero, so startWidth and startHeight return to their original values. This restores the appearance of the clip once the cursor moves away.

Overcoming the Eight-Track Limit

Flash is only able to play eight sounds simultaneously, but this project includes twelve sounds. However, because they're dependent on objects cleverly placed around the screen, only three or four ever play at once. Because we turn off each sound when the cursor travels more than 100 pixels from it, we can have as many sounds as we like potentially available.

As we've previously observed, when this project starts up, all twelve sounds technically begin playing. Actually Flash ignores sounds 9-12, but the user never hears the results anyway. In a millisecond or so, the enterFrame handlers are executed for each movie clip, and those clips that lie more than 100 pixels from the cursor immediately turn off their associated sounds.

Improved Version

After I built the original demo in 2001, I made certain important improvements, which are detailed on a separate page.

Source files for both the original (noisyRoom.fla) and the revised project (noisyRoomImproved.fla) may be downloaded from the MMShare/workshop/noisyRoom directory on Crow.


University of Baltimore Logo

Copyright © 2002 School of Information Arts and Technologies