Author Topic: 3D Sound System  (Read 239284 times)

Offline techwiz24

  • bit
  • Posts: 8
    • View Profile
Re: 3D Sound System
« Reply #75 on: June 04, 2013, 08:38:15 PM »
Bump

Offline Paul

  • Administrator
  • double
  • *****
  • Posts: 3494
  • Developer
    • View Profile
    • PaulsCode.Com
Re: 3D Sound System
« Reply #76 on: June 05, 2013, 01:54:39 PM »
Thanks for the bump.. forgot to look into that stream listener problem.

Do you have the project in source control somewhere? I want to make sure I have the latest source to try and figure out why my listeners aren't being notified. The archive on the first page is from January, so I'm not sure it that is up to date or not.

Not currently in any source control.  I might do that at some point.  The links on the first page should be current (the project hasn't had any major updates for a while).
Device: Samsung Galaxy Nexus i515
CPU: TI OMAP4460, 1.2 GHz (dual core, ARM Cortex-A9)
GPU: PowerVR SGX540, 307 MHz
RAM: 1 GB
Resolution: 720 x 1280
Rom: omni-4.4.4-20141014-toro-FML KitKat 4.4.4, rooted

Device: Eee PC 1015PEM
CPU: Intel Atom N550, 1.5 GHz (dual core, x86)
GPU: Intel GMA 3150, 200 MHz (dual core)
RAM: 2GB
Resolution: 1024 x 600
Rom: android-x86-4.3-20130725 Jelly Bean 4.3, rooted

Offline Smith61

  • bit
  • Posts: 8
    • View Profile
Re: 3D Sound System
« Reply #77 on: June 24, 2013, 02:48:32 AM »
There exists a bug within the JavaSound library plugin. When using Raw Streams with the plugin it fails to check how much of the data is actually written into the SourceDataLine. This causes data to be dropped when the queued buffer is bigger than the internal buffer of SourceDataLine. The problem is around line 714 of ChannelJavaSound. This can usually be fixed by passing in small amounts of data at a time but there is no way to find out the size of the buffer used in SourceDataLine as it is undefined according to the JavaDoc.

Offline Paul

  • Administrator
  • double
  • *****
  • Posts: 3494
  • Developer
    • View Profile
    • PaulsCode.Com
Re: 3D Sound System
« Reply #78 on: June 24, 2013, 07:59:02 AM »
I wonder if it would be feasible to use the value returned by sourcedataline.getBufferSize() as the maximum, and either internally chop down buffers that are too large, or produce an error or something.
Device: Samsung Galaxy Nexus i515
CPU: TI OMAP4460, 1.2 GHz (dual core, ARM Cortex-A9)
GPU: PowerVR SGX540, 307 MHz
RAM: 1 GB
Resolution: 720 x 1280
Rom: omni-4.4.4-20141014-toro-FML KitKat 4.4.4, rooted

Device: Eee PC 1015PEM
CPU: Intel Atom N550, 1.5 GHz (dual core, x86)
GPU: Intel GMA 3150, 200 MHz (dual core)
RAM: 2GB
Resolution: 1024 x 600
Rom: android-x86-4.3-20130725 Jelly Bean 4.3, rooted

Offline Smith61

  • bit
  • Posts: 8
    • View Profile
Re: 3D Sound System
« Reply #79 on: June 24, 2013, 11:17:34 AM »
You could do that or the write method returns the amount of bytes actually written. You could keep track between writes how much is left of the audio has not been written to the line and keep writing from the buffer until it is fully written. Using SourceDataLine.getBufferSize() would return the size of the buffer but that could still cause problems as there might be data remaining in the line when you go to write.

Also another bug I found was that you do not copy from the buffer's passed in into an internal buffer. Making it so we have to create a new buffer when we are say reading from a stream. If we use the same buffer there is a chance that we overwrite the previous data before the SoundSystem has a chance to write it to the SourceDataLine. I'm not sure if this was intended or not but the Docs do not mention it and it can cause some annoying bugs when it happens

Edit: And a feature request if the last one was a bug would be a feedRawData method that accepts start and length parameters similar to how IO streams work

Edit 2: After some further thinking your idea of splitting up the buffer while it is passed in should solve atleast the second issue. You would still need to take into account how much is actually written to the line. You never can be to safe with that. Then to reduce the amount of buffers that need to be created when a large buffer is passed in you could use an internal buffer cache that caches byte arrays the same size as the SourceDataLine's internal buffer. That way when large amounts of audio are passed in at once it is quick to grab already existing buffers and copy into them then recycle them after they have been fully written to the SourceDataLine
« Last Edit: June 24, 2013, 12:18:16 PM by Smith61 »

Offline Smith61

  • bit
  • Posts: 8
    • View Profile
Re: 3D Sound System
« Reply #80 on: June 24, 2013, 05:27:39 PM »
Another bug in a different library. This one is in the LibraryLWJGLOpenAL library. I'm not sure if it's the library or OpenAL acting up, but with raw streams you need to pass in atleast two buffers to get any sound to play. Passing in just one does not play anything and ends with an OpenAL error when stopping the SoundSystem.

Error in class 'ChannelLWJGL OpenAL'
    Invalid enumerated parameter value.


Since it is an OpenAL error I am leaning towards that it is an OpenAL problem and not a problem with the library, but figured I would point it out.


A second one is not so much a bug but AudioFormats with signed as true should not be allowed when using the OpenAL library. It should throw an error when trying to create a raw stream or convert the buffers before sending them to OpenAL. Another possible bug would be endianess. From what I've read of OpenAL it uses the native order of the system which may not be the format the audio is in. Not sure if you would want to error there or convert the buffers when they are passed in

Offline Smith61

  • bit
  • Posts: 8
    • View Profile
Re: 3D Sound System
« Reply #81 on: July 17, 2013, 04:10:45 AM »
Going round three with more bugs in the SoundSystem library. This is in the LibraryLWJGLOpenAL library. Maybe in other libraries to but only tested and confirmed on this one. This has to do with raw streams with no attenuation. It may work on other streaming sources but again only tested and confirmed on raw streams. When moving a source around there is no change in volume which is expected but when the listener is moved around the volume and position change as if there was attenuation on the source.

Here [nofollow] is a link to working code that shows this problem. The only thing that needs to be changed is the location of the sound file or you may provide your own audio data that is in the given format. This first creates a large amount of buffered audio in the system depending on the size of the audio passed in. It will then wait 10 seconds before moving to the next step. It will first move the listener, then the source to the listeners position, then the listener back to the origin.



A fix for one of the previous bugs that I currently have working can be found here [nofollow]. This is my fix for the first bug I mentioned.

Offline Paul

  • Administrator
  • double
  • *****
  • Posts: 3494
  • Developer
    • View Profile
    • PaulsCode.Com
Re: 3D Sound System
« Reply #82 on: July 17, 2013, 09:09:31 AM »
I'm guessing you are using stereo data for your stream.  OpenAL requires you to use mono data for 3D affects such as attenuation.

--EDIT-- NM, I missed that you said it works when moving the listener, just not the source.  I'll look into it.

--EDIT2--  I noticed this line.  I assume you have tried with other values besides ATTENUATION_NONE, and provided a rolloff factor or fade distance, right?
Code: [Select]
system.rawDataStream(format, false, sourceName, 0, 0, 0, SoundSystemConfig.ATTENUATION_NONE, 1f);
« Last Edit: July 17, 2013, 09:13:52 AM by Paul »
Device: Samsung Galaxy Nexus i515
CPU: TI OMAP4460, 1.2 GHz (dual core, ARM Cortex-A9)
GPU: PowerVR SGX540, 307 MHz
RAM: 1 GB
Resolution: 720 x 1280
Rom: omni-4.4.4-20141014-toro-FML KitKat 4.4.4, rooted

Device: Eee PC 1015PEM
CPU: Intel Atom N550, 1.5 GHz (dual core, x86)
GPU: Intel GMA 3150, 200 MHz (dual core)
RAM: 2GB
Resolution: 1024 x 600
Rom: android-x86-4.3-20130725 Jelly Bean 4.3, rooted

Offline Smith61

  • bit
  • Posts: 8
    • View Profile
Re: 3D Sound System
« Reply #83 on: July 17, 2013, 11:55:41 AM »
I am trying not to have any attenuation and the data is in mono format. You can check the format up near the top of the code in the paste. That is the same format that I used when recording the audio I was playing. The project I am using this for is a voice chat mod for the game Minecraft. Currently I do not want them to be 3D sounds but instead be a sort of Global chat room.

The 1f shouldn't/doesn't need to be there. It was leftover from trying to find a fix. I have not tried with any other value besides ATTENUATION_NONE since the only other two options are not what I was looking for. I also believe that using any normal streams are also affected by this bug. I'll edit back once I confirm it though.

Edit: Normal streams seem to work as expected. I can move both the source and the listener and the audio is not diminished in volume. Raw streams are the only ones that does not allow the source to be moved or placed in a certain location. Raw streams only want to be placed at (0, 0, 0) and will not move from there. Even creating a new source at (5, 5, 5) acts the exact same as the one placed at (0, 0, 0).

Edit 2: None of the attenuation types allow raw stream sources to be moved from the origin. I have tried to look through the source to find a problem but I can not find one.
« Last Edit: July 17, 2013, 04:02:02 PM by Smith61 »

Offline Steveice10

  • bit
  • Posts: 2
    • View Profile
Re: 3D Sound System
« Reply #84 on: July 17, 2013, 02:18:54 PM »
UPDATE: Turns out my problem has to do with my copy of LWJGL.

A suggestion: Better error reporting? For example, if a bit of reflection throws an InvocationTargetException, it doesn't let you know where it came from or what its wrapped exception is.
« Last Edit: July 17, 2013, 02:46:47 PM by Steveice10 »

Offline Paul

  • Administrator
  • double
  • *****
  • Posts: 3494
  • Developer
    • View Profile
    • PaulsCode.Com
Re: 3D Sound System
« Reply #85 on: July 17, 2013, 07:30:40 PM »
Oh, I thought you wanted attenuation.  In that case I'd use a rolloff factor of zero (sounds like you solved the issue though).  Also for ambient sources, I recommend using stereo.  WRT better error handling, that is something I've been planning just haven't had the time.
Device: Samsung Galaxy Nexus i515
CPU: TI OMAP4460, 1.2 GHz (dual core, ARM Cortex-A9)
GPU: PowerVR SGX540, 307 MHz
RAM: 1 GB
Resolution: 720 x 1280
Rom: omni-4.4.4-20141014-toro-FML KitKat 4.4.4, rooted

Device: Eee PC 1015PEM
CPU: Intel Atom N550, 1.5 GHz (dual core, x86)
GPU: Intel GMA 3150, 200 MHz (dual core)
RAM: 2GB
Resolution: 1024 x 600
Rom: android-x86-4.3-20130725 Jelly Bean 4.3, rooted

Offline Smith61

  • bit
  • Posts: 8
    • View Profile
Re: 3D Sound System
« Reply #86 on: July 17, 2013, 08:35:51 PM »
I didn't get it working on raw streams. The normal streams from files work as intended but it does not work when I provide that audio data myself. I have tried the ATTENUATION_ROLLOFF with a rolloff of zero but it acts the same as using ATTENUATION_NONE. Try running the code I sent you and you can hear the difference with raw streams. A couple of changes and you can use regular streaming sources from the same file and it will work normally. The problem is that raw sources can not be moved from the origin while all other sources can be.

I want to use raw streams as I will be creating the audio at runtime and the act of writing it out to play it correctly or creating a custom codec to read from a stream I am providing just to get around the issue doesn't seem like a good way when I should be able to just use raw streams.

Offline Paul

  • Administrator
  • double
  • *****
  • Posts: 3494
  • Developer
    • View Profile
    • PaulsCode.Com
Re: 3D Sound System
« Reply #87 on: July 17, 2013, 09:22:33 PM »
I don't understand the difference between a raw stream and a normal one.  They are the same on the OpenAL side.  Only difference is you are providing the data instead of SoundSystem providing it.  Pretty stumped on this one.
Device: Samsung Galaxy Nexus i515
CPU: TI OMAP4460, 1.2 GHz (dual core, ARM Cortex-A9)
GPU: PowerVR SGX540, 307 MHz
RAM: 1 GB
Resolution: 720 x 1280
Rom: omni-4.4.4-20141014-toro-FML KitKat 4.4.4, rooted

Device: Eee PC 1015PEM
CPU: Intel Atom N550, 1.5 GHz (dual core, x86)
GPU: Intel GMA 3150, 200 MHz (dual core)
RAM: 2GB
Resolution: 1024 x 600
Rom: android-x86-4.3-20130725 Jelly Bean 4.3, rooted

Offline Smith61

  • bit
  • Posts: 8
    • View Profile
Re: 3D Sound System
« Reply #88 on: July 17, 2013, 10:00:45 PM »
That is exactly why I am confused by it to. They should act the same way but they don't.

Offline Paul

  • Administrator
  • double
  • *****
  • Posts: 3494
  • Developer
    • View Profile
    • PaulsCode.Com
Re: 3D Sound System
« Reply #89 on: July 17, 2013, 10:10:08 PM »
I see the problem.  From line 688 in Library.java:

Code: [Select]
        // raw data streams will automatically play when data is sent to them,
        // so no need to do anything here.
        if( source.rawDataStream )
            return;

Then playing the raw stream happens from ChannelLWJGLOpenAL.java line 458:
Code: [Select]
            // restart the channel if it was previously playing:
            if( !playing() )
            {
                AL10.alSourcePlay( ALSource.get( 0 ) );
                checkALError();
            }

Which is missing a key block of logic that is in the normal play function, SourceLWJGLOpenAl.java from line 550:
Code: [Select]
        // Make sure the channel exists:
        // check if we are already on this channel:
        if( newChannel )
        {
            setPosition( position.x, position.y, position.z );
            checkPitch();
           
            // Send the source's attributes to the channel:
            if( channelOpenAL != null && channelOpenAL.ALSource != null )
            {
                if( LibraryLWJGLOpenAL.alPitchSupported() )
                {
                    AL10.alSourcef( channelOpenAL.ALSource.get( 0 ),
                                  AL10.AL_PITCH, pitch );
                    checkALError();
                }
                AL10.alSource( channelOpenAL.ALSource.get( 0 ),
                               AL10.AL_POSITION, sourcePosition );
                checkALError();

                AL10.alSource( channelOpenAL.ALSource.get( 0 ),
                               AL10.AL_VELOCITY, sourceVelocity );
               
                checkALError();

                if( attModel == SoundSystemConfig.ATTENUATION_ROLLOFF )
                    AL10.alSourcef( channelOpenAL.ALSource.get( 0 ),
                                    AL10.AL_ROLLOFF_FACTOR, distOrRoll );
                else
                    AL10.alSourcef( channelOpenAL.ALSource.get( 0 ),
                                    AL10.AL_ROLLOFF_FACTOR, 0.0f );
                checkALError();

                if( toLoop && (!toStream) )
                    AL10.alSourcei( channelOpenAL.ALSource.get( 0 ),
                                    AL10.AL_LOOPING, AL10.AL_TRUE );
                else
                    AL10.alSourcei( channelOpenAL.ALSource.get( 0 ),
                                    AL10.AL_LOOPING, AL10.AL_FALSE );
                checkALError();
            }
            if( !toStream )
            {
                // This is not a streaming source, so make sure there is
                // a sound buffer loaded to play:
                if( myBuffer == null )
                {
                    errorMessage( "No sound buffer to play" );
                    return;
                }
               
                channelOpenAL.attachBuffer( myBuffer );
            }
        }

In other words, raw data streams are simply ignoring whatever you have set for attenuation.  As a workaround, you should be able to call setAttenuation on the source after you create it.  This propagates down to setAttenuation on line 438 of SourceLWJGLOpenAL.java, which will do the necessary calls to alSourcef for rolloff factor.  If you are utilizing pitch or velocity, same thing.

--EDIT-- call to setAttenuation will probably need to be after feeding your first block of data, since it won't be attached to a channel before then.  May not even work then, since there is a race condition here between the command thread and the stream thread.  This is definitely a bug I will need to fix.
« Last Edit: July 17, 2013, 10:13:54 PM by Paul »
Device: Samsung Galaxy Nexus i515
CPU: TI OMAP4460, 1.2 GHz (dual core, ARM Cortex-A9)
GPU: PowerVR SGX540, 307 MHz
RAM: 1 GB
Resolution: 720 x 1280
Rom: omni-4.4.4-20141014-toro-FML KitKat 4.4.4, rooted

Device: Eee PC 1015PEM
CPU: Intel Atom N550, 1.5 GHz (dual core, x86)
GPU: Intel GMA 3150, 200 MHz (dual core)
RAM: 2GB
Resolution: 1024 x 600
Rom: android-x86-4.3-20130725 Jelly Bean 4.3, rooted