From 04d65685d51af2568c53571c41776bd9026b6f43 Mon Sep 17 00:00:00 2001 From: athomas Date: Tue, 8 Jul 2003 20:13:32 +0000 Subject: Added lesson 7 git-svn-id: file:///home/mbien/NetBeansProjects/JOGAMP/joal-sync/svn-server-sync-demos/joal-demos/trunk@32 235fdd13-0e8c-4fed-b5ee-0a390d04b286 --- www/devmaster/compress_sin_wave.jpg | Bin 0 -> 9332 bytes www/devmaster/doppler_effect.jpg | Bin 0 -> 16978 bytes www/devmaster/lesson5.html | 109 +++++++++++----------- www/devmaster/lesson7.html | 178 ++++++++++++++++++++++++++++++++++++ www/devmaster/sin_wave.jpg | Bin 0 -> 6923 bytes www/devmaster/sound_waves.jpg | Bin 0 -> 17496 bytes www/index.html | 3 +- 7 files changed, 235 insertions(+), 55 deletions(-) create mode 100644 www/devmaster/compress_sin_wave.jpg create mode 100644 www/devmaster/doppler_effect.jpg create mode 100644 www/devmaster/lesson7.html create mode 100644 www/devmaster/sin_wave.jpg create mode 100644 www/devmaster/sound_waves.jpg (limited to 'www') diff --git a/www/devmaster/compress_sin_wave.jpg b/www/devmaster/compress_sin_wave.jpg new file mode 100644 index 0000000..9974c9c Binary files /dev/null and b/www/devmaster/compress_sin_wave.jpg differ diff --git a/www/devmaster/doppler_effect.jpg b/www/devmaster/doppler_effect.jpg new file mode 100644 index 0000000..8adc77c Binary files /dev/null and b/www/devmaster/doppler_effect.jpg differ diff --git a/www/devmaster/lesson5.html b/www/devmaster/lesson5.html index 1fe183c..5eb3815 100644 --- a/www/devmaster/lesson5.html +++ b/www/devmaster/lesson5.html @@ -33,17 +33,17 @@ OpenAL Tutorials from DevMaster.net. Reprinted with Permission.
Maurais
Adapted For Java By: Athomas Goldberg

-

At this point in the OpenAL series I will show one method of having your buffers - be shared among many sources. This is a very logical and natural step, and it - is so easy that some of you may have already done this yourself. If you have - you may just skip this tutorial in total and move on. But for those keeners - who want to read all of the info I've got to give, you may find this interesting. - Plus, we will be implementing the Alc layer directly so that we can use some - of that knowledge gained in lesson 4. On top of that we will create a program - you might even use!

-

Well, here we go. I've decided to only go over bits of the code that are significant, - since most of the code has been repeated so far in the series. Check out the - full source code in the download.

+

At this point in the OpenAL series I will show one method of + having your buffers be shared among many sources. This is a very logical and + natural step, and it is so easy that some of you may have already done this + yourself. If you have you may just skip this tutorial in total and move on. + But for those keeners who want to read all of the info I've got to give, you + may find this interesting. Plus, we will be implementing the Alc layer directly + so that we can use some of that knowledge gained in lesson 4. On top of that + we will create a program you might even use!

+

Well, here we go. I've decided to only go over bits of the + code that are significant, since most of the code has been repeated so far in + the series. Check out the full source code in the download.

static ALC alc;
 static AL al;
 
@@ -64,13 +64,13 @@ OpenAL Tutorials from DevMaster.net. Reprinted with Permission.
Vector sources = new Vector();
-

First I've written out a few macros that we can use to index the buffer array. - We will be using several wav files so we need quite a few buffers here. Instead - of using an array for storing the sources we will use a Vector. We chose to - do this because it allows us to have a dynamic number of sources. We can just - keep adding sources to the scene until OpenAL runs out of them. This is also - the first tutorial where we will deal with sources as being a resource that - will run out. And yes, they will run out; they are finite.

+

First I've written out a few macros that we can use to index + the buffer array. We will be using several wav files so we need quite a few + buffers here. Instead of using an array for storing the sources we will use + a Vector. We chose to do this because it allows us to have a dynamic number + of sources. We can just keep adding sources to the scene until OpenAL runs out + of them. This is also the first tutorial where we will deal with sources as + being a resource that will run out. And yes, they will run out; they are finite.

static int initOpenAL() {
  
     ALC.Device device;
@@ -99,8 +99,8 @@ Vector sources = new Vector();
     return AL.AL_TRUE;
 }
 
-

This is some sample code from what we learned in the last tutorial. We get - a handle to the device "DirectSound3D", and then obtain a rendering +

This is some sample code from what we learned in the last tutorial. + We get a handle to the device "DirectSound3D", and then obtain a rendering context for our application. This context is set to current and the function will check if everything went smoothly before we return success.

static void exitOpenAL() {
@@ -121,16 +121,16 @@ Vector sources = new Vector();
     alc.alcCloseDevice(curDevice);
 }
 
-

This will do the opposite we did in the previous code. It retrieves the context - and device that our application was using and releases them. It also sets the - current context to null (the default) which will suspend the processing of any - data sent to OpenAL. It is important to reset the current context to null or - else you will have an invalid context trying to process data. The results of - doing this can be unpredictable.

-

If you are using a multi-context application you may need to have a more advanced - way of dealing with initialization and shutdown. I would recommend making all - devices and contexts global and closing them individually, rather than retrieving - the current context.

+

This will do the opposite we did in the previous code. It retrieves + the context and device that our application was using and releases them. It + also sets the current context to null (the default) which will suspend the processing + of any data sent to OpenAL. It is important to reset the current context to + null or else you will have an invalid context trying to process data. The results + of doing this can be unpredictable.

+

If you are using a multi-context application you may need to + have a more advanced way of dealing with initialization and shutdown. I would + recommend making all devices and contexts global and closing them individually, + rather than retrieving the current context.

static int loadALData() {
     // Variables to load into.
     int[] format = new int[1];
@@ -176,8 +176,8 @@ Vector sources = new Vector();
     return AL.AL_TRUE;
 }
 
-

We've totally removed the source generation from this function. That's because - from now on we will be initializing the sources separately.

+

We've totally removed the source generation from this function. + That's because from now on we will be initializing the sources separately.

static void addSource(int type) {
     int[] source = new int[1];
 
@@ -201,12 +201,12 @@ Vector sources = new Vector();
 }
 
 
-

Here's the function that will generate the sources for us. This function will - generate a single source for any one of the loaded buffers we generated in the - previous source. Given the buffer index 'type', which is one of the macros we - created right from the start of this tutorial. We do an error check to make - sure we have a source to play (like I said, they are finite). If a source cannot - be allocated then the program will exit.

+

Here's the function that will generate the sources for us. + This function will generate a single source for any one of the loaded buffers + we generated in the previous source. Given the buffer index 'type', which is + one of the macros we created right from the start of this tutorial. We do an + error check to make sure we have a source to play (like I said, they are finite). + If a source cannot be allocated then the program will exit.

static void killALData() {
 
     Iterator iter = sources.iterator();
@@ -218,9 +218,9 @@ Vector sources = new Vector();
     exitOpenAL();
 }
 
-

This function has been modified a bit to accommodate the Vector. We have to - delete each source in the list individually and then clear the list which will - effectively destroy it.

+

This function has been modified a bit to accommodate the Vector. + We have to delete each source in the list individually and then clear the list + which will effectively destroy it.

    char[] c = new char[1];
 
     while(c[0] != 'q') {	
@@ -248,19 +248,20 @@ Vector sources = new Vector();
 			System.exit(1);
         }
     }
-

Here is the programs inner loop taken straight out of our main. Basically it - waits for some keyboard input and on certain key hits it will create a new source - of a certain type and add it to the audio scene. Essentially what we have created - here is something like one of those nature tapes that people listen to for relaxation. - Ours is a little better since it allows the user to customize which sounds that - they want in the background. Pretty neat eh? I've been listening to mine while - I code. It's a Zen experience (I'm listening to it right now).

-

The program can be expanded for using more wav files, and have the added feature - of placing the sources around the scene in arbitrary positions. You could even - allow for sources to play with a given frequency rather than have them loop. - However this would require GUI routines that go beyond the scope of the tutorial. - A full featured "Weathering Engine" would be a nifty program to make - though. ;)

+

Here is the programs inner loop taken straight out of our main. + Basically it waits for some keyboard input and on certain key hits it will create + a new source of a certain type and add it to the audio scene. Essentially what + we have created here is something like one of those nature tapes that people + listen to for relaxation. Ours is a little better since it allows the user to + customize which sounds that they want in the background. Pretty neat eh? I've + been listening to mine while I code. It's a Zen experience (I'm listening to + it right now).

+

The program can be expanded for using more wav files, and have + the added feature of placing the sources around the scene in arbitrary positions. + You could even allow for sources to play with a given frequency rather than + have them loop. However this would require GUI routines that go beyond the scope + of the tutorial. A full featured "Weathering Engine" would be a nifty + program to make though. ;)

Download the Java Files and Ant build script

diff --git a/www/devmaster/lesson7.html b/www/devmaster/lesson7.html new file mode 100644 index 0000000..ddb54a3 --- /dev/null +++ b/www/devmaster/lesson7.html @@ -0,0 +1,178 @@ + + + +Untitled Document + + + + + +
+ +
+ + Wiki + Weblogs + Forums + JavaGames Home + www.java.net +
+
+OpenAL Tutorials from DevMaster.net. Reprinted with Permission.
+
+
+ + + + +

OpenAL + Tutorials

DevMaster.net

+

The Doppler Effect
+
Lesson 7

+ +

A Look at Real-World Physics

+

I know this will be boring review for anyone with a course in high school +physics, but lets humour ourselves. The Doppler effect can be a very tricky +concept for some people, but it is a logical process, and kind of interesting +when you get right down to it. To begin understanding the Doppler effect we +first must start to understand what a "sound" really is. Basically a sound is +your minds interpretation of a compression wave that is traveling through the +air. Whenever the air becomes disturbed it starts a wave which compresses the +air particles around it. This wave travels outward from it's point of origin. +Consider the following diagram.

+

In this diagram +(on the left) the big red "S" stands for the sources position, and the big +red "L" stands for (you guessed it), the Listener's position. Both source and +Listener are not moving. The source is emitting compression waves outward, which +are represented in this diagram by the blue circles. The Listener is +experiencing the sound exactly as it is being made in this diagram. The Doppler +effect is not actually present in this example since there is no motion; the +Doppler effect only describes the warping of sound due to motion.

+

What you should try to do is picture this diagram animated. When the source +emits a wave (the circles) it will look as though it is growing away from it's +point of origin, which is the sources position. A good example of a similar +effect is the ripples in a pond. When you throw a pebble into a calm body of +water it will emit waves which constantly move away from the point of impact. +Believe it or not this occurs from the exact same physical properties. But what +does this have to do with the Doppler effect? Check out the next diagram (on the +right).

+ +

+Wow, what's going on here? The source is now in motion, indicated by the +little red arrow. In fact the source is now moving towards the Listener with an +implied velocity. Notice particularly that the waves (circles) are being +displaced inside each other. The displacement follows the approximate path of +the source which emits them. This is the key to the Doppler effect. Essentially +what has happened is that the source has emitted a wave at different points in +it's path of travel. The waves it emits do not move with it, but continue on +their own path of travel from the point they were emitted.

+

So how does this effect the perceived sound by the Listener? Well, notice too +in the last diagram that the waves (circles) that are between the source and the +Listener are kind of compressed together. This will cause the sound waves to run +together, which in turn causes the perceived sound seem like it's faster. What +we are talking about here is frequency. The distances between the waves effects +the frequency of the sound. When the source that emits the sound is in motion, +it causes a change in frequency. You may notice too that distance between the +waves varies at different points in space. For example, on the opposite side of +the moving source (anywhere along the previous path of travel) the distances are +actually wider, so the frequency will be lower (the distance and frequency have +an inverse relationship). What this implies is that the frequency perceived by +the Listener is relative to where the Listener is standing.

+

The motion of the Listener can also affect the frequency. This one is a +little harder to picture though. If the source is still, and the Listener is +moving toward the source, then the perceived frequency by the Listener will be +warped in the same exact manner that we described for the moving source.

+

If you still have trouble picturing this, consider the following two +diagrams:

+

   +

+

These two diagrams will represent the sound in the form of a sine wave. Look +at the first one. Think of the peaks as the instance of the wave. The very top +point of the wave will be the same as the instance of the blue circle in the +previous set of diagrams. The valleys will be like the spaces in between the +blue circles. The second diagram represents a compressed wave. When you compare +the two you will notice an obvious difference. The second diagram simply has +more wave occurrences in the same amount of space. Other ways of saying this are +that they occur more often, with a greater regularity, or with a greater +frequency.

+

For anyone who is interested in some added information: The velocity of the +waves is the speed of sound. If the velocity of the source is greater than that +of the wave, then the source is breaking the sound barrier.

+

The Physics of OpenAL

+ +

Ok, either you have understood my ramblings on the Doppler effect from above, +or you have skipped it because you already have full knowledge of the Doppler +effect and just want to know how it effects the OpenAL rendering pipeline. I +think the best start to his section will be to quote the OpenAL spec directly:

+
+

"The Doppler Effect depends on the velocities of Source and Listener + relative to the medium, and the propagation speed of sound in that medium." - + chapter 3, subsection 7"

+
+

We can take this to mean that there are 3 factors which are going to affect +the final frequency of the sound heard by the Listener. These factors are the +velocity of the source, the velocity of the Listener, and a predefined speed of +sound.

+

When we refer to a "medium", what we mean is the kind of material that both +the source and Listener are "in". For example, sounds that are heard from +underwater are much different than sounds that are heard in the open air. Air +and water are examples of different mediums. The reason that sound is so +different between these mediums has to do with the particle density. As we said +before, sound is nothing but the motion of particles in the air. In a medium +with a much greater particle density the sound will be much different because +the particles are in closer contact. When they are in closer contact it allows +for the wave to travel much better. As an example of the opposite, think of +outer space. In outer space there is an extremely low particle density. In fact +there is only a few very light particles (mostly hydrogen) scattered about. This +is why no sound can be heard from space.

+ +

Ok, lets get back on topic. OpenAL calculates the Doppler effect internally +for us, so we need only define a few parameters that will effect the +calculation. We would do this in case we don't want a realistic rendering. +Rather if want to exaggerate or deemphasize the effect. The calculation goes +like this.

+

    shift = DOPPLER_FACTOR * freq * (DOPPLER_VELOCITY +- l.velocity) / (DOPPLER_VELOCITY + s.velocity)

+

Constants are written in all caps to differentiate. The "l" and "s" variables +are the Listener and source respectively. "freq" is the initial unaltered +frequency of the emitting wave, and "shift" is the altered frequency of the +wave. The term "shift" is the proper way to address the altered frequency and +will be used from now on. This final shifted frequency will be sampled by OpenAL +for all audio streaming that is affected.

+ +

We already know that we can define the velocity of both source and Listener +by using the 'AL_VELOCITY' field to 'alListenerfv' and 'alSourcefv'. The 'freq' +parameter comes straight from the buffer properties when it was loaded from +file. To set the constant values the following functions are provided for us.

+
public void alDopplerFactor(float factor);
+public void alDopplerVelocity(float velocity);
+
+

For 'alDopplerFactor' any non-negative value will suffice. Passing a negative +value will raise an error of 'AL_INVALID_VALUE', and the whole command will be +ignored. Passing zero is a perfectly valid argument. Doing this will disable the +Doppler effect and may in fact help overall performance (but won't be as +realistic). The effect of the Doppler factor will directly change the magnitude +of the equation. A value of 1.0 will not change the effect at all. Passing +anything between 0.0 and 1.0 will minimize the Doppler effect, and anything +greater than 1.0 will maximize the effect.

+

For 'alDopplerVelocity' any non-negative non-zero value will suffice. Passing +either a negative or a zero will raise an error of 'AL_INVALID_VALUE', and the +whole command will be ignored. The Doppler velocity is essentially the speed of +sound. Setting this will be like setting how fast sound can move through the +medium. OpenAL has no sense of medium, but setting the velocity will give the +effect of a medium. OpenAL also has no sense of units (kilometer, miles, +parsecs), so keep that in mind when you set this value so it is consistent with +all other notions of units that you have defined.

+ + + + + +

© 2003 DevMaster.net. + All rights reserved.

+ Contact us if you + want to write for us or for any comments, suggestions, or feedback.

+ + diff --git a/www/devmaster/sin_wave.jpg b/www/devmaster/sin_wave.jpg new file mode 100644 index 0000000..bad27c2 Binary files /dev/null and b/www/devmaster/sin_wave.jpg differ diff --git a/www/devmaster/sound_waves.jpg b/www/devmaster/sound_waves.jpg new file mode 100644 index 0000000..5a69332 Binary files /dev/null and b/www/devmaster/sound_waves.jpg differ diff --git a/www/index.html b/www/index.html index a34e552..7bdb985 100644 --- a/www/index.html +++ b/www/index.html @@ -106,7 +106,8 @@ Sharing Buffers
  • lesson 6: Advanced Loading and Error Handles.
  • -
  • lesson 7: The Doppler Effect
  • +
  • lesson 7: The + Doppler Effect
  • -- cgit v1.2.3