www.jpct.net

jPCT - a 3d engine for Java => Projects => Topic started by: paulscode on March 11, 2008, 02:38:51 am

Title: 3D Sound System
Post by: paulscode on March 11, 2008, 02:38:51 am
-- This slot is reserved for the most recent working releases --

Downloads:

Sound System (http://www.paulscode.com/source/SoundSystem/23OCT2010/SoundSystem.zip)  Version date:  October 23, 2010
The core SoundSystem library, independent from 3rd-party libraries.  It is stripped down to the bare essentials, and designed to be easily customizable with various sound library and codec plug-ins.  If memory is a concern (such as in an applet) this may be a good option, because it allows you to choose as many or as few plug-ins as you require for your project.  NOTE: The core SoundSystem library without any plug-ins is only capable of playing MIDI files.  Additional plug-ins should be added for more capabilities.  The source code and license are included in the .zip file.

Sound System jPCT (http://www.paulscode.com/source/SoundSystem/23OCT2010/SoundSystemJPCT.zip)  Version date:  October 23, 2010
The jPCT-friendly 3D sound library.  The SoundSystemJPCT class overrides the core SoundSystem libray, and provides a number of methods to make adding 3D sound to any jPCT project easy.  It includes methods for binding Listener to Camera and Sources to Object3Ds, as well as using SimpleVector parameters.  SoundSystemJPCT utilizes the LWJGL binding of OpenAL (with JavaSound as a backup option), and the J-Ogg library for .ogg support.  NOTE: The core SoundSystem library, source code, and all relevant licenses are included in the .zip file.

SoundSystem Utils (http://www.paulscode.com/source/SoundSystem/SoundSystemUtils.zip)  Version date:  August 8, 2009
Includes a SoundSystem loader, and an example XML file.


Plug-ins:

JavaSound library plug-in (http://www.paulscode.com/source/SoundSystem/23OCT2010/LibraryJavaSound.zip)  Version date:  October 23, 2010
Interface to the Java Sound API.  More compatable than OpenAL, but not as high quality and fewer features.  This plug-in utilizes JavaSound's panning and volume control methods to simulate an reasonable-quality 3D sound system.  Known bug: quickPlaying sounds will begin playing them at full volume for a split second, before switching to the correct volume.  This is a bug with the Java Sound API itself, and therefore beyond my control to correct.  An easy workaround is to add 0.02 seconds of silence to the beginning of each sound effect (the free Audacity sound editor (http://audacity.sourceforge.net/) works well for this).

LWJGL OpenAL library plug-in (http://www.paulscode.com/source/SoundSystem/24AUG2010/LibraryLWJGLOpenAL.zip)  Version date:  August 24, 2010
Interface to the LWJGL binding of OpenAL.  The LWJGL library (http://www.lwjgl.org (http://www.lwjgl.org)) is required for this plug-in to work.  This library sounds much better than Java Sound, but is not as compatable.  I recommend using the JavaSound library plug-in as a backup option.  NOTE: Please read the included LWJGL license.

JOAL library plug-in (http://www.paulscode.com/source/SoundSystem/29AUG2011/LibraryJOAL.zip)  Version date:  August 29, 2011
Interface to the JOAL binding of OpenAL.  The JOAL library (http://jogamp.org (http://jogamp.org/)) is required for this plug-in to work.  As mentioned previously, this library sounds much better than Java Sound, but is not as compatable.  I recommend using the JavaSound library plug-in as a backup option.  NOTE: Please read the included JOAL license.

WAV codec plug-in (http://www.paulscode.com/source/SoundSystem/23OCT2010/CodecWav.zip)  Version date:  October 23, 2010
Adds support for .wav files.

JOgg codec plug-in (http://www.paulscode.com/source/SoundSystem/24AUG2010/CodecJOgg.zip)  Version date:  August 24, 2010
Adds support for .ogg files using the J-Ogg library.  This codec is less compatible than the JOrbis codec, but the license is less restrictive.  Sometimes running incompatable .ogg files through a converter will make them compatable.  NOTE: Please read the included JOgg license.

JOrbis codec plug-in (http://www.paulscode.com/source/SoundSystem/23NOV2010/CodecJOrbis.zip)  Version date:  November 23, 2010
Adds support for .ogg files using the JOrbis library.  More compatible than the JOgg codec, but reads data more slowly (it may not be possible to stream more than one file simultaneously when using this codec).  This plug-in is licensed by the LGPL.  NOTE: Please read the included LGPL document.

IBXM codec plug-in (http://www.paulscode.com/source/SoundSystem/24AUG2010/CodecIBXM.zip)  Version date:  August 24, 2010
Adds support for Protracker, Fast Tracker 2, and Scream Tracker 3 (.s2m, .mod, and .xm) files using the IBXM library.  File sizes for these formats tend to be quite small, so this may be a good option for background music.  This plug-in is based on or using the IBXM library, which is bound by the BSD License.  NOTE: Please read the included license document.

JSpeex codec plug-in (http://www.paulscode.com/source/SoundSystem/24AUG2010/CodecJSpeex.zip)  Version date:  August 24, 2010
Adds support for .ogg or .wav files encoded with Speex (a compression optimized for human voice).  See http://www.speex.org/ (http://www.speex.org/) for more information.


Documentation:

JavaDoc (http://www.paulscode.com/docs/SoundSystem/)  Version date:  October 23, 2010
Also includes the JavaDocs for SoundSystemJPCT and all library and codec plug-ins, and the utils library.

3D Sound with SoundSystem (http://www.paulscode.com/tutorials/SoundSystem/SoundSystem.pdf)  PDF (download the example programs (http://www.paulscode.com/tutorials/SoundSystem/SoundSystemTutorialsSource.zip))
A tutorial-style guide to using the core SoundSystem library (last updated: April 14, 2009).

Guide to SoundSystemJPCT (http://www.paulscode.com/tutorials/SoundSystem/SoundSystemJPCT.pdf)  PDF (download the example programs (http://www.paulscode.com/tutorials/SoundSystem/SoundSystemJPCTTutorialsSource.zip))
Another tutorial-style guide to using SoundSystemJPCT. (last updated: April 14, 2009).


Demos:
(last updated: August 21, 2010)

Sound Effects Player (http://www.paulscode.com/demos/SoundSystem/21AUG2010/SoundSystemPlayerApplet.html)  (download the Source Code (http://www.paulscode.com/demos/SoundSystem/21AUG2010/SoundSystemPlayerAppletSource.zip))
Demonstrates library switching on the fly, streaming background music, playing MIDI, and playing multiple sources simultaneously.

Bullet / Target Collision (http://www.paulscode.com/source/BulletTargetCollision/)  (download the Source Code (http://www.paulscode.com/source/BulletTargetCollision/BulletTargetCollisionSource.zip))
Demonstrates the LibraryJavaSound plug-in.

Holy Bouncing Helicopter Balls! (http://www.paulscode.com/demos/SoundSystem/21AUG2010/Helicopter.html)  (download the Source Code (http://www.paulscode.com/demos/SoundSystem/21AUG2010/HelicopterSource.zip))
Currently uses the SoundSystem core -- I'm currently working on a version for SoundSystemJPCT, which will be much simpler.  Demonstrates moving through a world with multiple sources.


What's new?

- Fixed JOAL package name from the old net.java.games.joal to the new com.jogamp.openal
- Updated CodecWav link to current version
- Improved LibraryJavaSound performance slightly in non-Sun Java versions
- Handled rare pan-control exception
- Fixed fadeOutIn bug which caused fade-in effect to be silent
- Fixed a bug where certain types of .ogg files created in versions of Audacity were cut off just before the end of the sample
Title: Re: 3D Sound System
Post by: paulscode on March 11, 2008, 03:26:24 am
Project Overview:

This project began as a problem in the Support section, about OpenAL being extremely complicated, and that there needs to be a 3D sound library that is easy to understand and use.  I decided to create a class that does all the tedious stuff and simplifies OpenAL.  I have since added the ability to switch between OpenAL and JavaSound, using a common interface.  I also added automatic compatibility checking, to make life even easier for the programmer.  And of course, I extended the base library to make a version that is easily compatible with jPCT.

Now as you know, jPCT uses the Lightweight Java Game Library (lwjgl) for hardware rendering (http://www.lwjgl.org (http://www.lwjgl.org)), so chances are, your projects are already loading those libraries.  Cool thing is, lwjgl has a binding to OpenAL too, so that is what SoundSystem uses to interface with OpenAL.

This project was originally called "Sound Manager", and the thread title was "3D Sound using lwjgl binding of Open AL".  Somewhere along the way the library name changed to "Sound System", and I also decided to change the thread name.  Just thought I would point that out in case anyone decides to read through the old posts, so you won't be confused.

For a while I was regularly updating an extension of the SoundSystem class called "SoundManager", which used two different source management models for dealing intelligently with cases where more than 32 sources were playing at once.  It has since been discontinued, since there there doesn't seem to be any interest in it.  The way SoundSystem manages too many simultaneously playing sources is quite sufficient for most projects.

If anyone has any ideas for improving the library, let me know!
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: fireside on March 11, 2008, 08:05:45 am
Great project, should be very useful.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on March 12, 2008, 04:55:17 am
New version of SoundManager is out today.

JAR:
http://www.paulscode.com/libs/SoundSystem/11MAR2008/SoundManager.jar (http://www.paulscode.com/libs/SoundSystem/11MAR2008/SoundManager.jar)

Source:
http://www.paulscode.com/source/SoundSystem/11MAR2008/SoundManagerSource.zip (http://www.paulscode.com/source/SoundSystem/11MAR2008/SoundManagerSource.zip)

Here's what's new about this version:

1) SoundManager now supports attenuation (how a sound "fades" with distance).  Available types:
    No Attenuation: The sound will play at constant volume regardless of distance
    Linear Attenuation: lets you specify a distance at which a sound volume
                              will become completely silent.
                              (works for both mono and stereo sounds!)
     Logrithmic Attenuation (or Rolloff): More realistic - uses a rolloff factor
                                                    Smaller values for rolloff fade at
                                                    longer distances.  If rolloff is 0,
                                                    then the sound will not fade.
                                                    (only works for mono sounds)
     There are also a few varriables you can change to redefine the default attenuation settings.  Or you can just leave them alone and let SoundManager use the default settings:
         SoundManager.DEFAULT_ATTENUATION_MODEL
         SoundManager.DEFAULT_ROLLOFF_FACTOR
         SoundManager.DEFAULT_FADE_DISTANCE
2) You can now create multiple sources from the same sound file.  The method for creating a source is "newSource".  It is no longer necessary to call the "load" method.  SoundManager will automatically call "load" before creating a source if the sound file hasn't been loaded yet.  There are several ways to call "newSource", depending on how much information you want to supply.  SoundManager will use default values for any value you don't specify when creating your source.
    The least amount of information required to create a source is:
    newSource( sourcename, filename, toLoop );
          sourcename: A unique identifier for this source
                          (two sources may not use the same sourcename)
          filename:   The name of the sound file to play at this source
                          (if the sound file has not been loaded yet,
                              then SoundManager will load it for you)
          toLoop:     Should this source loop, or play the sound only once         
    Optional information you can specify when creating a new source:
    newSource( sourcename, filename, toLoop, x, y, z, attmodel, distORroll );
          (x, y, z):  Location in 3D space for this source.
                      Default location is the origin ( 0, 0, 0 )
          attmodel:   Attenuation model to use.  Possible values are
                              SoundManager.ATTENUATION_NONE
                              SoundManager.ATTENUATION_ROLLOFF
                              SoundManager.ATTENUATION_LINEAR
          distORroll: Either the fading distance or rolloff factor,
                      depending on the value of "attmodel".
3) .ogg files are supported.  They can be either streamed or played normally.  There are some varriables you can change to redefine how streaming is handled.  Or you can just leave them alone and let SoundManager use the default settings:
    SoundManager.STREAMING_BUFFER_SIZE   (size of each data "block")
    SoundManager.STREAMING_NUM_BUFFERS   (number of buffers to use when streaming)
4) There is also a method called "newStreamingSource".  A streaming source differs from a normal source, in that it has multiple, dynamic buffers.  Use newStreamingSource to create a source that will be streaming a sound.  newStreamingSource takes the same parameters as newSource.

To have support for .ogg files, the above jar is compiled with the source code from the j-ogg library, located at http://www.j-ogg.de (http://www.j-ogg.de).  If you want to alter the SoundManager class, you will need need to include that library before you will be able to compile.  The source files for the j-ogg library are also inside the zip file refrenced above.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: JavaMan on March 12, 2008, 02:27:04 pm
Wow, I don't need it now, but I will check this out in the future! Looks super easy to use.  ;D Which I um, like.
Jman
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: fireside on March 14, 2008, 03:52:10 am
Does the sound file need to be added to the jar?  I haven't tried it yet, just asking beforehand.  To tell the truth I have no experience with jar files at all other than putting them in a classpath.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on March 14, 2008, 09:47:40 pm
Does the sound file need to be added to the jar?  I haven't tried it yet, just asking beforehand.  To tell the truth I have no experience with jar files at all other than putting them in a classpath.
Yes, for now they need to be in the jar.  You can either put them in a package called "Sounds/", or you can change the global varriable:
SoundManager.SOUNDFILES_LOCATION
It needs to be a String containing the "/" separated path to the package containing your sound files, and must end with "/".

I am adding two more ways to load files - from a URL and from an external path.  I should hopefully be finished with this and a few other things I am working on, in the next couple of days.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: fireside on March 15, 2008, 12:39:04 am
O.K.  I'll have to read up on jars a little and get back.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on March 16, 2008, 02:42:55 am
New version of SoundManager is out today.
JAR:
http://www.paulscode.com/libs/SoundSystem/15MAR2008/SoundManager.jar (http://www.paulscode.com/libs/SoundSystem/15MAR2008/SoundManager.jar)

Source:
http://www.paulscode.com/source/SoundSystem/15MAR2008/SoundManagerSource.zip (http://www.paulscode.com/source/SoundSystem/15MAR2008/SoundManagerSource.zip)

SoundManager has changed quite a bit, so I decided to write a basic guide:
Code: [Select]
Guide to the SoundManager class

The simplest way to use SoundManager in your jPCT project:
Create the SoundManager object when you initialize things:
    soundManager = new SoundManager();
Bind the listener to the Camera after creating one:
    soundManager.bindListener( camera );
Create some sound sources:
    soundManager.newStreamingSource( "music", "deckthehalls.ogg", true );
    soundManager.newSource( "meow", "cat.wav", false );
    soundManager.newSource( "purr", "motor.wav", true );
Bind sound sources to Object3D's:
    soundManager.bindSource( "meow", my3DCat );
    soundManager.bindSource( "purr", my3DCat );
Call tick() in your main game loop:
    soundManager.tick();
Play the sounds any time you like:
    soundManager.play( "music" );
    soundManager.play( "meow" );
Call cleanup() at the end of your project:
    soundManager.cleanup();


Common Terms:
ATTENUATION:  How a sound "fades" with distance.
    If there is no attenuation, a sound will play at constant volume regardless of distance
FADE DISTANCE:  The distance at which a sound volume will become completely silent
    Used in Linear Attenuation
    (works for both mono and stereo sounds)
LINEAR ATTENUATION:  A sound's volume is inverse to it's distance
    A sound half fade-distance away will play at half volume
LOGRITHMIC ATTENUATION:  A sound's volume is a logrithmic function of it's distance
    A more realistic attenuation model - uses a rolloff factor
    (only works for mono sounds)
ROLLOFF:  A value used in logrithmic attenuation.
    Smaller values for rolloff fade away at longer distances
    If rolloff is 0, then the sound will not fade
STREAMING:  Using multiple buffers to break long sound files, (like background music) up
     into smaller pieces, so you can start playing immediately, rather than waiting to load.


Global References:
Attenuation models:
    public int ATTENUATION_NONE    = 0;  // no attenuation
    public int ATTENUATION_ROLLOFF = 1;  // logrithmic attenuation
    public int ATTENUATION_LINEAR  = 2;  // linear attenuation

Global Varriables (can be changed to fit your preference):
Package where the sound files are located:
    public String SOUNDFILES_LOCATION = "Sounds/";   
Attenuation model to use if not specified (one of the references listed above):
    public int DEFAULT_ATTENUATION_MODEL = ATTENUATION_ROLLOFF;
Default value to use for rolloff model when value isn't specified:
    public float DEFAULT_ROLLOFF_FACTOR = 0.03f;
Default fade distance for linear model if value isn't specified:
    public float DEFAULT_FADE_DISTANCE = 500.0f;   
Number of bytes to load at a time when streaming:
    public int STREAMING_BUFFER_SIZE = 4096*16;
The number of buffers used for each streaming sorce:
    public int STREAMING_NUM_BUFFERS = 2;   
The approximate size of a normal .ogg file:
    private int OGG_NORMAL_SIZE = 1048575;


Easy Interfacing with jPCT
When using these methods, don't forget to call tick() in the main game loop:
    bindListener( Camera c )
        Listener will automatically follow and align with the Camera object

   bindSource( Object3D o )
       A source will automatically follow an Object3D



Method Descriptions:

public void cleanUp()
    Stops all sounds and clears up any used resources

public boolean bindListener( Camera c )
    Orientates the listener to match the Camera orientation

public boolean bindSource( String sourcename, Object3D obj )
    Associates a sound source with an Object3D to follow

Releases a source from it's associated Object3D
    public void releaseSource( String sourcename )

public void releaseAllSources( Object3D obj )
    Releases all sources bound to this Object3D
    (Usually called before deleting an Object3D with sources attached to it, but not required)

public void tick()
    Re-aligns the listner to the camera, and keeps sources folowing the Object3D's they are bound to
    Should be called within the game loop
    (only required if you are using bindListener or bindSource)

public boolean load( String filename )
    Load the specified file (only used for non-streaming sources).
    It is not necessary for you to call this method in your program, but you can if you want to.
    (For example, you could load all the sounds at once and show a progress bar)
    SoundManager will automatically call this method if necessary when creating a source
    If "filename" is a url, it must begin with "http://"
    Returns "true" if there were no problems loading the file
   
public boolean newSource( String sourcename, String filename, boolean toLoop )
public boolean newSource( String sourcename, String filename, boolean toLoop, int attmodel )
public boolean newSource( String sourcename, String filename, boolean toLoop, int attmodel, float distORroll )
public boolean newSource( String sourcename, String filename, boolean toLoop, float x, float y, float z, int attmodel )
public boolean newSource( String sourcename, String filename, boolean toLoop, float x, float y, float z, int attmodel, float distORroll )
public boolean newStreamingSource( String sourcename, String filename, boolean toLoop )
public boolean newStreamingSource( String sourcename, String filename, boolean toLoop, int attmodel )
public boolean newStreamingSource( String sourcename, String filename, boolean toLoop, int attmodel, float distORroll )
public boolean newStreamingSource( String sourcename, String filename, boolean toLoop, float x, float y, float z, int attmodel )
public boolean newStreamingSource( String sourcename, String filename, boolean toLoop, float x, float y, float z, int attmodel, float distORroll )
    Create a new normal or streaming source.  A streaming source differs from a normal source, in that it has multiple, dynamic buffers.
    SoundManager will use default values for any value you don't specify when creating your source.
    sourcename: A unique identifier for this source (two sources may not use the same sourcename)
    filename: The name of the sound file to play at this source.  If "filename" is a url, it must begin with "http://"
        (if the sound file has not been loaded yet, then SoundManager will load it for you)
    toLoop: Should this source loop, or play the sound only once
    (x, y, z):  Location in 3D space for this source.  Default location is the origin ( 0, 0, 0 )
    attmodel:   Attenuation model to use.  Default is the value in DEFAULT_ATTENUATION_MODEL
    distORroll: Either the fading distance or rolloff factor, depending on the value of "attmodel".

public boolean deleteSource( String sourcename )
    Deletes the specified source

public boolean setPos( String sourcename, SimpleVector pos )
public boolean setPos( String sourcename, float x, float y, float z )
    Moves the named sound to the specified location.

public boolean play( String sourcename )
public boolean stop( String sourcename )
public boolean pause( String sourcename )
public boolean rewind( String sourcename )
    Controls for playing, stopping, pausing, and rewinding a source

public boolean playing( String sourcename )
    Returns true if the source is playing

public void moveListener( float xStep, float zStep )
public void moveListener( SimpleVector step )
public void moveListener( float xStep, float yStep, float zStep )
    Moves the listener, relative to their current position.

public void setListenerPos( float xNew, float zNew )
public void setListenerPos( SimpleVector posNew )
public void setListenerPos( float xNew, float yNew, float zNew )
    Positions the listener at the coordinates provided.

public void turnListener( float angle )
    Turns the listener counterclockwise by "angle" radians, relative to their current orientation.

public void setListenerOrientation( float angle )
    Sets the listener's orientation (counterclockwise rotation in radians along the y-axis)

public void setListenerOrientation( SimpleVector look, SimpleVector up )
public void setListenerOrientation( float lookX, float lookY, float lookZ, float upX, float upY, float upZ )
    Sets the listener's orientation based on a look-at point and an up-direction

public void recalculateDistances()
    Recalculates the distances between each source and the listener, and recalculates the gain if a
    source is using linear attenuation.  It is not necessary for you to use this method.
    SoundManager will automatically call this method when the listener moves or rotates, or a source moves.

Here's a rough overview of what's new about this version:

1) I moved the SoundManager class from package "Sounds" to a package called "paulscode.sound"

2) Sounds can now be loaded from either the jar, or from a url.  When loading from a url, the filename must begin with "http://" (that is how SoundManager determines wheter to look in the jar or go to a URL to load a file).  I didn't add the ability to load files from a harddrive directory (I figure it is just as easy to load them from the jar).

3) I corrected a math error in the setListenerOrientation( float angle ) method.

4) I added looping for streaming .ogg sources, and corrected a problem where the last block of data was getting cut off.

5) I rewrote the methods for handling streaming threads, to correct an exception I was getting when trying to clear buffer memory on exit.  Buffers are now all being cleared correctly when SoundManager.cleanUp() gets called.

6) I added in two new functions to make using SoundManager with jPCT a breeze.  They are designed to let you focus on the graphics, and not have to wory about sound. The functions are:
    a) bindListener( Camera c )
        Called after creating the camera.  The SoundManager will automatically translate and rotate the listener to match the camera any time the camera's position or orientation changes.  After calling this method, you don't have to even think about translations and rotations to keep the listener and camera in-sinc - SoundManager does it for you.
    b) bindSource( String sourcename, Object3D obj )
        Called after creating a new source and an Object3D.  Similar to bindListener, except it binds a sound source to an Object3D.  You can attach as many sources as you want to an object, and they can be regular, streaming, looping, whatever.  Again, after calling this method, you don't have to worry about moving your source to match the object - SoundManager takes care of it.

The only thing you have to remember when using either of the two "bind" methods, is you have to call SoundManager.tick() from inside your main game loop (that is the method where SoundManager checks if anything has moved).

I created a simple applet to demonstrate the bind features, which you can see at:
LINK NO LONGER EXISTS

Rotate the camera with the left and right arrow keys, and move the gear's depth with the up and down arrow keys.  You can get the source code for this applet at:
LINK NO LONGER EXISTS

One potential bug I am looking into is the fading between left and right speakers only seems to work when the source is close to the listener.  I haven't determined if it is a limitation with my soundcard, or a bug in the code.  I am looking into this further.  It would be helpful if a few people could run the above applet and see if they experience the same thing.  Thanks in advance!
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: fireside on March 16, 2008, 03:47:44 am
Cool applet.  I'm going to have to look at the source. 
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on March 19, 2008, 03:13:44 am
One thing you may have noticed if you've tried to create a lot of sources (depending on your sound card), at some point the sources will just not play - ie there is a maximum number of sources that can be played at one time.  Unfortunately, it seems that a source's distance from the listener has no bearing on which sources OpenAL decides to play when you have too many.  This would pose a serious problem in a 3D game where you could potentially have hundreds or thousands of sound sources.

So what I've decided to do, is make SoundManager smart enough to cull unnecessary sources.  Basically, there would be a "maximum source number".  Sources will have a priority based on their distance from the listener, closer sources having priority over further away sources.  Sources will be culled down to the maximum source number based on their priority.  Here is an illustration to demonstrate what I am talking about:

(http://www.paulscode.com/images/SourceDistance.jpg)

In this example, the maximum source number is four.  The green circle is the listener.  The four red circles are sources which are allowed to play, while the grey circles are sources that would be culled.  Which sources are culled will change dynamically as the listener or sources move, or when non-looping sounds stop playing.

I will keep you posted on how progress goes for this concept.

Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: fireside on March 19, 2008, 03:47:43 am
I was wondering about that very thing.  Mostly because it seemed like it would be a waste of resources. 
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on March 25, 2008, 03:08:10 am
I have finished adding the infrastructure for source culling.  It is late here in Maryland, so I'm going to bed - I will debug the code more thoroughly tomorrow and post the source.  A couple of basic initial tests have been promising, though - no exceptions, error messages, or lag ( always a good sign ;D ).  I am going to run some more "extreme" cases and see if I can get the class to break down.  I'll try and release the code tomorrow after running more tests and creating a nice demo applet to showcase the new source-culling.  Good night all!
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on March 26, 2008, 03:36:05 am
New version of SoundManager is out today.
JAR:
http://www.paulscode.com/libs/SoundSystem/25MAR2008/SoundManager.jar (http://www.paulscode.com/libs/SoundSystem/25MAR2008/SoundManager.jar)

Source:
http://www.paulscode.com/source/SoundSystem/25MAR2008/SoundManagerSource.zip (http://www.paulscode.com/source/SoundSystem/25MAR2008/SoundManagerSource.zip)

I finished the code for source culling, and I have run a number of tests.  I have found that in cases when there are thousands of sources, there is a noticable lag.  I am looking into this to see if I can streamline things a bit more.  For now, using around 500 sources or so runs well (and sounds really cool ;D)

There is a logic error somewhere I am having trouble locating, related to remembering to replay looping sources when they are reactivated.  For now I put a hack in that replays every source when it is reactivated (obviously not the correct behavior, but it let me debug the rest of the code).

I created an applet to demonstrate the new source culling, which you can see at:
LINK NO LONGER EXISTS

Move through the world with the arrow keys.  You can get the source code for this applet at:
LINK NO LONGER EXISTS

Let me know if you have any problems with the above applet.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: fireside on March 26, 2008, 05:06:50 am
The applet seemed to run fine for me.  Nice job.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: JavaMan on March 26, 2008, 12:40:51 pm
Hi, I tried out the applet. It looks cool all those cubes flying around. :o Is the applet supposed to play sound? I don't hear anything.

Jman
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: EgonOlsen on March 26, 2008, 02:05:18 pm
Me neither. Boxes yes, sound no. This is on a (quite crappy) Dell machine with some SoundMAX onboard sound. The console doesn't print out anything helpful either... ???
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: JavaMan on March 26, 2008, 02:23:28 pm
I'm using a Dell with a SoundMax onboard card as well.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: Jonas on March 26, 2008, 08:11:37 pm
Hi

Works fine for me -> soundblaster live!

Cool stuff.. ;D
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: EgonOlsen on March 26, 2008, 11:16:04 pm
It kinda works on the EEEPC...the 3d effect is working, but the sounds are all broken. Then again, this happens with all OpenAL stuff on this machine, so i wouldn't worry too much about it.
I should really test it on a "real" PC, but i'm too lazy to boot it right now... ;D
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on March 26, 2008, 11:21:38 pm
I ran some tests on a few of my other machines, and found a laptop that the sound doesn't play on either.  I am going to get on the lwjgl forums and see if I can find out anything about this.  I let you know what I learn.  Thanks for the feedback!
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: Kearnan on March 27, 2008, 12:25:12 am
Fun applet.  It worked fine and the sound was great (weird and fun) but great!  Nice job.  Note: Using the Realtek AC'97 audio that came with my Asus Motherboard (basic sound stuff)  Sound was fine, 3D and all.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on March 30, 2008, 03:20:11 am
I have been looking into the no-sound problem occurring on some machines, and I believe the problem is not related to OpenAL.  It seems to only be an issue with the lwjgl AppletLoader natives jar's.  When running the exact same code in an application using the natives dll's instead, it works perfectly (at least on the test laptop where I experienced this issue).  Here is a link to the Source Culling demo in an application:
LINK NO LONGER EXISTS

It would be great if those of you who were not hearing any sound could run the application and see if it works.  I am currently writing a couple of bare-bones example sourcecodes to post on the lwjgl forum and ask about this issue.  For now it doesn't seem there is much I can do, as this appears to be an lwjgl issue.

I am continuing to clean up the SoundManager class.  I have noticed an exception that is randomly getting thrown when playing a source.  It seems to happen only once, when the program first starts running, then never again afterwards.  It shows up on the Java console as an exception in method SoundManager.play() line 1015.  It seems to occurr more often on the laptop than on my main computer.  It could be related to an insufficient number of voices available on the sound card and OpenAL culling some without telling me.  I am looking into this problem as well.  For now I am just catching the exception and ignoring it, until I can figure out what is causing the error and how to correct it.

One other Exception is a null Pointer exception in paint() line 212.  I know what is causing this (simple logic error), and will have it corrected in the next SoundManager demo.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: JavaMan on March 30, 2008, 12:38:44 pm
Hi, I tried it out. The sound works in the app.

Quote
One other Exception is a null Pointer exception in paint() line 212.  I know what is causing this (simple logic error), and will have it corrected in the next SoundManager demo.
I'm not sure if this is right, but, judging from the output, I think the problem with the paint could be you are trying to paint to the Canvas and the framebuffer is still being loaded?  ::) So, the Canvas isn't in the frame yet. Just a suggestion.

Anyways, the sound comes through clean. It sounds like a battleground.

Jman

Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on March 30, 2008, 06:47:51 pm
I'm not sure if this is right, but, judging from the output, I think the problem with the paint could be you are trying to paint to the Canvas and the framebuffer is still being loaded?  ::) So, the Canvas isn't in the frame yet.

Thanks, that is a good thing to remember.  However in this case, the "Null Pointer" in question is the SoundManager object, not the Canvas.  This problem is a result of an ugly hack I made to overcome the problem of not being able to play a sound from an applets "init()" method.  The reason you are also seeing it in the application is that I coppied and pasted the code from the applet, and just changed jApplet to jFrame and added a main method.

The error is in this ugly "run once" loop I created to make all the sounds start playing at different times:
Code: [Select]
        if( runOnce )
        {
            // Play the sounds:
            for( int x = 0; x < OBJECT_COUNT; x++ )
            {
                soundManager.play( "sound_" + x );  // <<-------------EXCEPTION ON THIS LINE
                try
                {
                    // Sleep for a bit, so we dont peg the CPU:
                    Thread.sleep( 1000 / OBJECT_COUNT );
                } catch( Exception e ){}
            }
            runOnce = false;
        }
(In case you were wondering, this loop is also why there is a one-second pause before the graphics start drawing)

The reason for the exception, is that apparently "paint()" gets called from a seperate thread.  Therefore, it tries to access the SoundManager object before it is fully instantiated.  The reason you only see the exception once (or a couple of times on a slower cpu), is that after sleeping a bit at the end of the loop, the SoundManager finished being created, and is no longer null.  (This is quite obvious in retrospect).

Now obviously the "paint()" method is NOT the right place to be doing this anyway (really dumb hack on my part).  The correct way to do this is to get rid of that "run once" stuff, remove the loop from the "paint()" method, and stick it at the top of the method that runs the main game loop after creating the Sound Manager (so both are on the same thread).

At any rate, the next demo I make won't have this problem.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: JavaMan on March 30, 2008, 07:41:10 pm
Ok, that makes sense.

Quote
Now obviously the "paint()" method is NOT the right place to be doing this anyway (really dumb hack on my part).  The correct way to do this is to get rid of that "run once" stuff, remove the loop from the "paint()" method, and stick it at the top of the method that runs the main game loop after creating the Sound Manager (so both are on the same thread).

I agree, but then again its just a demo program.  ;)

Jman



Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on March 30, 2008, 09:22:43 pm
As my computer programming instructor used to say, "There are two ways to solve every problem.  There's the right way, and then there's Paul's way". ;D  I tend to think outside the box a little too much, and sometimes that results in problems like this one.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on April 01, 2008, 02:15:50 am
I have posted some questions about applets vs. applications on the lwjgl forums, so I am just waiting for a response before I can provide more information about that issue.  In the mean time, I have been tackling the other things that SoundManager needs fixed.  Operating on the assumption that the exception showing up randomly is related to OpenAl running out of channels and quietly culling sources, I added in some checks in the "new source" method, and a couple of other places, that dynamicly change the value for maximum source number based on available voice channels.  So far I have not gotten the exception in any of my tests, so I believe that problem is now fixed.  I have also located the logic error that was making the SoundManager forget which sources were playing before being culled, so I have removed that temporary hack, and the SoundManager now behaves exactly the way it should.  One final thing I am adding is "priority sources".  These sources will not be subject to culling based on distance (such as background music).

So at this point, this project is nearly complete.  The next release should be perfectly functionable in just about any project (although probably more compatible if used in applications than if used in applets).  Only restriction is you need to keep the number of active sound sources to 500 or less at any given time.  I am just waiting on the verdict from the lwjgl forums before I release the source.  I am going to do a bit of streamlining and commenting in the meantime.

Just so I have something to do, I am considering rewriting another SoundManager completely from scratch, using a different approach.  In the current SoundManager, the whole focus is on sources, and culling or reactivating them based on distance from listener.  I want to try a different approach, focused on soundcard voice channels rather than on sources.  In this new approach, I would set up all the active channels I could when the sound manager is created.  Then when a source requests to play, it will play on the next available channel.  If no channels are open, it will not play, and if it is a looping source, it will wait for a channel to open up.  Calling "play()" will not actually play the sound, it will just set a flag telling SoundManager that the user requested to play the sound.  Then on a seperate thread, the Sound Manager will sort the sounds by distance, then go down the list and start playing as many as it can on the available channels.

The whole point of making another SoundManager would be just to see which method is faster and can handle more sources.  If the new SoundManager works better, I will discard the old one and release the new one.  If not, at least it will be good programming practice  ;D
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on April 03, 2008, 03:48:28 am
Update on the lwjgl appletloader sound issue.

First of all, I loaded up two ratty old dell notebooks I had in storage, and both experience the same no-sound issue for my applet.  So that makes 3 out of my 6 test machines that experience the problem. :o

I have been having a long discussion on the lwjgl forums, and today I got a link to an applet written by "javalwjgl".  He is using the lwjgl binding of OpenAL, and the applet is being loaded with the appletloader:

http://kappa.javaunlimited.net/betashot/betashot.html (http://kappa.javaunlimited.net/betashot/betashot.html)

The sound for it works on my problem laptops.  So this would seem to indicate that the problem is correctable, and I am doing something incorrectly in my Java code, the html code, and/or which jar's I am loading.  I just need to figure out what he did differently with his applet, and figure out how to incorporate that change into mine.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: fireside on April 03, 2008, 04:14:56 am
Cool game, but why did I get a warning at the start?  I thought that got fixed somehow with the applet loader?  I didn't get a warning on your applet.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on April 03, 2008, 04:29:33 am
Don't really know.  He is obviously doing something different with his applet than I did with mine.  He may have put his own signature on the applet  -  I just used the signature that was already on the appletloader jar, so if you ever ran another appletloader program before mine, then you already got the warning and chose to trust that signature.  That is just a guess, though.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on April 04, 2008, 11:58:28 pm
I haven't gotten any response on the lwjgl issue in a couple of days.  I guess nobody can figure out what I did wrong with my applet.  This is an issue I need to solve, because I am trying to collect all the pieces I'll need to develop a browser-based game, and I want it to be compatible with as many computers as possible.  So I've decided to spend a lot of time this weekend putting a real effort into solving this problem.  Some places I am going to start are:

1)  I will start with the most basic sound program possible, so I am going to copy and paste the first OpenAl demo program on the lwjgl site, and put it into an applet.  I will not add any more complexity to it than necessary so I know for sure that there is not a problem with the Java code.  Get that working on my test machines, and then take what I learn, and apply it to a more complicated applet.

2)  I will spend some time searching the internet.  The lwjgl binding of OpenAL is not well doccumented (seems that most people with OpenAl lwjgl experience are not creating applets).  Because of this, I have been having trouble finding any useful information related to my problem.  What I really need to find is some source code or a guide, so that I can compare and see what I am doing wrong.  I highly doubt I am the only person who has had this problem, so I just need to find another person who had solved it.

3)  I will try recreating the native jars and resigning them to see if that helps at all.

If anyone can think of some more suggestions for me to try, let me know!
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: JavaMan on April 05, 2008, 01:08:27 am
Quote
(seems that most people with OpenAl lwjgl experience are not creating applets
Hey, maybe you should try distributing your game with JavaWeb start instead of an applet? That way maybe more people could help you out over at the lwjgl forums.
Just a suggestion.
Jman
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on April 05, 2008, 01:59:41 am
I have awesome news and lowsy news.

First the awesome news ... I solved the no-sound problem!!  It just occurred to me when I was re-reading this thread, and I got to the recent posts about that SoundManager exception.  It hit me that a similar "thread issue" like the one that was causing that exception could be causing this no-sound problem -- if init(), like paint(), were called from a seperate thread (doesn't seem logical to me that this would be the case, but you never know).  I tried moving all the sound stuff out of the init() method, and sticking it all right before the main game loop.  And it worked!  On all three test machines.

Now for the lowsy news.  I assume everyone creating an applet using jPCT is creating a number of their Object3Ds in the init() method (makes sense, right?).  That would also be the obvious place to instantiate the SoundManager and bind sound sources to the objects.  Problem is, creating a new SoundManager object initializes the sound system ... which can't be initialized in the init() method. (chicken .. egg .. no, chicken ...)

So that leaves me with two options:

FIRST OPTION
Add a new method in SoundManager called something like "initOpenAL()" which the user must call from somewhere outside the init() method of their applet.  The requirement to call this method would carry over to applications as well.  This would make the SoundManager slightly more difficult to use, and users would have to ensure that they called that method before trying to play any sounds.  This option would also require a somewhat significant change to the SoundManager class, since I would want to be able to bind sources to objects before those sources have necessarily been created (some type of queueing would accomplish this).

SECOND OPTION
Make a clear note that SoundManager MUST NOT be instantiated in the init() method, or sound will not work on some computers.  Then let the user figure out how to change their applet to follow that rule.


So which of these options would you prefer, or can you think of another alternative?


For now, I guess the simplest work-around (using option #2) would be to create a new method like "init2()", and move everything from "init()" over to it, then call init2() before starting the main game loop.  Just seems kind of hackish to me.

Hey, maybe you should try distributing your game with JavaWeb start instead of an applet? That way maybe more people could help you out over at the lwjgl forums.
That would be the obvious solution, but I kind of have my heart set on the game being an applet.  My idea for the game is to have it inset into a webpage, with things happening outside of the game applet itself (like private chat, trading, etc).  Besides, I want the SoundManager to work well for both applets and applications.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on April 05, 2008, 02:26:42 am
For now, I guess the simplest work-around (using option #2) would be to create a new method like "init2()", and move everything from "init()" over to it, then call init2() before starting the main game loop.  Just seems kind of hackish to me.

ARgh!  I just tried this, forgetting that paint() gets called from a seperate thread..  Another lovely exception!

So I guess Option #1 is it.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: fireside on April 05, 2008, 04:38:11 am
I agree with the applet thing.  I don't know, I just like applets a lot better than web starts.  I hope you'll paste some example code with your manager because I have zero experience with applets right now.  I just know that's how I want my game to eventually run.  Right now I'm more or less following the car demo way of instantiating 3d objects in their own class.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: EgonOlsen on April 05, 2008, 12:02:07 pm
Wouldn't it be an option to create the SoundManager anywhere but to ensure that OpenAL will be initialized the first time someone wants to play a sound?
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on April 05, 2008, 12:51:46 pm
Wouldn't it be an option to create the SoundManager anywhere but to ensure that OpenAL will be initialized the first time someone wants to play a sound?

Aha!  Yes, that is very good.  Then I would just make a note in the doccumentation that sounds can not be played from inside the init() method.  Come to think of it, you already couldn't do that ( the reason I wrote that ugly "run once" loop in the paint() method before).  That was one of the little bugs I was going to see if I could fix -- I guess now I can call it a "feature"  ;D ).

I like that a lot - wouldn't require the user to change anything.  You'd still use SoundManager exactly the way it works now.  Thanks for the great suggestion!
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on April 05, 2008, 01:04:25 pm
While thinking about how to impliment that last idea, I think I know a way to make it so sounds could be played from the init() method or anywhere else.  Assuming the root of the problem is a thread issue (which I am 99% sure it is), all I have to do is make it so all initialization, playing, pausing, stopping, rewinding, etc. is all done on the same thread.  I just need to set up a Command Buffer, which queues up commands from the user.  Then a seperate running thread will do all the work, like initializing the sound system if it hasn't been initialized yet, sorting sources, playing sounds, etc.

Actually, since I was going to do something exactly like this for the new SoundManager class, I think I will start from scratch here rather than trying to change the entire structure of the class I have now.  I could even allow the user to choose which Management Model to use -- source culling or channel monitoring.

So many ideas ... I am firing up NetBeans now!
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: EgonOlsen on April 05, 2008, 01:17:17 pm
While thinking about how to impliment that last idea, I think I know a way to make it so sounds could be played from the init() method or anywhere else.  Assuming the root of the problem is a thread issue (which I am 99% sure it is), all I have to do is make it so all initialization, playing, pausing, stopping, rewinding, etc. is all done on the same thread.  I just need to set up a Command Buffer, which queues up commands from the user.  Then a seperate running thread will do all the work, like initializing the sound system if it hasn't been initialized yet, sorting sources, playing sounds, etc.
Sounds exactly like what the AWTGLRenderer does to ensure that everything OpenGL-related happens in the AWT event dispatch thread.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on April 06, 2008, 09:05:29 pm
I have finished putting together the basic infrastructure for the new Command Buffer.  It is still full of bugs, so I will continue working on it.  The main bug right now is the computer lagging on random frames.  I believe this is most likely a thread communication problem.  I may have to rethink how I am doing this, so any suggestions would be helpful.  The way it works now is, the commandBuffer is a LinkedList containing CommandObjects.  There is a locking mechanism to prevent two threads from accessing the list simultaneously:

Thread #1 (End-user's thread, when they call SoundManager.tick()):
Code: [Select]
while( commandBufferLocked ){} // wait for other thread to finish

commandBufferLocked = true;  // tell other threads to wait

  // ... queue commands to move sources so they match Object3Ds

commandBufferLocked = false;  // tell other thread we are finished

Thread #2
Code: [Select]
while( commandBufferLocked ){} // wait for other thread to finish
commandBufferLocked = true;  // tell other threads to wait

  // ... actually move the sources

commandBufferLocked = false;  // tell other thread we are finished

This seems like it should work, but I want to rule it out as the source of the lag problem.  Is there another way to do this without a LinkedList.  I am thinking like some kind of queue you can "pop" in the order it was filled, and be sure whatever you get is whole / not corrupt?

This project is definitely teaching me a lot about threads!
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: JavaMan on April 06, 2008, 09:25:33 pm
I could imagine a problem with the boolean commandBufferLocked variable. It could be possible that both threads would access the variable at the same time. I suggest some method like this to change the variable.

Code: [Select]
public synchronized boolean commandBufferLockControl(boolean b, int type){
  if(type==1){
      commandBufferLocked=b;
      return b;
  }
   return commandBufferLocked;
}

This way setting and reading the commandBufferLock can be synchronized. I think though that using a LinkedList is good. I don't know if using an iterator on a HasSet would be any faster.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: EgonOlsen on April 06, 2008, 11:14:46 pm
Code: [Select]
while( commandBufferLocked ){}...this is a busy wait loop. Not a good idea. Just let the thread sleep and wake him up when the command buffer has data to be processed. And as JavaMan said: Use synchronized blocks instead of trying to rebuild your own semaphore logic by using booleans.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on April 07, 2008, 12:00:55 am
Code: [Select]
public synchronized boolean commandBufferLockControl(boolean b, int type){
  if(type==1){
      commandBufferLocked=b;
      return b;
  }
   return commandBufferLocked;
}
I am fairly new to Java and have never seen "synchronized" syntax before - I am going to read up on this right now.  Thanks for this tip - exactly the kind of thing I was looking for.

Code: [Select]
while( commandBufferLocked ){}...this is a busy wait loop. Not a good idea. Just let the thread sleep and wake him up when the command buffer has data to be processed.
That is an excellent idea.  I was actually trying to think of how to do this with sleep instead of a busy "while" loop.  I was confusing myself by trying to come up with two threads alternately sleeping while the other was using the buffer, then one waking the other up and vice-versa.  I hadn't considered this simple solution of just having one "Command Processer" thread sleep away and the second thread waking it when a new command goes into the list ( :-[ - DUH!).

The other thing I need to do smoothly is re-sorting the sources list when source positions change.  This same concept should work nicely here as well -- have a "Sources Sort" thread awaken whenever distances change.

These are both great ideas, thanks a lot!
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on April 07, 2008, 01:26:35 am
I have read up on synchronizing threads, and I had a thought about how to do the Command Buffer.  I would create a method like this in SoundManager:

Code: [Select]
    public synchronized void CommandQueue( CommandObject newCommand )
    {
        if( newCommand == null )
        {
            // execute queued commands
        }
        else
        {
            // queue a new command
        }
    }

This one method should work for both executing commands and queueing new commands, and since it is "synchronized", I can just let Java's built-in logic take care of regulating the threads.  How does this sound to you?
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: raft on April 07, 2008, 07:18:20 am
i guess you need to read javadocs of these methods ;)

* Object.wait() (http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Object.html#wait())
* Object.notify() (http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Object.html#notify())
* Object.notifyAll() (http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Object.html#notifyAll())

concurrency chapter (http://java.sun.com/docs/books/tutorial/essential/concurrency/index.html) of java tutorial may also help

r a f t
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on April 07, 2008, 01:35:46 pm
concurrency chapter (http://java.sun.com/docs/books/tutorial/essential/concurrency/index.html) of java tutorial may also help
Thanks a lot - very good tutorial.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on April 11, 2008, 02:32:01 am
The new thread infrastructure is in place, and I have done some extensive debugging before putting in the actual sound parts.  I did some conflict tests, and confirmed that without the "synchronized" methods, there were a lot of things that could go wrong in rare instances.  With things synchronized it runs somewhat slower, but has zero conflicts.  I have begun adding in the actual OpenAL stuff (I should have it finished this evening), then I am going to run more tests and do some comparisons between the two management models.  Some differences I have already discovered about them are:

1) The source culling method (the one used in the flying boxes demo) ensures that the closest sounds will play.  The drawback is that if there are not enough channels available, it cuts off other sounds before they finish in order to play the closer ones.  Since sounds always begin playing from the beginning (even when they were culled then reactivated), in cases where there are many looping sources of the same sound effect (like in the boxes demo), you hear the beginning of the sound a lot.  It's something to keep in mind when using this management model, but I still think this is going to be the best model to use in most cases.

2) The channel monitoring method (the new one) ensures that every time a sound starts, it plays from beginning to end, unless it moves beyond the cull distance (cull distance can be set to a really large number to turn this culling feature off).  The drawback is that closer sounds may not play if there are no channels open for them to play on.  Rather than just playing queued sources in just any old order, I've tried to make this management model somewhat intelligent.  It sorts the queued sources by distance before trying to play them, so the channels fill up with the closest sounds, but this isn't a perfect solution.  For example, you could have like 40 sources, some of them quite far away, which all get queued to play, filling up all available channels.  A second later, a really close source could get queued to play, but end up not playing because there are no channels open.  That's an important thing to keep in mind when using this management model.

If nothing goes wrong, I am planning to release the new SoundManager this weekend, along with a nice demo applet, and the source code as always.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on April 12, 2008, 02:38:39 pm
Things are coming along nicely.  All the OpenAL code is back in place, and the three threads are working together beautifully so far.  I haven't done any really intensive tests just yet, because I am working out a logic error related to sources starting out initially culled.  After I get it fixed, then I will start on a test applet.  I haven't decide what I want it to be yet :)
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on April 13, 2008, 10:13:32 pm
New version of SoundManager out today!
http://www.paulscode.com/source/SoundManager/13APR2008/SoundManager.jar (http://www.paulscode.com/source/SoundManager/13APR2008/SoundManager.jar)
Source Code:
http://www.paulscode.com/source/SoundManager/13APR2008/SoundManagerSource.zip (http://www.paulscode.com/source/SoundManager/13APR2008/SoundManagerSource.zip)

I also made a demo applet:
http://www.paulscode.com/source/SoundManager/13APR2008/Helicopter.html (http://www.paulscode.com/source/SoundManager/13APR2008/Helicopter.html)
Applet Source Code:
http://www.paulscode.com/source/SoundManager/13APR2008/HelicopterSource.zip (http://www.paulscode.com/source/SoundManager/13APR2008/HelicopterSource.zip)

This has been a major overhaul of the class - I started from scratch and rebuilt it from the ground up.  Some new features about this version:

    All OpenAL calls are all done from a single thread.  This required a complicated Command Buffer infrastructure.

    Sorting and source management are now all done on a seperate thread.

    There are two management models to choose from:  active culling (plays closest sounds and culls further away sounds), and channel monitoring (plays closest sounds, only when channels are open - doesn't cull sources).

    Priority sources (will not be culled, example: background music).


In order to keep SoundManager simple to use, the actual methods and the way the class is used, have not changed very much from the previous version.  A couple of minor things have changed:

    I changed the method setPos() to setPosition(), just to be consistant in my naming conventions.  I believe I made a couple of other minor method name changes, but I don't recall which ones.  If something in your program breaks though, it shouldn't be very difficult to find the correct method name, as the changes are very minor.

    The basic commands like play, stop, rewind, etc. no longer return booleans for success or failure.  This is because now they merely queue a command which gets executed on a seperate thread.

    There are new constructors for newSource() and newStreamingSource().  They are the same as the previous constructors, plus a new first arguement being a boolean.  Setting this argument to "true" makes the new source a "priority source" (doesn't get culled).  All the old constructors still exist, so if priority is not specified, SoundManager assumes a new source is not a "priorty source".

    There is a new varriable the user can set:  MANAGEMENT_MODEL.  Possible values are MANAGEMENT_ACTIVE_CULLING and MANAGEMENT_CHANNEL_MONITORING.  MANAGEMENT_MODEL can be changed dynamically at any time in your program.

    There are some new methods that give you access to the OpenAL components like source buffer identifiers and the like.  This is just in case anyone wants to do OpenAL stuff not currently supported by SoundManager, like doplar effect, directional sources, etc.

I plan to write a new guide to fully explain how to use the class, including all the new features.

Because there have been such extensive changes, there are bound to be problems.  I have run tests and everything seems stable, but the best way to find all the bugs is for people to start using the class.  If you have any problems, error messages, exceptions, etc. let me know, and I will look into it.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: fireside on April 13, 2008, 10:37:01 pm
Interesting applet.  Nice work on the sound manager. 
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: EgonOlsen on April 13, 2008, 11:35:46 pm
I'm going to use this in "nameless Bomberman clone", when it's time to add sound to it. Would it be possible to add a kind of fallback mode that uses Javasound instead? It doesn't have to adjust volume or position, just play some sound in case that OpenAL doesn't work. My experience from Paradroidz is, that OpenAL isn't that reliable on some platforms, while Javasound always worked (after setting the mixing to software...). For me, this can be a very simple fallback. Something like:

Code: [Select]
import java.io.*;
import javax.sound.sampled.*;

public class StrippedSound {

   private static Mixer mixer;
   private byte[] data;
   private AudioFormat format;
   private DataLine.Info dataLineInfo;
   private boolean ok=false;
   private Clip currentLoopClip=null;
   private Clip lastClip=null;
   private boolean mute=false;

   static {
      Mixer.Info[] mixers=AudioSystem.getMixerInfo();
      for (int i=0; i<mixers.length; i++) {
         if ("Java Sound Audio Engine".equals(mixers[i].getName())) {
            mixer=AudioSystem.getMixer(mixers[i]);
         }
      }
   }

   public static void main(String[] args) {
     StrippedSound s1=new StrippedSound(new File("sound1.wav"));
     StrippedSound s2=new StrippedSound(new File("sound2.wav"));
     StrippedSound s3=new StrippedSound(new File("sound3.wav"));
     
     for (int i=0; i<50; i++) {
       double rnd=Math.random();
       if (rnd<0.3) {
         s1.play();
       }
       else {
         if (rnd < 0.6) {
           s2.play();
         }
         else {
           if (rnd < 1) {
             s3.play();
           }
         }
       }
       
       try {
         Thread.sleep(200);
       } catch(Exception e) {
         //egal
       }
     }
     
     while (s1.isRunning()||s2.isRunning()||s3.isRunning()) {
       // Warten, bis auch der letzte fertig ist...
       Thread.yield();
     }
     
     System.exit(0);
   }

   public StrippedSound(File sound) {
      try {
         System.out.println("Loading sound from file");
         AudioInputStream soundStream=AudioSystem.getAudioInputStream(sound);
         format=soundStream.getFormat();

         int len=(int) (format.getFrameSize()*soundStream.getFrameLength());
         data=new byte[len];
         int l=0;
         int lp=0;
         do {
            l=soundStream.read(data, lp, len);
            lp+=l;
         } while (l!=-1);

         dataLineInfo=new DataLine.Info(Clip.class, format);
         if (!AudioSystem.isLineSupported(dataLineInfo)) {
            System.out.println("Audio-Line not supported!");
         }
      } catch (Exception e) {
         System.out.println("Error loading sound: "+e);
      }
   }

   public void setMute(boolean is) {
      mute=is;
   }

   public boolean playedFine() {
      return ok;
   }

   public boolean isRunning() {
      return lastClip!=null&&lastClip.isRunning();
   }

   public void stop() {
      if (lastClip!=null&&lastClip.isRunning()) {
         lastClip.stop();
         lastClip=null;
      }
   }

   public void play() {
      if (mute) { return; }
      Clip soundClip=getClip();
      if (soundClip!=null) {
         soundClip.start();
      }
   }

   public void endLoop() {
      if (currentLoopClip!=null) {
         currentLoopClip.loop(0);
         currentLoopClip=null;
      }
   }

   public void loop() {
      if (mute) { return; }
      if (currentLoopClip==null) {
         currentLoopClip=getClip();
         if (currentLoopClip!=null) {
            currentLoopClip.loop(Clip.LOOP_CONTINUOUSLY);
         }
      }
   }

   private Clip getClip() {
      Clip soundClip;
      try {
         if (mixer!=null) {
            soundClip=(Clip) mixer.getLine(dataLineInfo);
         } else {
            soundClip=(Clip) AudioSystem.getLine(dataLineInfo);
         }
         soundClip.open(format, data, 0, data.length);
      } catch (LineUnavailableException e) {
         ok=false;
         return null;
      }
      ok=true;
      lastClip=soundClip;
      return soundClip;
   }
}

...just with the API of the bigger OpenAL solution, so that i don't have to wrap the sound stuff myself to support both.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on April 13, 2008, 11:49:55 pm
I'm going to use this in "nameless Bomberman clone", when it's time to add sound to it. Would it be possible to add a kind of fallback mode that uses Javasound instead?

Yes, that is a good idea.  I'll look into adding Javasound into SoundManager so that you can use the same interface for either sound system.  I'll also do some research to see if there is a way to detect when OpenAL is not working properly.  At the very least, I could have SoundManager automatically switch to Javasound if an exception gets thrown during AL initialization.  It would also be good to allow the user to switch modes dynamically.

I'll start looking into these ideas.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on April 14, 2008, 11:56:13 pm
I have begun looking into Javasound and have download a bunch of sourcecode I am going to dig through.  Specifically I am looking for ways to do the things that SoundManager already does: Multiple Sources; Pause, Play, Rewind, and Stop; normal playback of WAV and OGG sounds; and streaming playback of OGG sounds.  I'm also going to look for a function for changing source volume - if I can find that, then Javasound could potentially support Linear Attenuation for a simi-3D sound system.  If I get really ambitious, I might even write my own Logrithmic (Rolloff) Attenuation algorithm.  That way the only difference between the OpenAL and Javasound systems would be the "true 3D" left/right fading for mono sounds that OpenAL supports -- something that, at least on my soundcard, doesn't seem to work very well anyway ;D

I'm going to start by writing test programs to learn the skills needed to use Javasound.  After that, I will begin incorperating the code into SoundManager.  The later task will not be trivial, mind you.  I hadn't originally planned to use multiple sound libraries when I designed the class, so there will have to be some significant structural changes.

While I'm restructuring the class I also plan to address any other bugs that are discovered.  I'm hoping a few people will give me feedback on the helicopter demo applet, or even better on any of their own projects they are using the SoundManager class in.  One potential bug I noticed yesterday is that often a ball will bounch quite close, but I don't seem to hear a nice "Boing" when it happens.  I'm not sure if this is a logic problem specific to that applet (using Math.sin() always gives me a headache), or if it is a systematic problem with the SoundManager.  Thinking back, I did do a ton of testing with looping sources because of the complexity involved with managing them.  As a result of this special attention, looping sources seem to work quite well now (the flying cubes applet works beautifully with the latest version of SoundManager).  However, I may not have done enough testing for the simple non-looping non-streaming sources, so I will go back and look at those types of sources more closely.  Could be a delay issue (between when the command is queued and when it actually gets executed), could be a channel issue (didn't cull sources correctly before trying to play), or could be a logic issue (told too many sources to play, filled up channels, didn't cull the right ones).  Hard to say at this point, but I am sure to find the cause if I dig into it a little further.

--- UPDATE ---
    I found the cause for this "boing" problem.  It is due to some flawed logic on my part, related to the fact that the command-processing thread runs seperate from the source-management thread.  What's happening is whenever several balls hit the ground at the same time, commands are queued to play more sources than there are available channels.  Because there are not enough channels, some of the sources do not play.
    When using the active-culling management model, the source-management thread goes through the list and culls the far-away sounds, freeing up channels.  At this point, if these were looping sources, source-management would then reactivate the closest sources.  Problem is, these are not looping sources, and SoundManager does not reactivate non-looping sources (to avoid sound effects being repeated if they happen to be located at a position where they alternate back and forth between culled and active).  So basically, if OpenAL was not able to play them before, they simply do not play at all.
    Something similar happens when using the channel-monitoring management model.  As before, the channels get filled up with a bunch of sources (not necessarily the closest ones).  Now, if these were looping sources, the management thread would play the closest ones as soon as channels became free.  But since they are non-looping sources, SoundManager does not play them when channels open up (to avoid a potential time-delay between when the sound was supposed to play, and when it actually does).  So like in the active-culling management model, if OpenAL was not able to play the source before, it does not play at all.
    Ok, so all this sounds rather complicated.  Well, actually this is an easy fix.  Instead of having the command processor actually playing a source, I'll just have it set a "toPlay" boolean for the source.  Then the source-management thread can actually play the sources after making a decision which sources should be played.  Only thing I'll have to make sure of is that the entire process from queueing a command to play, and when the sound actually comes out of the speakers, happens fast enough.  There's nothing worse than firing your lazer cannon, then hearing the blast half a second later (brings to mind the scene from Star Wars, Attack of the Clones, where Jango Fett was setting off seismic charges in the asteroind field) ;D

--- END UPDATE ---

I'll keep you posted on my progress.  Development on the SoundManager may slow down just a bit, because starting this week I am going to begin working on some other components for my game, but I will try and manage my time so SoundManager is completed in a timely manner.

Thanks for all the great help and tips you guys have been giving me.  Relatively small community here, but the jPCT forums are my favorite by far.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: JavaMan on April 15, 2008, 02:46:15 am
I tried out the applet. Works fine for me. Sound is clear and not broken or anything. One weird thing is that when I press escape Firefox crashes.  ???


Quote
Relatively small community here, but the jPCT forums are my favorite by far

I agree, the jpct forums are active. I also use the lejos robotics forums and things over there aren't even half of active as things here.



Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on April 15, 2008, 02:53:00 am
I tried out the applet. Works fine for me. Sound is clear and not broken or anything. One weird thing is that when I press escape Firefox crashes.  ???
Oh, yes, I know what is causing that.  When you press esc, it cleans up memory and stops rendering.  Problem is, I don't know the Java command for actually closing the browser window from an applet  (I know, I am such a noob) :-[

-- EDIT --
Oh, and I didn't call shutdown method anyway.  oops!  Let me fix that real quick!
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: JavaMan on April 15, 2008, 02:55:12 am
I am using the applet in one tab and I am in the jpct forums in another tab so I'm not sure if thats it. I don't no maybe.

Oh, excuse my ignorance, but what is a noob?
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on April 15, 2008, 03:10:28 am
OK ... So NOW the applet actually DOES clear up memory when you press Esc :D.  I still don't know how to close the browser from the applet, though.

Oh, excuse my ignorance, but what is a noob?
Gamer's jargon, short for "newbie".  In normal slang, it means something like "green" or "wet behind the ears".  Basically someone who is inexperienced at something.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: JavaMan on April 15, 2008, 02:15:09 pm
Quote
OK ... So NOW the applet actually DOES clear up memory when you press Esc Cheesy.  I still don't know how to close the browser from the applet, though.

I don't know anything about applets, :-[ so I can't answer that. The applet stops running when I press esc, and I can go and surf on the other tab, but when I close the applets tab firefox crashes. I know ff has some problems so maybe thats it. Anyway the soundmanager works on this machine. :)

Quote
Gamer's jargon, short for "newbie".  In normal slang, it means something like "green" or "wet behind the ears".  Basically someone who is inexperienced at something.

Ah, ok thanks.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on April 15, 2008, 03:04:54 pm
The applet stops running when I press esc, and I can go and surf on the other tab, but when I close the applets tab firefox crashes. I know ff has some problems so maybe thats it.
I tried to recreate the problem on my main PC.  I tried multiple tabs in Internet Explorer, Firefox, and Netscape Navigator.  None of them crashed for me when closing the applet tab, whether the applet was stopped or running.  I'll see if I have any problems on my other test machines.  Can't really say what the problem is.  Do you only have the problem after stopping the applet with Esc, or does it also happen if you close the tab while the applet is running?
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: JavaMan on April 15, 2008, 10:06:28 pm
Quote
Do you only have the problem after stopping the applet with Esc, or does it also happen if you close the tab while the applet is running?

It happens either way. While the applet is running, if I first press the esc key and then click the x the firefox window just closes.

Also, I tried it on ie, and the same thing happened. Except I had gone to the jpct site in one window clicked on the forums button, (which opened up in a new window) and tried out the applet. When I pressed esc and then closed the applet's window, both the applet's window and the first IE window closed.   ::)

If I just close the tab while the applet is running, firefox locks up, and I have to end it manually through xp's task manager.

Hope this helps.

Jman
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: raft on April 16, 2008, 12:25:37 am
i once had implemented moving sounds for karga using java sound. it basicly worked in tests but doesnt sound that good. it then seemed unnecessary to me and i decided not to use it in karga . if it may help i can send post the source.

note; the code has almost no comments. i dont have time to write comments and i dont even remember what i did exactly
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on April 16, 2008, 03:48:22 am
Sure, I'd like to see your code, raft.  I might find something useful.  I haven't sat down to look at the Javasound stuff much yet, hopefully I will have more time tomorrow.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: raft on April 16, 2008, 11:25:07 am
ok then :) here it is: http://www.aptalkarga.com/download/karga_sound.zip

there are a few other karga classes to compile the source but they are no big deal. Logger (http://www.aptalkarga.com/download/Logger.java) is also in download directory.

SoundBank is the top level sound class. it loads the sounds and running sounds instances are created with it
SoundsInfo is the configuration class. dont get fooled when you see all of its fields are final and null. they're filled in externall by jibx. (there is information about this in karga thread)
PointSound is the class which implements moving sounds.
AmbientSound is self explanatory

btw, i correct myself: all of these classes even the PointSound are used in karga at the moment. i simply create PointSound only for main user. in that case source and dest positions are always the same, so it behaves like an AmbientSound

hope this helps,
r a f t
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on April 16, 2008, 02:51:54 pm
It happens either way. While the applet is running, if I first press the esc key and then click the x the firefox window just closes.

Also, I tried it on ie, and the same thing happened. Except I had gone to the jpct site in one window clicked on the forums button, (which opened up in a new window) and tried out the applet. When I pressed esc and then closed the applet's window, both the applet's window and the first IE window closed.   ::)

If I just close the tab while the applet is running, firefox locks up, and I have to end it manually through xp's task manager.

Ok, I'd like to try and isolate the problem to see if it is specific to:
a) SoundManager
b) How I'm using jPCT
c) How I'm creating an applet

So I've created a couple more applets I'd like you to run.  The first is the helicopter applet with all the SoundManager stuff commented out:
LINK NO LONGER EXISTS

And the second is an applet without any jPCT, only SoundManager:
LINK NO LONGER EXISTS
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: JavaMan on April 16, 2008, 10:48:40 pm
Hi,
When I close the tab for the first applet(whether I pressed esc first or not) with just jpct, firefox closes out. I also had a completely different firefox window open to a university site and it closed as well.

On the other hand, the SoundManager only applet works fine. The tab closes out properly.

Jman
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on April 16, 2008, 10:52:41 pm
After making that "No Sound" helicopter applet and running it, I immediately noticed that it is running at quite a bit faster framerate than the one with sound.  That means SoundManager has some significant overhead, which prompted me to think of ways to streamline and optimize.  I took a really close look at the class and how things work, and wrote down a full page of notes on some minor changes I could make to speed things up.  There is one major change I am going to make as well:
    As things are now, in cases where all the sources change position each frame (such as when the camera is moving), the source manager thread is getting woke up every frame to re-sort the list.  Because the source-manager thread calls AL functions (to cull and reactivate sources), it is synchronized with the command thread which also calls AL functions.  The user's game thread is synchronized with the command thread, because the user calls "tick()" every frame to queue commands for moving sources.  THEREFORE the game thread has to potentially wait for the source-manager thread to re-sort the threads list every frame.
    Now I can't think of any way around this three-thread synchronization.  Even if I had absolutely all AL calls running in one thread, all three threads would still need to be synchronized with each other.  For example, when the user says "Play my source", a command must be queued (synchronization between game thread and command thread), then that command has to run by the source-management thread to see if that source is able to play or if it should be culled(synchronization between command thread and source-management thread).  This dependency occurrs regardless of which thread actually plays the source.
    So basically, potentially each frame, the user has to wait to access the command queue, while the the command thread is in the middle of executing the queued "move source" commands, which requires the command queue to wait to access the source list, which the source-management thread is using during the re-sort cycle.  I know, my head is aching, too (did I mention I hate threads?)  :D
    Anyway, I did think of a (really obvious) way to reduce the sort time, which should improve overall performance.  Right now, there is a source map (sources stored by name) and a source list (used for sorting, culling, reactivating).  Since the only purpose of the source list is to play the closest sources, there is no reason for it to contain inactive sources (except for culled looping-sources).  All I need to do is to only put sources into the list when they are playing, then when they finish playing or are stopped, or when non-looping sources are culled, remove them from the list.  That should greatly reduce the time it takes to re-sort the source list (Except in cases where all the sources were looping-sources - there would be no improvement then).
    I did notice another potential problem.  Right now, the user can dynamically change MANAGEMENT_MODEL in their program at any time.  However, this variable is used in the source-management thread, so I need to make sure updating MANAGEMENT_MODEL is done in a synchronized method rather than letting the user acces the varriable directly.  This is true for a couple of other varriables as well.  Easy fix - I just need to make these varriables private and create synchronized "get" and "set" interface methods.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on April 16, 2008, 11:16:20 pm
When I close the tab for the first applet(whether I pressed esc first or not) with just jpct, firefox closes out. I also had a completely different firefox window open to a university site and it closed as well.

On the other hand, the SoundManager only applet works fine. The tab closes out properly.
Hmm.  Slightly different problem, but still there.  That is odd.  Let's see if it is a jPCT issue or an lwjgl issue.  Could you please try this applet which runs in software mode and doesn't use the lwjgl appletloader, and let me know if it also has a problem?
LINK NO LONGER EXISTS
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: JavaMan on April 17, 2008, 12:25:41 am
When I close the tab firefox, doesn't close out, so maybe it is lwjgl?

Jman
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on April 17, 2008, 01:05:39 am
When I close the tab firefox, doesn't close out, so maybe it is lwjgl?
Yes, looks like a problem with lwjgl graphics (i.e. hardware mode) running in an applet.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: JavaMan on April 17, 2008, 01:39:52 am
Didn't you have trouble with the applet loader earlier?

Jman
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on April 17, 2008, 02:39:50 am
Didn't you have trouble with the applet loader earlier?
Yes, I did.  I was going to upload a version of the helicopter applet run without the applet loader, but my main pc got hit with a virus this afternoon, and I am in the middle of recovery (typing from one of my test machines at the moment).  I'll post a link after I fix my pc, so we can see if it is specific to the applet loader or lwjgl in general.

-- EDIT --
Never mind, I can't create an lwjgl applet without the appletloader afterall, because you can't control how the browser starts up the JVM (requires argument -Djava.library.path=c:\lwjgl\native\win32 to load the native dll's).  Unless someone else knows how to run a lwjgl applet without the appletloader?
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: EgonOlsen on April 17, 2008, 06:53:34 am
What are you doing, when the user presses escape? And about the loader: You always need some stuff that loads the native parts. If not done by the appletloader, you have to write it yourself, which will lead to another applet loader...
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: JavaMan on April 17, 2008, 01:07:22 pm
Quote
Unless someone else knows how to run a lwjgl applet without the appletloader?

I was reading about it and this page has some information on giving command line arguments to the JVM through the html page.

jdk6.dev.java.net/plugin2/#COMMAND_LINE_ARGS (http://jdk6.dev.java.net/plugin2/#COMMAND_LINE_ARGS)

Jman
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: EgonOlsen on April 17, 2008, 01:49:09 pm
Quote
Unless someone else knows how to run a lwjgl applet without the appletloader?

I was reading about it and this page has some information on giving command line arguments to the JVM through the html page.

jdk6.dev.java.net/plugin2/#COMMAND_LINE_ARGS (http://jdk6.dev.java.net/plugin2/#COMMAND_LINE_ARGS)

Jman
Unfortunately, this new plugin is Firefox3 und IE7 only. It doesn't work in Firefox2, which will still offer the old plugin only.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on April 17, 2008, 01:59:31 pm
What are you doing, when the user presses escape?

In the no-sound applet, I am doing nothing (just setting "loop = false" to end the game loop.  Is there some "shut down" stuff I need to do to jPCT?  That could be the problem.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: EgonOlsen on April 17, 2008, 02:53:43 pm
Maybe removing the canvas from the applet helps...IIRC, we had some thread about this here, but i can't remember the outcome.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on April 17, 2008, 03:18:05 pm
Maybe removing the canvas from the applet helps...IIRC, we had some thread about this here, but i can't remember the outcome.

Ok, good idea.  I added in the line
Code: [Select]
this.remove( myCanvas ); in the shutdown method, and I re-uploaded the Helicopter applet.  Hopefully that will fix the problem.  The link again:
LINK NO LONGER EXISTS

Oh, BTW, I finally managed to clean the virus off my main pc.  I ended up loosing a bunch of stuff after returning to a previous restore point.  Last scans with updated AVG, spybot, and adaware all came out clean, so hopefuly it is finally gone.  It was a nasty one that locked out my administrator privilages and created a new administrator account (I assume to let someone connect to my computer remotely).  I detected the virus immediatly and quickly disconnected the network cable, so I doubt they got much.  I hate hackers - got nothing better to do with their lives than mess with other people's.  >:(
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: JavaMan on April 18, 2008, 11:06:42 pm
Well, I suppose your probably sick of me giving bad news concerning this applet, but things are even stranger now.
When I press escape firefox's and IE's windows both close out. But if I simple close the tab of the applet in firefox, the other tab continues to run ok.  ::)

I was thinking maybe you should post this on the lwjgl forums to see if anyone else has this problem. Or maybe did you already do that?

Quote
Maybe removing the canvas from the applet helps...IIRC, we had some thread about this here, but i can't remember the outcome.
I think that was me, and no it never got resolved, but that was on a different pc. I just decided to tell the user to choose gl or software.

Jman
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on May 05, 2008, 11:36:49 pm
Hey, just wanted to let anyone who is waiting for the next release of SoundManager know, I am taking a break from programming for a month and a half.

I managed to obtain a (hard to get) waiver allowing me to take my Air Force promotion test a year earlier than expected :D  I'll be testing the beginning of next month, so between now and then I will be spending all my free time studying.

After that, if all goes according to plan, I am taking two weeks of leave to visit family in Kansas and California, so I won't be doing any programming until I get back home to Maryland.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: fireside on May 06, 2008, 03:41:16 am
Good luck with that. 
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: JavaMan on May 06, 2008, 03:30:40 pm
Have a nice time in California! The land of tech. ;D

Jman
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on May 10, 2008, 03:30:01 am
Ok, I know I said I was going to spend all my free time studying.
But I have alway heard that it is good to take a break every now and then...

Ok, fine - I'm really just a programming junkie  ;D

Anyway, I have been looking more closely at Java Sound, and it looks like it is every bit as capable a library as OpenAL.  I am going to continue looking into the differences between them, but initially I am kind of wondering if it might be a good idea to just use Java Sound and forget about OpenAL.  I have posted the following question on other forums as well, and thought I would post it here too, in case any of you have input on the subject:

Is there any advantage to using OpenAL vs Java Sound (specifically performance or compatibility issues), and would there be a real benifit to having SoundManager capable of both?  Or would using only Java Sound make more sense, in order to reduce complexity?

I suppose I will know more when I create some test applets and compare performance.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: EgonOlsen on May 10, 2008, 10:38:07 am
My experience from Paradroidz was, that Javasound was:

a) more compatible when using software mixing
b) less compatible (close to 0%) when using hardware mixing
c) slightly slower

than OpenAL.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on May 10, 2008, 11:11:53 am
My experience from Paradroidz was, that Javasound was:

a) more compatible when using software mixing
b) less compatible (close to 0%) when using hardware mixing
c) slightly slower

than OpenAL.

Sounds like there would be a benifit to including both into my library, then.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on May 10, 2008, 04:41:33 pm
I have started working on a new class today, called SoundSystem.  It is basically going to be an interface class that will handle all calls to both sound libraries, and allow switching between them.  In other words, the SoundManager and SourceManager classes will be able to call methods like SoundSystem.initialize(...), SoundSystem.play(...), etc, without directly accessing methods from either library.  This will not only make things more organized, but it will also make future expansions much easier.  It should also help in simplifying thread synchronization and tracking down thread conflicts, by keeping all the synchronized sound-related methods together in a single class rather than spread out in three classes as they are now.

SoundSystem will initially support only OpenAL, until I get it incorporated into my library and debugged.  I will then expand it to support Javasound.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: fireside on May 11, 2008, 06:05:27 pm
Sounds good.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on May 14, 2008, 11:16:10 pm
Progress update

After doing some work on the SoundSystem class, I am starting to see how useful this interface is actually going to be.  So I've decided to make SoundSystem a library that can be used separately from SoundManager.  I think it could be useful for people who want to use both OpenAL and Javasound in their project, but they don't want the high-level components of SoundManager, such as source management.  With SoundSystem, you wouldn't have to learn the syntax for two seperate libraries, or worry about thread issues.

Therefore, I my plan now is to implement and debug the SoundSystem library before reworking SoundManager to use it (contradicting what I said in my last post).  I'll keep everyone updated, and I'll post the JAR and source for the library when I finish it.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on May 15, 2008, 03:37:34 am
I am trying to write a logrithmic attenuation algorithm for Javasound, since it doesn't have one built into it by default like OpenAL does.

My understanding of how attenuation works in the real world, is that waves attenuate according to the inverse of the distance squared:

Code: [Select]
intensity = initialIntensity / (1 + distance * distance);
So with sound waves, volume should be:

Code: [Select]
volume = initialVolume / (1 + distance * distance);
And then adding in a rollOff factor:

Code: [Select]
volume = initialVolume / (1 + rollOff * distance * distance);
Now here is were I am stumped.  From what I understand, the "logrithmic" part of a logrithmic attinuation algorithm is there to compensate for the fact that the "loudness" of a sound detected by the human ear is not a linear function of that sound's decible value.  I've been searching the internet, but I can't figure out exactly what I need to add to my formula for it to match what OpenAL does.

I thought I would post this here in case anyone happens to know anything about this topic.  If not, I will just use the formula as is.  Only drawback is my algorithm doesn't match the OpenAL algorithm, so you'd have to use different rolloff factors depending on whether you were in OpenAL or Javasound mode, and the attinuation effect would not be the same for both libraries (which may complicate things for the user).

Other solution would be to not use the built-in OpenAL logrithmic attenuation model, and use my algorithm for both Javasound and OpenAL.  This would reduce the realism achieved with OpenAL, but it would ensure that both libraries have the same behavior.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: EgonOlsen on May 18, 2008, 01:34:12 pm
Personally, i could happily live with both solutions giving a little different results. I would leave OpenAL as it is and add your own solution to JavaSound until you can come up with the correct solution. Nobody will hear the difference anyway... ;)
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on May 18, 2008, 09:22:07 pm
Yeh, I think you're right.  I'll leave OpenAL as it is.

BTW, I finally got an answer on the lwjgl formus for why the panning in OpenAL only works for really close sources.  Apparently, it is because the sources are omni-directional instead of directional.  I have been advised to use directional sources instead.  That seems rather unrealistic to me.  Many sources in real life are omnidirectional, but if a sound is to you right, regardless of how far away it is, you're going to hear it out of your right ear louder than your left one.

I guess I will try and make every source directional, pointed at the listener and see if that fixes the problem.  Just one more thing to complicate matters.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on May 20, 2008, 05:17:22 am
Today I created a test applet to try and explain the panning problem to someone who had asked me a stupid question.  Turned out I was the one who ended up looking dumb, because, to my amazement, the applet works exactly the way it is supposed to (true 3D fading between left and right speaker, regardless of distance). :o

So the whole omnidirectional source thing is not what is causing the problem.  So far, I have not been able to track down exactly where the bug is, but I'll keep looking.

The thing that amazes me is that I've started from scratch on SoundManager three times, but apparantly I made the same mistake every time ???  Now I just have to figure out what that mistake is so I can correct it!
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on May 23, 2008, 10:19:26 pm
I'm making great progress on the SoundSystem.  I have moved the CommandQueue stuff over to this class to ensure everything is done on a single thread, and I retested the system for thread conflicts, finding none.  I made a sound library template class called (you guessed it) SoundLibraryTemplate.  This class is to be extended with the specific libraries.

The way the system works is, the SoundSystem class takes care of thread issues, and it passes commands on to the active sound library.  Since all (both) sound libraries extend the template class, they have common interface methods, making the process simpler.

I am about 90% finished with the OpenAL extension of SoundLibraryTemplate (called SoundLibraryOpenAL, of course ;D).  I just need to add in some stuff for shutting down when switching between libraries, and copying sources over from one library to another.  There will be two switch methods, one that copies sources over (so the user won't have to recreate all sources every time he switches between OpenAL and Javasound), and one that just starts fresh.  The user can chose whatever works best for his application.

I have also created some test applets, and the 3D fading appears to be working the way it should.  I never did find the problem with previous versions of SoundManager, so I copied and pasted from the applet I mentioned in my last post.  Fortunately, that seems to have paid off.

I am hoping to finish SoundSystem this weekend, if I don't run into any serious problems.  In case you are wondering, I am going to spend some time studying this weekend for my test as well.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: EgonOlsen on May 23, 2008, 11:30:55 pm
Good news. Maybe i should start to look out for some sounds to use in my project... ;D
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on May 25, 2008, 09:39:56 pm
Progress Update

I backtracked a little bit today to change the way sources are handled in the OpenAL part of the SoundSystem (back to the basics, really).  Puts me a little behind schedule, but it should improve the library in the long run.

Ever since I implemented source culling in the SoundManager class, the way I have handled sources is to delete the culled sources, and recreate the non-culled ones if necessary.  This method works, but after a discussion on Egon's thread about his Bomberman-inspired game, I am changing this concept.

The way it is going to work, is that when OpenAL is initialized, it will grab all available channels (or however many you specify) and create a permanant source for each.

Ok, terminology is biting me in the butt right now.  From now on, let me refer to those permanant sources as "channels".  As far as OpenAL is concerned, these are the only "sources" that exist.  So when I use the term "source" from now on, I am referring to the peripheral information about a source (sound filename, position, gain, etc) rather than an actual "OpenAL source".  Hopefully you can understand the distinction.  When I use the term "cull", I mean "stop a channel", and when I use the term "reactivate" I mean "transfer a source over to one of the channels and play it".

With the new method, when a source is to be culled, another source will be given that channel.  The speed benefit should be significant when dealing with large numbers of sources.  Also, this is going to simplify things when I finish SoundSystem and get back to the SoundManager and source management.  By grabbing up all the available channels in the beginning, I will no longer need to recheck if the soundcard has channels available every time a source is reactivated.

-- EDIT --
This new method of dealing with sources is now in place in the SoundSystem library.  I have tested it, and it works beautifully (at least for monotone sounds).  I have it iterating through the channels when a call to "play()" is made.  This makes SoundSystem even more useful, because you could use it as-is, even without a source-management system like SoundManager, and still get acceptable behavior in situations where you are not playing a huge number of sources simultaneously.  The only thing I need to figure out is how to handle stereo sounds (each stereo sound uses two "soundcard-channels", but it has only one "OpenAL-source").

-- UPDATE --
I ran some tests with stereo sounds.  Unfortunately, it seems that when OpenAL runs out of soundcard-channels, it decides to silently override others that are in-use, and not give any errors, warnings, or messages of any kind to alert you.  Same situation if you start a different application with sound in it after you reserve your soundcard-channels.  Either application can override the other application's playing sounds when soundcard-channels run out.  Only way I can see around this is to determine the number of available soundcard-channels and divide that number by two, using only that many.  The problem would still exist in a situation where the user had multiple applications open that were playing too many sounds.  As far as I can see, there's not much I can do in that situation.  Guess I just won't worry about it..

-- EDIT --
Stereo sounds now work the way they should, and tests do not seem to indicate any problems.  I'll now get back to finishing the SoundSystem library.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on May 26, 2008, 04:29:27 am
Well the OpenAL panning problem has reared its ugly head once again.  Turns the reason it seemed to be fixed was that I had mis-diagnosed the problem.  My assumtion had been that it was a source-related problem, but it turns out that it is in fact a listener-related problem.  It has something to do with when the listener moves, its orientation gets thrown off.  The code I'm using for this is directly out of a book I bought, and it seems to be written correctly.  I've been googling and wracking my brains for hours, but I can not figure out what the problem is!  I've posted a question on the lwjgl forum, so hopefully someone over there can point me in the right direction.  I'll post the code here, as well, in case any of you guys can see anything obvious like a math or logic error:

Create the Listener:
Code: [Select]
    private synchronized void initListener()
    {
        // Listener is at the origin, facing along the z axis, no velocity:
        listenerPosition = BufferUtils.createFloatBuffer( 3 ).put(
            new float[] { 0.0f, 0.0f, 0.0f } );
        listenerOrientation = BufferUtils.createFloatBuffer( 6 ).put (
            new float[] { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f } );
        listenerVelocity = BufferUtils.createFloatBuffer( 3 ).put (
            new float[] { 0.0f, 0.0f, 0.0f } );
       
        // Flip the buffers, so they can be used:
        listenerPosition.flip();
        listenerOrientation.flip();
        listenerVelocity.flip();
       
        AL10.alListener( AL10.AL_POSITION, listenerPosition );
        AL10.alListener( AL10.AL_ORIENTATION, listenerOrientation );
        AL10.alListener( AL10.AL_VELOCITY, listenerVelocity );
    }

Move the listener:
Code: [Select]
    private void moveListener( float x, float y, float z )
    {
        float xOffset = x - listenerPosition.get( 0 );
        float yOffset = y - listenerPosition.get( 1 );
        float zOffset = z - listenerPosition.get( 2 );
       
        listenerPosition.put( 0, x );
        listenerPosition.put( 1, y );
        listenerPosition.put( 2, z );
       
        AL10.alListener( AL10.AL_POSITION, listenerPosition );
       
        // Keep the listener facing the same direction by
        // moving the "look at" point by the offset values:
        listenerOrientation.put( 0, listenerOrientation.get( 0 ) + xOffset );
        listenerOrientation.put( 1, listenerOrientation.get( 1 ) + yOffset );
        listenerOrientation.put( 2, listenerOrientation.get( 2 ) + zOffset );
       
        AL10.alListener( AL10.AL_ORIENTATION, listenerOrientation );
    }

And turn the listener:
Code: [Select]
    public void setListenerAngle( float angle )
    {
        float xOffset = -1.0f * (float) Math.sin( angle );
        float zOffset = -1.0f * (float) Math.cos( angle );
        listenerOrientation.put( 0, listenerPosition.get( 0 ) + xOffset);
        listenerOrientation.put( 2, listenerPosition.get( 2 ) + zOffset);
        AL10.alListener( AL10.AL_ORIENTATION, listenerOrientation );
    }
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on May 26, 2008, 05:37:19 pm
Problem solved (hopefully for good this time).  You must use coordinates that represent normalized vectors for both look-at point and up-direction (contradictory to what my book says.  Geez, you think they would have tested their code before publishing).  I mean the book even has a big diagram and a paragraph about how when you move the listener, his orientation changes, so you have to also change the look-at point to match the offset, blah, blah, blah.  WHAT A BUNCH OF BOLOGNA!

I can't believe it took me so long to figure this out (I mean, I already knew the up-direction was normalized).  Wasted all evening yesterday and half the morning today on this.

Ok, NOW I'll get back to finishing the SoundSystem library!   :D
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on May 27, 2008, 01:23:06 am
I did a little more work on SoundSystem today, but I had to take a break from the computer for most of the day to study for my test.  Because of the couple of hang-ups mentioned previously, I haven't finished SoundSystem this weekend like I'd hoped.  What I do have seems to be running well, and I have finished working out all the kinks with switching between sound libraries on the fly.  Sources and listener information are preserved.  I can see this being easily used in some kind of menu system where a player could change sound libraries at will, at any time during the game.

All I really have left is to figure out streaming sources in Javasound, and a couple of minor logic errors I need to track down related to the 3D panning stuff I wrote for Javasound.  When I get those things working, I will release SoundSystem.

This library has become a bit larger than I expected - I am currently at 12 different classes (not counting all the ogg-related stuff).  That is quite a lot when you are talking about something complicated like 3D sound.  Thankfully I have commented things pretty well, because it is getting harder to keep track of everything.  This is really turning out to be a fun project!
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: fireside on May 28, 2008, 06:03:35 pm
How big is it?  Size gets to be a premium on an online game. 
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on May 29, 2008, 12:32:26 am
How big is it?  Size gets to be a premium on an online game. 

The JAR for SoundSystem is currently around 200 KB
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: EgonOlsen on May 29, 2008, 11:51:30 pm
The JAR for SoundSystem is currently around 200 KB
Only the compiled classes? Is that thing zipped? 200K doesn't matter to me, but i'm surprised that it turned out quite huge. I expected it to be much smaller. jPCT itself isn't much bigger than that.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on May 30, 2008, 12:24:14 am
Only the compiled classes? Is that thing zipped? 200K doesn't matter to me, but i'm surprised that it turned out quite huge. I expected it to be much smaller. jPCT itself isn't much bigger than that.

That is the compiled JAR containing only the classes, not zipped.  It will be a bit larger than that if I ever get around to finishing it.  Hopefully I'll get some time to work on it Saturday.  My schedule has been crazy this week.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on June 03, 2008, 03:48:17 am
Well, I finished my promotion test, and I am leaving for vacation tomorrow morning.  I won't be able to get back to this project for a couple of weeks, so sorry to anyone who is waiting for the next release.  I was hoping to finish it before I left, but that didn't work out.  Oh, well..  Talk to you all when I get back!
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: JavaMan on June 03, 2008, 03:53:29 am
Have a nice time!
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: fireside on June 03, 2008, 09:56:20 am
Have a good one. 
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on July 16, 2008, 12:23:42 am
I'm back from vacation, and I'll get back to finishing this project soon.  I have a couple other non-jPCT projects I'm working on as well.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on July 17, 2008, 09:08:19 pm
I spent some time going back through the code.  It is always a challenge to come back to a project after not looking at it for a while.  I came across something I had wanted to change a while back.  I had put it on a back burner to work on other things, and then just forgot about it.  It is related to loading a .ogg file into a non-streaming source.  I had originally used the code from the .ogg streamer, and was just loading in a single chunk of data of a pre-determined size.  Anything larger required the user to change a variable (MAX_OGG_SIZE or something), which seems really hackish to me.  I decided to work on this problem for a while, to get back into the swing of things.  I want it to read in the entire file in seperate chunks of data, and then combine them into a single sound buffer.  I haven't got this working yet, so I'll do some more work on it today.  Also, messing around with the .ogg related code seems to have broken .ogg streaming ???  I'm not getting any exceptions or errors - streaming sources are just not playing.  I'll have to track that problem down next.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: EgonOlsen on July 17, 2008, 09:55:00 pm
Hurry up...i need sound!  ;D Good to see that you are back on track.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on July 18, 2008, 01:10:58 am
Ok, I got non-streaming .oggs being completely loaded rather than just the first chunk.  This was actually a memory-saving fix.  Before, every (non-streaming) .ogg sound took up exactly the same amount of memory.  Now they now use up only as much memory as needed to load them.  I decided to keep in the maxOggSize configuration varriable there just to prevent a virtually infinite loop in a case where an .ogg was insanely stupid-huge or if there was some strange problem during load time that prevented OggDecoder from reaching the end of the file.  By default I set the max .ogg size at 256 MB (I don't think anyone will be trying to load anything that ginormous - should be streaming that sucker anyway!), and the user is able to change that number if so desired.  As you might expect, when loading large .ogg sounds, the application will hang while waiting for it to load.  This can of course be prevented by streaming large sounds instead of pre-loading them.

I have not fixed the "streaming-sources not playing" problem yet.  I can't seem to track it down.  I am sure it is some sort of logic error, I just have to find it.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on July 29, 2008, 04:34:42 am
Man, this is getting rediculous!  I seriously cannot figure out what's wrong.  I have put in println messages to see where it is breaking down, and everything seems fine up to the point where it goes to read in data.  Then it gets into an infinite loop of saying "Reading a chunk of data", but nothing plays.  This is really strange -  I mean, streaming was working fine before - I don't know what I did to break it.  Unfortunately, I didn't keep a recent backup of the code before I messed around with it, and I have been looking at this for a week now without success.  I am thinking that the project has become so large I am having a lot of trouble just swimming through the code.  I have decided to start stripping things down to the bare bones and hopefully I will be able to find the source of the problem.  I'll start by cutting out all the Javasound code, since I know there are other problems in that part, and focus on getting the OpenAL part working again.  Of course I will keep a backup so I can put everything back together after I fix this darn streaming (or should I say not streaming) problem.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on August 03, 2008, 09:07:11 pm
Problem solved!  I had to tear the project apart, but I finally found the problem!  I was not preloading a block of data before starting the stream loop (yeh - something really simple).  I must have accidentally deleted the line that called this method when I was removing comments or debug messages.  A single line of code can really kill things sometimes!

Anyway, I am hopefully back on track now.  I just need to plug all the Javasound code back in, and fix the problems I was having with streaming oggs in Javasound.  It is finally looking like there may be a light at the end of the tunnel!
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: EgonOlsen on August 03, 2008, 09:16:43 pm
Go, go, go... ;D
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on August 05, 2008, 10:47:27 pm
I am nearly complete.  All the Javasound stuff is back in place, and I have streaming working as well.  The only thing left I need to figure out is how to reserve all the available channels and reuse them (like I am doing in the OpenAL part).  Javasound is different enough from OpenAL that it is not immediately obvious to me how to acomplish this.  I have some ideas - I just need to make some test programs to see what works.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on August 09, 2008, 08:49:48 pm
I found a method that seems to work.

The main problem I was having was trying to use "Clip" for nonstreaming sources and "SourceDataLine" for streaming sources.  Theoretically, this would be the best way, but these two classes do not work interchangably, and managing both types was getting to be a headache.  The only way I can get around this is to use SourceDataLine for every source -- in other words "stream" everything.  For a "nonstreaming" source, all the data will be queued to play at once, whereas in a "streaming" source, buffers are used to queue the data as usual.  This may not be the ideal method, but it works.

Another problem I was having was that when instantiating a SourceDataLine, it takes "format" as a parameter (which, for my purposes, is unknown until the user actually wants to play a source).

A third problem is that I read online that there can be any number of SourceDataLines created, but trying to "open()" more than 32 simultaneously results in an exception.  I haven't actually tested this, but I've read the same thing from more than one website.  It seems reasonable that the maximum number of SourceDataLines would be constant since the Javasound "Mixer" is "software-rendered", from what I understand.  I plan to test to make sure the number 32 can be trusted here even if other programs with sound are running.  Worse case scenario, it may turn out that, as with OpenAL, I'll just have to live with the uncertainty of how many sources can be played simultaniously.  Either way, I will write my code to "catch" any exceptions that happen due to running out of voices.

So my solution works like this: I create a mixer when Javasound initializes, and I create a list of 32 SourceDataLine varriables (they are all "null" to start with).  "Loading" a sound file stores its format and byte data for later use, but it does nothing to the SourceDataLines.  Then, whenever a source is to be played, a SourceDataLine is instantiated with the correct format, set to the correct gain and pan information, and supplied with byte data for whatever sound is to be played.  If the end of the list is reached and no SourceDataLines are empty, the program loops back to the first SourceDataLine, stops and closes it, reinstantiates it with the new format, changes the gain and pan, and supplies it with the new source data.

Preliminary tests show this method to be working, so I am now in the process of moving the code over to my SoundSystem library.  There will also be some minor tweaking for things like "priority sources" and the like.  I will let everyone know how this goes.  I am nearly ready to run some final tests and release the SoundSystem library (finally!)


--EDIT--
Oh, BTW, I do not have a working formula for calculating pan in the Javasound library.  Basically I have vectors for souce position and listener position, and normal vectors for look-at point and up direction.  From that I need to calculate a float between -1 (left speaker) and 1 (right speaker).  My math skills are far to poor to handle a problem like this, so I have been looking for a formula online that someone else has written (so far without luck).  In the mean time, Javasound will just not have panning 3D sources.  BTW, if any of you are more "mathematically endowed" than me, suggestions would be greatly appreciated.

--EDIT 2--
I found someone to help me out with the panning formula.  The psudocode they gave me is:
Code: [Select]
vec3 side = cross(listener.up, listener.look_at);
side.normalize();
float x = dot(source.position - listener.position, side);
float z = dot(source.position - listener.position, listener.look_at);

float angle = atan2(x, z);

// One way you could compute the panning value from the angle:
float pan = sin(angle);
I am going to try and implement this to see if it works (crossing my fingers).
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on August 10, 2008, 05:52:40 am
YES!  SoundSystem is finally finished!  Everything is in place and seems to be working with no problems.  Just to be safe, I am going to run some more extensive tests tomorrow.  I also need to write up some documentation for using the library.  I will try and post an initial release tomorrow afternoon.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: EgonOlsen on August 10, 2008, 03:45:06 pm
Good news. I guess this means that i can now start to search for some cool sounds for my game... ;D
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on August 11, 2008, 12:17:04 am
SoundSystem Library, Alpha Release

I was called in to work today, so I didn't get around to the testing that I planned to do.  However, I decided to release the library today, anyway, in case anybody wants to start getting familiar with it (I can't guarantee there are no bugs).

I am going to start writing up some documentation, and I'll try and post that by tomorrow evening.  Then I'll begin running some serious tests and fixing bugs.  I'll post updates every couple of days as things get fixed, until I am comfortable that the library is stable.  The I'll start working on the SoundManager class that uses this new library.


The JAR file:
http://www.paulscode.com/libs/SoundSystem/10AUG2008/SoundSystem.jar (http://www.paulscode.com/libs/SoundSystem/10AUG2008/SoundSystem.jar)

The source code:
http://www.paulscode.com/source/SoundSystem/10AUG2008/SoundSystemSource.zip (http://www.paulscode.com/source/SoundSystem/10AUG2008/SoundSystemSource.zip)


Since there is no documentation, here are a couple of quick things to get you started:

Create the SoundSystem:
Code: [Select]
SoundSystem mySoundSystem = new SoundSystem( SoundSystemConfig.SOUND_LIBRARY_OPENAL );
Create and Play 3D sources on the fly:
Code: [Select]
mySoundSystem.quickPlay( "tada.wav", true, 0, 0, 0 );  // filename, loop, position
Switch between libraries on the fly:
Code: [Select]
mySoundSystem.switchLibrary( SoundSystemConfig.SOUND_LIBRARY_JAVASOUND );
The methods for creating new sources, streaming, moving sources, moving the listener, etc. are all similar to the ones in the SoundManager class from before, with the exception that now there is a "priority" boolean for making priority sources (ones that are not overriden by new sources when channels run out).  And one more thing: all the configuration stuff has been put together in the SoundSystemConfig class, so if you are having trouble finding something, it is probably there.  It has synchronized "get" and "put" interface methods for accessing the various settings.

Have fun!
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: EgonOlsen on August 11, 2008, 08:00:17 pm
What am i supposed to use for playing event sounds like explosions, shoots...that kind of thing? Does quickPlay() make sense for this or does it load the soundy every time i call it or creates some other overhead that should be avoided? Or is using newSource() a better idea? Can i start playing one source multiple times at a time (like when many bombs explode at the same time)?
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on August 12, 2008, 12:32:53 am
What am i supposed to use for playing event sounds like explosions, shoots...that kind of thing? Does quickPlay() make sense for this or does it load the soundy every time i call it or creates some other overhead that should be avoided? Or is using newSource() a better idea? Can i start playing one source multiple times at a time (like when many bombs explode at the same time)?

quickPlay() is exactly the method you want to use for explosions, etc.  I actually designed it specifically for your game after reading how you wanted to use the sound library.  A sound effect (explosion for example) may be preloaded with the method "loadSound()", or you can simply run "quickPlay()", and it will load the sound for you the first time it encounters it.  The sound file is loaded only once and reused, and you can have as many source as you like playing a sound.


On another topic, I have had a chance to use SoundSystem a little and so far I have identified the following issues:

1) The OpenAL library takes several seconds to initialize.  Not a huge problem since you don't usually initialize it very often, but still anoying.  I believe the time is being spent reserving the audio channels.  I haven't thought of any way around this, but I will look into it further.

2) The Rolloff attenuation model for JavaSound is WAY different than the one for OpenAL.  Sounds become silent VERY quickly as they move away from the listener.  I am going to tweak the formula a bit more to try and improve this.

3) Pausing does not work correctly for either OpenAL or JavaSound (different problems for each library).  In OpenAL pausing only works for non-streaming sources.  In JavaSound, there is some issue with pausing and rewinding normal sources, and catching a pause event when streaming a source.

4) OGG sounds played in JavaSound are not playing at the correct sample rate (they are too slow).  I hadn't noticed it before due to the test .ogg file I was using of breaking glass, which sounds fine at a slower sample rate.  Things like background music are greatly affected by this problem, so it is currently my highest priority on the list of bugs to fix.

These are the only issues I have noticed, but I haven't done much testing as of yet.  Let me know if you notice any other problems while using the library.

I am working on a JavaDoc for the SoundSystem library, but it is going pretty slow.  I'll let you know when I get it finished.  I also want to write an tutorial-style guide for newcommers to use.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on August 13, 2008, 04:05:14 am
I thought I would clarify the quickPlay() method some more, in case there was any confusion about what it actually does.

Basically, the method creates a temporary source which is removed after it has finished playing.  It can be made into a permanant source by calling the setActive() method using the source name returned by the quickPlay() method.  The setActive() method could also be used to have a source automatically removed after it finishes playing.

Now if you are concerned about the overhead involved with "removing" and "recreating" sources, do not worry.  It all comes down to terminology.  As far as the underlying library is concerned, sources are not actually being deleted - there are 32 permanant sources the entire time which never go away (I call them "channels").  When a temporary "source" is removed, all that is really being removed is the peripheral information: a 3D vector, two Strings, and some floats.  When a new "source" is created, new peripheral information is created, and as far as the underlying library is concerned, one of those 32 "channels" merely changed its position.  Bytes from the correct sound file are fed into whichever source is supposed to play that sound, so there is no extra overhead involved in switching between different sound effects on a single channel or playing a single sound effect on multiple channels.

BTW, I have been working on the JavaDoc for this part, and I noticed that I never implemented the "removing of temporary sources" code.  I corrected this (a very simple fix), and it will be working properly in the next release.  In the mean time, all sources act like permanant sources.  This is a minor bug, and not likely to affect things much, since the overhead for each "source" is quite small.

I hope this clears up some confusion about how things work in the background.  I am about halfway finished with the JavaDoc -hopefully I will have it completed by the weekend.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: EgonOlsen on August 13, 2008, 07:35:47 pm
I've added an explosion sound for the bombs as a starter. All worked fine so far!  ;D
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: EgonOlsen on August 14, 2008, 10:18:02 pm
I've added multiple sounds for all kinds of game events: Your SoundSystem works great so far.... ;D

I've noticed one strange thing though and that is if you exit the application without calling cleanUp(), one of my machines (with onboard sound) hangs. It returns to the desktop, but you can't do anything on it. Not even the mouse is moving any longer. This is no problem as i can just call cleanUp() and all is fine, but i found it a bit strange anyway.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on August 15, 2008, 01:34:16 pm
I've added multiple sounds for all kinds of game events: Your SoundSystem works great so far.... ;D

I've noticed one strange thing though and that is if you exit the application without calling cleanUp(), one of my machines (with onboard sound) hangs. It returns to the desktop, but you can't do anything on it. Not even the mouse is moving any longer. This is no problem as i can just call cleanUp() and all is fine, but i found it a bit strange anyway.

I am not sure why that would happen.  I do know that if you are using the OpenAL part, the cleanUp() method calls AL10.alDeleteSources() to remove the channels, AL10.alDeleteBuffers() to remove the loaded sound buffers, and AL.destroy() to shut down OpenAL.  Perhaps since OpenAL makes use of a .dll, there may be artifacts from that in memory if OpenAL is not shut down properly?  I will definitely make a note in the documentation on this, though.  Thanks!
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on August 16, 2008, 02:53:45 am
Today I decided to take a break from the JavaDoc for a while and run some tests and fix bugs.

1) I solved the Javasound OGG sample-rate bug.  After tinkering around a bit, I found that for stereo OGGs, you have to multiply the sample rate by four, but for mono OGGs no change is required.  I am not sure why this is the case (I couldn't find any documentation about this issue online), so I really can't say with 100% certainty that the problem is gone for good, but I downloaded several stereo and mono oggs from a variety of places, and they are all playing at the correct speed in both OpenAL and JavaSound, streaming and non-streaming.

2) I added quickStream() methods, which take the same parameters as quickPlay() except they stream the source.

3) I created a class called SoundSystemLogger, which handles all output messages.  It has methods for handling 3 kinds of messages: Normal, Important, and Error.  I added a setLogger() method in SoundSystemConfig, which you have the option of calling before instantiating the SoundSystem.  This will allow the user to extend the SoundSystemLogger class and override its methods to handle output messages any way they like (for example error messages could be handed off to your own error logger which prints them in a dialog box instead of the Java Console).  If no SoundSystemLogger is set before creating the SoundSystem, then the basic SoundSystemLogger class is used as the default message logger for the SoundSystem.

4) I noticed a bug that occurs when switching between libraries.  Basically any source that is being streamed from a seperate thread (streaming sources in OpenAL, and both types of sources in JavaSound) will cause an exception to be thrown when the playing library's "cleanup()" method is called before initializing the new library.  This is because the source object may become null between when I check if the source is null and when I use the source (a thread synchronization problem).  I think I can solve this by something like Thread.sleep(20); after interrupting the StreamThread so it has time to shut down, before removing the source object.

I plan to release a new version of SoundSystem tomorrow hopefully after fixing the thread problem and looking into the JavaSound rolloff attenuation bug.  I'll take a look at the pause issue again, but if there isn't a quick fix, I'll wait until the following release to fix that problem.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on August 17, 2008, 04:49:31 am
SoundSystem Beta Release

JAR:
http://www.paulscode.com/libs/SoundSystem/16AUG2008/SoundSystem.jar (http://www.paulscode.com/libs/SoundSystem/16AUG2008/SoundSystem.jar)

Source Code:
http://www.paulscode.com/source/SoundSystem/16AUG2008/SoundSystemSource.zip (http://www.paulscode.com/source/SoundSystem/16AUG2008/SoundSystemSource.zip)

Let's see, there have been quite a few changes since the first release, so I'll try to list everything here.

1) Sample rate (playback speed) for stereo .oggs is now working for most .ogg files.  I have found one stereo .ogg file that still plays too slowly, and I have also found some monotone .oggs that do not play at all (most monotone oggs are working fine, though).  Strangely, one of the .ogg files that is not working is the "gunshot" sound effect I used in one of my previous demo applets.  Since the file used to load and play properly, this seems to indicate that I may have broken something in the .ogg loading code.  The good thing about that is I still have the source code for that demo applet.  I should be able to compare line-by-line with the SoundSystem source code to locate the problem.  This is an issue I will continue to work on, but for now it is acceptible.  95% of .ogg files play correctly for both OpenAL and Javasound (and I haven't found any sound files that "work for one but not the other").

2) There are new methods for creating fast sources: quickStream(), which I mentioned in my last post, and backgroundMusic().  backgroundMusic() creates a permanant, priority, streaming, looping, non-attenuating source and plays it.  You can specify a source name or not, and you can also specify looping or not.  The easiest way to use it is just backgroundMusic( "music.ogg" );.

3) I fixed a number of null pointer exceptions caused when shutting things down or switching between libraries.  I will continue to correct problems like these as they pop up, but for now I believe I got most of them.

4) There is a new SoundSystemLogger class for handling messages, as I mentioned in my last post.  There are still "println's" floating around that I am working on removing.  The next release will have the logger fully implemented in all classes.

5) I fixed a mirror-image bug with Javasound panning (sources to the right were playing in the left speaker and vice versa).  Works correctly now.

6) I did some tweaking on the Javasound Rolloff attenuation, and I got it really close to OpenAL's rolloff attenuation.  It's a far cry better than it was before.  In fact, all the 3D effects I am emulating in JavaSound are pretty much dead-on matches to the built-in OpenAL effects (listener orientation, 3D panning, attenuation).  On my PC I'd have trouble telling which library is active if I didn't write the code myself. In fact 3D panning is better in JavaSound, because it works for both stereo and monotone sounds ( ok, enough bragging :P )

7) I made a major change to the way all sound files are loaded.  Before, there used to be four slightly different ways of loading sound files due to the fact that there are two supported formats and two libraries.  Now there is a file loader class which provides generic methods for reading from sound files regardless of their format.  It handles the format-specific details in the background.  This one class has been fully implemented for all file loading: wav or ogg, streaming or nonstreaming, OpenAL or Javasound.  One good thing about this is now sounds will play at the same sample rate for both OpenAL and Javasound, so even if I don't ever fix the sample rate bug, a user could potentially just change the speed of his sound file to compensate for the bug.  The best thing about this new loader, though, is that it can stream both wavs and oggs (before you could only stream oggs).

I spent most of today trying to get pause to work.  I didn't think I was even going to get a release posted today because I had things torn apart.  I am still nowhere close to getting pause to work.  It is deceptively tricky.  At the moment I have sources so they pause, but when they start back up, some of the queued sound data is getting lost.  For non-looping sources it sounds like the sound gets cut off soon after resuming after a pause.  For looping sources, it sounds like they are getting rewinded (thats in Javasound, non-streaming sources.  I haven't got around to looking at the other situations just yet).  I will work on this some more, but I am kind of beginning to wonder if this function is all that vital.  Pause is good if you are making an audio player, but for video games, I am not sure where you would need to pause a sound (stop and play should be sufficient for most games).  Does anybody else have some feedback on this issue?  I just still haven't decided if a pause function is really worth all the effort.

--UPDATE--
I believe I figured out why I am having a problem with pausing.  I think it is related to the SourceDataLine.stop() method being called from the command thread while data is being fed into the line from the stream thread.  The stop() method ends both input and output, so maybe I just need to make sure input has completed before calling stop().  I could have the command thread set a boolean to pause the source, then the stream thread can actually call stop() when it is finished inputing bytes.  I'll try this out and let you know how it goes.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on August 17, 2008, 05:30:15 pm
I discovered a major bug today, which I assume is related to the new SoundFileLoader class I added.  Basically, if a streaming source plays through to the end, any future attempts to play that same source will result in no sound being played.  This is, of course, a must-fix bug.  I am attempting to track the problem down now, and I'll post an updated version of SoundSystem as soon as I get this fixed.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on August 18, 2008, 04:36:51 am
I spent all day on the streaming source replay bug today.  Turns out it is actually two problems, one for Javasound and one for OpenAL.  The Javasound problem was that when you call SourceDataLine.flush() from one thread before it ends, then you write data on the line from a new thread, the line keeps on flushing so nothing ever gets played (strangely, this happens even if you wait a really long time before trying to write data to the line).  The solution is to only call SourceDataLine.stop() from the first thread.  Then from the second thread, call SourceDataLine.flush() and SourceDataLine.drain() (not sure why I have to drain, but it doesn't work unless I do).  Then you can SourceDaraLine.start() and begin writing the data.  Strange problem, and it was rather difficult to find.

Obviously, this is not the same problem happening for OpenAL, since it doesn't use SourceDataLines.  This second problem behaves exactly like the first problem, though.  I have not solved it yet, although I spent most of the day trying to.  I have tracked it down to queuing and processing stream buffers.  Basically, the first time the sound plays, streambuffers are processed and played no problem.  If the stream is looping, I can go back to the beginning of the stream and immediately replay (from the same thread), no problem.  However, if the stream ends and the thread stops, then when I create a new thread later to restream the sound, I can queue stream buffers without any errors, but they are processed and discarded super-fast and no sound is being produced.  Strangely, this looks a lot like what was happening in Javasound to me.  Except for OpenAL there doesn't seem to be anything equivalent to flush() and drain().  I would like to find what is causing this bug, but worst case scenario, I could simply redesign the stream thread so it sleeps rather than shutting down (would require some rearranging of thing, but not super difficult).  It would be interrupted when the source needed to be restreamed, and shut down when cleanUp() is called.  If I do decide to do it this way, I will probably also change it for Javasound as well just so it matches.  Come to think of it, that is probably a better way to handle threads for streaming sources, anyway.

My guess is this problem has most likely been around since I started doing "channel reserving".  I just hadn't noticed it until now, because I simply never ran a test where a streaming source was played all the way through, then replayed.  I definitely can not assume that just because something worked in SoundManager, that it should also work in SoundSystem.  They are really two completely different beasts.

One happy note, though:  I got the pause function to work.  It's a little unresponsive in Javasound.  This is because the SourceDataLine feeds data into the Mixer, so when you pause the SourceDataLine, the sound stops playing a second later (this is also true for stop).  It can be tweaked a little by messign with the streaming buffer size, but it there is no way to get completely around the problem since it is a limitation of the library.  It works well enough, and like I said before, I really can't think of why it would be needed in a game anyway.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on August 18, 2008, 11:25:50 pm
I would like to find what is causing this bug, but worst case scenario, I could simply redesign the stream thread so it sleeps rather than shutting down (would require some rearranging of thing, but not super difficult).  It would be interrupted when the source needed to be restreamed, and shut down when cleanUp() is called.
On second thought, that idea will not work either in the new "permanant channel" infrastructure.  Since "sources" hop around from channel to channel, there is likely be more than one source (and therefore more than one stream-thread) playing on a channel throughout its life, so the second time something tries to stream on a given channel, it will not produce any sound.

And to further complicate things, I came across the following post on the lwjgl forums:
Quote
AL_INVALID_OPERATION can occur for a few reasons:
...
Trying to alSourceQueue one or more Buffers on a Source that already has
a Buffer attached to it using alSourcei AL_BUFFER.    (If you are streaming
data to a Source you should always call 'alSourceQueue' to add Buffers to
the Source.)
...
Because the OpenAL sources (channels) are permanant, this means that after playing a non-streaming "source" on a given channel, attempting to play a streaming one on that same channel would result in an AL_INVALID_OPERATION error.  I haven't tested to see if this is true, but I am willing to bet that it is.  This, of course, means that I will have to stream all sources just as I am doing in Javasound now.  A "normal" source has the data pre-loaded in a buffer, while a "streaming" source reads in small chunks of data directly from the file as it plays.  Both will need to use alSourceQueue to queue the data like a streaming source, regardless of where that data is coming from.

So what this all means is that I am going to have to make another fundamental change to how the SoundSystem is designed.  My plan is to eliminate the entire "stream-thread" concept, and instead have "channel-threads".  Basically there would be 32 (or however many channels there are) threads, one attached to each audio channel.  They would use an interface much like the "Command Queue", where sources would tell whichever channel they are assigned to what they would like to do, and the "channel-thread" will process those commands.  Commands will be straightforward, like "stream filename", "play sound-buffer x", "stop", "pause", "rewind", "flush", and "shut down".  The thread will handle the library-specific details like how to feed data into the stream and the like.

This change is quite major, and it will most likely take some time to finish and debug.  I am going to spend an great deal of time making sure this new thread infrastructure is completely synchronized and stable.   Ultimately, the changes will all be in the background.  The user-interface for SoundSystem will not change, so feel free to use one of the two initial versions in the mean time just to get used to using the library.  No need to worry that everything will be broken when the next release comes out.  Hopefully this is the last major change I will be making to the SoundSystem.  I'd rather focus on fixing minor bugs (that's a lot more fun).
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: EgonOlsen on August 19, 2008, 12:26:49 am
32 threads? How many do you spawn in the current implementation? 32 sounds like a bad idea to me...
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on August 19, 2008, 02:37:19 am
32 threads? How many do you spawn in the current implementation? 32 sounds like a bad idea to me...

Currently, as many threads spawn as there are sources actively streaming (up to 32 at any given time).  If you are using non-streaming sources in OpenAL, then no additional threads are spawning (except, of course for the main "Command Queue" thread).
--EDIT--
This is significantly fewer than were spawned by the SoundManager class.  For example, in my "flying boxes" demo applet, there were 500 threads running at once.
--EDIT #2--
Oh, but then most of those sources were being culled, so most of the threads were shut down.  So again 32 Threads were running at any given time.  Disregard my last statement ;D

Is there a lot of overhead with using 32 threads or something, or are you referring to the difficulty with synchronizing that many? I wasn't aware that running 32 threads was extreme (I am rather new to the whole thread business, but I thought computers are used to handling hundreds of threads at a time).  If you think that 32 threads is too much overhead, I will come up with a new solution that somehow uses a single thread to handle all channels.  I think it could be done by iterating through a channel list, processing one queued command each or feeding a chunk of data into the stream, then looping back to the first channel.  It would need to be somewhat intelligent, though, to avoid gaps in the audio stream.  For example, it takes a noticable amount of time to load a sound file that has not yet been loaded, so the ChannelThread would need to be able to say, "Ok, I'll tell the CommandThread to load that sound.  In the mean time, let me move on to the next channel and take care of this one later when that sound buffer is ready."

I'll have to see if one thread is fast enough to avoid gaps in the audio stream.  I may have to do something like assigning a thread to like every 4 channels or something if one tread is not enough to handle the work load.

Thank for the feedback!
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on August 19, 2008, 03:03:59 am
While we are on the subject of threads, I decided to make a basic thread class which takes care of all the normal synchronization stuff, and extend it in any future threads I create.  I was wondering if some of you Java gurus out there could take a look at it and let me know if it looks sound to you, or if you see any problems.  I know this is more related to Java and not about the SoundSystem, but any and all comments or suggestions on the subject of threads would be greatly appreciated!

Code: [Select]
package paulscode.sound;


public class SimpleThread extends Thread
{
    // thread running or not:
    private boolean alive = true;
    // thread ending or not:
    private boolean kill = false;
   
    // clear any memory used by the thread.
    // MUST call super.cleanUp() at the bottom of Overriden cleanUp() method!!!
    public void cleanUp()
    {
        kill( true, true );  // tread needs to shut down
        alive( false, true );  // thread has ended
    }
   
    @Override
    public void run()
    {
        /*  How the run() method should be set up:  */
       
        // Do your stuff here.  Remember to check dying() often to know when
        // the user wants the thread to shut down.
       
        // MUST call cleanUp() at the bottom of Overridden run() method!!!!!
        cleanUp();  // clears memory and sets status to dead.
    }
   
    // calls the rerun() method on a seperate thread, which calls run() when
    // the previous thread finishes:
    public void restart()
    {
        new Thread()
        {
            @Override
            public void run()
            {
                rerun();
            }
        }.start();
    }

    // kills the previous thread, waits for it to end, and then calls run():
    private void rerun()
    {
        kill( true, true );
        while( alive( false, false ) )
        {
            snooze( 100 );
        }
        alive( true, true );
        kill( false, true );
        run();
    }
   
    // returns true if thread is alive, false if it is dead:
    public boolean alive()
    {
        return alive( false, false );
    }
   
    // sets dying() to true, letting the thread know it needs to shut down:
    public void kill()
    {
        kill( true, true );
    }
   
    // returns true if user requested the thread to be shut down:
    protected boolean dying()
    {
        return kill( false, false );
    }
   
    // sets or returns varriable 'alive'
    private synchronized boolean alive( boolean b, boolean toChange )
    {
        if( toChange )
            alive = b;
        return alive;
    }
    // sets or returns varriable 'kill'
    private synchronized boolean kill( boolean b, boolean toChange )
    {
        if( toChange )
            kill = b;
        return kill;
    }
   
    // Sleeps for the specified number of milliseconds:
    protected void snooze( long milliseconds )
    {
        try
        {
            Thread.sleep( milliseconds );
        }
        catch( InterruptedException e ){}
    }
}
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on August 19, 2008, 04:13:27 am
Ok, so here is Plan B.  Forget the whole command-queueing idea - its overly complicated.  The only thing that absolutely must be done from a single thread is feeding chunks of data into an audio stream.  Everything else can be done from the Command Queue thread that is already in place and working nicely.  What I will do is create a single Channel Thread which will maintain a list of actively streaming channels.  It will iterate through them feeding them chunks of data.  When the end of the stream for a particular channel is reached, it will be dropped from the list.  I like this much better than my first idea - simpler is always good.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: EgonOlsen on August 19, 2008, 09:28:51 am
Ok, so here is Plan B.  Forget the whole command-queueing idea - its overly complicated.  The only thing that absolutely must be done from a single thread is feeding chunks of data into an audio stream.  Everything else can be done from the Command Queue thread that is already in place and working nicely.  What I will do is create a single Channel Thread which will maintain a list of actively streaming channels.  It will iterate through them feeding them chunks of data.  When the end of the stream for a particular channel is reached, it will be dropped from the list.  I like this much better than my first idea - simpler is always good.
Sounds much better too me than spawing lots of thread. The problems with so many threads is, that you

a) are using more system resources for context switches and thread management
b) are getting a highly non-deterministic behaviour. Java doesn't guarantee that a particular thread gets called in a time frame. The more you use, the higher the chance that a thread is late...especially when run on single-core, low-spec cpus

I don't see anything wrong with spawning a thread for each streaming source as you usually don't have that much in a game IMHO. I do see something wrong with spawning 32 of them. It's always better to iterate through a pool of <whatever> than to start a single worker thread per <whatever>.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on August 19, 2008, 12:31:38 pm
highly non-deterministic behaviour. Java doesn't guarantee that a particular thread gets called in a time frame. The more you use, the higher the chance that a thread is late

That is good to know.  Thanks!

I actually prefer to use as few threads as possible, anyway.  Saves me the headache of trying to remember what all is running at any given time and could potentially have a conflict over a particular resource.  So thanks for the comment about 32 threads being a bad idea - made me stop to think of something better and a lot simpler.

So I started on implementing Plan B yesterday, and it looks like it is actually going to be much easier to do than I originally thought  There is really not all that much I'll have to add - I'm mostly cutting out old classes and moving sections of code from one place to another.  And the best part is that there will never be more than 3 threads running at any given time:  The user's main thread, the command thread, and the channel thread.  If none of the sound sources are moving, the command thread will be sleeping, and if there are no sources playing, the channel thread will be sleeping.  I think this is probably the most efficient way to do things.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on August 20, 2008, 11:42:19 pm
Initial tests of the new single-stream-thread infrastructure have not been promising.  Javasound has skipping and strange problems where the last part of a sound repeats itself at the end of the stream like an echo.  OpenAL is not playing at all.  For now, I can't say one way or the other if there is a problem with the stream thread not being able to keep up with 32 sources.  If that were the case, though, I would expect only to see gaps in the stream, not the echo thing or muted sound.  I will just have to dig into each problem further to see what I can do to fix things.

In the mean time, I am also keeping an eye out for any way possible to reduce the amount of time the stream thread spends on each channel as it loops through them.  The faster it can make it through every source, the less likely there will be problems with pauses, clicks, etc. during playback.  One of the things I thought of is use synchronized methods interfacing booleans that can be set by the command thread to tell the stream thread things like if the source is paused or stopped, so the stream thread does not have to spend any time calling the slower library-specific functions for checking the state of each source.  If the paused boolean is true, it can immediately move on to the next source.  If stopped boolean is true, it can drop that source from its list.  That way, it can focus all its energy into feeding data to each channel and moving on to the next one.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: EgonOlsen on August 21, 2008, 12:01:41 am
Isn't it possible to use the old infrastructure, where not all the sources were streaming ones and just let the user reserve some as streaming sources if he/she wants to?
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on August 21, 2008, 01:00:58 am
Unfortunately, all Java sources in the old infrastructure were technically streaming sources, and had seperate threads to stream them.  Also, there was a problem with OpenAL streams (they could not be replayed after playing once), a problem which I never solved.

I could make this a fallback option if I am ultimately unable to get the single source-stream thread idea to work.  I would have to change non-streaming Java sources over to "Clips", and just using "SourceDataLines" for the reserved streaming channels.  I would have to solve the OpenAL bug, of course.  I am sure there is a solution, I'd just have to spend some more time on it.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on August 21, 2008, 01:45:00 am
On another topic, I've decided to refracter a number of class names, varriable names, globals, methods, etc. in this project, because practically everything is prefixed with the word "Sound" (which makes it really hard to find stuff sometimes).  Everyone knows this is a sound library, so this naming convention was needlessly redundant in the first place.

There will be a small change felt by the end user:  I removed the word "SOUND_" from the global identifiers used to switch between libraries:
SoundSystemConfig.SOUND_LIBRARY_NOSOUND, SoundSystemConfig.SOUND_LIBRARY_OPENAL, SoundSystemConfig.SOUND_LIBRARY_JAVASOUND, and SoundSystemConfig.SOUND_LIBRARY_TEMPLATE

It shouldn't be a serious change, since you are most likely only using these globals in a couple of places in your program.  I know I said I wouldn't change the interface at all, but I really had to this one time ... :)
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: EgonOlsen on August 21, 2008, 09:48:39 am
I've written a simple wrapper around your sound system, so a change in the naming convention only affects one class in the game...no problem at all... ;D
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: EgonOlsen on August 21, 2008, 02:12:13 pm
A short question: Is it possible to determine if the system is still playing something (i'm still using the first released version)? The thing is, that i'm using a click-sound in the GUI. This sound is also played when the user clicks "quit". On the way to quitting, the SoundSystem is cleaned up. If this happens while it's still processing the click-sound, the best thing that happens is an exception, the worst thing is a complete system stall. cleanUp() should handle this case IMHO but as long as it doesn't: Is there a way to determine this situation? Currently, i'm waiting 300ms before calling cleanUp(). That may fix it, but you never know...
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on August 21, 2008, 11:06:08 pm
A short question: Is it possible to determine if the system is still playing something (i'm still using the first released version)? The thing is, that i'm using a click-sound in the GUI. This sound is also played when the user clicks "quit". On the way to quitting, the SoundSystem is cleaned up. If this happens while it's still processing the click-sound, the best thing that happens is an exception, the worst thing is a complete system stall. cleanUp() should handle this case IMHO
I will definitately address that problem before the next release.  Thanks for pointing it out!

Quote
but as long as it doesn't: Is there a way to determine this situation? Currently, i'm waiting 300ms before calling cleanUp(). That may fix it, but you never know...
DOH!  I forgot to put a "playing()" method into the SoundSystem class to check a source's state!! ???  I looked at the code, and there isn't any way to check a source's state from outside the SoundSystem class (the soundLibrary varriable is private).  The only thing you can do is recompile the source code adding the following method to the SoundSystem class:

Code: [Select]
public synchronized boolean playing( String sourcename )
{
    if( soundLibrary == null )
        return false;

    SourceData src = soundLibrary.getSources().get( sourcename );

    if( src == null )
        return false;

    return src.playing();
}

Only requirements for to recompile are to include the lwjgl.jar and lwjgl_util.jar libraries.  The above method will be in the next release.  Sorry I forgot to put that in there.  What an oversight!  :-[

-- EDIT --
I also just thought, in case you couldn't figure this out for your self ;D, if you are using quickPlay to play the click sound, you will need to get the sourcename for it.  You could do something like this before shutting down your application:
Code: [Select]
String sourcename = mySoundSystem.quickPlay( "click.wav" );   // wherever you are playing the click

// ...  in the shutdown location:

while( mySoundSystem.playing( sourcename ) )
{
    try{Thread.sleep(100);}catch( Exception e ){}
}
mySoundSystem.cleanUp();
// The End

--EDIT #2--
I just realized you are talking about anything playing at all.  That would also be a good method to add.  You could use something like this (Again, you'll have to add this method to the SoundSystem class):
Code: [Select]
public synchronized boolean somethingPlaying()
{
    if( soundLibrary == null )
        return false;

    HashMap<String, SourceData> sourceMap = soundLibrary.getSources();
    if( sourceMap == null )
        return false;

    Set<String> keys = sourceMap.keySet();
    Iterator<String> iter = keys.iterator();       
    String sourcename;
    SourceData source;
       
    while( iter.hasNext() )
    {
        sourcename = iter.next();
        source = sourceMap.get( sourcename );
        if( source != null )
            if( source.playing() )
                return true;
    }

    return false;
}
I will also add a method like this to the SoundSystem for the next release (not certain about the name, though ;D)
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: EgonOlsen on August 21, 2008, 11:38:05 pm
Thank you. The sources are a part of the project anyway, so i have no problem to modify and recompile them.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on August 23, 2008, 02:39:06 am
Isn't it possible to use the old infrastructure, where not all the sources were streaming ones and just let the user reserve some as streaming sources if he/she wants to?

I would have to change non-streaming Java sources over to "Clips", and just using "SourceDataLines" for the reserved streaming channels.  I would have to solve the OpenAL bug, of course.

After more consideration, I've decided to use Egon's suggestion of reserving a certain number of streaming channels, making all the other ones non-streaming.  The reason I changed my mind on this is that streaming is quite an involved process, and I want my library to be as non cpu-intensive as possible.  The benefit of using non-streaming sources is that you simply hand all of the pre-loaded data off to the sound library to play.  Streaming a source, on the other hand, is done in a busy loop which reads data in from a file input stream (or from a buffer if it is a "normal" source), keeps checking how much data has been processed, and feeds the data to the channel in pieces.

I want to use a hybrid of Egon's suggestion and my single stream-thread concept.  This will hopefully solve the OpenAL multi-thread bug I mentioned earlier.  One potential issue I am aware of is that in OpenAL, non-streaming sources can be any size, but I believe there is a maximum size you can use for a Javasound Clip.  I'll need to figure out what that value is and change the default settings in SoundSystemConfig to match that.  I'll be sure to mention this Javasound limitation in the documentation as well.  The result of this limitation would mean that if a sound effect is too long, the end of it would be cut off.  Hopefully the maximum Clip size is something reasonable.
-- EDIT --
On second thought, I will check for maximum Clip size violations in the LibraryJavaSound class rather than changing SoundSystemConfig default settings.  That way I won't be placing a needless limitation on the OpenAL side.
-- END EDIT --

By default I will have the number of streaming channels set at four.  You will be able to change this number using a method like SoundSystemConfig.setMaximumStreamingSources( int ).  Four should be more than enough streaming channels.  If you think about it, in all likelyhood you would never need to have more than a couple of streaming sources playing at the same time in a game - for things like background music, characters speaking, or rendered cut-scenes.  Most other sound effects are going to be short enough to not need them streamed.

This is a fairly large change to the code and will require some extensive debugging.  I'm hoping to spend a lot of time this weekend working on it.  Hopefully I will be able to post the next release in a couple of days, assuming I don't run into any major problems.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on August 23, 2008, 08:35:49 pm
I believe there is a maximum size you can use for a Javasound Clip.  I'll need to figure out what that value is and change the default settings in SoundSystemConfig to match that.  I'll be sure to mention this Javasound limitation in the documentation as well.  The result of this limitation would mean that if a sound effect is too long, the end of it would be cut off.  Hopefully the maximum Clip size is something reasonable.
-- EDIT --
On second thought, I will check for maximum Clip size violations in the LibraryJavaSound class rather than changing SoundSystemConfig default settings.  That way I won't be placing a needless limitation on the OpenAL side.
-- END EDIT --

After looking into this a little further, I am no longer sure there is a limit to how large a Clip can be.  The reason I originally thought so is that I remembered coming across the following line of code when I was looking at raft's Karga Sound SoundBank class:
Code: [Select]
MAX_SAFE_CLIP_LENGTH = 2097151;
A quick search online, however, has not shown this to be a limitation of Javasound.  Most likely this is just the Karga Sound equivalent to:
Code: [Select]
SoundSystemConfig.setMaxFileSize( 2097151 );
I will run some tests with really huge Clips to see if it causes any problems.  If not, this will not be an issue after all.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on August 24, 2008, 02:49:20 am
I finished coding the new infrastructure today (it was a bit more involved than I had anticipated).  I decided to run a simple test and...  no sound.  hehe, I love it when that happens.  Oh well, at least the main part of the work is finished.  I'll start debugging tomorrow  ;D
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on August 24, 2008, 03:19:39 pm
After looking into this a little further, I am no longer sure there is a limit to how large a Clip can be.
...
I will run some tests with really huge Clips to see if it causes any problems.  If not, this will not be an issue after all.

Ok, turns out there is a maximum clip size.  Unfortunately, the solution is a little more complicated than just trimming down the size of the buffer, as you can see from the console output:

UNTRIMMED BUFFER:
Code: [Select]
buffer length: 5950208
Error in class ChannelJavaSound
    Unable to attach buffer to clip in method 'attachBuffer'
java.lang.IllegalArgumentException: Requested value 176400.0 exceeds allowable maximum value 48000.0.

TRIMMED BUFFER:
Code: [Select]
buffer length: 48000
Error in class ChannelJavaSound
    Unable to attach buffer to clip in method 'attachBuffer'
java.lang.IllegalArgumentException: Requested value 176400.0 exceeds allowable maximum value 48000.0.

As you can see, output from the exception is the same regardless of the buffer size, so my guess is it is getting its information from the AudioFormat varriable.  You may also notice the "Requested value 176400.0" is not the same as the untrimmed buffer size 5950208.

-- EDIT --
After looking more closely at the AudioFormat varriable, I discovered that 176400 is the value of myAudioFormat.getFrameRate().  It is not related to the buffer length (or a maximum Clip size).  This was completely unanticipated, as you can imagine, since these files work fine on SourceDataLines.  I did some searching online, and found that the maximum framerate value for a mixer framerate control is 48000 (as the above output indicated).  Strange thing is, I just now ran a quick test and the file can be opened in the exact same place in the code using the same AudioFormat information without problems when I use a SourceDataLine instead of a Clip.  I am not sure why I am able to use SourceDataLine to load these files and not Clip.  Unfortunately, this seems to be happening with every single .ogg file I have, so this problem absolutely must be solved, even if it means doing a complete 180 and going back to streaming all Javasound sources on SourceDataLines.  I'll tinker around some more to see if I can get them to load into a Clip and let you know what I find out.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on August 24, 2008, 05:48:59 pm
I discovered the "source" of my problem :P

Turns out it was related to the sample-rate hack I added in for slow ogg files (where I was multiplying the sample-rate by 4).  Basically, there are two constructors for AudioFormat, a long one which lets you specify frame rate and frame size, and a short one which calculates them for you based on sample rate.  Since I previously multiplied the sample rate by 4, this in turn resulted in the frame rate being calculated 4 times too large as well.  I switched to the long constructor to specify all values, and this seems to have fixed both the sample-rate problem and the frame-rate problem.  I was even able to remove that X4 hack!

So at least the problem is solved for Javasound, I haven't had a chance to see if sample-rates are also working in OpenAL (there are other OpenAL-specific bugs preventing me from testing this at the moment).

And the final story on maximum clip size:  YES there is one!  It is probably 2097151 as indicated in raft's Karga Sound code, however clip sizes seem to be limited to powers of 2 (I'm getting out of bounds exceptions otherwise).  Since 2097152 is one byte too large, I am forced to set the maximum clip size in Javasound to 1048576.  This translates to about 5-10 seconds of playback depending on the samplerate and mono or stereo.  It seems reasonably long enough for most game sound effects.  Anything longer would have to be streamed on one of the 4 stream channels.

--EDIT--
One more thing I noticed during all this is that apparently Clips, unlike SourceDataLines, will persist after you shut down your application unless their close() method is called.  What this means is if you run your program several times never closing the Clips, you will eventually run out of soundcard voices and have to reboot!  This is just one more reason why the SoundSystem cleanup() method must be called before exiting your program.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on August 24, 2008, 08:02:01 pm
OpenAL non-streaming sources are working now.  I had zero problems with any of my sample ogg files, and everything plays at the correct sample rate.  I found one wav file (the gear sound from my first sample applet) which plays too slowly in OpenAL, but plays correctly in JavaSound.  Also, there was one ogg file (the "broken glass" sound) which will not load in Javasound due to the frame rate being too high, but it plays fine in OpenAL.

That makes two problems out of 30 total test files.  For now, I think that is acceptable.  I suspect that if a particular sound doesn't work, running it through a tool to reduce its sample rate will probably make it usable (i.e. lower quality sounds are more likely to work than super high-quality stereo sounds).  If it turns out that this becomes a big issue to a lot of people, I could put a hack into the file reader which would check the frame rate, and if it is too large, divide that by two and then double the frame size.  Another thing I might do is write an application which lets you try out a sound effect on both OpenAL and Javasound, streaming and non-streaming.  That way you could check if a sound is going work before using it.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: EgonOlsen on August 24, 2008, 08:05:25 pm
I had some wav-files that didn't load either...mono, low sample rate ones. I don't know why, but i don't care. I just picked similar ones that worked fine.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on August 24, 2008, 08:56:39 pm
I had some wav-files that didn't load either...mono, low sample rate ones. I don't know why, but i don't care. I just picked similar ones that worked fine.
Well I do know that in the first release of SoundSystem, I was loading sound files four different ways, in four different places.  The place your files are probably being loaded is when pre-loading wav files to use in OpenAL non-streaming sources, in SoundLibraryOpenAL.loadSound().  This location used org.lwjgl.util.WaveData to load the wav file.

To make things more consistant, all files are now loaded from a single class, called FileReader.  While this should keep things more consistant, hopefully it won't end up making any of the files unusable that you are currently using.  I hate it when one thing breaks while I am trying to improve something else.  If that were to happen, I'll have you send the problem file(s) to me and I'll take a look to see if I can figure out why they don't work.

One thing I could do if WaveData turns out to be more compatible than the method FileReader is currently using, I may be able to change FileReader to use WavData instead to load wav files.  For now, I like the current method I'm using, because both formats are initially placed into an AudioInputStream / AudioFormat context, and reading data later doesn't require me to keep checking what format I am loading from.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on August 25, 2008, 02:09:35 am
I thought I would give a progress update.  I am still working out bugs with the new single-thread streaming stuff.  I haven't seen anything major that would make me believe I won't be able to get it to work.  As with any new system, it is just going to take time to work out all the kinks.

As for the rest of the SoundSystem, I have got quite a bit done today.  Switching Javasound over to using Clips instead of SourceDataLines is now totally finished and debugged.  Non-streaming sources work perfectly for both libraries, and all functions and combinations of play, pause, rewind, and stop are working.  Sounds can reach the end and then be replayed again with no problem.  Sample rates are correct for 90% of my test files.  Attenuation and panning still work like they should.  I have all messages generated in any class routed through the SoundSystemLogger.  And finally, I finished renaming classes and varriables.  I am starting to get a little burned out, so I think I'll call it quits for today and work on debugging the stream-thread stuff some more tomorrow.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on August 28, 2008, 11:23:44 pm
This week, I took a little break from the project, because I got a little burned out on it.  Starting tomorrow, I have a 4-day weekend, so I am going to get back to finishing.  When I get the stream-thread working properly, I want to spend at least a day running tests to make sure everything is stable and there are no problems.  There are a couple of things I want to focus on.  First is using multiple sources, streaming and non-streaming, in both OpenAL and JavaSound.  The second thing I want to focus on is library-switching and shutting-down, making sure the cleanup() method is clearing everything out in the correct order and avoiding any exceptions. I'll try and have a new release posted by Monday evening.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: EgonOlsen on August 28, 2008, 11:52:42 pm
I'm looking forward to the next release. I'm quite happy with the old version under Windows, but under Linux, i have to use JavaSound, i.e. multiple threads, i.e. jerky behaviour on the 630Mhz cpu that the Linux machine uses.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on August 29, 2008, 10:27:31 pm
I discovered a couple of really strange bugs today.  I was using one particular .ogg file while working on the Stream Thread, and I got everything working for a single streaming source in both OpenAL and JavaSound (i.e. looping or nonlooping, play, pause, stop, and rewind, and various combinations of them).  When I then tried to use some different files and to stream multiple sources at the same time, I found two problems.  The first problem is that some sounds are skipping in JavaSound but not in OpenAL (it almost sounds like the stream buffers are playing out of order).  The second problem is that for some sounds, I get to the line of code where I read from the AudioInputStream, and then the AudioInputStream.read( byte[], int, int ) method never returns (thus knocking the StreamThread out of commission).  The weird thing about this second bug is that the files which are causing the problem were working fine in the second release of SoundSystem, which used the same code for reading them.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on August 30, 2008, 03:11:15 am
I solved the JavaSound skipping bug.  The reason this problem popped up is that during the main loop in the Stream Tread, I told it to sleep for a bit between each time it loops through the list of streaming sources (so the thread won't be very CPU intensive).  This sleeping created a problem because of the way I was checking if more data needed to be queued:
Code: [Select]
if( sourceDataLine.available() >= sourceDataLine.getBufferSize() )
    // ... queue another chunk of data

The above statement was only true when sourceDataLine.available() == sourceDataLine.getBufferSize() (i.e. when all queued data was processed).  So basically there would be a skip every time all data finished being processed while the Stream Thread was sleeping.  The solution to the problem was to change the above code to:
Code: [Select]
if( sourceDataLine.available() > 0 )
    // ... queue another chunk of data

Another thing that would help if this problem resurfaces (on a slower computer, for example), would be to increase the streaming buffer size, using SoundSystemConfig.setStreamingBufferSize( int ).

As for the AudioInputStream read-hanging problem, I have determined that it is only occuring on two specific .ogg files and only when more than one .ogg are streaming simultaneously.  Other than that, I am completely stumped on this problem.  I can track the problem down to the exact line of code where it is hanging, and I can not figure out why it would hang there, expecially since it works fine when the file in question is streamed by itself.  It doesn't seem likely that this is a thread synchronization problem, but I'm not ruling that out as a possibility.  I'm kind of grasping for straws at this point.  :-\

--EDIT--
I've decided to place this problem on a back burner for now, and finish getting everything else stable and debugged for the next release.  I am beginning to think this may be a bug in the j-ogg library (or how I am using it), since it only seems to be happening specifically with .ogg files.  For now, I'm putting this in the "incompatibility issues" category along with the sample-rate problem.  Basically what it will mean is if anyone wants to stream more than one .ogg file at once, they will have to make sure their files can be streamed together.  Eventually I will come back and try to solve this problem, but for now it is rather low-priority for me, since I don't intend to stream more than one file at a time in my game anyway.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on August 30, 2008, 10:15:11 pm
I completed the JavaDoc for SoundSystem.  It is located at:
http://www.paulscode.com/docs/SoundSystem/30AUG2008/ (http://www.paulscode.com/docs/SoundSystem/30AUG2008/)

I post the new version of SoundSystem soon.  There are just a couple more things I want to check first.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on August 31, 2008, 04:06:27 am
New release of the Sound System library

JAR:
http://www.paulscode.com/libs/SoundSystem/30AUG2008/SoundSystem.jar (http://www.paulscode.com/libs/SoundSystem/30AUG2008/SoundSystem.jar)

Source Code:
http://www.paulscode.com/source/SoundSystem/30AUG2008/SoundSystemSource.zip (http://www.paulscode.com/source/SoundSystem/30AUG2008/SoundSystemSource.zip)

The differences in this release are mentioned in my previous posts.  If you discover any problems or bugs, let me know and I will work on them.  I am going to begin working on the new SoundManager, which will make use of the SoundSystem.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on August 31, 2008, 06:12:54 pm
Sound System Minor Bug Fixes

JAR:
http://www.paulscode.com/libs/SoundSystem/31AUG2008/SoundSystem.jar (http://www.paulscode.com/libs/SoundSystem/31AUG2008/SoundSystem.jar)

JavaDoc:
LINK NO LONGER EXISTS

Source Code:
http://www.paulscode.com/source/SoundSystem/31AUG2008/SoundSystemSource.zip (http://www.paulscode.com/source/SoundSystem/31AUG2008/SoundSystemSource.zip)

The one thing that I hadn't tested before yesterday's release was the ability to cull and activate sources (methods which SoundManager will use for SourceManagement).  I had to change how QuickPlay works, so that instead of immediately playing the new source, it queues a command to play it, so it doesn't bypass the culling/activating.  I ran several tests, and there doesn't seem to be any problems with this change.  I also made a few other minor tweaks to the default settings, such as increasing the default streaming-buffer size (some higher-quality sounds were skipping in JavaSound).

I also forgot to mention a couple of quick notes for anyone who is switching to a newer release of SoundSystem from the initial release.  There have been a couple of changes to JavaSound since then.  First of all, rolloff attenuation in JavaSound is much closer to OpenAL's rolloff attenuation, so you will most likely need to change whatever rolloff factor you were using before.  Secondly, 3D panning in JavaSound was backwards in the initial release of SoundSystem, so if you had put some type of code to compensate for that bug, it will need to be removed when switching to the new release.

Unless I or someone else using the SoundSystem finds a major problem, this will probably be the last release of SoundSystem for a while, at least until I finish the SoundManager.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: EgonOlsen on August 31, 2008, 07:23:36 pm
I hate to say it but...it doesn't work too well... :'( It seems to work fine when using JavaSound, but with OpenAL almost every sound sounds distorted. Plus it gave me this exception once:

Code: [Select]
Exception in thread "Thread-3" org.lwjgl.openal.OpenALException: OpenAL error: Invalid Value (40963)
at org.lwjgl.openal.Util.checkALError(Util.java:64)
at org.lwjgl.openal.AL10.alBufferData(AL10.java:1059)
at paulscode.sound.LibraryOpenAL.loadSound(LibraryOpenAL.java:252)
at paulscode.sound.LibraryOpenAL.quickPlay(LibraryOpenAL.java:351)
at paulscode.sound.SoundSystem.CommandQuickPlay(SoundSystem.java:1661)
at paulscode.sound.SoundSystem.ManageSources(SoundSystem.java:1963)
at paulscode.sound.CommandThread.run(CommandThread.java:92)

I've uploaded three sounds for you to test here:

http://www.jpct.de/sounds/click.wav (http://www.jpct.de/sounds/click.wav)
http://www.jpct.de/sounds/explosion.wav (http://www.jpct.de/sounds/explosion.wav)
http://www.jpct.de/sounds/comeon.wav (http://www.jpct.de/sounds/comeon.wav)

click and explosion sound awful while comeon (it's a whistle...the name is misleading) plays fine (one of the few that does). I hope this helps...
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: EgonOlsen on August 31, 2008, 07:30:22 pm
JavaSound isn't that great either...I got this after a minute or so:

Code: [Select]
    Channel null in method 'stop'
Error in class SourceJavaSound

After that, sound output was gone. Plus i had the feeling that some sounds were skipped or wrongly played, but i'm not really sure about that...
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on August 31, 2008, 10:37:20 pm
Wow, so many problems!  The first one sounds like I need to take a serious look at the FileReader class, and perhaps rethink the whole thing rather than trying to fix something that simply doesn't work (I tend to get a little tunnel vision occasionally.  This class has been giving me headaches from day one).  As for the null channel problem, I haven't encountered it before, but I will try and replicate the problem by running more strenuous tests over a longer period of time.  Sounds like a thread synchronization problem to me, but I'm not sure.  I should also run more tests different machines, not just my main PC, to see if things break down on less-than-ideal computers.

I suppose I shouldn't have released the library yet - I honestly thought everything was working.  I will keep you posted on my progress.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: EgonOlsen on August 31, 2008, 10:49:21 pm
About the stop thing: Maybe i've called stop on an already finished sound. I'm using this for the water pistol sound...it plays as long as you press the button and/or you aren't out of water. If this happens, i call stop. Maybe the sound has been played to the end already? I'm not checking this.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on August 31, 2008, 11:49:50 pm
About the stop thing: Maybe i've called stop on an already finished sound. I'm using this for the water pistol sound...it plays as long as you press the button and/or you aren't out of water. If this happens, i call stop. Maybe the sound has been played to the end already? I'm not checking this.

Calling stop() on a finished sound should not cause a problem, but I will look into that.  BTW, how was the source originally created, with quickPlay() or createSource()?  -- EDIT -- Looking at the stack trace you mentioned above, I'm guessing the source was created with quickPlay().
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on September 01, 2008, 01:17:28 am
I looked into the stop() error message problem, and I found one way that error message could occur.  Basically what could happen is that if a source finishes playing, and then several other sources play so that the channel iterator gets back to the channel which that first source was playing on, and then if stop() is called on that original source, it checks to see if the source has a channel, which it no longer does, and therefore generates the error message.  I believe I can solve this problem by setting the state of the first source to "stopped" at the time a second source is queued to play on the first source's channel.  That way the stop() method will simply return since the source's state is already set to "stopped", rather than trying to stop the first source's channel to which there is no longer a handle.

That being said, I do NOT think this is what caused your problem, because as you mentioned, sound output disappeared after you got the error message.  That can't be explained by the scenario I mentioned above, so I will continue to try and recreate the problem you experienced.  It could be explained by a bug in the channel-iterator code, so I will go back and look at that again.  One thing I was wondering, are you creating your sources as "priority" sources or just regular ones?  Another thing I should take a second look at is the case where enough priority sources are playing that there are no channels available, and make sure there isn't any bug there.

Thanks for the great feedback, btw.  Your descriptions of the bugs are thorough, which is very helpful.

-- EDIT --
Oh, one more thing in case you come across it, I fixed a small unrelated bug where an error message about a sound skipping was occasionally being printed when a streaming source reached its end.  Simple logic error on my part.  I had added this message in last minute, and before I posted the library, I hadn't tested it in the case where a stream actually reached its end.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on September 01, 2008, 05:10:32 am
I've decided to replace the FileReader class.  Instead I will utilize org.lwjgl.util.WaveData for pre-loading audio files.  I will have to make a choice, however.  WaveData loads the entire audio file, which may not be idea for large files that you would normally stream.  So my choices are:

1) Use WaveData for all sources (would use more memory for streaming sources and would require large files to be pre-loaded to avoid noticable lag the first time they were played)

2) Use WaveData only for normal sources and keep the current AudioInputStream infrastructure for streaming sources (less compatible, some files sound distorted in OpenAL but not in JavaSound).

Does anyone have any thoughts on which route sounds better?  I really haven't decided yet - I can see the benefits of either choice.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: EgonOlsen on September 01, 2008, 07:20:37 am
For the record: I'm just using quickPlay, nothing else.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on September 01, 2008, 03:26:09 pm
For the record: I'm just using quickPlay, nothing else.

Awesome, thanks.

1) Use WaveData for all sources (would use more memory for streaming sources and would require large files to be pre-loaded to avoid noticable lag the first time they were played)

2) Use WaveData only for normal sources and keep the current AudioInputStream infrastructure for streaming sources (less compatible, some files sound distorted in OpenAL but not in JavaSound).

After giving it some thought, I believe I will go with the first option for now.  I intend to come back and look at the compatibility issues I am having with the AudioInputStream method, but considering all the problems it currently causes, I just don't think it is smart to use it until I can figure out how to make it work reliably.  After looking at the JavaDoc for the WaveData class, it looks like I can make it work for both .wav and .ogg files (WavaData.create() method can take an input stream as an argument, so I should be able to pass it the OggInputStream).  Using WaveData should fix the first problem you are having and hopefully that 'Invalid Value' exception as well.  It will solve some of the compatibility issues I have been having.  It should also eliminate the locking up while streaming multiple .oggs (since files will always be read in one at a time).  I am going to add a new method to SoundSystem called "unloadSound()".  This will allow memory from a previously loaded file to be freed up.

That being said, I have not yet found the reason for the JavaSound stop() bug, but when I finish the WaveData stuff, I will take a closer look into that problem as well.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on September 01, 2008, 08:51:46 pm
I've finished switching over to the new file loading method, and all my tests so far have been very good.  The switch has corrected nearly every compatibility issue.  Every one of my test files load without a hitch, including the three files from Egon's game.  All files play correctly in both JavaSound and OpenAL, except for one .ogg file (the famous broken_glass.ogg).  That file still can not be attached to non-streaming sources in JavaSound (due to the frame rate being too high, as before).  Like before, it can be streamed in JavaSound, and it works fine in OpenAL.  This is still a much higher success rate than ever, so I am feeling really good about file compatibility in SoundSystem now.

I will now begin looking into that stop() error.  Hopefully, I will be able to re-create the bug and find out what is causing it.

-- EDIT --
I forgot to mention, the WaveData class is really geared more toward lwjgl and OpenAL, so I ended up downloading the source for that class and modifying it to be more genaric.  Also, I want to eventually make a JOAL version of SoundSystem for some of my friends who are not using lwjgl, so by using my own version of WaveData, SoundSystem is not totally dependant on the lwgjl library (I will easily be able to replace the three classes LibraryOpenAL, ChannelOpenAL, and SourceOpenAL with JOAL versions).
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on September 02, 2008, 04:43:02 am
I created a test applet that has allowed me to replicate the JavaSound stop() bug:
LINK NO LONGER EXISTS

The interesting thing about it is when the error occurs, only normal sources are affected, while the streaming source still works fine.  This is really looking like a bug in my channel-selector code, but I have not found what is causing the problem as of yet.  I will look into this some more tomorrow.  At least I can recreate the problem, which is hopefully the first step to solving it.

-- EDIT --
I forgot to mention, the problem can be easily replicated by simply starting and stopping the "special source" several times.  The number of times it takes to replicate the problem seems to vary, so I am thinking perhaps the problem is not in the channel-selector code as I mentioned above.  In that case, I would expect the problem to always occur on the same number.  This is quite odd.

-- EDIT #2 -- I have discovered that after a while the sources start getting cut off during playback.  Initially multiple sources can play simultaneously just great, but then it seems like the previous source is cut off when the same sound effect (i.e. explosion.wav) is played on a new source.  I wonder if this is related to the first problem, as it seems to happen just before the stop() error message gets printed and normal sources stop working.  Seems like the sound card is running out of voices or something.

-- EDIT #3 --
I have found an "access control" exception that happens occasionally when shutting down or switching libraries while multiple sources are playing.  I will look into solving this problem.

-- EDIT #4 --
Last update for today.  I noticed that the stop() problem happens on OpenAL as well, not just JavaSound, which is very significant.  I also discovered that the source-cut-off problem only seems to happen in JavaSound, and not in OpenAL, which may indicate that the two problems are not related after all.  Hmm.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on September 04, 2008, 01:29:28 am
Last update for today.  I noticed that the stop() problem happens on OpenAL as well, not just JavaSound, which is very significant.  I also discovered that the source-cut-off problem only seems to happen in JavaSound, and not in OpenAL, which may indicate that the two problems are not related after all.

I take that back.  The cut-off bug does in fact happen in OpenAL as well, it just seems to take longer.  I still have not found the source of these problems, although I am almost positive it has something to do with how I am managing the channels.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on September 04, 2008, 02:48:28 am
 ;D  ;D ;D I found the bug!  It was a simple typo where I mixed up a varriable for the streaming channel list instead of the correct one for the normal channel list.  Fixing this appears to have corrected both the null stop() exception and the source cut-off bug, however I have only run a couple of tests so far.  I also discovered what is causing the control access exception I mentioned, and I have that problem fixed as well.  I will post another release this evening after I run a few more extreme tests to make sure the library is now stable.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on September 04, 2008, 03:42:13 am
Sound System Stable Release

JAR:
http://www.paulscode.com/libs/SoundSystem/03SEP2008/SoundSystem.jar (http://www.paulscode.com/libs/SoundSystem/03SEP2008/SoundSystem.jar)

JavaDoc:
LINK NO LONGER EXISTS

Source Code:
http://www.paulscode.com/source/SoundSystem/03SEP2008/SoundSystemSource.zip (http://www.paulscode.com/source/SoundSystem/03SEP2008/SoundSystemSource.zip)


I also uploaded the test applet again using the new-and-improved Sound System:
LINK NO LONGER EXISTS

Let me know whether or not you have any problems, and sorry it took so long for me to get this thing working like it should :-[
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: fireside on September 04, 2008, 08:34:22 am
The example applet seemed to work well in both switch modes for me.  Good job. 
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: EgonOlsen on September 04, 2008, 08:44:28 am
Ok, i'll see if i manage to try this version today and report back my findings... ;)
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: zammbi on September 04, 2008, 11:14:00 am
Nice one, demo works all good for me. I will surely be using this for my game when I add sound.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: EgonOlsen on September 04, 2008, 09:44:17 pm
I've tried OpenAL and JavaSound on Vista and JavaSound on Linux (OpenAL is broken on that Linux anyway)...everything worked fine. The only difference between the two that i found is, that the explosion sound sounds quite different, but i can live with that.  ;D ;D
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on September 04, 2008, 10:34:22 pm
I've tried OpenAL and JavaSound on Vista and JavaSound on Linux (OpenAL is broken on that Linux anyway)...everything worked fine. The only difference between the two that i found is, that the explosion sound sounds quite different, but i can live with that.  ;D ;D

Yes, I noticed that about the explosion, too.  Not really sure what causes that difference (it sounds crisper on OpenAL to me, like the difference between stereo and mono).  I'm glad to hear everything is working fine, though.

I have started working on the new SoundManager.  It really shouldn't take very long to complete, since SoundSystem already takes care of most of the stuff SoundManager was doing before.  All SoundManager will need to handle is source culling/activating based on distance from listener, attaching the listener to the Camera, and attaching sources to Object3D's.  All of that code is already written, so it should be a simple matter of copy and paste, and then debugging.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on September 06, 2008, 12:48:41 am
I've been making progress on SoundManager.  I created the methods in SoundManager for binding sources to Object3Ds and binding the listener to the camera, as well as the tick() method, and everything appears to be working well.

The SoundManager class extends the SoundSystem class, since most of its methods directly interface with the SoundSystem anyway.  There is a new SoundManagerConfig class for interfacing SoundManager-specific settings like Management Model and Cull-Distance, while all the general settings will still be interfaced using the SoundSystemConfig class.

Rather than creating a whole new source management thread, I decided to extend the CommandThread class, to have it handle source management.  The SoundSystem init() method is extended in SoundManager so that it creates a SoundManagerThread in place of a CommandThread.  It makes sense for this thread to be in charge of source management anyway, since it is already the thread responsible for executing commands to create, play, cull, or activate sources.

Unfortunately, source management is not going to be as copy-and-paste as I originally thought.  I forgot that there was a bug which I never got around to fixing (the "boing" problem I explained back on page 4 of this topic).  I also want to improve the speed of source management by maintaining a list of actively playing sources amd culled looping sources, so that I only need to sort that shorter list rather than the entire list of sources every time distances change.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on September 09, 2008, 12:58:22 am
I finished the initial coding for the new SoundManager, and for the most part it works really well.  The bindListener( Camera ) and bindSource( Object3D ) methods seem to work, and both management models appear to be working the way they are supposed to.

There is one bug that I am trying to track down.  The behavior for this bug is exactly like the stop() problem that SoundSystem used to have.  It seems to usually occur when trying to stop a source after the list of actively playing sources fills up and gets sorted.  I haven't had a chance to track the problem down to a more specific sequence of commands, though, so sorting may be completely unrelated.  Just to be sure the problem isn't on the SoundSystem side, I ran some more tests on SoundSystem for cases where the channels become full and sources are forced to stop to make room for other sources.  I was not able to recreate the error that way, so I am fairly certain the problem is isolated to SoundManager's culling and activating of sources.  This does narrow down my search a little, since I can assume the bug is located somewhere in the culling/activating code found in classes SoundManager, SoundSystem, Library, or Source, or in the logic I am using for the two source-management models.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on September 11, 2008, 01:37:22 am
I am taking a break from SoundManager to add a couple of "wish list" items to SoundSystem.

First of all, I have added support for MIDI to SoundSystem.  Everything is stable, and there do not seem to be any problems.  OpenAL does not have an interface for MIDI, so all MIDI playback must be done through Javasound.  Since MIDI playback is done completely seperate from the Javasound Mixer, there are no conflicts when switching between libraries while using MIDI (i.e., you can play MIDI when either OpenAL or Javasound is active, it doesn't matter).  Typically, MIDI plays through a seperate chipset on the soundcard (although a Windows software synthesizer is used for some low-end soundcards), so it shouldn't use up any of the soundcard voices used by other sources.  The drawback is that only one MIDI file can be played at once, so what I had to do is create a new channel type specifically for MIDI playback.  It is instantiated in the base Library class, so all extended libraries play the MIDI source through the same route.

I have SoundSystem taking care of all the messy details, so creating and playing a source using a .mid file is no different than when using a .wav or .ogg file, except that the file can not be pre-loaded.  It makes no difference whether you specify the MIDI source as "Streaming" or "Normal", because MIDI playback involves things like "sound banks", "pressures", and "sequences", which is completely unlike other sound types (i.e., there is no "sound byte" data or stream-buffers involved).  Only one MIDI source can exist at a time, so if multiple sources are created from .mid files, the newest MIDI source will automatically remove any previous one, to avoid conflicts.  3D position has no effect on the MIDI source, so MIDI is really only suitable for background music.

A couple of things about MIDI in Java.  MIDI will not play from within an applet unless a "Soundbank" (.gm) file is specified.  Also, I do not believe MIDI will work in an application if a soundbank is not installed.  I know a sound bank is installed along with versions of the JDK, but of course you can not assume that your players will always have JDK installed on their machines.  What I did is make SoundSystem smart enough to check if a sound bank exists, and if not it loads a default one automatically.  I compiled a JAR called SoundSystemResources.jar (about 500KB), which contains the default soundbank file in package "paulscode.sound.resources".  If your applet or application uses MIDI, you will want to link with that JAR at runtime (or compile that package and file in your own JAR).  It is not necessary to link with SoundSystemResources.jar if your program does not use MIDI, or if you somehow know the end user already has a soundbank installed on their machine.

Also, if you prefer to use your own soundbank file rather than the one in SoundSystemResources.jar, you can use a method called SoundSystemConfig.setDefaultMidiSoundBank( String ).  The string parameter is a package path (such as "pauscode/sound/resources/soundbank.gm"), or an online URL path (beginning with "http://").

One more thing about MIDI.  I would eventually like to add my own software synthesizer to SoundSystem so that MIDI files could be loaded into an AudioInputStream context.  That way you could play as many .mid files as you like simultaneously, and the 3D functions would work the same as any other source.  Unfortunately, I have not been able to find any useful source code (other than GPL stuff), and it is simply too large a project for me to tackle myself at this time.  Perhaps in the future.

I am looking into adding support for .mp3 files, but I will only add this if I can find freely usable source code, and that it is not GPL-licensed source code.  Two reasons:
1) I do not want SoundSystem to be dependant on an external JAR.
2) GPL stuff can not be used in commercial applications ("free and open" does not mean "no-strings-attached").

Another thing I am looking into is manual volume manipulation, especially for the MIDI source (MIDI files tend to be quite loud, I've noticed).  I haven't really decided the best way to do this yet.  I would kind of like to make volume changes on a per-source basis as well as a "master volume".  I am not sure how difficult that is likely to be (the code will of course be different between Javasound and OpenAL).
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on September 12, 2008, 10:06:12 pm
After running some better tests with the MIDI stuff, it is starting to look less appealing.  The MIDI events often take up a noticable amount of time to run, so the program hangs at random points when MIDI playback is running on the main thread.  I may be able to fix this by running the MIDI on a seperate thread.  For me, this destroys the appeal of MIDI alltogether.  I guess since I put a great deal of effort into coding the thing, instead of just deleting it, I will probably go ahead and add in a MIDI playback thread.  It will only be spawned if MIDI is played, so it will not be an issue if MIDI is not being used by a program.  At this poing, I doubt I'll be using MIDI in my game anyway.  I'll just convert any MIDI music to OGG format and stream it.  I'll go ahead and leave the functionality in there just in case someone else wishes to use MIDI.

As for .mp3 format, there does not appear to be any non-GPL source code out there, so I am not adding support for the .mp3 format at this time.  Eventually I may come back and write my own .mp3 decoder, but that is REALLY low-priority (lot of work for very little gain).  It is easy enough to find file format converters anyway, and .ogg seems to be a well supported compressed audio format.

I've figured out how to manipulate source volume and master volume in Javasound (pretty easy, actually), but I am having trouble doing the same for OpenAL.  The problem is that to manually alter the "gain" for a source, it prevents me from using OpenAL's built-in rolloff attenuation model.  I could bypass the built-in rolloff attenuation stuff and use my own rolloff attenuation code that I wrote for Javasound, but that is something I would like to avoid if at all possible.

I'm not sure if it would be better to have the ability to change volume or to just leave SoundSystem the way it is.  Does anyone have any thoughts on this?
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: EgonOlsen on September 13, 2008, 12:38:52 am
It would be nice to have the option to adjust the volume, but personally, i can easily live without that.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on September 13, 2008, 06:27:34 pm
Good news!  I figured out how to alter a source's volume in OpenAL without having to bypass the built-in rolloff attenuation stuff.  I have finished implementing master volume and per-source volume for both libraries.  Usage is simple.  There are two new methods available in the SoundSystem class.  Both take a float value for volume, in the range 0.0f - 1.0f.

Code: [Select]
setVolume( String sourcename, float value );
setMasterVolume( float value );

I think I have finished adding new stuff to SoundSystem, so now I'll get back to fixing the SoundManager problem.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on September 14, 2008, 05:34:47 am
I solved the stop() bug in SoundManager.  Now there seems to be a logic error somewhere in the source management code.  If the source count stays less than 50-75, it seems to work great.  As the number becomes larger, though, it seems like the wrong sources are playing (i.e. not necessarily the closest ones).  I will try my best to solve this problem tomorrow if possible, so I can post the next release of SoundManager (and SoundSystem).

I also discovered today that the coordinate system for jPCT and the one for SoundSystem are backwards as far as the z-axis is concerned.  This has been my first oportunity (since I fixed the panning problem from the old version of SoundManager) to bind a Source to an Object3D and both visually and audibly compare the two.  The problem exists because OpenAL thinks -z means "forward" and +z means "reverse" (when +y is "up" and +x is "right").  jPCT, on the other hand, thinks z means "forward" and -z means "reverse" (to me, this makes more sense, which is probably why the panning code I wrote for Javasound was originally backwards from OpenAL).

There are two ways I can compensate for this problem.  The first way would be to change SoundSystem so that it reverses all z coordinates supplied for methods like "setPosition()" "setListenerOrientation()", etc., thus making SoundSystem behave like jPCT.  The second way would be to leave SoundSystem alone, and instead reverse the z coordinates in the SoundManager tick() method after it reads the coordinates from the Camera and Object3D's.  Any thoughts on which way sounds better?
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: EgonOlsen on September 14, 2008, 12:00:27 pm
I would go for the second way. +y up and -z into the screen is more common than what jPCT does, albeit i find +z into the screen more logical, which is why i choosed that one. What does that mean for the setListenerPosition()-method in SoundSystem? Do i have to have to do something like

Code: [Select]
soundSys.setListenerPosition(pos.x, -pos.y, -pos.z);

to be correct? Currently, i'm simply doing

Code: [Select]
soundSys.setListenerPosition(pos.x, pos.y, pos.z);

which seems to work for me, but my y doesn't change anyway. Z may be reversed then, but it's impossible to hear that on stereo speakers only.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on September 14, 2008, 03:42:06 pm
Quote
+y up and -z into the screen is more common than what jPCT does
jPCT and OpenAL have been my first experience with 3D programming, so I wasn't aware of that.  I agree that +z to the screen seems more logical, but if the other way is more common, I should probably leave SoundSystem as it is, and just change the SoundManager tick() method where SoundSystem Listener and Source's follow jPCT Camera and Object3D's.

Quote
What does that mean for the setListenerPosition()-method in SoundSystem? Do i have to have to do something like

Code: [Select]
soundSys.setListenerPosition(pos.x, -pos.y, -pos.z);

which seems to work for me, but my y doesn't change anyway. Z may be reversed then, but it's impossible to hear that on stereo speakers only.
I hadn't considered that the y-coordinates may be reversed as well.  I was just reversing the z-coordinates.  I know FOR SURE that +y is "up" in OpenAL, but I have not used jPCT enough to notice what the up-directon is there (none my demo applets have manipulated the listener y-coordinates).  Just to make sure, is "up" -y in jPCT?  If so, then you would be correct in reversing all y-coordinates as well.  If the y-coordinates were backwards, my guess is it would be quite noticable in a game where the Camera/Listener had free motion through 3-D space (although I have never tested such a scenerio).

In addition to setting the listener's position as you indicated above, you should also set the listener's orientation as well (at least once), or the listener will be facing the wrong direction and be upside-down by default.  Hmm... come to think of it, that is probably what you meant when you said "Z may be reversed then". ;D

ANYWAY, to reverse and flip the default listener orientation use this:
Code: [Select]
soundSys.setListenerOrientation( 0, 0, -1, 0, -1, 0 );   // look toward -z, up toward -y

Or you can match the Listener orientation to the Camera (or to any normalized jPCT SimpleVector's for that matter) using something like this:
Code: [Select]
SimpleVector direction = camera.getDirection();
SimpleVector up = camera.getUpVector();
soundSys.setListenerOrientation( direction.x, -direction.y, -direction.z, up.x, -up.y, -up.z );  // both y and z coordinates reversed


Also, don't forget to reverse the y and z coordinates when creating new sources (and when moving them):
Code: [Select]
SimpleVector pos = myObject3D.getTransformedCenter();
soundSys.quickPlay( "explosion.wav", false, pos.x, -pos.y, -pos.z );
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: EgonOlsen on September 14, 2008, 04:04:38 pm
Just to make sure, is "up" -y in jPCT? 
Yes, it is. That's the drawback of having +z going into the screen.

BTW: I accidently edited your post instead of replying...i hope that i've rebuild it as close as possible...sorry... :(
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on September 14, 2008, 04:06:06 pm
I thought I would explain what you'd experience when trying to use jPCT coordinates in SoundSystem without reversing the z-direction (just in case anyone is having trouble visualizing what I'm talking about).  I drew a simple diagram representing an Object3D moving in the +x direction (viewed from above):

(http://www.paulscode.com/images/zReverseExample.gif)

As you can see from this diagram, the jPCT Camera would "see" the object moving to the right, while the SoundSystem Listener would "hear" an attached source moving to the left, because it would be "listening" from the opposite direction.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on September 14, 2008, 04:06:58 pm
BTW: I accidently edited your post instead of replying...i hope that i've rebuild it as close as possible...sorry... :(

hehe, np.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on September 14, 2008, 06:26:12 pm
Sound System, Bug Fixes and Additions

JAR:
http://www.paulscode.com/libs/SoundSystem/14SEP2008/SoundSystem.jar (http://www.paulscode.com/libs/SoundSystem/14SEP2008/SoundSystem.jar)

Source Code:
http://www.paulscode.com/source/SoundSystem/14SEP2008/SoundSystemSource.zip (http://www.paulscode.com/source/SoundSystem/14SEP2008/SoundSystemSource.zip)

JavaDoc:
LINK NO LONGER EXISTS

Test Applet:
LINK NO LONGER EXISTS

Resources JAR: (only required when playing MIDI from an applet)
http://www.paulscode.com/libs/SoundSystem/SoundSystemResources.jar (http://www.paulscode.com/libs/SoundSystem/SoundSystemResources.jar)

Rather than waiting until I finish fixing SoundManager, I decided to go ahead and post the current version of SoundSystem, since there have been a couple of important bug fixes:

1) The main bug fix is that I was not calling each source's "positionChanged()" method when the listener moved or changed orientation, so "distanceFromListener" was not being updated.  There was no noticable problem in OpenAL when using rolloff-attenuation (because the gain is set internally by OpenAL in that case).  The bug was apparent in linear attenuation under OpenAL and in both attenuation models under JavaSound.  In JavaSound, this bug also caused panning to not update when the listener orientation changed.

2) The minor bug fix is that I had the default listener orientation set to (0, 0, 1, 0, 1, 0) instead of (0, 0, -1, 0, 1, 0), because I did not realize that OpenAL considered "-z" to be "forward" and "z" to be "reverse".  So in other words, the listener by default was facing the wrong direction (toward the player) instead of facing forward.  This explains why Egon was able to use jPCT coordinates for sources in his "Nameless Bomberman Clone" game without noticing any problems (although technically coordinates were backwards and upside down, but you can't hear the difference between that and facing the correct direction, when playing on normal stereo speakers).

Another major update in this version is the ability to change each source's volume, and there is also a master volume which affects all sources.  I think this is an important addition to the library, since most games have configuration menus which allows the player to manually change the volume, turn down or mute the music, etc.

-- EDIT --
One more new thing in this version is the ability to play back MIDI.  Playback of other sources is a bit choppy when MIDI is playing while the JavaSound library is being used, but simultaneous MIDI and other sources both play smoothly under OpenAL.  I have no intention of working on MIDI any time soon, so it is available "as is" for now.

-- EDIT #2 --
Another bug that is fixed in this version is the regular expression for SoundSystemConfig.PREFIX_URL.  Before, I had accidentaly typed in an extra [tT] (i.e. using the expression would search for "htttp://" instead of "http://").
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: EgonOlsen on September 14, 2008, 10:48:04 pm
I've dropped the new sources into my game...everything works fine!  ;D
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on September 16, 2008, 02:59:03 am
SoundManager, Version 2

JAR:
http://www.paulscode.com/libs/SoundSystem/15SEP2008/SoundManager.jar (http://www.paulscode.com/libs/SoundSystem/15SEP2008/SoundManager.jar)

JavaDoc:
LINK NO LONGER EXISTS

Source Code:
http://www.paulscode.com/source/SoundSystem/15SEP2008/SoundManagerSource.zip (http://www.paulscode.com/source/SoundSystem/15SEP2008/SoundManagerSource.zip)

Demo Applet:
http://www.paulscode.com/demos/SoundSystem/15SEP2008/ (http://www.paulscode.com/demos/SoundSystem/15SEP2008/)

Demo Applet Source Code:
http://www.paulscode.com/demos/SoundSystem/15SEP2008/HelicopterSource.zip (http://www.paulscode.com/demos/SoundSystem/15SEP2008/HelicopterSource.zip)

I finally fixed the source management bug I was having, and everything appears to be working ok now.  Initial tests show that source management is still rather resource-intensive.  I will continue to try and streamline the source management process, but I can't promise any big optimization breakthroughs.

The demo applet listed above is just a modified version of the Helicopter demo applet from before.  I changed it that you can see the different source management models at work.  What it does is make the balls red when they have an active (non-culled) source attached.  Balls with culled sources attached appear grey.

After finishing SoundManager and weighing the pros and cons between it and SoundSystem alone, I have decided not to use SoundManager in my game.  I decided to go ahead and release SoundManager in case anyone else finds it usefull, though, and I will work to fix any bugs that people find.  For my game, though, I'm going to just make a jPCT version of SoundSystem which has SoundManager's two "bind" methods for attaching the listener to the camera and sources to object3D's and the tick() method to call in the main game loop.  The way SoundSystem handles sources is more than sufficient, in my opinion.  This new jPCT version of SoundSystem will have an additional "quickPlay" method which takes an Object3D as an argument (automatically binding the source to the Object3D).  I'll post the JAR and source code when I finish it.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: paulscode on September 16, 2008, 05:48:50 am
SoundSystemJPCT

JAR:
http://www.paulscode.com/libs/SoundSystem/15SEP2008/SoundSystemJPCT.jar (http://www.paulscode.com/libs/SoundSystem/15SEP2008/SoundSystemJPCT.jar)

JavaDoc:
LINK NO LONGER EXISTS

Source Code:
http://www.paulscode.com/source/SoundSystem/15SEP2008/SoundSystemJPCTSource.zip (http://www.paulscode.com/source/SoundSystem/15SEP2008/SoundSystemJPCTSource.zip)

Here is the jPCT-friendly version of SoundSystem.  Instead of overwriting the SoundSystem class, I decided to just extend it.  That way, any updates and bug fixes in SoundSystem will carry over to SoundSystemJPCT.  I added in a whole bunch of methods for creating sources, quickPlay, moving sources, listener orientation, etc.  These new methods take SimpleVector arguments.  To make things easy for interfacing with jPCT, all methods which take SimpleVectors as arguments assume the SimpleVectors are using the jPCT coordinate system, and they convert them to the OpenAL coordinate system automatically.  The JavaDoc goes into more detail about that.

Next thing I am going to work on is some user-friendly "getting started" tutorials.  I am suspect SoundSystem looks really complicated when you are staring at the JavaDoc or source code, so I think a guide will let people know how simple SoundSystem really is (especially compared to any other 3D sound library).
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: EgonOlsen on September 16, 2008, 07:56:58 pm
FYI: Your SoundSystem works fine with LWJGL 2.0rc2...just in case you haven't tried it yet.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: EgonOlsen on September 17, 2008, 03:37:46 pm
Is there a way to determine if SoundSystem has been initialized correctly? I have a problem with LWJGL2.0rc2 on one machine and OpenAL doesn't initialize (not your fault, i think...must be some flaw in rc2) correctly. But the SoundSystem seems to discard this information except that it prints out the stack trace, but that doesn't allow me to react to this problem. If i could, i would simply fall back to JavaSound instead. Why don't you propagate the LWJGLException (or maybe a simple RuntimeException) up to the constructor of SoundSystem, so that i can catch it!?
Title: Re: 3D Sound System
Post by: paulscode on September 17, 2008, 09:55:19 pm
Why don't you propagate the LWJGLException (or maybe a simple RuntimeException) up to the constructor of SoundSystem, so that i can catch it!?

Sure, that is a good idea.  I'll post the update as soon as I finish, and I'll also have it throw any exceptions from the switchLibrary method as well.

-- EDIT --
OK, I'm dumb.  Hopefully you didn't read what I originally posted here (you'd think I didn't know how my own library works ;D).  ANYWAY, I created an exception called SoundSystemException, so that the SoundSystem class is not dependant of lwjgl just to throw the LWJGLException.  The SoundSystemException will contain the message from the LWJGLException, or a message explaining whatever problem occurred during load time.  The switchLibrary() method also throws a SoundSystemException if a problem occurred while trying to switch libraries.  Additionaly, I added in a checkLoadError() method into the SoundSystem class, which returns true if an error occurred during load time.  It is a synchronized interface, so it could be used from a seperate thread elsewhere in your program where you might need to know if an error had occurred during load time.  The checkLoadError() method can also be used after the switchLibrary() method to know if an error occurred while trying to switch to a different library.

BTW, technically I could get rid of the exception throwing in the constructor and just have you use the checkLoadError() method (would eliminate the need to put in a try/catch when instantiating the SoundSystem).  Personally I don't have a real preference either way (I'd only need to cut out a couple lines of code).  What are your thoughts on this?
Title: Re: 3D Sound System
Post by: paulscode on September 18, 2008, 01:19:18 am
-- EDIT --
Hehe, hopefully I got it right this time ;D.  Let me know if this doesn't catch the error you are experiencing.

JARS:

Sound System jPCT (http://www.paulscode.com/libs/SoundSystem/17SEP2008/SoundSystemJPCT.jar)
Sound System (http://www.paulscode.com/libs/SoundSystem/17SEP2008/SoundSystem.jar)
Sound Manager (http://www.paulscode.com/libs/SoundSystem/17SEP2008/SoundManager.jar)


Source Code:

Sound System jPCT (http://www.paulscode.com/source/SoundSystem/17SEP2008/SoundSystemJPCTSource.zip)
Sound System (http://www.paulscode.com/source/SoundSystem/17SEP2008/SoundSystemSource.zip)
Sound Manager (http://www.paulscode.com/source/SoundSystem/17SEP2008/SoundManagerSource.zip)


Oh, BTW, I recently reorganized things a little better on my server.  I updated all the links in this thread, and removed any dead links.
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: EgonOlsen on September 18, 2008, 11:26:54 pm
The exception is thrown, i can catch it and revert to Javasound...all is fine (except that the exception happens...but it's not your fault, the dll is linked to a missing VC++9.0 dll).
Title: Re: 3D Sound System
Post by: paulscode on September 18, 2008, 11:50:47 pm
Sound System Without Exception in Constructor

JARS:

Sound System jPCT (http://www.paulscode.com/libs/SoundSystem/18SEP2008/SoundSystemJPCT.jar)  (Download Source Code (http://www.paulscode.com/source/SoundSystem/18SEP2008/SoundSystemJPCTSource.zip))

Sound System (http://www.paulscode.com/libs/SoundSystem/18SEP2008/SoundSystem.jar)  (Download Source Code (http://www.paulscode.com/source/SoundSystem/18SEP2008/SoundSystemSource.zip))

Sound Manager (http://www.paulscode.com/libs/SoundSystem/18SEP2008/SoundManager.jar)  (Download Source Code (http://www.paulscode.com/source/SoundSystem/18SEP2008/SoundManagerSource.zip))


This is basicaly the same as the last release, except without the exception thrown in the constructor.  After a lively discussion on the gamedev forums, I decided to remove the exception being thrown in the constructor at the request of two other programmers who have been using the SoundSystem library in their games (as well as input from a couple of other random people on the forum).  Their argument was that since the checkLoadError() method can be used to determine when an error occurred while loading the sound library, there is no need to make the constructor more complicated than it needs to be.  As a compromise, I merely commented out "throws SoundSystemException" in the two constructors and added in a try/catch.  This can be easily changed back if desired (it is difficult to please everyone, but I think this is the best choice all around).  Any future releases of the SoundSystem will not throw the exception in the constructor either.

The only new thing that I added to this release is a synchronized method in the SoundSystem class called initialized(), which will return false if a sound library is busy loading.  I thought that this might also be usefull from a program that uses multiple threads which might need to check if the SoundSystem is busy switching between libraries (shouldn't be an issue since commands are all executed in sequence from a single command thread, but just in case someone finds this functionality useful, it is there).

-- EDIT --
BTW, what I could do if you need to know what exception was thrown during the constructor, add a method which will retrieve the exception that was thrown.
Title: Re: 3D Sound System
Post by: paulscode on September 19, 2008, 01:22:56 pm
I thought of a way to kill two birds with one stone.  I can add a static method called libraryCompatible( int ) to the SoundSystem class.  It will return true if a library is compatible or false if not.  For OpenAL, it will try to call AL.create(), and if an LWJGLException is thrown, it will return false.  For JavaSound, it will search for the Mixer, and if it is not found, it will return false.

So in your program, you would be able to check if a particular library is compatible before instantiating the SoundSystem.  i.e.:

Code: [Select]
int useLibrary;

if( SoundSystem.libraryCompatible( SoundSystemConfig.LIBRARY_OPENAL ) )
    useLibrary = SoundSystemConfig.LIBRARY_OPENAL;
else if( SoundSystem.libraryCompatible( SoundSystemConfig.LIBRARY_JAVASOUND ) )
    useLibrary = SoundSystemConfig.LIBRARY_JAVASOUND;
else
    useLibrary = SoundSystemConfig.LIBRARY_NOSOUND;

SoundSystem soundSys = new SoundSystem( useLibrary );

How does that idea sound?
Title: Re: 3D Sound using lwjgl binding of Open AL
Post by: EgonOlsen on September 19, 2008, 02:06:47 pm
Sounds ok to me. However, doing it the exception-way is ok for me too. Do it in the way you prefer and i'll adapt to it.
Title: Re: 3D Sound System
Post by: paulscode on September 19, 2008, 11:11:57 pm
Sound System with library compatibility checking

JARS:

Sound System jPCT (http://www.paulscode.com/libs/SoundSystem/19SEP2008/SoundSystemJPCT.jar)  (Download Source Code (http://www.paulscode.com/source/SoundSystem/19SEP2008/SoundSystemJPCTSource.zip))

Sound System (http://www.paulscode.com/libs/SoundSystem/19SEP2008/SoundSystem.jar)  (Download Source Code (http://www.paulscode.com/source/SoundSystem/19SEP2008/SoundSystemSource.zip))

Sound Manager (http://www.paulscode.com/libs/SoundSystem/19SEP2008/SoundManager.jar)  (Download Source Code (http://www.paulscode.com/source/SoundSystem/19SEP2008/SoundManagerSource.zip))


I finished adding the static libraryCompatible( int  ) method into the SoundSystem class.  It can be used as I mentioned in my last post, to check if a particular library is compatible on the user's system.

I removed the checkLoadError() method, and replaced it with the static method getLastException(), which returns the last exception thrown or null if none.

Additionally, I altered the SoundSystemException class, adding a getType() method, which returns one of several possible int identifiers for what caused the exception (see the JavaDoc for more details).

I think I've covered all the bases this time ;D  Let me know if you think of anything else that I can add to make the library better.
Title: Re: 3D Sound System
Post by: paulscode on September 20, 2008, 03:15:53 pm
I have decided to put in compatibility testing into the first SoundSystem constructor which doesn't take a library type parameter.  That way compatibilty checking would only be required when manually specifying which sound library to use.  I am also going to add a synchronized static method to the SoundSystem class called currentLibrary(), which will return the library type that is currently loaded.

-- EDIT --
I hate to keep flip-flopping on the exception-throwing issue, but I think I am going to change the second SoundSystem constructor (the one which takes a library-type parameter) back so that it throws a SoundSystemException again.  The reason I changed my mind on this again is that I kind of want to force the programmer to think about library compatibility when manually selecting a libraries (the switchLibrary() method also throws a SoundSystemException).  The first SoundSystem constructor (the one with no parameters) still won't throw an exception, since it will be intelligent enough to check for library compatibility automatically.

By having the second constructor throw an exception, this should accomplish my goal of forcing the programmer to think about compatibility issues when manually selecting a library.

By having the first constructor not throw an exception will hopefully be helpful for those who want to put as little thought into the sound library as possible.
-- END EDIT --
Title: Re: 3D Sound System
Post by: paulscode on September 21, 2008, 12:27:42 am
Sound System with automatic compatibility checking

JARS:

Sound System jPCT (http://www.paulscode.com/libs/SoundSystem/20SEP2008/SoundSystemJPCT.jar)  (Download Source Code (http://www.paulscode.com/source/SoundSystem/20SEP2008/SoundSystemJPCTSource.zip))

Sound System (http://www.paulscode.com/libs/SoundSystem/20SEP2008/SoundSystem.jar)  (Download Source Code (http://www.paulscode.com/source/SoundSystem/20SEP2008/SoundSystemSource.zip))

Sound Manager (http://www.paulscode.com/libs/SoundSystem/20SEP2008/SoundManager.jar)  (Download Source Code (http://www.paulscode.com/source/SoundSystem/20SEP2008/SoundManagerSource.zip))

As mentioned in my last post, the constructor without parameters will automatically attempt to initialize the highest priority library first, and if that fails it will try the next one, and so on.  The default priority order for loading libraries is OpenAL first, then JavaSound, then No Sound.  This order can be changed by creating an int array of library types in their order of priority, and then passing that to the static method SoundSystemConfig.setLibraryPriorities:

Code: [Select]
int[] libraries = new int[3];
libraries[0] = SoundSystemConfig.LIBRARY_JAVASOUND;  // will try to load first
libraries[1] = SoundSystemConfig.LIBRARY_OPENAL;     // will try this second
libraries[2] = SoundSystemConfig.LIBRARY_NOSOUND;    // this one last

SoundSystemConfig.setLibraryPriorities( libraries );
mySoundSystem = new SoundSystem();

I also finished writing my tutorial-style guide.  It is in PDF format.  I put links to it and the example programs  for the guide on page one of this thread.
Title: Re: 3D Sound System
Post by: paulscode on September 24, 2008, 12:44:08 am
Sound System, "applet no-sound" bug fix

JARS:

Sound System jPCT (http://www.paulscode.com/libs/SoundSystem/23SEP2008/SoundSystemJPCT.jar)  (Download Source Code (http://www.paulscode.com/source/SoundSystem/23SEP2008/SoundSystemJPCTSource.zip))

Sound System (http://www.paulscode.com/libs/SoundSystem/23SEP2008/SoundSystem.jar)  (Download Source Code (http://www.paulscode.com/source/SoundSystem/23SEP2008/SoundSystemSource.zip))

Sound Manager (http://www.paulscode.com/libs/SoundSystem/23SEP2008/SoundManager.jar)  (Download Source Code (http://www.paulscode.com/source/SoundSystem/23SEP2008/SoundManagerSource.zip))

I fixed an OpenAL thread-synchronization bug that would occur on some computers in cases where the SoundSystem object was created from outside the main thread, such as in an applet's init() method.

The no-sound bug probably cropped up after I rearranged things when I added the code to propagate exceptions back to the SoundSystem constructor.  For some reason, I had moved the library initialization code from being run by the Command Thread.  This was a simple fix.  I moved initialization back to where it is run from the command thread.  To keep the exception propagation working, I now have the thread which instantiated the SoundSystem wait up to ten seconds for initialization to finish.  If initialization is not complete by that time, it throws an exception.  Likewise, if initialization resulted in an exception, the constructor retreives that exception with the getLastException() method and throws it.

This change is completely in the background, so none of the methods or constructors are different than the last release of SoundSystem.
Title: Re: 3D Sound System
Post by: paulscode on September 26, 2008, 01:02:37 am
Hey, Egon, this is likely to be one of the last posts on this thread, so before it is left to slowly sink out of sight beneath all the awsome new future projects, I would like to request that this thread be made sticky, or that a link to Sound System be added to the 3rd party downloads section (at your discretion, of course).

The reason for this request is that developers who are new to jPCT may also be looking for a 3D sound library to use in their project, and making SoundSystem easy to find could be helpful.

If you choose to put a link in the 3D party downloads section, the following zip file contains all the JAR's, javaDoc, source code, tutorial guide, and example applications.  If I make any future updates, tutorials, etc., I will re-zip everything and place it at the same location, so this link will always be correct:

http://www.paulscode.com/downloads/SoundSystem.zip (http://www.paulscode.com/downloads/SoundSystem.zip) (last updated: 26 November 2008)
Title: Re: 3D Sound System
Post by: paulscode on November 15, 2008, 03:14:07 am
Sound System, automatic compatibility check bug fix

JARS:

Sound System jPCT (http://www.paulscode.com/libs/SoundSystem/14NOV2008/SoundSystemJPCT.jar)  (Download Source Code (http://www.paulscode.com/source/SoundSystem/14NOV2008/SoundSystemJPCTSource.zip))

Sound System (http://www.paulscode.com/libs/SoundSystem/14NOV2008/SoundSystem.jar)  (Download Source Code (http://www.paulscode.com/source/SoundSystem/14NOV2008/SoundSystemSource.zip))

Sound Manager (http://www.paulscode.com/libs/SoundSystem/14NOV2008/SoundManager.jar)  (Download Source Code (http://www.paulscode.com/source/SoundSystem/14NOV2008/SoundManagerSource.zip))

Fixed a problem some people were having on slower machines, where the automatic library compatibility check did not wait long enough for OpenAL to load before switching to JavaSound.  Fixed it so SoundSystem waits up to 10 seconds before giving up and switching.  This seems to be long enough for everyone who was having the problem.
Title: Re: 3D Sound System
Post by: fireside on November 15, 2008, 08:45:33 pm
Thanks for the work.  Hopefully I'll be using it on my next game.  I didn't download yet, though, because I'm really just getting started on it.  I was working on something else for a while.
Title: Re: 3D Sound System
Post by: paulscode on November 16, 2008, 06:42:54 am
Sound System, streaming sources no longer pre-loaded!


JARS:

Sound System jPCT (http://www.paulscode.com/libs/SoundSystem/15NOV2008/SoundSystemJPCT.jar)  (Download Source Code (http://www.paulscode.com/source/SoundSystem/15NOV2008/SoundSystemJPCTSource.zip))

Sound System (http://www.paulscode.com/libs/SoundSystem/15NOV2008/SoundSystem.jar)  (Download Source Code (http://www.paulscode.com/source/SoundSystem/15NOV2008/SoundSystemSource.zip))

I went back and looked at compatibility issues, and figured out the source of all my previous problems.  It was related to endianness.  Understanding this allowed me to write a working method for streaming directly from .ogg and .wav files.  I was able to remove the annoying workaround where I had to preload every audio file.

This is an enormous reduction in the amount of memory required for streaming sources, since SoundSystem now streams directly from the file or URL instead of from a huge pre-loaded audio buffer.
Title: Re: 3D Sound System
Post by: paulscode on November 16, 2008, 05:23:14 pm
SoundSystem library-switching bug fix, SoundSystemSmall released.


JARS:

Sound System jPCT (http://www.paulscode.com/libs/SoundSystem/16NOV2008/SoundSystemJPCT.jar)  (Download Source Code (http://www.paulscode.com/source/SoundSystem/16NOV2008/SoundSystemJPCTSource.zip))

Sound System (http://www.paulscode.com/libs/SoundSystem/16NOV2008/SoundSystem.jar)  (Download Source Code (http://www.paulscode.com/source/SoundSystem/16NOV2008/SoundSystemSource.zip))

Fixed a bug where audio data was being pre-loaded for streaming sources when switching between libraries.


I also decided to make a smaller version of SoundSystem for use in projects where memory is a concern, such as in web applets.  I removed support for OpenAL, eliminated all MIDI stuff, and cut out many of the redundant methods.  I was able to reduce the size of the JAR from 280KB down to 110KB.  The j-ogg library source is not compiled into the JAR, so to play .ogg files, the j-ogg library jar must be included at run time.  I stuck the compiled j-ogg jar inside the SourceCode .zip file):

Sound System Small (http://www.paulscode.com/libs/SoundSystem/16NOV2008/SoundSystemSmall.jar)  (Download Source Code (http://www.paulscode.com/source/SoundSystem/16NOV2008/SoundSystemSmallSource.zip))

Title: Re: 3D Sound System
Post by: fireside on November 16, 2008, 06:41:47 pm
Does the midi stuff take up much memory?  I was looking for something small, definitely, but midi music is super efficient for memory space.
Title: Re: 3D Sound System
Post by: paulscode on November 16, 2008, 07:38:06 pm
Cutting out the MIDI stuff from SoundSystemSmall was because of performance issues, not memory concerns.

MIDI is processed by Javasound.  Problem is, Javasound seems to (poorly) handle MIDI events and audio clip playback from a single thread, and because of this, whenever the thread is busy processing MIDI events, any playing audio clips skip.

In SoundSystem, MIDI only works well when OpenAL is the active library.  This allows Javasound to focus entirely on MIDI, while OpenAL handles all other audio playback.

Therefore, I removed MIDI support from SoundSystemSmall because OpenAL was removed.  I may go back at some point to see if I can get both MIDI and normal audio to play smoothly at the same time in Javasound, but for now there was no point in including MIDI support.  The small file size of MIDI music is useless if it can't be played at the same time as other sound effects.
Title: Re: 3D Sound System
Post by: fireside on November 16, 2008, 11:57:47 pm
OK, I'll probably use the larger library, then.  Have to see how things work out of course.  By the way, that code for the exact position of collision works great, so thanks a lot.  Gave me a great start on this game. 
Title: Re: 3D Sound System
Post by: paulscode on November 17, 2008, 12:59:44 am
I'll give MIDI another look tomorrow.  Maybe I'll see something I missed before.
Title: Re: 3D Sound System
Post by: paulscode on November 26, 2008, 11:23:11 pm
SoundSystemJPCT for new jPCT release.

JAR (http://www.paulscode.com/libs/SoundSystem/26NOV2008/SoundSystemJPCT.jar)  (Source Code (http://www.paulscode.com/source/SoundSystem/26NOV2008/SoundSystemJPCTSource.zip))

Removed the temporary work-around for the camera up-vector bug in the last version of jPCT.
Title: Re: 3D Sound System
Post by: EgonOlsen on November 26, 2008, 11:35:31 pm
Now that was fast... ;D
Title: Re: 3D Sound System
Post by: paulscode on November 26, 2008, 11:56:00 pm
I've been on the edge of my seat waiting for the next release of jPCT  :D

JK, it was only one line of code I had to comment out.
Title: Re: 3D Sound System
Post by: paulscode on December 16, 2008, 01:47:26 am
I have been informed of a new bug today.  Sometimes if an exception is thrown anywhere in a program (sometimes even if it is caught) before OpenAL has finished initializing, the OpenAL initialization times out, and SoundSystem automatically switches to JavaSound.  At the moment I have no idea what is causing this, but I am looking into it.  I always have trouble tracking down these "sometimes" bugs, since they can be difficult to replicate.  It is not a major problem, but one I'd like to eliminate if possible.  I'll post an update if I can figure out what's causing this to happen.
Title: Re: 3D Sound System
Post by: paulscode on December 16, 2008, 04:28:04 am
I was able to replicate the problem, and I tracked it to the line of code:

Code: [Select]
AL.create()
Turns out it is not actually an infinite loop as I feared.  Instead, what seems to be happening is that this method gets called, and then if an exception occurs before it finishes, it takes several seconds longer to finish.  Very strange.  I don't see anything that I can do to prevent this from happening, as this appears to be an issue with OpenAL and not with my code.  I will just increase the length of time that SoundSystem waits for OpenAL to load before it gives up and switches to JavaSound (or throws a SoundSystemException if using the second constructor).  I'll post the update when I have time to FTP everything.
Title: Re: 3D Sound System
Post by: fireside on December 17, 2008, 09:43:10 pm
You haven't found any way of using the small version with midi have you?  Would it be risky to use another thread? 
Title: Re: 3D Sound System
Post by: paulscode on December 18, 2008, 01:14:24 am
I tried using a seperate thread (the MidiThread class), but it didn't improve the performance.  I think JavaSound is still running the MIDI events and audio mixing on a single thread that I have no control over.  Come to think of it, I should probably remove the MidiThread class since it didn't help at all.  I haven't had a lot of time to look at this again.  I'll try and spend some time looking into the problem this weekend.  What I would REALLY like to do is write my own synthesizer to play MIDI into an AudioInputStream context, so that MIDI files could be used like any other format rather than playing through that crappy JavaSound midi event interface.  I wasn't able to find a non-GPL library to use, but I'll search around again and see if I can find one.  I may end up just studying the source code for the GPL one to figure out what they are doing, and learn how to write my own synthesizer (not using the original source code), and therefore not be bound by the GPL license.
Title: Re: 3D Sound System
Post by: fireside on December 18, 2008, 02:21:20 am
It might end up being the same size, though.  I suppose I get a little carried away with file size, but I like a small game that does a lot.  I might could skip music and use the small one.  It's a ways off, anyway.
Title: Re: 3D Sound System
Post by: paulscode on December 18, 2008, 02:33:05 am
I just now noticed a problem when playing a MIDI file in SoundSystem vs. playing it in a seperate player.  Sounds as if two instances of the file are playing simultaneously with a slight phase shift between them  ???  I hadn't noticed the problem before, since I hadn't actually played the test file in a seperate player, so I thought that is how it was supposed to sound.  There's most likely a bug in my code somewhere that I haven't noticed.  If the file is somehow being processed twice, it could be leading to the hang-up problem if JavaSound is having to work double-time (not to mention the conflicts that could occur due to the fact that only one MIDI output should be possible at one time on a given synthesizer).  I'll see if I can track down what is causing this double-playing.  I'll keep my fingers crossed that solving this will also solve the other problem.   :-X
Title: Re: 3D Sound System
Post by: paulscode on December 24, 2008, 02:00:48 am
I fixed the "phase shift" problem, and that also solved the skipping but it didn't fix the hang-up problem.  I uploaded a demo applet to demonstrate.  It is just a modified version of the player applet I wrote a while back:

http://www.paulscode.com/demos/SoundSystem/23DEC2008/ (http://www.paulscode.com/demos/SoundSystem/23DEC2008/)

To replicate the problem, start up the MIDI music, and then play one of the sound effects over and over again for a while (not too fast or you won't be able to hear what's going on).  You will see that randomly the sound effect will sometimes take up to a second or more from the time you press the button to when it actually plays.  Turn off the MIDI music, and the hang-up problem goes away.

I'm going to do some more work on this to see if I can somehow solve this problem, but if not, I'm affraid MIDI is just not ever going to be useful when using JavaSound to play other sound effects at the same time.
Title: Re: 3D Sound System
Post by: fireside on December 24, 2008, 05:07:34 am
It wasn't working on my computer for some reason, it just kept scrolling.  What about streaming as opposed to keeping it in memory?  I'm pretty sure I've played java games that had music and sound effects.
Title: Re: 3D Sound System
Post by: paulscode on December 24, 2008, 09:38:36 am
It wasn't working on my computer for some reason, it just kept scrolling.
Are you talking about the graphics or the sound (what is scrolling?)
If the problem is with the sound, is it just the MIDI, or are the other sound effects not working as well?  Are there any error messages or exceptions printing out to the Java console?
If you are referring to the graphics flicker, that is because they are not buffered.  I really should change that.  I originally just threw this applet together to replicate a bug that Egon was having with the Robombs sound effects a while back.

What about streaming as opposed to keeping it in memory?
MIDI can't be streamed.  Well, depending on your definition of streaming, that is (you could say that MIDI is always streamed).  Here's how it works.  A MIDI file does not contain any audio data at all.  Instead, it is full of commands called MIDI events.  These say higher-level things like "Play a high C on a guitar for one second".  These commands are loaded from the file into something called a "sequence".  Java sound has a "sequencer", which sends the MIDI events to a Receiver.  The receiver takes the events and tells the synthesizer what to do.  The synthesizer generates the actual audio.

So it appears to me that the problem is coming either from the sequencer taking too long to generate the MIDI events or the synthesizer taking too long to generate the audio.  More specifically, while JavaSound is somehow busy with a MIDI event, it doesn't get around to starting playback on the clips.  Running the entire process on a seperate thread does not seem to help, so something internal to JavaSound between MIDI and clip processing appears to be running on the same thread.  I do not seem to have any control over that, although I am looking into this some more.  If I can find some source code for playing clips and MIDI at the same time, it might help.

I'm pretty sure I've played java games that had music and sound effects.
Yes, of course, which is why this problem is so perplexing.  I know it is possible, I just can't figure out how.
Title: Re: 3D Sound System
Post by: paulscode on December 24, 2008, 10:39:36 am
I thought of some things to test which should help me narrow down where the MIDI/Clip hang-up problem is occurring:

1) Check if the command thread is actually running the Clip "play" commands at the proper time, and if so, is it taking a long time to process those commands.

2) Check if the hang-up problem only occurs for Clips, or if it also affects SourceDataLines as well.

3) Determine if there is an actual line of code that is taking a long time to run, or if the hang-up is completely internal.

4) Determine if the problem still occurs when using a Microsoft Windows-specific synthesizer instead of the Java synthesizer.

5) Rule out conflicts with SoundSystem code, such as the command thread.  To do this, I will create a bare-bones test case from scratch which does not use the SoundSystem library.

6) Rule out conflicts with non-sound related stuff, such as KeyEvents.

7)  Determine if the problem is with the sequencer or the synthesizer.  To do this, I will write a test program using the software synthesizer I talked about instead of the internal JavaSound synthesizer.  This would give me the ability to control what thread synthesis is happening on.  Obviously I won't be able to use this in the SoundSystem library, but it should help me verify if the synthesizer is the problem.

Title: Re: 3D Sound System
Post by: fireside on December 24, 2008, 05:46:03 pm
Quote
Are you talking about the graphics or the sound (what is scrolling?)

It's the graphics that appear to be scrolling.  I'll try it again.  I could just see the text choices going by really fast, like tv's in the old days when the vertical hold was off.
Title: Re: 3D Sound System
Post by: paulscode on December 25, 2008, 12:16:08 am
Oh, ok, I have the graphics buffered now so you can read the commands  ;)
Title: Re: 3D Sound System
Post by: fireside on December 26, 2008, 04:00:56 am
Yes, there does seem to be a slight delay when using java sound.
Title: Re: 3D Sound System
Post by: paulscode on December 31, 2008, 12:37:56 am
I'm going to look into an applet-specific option for MIDI.  Instead of using JavaSound to play MIDI, I will have the applet communicate back with the browser, and let the browser handle playing the MIDI file.  I've been playing around with applet / javascript interaction and it seems like this should be pretty simple (basically you'd interact with hidden <embed> tags - one for each MIDI file you want the applet to be able to play).  This option would of course require you to place the javascript code into the html page where the applet resides.  I will also need to make sure it is compatible with all the major browsers.  I am not actually going to include this in the SoundSystem library, but I'll release it as a seperate JAR that should go nicely with the small version of SoundSystem for use in applets (assuming of course that I can get it to work and it doesn't have any compatibility or delay problems).
Title: Re: 3D Sound System
Post by: fireside on December 31, 2008, 03:07:08 am
Sounds good.  Hope it works out.
Title: Re: 3D Sound System
Post by: paulscode on January 01, 2009, 09:14:55 pm
My initial attempts with the javascript MIDI stuff have been somewhat problematic.  It took me a while to find a method for controling MIDI via javascript which works in all the major browsers.  I eventually did find one.  Problem is it adds a new hiden element to the page each time play() is called, which causes the applet to loose focus, thus requiring you to either request focus again or click on the applet's frame.

One good thing I have discovered though is that the sound effects delay problem is gone when using the browser to play MIDI, so I am going to tinker around with this thing for a while to see if I can get it to behave properly.
Title: Re: 3D Sound System
Post by: fireside on January 01, 2009, 11:26:56 pm
That is a problem with Java.  I found a getfocus or something like that, but when I tried it, it didn't work.  The only way to really get the focus in an applet is to click inside it that I've found. 
Title: Re: 3D Sound System
Post by: EgonOlsen on January 02, 2009, 12:21:29 am
If your applet is signed anyway, you could use java.awt.Robot to let the applet click itself. Quite hacky, but possible... ;D
Title: Re: 3D Sound System
Post by: paulscode on January 30, 2009, 05:02:16 am
Ok, I think I have the Javascript MIDI library behaving in an acceptable manner finally.  The losing-focus problem has been solved.  In case you were wondering why it took me so long, it is extremely difficult to get something that behaves the same way in all browsers.  Oh, and I really hate Microsoft, btw.   >:(

Anyway...  Here it is:
Javascript and required files (http://www.paulscode.com/source/MIDI/PlayMidi/29JAN2009/MIDIAppletJavascrypt.zip)

Demo Applet (http://www.paulscode.com/source/MIDI/PlayMidi/29JAN2009/) demonstrating use of the javascript alongside the small version of Sound System
(Java Source (http://www.paulscode.com/source/MIDI/PlayMidi/29JAN2009/MIDIAppletSource.zip),  HTML Source (http://www.paulscode.com/source/MIDI/PlayMidi/29JAN2009/MIDIAppletHTMLSource.zip))

To use this javascript, make sure the files playmidi.js and silence.mid are in the same directory, and place the following line of code somewhere on your HTML page:
Code: [Select]
<script type='text/javascript' src='playmidi.js'> </script>
Include the following methods in your extended JApplet class.  These are just simple interfaces to the Javascript methods (the method names are pretty self-explanatory):
Code: [Select]
    public void loadMIDI( String fileUrl, float gain, boolean loop )
    {
        if( fileUrl == null )
            return;
       
        int volume = (int) (gain * 100.0f);
       
        if( volume > 100 )
            volume = 100;
        if( volume < 0 )
            volume = 0;
       
        String loopString;

        if( loop )
            loopString = "true";
        else
            loopString = "false";
       
        JSObject mainWindow = JSObject.getWindow( this );
        String[] args = new String[3];
        args[0] = fileUrl;
        args[1] = String.valueOf( volume );
        args[2] = loopString;
       
        mainWindow.call( "loadMIDI", args );
    }
   
    public void playMIDI( String fileUrl )
    {
        if( fileUrl == null )
            return;
       
        JSObject mainWindow = JSObject.getWindow( this );
        String[] args = new String[1];
        args[0] = fileUrl;
       
        mainWindow.call( "playMIDI", args );
       
        this.requestFocus();
    }
   
    public void pauseMIDI( String fileUrl )
    {
        if( fileUrl == null )
            return;
       
        JSObject mainWindow = JSObject.getWindow( this );
        String[] args = new String[1];
        args[0] = fileUrl;

        mainWindow.call( "pauseMIDI", args );
       
        this.requestFocus();
    }
   
    public void stopMIDI( String fileUrl )
    {
        if( fileUrl == null )
            return;
       
        JSObject mainWindow = JSObject.getWindow( this );
        String[] args = new String[1];
        args[0] = fileUrl;

        mainWindow.call( "stopMIDI", args );
       
        this.requestFocus();
    }
   
    public void rewindMIDI( String fileUrl )
    {
        if( fileUrl == null )
            return;
       
        JSObject mainWindow = JSObject.getWindow( this );
        String[] args = new String[1];
        args[0] = fileUrl;

        mainWindow.call( "rewindMIDI", args );
       
        this.requestFocus();
    }
   
    public void setMIDIAttribute( String fileUrl, String attribute, String value )
    {
        if( fileUrl == null )
            return;
       
        JSObject mainWindow = JSObject.getWindow( this );
        String[] args = new String[3];
        args[0] = fileUrl;
        args[1] = attribute;
        args[2] = value;
       
        mainWindow.call( "setMIDIAttribute", args );
    }

To be able to compile your applet, you will also need to include the file 'plugin.jar', which can be found in your jre directory under the 'lib' subdirectory.  Also, import netscape.javascript.JSObject at the top of your code.  You do NOT need to include 'plugin.jar' in your applet's archive list at runtime - it will already be loaded when running the applet from inside a browser

I have the javascript working for all the major browsers using the QuickTime audio pluggin for MIDI, which is the default for most browsers, so most people are likely to be using it.  The javascript may works with some other audio pluggins as well, but I haven't taken the time to test this yet.  Problem is each pluggin uses its own method names for the controls (play() Play() or doPlay(), for example) so I'd have to check what audio pluggin a user has and call the correct methods for it).  I may come back at some point to work on that, but for now it is probably going to work 90% of the time.

A couple of limitations / bugs with this javascript:
1) Apparently a "hidden" embed tag cannot be played in browsers based on Netscape technology (Firefox for example), so I had to make the player visible.  A width and height to zero works fine in Firefox, but it does not compute in Internet Explorer, so I was forced to go with a width and height of 1.  Therefore, the browser displays a single pixel for each embed tag wherever you place the javascript on your page.  For that reason, I recommend placing the script at the bottom of the page (right before closing the </body>)  Or if you have a better place on the page, just put it wherever.  I'm going to tinker around with this some more to see if I can figure a way to make the thing completely invisible (I might have to brush up on my HTML skills).
2) With the QuickTime pluggin (possibly other pluggins as well), you can't change the "volume" and "looping" attributes via javascript once your <embed> tag has been created.  For that reason, you must specify the volume and looping attributes of your MIDI file when you load it, and they can not be changed later.
3) The user has complete control over the MIDI playback, so if they have music or embed disabled in their browser, or their Synth volume control is muted, there's not much you can do about it.
4) I was having problems with loud scratching sounds in some browsers the first time a sound is played.  To compensate, I had to make the javascript automatically play a silent MIDI file when it starts up.  This is completely transparent, but you are required to place the file "silence.mid" wherever the javascript is located.  On one of my test machines, I noticed the scratchiness had popped back up when loading the sounds from inside an applet rather than from the HTML.  If this starts happening a lot, a workaround would be to pre-load the MIDI files directly from the HTML rather then from inside the applet:
Code: [Select]
<script type='text/javascript' src='playmidi.js'> </script>
<script type='text/javascript'>
<!--
loadMIDI( 'theme.mid', 100, true );
loadMIDI( 'Bach.mid', 40, false );
//-->
</script>
Title: Re: 3D Sound System
Post by: fireside on January 30, 2009, 05:05:19 pm
It says I need to install apple Quicktime plugin.  Would that be right? 
Title: Re: 3D Sound System
Post by: fireside on January 30, 2009, 07:50:11 pm
Apparently Firefox doesn't come with a midi player.  I realize you just did a ton of work on it, but I'm not sure I would want to ask people to download Quicktime if they have Firefox on their computer which is over 20 per cent right now.  I have to think about it a little bit.  I'm really sorry about this.  I had no idea it would be this complicated.  I should have just shut up.
Title: Re: 3D Sound System
Post by: paulscode on January 30, 2009, 10:08:27 pm
Yes, Quicktime or any other pluggin for playing MIDI is required for this script to work in any browser, not just Firefox.  No problem, I learned a lot making this script.  BTW, there is another way to do it using flash (would require a Flash pluggin to be installed, of course).  I didn't choose that route because I figured users are more likely to have Quicktime installed than Flash.  If you prefer, I can make a Flash version of the script.
Title: Re: 3D Sound System
Post by: paulscode on January 30, 2009, 10:43:30 pm
I had another thought.  I could use the <BGSOUND> tag, which only works in Internet Explorer.  As you say, that would exclude over 20% of users, but at least it would be silent and not ask them to install anything.

I could also make a hybrid, which would use <BGSOUND> if the user was running Internet Explorer, and <EMBED> (either QT or Flash) if the user was running a different browser like Firefox.  That would reduce the users requiring a pluggin installed from 100% down to 20%.
Title: Re: 3D Sound System
Post by: paulscode on January 30, 2009, 10:49:59 pm
Hmm, I wonder what would happen if I were to create a seperate applet that uses JavaSound to play MIDI (communication between applets could be done through javascript) - if I would still have the delay problems that I am experiencing with MIDI and JavaSound in SoundSystem .  I think I'll give that a try.
Title: Re: 3D Sound System
Post by: fireside on January 30, 2009, 11:02:51 pm
Pretty much everyone that plays games on the internet has Flash installed, so I think it would be the better option. 

I'll admit I don't know anything about this yet, but I noticed this page in a search which states that there are 2 sequencers in java, the java sound sequencer and the real time sequencer.  Was wondering if that might be useful for this situation. Question 3.10

http://www.jsresources.org/faq_midi.html
Title: Re: 3D Sound System
Post by: fireside on January 31, 2009, 12:01:04 am
I edited the above post.  It just seems like such a round about solution to me. 
Title: Re: 3D Sound System
Post by: paulscode on January 31, 2009, 03:04:21 am
Really interesting - I hadn't heard about there being more than one sequencer available in Java.  It might be worth a shot to try using that Real Time Sequencer (since I don't really know where the hang-up problem is coming from specifically).  Did you happen to come across anything that demonstrates how to actually choose what sequencer you want to use?  After a couple of quick google searches, the only method I can find for getting a sequencer instance is javax.sound.midi.MidiSystem.getSequencer(), which returns the "default sequencer" (I assume this is the "Java Sound Sequencer", not the "Real Time Sequencer").  I'll look into this some more tomorrow, as well as the other things I mentioned above (like using flash, etc.)  At least I have a few things I can try out (I hate when I run into a brick wall and can't think of anything to do).

--EDIT--
I'm thinking maybe something along these lines might also work for choosing a sequencer (I've done this before for choosing a synthesizer):
Code: [Select]
MidiDevice device;
MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo();
for( int i = 0; i < infos.length; i++ )
{
    try
    {
        device = MidiSystem.getMidiDevice( infos[i] );
    }
    catch( MidiUnavailableException e )
    {
          // Handle or throw exception...
    }
    if( device instanceof Sequencer )
    {
        // TODO: Somehow figure out if this is the "Real Time Sequencer"
    }
}
Worth a shot anyhow.
Title: Re: 3D Sound System
Post by: fireside on January 31, 2009, 03:45:57 am
Yeah, that looks similar to the code on this page which is for getting non-default sequencers:
http://java.sun.com/docs/books/tutorial/sound/accessing-MIDI.html
Title: Re: 3D Sound System
Post by: paulscode on January 31, 2009, 04:34:10 am
Thanks for the link.  That's probably the page where I got that code from initially (the example on that page is for selecting a non-default synthesizer, not a sequencer).
Reading that page again, I found the following paragraph which confirms my previous thought that perhaps some similar code could be used to locate a non-default sequencer, too:
Quote
Here is the method for learning about the installed devices:

    static MidiDevice.Info[] getMidiDeviceInfo()

As you can see, it returns an array of information objects. Each of these returned MidiDevice.Info objects identifies one type of sequencer, synthesizer, port, or other device that is installed.
Title: Re: 3D Sound System
Post by: fireside on January 31, 2009, 04:54:29 am
This may or may not apply also:
http://java.sun.com/j2se/1.5.0/docs/api/javax/sound/midi/Sequencer.SyncMode.html
Title: Re: 3D Sound System
Post by: paulscode on January 31, 2009, 12:27:39 pm
Oh, yes, I have seen that setting before, but I never had to actually change it from it's default setting (you never know - switching to a different sequencer might require this setting to be changed).

So in our case, the sequencer is running in a master synchronization mode, generating MIDI messages and sending them to the JavaSound synthesizer (we aren't doing anything fancy like relaying MIDI messages from a music keyboard directly to a hardware synthesizer).  So from the information on that link, it looks like I will probably want to use the MIDI_SYNC mode.
Title: Re: 3D Sound System
Post by: fireside on January 31, 2009, 04:31:57 pm
One other thing, you've probably already tested it, but if the sound effect is in memory rather than streaming it may change whether there is a delay. 
Title: Re: 3D Sound System
Post by: paulscode on January 31, 2009, 10:18:27 pm
MIDI does not stream, i.e., the entire "sequence" is loaded from the .mid file, not read in a little at a time.
Title: Re: 3D Sound System
Post by: fireside on January 31, 2009, 10:45:49 pm
Yeah, but what about the sound effects?  They can be either streamed or loaded from memory can't they?
Title: Re: 3D Sound System
Post by: paulscode on January 31, 2009, 10:59:12 pm
Oh, sorry, I missunderstood you there.  In the demo applet that was experiencing the delay problem, those sound effects were not being streamed.  I haven't checked if streaming the sound effects instead would make a difference or not.
Title: Re: 3D Sound System
Post by: fireside on January 31, 2009, 11:43:45 pm
Oh, just a thought.  I would think that if it mattered, the streaming would cause the delay.
Title: Re: 3D Sound System
Post by: paulscode on February 01, 2009, 02:21:37 am
Ok, I finally had a little time to play around with the MIDI stuff some more today.  Interestingly, it turns out that the "Real Time Sequencer" is in fact the default sequencer, and therefore the one that is being used by SoundSystem.  Another interesting thing is that "Java Sound Sequencer" does not even show up in the list (perhaps it was removed in the latest version of Java??!)

I used the following code to generate some output about the MIDI devices:
Code: [Select]
        try
        {
            MidiDevice device = null;
            MidiDevice.Info[] midiDevices = MidiSystem.getMidiDeviceInfo();
            System.out.println( midiDevices.length + "MIDI Devices:" );
            for( int i = 0; i < midiDevices.length; i++ )
            {
                try
                {
                    device = MidiSystem.getMidiDevice( midiDevices[i] );
                }
                catch( MidiUnavailableException e )
                {
                      device = null;
                }
               
                System.out.println( "    " + midiDevices[i].getName() );
                if( device instanceof Synthesizer )
                    System.out.println( "        *this is a Synthesizer instance" );
                if( device instanceof Sequencer )
                    System.out.println( "        *this is a Sequencer instance" );
            }
        }
        catch( Exception e )
        {
            // Midi unavailable
        }
        System.out.println( "Default sequencer: " + sequencer.getDeviceInfo().getName() );
        if( sequencer instanceof Synthesizer )
            System.out.println( "Default sequencer is also a synthesizer" );
        System.out.println( "Default synthesizer: " + synthesizer.getDeviceInfo().getName() );
        if( synthesizer instanceof Sequencer )
            System.out.println( "Default synthesizer is also a sequencer" );


Here is the JAva Console output I get:
Quote
6MIDI Devices:
    USB Audio Device
    Microsoft MIDI Mapper
    USB Audio Device
    Microsoft GS Wavetable SW Synth
    Real Time Sequencer
        *this is a Sequencer instance
    Java Sound Synthesizer
        *this is a Synthesizer instance
Default sequencer: Real Time Sequencer
Default synthesizer: Java Sound Synthesizer

So it looks like I won't be able to try using a different sequencer after all, since there is only one available.

On the other hand, I may be able to send the MIDI messages to the Microsoft GS Wavetable SW Synthesizer.  Of course, that would only work on computers running versions of Microsoft Windows.

Hmm.. maybe I could find out what are the default software synthesizers on Linux, Mac, and Solaris, and have SoundSystem choose whichever one is available on the user's computer (or use the default Java Sound Synthesizer if none are found).  Let me see if using a different Synthesizer corrects that delay bug...
Title: Re: 3D Sound System
Post by: paulscode on February 01, 2009, 02:36:52 am
Yes it does!  Hurray!  ;D

Ok, so now I just need to research what are the common software synthesizers on various operating systems.
Title: Re: 3D Sound System
Post by: fireside on February 01, 2009, 02:42:50 am
That's a good start.  Even if there is a slight delay on one of the other systems, It might be something to live with since a vast majority use windows. 
Title: Re: 3D Sound System
Post by: paulscode on February 01, 2009, 04:05:07 am
Err, Ok I am having more difficulty than expected finding what software synthesizers are common on other operating systems.  For example, I can find a ton of synthesizers that are available for Linux, but nothing indicating if any of them are part of a normal install.  Similar situation for Mac.  I think what I'll do is go on several different forums and post a link to an applet that outputs the available MIDI devices.  I'll have people running Non-Microsoft Windows operating systems tell me what output they get, and then maybe I can figure out what (if any) software synthesizers are commonly installed.
Title: Re: 3D Sound System
Post by: paulscode on February 01, 2009, 04:33:02 am
Here is a link to that MIDI Device Discovery applet:

http://www.paulscode.com/source/MIDI/MIDIDeviceDiscovery/ (http://www.paulscode.com/source/MIDI/MIDIDeviceDiscovery/)

If anyone here is running a non-Microsoft Windows operating system, could you please run the applet and copy the output from the Java Console?  Be sure to mention what operating system and version you are running.

--Interesting note:  Microsoft changed the name of their synthesizer slightly in Vista (they removed the "SW").  Kind of odd since it has had the same name since Windows 3.1, as far as I can remember.
Title: Re: 3D Sound System
Post by: EgonOlsen on February 01, 2009, 10:01:56 am
This is the output when running it on an EEEPC 701 4G with the default Linux installation (some Xandros IIRC).

Code: [Select]
2 MIDI Devices:
    Real Time Sequencer
        *this is a Sequencer instance
    Java Sound Synthesizer
        *this is a Synthesizer instance
Title: Re: 3D Sound System
Post by: paulscode on February 01, 2009, 03:28:28 pm
Man, I keep seeing "Real Time Sequencer" and "Java Sound Synthesizer" over and over again for various Linux versions as well as for Mac OS.  So far the only different Synthesizer I have seen is on a Kubuntu 8.04 (64 bit) with Konqueror, which has the Gervill synthesizer (that's the GPL-licensed open-source Java software synthesizer I was talking about a few posts back.  It may be a standard-install on Kubuntu - I'll have to see a few more examples, though to know).

So it looks like practically all non-Microsoft OS's are going to have to use the default Synthesizer and Sequencer, and therefore will probably still going to have to deal with the delay problem when playing MIDI and sound effects simultaneously under JavaSound.

Maybe I could figure out a way to distribute Gervill seperately (since it is open-source and all) for folks who are not using a Microsoft OS.  I'll look into this (first I will have to see if using it corrects the delay problem).
Title: Re: 3D Sound System
Post by: paulscode on February 01, 2009, 04:08:49 pm
Ok, another question.  I can think of several ways to distribute Gervill.  Which way sounds best?

Option #1:  Make a stand-alone Java application that the user would have to run before playing his/her game.  Advantages:  Would make meeting the GPL-license requirement easy (just distribute the stand-alone application's source code and license document along with it).  Disadvantages:  Would require the user to actually think.

Option #2:  Distribute the application from Option #1 along with the game, and have it launched automatically by the game if a software synthesizer wasn't found on the user's computer.  Advantages:  Same as Option #1.  Also, would be completely transparent (user doesn't have to think).  Disadvantages:  Would only be an option for Applications.

Option #3:  Make a seperate applet that would be added to the page via Javascript if a software synthesizer wasn't found on the user's computer.  Advantages:  (none, but would would be required to cover Applets if Option #2 were chosen)  Disadvantages:  Applets only.  Also, would require the game website to have a link for downloading the seperate applet's source code and GPL license-agreement.

Option #4:  Link with a seperate JAR library that contains Gervill, which would be used if a software synthesizer wasn't found on the user's computer.  Advantages:  Simplest option to implement.  Disadvantages:  Would increase the memory footprint (could be an issue for applets).  Also, would require making the Gervill JAR library's source code and GPL license-agreement available (links on the game website for applets, or bundled with applications).

Did I mention that I hate GPL-licensed stuff?

Anyway.. I tend to lean toward Option #4, but I thought I would get some feedback on this before deciding.
Title: Re: 3D Sound System
Post by: fireside on February 01, 2009, 04:34:15 pm
This is side tracking, but this appears to be a mixer problem to me.  The reason it works with another synth is that it isn't using the sound api for both effects and music anymore.  There is a mixer for java 5.  I was just wondering if you explored that possibility at all.  I don't know if it's automatic or what.

http://java.sun.com/j2se/1.5.0/docs/api/javax/sound/sampled/Mixer.html
Title: Re: 3D Sound System
Post by: paulscode on February 01, 2009, 04:56:49 pm
Yes, I am using a mixer for the sound effects.  How would I link a MIDI device up to the Mixer, though?  I don't see any "getTransmitter" or "getReceiver" methods (or any MIDI-related methods) for the Mixer or Line classes.  I don't see "getMixer" or "setMixer" methods (or any Mixer or Line related methods) for the MIDIDevice, Sequencer, or Synthesizer classes either.  The Mixer appears to be only used for mixing Lines, which are instances either of DataLine (SourceDataLine, TargetDataLine, or Clip) or Port (compact disks, headphones, audio input jacks, audio output jacks, microphones, or speakers).

I'll do some more searching on this though, to see if MIDI can somehow be routed through a mixer.  At the moment, the only way I know how to do it is by converting the MIDI sequence into an AudioInputStream context (which is what Gervill does).
Title: Re: 3D Sound System
Post by: fireside on February 01, 2009, 05:36:14 pm
OK.  This whole problem is just so mystifying to me.  I mean, we're just trying to play some music and sound effects at the same time.  Surely that must have occurred to them. 
 I guess either way, then.  Apple might have one, so it might be just linux and I would think it wouldn't be much of a download.
Title: Re: 3D Sound System
Post by: paulscode on February 01, 2009, 06:17:18 pm
I'm afraid there isn't one on apple either, here is an example:

Quote
-- Opera - Java Console --

Java vendor: Apple Inc.
Java version: 1.5.0_16

type 'h' for help

--
Sun Feb 01 14:52:57 EST 2009 JEP creating applet MIDIDeviceDiscovery (http://www.paulscode.com/source/MIDI/MIDIDeviceDiscovery/)
2 MIDI Devices:
Real Time Sequencer
*this is a Sequencer instance
Java Sound Synthesizer
*this is a Synthesizer instance

I agree that this does seem like a Mixer issue, and you would think they would have thought of that when they created the Java Sound Synthesizer.  I just need to keep playing around with this thing to get it working.
Title: Re: 3D Sound System
Post by: paulscode on February 01, 2009, 06:59:57 pm
I think I may have solved the delay problem (using "Java Sound Synthesizer")!  I noticed that if I select the Java Sound Synthesizer it returns "null" when I call 'getDefaultSoundbank()'.  I recalled that I added in the following code, because applets (and applications as well if JDK is not installed) were completely silent (I originally got this solution from a forum somewhere)
Code: [Select]
        if( !( sequencer instanceof Synthesizer ) )
        {
            try
            {
                    synthesizer = MidiSystem.getSynthesizer();
                    synthesizer.open();
                    Soundbank soundbank = synthesizer.getDefaultSoundbank();
                    if( soundbank == null )
                    {
                          URL defaultSoundBankFile = getClass().getClassLoader()
                              .getResource(
                                        SoundSystemConfig.getDefaultMidiSoundBank() );

                          Soundbank defaultSoundBank =
                                      MidiSystem.getSoundbank( defaultSoundBankFile );
                          synthesizer.loadAllInstruments( defaultSoundBank );
                    }

                    Receiver receiver = synthesizer.getReceiver();
                    Transmitter transmitter = sequencer.getTransmitter();
                    transmitter.setReceiver( receiver );
                }
...

The thought occurred to me, that perhaps the instruments are really there, built into the Java Sound Synthesizer and simply not retrievablty with getDefaultSoundbank() - If that were the case, it would mean that I am loading a whole new set of instruments on top of the ones already there, and confusing JavaSound.  I removed the sound bank loading code (leaving in the transmitter/receiver linkage), and ran the applet.  It works beautifully now, with no delay problem (at least on my main computer - I still need to verify this on my test machines).

So moral of the story:  Don't always trust what you read on the forums  :D.  I think the reason this took so long to solve, is there was I thought I had corrected another problem, I wasn't getting any error messages or exceptions, and I didn't notice the delay problem until sometime later after I made the change.
Title: Re: 3D Sound System
Post by: paulscode on February 01, 2009, 07:13:13 pm
Verified on my test machines - problem solved!  I will make the changes to SoundSystem and post an update later.

An interesting side-note:  If there is a MIDI music keyboard hooked up to the computer, JavaSoundSynthesizer will play MIDI through it - I little bit anoying, but something I can live with (I suspect Java is actually playing the MIDI through the Microsoft MIDI Mapper - I had a similar bug several years ago with a MIDI program called "Cakewalk", which I solved by changing the Microsoft MIDI Mapper setting for "default MIDI device" or something).  Most players are not going to have MIDI keyboards hooked up, anyway.
Title: Re: 3D Sound System
Post by: fireside on February 02, 2009, 12:10:32 am
Cool.  Glad you finally got it worked out.
Title: Re: 3D Sound System
Post by: paulscode on February 02, 2009, 02:20:29 am
Sound System MIDI Fixes

JARS:

Sound System jPCT (http://www.paulscode.com/libs/SoundSystem/01FEB2009/SoundSystemJPCT.jar)  (Download Source Code (http://www.paulscode.com/source/SoundSystem/01FEB2009/SoundSystemJPCTSource.zip))

Sound System (http://www.paulscode.com/libs/SoundSystem/01FEB2009/SoundSystem.jar)  (Download Source Code (http://www.paulscode.com/source/SoundSystem/01FEB2009/SoundSystemSource.zip))

Sound System Small (http://www.paulscode.com/libs/SoundSystem/01FEB2009/SoundSystemSmall.jar)  (Download Source Code (http://www.paulscode.com/source/SoundSystem/01FEB2009/SoundSystemSmallSource.zip))


Other:

Demo Applet (http://www.paulscode.com/demos/SoundSystem/01FEB2009/SoundSystemPlayerApplet.html)

JavaDoc (http://www.paulscode.com/docs/SoundSystem/)

PDF Tutorial (http://www.paulscode.com/tutorials/SoundSystem/SoundSystem.pdf)


What's new?

- Corrected the delay problem that was happening when playing sound effects with the Java Sound library while MIDI was playing.  This fix also eliminated the need for SoundSystemResources.jar, which significantly reduces the memory footprint required to play MIDI in applets.
- Removed the MidiThread class (a work-around that is no longer needed).
- Added support for MIDI into the small version of sound system.
- Made a few changes to the PDF tutorial document.
Title: Re: 3D Sound System
Post by: fireside on February 02, 2009, 02:33:12 am
Does the soundsystemsmall have any dependencies?  Does it play ogg?
The demo applet isn't working for me for some reason.  Never mind, I needed to click in the window to get focus.
Title: Re: 3D Sound System
Post by: paulscode on February 02, 2009, 02:56:02 am
SoundSystemSmall has no dependencies when playing .wav or .mid.  To play .ogg, you must include the j-ogg library.

Oops - I just noticed that I forgot to include that JOgg.jar file in the above SoundSystemSmallSource.zip, so I re-uploaded it (thanks for reminding me by mentioning .ogg!)
Title: Re: 3D Sound System
Post by: fireside on February 02, 2009, 03:06:43 am
What's different about midi, it says that would be covered in a later tutorial in the pdf?
Title: Re: 3D Sound System
Post by: paulscode on February 02, 2009, 03:34:00 am
I am working on a more in-depth tutorial right now, but until then, you basically create MIDI sources just like any other sources, using any of the source creation methods (doesn't matter if you use a normal or streaming source method, both do the same thing when you specify a MIDI file).    Easiest method to use would probably be BackgroundMusic().  The file must have the extension '.mid' or '.midi'.

You can manipulate the MIDI source just like any other source (for example, you can change the volume of the MIDI source using the SoundSystem.SetVolume() method.  Attenuation and 3D Panning effects do not apply to MIDI sources.

So that is MIDI in a nut-shell (the tutorial will go a little more in-depth, but that should be enough to get you started).
Title: Re: 3D Sound System
Post by: paulscode on February 03, 2009, 12:02:40 am
Oops, I just realized that I never uploaded the changes I made to that PDF Tutorial (http://www.paulscode.com/tutorials/SoundSystem/SoundSystem.pdf).  The most important difference is that the old version stated that all files are pre-loaded into memory, including those used by streaming sources - THAT IS NO LONGER TRUE!  I hope nobody was confused if they read that.  Streaming sources are actually streamed, not read in all at once.  I also decided to go ahead and add a short section on MIDI into the tutorial before I re-uploaded it.

My next tutorial will go much more in depth into source creation, manipulation, and various settings, and it will explain a little more about what is going on behind the scenes.  The first tutorial was more of a "getting started" type of guide.
Title: Re: 3D Sound System
Post by: paulscode on February 09, 2009, 01:59:04 am
I got an interesting suggestion today from someone using the SoundSystem.  He wanted to be able to queue up a MIDI loop to play immediately after the end of an intro/lead-in.  I am thinking a function like this would actually be usefull for all types of sources, not just for MIDI (since background music could be in any format).  The way it should work is you specify a sound that you want to play from a particular source as soon as the sound it is currently playing finishes.  You would also indicate if the new sound should loop or play only once.

Only thing I am not sure about is how to handle calls to stop and play in the following situations:

1) The source is stopped before the first sound finishes.  Should a subsequent call to play restart the first sound, then switch to the second sound, or would some other behavior be expected in this case?

2) The first sound finished, and the new sound is playing away when the source was stopped.  Should a subsequent call to play start the new sound or the first sound?  Maybe it should play the new sound, since this would normally be used for background music, and the main music loop is likely to be the new sound?

I think it is a good idea, but I thought I would get some suggestions before I actually implemented it.
Title: Re: 3D Sound System
Post by: fireside on February 09, 2009, 02:28:54 am
I don't really have enough experience with it yet.  Actually, I haven't gotten a chance to try out your sound program yet.  I've been playing around with a free midi composer right now.  I think being able to specify the next song after the current one is finished would be a good idea if that's what you mean.
Title: Re: 3D Sound System
Post by: elias4444 on February 11, 2009, 05:07:35 pm
Hey Paul, I've been looking for a good sound system to plop down into my own game engine. How have you licensed your code? Is it free to use?
Title: Re: 3D Sound System
Post by: paulscode on February 12, 2009, 12:01:57 am
Yes, it is free to use and alter any way you like, in any commercial and/or non-commercial product or otherwise.  You are not required to give me credit, but of course it would be nice.  Since one of the classes in the library (AudioData) is based on source code from the lwjgl library, if you decide to redistibute the library or source code in its current form or in a modified form, you must include the lwjgl license agreement, which basically says, "this library is offered as is, and we are not responsible for any damages ... etc".  To read the full text of the agreement, see the JavaDoc for the AudioData class, or read the comments in the AudioData class's source code.
Title: Re: 3D Sound System
Post by: paulscode on February 22, 2009, 01:58:21 am
After looking into the sound-queuing idea more closely, I have decided to only implement this for streaming sources and MIDI sources, not for normal sources.  Reason is that there is no way to know when a playing normal source has reached the end, other than to continuously check if it is still playing.  On the other hand, it is easy to know when a streaming source reaches the end, and at that time the StreamThread can start feeding in audio data from the next sound in the queue.  It is also easy to know when MIDI reaches the end, since an "end of sequence" event occurs, at which point the next sequence in the queue can be loaded into the sequencer.

I think this is an acceptable compromise, since sound queuing is mostly going to be used for background music, which will generally be streaming or MIDI.
Title: Re: 3D Sound System
Post by: zammbi on March 01, 2009, 04:51:52 am
Hey I think this great work, finally been able to use your library.
I been testing quite a few sound libraries to play ogg for my 2d game and each one has its own problems or rarely gets updated.
Which I'm hoping you can fix the bugs I'm having with Sound System Small.
I am loading a ogg (music) which plays fine.
Then there's some clicking noises in the middle.
After the song finishes it will keep playing a soft sound, small part of my ogg.
It then sucks my ram up.
If I try to loop it, it wont loop.
Also seems I'm having trouble playing my ogg sounds...
Title: Re: 3D Sound System
Post by: paulscode on March 01, 2009, 03:00:05 pm
From you post, it seems you are having the problems only with .ogg files, is this correct?  Could you email me the .ogg file(s) you are having problems with, or post links to them?

Also, could you please let me know the details about your computer (speed, memory, audio hardware, os)? 

Additionally, could you please run the following applet:
http://www.paulscode.com/demos/SoundSystem/01FEB2009/SoundSystemPlayerApplet.html (http://www.paulscode.com/demos/SoundSystem/01FEB2009/SoundSystemPlayerApplet.html)
With the JavaSound library loaded, please stream the file "beats.ogg" (using the space bar), and let me know if the music has the same problems you were experiencing and if it loops correctly.  If you do experience problems, then try the same test in OpenAL to see if there is a problem there as well.
Title: Re: 3D Sound System
Post by: zammbi on March 01, 2009, 03:19:48 pm
The demo posted the sound is perfect hm...
I'm sure I'm not doing anything wrong in my code as I basically follow your examples. But I will test it tomorrow on a plain app (heading to bed now).

Stats:
Duel core 2ghz, 3Gigs of ram, Realtek High definition, Windows 7.

I'll send you the files.

Edit: sent.
Title: Re: 3D Sound System
Post by: paulscode on March 01, 2009, 03:51:47 pm
Ok, great, I got the .ogg files.  I'll run some tests to see if I can track down the problem.  Good to hear the demo applet works for you  - I should be able to just focus on the files themselves.  I'll let you know what I find out.
Title: Re: 3D Sound System
Post by: paulscode on March 01, 2009, 06:31:41 pm
Ok, I've had a little time to look into this.  First of all, the problem happens in both JavaSound and OpenAL, so we can rule out anything specific to JavaSound or SoundSystemSmall.  My initial best-guess is that there may be a problem with the j-ogg library loading process for these specific .ogg files.  The reason I think this, is because for both of these files, the ogg loader is getting into an infinite loop during load time.   A very similar bug, which I've known about for some time, will often occur when loading more than one .ogg file simultaneously (such as when streaming two .ogg files at once).  I can track the problem down to a call to the OggInputStream.read() method, but I don't know enough about how the j-ogg decoding process works to get any closer to the problem than that.

Here's my best explanation of what's happening with your two files:

1) For Intro.ogg, most of the file loads correctly, but the loader gets stuck near the end, loading the same chunk of data over and over again and never reaching EOF.  So when you stream this file, it sounds like the end repeats over and over again.  Also, as you mentioned before, there seems to be some random clicking during playback, which could also be symptomatic of a problem during load-time.

2) For Login Sound.ogg, the exact same problem happens near the beginning of the sound.  The sound effect is silent at this part, so that is why you don't hear anything playing, whether you try to stream the file or pre-load it for a normal source.  It doesn't get very far into the file before the infinite loading loop begins, so it is impossible to tell if this sound would have the same clicking problem as Intro.ogg.

That's all I the information I have for the moment.  I am going to create a small test program much more simple than SoundSystem, so I can hopefully get some help from other programmers who have used the j-ogg library more extensively than I have.  If possible, I'll also try to get in touch with the j-ogg library's developer Jarnbjo.

One more thing that might be useful - do you know what program was used to create these two .ogg files?  It might possibly give me an idea what is special about these two .ogg files as compared to the .ogg files I have been using in all my previous test cases.
Title: Re: 3D Sound System
Post by: paulscode on March 01, 2009, 08:21:21 pm
Progress update:

I have put together my test program and posted the question on a couple of forums.

I have been experimenting with various file converter programs to see if I could produce .ogg files that consistantly have the load-problem, and I found a couple that do - "VLC Media Player" and "MP3 Converter Simple".  Both of these programs have a lot of settings to choose from when saving the .ogg file, so I am going to try and play around with these settings to see if I can figure out what causes the j-ogg loader to choke.  Hopefully that might help in tracking down the source of the problem.  At the very least, it will provide a work-around until I can figure out what is causing the problem (changing the settings on the existing .ogg files to make them compatible with SoundSystem).

--UPDATE--
I have been playing around with converter settings, and I can not seem to find any discernable pattern.  The settings in one converter will produce a file that can't be loaded, while the exact same settings in another converter will produce a file that works fine.  The clicking problem also seems to be completely random from one converter to another.

I did however discover one important thing:  very small .ogg files almost NEVER load properly, no matter what their settings are or which converter was used to create them.  I'm pretty sure that is why your Login Sound.ogg file will not load.

So, until I figure this problem out, here are some work-arounds that you can use:

1) For the larger music sounds that you stream, until I get this problem fixed, just run your files through a converter which produces .ogg files that are compatible with SoundSystem.  A simple freeware one that I like is called "Free Audio Converter", which you can download from http://www.free-audio-editor.com/FreeAudioConverter.exe (http://www.free-audio-editor.com/FreeAudioConverter.exe).  It seems to do best when converting from .wav to .ogg, so I would recommend converting the original .ogg into a high-quality .wav, then convert that back into a .ogg with whatever compression level you want (otherwise it will sometimes add in small random clicks and scratches).

2) Use the .wav format for any small sound effects that you are not streaming.  Note that the actual audio data itself is the same size whether you loaded it from a .wav or a .ogg, so unless you are streaming the audio, there is no advantage to using .ogg files over .wav files.  Of course memory is often a concern for applets, so in order to avoid the memory required to compile your .wav files directly into the JAR, just pre-load their audio date from online URLs instead, by using the loadSound() method.  Just make sure the filename you pass to SoundSystem begins with "http://" (that is how it knows to look online rather than inside the JAR).  Hmm.. I just now realized that I never provided an unloadSound() interface method (I'm sure I did, but it must have disappeared somehow).  Anyway ... I will correct that in the next release.

Sorry for all the .ogg problems.  Hopefully this will be enough to at least get you up and running - I have no idea if I will be able to solve this.  If I can't get j-ogg to work, I may have to end up looking for other alternative ogg libraries.
Title: Re: 3D Sound System
Post by: zammbi on March 01, 2009, 11:19:07 pm
Thanks for looking at this!
Have you tried jobrbis? http://www.jcraft.com/jorbis/
That might help you.
Title: Re: 3D Sound System
Post by: paulscode on March 02, 2009, 01:51:55 am
I will only use jorbis as a last resort, since I want to avoid anything with the term "GPL" attached.  Granted, this library only falls under the "Lesser" GPL, but I am still very leery about using anything with GPL on it, as the legal restrictions are extremely complicated, controlling, and very difficult to understand.
Title: Re: 3D Sound System
Post by: zammbi on March 02, 2009, 06:54:06 am
Oh ok, I see everyone using that one. I do remember there was another one around but can't remember what its called.

Maybe the creator of Jogg could help about the problem?
Title: Re: 3D Sound System
Post by: zammbi on March 02, 2009, 07:19:46 am
I searched around, I found 2 others that were also GPL.
But I also found this one: http://jflac.sourceforge.net/index.html
It has no real licence. Hope that helps.
Also has last updated in 2008.
Title: Re: 3D Sound System
Post by: paulscode on March 02, 2009, 01:33:17 pm
Yeh, I've done some more searching as well, and it looks like there isn't going to be anything without the LGPL license (unless I wanted to remove support for .ogg and switch to .flac).  If I can't solve this j-ogg problem, then I'll probably just have to read that LGPL document carefully to figure out what all the legal jargon in there means, and what my obligations are if I decide to use it in my library.  I am definitely no lawyer - documents like these sound like a foreign language to me.

The main thing I want to make absolutely sure of is that anyone using SoundSystem is NOT required to distribute the source-code to their projects, or that their projects must be "free and open".  If anyone has some experience using LGPL licensed stuff, any tips would be greatly appreciated.
Title: Re: 3D Sound System
Post by: zammbi on March 02, 2009, 02:15:46 pm
Oh I had thought jflac has supported ogg, because a the site pointing to it said it did. But can't see this on there site so I guess not.
You could always write your own ogg lib  :P
Title: Re: 3D Sound System
Post by: paulscode on March 02, 2009, 04:02:17 pm
You could always write your own ogg lib  :P
Hehe.  Have you seen the source code for j-ogg?   :D
Title: Re: 3D Sound System
Post by: fireside on March 02, 2009, 04:43:00 pm
The only thing I know about GPL is that if you mix your code with it, then it becomes also gpl.  If you keep the library separate, then your own work doesn't have to be GPL.  If you distribute it, I'm not sure if you are required to place a link to the source or not.  Anyone that uses Java is using GPL code, because Java uses a GPL license, although slightly modified.
Title: Re: 3D Sound System
Post by: paulscode on March 02, 2009, 05:37:55 pm
Thanks.  I have posted on several forums a list of questions about LGPL, specific to using JOrbis in my project here.  I am also looking carefully at the text of the license to see what are the legal concerns if I do decide to use it in my project.  So far, I do know that the following will be required:

1) To keep the LGPL license off of my library, the JOrbis source can not be compiled into it.  The difference between GPL and LGPL seems to be that I am allowed to interface with an LGPL licensed library without restricting my project to the license.  The SoundSystem library alone will only be able to load .wav and .mid files, but to support .ogg files, you would have to link to an external JOrbis jar.

2) The user must be able to swap out the JOrbis library for newer versions.

3) Applications using the SoundSystem library which link to JOrbis will not themselves be under the LGPL license.  However bundeling the JOrbis jar with them is, of course, considered a form of "redistributing" the JOrbis library, and must therefore follow the guidelines of redestributing a LGPL software (The JOrbis source will need to be distributed along with the jar, as well the LGPL license and anything else required by the LGPL license).

The things I am unclear on are:

1) For applets which use SoundSystem and link to the JOrbis jar online, is that considered "redistribution" of the JOrbis library, and if so what is required by the applet's owner to be legally compliant with the LGPL?

2) What, besides the JOrbis source and LGPL document, must be included with a project like SoundSystem or a product that uses SoundSystem?  How specifically do those required things need be incorperated into the product (and are there differences between compiled form vs source code, or applet vs. application)?

3) What am I required to tell people who want to use SoundSystem, and specifically how am I required to tell them?
Title: Re: 3D Sound System
Post by: fireside on March 02, 2009, 10:58:39 pm
I know with open source games I have played there is usually a choice of a binary distribution.  This dist does not include the source, so I don't think it's required.  The site, however, provides a source code download, or a link to the source code.  It might be simpler to go with an lgpl with your library and then mix the code into one jar, depending how you feel about it, since the restrictions are going to be approx the same so why not just have one jar?  Just a suggestion, of course.  One place where you might want to ask is at the Linux Game Tome.  From what I've used, I think people that use your library would need no more than a link to your site with the source for the sound library.
  http://www.happypenguin.org/
Title: Re: 3D Sound System
Post by: paulscode on March 03, 2009, 02:54:28 am
That makes sense, however I really don't want to include the Jorbis sources in SoundSystem, because I don't want to restrict users to LGPL if they are not using the .ogg format in their projects.

What I am thinking of doing instead is to create an "IDecoder" interface in SoundSystem, and then have any number of independant derivatives which the user may add.

By default, SoundSystem would use a J-Ogg derivitive of IDecoder, for everyone who wants to avoid the LGPL headache and would rather run their .ogg files through a converter to make them work.

Then, I would make a LGPL-licensed JOrbis derivitive of IDecoder available as an add-on.  A user would load an extra jar and use something like this in their code:
Code: [Select]
SoundSystemConfig.addDecoder( "ogg", myJorbisDecoder );
That way, users will only have to deal with the LGPL license if they want to.  This would also make it easy to add support for additional audio formats in the future.  For example I might want to add in the GPL-licensed Gervil MIDI software synthesizer so MIDI could be used like any other format, or I may someday want to implement a .flac decoder:
Code: [Select]
SoundSystemConfig.addDecoder( "mid", myGervilDecoder );
SoundSystemConfig.addDecoder( "flac", myFlacDecoder );

To keep down the size of SoundSystemSmall, it would not have a default .ogg decoder built in, allowing the user to choose which one (if any) they prefer to use.
Title: Re: 3D Sound System
Post by: fireside on March 03, 2009, 04:48:55 am
That sounds pretty good.  Personally, I think I might prefer to run my ogg files through a converter if it wasn't too much trouble and skip having to worry about adding a source code link.  This is one of those times where it really doesn't make sense because it's questionable how it would work with java applets that only stay in memory for a little while. 
Title: Re: 3D Sound System
Post by: paulscode on March 04, 2009, 01:42:25 am
I've been talking with a number of developers who are familiar with the LGLP license, and I have learned a couple of useful things which I thought I would share for anyone who is interested.

The whole point of LGPL is that the user should be able to upgrade the lgpl code/library with different versions. For example, if I were to use JOrbis v0.9 and a user finds that it doesn't work on their system then they should be able to go and fetch JOrbis v1.0 which does work on their system, and use it to play their game with this newer version. It doesn't matter how the user is allowed to be able to do that, as long as it's possible.  It is not necessary to dynamically link (although that is often how it is done) - simply releasing the source code for the parts that incorperate JOrbis is sufficient, so the user can rebuild them with a newer version.  As long as this basic requirement is met, then it is not necessary to license a project that uses LGPL libraries with the LGPL license.

What is interesting is when you are talking about applets.  The basic requirement still stands - that the user must be able to swap out different versions of the LGPL parts.  Again, it doesn't matter how the user is allowed to do this, as long as it is possible.  For example, you are covered if you provide a link to the source code for whatever parts incorporate the LGPL licensed library (since the user can potentially recompile the source with a different version of the library, create a local html file, and modify the <archive> parameters for the applet to link with the new version).  The LGPL license document must also be provided, and if any modifications were made to the original library, those must be clearly outlined and the original source code provided as well.  The easiest way would be to bundle all this stuff together in a zip file and provide a link to it somewhere obvious on the website where the applet resides.

One more interesting thing is that you are allowed to modify the source of an LGPL library, so long as you release the modifications back to the community, which could be as simple as posting an archive of the source code for the modified version.  The modified source is, of course, still bound by the LGPL.
Title: Re: 3D Sound System
Post by: zammbi on March 04, 2009, 09:30:57 am
Still confused on what's happening...
Will I be seeing ogg support anytime soon ?  ::)
Title: Re: 3D Sound System
Post by: paulscode on March 04, 2009, 01:26:05 pm
Will I be seeing ogg support anytime soon ?  ::)
Depends on a couple of things.  Firstly, to prove that the problem is with the J-Ogg library and not with my code (I will know when I get JOrbis up and running).  Secondly, whether or not JOrbis is any better/more compatible than j-ogg, or if I will need to try another library.  Lastly, how long it takes me to implement the new IDecoder infrastructure.  This is a fairly significant change, so I don't expect to have it finished and debugged for at least a few weeks.
Title: Re: 3D Sound System
Post by: zammbi on March 04, 2009, 01:35:35 pm
Ok thanks.
For now then I'll use the old sound lib I was using and try to repair what I can and then move to yours once yours is ready.
Title: Re: 3D Sound System
Post by: paulscode on March 06, 2009, 01:28:55 am
I finally got JOrbis up and running.  It is an extremely low-level library - it takes about sixteen lines of code to simply read the header (not counting comments,if,try,case,break,while,etc), compared to JOgg which only required one line of code to do the same.  Great news, though - JOrbis is extremely compatible.  I haven't found a single .ogg file so far that it wasn't able to load, including very short-duration sounds!  And no more random clicking during any of them either!  I am very happy with this library - definitely worth having to deal with the whole LGPL issue.

I will now begin work on the new IDecoder infrastructure.  I have changed the basic concept a little, so that it will be possible to decode more than one file at a time (for example streaming multiple .ogg files simultaneously).  There will be an ICodec infrastructure, which will return IDecoder instances.  Each ICodec will have its own internal derivitive class of IDecoder.  The codec will return a decoder instance when asked for one.  That way there will be only one single codec instance for each audio format, but multiple decoder instances - one for each file that is being read from.  Each decoder instance will be shut down and discarded when it is no longer needed (i.e. when a file has finished pre-loading, a stream has been stopped, etc.)
Title: Re: 3D Sound System
Post by: zammbi on March 06, 2009, 05:37:44 am
That's great that you got it working.
Can't wait to test. Just want to get rid of this current sound lib I'm using.
Title: Re: 3D Sound System
Post by: paulscode on March 17, 2009, 03:43:35 am
Progress update:  I finished writing the new Codec/Decoder infrastructure into SoundSystem, and it is working beautifully in JavaSound - both regular and streaming sources, applets and applications.  When playing under OpenAL, on the other hand, there are serious bugs.  I get skipping, clicks, and random freezing, and the problems are worse in an applet vs. an application.  I'm in the process of trying to track down the source(s) of these problems, but haven't had any luck yet.  So far I have only written the codec for the JOrbis library, so when I get it working properly I still need to write codecs for the JOgg library and for unencoded pcm (.wav files) and debug those as well.
Title: Re: 3D Sound System
Post by: paulscode on March 23, 2009, 01:00:40 am
I finally figured out what is causing all the problems with streaming in OpenAL.  The JOrbis library is much slower at decoding .ogg files than JOgg is (JOrbis seems to be decoding the data at about the same speed as playing the sound - I don't know if this is intentional or just a coincidence).  Since the default number of stream buffers is 2, what happens is that one buffer finishes being processed, and another begins loading to replace it.  It takes so long to load that next buffer that the remaining queued buffer sometimes finishes playing first.  As you would expect, when this happens you hear a skip or click.  The problem is, in OpenAL when there is no data being fed in to the stream, it sometimes crashes.  This of course highlights an underlying bug with the OpenAL library that I will need to track down.

In the mean time, simply increasing the number of streaming buffers to 3 seems to have fixed the problem.

You might be wondering why there wasn't any clicking or skipping in JavaSound also.  The reason is that the JavaSound library starts reading the next buffer when the first one begins processing rather than after it has finished processing like in OpenAL, so it has time to finish decoding the next buffer before the stream runs out of data.

I was also thinking, the "no data, stream crashes" bug could potentially be a big problem if, for example, you were streaming background music from an online url and the user happened to have a really slow internet connection.  Of course one would expect there to be problems with streaming in that case, but the stream should not crash because of it.  I will try and figure out a way to prevent this from happening or at least detecting when the stream has crashed and resetting it.

Also, the slow decoding speed of JOrbis could be a really big concern.  For example, in a project where you wanted to pre-load a whole bunch of .ogg sound effects, the load time could be significantly long.  Also, I doubt it will be possible to stream more than one .ogg file at a time with JOrbis (since all simultaneous streams are handled by a single "StreamThread").  I'm looking into this problem further to see if maybe I am using the decoder incorrectly (maybe there is a setting or something that is making it decode at playback speed).
Title: Re: 3D Sound System
Post by: paulscode on March 24, 2009, 12:49:52 am
After a lot of searching on google and discussing the issue on various forums, it doesn't appear that there is any way to speed up the JOrbis decoder.  It looks like this is just a limitation that users will have to accept when using JOrbis instead of JOgg.  JOrbis is much more compatible, but JOgg is much faster.

I am proceeding on to code the JOgg and .wav codec pluggins.
Title: Re: 3D Sound System
Post by: paulscode on March 27, 2009, 01:43:13 am
I have finished implementing the new ICodec/IDecoder infrastructure and I've written codecs for .wav, JOrbis, and JOgg.  All tests have been stable with no problems.  As mentioned in my previous posts, both JOrbis and JOgg have there own benefits and drawbacks, so the user now has the flexability to decide what they want to use in their project.

I actually like this setup I'm using for codecs so much that I think I will change how I am doing the individual libraries (lwjgl binding of OpenAL, JavaSound, and "no sound"), and make them stand-alone pluggins as well.  Instead of having three versions of SoundSystem out there, instead there will be a SoundSystemCore (equivalent to the current SoundSystemSmall) which will be completely stripped down - not have any of the redundancy of the current SoundSystem class.  This core library would only be capable of playing MIDI files, but the library and codec pluggins could be added as desired to increase functionality.  So for example, a user may only want to use OpenAL and Jorbis, and he will be able to eliminate the overhead of the other libraries and codecs that he isn't using (a major benefit for use in applets where memory is a concern).  The SoundSystemCore would be extended into the SoundSystem class (OpenAL, JavaSound, .wav, and JOgg pluggins included plus all the redundant methods in the current SoundSystem class).  The SoundSystemCore would also be extended into SoundSystemJPCT (with OpenAL, Javasound, .wav, and JOgg pluggins plus the jPCT-specific methods, like binding Listener to Camera, auto-conversion of SimpleVectors into the SoundSystem coordinate system, etc.)

I am going to begin working on this concept tomorrow, and I'll see how it goes.  If it is going to be a major hassle, I'll probably release an updated version of SoundSystem as it is now, before implementing the new infrastructure.
Title: Re: 3D Sound System
Post by: zammbi on March 27, 2009, 03:58:24 am
Glad everything is going well, can't wait to test and remove the current sound lib I'm using.
Title: Re: 3D Sound System
Post by: paulscode on March 28, 2009, 07:54:25 am
Seperating the libraries from SoundSystem was a lot easier than I expected it to be (I think because I always had a sense when I was programming them that they were seperate entities from the core library).  It really just required making a couple of big changes to the SoundSystemConfig class and several minor changes in other random classes.

I have decided to do a couple of things differently than before.

The first thing I'm going to do differently is that I am just going to call the library core class "SoundSystem" rather than "SoundSystemCore" (as mentioned before this will be the stripped-down customizable version).  I will not post any equivalent of the old "full SoundSystem" class here.  Rather, I will post only the core SoundSystem class, and the SoundSystemJPCT extention (since this is the jPCT forum, after all).

Another thing I changed today is that I combined the ICodec and IDecoder classes into a single ICodec class (made more sense because all that the ICodec was doing before was returning instances of IDecoder).  The method for assigning a codec to a particular file type now works like this:
Code: [Select]
SoundSystemConfig.setCodec( "ogg", CodecJOrbis.class ); // takes a Class parameter, not an instance parameter any moreInternally, when SoundSystem needs to decode the audio data, it grabs an instance of the class using:
Code: [Select]
SoundSystemConfig.getCodec( "myfilename.ogg" );Adding libraries now works in a similar manner:
Code: [Select]
SoundSystemConfig.addLibrary( LibraryLWJGLOpenAL.class );I removed the old method for setting library priorities (this was used by SoundSystem's built-in compatibility checking).  Now, the order you add the libraries using the above "addLibrary" method is the order SoundSystem will try to load them (if the first one fails, it tries the second one, etc).

I am also working to ensure that even though the SoundSystem core is stripped down and more flexible, it is still easy to use.  I feel like I have been able to accomplish that.  Here is an example - say you were using the SoundSystem core in a project.  You wanted it to have support for .wav files only, and you wanted it to try OpenAL first, then JavaSound as a backup option.  To do this, you would first link with the required jars:
Code: [Select]
SoundSystem.jar
LibraryLWJGLOpenAL.jar
LibraryJavaSound.jar
CodecWav.jar
(lwjgl.jar, jpct.jar, etc)
Then you would do a couple of extra steps in your program before instantiating the SoundSystem:
Code: [Select]
SoundSystemConfig.setCodec( "wav", CodecWav.class );
SoundSystemConfig.addLibrary( LibraryLWJGLOpenAL.class );
SoundSystemConfig.addLibrary( LibraryJavaSound.class );
SoundSystem soundSystem = new SoundSystem();
As you can see, it's still not too much of a hassle to use.

Anyway, most of the changes are going to be completely internal to SoundSystem, and as long as you use SoundSystemJPCT rather than the SoundSystem core by itself, your program is not likely to be affected at all by the change.  The only change that may affect you is if you are using the SoundSystem.switchLibrary method.  The reason this method has changed is that I have completely removed all the "global library identifiers" from the SoundSystemConfig class (for example, SoundSystemConfig.LIBRARY_JAVASOUND).  All class methods that used to take one of these identifiers as a parameter will now take the library class as a parameter instead.  Example:
Code: [Select]
mySoundSystem.switchLibrary( LibraryJavaSound.class );I fell this is a very minor change, and it shouldn't take too much effort to fix anything that breaks because of it.

So far all of my tests have gone smoothly, so I should be ready to post a new release soon.
Title: Re: 3D Sound System
Post by: fireside on March 28, 2009, 01:46:26 pm
Sounds good.  I may be experimenting with it soon.  Once I get a few more things worked out in my game.
Title: Re: 3D Sound System
Post by: paulscode on March 30, 2009, 05:11:18 am
I ran some more extreme tests today in preparation for releasing the new version of SoundSystem.  I have uncovered a couple of serious bugs that I need to track down.  (This is pretty normal for me - a major update like this never goes off without a hitch).

The first bug is when streaming with the JOgg codec.  It seems that if I rapidly play and stop a streaming source it will eventually crash.  I don't recall if I ever ran a test like this on previous versions of SoundSystem, so I will first make sure that this bug wasn't happening before.  If not, then it is most likely a problem with the new CodecJOgg class.

The second bug is when using quickPlay in JavaSound to rapidly play a whole bunch of sources at once.  Eventually all normal sources stop playing and I receive a message "Error in class 'ChannelJavaSound', Buffer missing audio data in method 'attachBuffer'".  MIDI and streaming sources do not appear to be affected by this problem, and they continue to work normally after the problem occurs.  This is a new bug I have never seen before, and at the moment I have no idea where it is coming from.  I will check to see if this bug is present in the newest version of SoundSystem right before I disconnected the Libraries from SoundSystem to make them external pluggins.  This will let me know if the problem came from the new "Codec pluggin" infrastructure.  If the problem does not exist there, then it most likely appeared as a result of the new "Library pluggin" infrastructure.

At the moment I do not have a clear idea of what might be causing these two bugs, so I really can't speculate on how long it might take for me to track them down.  I will post further information as I learn more.
Title: Re: 3D Sound System
Post by: paulscode on March 30, 2009, 11:18:18 pm
Ok, I managed to track down the "Buffer missing audio data" problem today.  The problem turned out to be related to a new class called SoundBuffer, which I created for wrapping audio data buffers with the audio format in which the data is stored (I wrote this class for use with the new ICodec infrastructure to help me keep track of data from multiple sources in multiple formats).  On a whim, I had gone back and changed a few methods in the Library classes to use this more elegant class, and in the process I made a rather simple logic error which resulted in the bug (I forgot about the fact that multiple non-streaming sources can get their data from the same SoundBuffer, so I can't call a normal source's SoundBuffer cleanup() method from inside the Source cleanup() method - instead, it must be called from the Library cleanup() and unloadSound() methods).

So one bug is fixed.  I will now start looking at the other one.
Title: Re: 3D Sound System
Post by: paulscode on March 31, 2009, 05:11:13 am
I fixed the bug.  It was another logic error (it was in some very old code - I'm surprised I hadn't noticed this bug before).  I will post the new release shortly after I package everything up with their corresponding license documents.  This has been a significant update, so I'm sure there are still bugs.  I'll try and fix problems as they surface.
Title: Re: 3D Sound System
Post by: paulscode on March 31, 2009, 06:20:58 am
Sound System, major updates:
Please reference page one for more information.

Sound System jPCT (http://www.paulscode.com/source/SoundSystem/SoundSystemJPCT.zip)
Sound System (http://www.paulscode.com/source/SoundSystem/SoundSystem.zip)
JavaSound library pluggin (http://www.paulscode.com/source/SoundSystem/LibraryJavaSound.zip)
LWJGL OpenAL library pluggin (http://www.paulscode.com/source/SoundSystem/LibraryLWJGLOpenAL.zip)
WAV codec pluggin (http://www.paulscode.com/source/SoundSystem/CodecWav.zip)
JOgg codec pluggin (http://www.paulscode.com/source/SoundSystem/CodecJOgg.zip)
JOrbis codec pluggin (http://www.paulscode.com/source/SoundSystem/CodecJOrbis.zip)

JavaDoc (http://www.paulscode.com/docs/SoundSystem/)

Tutorial (http://www.paulscode.com/tutorials/SoundSystem/SoundSystem.pdf) (example programs (http://www.paulscode.com/tutorials/SoundSystem/SoundSystemTutorialsSource.zip))

What's new?

Added new transition methods for MIDI and streaming sources with the ability to queue next sounds and create fade in/out effects.
Created a new stripped-down customizable core SoundSystem library
Added a codec and library pluggin infrastructure, allowing the user to choose which sound libraries and codecs to use.

Title: Re: 3D Sound System
Post by: fireside on March 31, 2009, 06:14:23 pm
Great work.  Glad you have the tutorial there.  It will still be a little while for me before I become concerned with sound, but I'm looking forward to trying it out.
Title: Re: 3D Sound System
Post by: paulscode on April 10, 2009, 01:22:58 am
Sound System, Minor Updates

Sound System jPCT (http://www.paulscode.com/source/SoundSystem/SoundSystemJPCT.zip)
Sound System (http://www.paulscode.com/source/SoundSystem/SoundSystem.zip)

JavaSound library pluggin (http://www.paulscode.com/source/SoundSystem/LibraryJavaSound.zip)
LWJGL OpenAL library pluggin (http://www.paulscode.com/source/SoundSystem/LibraryLWJGLOpenAL.zip)

WAV codec pluggin (http://www.paulscode.com/source/SoundSystem/CodecWav.zip)
JOgg codec pluggin (http://www.paulscode.com/source/SoundSystem/CodecJOgg.zip)
JOrbis codec pluggin (http://www.paulscode.com/source/SoundSystem/CodecJOrbis.zip)

- Fixed problem with second constructor for SoundSystem class where derived classes would not automatically load their default libraries and codecs.
- Removed all refrences to "println" and "printStackTrace" from the codec classes.  Using the logger to handle all messages instead.
- Corrected four potential "null pointer exception" lines in the LibraryJavaSound and LibraryLWJGLOpenAL classes.

Title: Re: 3D Sound System
Post by: fireside on April 10, 2009, 04:57:50 pm
I take it SoundSystemJpct comes with the tutorial?  I'm still not ready to work on sound in my game, but I'm glad you got everything worked out so it's ready.
Title: Re: 3D Sound System
Post by: paulscode on April 10, 2009, 09:37:02 pm
I'm working on a tutorial for SoundSystemJPCT.  Currently, there is only a tutorial for the core SoundSystem library.
Title: Re: 3D Sound System
Post by: paulscode on April 15, 2009, 05:39:28 am
Miscellaneous updates and bug fixes
Descriptions for each item can be found on page one of this thread.

Sound System jPCT (http://www.paulscode.com/source/SoundSystem/SoundSystemJPCT.zip)
Sound System (http://www.paulscode.com/source/SoundSystem/SoundSystem.zip)

JavaSound library pluggin (http://www.paulscode.com/source/SoundSystem/LibraryJavaSound.zip)
LWJGL OpenAL library pluggin (http://www.paulscode.com/source/SoundSystem/LibraryLWJGLOpenAL.zip)
JOAL library pluggin (http://www.paulscode.com/source/SoundSystem/LibraryJOAL.zip)

WAV codec pluggin (http://www.paulscode.com/source/SoundSystem/CodecWav.zip)
JOgg codec pluggin (http://www.paulscode.com/source/SoundSystem/CodecJOgg.zip)
JOrbis codec pluggin (http://www.paulscode.com/source/SoundSystem/CodecJOrbis.zip)

JavaDoc (http://www.paulscode.com/docs/SoundSystem/)
3D Sound with SoundSystem (http://www.paulscode.com/tutorials/SoundSystem/SoundSystem.pdf)  (example programs (http://www.paulscode.com/tutorials/SoundSystem/SoundSystemTutorialsSource.zip))
Guide to SoundSystemJPCT (http://www.paulscode.com/tutorials/SoundSystem/SoundSystemJPCT.pdf)  (example programs (http://www.paulscode.com/tutorials/SoundSystem/SoundSystemJPCTTutorialsSource.zip))


What's new?

- Finished writing the long-awaited tutorial guide for SoundSystemJPCT.
- Corrected a thread synchronization problem that caused occasional NulPointerExceptions when temporary (quickPlay) sources were bound to Object3Ds.
- Fixed a bug in the JavaSound library plug-in where ambient sources were 3D panning between left and right speaker rather than being ambient.
- Fixed a problem in bindListener where the listener did not initially match the camera until tick() was called for the first time.
- Eliminated a long pause that was being added to the end of streaming sources when using the Wav and J-Ogg codec plug-ins.
- Added a new library plug-ins for JOAL.
- Fixed a class-name mistype in error messages logged by library pluggins.
- Fixed a potential logic error in the LibraryLWJGLOpenAL class channel-initialization code.

Title: Re: 3D Sound System
Post by: JavaMan on April 20, 2009, 11:24:14 pm
Its great how you continue to update this. I don't need it yet, but I will definitely check it out in the future.
Title: Re: 3D Sound System
Post by: paulscode on April 21, 2009, 03:06:55 am
At the request of a couple of users, I added the ability to manipulate pitch.  This is a useful feature, because making slight random pitch changes when playing sound effects can help reduce the repetitiveness and make a game's sound effects more believable.  Also, this could potentially be used to create a "Doppler effect" for moving sources.

There are two new methods in the SoundSystem class:
Code: [Select]
getPitch( String sourcename )
setPitch( String sourcename, float newPitch )
Possible values for pitch are 0.5f - 2.0f (where 1.0f is normal pitch).  Changing the pitch also changes the playback speed.  I uploaded the updated SoundSystem core and library pluggins.  The links in my initial post are still the same.

Since there are already several people using SoundSystem in their projects, I don't want to break the existing quickPlay method by adding in a parameter for initial pitch if it isn't necessary.  The following can be used instead:
Code: [Select]
soundSystem.setPitch( soundSystem.quickPlay( ... ), initialPitch );
This works fine on my computer, but if there winds up being latency problems with this method on slower machines, I will go back and change the quickPlay method.
Title: Re: 3D Sound System
Post by: paulscode on April 28, 2009, 02:29:53 am
At the request of a user, I added a new 'loadSound( String identifier, URL url )' method and uploaded the updated library.  This allows you to use a URL instance rather than specifying a String filename parameter.  The links on my original post are still the same.  Changes were applied to the SoundSystem core and all library plug-ins.  The 'String identifier' parameter must end in the file's extension (example "whatever.ogg"), so SoundSystem knows what codec to use when reading from the URL.  This identifier can be used for the 'String filename' parameter in the newSource and quickPlay methods.
Title: Re: 3D Sound System
Post by: paulscode on May 04, 2009, 10:15:11 pm
Over the weekend I discovered some delay problems whenever there are more than 20 or so sources playing at around the same time in the Helicopter demo applet I wrote some time ago.  I spent a great deal of time looking into the issue.

I haven't been able to solve this problem yet, but I have discovered a couple of interesting things.  Firstly, the problem only appears when running jPCT via the LWJGL Applet Loader, and only for the LibraryLWJGLOpenAL plug-in (LibraryJavaSound works fine, even when loaded via the Applet Loader).  In other words, I can only replicate the problem when mixing the LibraryLWJGLOpenAL plug-in with jPCT in an applet.  Since jPCT relies on the LWJGL, as does the LibraryLWJGLOpenAL plug-in, I suspect there is a thread synchronization problem in my code related to the LWJGL that is conflicting with jPCT.  The confusing thing is that the problem only appears in applets and not applications (due to limited resources, perhaps?)

I am currently working on porting the helicopter demo applet to the JMonkey Engine so I can mix OpenAL and OpenGL in an applet without the LWJGL Applet Loader.  This should either strengthen or refute my theory that the problem is a thread synchronization issue related to the LWJGL.  If the problem exists there as well, then I will start looking at other possible causes, such as memory leaks and the like.  I will post further information as I progress.
Title: Re: 3D Sound System
Post by: EgonOlsen on May 10, 2009, 10:15:12 pm
When using the AWTGLRenderer, rendering happens in the AWT event dispatch thread. And there are some synchronizations in jPCT to make this possible but nothing of this is related to LWJGL directly. I assume you are using this renderer in the demo?

You may want to try two things: Try to compile the objects in the scene to shift some load from the CPU to the GPU and try the JOGL renderer instead. For both, you'll need the latest beta of 1.18: http://www.jpct.net/download/beta/jpctapi_118pre3.zip (http://www.jpct.net/download/beta/jpctapi_118pre3.zip)
Title: Re: 3D Sound System
Post by: paulscode on May 11, 2009, 04:33:34 am
I am almost positive there is a thread synchronization problem somewhere.  The random-delay behavior looks identical to what was happening in a target-shooter applet I started working on a while back, which turned out to be an awt event thread issue.  I think what I'll do is use a much simpler test applet rather than trying to make the helicopter demo work (there are too many things going on in that demo to rule out a problem in the applet's source).  Instead I'll make an test-case applet that simply adds a bunch of primitives to the world and starts playing sounds to see if I can replicate the problem.  If I can replicate the problem, then I'll give your suggestions a shot to see if there is any difference.  If I am unable to replicate the problem, I'll try rewriting the helicopter applet from scratch.  I wrote that one when I was new to Java and jPCT, so it may just be poorly written / not thread-safe.
Title: Re: 3D Sound System
Post by: paulscode on July 28, 2009, 11:20:08 pm
I thought I would share a recent conversation I had with a developer, in case anyone else was having a similar issue.

Quote from: Howard
hey Paul,

I extended your Sound System and added this class/function. My goal is to load all sounds on startup and associate them with a string identifier for play/pause/stop later. I'm not really sure what ManageSources really does but it only works with the QUICK_PLAY option. The question is, is the below correct for what I'm trying to do?

Also, I noticed a minor problem. Sometimes when a sound starts to play, a split second into that sound, the sound starts again. This happens randomly but every so often. It's very slight so you really have to listen for it. After running a bunch of tests I can only assume the CommandThread is going to sleep right after the sound just starts to play and then when the thread is awaken, it finishes off what it started. I don't know. Your thoughts please.

Any help would be greatly appreciated.

howie
Code: [Select]
public class NinjaSound extends SoundSystem
{

    public void loadSound( String sourcename, String filename,
                           boolean toStream, boolean toLoop )
    {
        if( toStream )
        {
            newStreamingSource( true, sourcename, filename, toLoop, 0, 0, 0,
                                SoundSystemConfig.ATTENUATION_NONE, 0 );
        }

        ManageSources( new CommandObject( CommandObject.QUICK_PLAY, true,
                           true, toLoop, sourcename, filename, 0, 0, 0,
                           SoundSystemConfig.ATTENUATION_NONE, 0, false ) );

        if( !toStream )
        {
            loadSound( filename );
        }
    }
}
Quote from: Howard
never mind. I figured it out. I was basing my code on your backgroundMusic function. The newStreamingSource and ManageSources basicly do that same thing so you end up with two calls in the sourceMap.

Code: [Select]
    public void backgroundMusic( String sourcename, String filename,
                                 boolean toLoop )
    {
        newStreamingSource( true, sourcename, filename, toLoop, 0, 0, 0,
                            SoundSystemConfig.ATTENUATION_NONE, 0 );
        // Queue a command to quick stream this new source:
        ManageSources( new CommandObject( CommandObject.QUICK_PLAY, true,
                           true, toLoop, sourcename, filename, 0, 0, 0,
                           SoundSystemConfig.ATTENUATION_NONE, 0, false ) );
        CommandQueue( new CommandObject( CommandObject.PLAY, sourcename) );
       
        commandThread.interrupt();
    }

here's my new function for loading sound.

Code: [Select]
public class NinjaSound extends SoundSystem
{

    public void loadSound( String sourcename, String filename,
                           boolean toStream, boolean toLoop )
    {
        CommandNewSource( false, toStream, toLoop, sourcename,
                          filename, 0, 0, 0,
                          SoundSystemConfig.ATTENUATION_NONE, 0 );

        commandThread.interrupt();
    }
}


Quote from: Paul
Howard,
 
Yes, I can see how this part of the code might be confusing.  I originally made it so quickPlay and backgroundMusic both created a temporary source and then immediately played it (seems logical).  All commands, including these two, were processed in order from the "CommandQueue" method via the Command Thread.
 
However, I later wanted the ability to "cull" and "activate" sources.  This feature is so that developers can extend the SoundSystem and manage which sources should play and which shouldn't based on their own rules.  For example, one might create a game where there are hundreds of simultaneously playing sources, and they only want the closest ones to play on whatever channels are available.
 
This seemingly simple update ended up requiring a significant change to the CommandQueue infrastructure.  All source creation, deletion, cull, and activate commands now needed to be processed first before play commands could be processed (this is the only way to ensure that only the active sources would play and not the culled ones).  So I created a new method called ManageSources, which is basically the same as CommandQueue, except it is called before CommandQueue is called.  This method processes the creation, deletion, cull, and activate commands that needed to be processed first.  The Command Thread processes all commands in the ManageSources queue first, then those in the CommandQueue.  Additionally, the ManageSources method is used in extended classes to sort the sources (by distance, for example), and to cull and activate the proper ones.  After all of those commands in the ManageSources queue are done, the commands in the CommandQueue are processed.
 
This change also required me to change the quickPlay and backgroundMusic methods, because I could no longer have these methods automatically play the new source (cull and activate stuff had to be figured out first via ManageSources).  So I changed it so quickPlay and backgroundMusic queues one command to create the source (via ManageSources), and a second command to play the source (via CommandQueue).
 
Now, I have tested this new infrastructure quite a bit since I wrote it, but I will go back and take another look to make sure two calls to "play" are not happening from the quickPlay and backgroundMusic methods.  I should also add in more comments to that section of the code to explain what is going on and why there are two methods that look virtually the same.
 
Thanks for the insight!
 
-Paul
Quote from: Paul
Howard,

After reviewing the source, you are correct - there is a bug in the backgroundMusic method (not in the quickPlay method, though) -- I am creating two sources with the exact same information.  Nice catch!  I will have this corrected in the next release.

-Paul
Title: Re: 3D Sound System
Post by: paulscode on August 06, 2009, 02:51:30 am
Today I finished a major update to the SoundSystem.  I wrote a new class to make switching between String filename/identifier and URL on the fly very easy.  I worked it into all the streaming methods and the MIDI channel stuff (as well as reworking the loadSound method to use this new setup), so now either URLs or filenames can be used with all types of sources (MIDI, normal, and streaming).  Everything seems to be working after running several quick tests.  However, since the change was rather extensive (I ended up editing almost every class), I need to spend some time doing more extreme testing to make sure the library is still stable and all features work.  I also have a couple more small additions I want to add before the next release.
Title: Re: 3D Sound System
Post by: paulscode on August 08, 2009, 07:37:30 pm
Sound System, Cumulative Updates/Bug-Fixes

Sound System jPCT (http://www.paulscode.com/source/SoundSystem/SoundSystemJPCT.zip)
Sound System (http://www.paulscode.com/source/SoundSystem/SoundSystem.zip)
Sound System Utils (http://www.paulscode.com/source/SoundSystem/SoundSystemUtils.zip)

JavaSound library pluggin (http://www.paulscode.com/source/SoundSystem/LibraryJavaSound.zip)
LWJGL OpenAL library pluggin (http://www.paulscode.com/source/SoundSystem/LibraryLWJGLOpenAL.zip)
JOAL library pluggin (http://www.paulscode.com/source/SoundSystem/LibraryJOAL.zip)

JOrbis codec pluggin (http://www.paulscode.com/source/SoundSystem/CodecJOrbis.zip)

-Made it so initializing OpenAL plug-ins will notify when AL_PITCH is not supported
-Fixed vorbis-header compatability issue with OGG files generated by Audacity
-Improved error-handling in multiple classes
-Updated and added multiple classes to allow user to specify either String filenames or URL instances
-Added new class to associate filename/identifier with URL
-Improved MIDIChannel class - searches for alternate sequencer/synthesizer if defaults don't work
-Added a new method for feeding raw audio data directly to a channel through streaming sources
-Added a new source-creation method to produce streams that can be fed directly with raw audio data
-Added a new SoundSystemUtils library which includes an XML loader
-Corrected problem in LibraryJavaSound plug-in where sources would only play once
-Corrected channel-source association bug which caused rare odd behaviors

Title: Re: 3D Sound System
Post by: paulscode on August 09, 2009, 11:49:34 am
Something I changed seems to have broken Command synchronization.  I am currently looking into the problem, so please stand by.
Title: Re: 3D Sound System
Post by: paulscode on August 09, 2009, 08:43:33 pm
Ok, I solved the problem.  This logic error has actually been in the code for a very long time, but it never manafested itself until now.  I had to change the CommanQueue/ManageSources infrastructure to correct it, so any legacy code that extends the SoundSystem class for customized source management models will most likely now be broken.  If this causes problems for anyone, please refer to the JavaDoc for the proper new way to do custom source management, or post questions here for help.  Sorry any inconvenience this causes.

Updated packages:
Sound System (http://www.paulscode.com/source/SoundSystem/SoundSystem.zip)
Sound System jPCT (http://www.paulscode.com/source/SoundSystem/SoundSystemJPCT.zip)
Sound System Utils (http://www.paulscode.com/source/SoundSystem/SoundSystemUtils.zip)
Title: Re: 3D Sound System
Post by: influt on November 05, 2009, 03:53:26 pm
Hello. It's my first try to tickle SoundSystemJPCT so I might miss something.
I tried playing sounds with the quickPlay() method. The code is exactly the same as in the Helicopter.java with the only difference - I do'not assign the sound to an Object3D:
Code: [Select]
soundSystem.quickPlay( "menu.wav", false);unfortunately it fails showing me the following message:
Code: [Select]
Exception in thread "Thread-290" java.lang.ClassCastException: java.lang.String cannot be cast to paulscode.sound.FilenameURL
at paulscode.sound.SoundSystem.ManageSources(SoundSystem.java:2153)
at paulscode.sound.CommandThread.run(CommandThread.java:118)
Title: Re: 3D Sound System
Post by: paulscode on November 05, 2009, 09:35:19 pm
Oops, sorry about that - I think I know what caused that part to break - I never updated the SoundSystemJPCT extension after making the String/URL changes to SoundSystem.  Let me take a look at the code, and I'll upload an update this evening.
Title: Re: 3D Sound System
Post by: paulscode on November 05, 2009, 11:53:37 pm
Ok, I fixed the problem.  There are also a few minor fixes to the SoundSystem core itself since the last version I posted.

I haven't updated the JavaDoc yet - there seems to be a bug in NetBeans that is preventing me from producing any JavaDocs, and I haven't had time to search for a fix.

Updated packages:
Sound System jPCT (http://www.paulscode.com/source/SoundSystem/SoundSystemJPCT.zip)
Sound System (http://www.paulscode.com/source/SoundSystem/SoundSystem.zip)


- Corrected a problem in the SoundSystemJPCT extension where source creation methods requiring a String filename parameter stopped working after a previous core library update.
- Added additional methods that take URL file references.
- Simplified thread synchronization in the core library, making it easy for users to manually manipulate sources by synchronizing on SoundSystemConfig.THREAD_SYNC object.

Title: Re: 3D Sound System
Post by: paulscode on February 26, 2010, 12:32:56 am
I've discovered that the latest release of LWJGL breaks the SoundSystem library, because they no longer support indirect buffers.  I've already figured out a solution and I am in the process of implementing it.  I've been really busy lately so it might be a couple of weeks before I'm ready to post an update.
Title: Re: 3D Sound System
Post by: EgonOlsen on April 05, 2010, 09:37:29 pm
Damn...i just tried to update Robombs with the latest LWJGL and ran into this problem. I haven't updated the SoundSystem for ages, because it just worked for me in the way it was. I guess i have to do it now once you finish the fix.
Title: Re: 3D Sound System
Post by: paulscode on April 06, 2010, 02:30:52 am
I am hoping to solve a few unrelated problems when running with the 64-bit sun Java plug-in for Firefox in Linux, before I post the next big release.  However, if I can't get these fixed in the next few days, I'll go ahead and post what I have now and post another update later.
Title: Re: 3D Sound System
Post by: paulscode on April 12, 2010, 03:51:12 am
The switching problem is in fact not limited to 64-bit sun Java like I thought.  It also happens in 32-bit applets and applications.  The problem occurs depending on the order you load/switch between library plug-ins - I just hadn't set up my test cases correctly to notice this, so I came to the wrong conclusion about the cause.  This is a serious problem which must be solved before I can upload the library for use (it would almost certainly break legacy code).  I am 99% certain the problem was caused by a recent bug-fix to solve the library-switch source-copy issue when samples are loaded via URL.  This is a relatively small section of code, so hopefully it won't be too difficult to track down now that I know were to focus my attention (I got off-track assuming it was a 64-bit/32-bit issue).
Title: Re: 3D Sound System
Post by: MarcusKyo on May 25, 2010, 03:20:02 pm
Hi Paul. I've been using the library and I'm loving it! Just one question though...

I like the "turnListener" method, but I was wondering if you were going to put in anything that would actually turn the direction the listener would be moving towards. "turnListener" just turns the "head" of the listener which doesn't really help when I want to turn and walk into a different direction. Sure, I guess I could write my own method, but I'm pretty lazy. :)

What do you think? I think it'd be a nice option to have seeing as how right now you can only have the listener strafe left and right on the x axis.
Title: Re: 3D Sound System
Post by: paulscode on May 25, 2010, 05:53:00 pm
There is the method "setListenerOrientation" (been around since the very first release, actually).  With this method you specify the "look" and "up" directions for the listener.  If you are writing a first-person shooter where "up" doesn't change, then you could use your direction parallel to the ground for "look", and for "up" you'd just use floats 0,1,0 (core SoundSystem) or SimpleVector 0,-1,0 (SoundSystemJPCT).  If your game is not as simple as a first-person shooter like Wolfenstein and you need "up" to change, then you'll need to use "setListenerOrientation" to specify both the "look" and "up" directions, since there are an infinite number of possible orientations if you only know one axis.  Of course they don't necessarily have to be "look" and "up" - if you know any two directions then you can use a little vector math to calculate "look" and "up" and plug that information into the "setListenerOrientation" method.  You could also get this information from the Camera (SoundSystemJPCT has a version of "setListenerOrientation" that takes a Camera argument, and also has automatic Camera/listener syncing if that is something you need).

If the "setListenerOrientation" method is not what you are after, let me know what kind of method you'd like to see, and I'll see if it is something worth adding.

BTW, to anyone waiting for the next release of SoundSystem, it may be a couple months - I've had no time for programming between school, work, and the baby.  When I finish the class I'm in, maybe things will slow down a bit and I'll have more time for fun.
Title: Re: 3D Sound System
Post by: MarcusKyo on May 26, 2010, 11:31:12 am
Oh, sorry! I knew about the "setListenerOrientation", but I had thought for some reason that it only let you orient the listener up and down. My mistake.

I should have used that. Right now I have it so that after I turn the listener, I calculate the new position to that angle.

Sorry for the trouble. I'll get back to enjoying the library now. :)
Title: Re: 3D Sound System
Post by: paulscode on August 10, 2010, 02:28:41 am
Ok, I'm finally back to working on the SoundSystem again.  I sat down today to go back trough the code and familiarize myself with it.  One user reported a thread synchronization problem, which I am trying to track down.  I expect to post the next release later this week (although I'm sure I've said that before..).
Title: Re: 3D Sound System
Post by: zammbi on August 15, 2010, 05:55:47 pm
This library is so handy. Its the only sound one that I've tested that just works.

What's the best way to create a music list? I couldn't see a "soundSystem.backgroundMusic(String[] filename)" method.
Title: Re: 3D Sound System
Post by: paulscode on August 15, 2010, 07:57:47 pm
What's the best way to create a music list? I couldn't see a "soundSystem.backgroundMusic(String[] filename)" method.

You could use something like this:

Code: [Select]
public String backgroundMusic( String[] filename )
{
    if( filename == null || filename.length < 1 )
        return null;

    String sourcename = "Background_"
        + mySoundSystem.randomNumberGenerator.nextInt()
        + "_" + mySoundSystem.randomNumberGenerator.nextInt();

    mySoundSystem.backgroundMusic( sourcename, filename[0], false );

    for( x = 1; x < filename.length; x++ )
        mySoundSystem.queueSound( sourcename, filename[x] );

    return sourcename;
}
Title: Re: 3D Sound System
Post by: zammbi on August 15, 2010, 08:20:20 pm
Works great thanks.

Edit: What if I want to keep this list repeating? Is there some kind of background music finished event that I can put a listener too or something like that?
Title: Re: 3D Sound System
Post by: paulscode on August 15, 2010, 09:41:58 pm
What if I want to keep this list repeating? Is there some kind of background music finished event that I can put a listener too or something like that?

I've added stream listening to the upcoming version update.

--EDIT--
The final code clean-up is taking a bit longer than I anticipated.  I'll have this thing finished soon..
Title: Re: 3D Sound System
Post by: paulscode on August 22, 2010, 05:13:46 am
Sound System, Major Update, Beta Release

Sound System jPCT (http://www.paulscode.com/source/SoundSystem/21AUG2010/SoundSystemJPCT.zip)
Sound System (http://www.paulscode.com/source/SoundSystem/21AUG2010/SoundSystem.zip)

JavaSound library pluggin (http://www.paulscode.com/source/SoundSystem/21AUG2010/LibraryJavaSound.zip)
LWJGL OpenAL library pluggin (http://www.paulscode.com/source/SoundSystem/21AUG2010/LibraryLWJGLOpenAL.zip)
JOAL library pluggin (http://www.paulscode.com/source/SoundSystem/21AUG2010/LibraryJOAL.zip)

WAV codec pluggin (http://www.paulscode.com/source/SoundSystem/21AUG2010/CodecWav.zip)
JOgg codec pluggin (http://www.paulscode.com/source/SoundSystem/21AUG2010/CodecJOgg.zip)
JOrbis codec pluggin (http://www.paulscode.com/source/SoundSystem/21AUG2010/CodecJOrbis.zip)
IBXM codec pluggin (http://www.paulscode.com/source/SoundSystem/21AUG2010/CodecIBXM.zip)

JavaDoc (http://www.paulscode.com/docs/SoundSystem/)

I am calling this a beta release, because this has been one of the biggest overhauls of the library yet, and I fully expect there to be bugs.  I'll post additional updates in the coming days and problems are discovered.  I'm working on updating the tutorials as well.

There have been extensive changes since the last release.  I'll try and explain all of them quickly.

The big/important changes:

1) I fixed the incompatibility introduced back in LWJGL 2.3 when they stopped supporting indirect buffers.
2) I added a Doppler effect algorithm to LibraryJavaSound using sample-rate controls.  Note: normal sample-rate ranges in JavaSound are 4KHz - 48Khz, so this can effect how well certain sound effects do with the Doppler effect.
3) I implemented a standard interface for Doppler effect, which can now be used with all library plug-ins.  There are also new Doppler-effect interface methods in SoundSystemJPCT with SimpleVector parameters in jPCT's coordinate system.
4) I implemented a new stream-listener interface, which enables listening for End of Stream events (most useful for playing a sequence of music clips)
5) I added in an intelligent auto-search for common MIDI synthesizers when the default is missing.  This makes MIDI possible on non-Sun Java versions (such as OpenJDK)
6) I added the ability to create normal sources from raw PCM data.  Most useful for playing procedurally-generated sound effects.
7) I added the ability to check the millisecond position of any playing source
8) I added a Mixer ranking system, and an intelligent Mixer-picking based on the functions compatible with each Mixer.  This allowed an intelligent work-around for the Java Sound "webcam chosen as default Mixer" bug, as well as the fact that non-Sun Java (such as OpenJDK) may not have the "Java Sound Audio Engine" mixer available.

Additional changes:

1) I fixed a reverse-byte-order bug in CodecIBXM which caused some sounds to be loud and scratchy.
2) I fixed a bug where switching libraries caused pre-loaded sounds not to re-load.
3) I fixed various bugs when running 64-bit Java plug-in for Firefox on Linux.  There are still more (see below).
4) I added an error message when attempting to load a missing file from the JAR.  Before it acted as if there were no problem if a file was not present.
5) I added in a workaround for the Java Sound bug where a random InterruptedException is sometimes thrown when trying to access the default MIDI sequencer.
6) I added a varriable to SoundSystemCongfig for specifying which MIDI synthesizer to try first
7) I fixed the message-flooding bug that would happen when Mixer controls are not available.
8) I fixed various potential thread-synchronization bugs.

There are still several know issues with 64-bit Java on Linux which I am currently working on, including:

1) No MIDI
2) Random blocking for a half-second every few seconds
3) No sound from Java Sound when switching from OpenAL to Java Sound on the fly
4) JFrame 'paint' method causes system graphics to go wacky when playing JavaSound, and can even result in a complete OS lock-up requiring reset.

Please let me know if you run into any problems, and I will work on correcting them right away.
Title: Re: 3D Sound System
Post by: zammbi on August 22, 2010, 08:34:20 am
Have you updated the links? I replaced the libraries but still getting the openAL error.
The modified date inside the zip all show 2009.
Title: Re: 3D Sound System
Post by: paulscode on August 22, 2010, 12:51:51 pm
That is really weird..  I FTP'ed all the files yesterday, but just now downloaded them and got the old version ???  Let me try this again..

OK, this makes no sense.

- I delete the files from the server.
- I try to download them from the browser to make sure they are gone.
- I double-check the zip files again to verify it is the current version.
- I FTP the files to the server.
- I download the files from the server and...  old version!???
Title: Re: 3D Sound System
Post by: zammbi on August 22, 2010, 01:01:00 pm
Quote
That is really weird..  I FTP'ed all the files yesterday, but just now downloaded them and got the old version   Let me try this again..
Ah good then its not just me :)
Title: Re: 3D Sound System
Post by: paulscode on August 22, 2010, 01:20:52 pm
Ok, I have no idea why the old version is being cached and sent instead of the new version.  It must be a bug with either my FTP program or the server, I'll have to try and track it down.

In the mean time, I changed to links to point to the 21 August version archive directory instead of the "latest version" directory, and that seems to be working.  Give it a shot and let me know if you are still getting the old version.
Title: Re: 3D Sound System
Post by: zammbi on August 22, 2010, 01:29:04 pm
Yeah hardware mode is working  :D
My XM music is also sounding better. Thanks for your hard work.

Btw it seems IBXM is the old version and its now called Micromod-j:
http://sites.google.com/site/mumart/
Title: Re: 3D Sound System
Post by: paulscode on August 22, 2010, 01:34:38 pm
Yeah hardware mode is working  :D
My XM music is also sounding better. Thanks for your hard work.

Btw it seems IBXM is the old version and its now called Micromod-j:
http://sites.google.com/site/mumart/

Good to see the downloads are working.  I'll take a look at Micromod-j, thanks for the link.
Title: Re: 3D Sound System
Post by: zammbi on August 23, 2010, 04:07:42 pm
I found a great Java voice codec: http://jspeex.sourceforge.net/index.php
I'm going to look into adding some voices to my game.
Wondering if you want to add this codec to your great library?  ;)
Title: Re: 3D Sound System
Post by: paulscode on August 23, 2010, 08:56:18 pm
This is for reading files that are compressed way down using the assumption that voice only ranges from 2 to 44 kbps.  Very interesting.  I thought it was a speech synthesis library at first glance..
Title: Re: 3D Sound System
Post by: zammbi on August 23, 2010, 11:47:37 pm
Quote
This is for reading files that are compressed way down using the assumption that voice only ranges from 2 to 44 kbps.
Yeah, I'm going to add voice to my game. I wanted to use speech synthesis but the voices are large on good quality. So instead I'll use the speech synthesis and compress the sound. I saw Speex was good for compressing voice and they had a Java version.
Title: Re: 3D Sound System
Post by: paulscode on August 24, 2010, 12:18:11 pm
I am in the process of writing a codec plug-in for JSpeex.  It is a fairly low-level library, though, so it may take a while for me to understand it well enough to get it functioning properly in the context of an ICodec implementation.  I'll keep you updated
Title: Re: 3D Sound System
Post by: zammbi on August 24, 2010, 01:25:52 pm
Quote
I am in the process of writing a codec plug-in for JSpeex.  It is a fairly low-level library, though, so it may take a while for me to understand it well enough to get it functioning properly in the context of an ICodec implementation.  I'll keep you updated
Woot. Have you got a donations area setup? I can throw a little beer money your way for your troubles.
Title: Re: 3D Sound System
Post by: zammbi on August 24, 2010, 02:11:54 pm
Oh btw software mode does not work for me. Its just fuzzy now for my XM music.
Title: Re: 3D Sound System
Post by: paulscode on August 24, 2010, 09:04:13 pm
Oh btw software mode does not work for me. Its just fuzzy now for my XM music.
This is with the LibraryJavaSound plug-in, right?  I noticed that my previous "fix" actually created another problem, due to some faulty logic on my part when I wrote the system for matching libraries with codecs that produce incompatible data.  I've re-worked the way byte-order reversal works, and I am running tests to make sure it works for all combinations of normal/streaming/LWJGLOpenAL/JOAL/JavaSound.  I'll post an update this evening if all goes well.
Title: Re: 3D Sound System
Post by: paulscode on August 25, 2010, 03:55:24 am
Sound System, Bug Fixes, New Plug-in

Sound System jPCT (http://www.paulscode.com/source/SoundSystem/24AUG2010/SoundSystemJPCT.zip)
Sound System (http://www.paulscode.com/source/SoundSystem/24AUG2010/SoundSystem.zip)

JavaSound library pluggin (http://www.paulscode.com/source/SoundSystem/24AUG2010/LibraryJavaSound.zip)
LWJGL OpenAL library pluggin (http://www.paulscode.com/source/SoundSystem/24AUG2010/LibraryLWJGLOpenAL.zip)
JOAL library pluggin (http://www.paulscode.com/source/SoundSystem/24AUG2010/LibraryJOAL.zip)

WAV codec pluggin (http://www.paulscode.com/source/SoundSystem/24AUG2010/CodecWav.zip)
JOgg codec pluggin (http://www.paulscode.com/source/SoundSystem/24AUG2010/CodecJOgg.zip)
JOrbis codec pluggin (http://www.paulscode.com/source/SoundSystem/24AUG2010/CodecJOrbis.zip)
IBXM codec pluggin (http://www.paulscode.com/source/SoundSystem/24AUG2010/CodecIBXM.zip)
JSpeex codec pluggin (http://www.paulscode.com/source/SoundSystem/24AUG2010/CodecJSpeex.zip)

JavaDoc (http://www.paulscode.com/docs/SoundSystem/)

I fixed the new bug I introduced by trying to fix the IBXM reverse-byte-order bug.  While this is a relatively minor fix, I ended up having to make small changes to nearly every package, so be sure to download all the new versions (in other words, mix-and-match at your own peril).

Additionally, I finished the JSpeex codec plug-in.  Speex-encoded files are generally wrapped into a .ogg container file.  (This is what is produced by the binaries you can download from http://www.speex.org/downloads/ (http://www.speex.org/downloads/)).  While I was digging around, I noticed that there is an "experimental" capability for JSpeex to wrap the data into .wav files as well.  Since the .wav format is quite simple to read from (much easier to understand than .ogg), I went ahead and made this codec plug-in useable with either format.  By default, it assumes a .ogg container, but I added a method you can call to use speex-encoded .wav files if you prefer instead.  Just a reminder - these aren't normal .ogg or .wav files (just the header information is), so obviously they will not work with the other codec plug-ins.  I would recommend using a different file extension (like .spx) so you don't get them mixed up with any other non-speex files.

One more note: Speex can also save into "raw" format (i.e., no header information).  I didn't make the codec plug-in support this format because it requires the user to define the header information manually, which doesn't mesh well with SoundSystem.  However, if using the raw format is a requirement for you, let me know and I can look into it more closely to see if there is a way to support it in my codec plug-in.

As always, let me know if you run into any problems, and I will work on correcting them as soon as possible.
Title: Re: 3D Sound System
Post by: paulscode on August 25, 2010, 11:36:07 am
I noticed a weird bug in the LibraryJavaSound plug-in today, where if the source and listener have exactly the same position, the source is silent regardless of its intended volume.  This is on my PC running Linux and 64-bit Sun Java (a combination which has a multitude of other problems), so I'll verify that this is happening on "normal" computers as well when I get home this evening (if anyone wants to test this for me, try playing a source from position 0,0,0 without moving the listener, and see if you hear anything).
Title: Re: 3D Sound System
Post by: paulscode on August 25, 2010, 11:31:45 pm
I've verified that this is a 64-bit Sun Java Linux thing (works fine in other OSs and JREs).  It is really odd - everything indicates that the source is playing, but no sound.  I think maybe I'll play around with the gain controls next (maybe it's assuming incorrectly that a gain of "0" is silent instead of initial gain).
Title: Re: 3D Sound System
Post by: zammbi on August 26, 2010, 05:16:47 pm
Sounds like (no pun intended) that coding sound for Linux is quite a bucket of joy.

Quote
Additionally, I finished the JSpeex codec plug-in.
Wow, very quick.

I did some JSpeex results on my blog: http://c-o-f.tumblr.com/

XM seems to work on software mode now. Thanks for fixing that.
Title: Re: 3D Sound System
Post by: paulscode on August 26, 2010, 10:56:33 pm
Sounds like (no pun intended) that coding sound for Linux is quite a bucket of joy.
There were two small issues with 32-bit Java, which I have addressed (the webcam bug and the lack of a default JavaSound Mixer for non-Sun Java versions like OpenJDK), but it's mainly just 64-bit Sun Java for Linux that's a total piece of crap (which is why Ubuntu for example ships with OpenJDK instead).
Title: Re: 3D Sound System
Post by: paulscode on October 24, 2010, 05:44:08 am
Bug-Fixes Update

Sound System jPCT (http://www.paulscode.com/source/SoundSystem/23OCT2010/SoundSystemJPCT.zip)
Sound System (http://www.paulscode.com/source/SoundSystem/23OCT2010/SoundSystem.zip)

JavaSound library pluggin (http://www.paulscode.com/source/SoundSystem/23OCT2010/LibraryJavaSound.zip)

WAV codec pluggin (http://www.paulscode.com/source/SoundSystem/23OCT2010/CodecWav.zip)


What's New:
- Updated CodecWav link to current version
- Improved LibraryJavaSound performance slightly in non-Sun Java versions
- Handled rare pan-control exception
- Fixed fadeOutIn bug which caused fade-in effect to be silent
Title: Re: 3D Sound System
Post by: paulscode on November 23, 2010, 11:24:19 pm
CodecJorbis, Bug-Fix

Jorbis codec pluggin (http://www.paulscode.com/source/SoundSystem/23NOV2010/CodecJOrbis.zip)

- Fixed a bug where certain types of .ogg files created in versions of Audacity were cut off just before the end of the sample.
Title: Re: 3D Sound System
Post by: fireside on November 24, 2010, 03:08:48 am
Are there any docs or tutorials for soundsystem jpct?
Title: Re: 3D Sound System
Post by: paulscode on November 24, 2010, 03:56:50 am
Are there any docs or tutorials for soundsystem jpct?

Yes I wrote a guide a while back with some example programs, called Guide to SoundSystemJPCT (http://www.paulscode.com/tutorials/SoundSystem/SoundSystemJPCT.pdf)  (source for example programs (http://www.paulscode.com/tutorials/SoundSystem/SoundSystemJPCTTutorialsSource.zip))
Title: Re: 3D Sound System
Post by: fireside on December 08, 2010, 02:33:10 am
Still not quite ready to try adding sound, but just asking, if I just use soundsystem, will it run in an unsigned applet?
Title: Re: 3D Sound System
Post by: paulscode on December 08, 2010, 02:42:03 am
Yes, you can use the core SoundSystem with LibraryJavaSound plugin and any of the codec plugins for unsigned applets
Title: Re: 3D Sound System
Post by: EgonOlsen on February 10, 2011, 10:53:06 pm
Edit: Removed for now...i must have done something fishy...i get exceptions in classes that aren't there... ???
Title: Re: 3D Sound System
Post by: EgonOlsen on February 10, 2011, 11:24:13 pm
Figured it out...I had a directory called paulscode with old SoundSystem sources on the same level as src as backup. It wasn't marked as source folder nor was it part of the classpath but somehow, Eclipse figured out that it should be used instead of the sources located in the actual src-folder...no idea why, but deleting it helped. After figuring out that i now have to add libraries and codecs (haven't updated the SoundSystem for ages...), sound is back again... ;D
Title: Re: 3D Sound System
Post by: paulscode on February 11, 2011, 11:06:34 pm
After figuring out that i now have to add libraries and codecs (haven't updated the SoundSystem for ages...), sound is back again... ;D
Yes, the library has started becoming a bit bloated I think (although considerably more compatible than it was before).  I've stopped adding new features, and just plan to make bug-fixes and optimizations when needed.  I do have a new update I should get out at some point, though, which reduces the delay that used to happen when transitioning between music streams.  I'll try and get the code cleaned up and post it this weekend.

BTW, I am working on an Android version which utilizes a native mixer I wrote (requires the NDK of course).  The API is virtually the same, so it should make porting desktop jPCT games to Android a bit easier from an audio standpoint.  I haven't had a lot of time for programming lately, but hopefully I'll be able to get it out in the coming weeks.
Title: Re: 3D Sound System
Post by: Disastorm on March 25, 2011, 05:22:45 am
Hello what does this mean?

Error in class 'LibraryLWJGLOpenAL'
    Unable to open file 'sound/fx/scraping-ice-1.wav' in method 'loadSound'
Error in class 'LibraryLWJGLOpenAL'
    Sound buffer was not created for sound/fx/scraping-ice-1.wav
Error in class 'LibraryLWJGLOpenAL'
    Source 'Source_-967832717_1724366595' not found in method 'play'

That is what I get if i just initilize the SoundSystemJPCT and then try to play the sound.

If I try to initialize the SoundSystemJPCT using the SoundSystemLoader I get this error when trying to play the file:

Exception in thread "main" java.lang.NullPointerException
Error in class 'LibraryLWJGLOpenAL'
    Unable to open file 'scraping-ice-1.wav' in method 'loadSound'
        at paulscode.sound.SoundSystemJPCT.quickPlay(SoundSystemJPCT.java:1591)
        at paulscode.sound.SoundSystemJPCT.quickPlay(SoundSystemJPCT.java:1542)
        at paulscode.sound.SoundSystemJPCT.quickPlay(SoundSystemJPCT.java:1520)
        at paulscode.sound.SoundSystemJPCT.quickPlay(SoundSystemJPCT.java:1377)
        at game.sound.SoundSystem.main(SoundSystem.java:45)

which seems to be a nullpointer at some randomNumberGenerator.  How can I fix these problems??
Title: Re: 3D Sound System
Post by: paulscode on March 27, 2011, 11:42:22 am
Hello what does this mean?
...
    Unable to open file 'sound/fx/scraping-ice-1.wav' in method 'loadSound'
...
    Unable to open file 'scraping-ice-1.wav' in method 'loadSound'

This means it was unable to open the file.  Most likely cause is the name of the file or the folder path are misspelled.  Note that it is case sensitive (i.e. "sound" vs. "Sound"), and be sure to check if there is a missing "s" (i.e. "sound" vs. "sounds").

If you are sure the path and file names are correct, the next thing to check is if you compiled the file into the JAR (passing a name like "sound/fx/whatever.wav" will look inside the JAR for the file, not in the external containing folder).

If neither of those are the problem, please post your initialization code (any SoundSystemConfig settings and plug-ins), or the HTML file you are using for the loader.
Title: Re: 3D Sound System
Post by: Disastorm on March 31, 2011, 07:30:22 pm
the file/path is correct, to make sure I even created a file object:

Code: [Select]
     soundSystem = new SoundSystemJPCT();

            File file = new File("scraping-ice-1.wav");
        soundSystem.quickPlay(file.getAbsolutePath(), false);

heres error:

Code: [Select]
Error in class 'LibraryLWJGLOpenAL'
    Unable to open file 'C:\Users\Disastorm\Documents\NetBeansProjects\ProjectDerby\scraping-ice-1.wav' in method 'loadSound'
Error in class 'LibraryLWJGLOpenAL'
    Sound buffer was not created for C:\Users\Disastorm\Documents\NetBeansProjects\ProjectDerby\scraping-ice-1.wav
Error in class 'LibraryLWJGLOpenAL'
    Source 'Source_-842624421_159493175' not found in method 'play'


if I use this xml to load it:

Code: [Select]

<!-- Add a couple of library plug-ins: -->
< addLibrary
className = paulscode.sound.libraries.LibraryLWJGLOpenAL />

< addLibrary
className = paulscode.sound.libraries.LibraryJavaSound />


<!-- Add some codec plug-ins: -->


< setCodec
extension = wav
className = paulscode.sound.codecs.CodecWav />

<!-- Instantiate the SoundSystem: -->
< create />


<!-- Load a clip into memory: -->
    < loadSound
        filename = scraping-ice-1.wav />

using

Code: [Select]
  try {

            soundSystem = new SoundSystemJPCT();
            File file = new File("Example.xml");
            SoundSystemLoader.loadXML(file.toURL(), soundSystem);
        } catch (MalformedURLException ex) {
            Logger.getLogger(SoundSystem.class.getName()).log(Level.SEVERE, null, ex);
        }
            File file = new File("scraping-ice-1.wav");
        soundSystem.quickPlay(file.getAbsolutePath(), false);

I get

Code: [Select]
Exception in thread "main" java.lang.NullPointerException
Error in class 'LibraryLWJGLOpenAL'
    Unable to open file 'scraping-ice-1.wav' in method 'loadSound'
        at paulscode.sound.SoundSystemJPCT.quickPlay(SoundSystemJPCT.java:1591)
        at paulscode.sound.SoundSystemJPCT.quickPlay(SoundSystemJPCT.java:1542)
        at paulscode.sound.SoundSystemJPCT.quickPlay(SoundSystemJPCT.java:1520)
        at paulscode.sound.SoundSystemJPCT.quickPlay(SoundSystemJPCT.java:1377)
        at game.sound.SoundSystem.main(SoundSystem.java:54)
Title: Re: 3D Sound System
Post by: paulscode on April 02, 2011, 01:15:58 am
the file/path is correct
...
Code: [Select]
Error in class 'LibraryLWJGLOpenAL'
    Unable to open file 'C:\Users\Disastorm\Documents\NetBeansProjects\ProjectDerby\scraping-ice-1.wav'
...

well...

If you are sure the path and file names are correct, the next thing to check is if you compiled the file into the JAR
Title: Re: 3D Sound System
Post by: Disastorm on April 05, 2011, 02:03:46 am
even if i give the absolute path i need to put it in the jar?  I can't just run the project in netbeans?
Title: Re: 3D Sound System
Post by: paulscode on April 05, 2011, 12:26:23 pm
??  Absolute path implies that it is not in the jar, doesn't it?  If there is some reason you can't/won't compile your resource files in the jar, then why not use one of the methods that take an InputStream argument to load your files?  Also, there's no problem running from within Netbeans.
Title: Re: 3D Sound System
Post by: Disastorm on June 09, 2011, 08:27:08 pm
Hey I have this mp3 file that i converted to ogg and when i play it (im using backgroundmusic, havnt tried quickplay) right before it starts theres like a split second of a loud screeching sound.  Do you know how I can fix this?  I also tried converting it to wav instead but it still has that sound.
Title: Re: 3D Sound System
Post by: paulscode on June 10, 2011, 09:00:39 pm
Wow, I've definitely seen that before, but it's been a while (I'm still shuddering from the flashback I just got after reading your post :D ).  I don't recall off hand what the solution was for this.  Which library plug-in has the problem(or do they both?).  I can run some tests if you upload the file for me to grab.
Title: Re: 3D Sound System
Post by: Disastorm on June 12, 2011, 06:28:24 am
its the one called Aftermath on this site: http://incompetech.com/m/c/royalty-free/index.html?genre=horror

the download is an mp3 but i converted it to ogg and wav and the screech occurs for both of them.
Title: Re: 3D Sound System
Post by: paulscode on June 12, 2011, 03:30:05 pm
I can't reproduce the problem here.  What program are you using to convert the file?  Have you tried another program (such as Audacity)?  Please upload the actual ogg file you are having the problem with so I can see if there is something unique about that particular file's data that could be causing the weird behavior.

Which library plug-in has the problem(or do they both?)
You can get this from the Console output.  I assume you are using SoundSystemJPCT, but that doesn't tell me which library plug-in you are experiencing the problem for, because SoundSystemJPCT will either load the LWJGLOpenAL or JavaSound plug-in, depending on your OS and what components / drivers are installed.  Also, you might try using the CodecJOrbis plug-in to see if it also has the screeching behavior, since JOrbis has been around for a while and is well supported and more compatible than the JOgg codec plug-in which ships with SoundSystemJPCT.

--EDIT--
I decided to read back through this thread to figure out when it was that I experienced this screeching behavior before (3 years and 26 pages worth of history here).  I finally found it, but unfortunately, that earlier problem does not apply to your case, because it was related specifically to playing MIDI through a javascript interface I was working on at the time:
...
4) I was having problems with loud scratching sounds in some browsers the first time a sound is played.  To compensate, I had to make the javascript automatically play a silent MIDI file when it starts up.  This is completely transparent, but you are required to place the file "silence.mid" wherever the javascript is located.
...
Title: Re: 3D Sound System
Post by: Disastorm on June 13, 2011, 05:15:14 am
Audacity is already what I used.  here is the file: http://www.sendspace.com/file/6y42tr

This is the library: LWJGL OpenAL
Title: Re: 3D Sound System
Post by: paulscode on June 13, 2011, 02:38:30 pm
Thanks.  There is definitely something wrong with that file - the screech happens in every player that I played it in (including Audacity), so I don't think its a problem with the SoundSystem (although I haven't given CodecJOrbis a try yet, but I doubt it will fare any better than CodecJOgg).  What version of Audacity did you use to convert this file, and what OS are you running?  Also, does every file you convert have the screech problem, or just this one?

Give the file below a try and let me know if the screech is gone:
http://www.paulscode.com/downloads/Aftermath.ogg (http://www.paulscode.com/downloads/Aftermath.ogg)
(I exported it via Audacity 1.3.12-beta compiled on 64-bit Ubuntu Maverick)
Title: Re: 3D Sound System
Post by: Disastorm on June 13, 2011, 11:04:38 pm
I'm not home right now so when I get home I'll try it.  However, I do know when i tried playing this file in vlc it played without the screech.  In any case, it may be because of an old Audacity version, I will try updating that.  I am on Windows 7 64bit

*edit that fixed it, turns out i was using the non-beta version which doesnt officially support windows 7.  I installed the beta version and it works.  Thanks.
Title: Re: 3D Sound System
Post by: paulscode on June 14, 2011, 11:57:35 am
You're right, it does play correctly in VLC.  It is definitely a file/ codec compatibility issue then (although I don't feel too bad about my library not handling this file since 90% of other players don't seem to either).  I haven't had a chance to try CodecJorbis yet, so you might try it since it is typically compatible with a lot more files than CodecJOgg is.

-edit- glad to see you got it working.  There was another issue with the last frame of audio data in ogg files created in older versions of Audacity, and I was able to adapt CodecJOrbis to handle it, so I'll probably tinker around with that file some more to see if I can figure out what the issue is with the data right there at the beginning (probably just the first frame).  It would be nice to brag that my library can handle files that most other programs cannot :)
Title: Re: 3D Sound System
Post by: Disastorm on June 17, 2011, 11:10:47 am
hey is there anything special u do to convert it with Audacity.  My converted file now has a screech at the end (or at least it plays around when the sound is going to loop again) instead of the beginning lol, however the one you uploaded does not have a screech anywhere.  However when i look at my ogg file in Audacity it does not have the screech anywhere.
heres my ogg: http://www.sendspace.com/file/crnxzp
Title: Re: 3D Sound System
Post by: paulscode on June 17, 2011, 12:23:49 pm
I didn't do anything special; just used whatever were the default settings.  I'll take a look at your file later to see if I can find anything useful about the audio data.  Do you get the same behavior if you use the CodecJOrbis plug-in?  Also, do you get the same behavior for every file you convert or just this one?
Title: Re: 3D Sound System
Post by: Disastorm on June 17, 2011, 07:32:20 pm
I didn't do anything special; just used whatever were the default settings.  I'll take a look at your file later to see if I can find anything useful about the audio data.  Do you get the same behavior if you use the CodecJOrbis plug-in?  Also, do you get the same behavior for every file you convert or just this one?

Well I just converted some random mp3 I found on my pc to ogg and it didnt have a screech anywhere, so it might just be that file.
Title: Re: 3D Sound System
Post by: paulscode on June 18, 2011, 02:38:17 am
Weird, I can't find anything wrong with that second file you posted.  I have no idea why it has a screech at the end when played with CodecJOgg.  If you start having the same problem with other files, all I can suggest is to switch to CodecJOrbis or try another converter.
Title: Re: 3D Sound System
Post by: Disastorm on June 18, 2011, 03:00:06 am
did it have the screech for you as well when playing it with Sound System ?  I reconverted it again this time but i cut a little bit off the end and this time theres no screech.

btw off topic is there any way to download a javadoc from a webpage?  I've used some libraries (I believe this one also does not include a javadoc directory in the zip?) that don't have a downloadable javadoc so its annoying sometimes when programming with them.  Do I need to create a project with the source and then generate a javadoc manually?
Title: Re: 3D Sound System
Post by: Disastorm on July 14, 2011, 09:03:27 pm
hey i was just wondering does this work on android?
Title: Re: 3D Sound System
Post by: paulscode on July 15, 2011, 12:43:41 am
Not yet, but I have an Android version in the works.  It's not a simple port, because there isn't a good mixer built into the Java portion of Android, so I'm writing one in native code via the NDK.  The API interface will still be through Java, and will be virtually identical to the original SoundSystem.  I don't have a good estimation for a completion date, though - it is at least a month out (I had put it on hold for a while while working on other projects, but I recently came back to working on it again).
Title: Re: 3D Sound System
Post by: Disastorm on July 15, 2011, 12:55:29 am
Ah ok.  What do most people currently use to produce sound in android apps, do you know?  It looks like the android libraries have their own sound player called SoundPool or something ??
Title: Re: 3D Sound System
Post by: EgonOlsen on July 15, 2011, 06:57:33 am
I'm using SoundPool, wrapped in a very small layer, my SoundManager-class. You can find it in the Alien Runner sources if needed, but it's really nothing fancy.
Title: Re: 3D Sound System
Post by: EgonOlsen on July 15, 2011, 10:43:27 am
Just make sure to use ogg instead of mp3, because Android has some problems with loading mp3 files and just hangs (at least on 1.6, haven't tried newer versions in that respect).
Title: Re: 3D Sound System
Post by: Disastorm on July 16, 2011, 12:24:57 pm
alright thanks for the info.
Title: Re: 3D Sound System
Post by: AGP on July 26, 2011, 08:07:36 pm
I'm also hoping for an Android version. Question: does your sound system handle pitch-shifting? If not, that would be a very useful addition.
Title: Re: 3D Sound System
Post by: paulscode on July 28, 2011, 11:30:11 pm
does your sound system handle pitch-shifting? If not, that would be a very useful addition.
Yes it does.  Also has interface for doppler effect.
Title: Re: 3D Sound System
Post by: AGP on August 06, 2011, 08:08:43 am
Very cool, thanks. When do you suppose you'll have the Android version available?
Title: Re: 3D Sound System
Post by: paulscode on August 06, 2011, 07:20:16 pm
I'm back to working on this project again.  I should have a beta version out sometime next week.  The main thing is finding every optimization possible in the Java portions, like reusing Objects everywhere possible (my main library was a tad wasteful in this regard).

I'm playing around with an ObjectManager class which allows you to check out/in Objects based on their type from a hashmap of Object pools.  Still working out the kinks on this idea, though.

Other optimizations are moving most of the low-level process from Java into the native code, so there is less traffic passing between Java and native.  I've done a lot of this already, but there are still other improvements I can make on this as well.
Title: Re: 3D Sound System
Post by: AGP on August 10, 2011, 09:05:54 pm
As it happens I'm working on an Android project for which I need to do pitch-shifting, so I can't wait to try your Android version soon! Thanks again for your great work, Paul, you're a real credit to these boards.

Anyway, I tried writing a quick PC version, but your WAV plugin wouldn't open the WAV file I generated with Windows's Sound Recorder. What programs could I use to generate a Sound System-readable file?
Title: Re: 3D Sound System
Post by: paulscode on August 10, 2011, 10:39:16 pm
I haven't had a problem with CodecWAV before (although most people including myself are using the .ogg format).  What kind of behavior do you get (screeching, no audio, etc)?  Could you post a link to a broken .wav file so I can run some tests to see if there is anything obvious I can fix?

For editors, I mainly use Audacity (although admittedly don't think I've ever used it to create .wav files, so it may have the same issue).  The code for CodecWAV is quite simple, so I guess I just figured it was good to go after testing it on a few .wav files I had sitting around on my computer (assumptions do tend to get me into trouble ;D)

The initial release of SoundSystemAE will only have one codec (CodecTremolo, for .ogg files).  The reason for this is that I've redesigned the Codec and Library infrastructure in order to optimize performance on Android.  One of these optimizations was to give both the Library and Codec plug-ins a native component.  The two are linked by passing some integers through SoundSystemAE at startup.  These integers represent native function pointers.  Library and Codec reconstruct these pointers to communicate directly with each other at the native level, rather than sending buffers through the JNI to Java and then back through JNI to native (if you do any profiling on the ALAN demo I posted yesterday, you'll see how badly that affects performance).

That being said, the ICodec interface still has the "read()" and "readAll()" methods which are used by SoundSystemAE whenever a Codec doesn't have a native component.  So the PC version Codecs should be fairly easy to port over to the Android version (if you do that, though, you'd probably want to set the buffer sizes fairly high to reduce the amount of traffic moving from Java to native).
Title: Re: 3D Sound System
Post by: AGP on August 11, 2011, 06:54:41 pm
Thanks for the quick response. If you're running Windows, you can just use its built-in sound recorder. My file is just me saying "test" or something, but if you want it I'll send it to you.
Title: Re: 3D Sound System
Post by: paulscode on August 11, 2011, 08:22:34 pm
I don't have a computer with Windows on it here, just a netbook with Ubuntu (I'm currently on TDY and won't be back home until mid September).  Could you send me the test file?
Title: Re: 3D Sound System
Post by: AGP on August 12, 2011, 02:38:42 am
Here it is: (Link removed).
Title: Re: 3D Sound System
Post by: paulscode on August 15, 2011, 09:55:36 pm
I thought I would give a quick progress update on SoundSystemAE.  I'm currently working out some stability issues with the part of the library that reads from the app's compressed assets.  This is kind of essential because without it, apps would require access to the sdcard and have the audio files placed there.  That is a limitation I would like to avoid if at all possible, since not all Android devices even have an sdcard, and nobody likes adding extra permissions to their app if they don't have to.
Title: Re: 3D Sound System
Post by: AGP on August 15, 2011, 11:21:03 pm
Awesome, although I have to say my particular program uses SD card to store before playing back the sound. Any chance I can try it out?
Title: Re: 3D Sound System
Post by: paulscode on August 16, 2011, 12:23:53 am
Sure, I'll post what I have so far.  Let me clean it up a bit first.. I'll upload it shortly.
Title: Re: 3D Sound System
Post by: paulscode on August 16, 2011, 02:47:01 am
Unfortunately, I seem to have broken something - Tremolo is crashing after decoding ten or so blocks of data.  I have to go to work tonight, so I won't be able to fix it until tomorrow afternoon.  I apologize for the delay.
Title: Re: 3D Sound System
Post by: AGP on August 16, 2011, 02:51:01 am
Thanks for trying, I'll be around tomorrow. :- )
Title: Re: 3D Sound System
Post by: paulscode on August 16, 2011, 10:02:37 pm
I've been diagnosing the problem a bit.  It looks to be the exact same behavior that I was getting with decoding the compressed files, now happening when decoding uncompressed files.  To rule out any file reading as the cause, I've even read the file contents entirely with Java, and passed the encoded data to the native library to decode, but I still get the same behavior.  This is really perplexing, because the latter case is virtually identical to what I did in the ALAN demo, and it worked fine there (same file and everything).  I'll continue trying to track down what has changed.  I'd guess it is most likely a pointer or memory allocation issue.  Apparently I've gotten too dependent on Java and forgotten how to use c/c++ :-[
Title: Re: 3D Sound System
Post by: AGP on August 17, 2011, 12:18:30 am
Sounds like a nightmare. Thanks for the update.
Title: Re: 3D Sound System
Post by: AGP on August 18, 2011, 11:30:34 pm
Paul, have you any news? Thanks in advance.
Title: Re: 3D Sound System
Post by: paulscode on August 24, 2011, 01:24:29 am
Sorry, I've been tracking down a problem with another one of my projects.  I'm back to working on this one again.  I'll post an update once I figure out what's causing my problem.  I'm going to start with the working decoder, and work my way back to what I have now, to try and figure out where things break.
Title: Re: 3D Sound System
Post by: AGP on August 25, 2011, 11:40:40 pm
I'm glad you're back on it. Please keep us posted.
Title: Re: 3D Sound System
Post by: paulscode on August 29, 2011, 08:55:07 pm
LibraryJOAL, Version update

JOAL library plug-in (http://www.paulscode.com/source/SoundSystem/29AUG2011/LibraryJOAL.zip)

- Fixed JOAL package name from the old net.java.games.joal to the new com.jogamp.openal.
Title: Re: 3D Sound System
Post by: AGP on August 30, 2011, 12:15:36 am
Cool, thanks. By the way, did you ever figure out why my wav file wouldn't play?
Title: Re: 3D Sound System
Post by: paulscode on August 30, 2011, 01:11:51 am
Not yet, I've been putting out a lot of brush fires with several of my projects for the past couple weeks.. I may have too many projects going at once, haha.  It is definitely in the queue  ;D
Title: Re: 3D Sound System
Post by: Marlon on February 01, 2012, 11:23:11 pm
Hello!
I want to use SoundSystemJPCT for my game and I wonder if I can play a wav file, which is stored at a fix position on my hard drive.
I do not want to compile a sound file into a jar, I want to play it while using an absolute path to this file.

For example: If I use this code:
Code: [Select]
String path=System.getProperty("user.home")+"\\forgottenelements\\appletcontent\\sound\\"+type+"\\"+name+".wav";
soundSystem.quickPlay(path, false, vec);

I get the following error:
Code: [Select]
Error in class 'LibraryJavaSound'
    Unable to open file 'C:\Users\Marlon\forgottenelements\appletcontent\sound\misc\queststart.wav' in method 'loadSound'

I searched with the help of google, I searched in this forum, but I couldn't find anything useful.

Thanks in advance!
Marlon
Title: Re: 3D Sound System
Post by: EgonOlsen on February 01, 2012, 11:55:50 pm
Have you set

Code: [Select]
SoundSystemConfig.setSoundFilesPackage("");

? I don't know if one has to, but i did in Robombs and i had no problem loading files from disk.
Title: Re: 3D Sound System
Post by: Marlon on February 02, 2012, 12:25:07 am
Have you set

Code: [Select]
SoundSystemConfig.setSoundFilesPackage("");

? I don't know if one has to, but i did in Robombs and i had no problem loading files from disk.

I already set this, but without success. :(
I checked the Robombs source code, but it seems that there sound files are loaded with relative paths?

Any other tipps?
Title: Re: 3D Sound System
Post by: paulscode on February 03, 2012, 09:01:42 pm
When the file is not compiled into the JAR, you must use the loadSound method (the version that takes a URL instance & a String identifier).  This is usually called when initializing the application, or loading a scene or game level.  The identifier should look like a filename (ending in .wav for example) because that is how the library knows which codec to use.  Then calls to quickPlay will use that identifier in place of the filename parameter.  When you are done with the sample, you can call unloadSound if you want to free the memory it is using (such as when transitioning between game levels that have a different set of sound effects)
Title: Re: 3D Sound System
Post by: Marlon on February 06, 2012, 06:22:02 pm
Thanks for your answer.
Actually... I got it running.

If I use
Code: [Select]
String path=System.getProperty("user.home")+"\\forgottenelements\\appletcontent\\sound\\"+type+"\\"+name+".wav";
if(soundNotLoaded(path)) {
try {
soundSystem.loadSound(new File(path).toURL(), path);
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
soundSystem.quickPlay(path, false, vec);

... the sound gets loaded correctly and it is played.
But... the problem is that the sound always is panned the same (I can hear the same sound with the same volume on each speaker).
For the position of the sound I use a 3D object.
It seems that there is no 3D effect. Mhhh... did I do something wrong?
Title: Re: 3D Sound System
Post by: paulscode on February 06, 2012, 07:43:04 pm
Make sure your file is mono, not stereo.  Stereo files should be used for ambient sources, like background music, crickets, etc, and mono files should be used for point sources.
Title: Re: 3D Sound System
Post by: Marlon on February 06, 2012, 07:54:20 pm
Of course my file is mono (I use it at Forgotten Elements 2D already). Only the background music is stereo.
Title: Re: 3D Sound System
Post by: paulscode on February 06, 2012, 08:48:40 pm
I didn't mean to insult your intelligence, but I can't even count how many times that question has been asked from folks using stereo files.  Is this problem happening with every file or just particular ones?  Could you post a link to one of the audio files that is having the problem?  If the sound is mono and the source position is not virtually the same as the listener position, and the attenuation model is not ATTENUATION_NONE, then there must be a bug in my code somewhere.  It will be easier to track down the cause with a file that experiences the problem (none of my files are doing this).
Title: Re: 3D Sound System
Post by: Marlon on February 06, 2012, 10:45:31 pm
I didn't mean to insult your intelligence, but I can't even count how many times that question has been asked from folks using stereo files.

No problem, I can understand that.
I wrote an own engine for my game (www.forgottenelements.com / still in 2D) and pan the sound depending on where the enemies are located. Because I am transforming my game to a 3D game and use JPCT I thought about using your Library also.

When I initialize the JPCT Camera I use the following code:
Code: [Select]
if(SoundController.getInstance().getSoundSystem()!=null) {
SoundController.getInstance().getSoundSystem().bindListener(cam);
}

Every Frametick I use this code:
Code: [Select]
if(SoundController.getInstance().getSoundSystem()!=null) {
SoundController.getInstance().getSoundSystem().tick();
}

I don't set any Attenuation, should I do this?
For example I use this file:
www.forgottenelements.com/appletcontent/sound/misc/questcomplete.wav

Thanks,
Marlon
Title: Re: 3D Sound System
Post by: paulscode on February 07, 2012, 12:27:31 am
By default, it should use ATTENUATION_ROLLOFF, so if you aren't changing it that shouldn't be the problem.  I downloaded your file and will do some tests.  I'll let you know what I find.
Title: Re: 3D Sound System
Post by: paulscode on February 07, 2012, 12:37:34 am
Hmm.. it seems to pan ok on my computer.  Let me write a quick test applet for you to run, to rule out a hardware-related issue.
Title: Re: 3D Sound System
Post by: paulscode on February 07, 2012, 01:48:52 am
Ok, I rigged up one of my old applets.  Let me know if you hear/ don't hear the panning between left/ right speakers as the camera rotates in place:

Panning Test Applet (http://www.paulscode.com/demos/jpct/jPCTGears/)
Title: Re: 3D Sound System
Post by: Marlon on February 07, 2012, 09:05:03 pm
Wow! First I have to say thank you! And its great that you posted a demo applet!
The Applet is running and 3D Sound working.
Its like the wheels are rotating around my head. :)

But: It's still not running with my code. The sound always has the same volume and panning and then (20 Sounds later) there is an exception:
Code: [Select]
java.lang.NullPointerException
at paulscode.sound.SoundSystemJPCT.tick(SoundSystemJPCT.java:270)
at graphic.Graphic3DController.update(Graphic3DController.java:708)

And at the beginning there is this exception:
Code: [Select]
Initializing LWJGL OpenAL
    (The LWJGL binding of OpenAL.  For more information, see http://www.lwjgl.org)
Error in class 'LibraryLWJGLOpenAL'
    Unable to initialize OpenAL.  Probable cause: OpenAL not supported.
    ERROR MESSAGE:
        Could not locate OpenAL library.
    STACK TRACE:
        org.lwjgl.openal.AL.create(AL.java:151)
        org.lwjgl.openal.AL.create(AL.java:102)
        org.lwjgl.openal.AL.create(AL.java:201)
        paulscode.sound.libraries.LibraryLWJGLOpenAL.init(LibraryLWJGLOpenAL.java:164)
        paulscode.sound.SoundSystem.CommandNewLibrary(SoundSystem.java:1576)
        paulscode.sound.SoundSystem.CommandQueue(SoundSystem.java:2572)
        paulscode.sound.CommandThread.run(CommandThread.java:121)
    ERROR MESSAGE:
        Could not locate OpenAL library.

Starting up SoundSystemJPCT...
Switching to Java Sound
    (The Java Sound API.  For more information, see http://java.sun.com/products/java-media/sound/)
JavaSound initialized.


I am initializing this way:
Code: [Select]
public void initSoundSystem() {
        try
        {
            // add some plug-ins:
            SoundSystemConfig.addLibrary( LibraryLWJGLOpenAL.class );
            SoundSystemConfig.addLibrary( LibraryJavaSound.class );
            SoundSystemConfig.setCodec( "wav", CodecWav.class );
        }
        catch( SoundSystemException e )
        {}
soundSystem=new SoundSystemJPCT();
SoundSystemConfig.setSoundFilesPackage("");
}

At the end I call cleanup(), to avoid dead instances.

Marlon

Edit: Wrong language ;D
Title: Re: 3D Sound System
Post by: EgonOlsen on February 07, 2012, 09:24:32 pm
...ein bisschen sehr in Deutsch, oder ???
Title: Re: 3D Sound System
Post by: Marlon on February 07, 2012, 09:53:19 pm
...ein bisschen sehr in Deutsch, oder ???

Bamm... OMG... fortunately I am only speaking 2 languages... Sorry for wrong language.  :-[
But its edited already... ;)
Title: Re: 3D Sound System
Post by: paulscode on February 07, 2012, 10:27:58 pm
Code: [Select]
java.lang.NullPointerException
at paulscode.sound.SoundSystemJPCT.tick(SoundSystemJPCT.java:270)
at graphic.Graphic3DController.update(Graphic3DController.java:708)
Aha, I can see that if it is hitting the exception at the beginning of the loop, then the subsequent source positions wouldn't get updated.  This most likely is the cause for your sounds not panning.  I'll see if I can verify that this is what's happening, and fix the problem if it is.  I'm not sure why the null pointer exception is happening in the first place, though.  This used to happen when using quickPlay, because I wasn't making sure when a temporary source is destroyed, that it gets removed from any objects it is bound to.  I thought I had fixed this problem, but I'll take another look at the code to see if I missed something.  Could be a thread synchronization problem.


And at the beginning there is this exception:
Code: [Select]
Initializing LWJGL OpenAL
    (The LWJGL binding of OpenAL.  For more information, see http://www.lwjgl.org)
Error in class 'LibraryLWJGLOpenAL'
    Unable to initialize OpenAL.  Probable cause: OpenAL not supported.
    ERROR MESSAGE:
        Could not locate OpenAL library.
    STACK TRACE:
        org.lwjgl.openal.AL.create(AL.java:151)
        org.lwjgl.openal.AL.create(AL.java:102)
        org.lwjgl.openal.AL.create(AL.java:201)
        paulscode.sound.libraries.LibraryLWJGLOpenAL.init(LibraryLWJGLOpenAL.java:164)
        paulscode.sound.SoundSystem.CommandNewLibrary(SoundSystem.java:1576)
        paulscode.sound.SoundSystem.CommandQueue(SoundSystem.java:2572)
        paulscode.sound.CommandThread.run(CommandThread.java:121)
    ERROR MESSAGE:
        Could not locate OpenAL library.

Starting up SoundSystemJPCT...
Switching to Java Sound
    (The Java Sound API.  For more information, see http://java.sun.com/products/java-media/sound/)
JavaSound initialized.

Do you get that same exception with the applet?  Make sure the OpenAL native library is on your system somewhere.


I am initializing this way:
Code: [Select]
public void initSoundSystem() {
        try
        {
            // add some plug-ins:
            SoundSystemConfig.addLibrary( LibraryLWJGLOpenAL.class );
            SoundSystemConfig.addLibrary( LibraryJavaSound.class );
            SoundSystemConfig.setCodec( "wav", CodecWav.class );
        }
        catch( SoundSystemException e )
        {}
soundSystem=new SoundSystemJPCT();
SoundSystemConfig.setSoundFilesPackage("");
}
With SoundSystemJPCT you do not need the calls to addLibrary and setCodec (these are done automatically in the background when you instantiate the SoundSystemJPCT object -- those calls are only a requirement for the core SoundSystem library).  That being said, even though calling these again is redundant, it shouldn't have any negative effects.

Since your problem is happening in JavaSound, I re-uploaded that test applet using JavaSound instead of OpenAL, just to make sure the problem isn't there.  The above link is the same.
Title: Re: 3D Sound System
Post by: Marlon on February 07, 2012, 10:40:41 pm
Oh I only downloaded the OpenAl jar, that you provided.
What OpenAl file(s) should I take? I want other users (which run my code) automatically download this file.

I just tested the new applet you uploaded.
Mhhh.. the sound is panned in the middle, no 3D effect.
Title: Re: 3D Sound System
Post by: paulscode on February 08, 2012, 12:36:01 am
Oh, ok.  It is a problem with JavaSound then.  Oracle has royally screwed up JavaSound in recent versions by their decision to remove the "Java Sound Audio Engine" software mixer (requiring developers to choose one of the hardware mixers, which are all different with different capabilities for different sound cards).  I'm in the process of writing my own software mixer, but it will probably be some time before it is complete (I don't have much free time for programming any more, and what little I do have I am busy working on my N64 emulator project).  In the mean time, I would suggest using OpenAL, as it is more reliable (used to be JavaSound was more reliable, but not any more).

For the native OpenAL library, it ships with LWJGL (which I assume your application is using since you are writing it for jPCT, unless you are going with the software renderer)  It is included with all the other native libraries.
Title: Re: 3D Sound System
Post by: Marlon on February 08, 2012, 01:35:45 am
Thanks for your tipps and your help!

I am planning to release a first 3D Test Version for my game Forgotten Elements very soon (probably this week).
Yes, you're right, I am using JPCT and the hardware renderer.
So you suggest to use SoundSystemJPCT and provide the OpenAl version for the players, who download the game?
Title: Re: 3D Sound System
Post by: Marlon on February 08, 2012, 07:19:59 pm
With the integrated OpenAl32.dll it works!
Unfortunately sometimes the Nullpointer Exception I mentioned before still occurs.
But I catch it and its ok.
Thanks again!
Marlon

Edit:
Everytime I exit my program (running at eclipse) the program crashes and I get the following error code:
Code: [Select]
Problemsignatur:
  Problemereignisname: BEX
  Anwendungsname: javaw.exe
  Anwendungsversion: 7.0.10.8
  Anwendungszeitstempel: 4e897db7
  Fehlermodulname: OpenAL32.dll_unloaded
  Fehlermodulversion: 0.0.0.0
  Fehlermodulzeitstempel: 4e894548
  Ausnahmeoffset: 0945d03f

Any ideas?
Title: Re: 3D Sound System
Post by: paulscode on February 09, 2012, 05:08:52 am
I haven't seen that error before.  Do you know if cleanup is able to successfully finish before that error appears? (it should print a short blurb into the console stating I am the author once cleanup is complete)
Title: Re: 3D Sound System
Post by: Marlon on February 09, 2012, 01:23:24 pm
I haven't seen that error before.  Do you know if cleanup is able to successfully finish before that error appears? (it should print a short blurb into the console stating I am the author once cleanup is complete)

Yes, your name is written and it should clean up successfully.
By the way... is it possible to deactivate any console output?
Title: Re: 3D Sound System
Post by: paulscode on February 10, 2012, 11:33:55 am
Yes, your name is written and it should clean up successfully.
By the way... is it possible to deactivate any console output?
You can deactivate the console output by creating a minimal extension of the Logger class with all the printing methods overridden (take a look at the sourcecode to see which methods).  If cleanup is completed successfully, I'm not sure what would be causing that crash.  You aren't trying to play any other sounds (like in the menus or on exit)?
Title: Re: 3D Sound System
Post by: Marlon on February 10, 2012, 01:35:49 pm
Yes, your name is written and it should clean up successfully.
By the way... is it possible to deactivate any console output?
You can deactivate the console output by creating a minimal extension of the Logger class with all the printing methods overridden (take a look at the sourcecode to see which methods).  If cleanup is completed successfully, I'm not sure what would be causing that crash.  You aren't trying to play any other sounds (like in the menus or on exit)?

I play sounds from the menu, but then I call quickPlay() without an Object3D.
I play an mp3 as stream as well, but I don't think that this causes the problem.
Is it possible to play mp3s as background music via your SoundSystem as well?
Title: Re: 3D Sound System
Post by: paulscode on February 10, 2012, 10:31:28 pm
I play sounds from the menu, but then I call quickPlay() without an Object3D.
You should be fine as long as sounds aren't queued to play after the call to cleanup.  I'm not sure what would be causing that crash.  I can't seem to replicate it on my computer.

Is it possible to play mp3s as background music via your SoundSystem as well?
There is no mp3 codec plugin at the moment (must use the .ogg format instead)
Title: Re: 3D Sound System
Post by: Marlon on February 14, 2012, 12:41:38 pm
On my other computer SoundSystemJPCT seems to run fine (which is having other problems though).
There seem to be big differences between a Win 7 System and a Win XP System. :/
Title: Re: 3D Sound System
Post by: Marlon on February 17, 2012, 02:01:30 pm
Hello, its me again.
I decided to use SoundSystemJPCT in the testing phase of my project.
However, there are some problems left:
1. As I mentioned before, on my Windows 7 Notebook the whole program crashes, when using the SoundSystem.
It crashes when I call SoundSystem.cleanUp(), when trying to close the program.
While running the program, there is no problem.
There is no error log, only a "JAVA(TM) Platform SE binary" window, after returning to windows.
It says:
Code: [Select]
Problemereignisname: BEX
  Anwendungsname: javaw.exe
  Anwendungsversion: 7.0.10.8
  Anwendungszeitstempel: 4e897db7
  Fehlermodulname: OpenAL32.dll_unloaded
  Fehlermodulversion: 0.0.0.0
  Fehlermodulzeitstempel: 4e894548
  Ausnahmeoffset: 0695d03f
  Ausnahmecode: c0000005
  Ausnahmedaten: 00000008
  Betriebsystemversion: 6.1.7600.2.0.0.768.3
  Gebietsschema-ID: 1031
  Zusatzinformation 1: 0a9e
  Zusatzinformation 2: 0a9e372d3b4ad19135b953a78882e789
  Zusatzinformation 3: 0a9e
  Zusatzinformation 4: 0a9e372d3b4ad19135b953a78882e789
On my other pc it runs without problems.

2. I want to play an ogg file as backgroundmusic. How can I load the ogg file (absolute path) from the disk and play it?
3. Is there a way to set a mastervolume for all sounds (played with quickplay()) and a mastervolume for the background music in a separate way?

Thanks for your help!
Marlon
Title: Re: 3D Sound System
Post by: Marlon on February 19, 2012, 07:00:46 pm
Forgotten Elements 3D Test Version was just released!
Feel free to check it out.
Tell me if the sound is running on your computer and the program exits without any problems.

http://www.forgottenelements.com