3D Sound System

Started by paulscode, March 11, 2008, 02:38:51 AM

Previous topic - Next topic

paulscode

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.

fireside

#241
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
click here->Fireside 7 Games<-

fireside

#242
I edited the above post.  It just seems like such a round about solution to me. 
click here->Fireside 7 Games<-

paulscode

#243
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):
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.

fireside

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
click here->Fireside 7 Games<-

paulscode

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:
QuoteHere 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.


paulscode

#247
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.

fireside

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. 
click here->Fireside 7 Games<-

paulscode

MIDI does not stream, i.e., the entire "sequence" is loaded from the .mid file, not read in a little at a time.

fireside

Yeah, but what about the sound effects?  They can be either streamed or loaded from memory can't they?
click here->Fireside 7 Games<-

paulscode

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.

fireside

Oh, just a thought.  I would think that if it mattered, the streaming would cause the delay.
click here->Fireside 7 Games<-

paulscode

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:
        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:
Quote6MIDI 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...

paulscode

Yes it does!  Hurray!  ;D

Ok, so now I just need to research what are the common software synthesizers on various operating systems.