Real 3D SoundBlitzMax Forums/MiniB3D Module/Real 3D Sound
| I've set up a google code page for my latest project, wich is a module to provide real 3D sound to games being made with miniB3D. It works in a very similar way to the 3D sound routines that where present in B3D, but I've added some changes in order to benefit more of the OpenAL library.|
This module is a forked version of the previous work made by Klepto2 (minisound3d) and Mark sibly (the OpenAL max driver). but my version has some differences on the classes design, has had several fixes and improvements, and let's you use some of the features OpenAL has (such as real per-entity doppler effect).
The name of this semi-new module is sound3D, It has been tested to work pretty well on latest minib3d version, and I've released it under the MIT license, so if anyone wants to join, change it, fork it or whatever, development is open!
It is more or less a finished work, but I will be happy to fix any issue that may appear.
This is the link of the project: http://sound3d.googlecode.com
It has a downloadable version, but I will not be creating a download for every revision commited, so if you like this module and use it, feel free to get tortoise SVN or any other subversion client.
| Hi, I have little stupid question :/ how to install and use it? |
Then compile. Then rebuild documentation.
| Thank you. |
| Example, based on a bradford6 old example, updated to work with Sound3d. It shows a very basic setup, so it is a good starting point for people willing to use this.|
(hope Bradford6 don't mind me posting it here)
[bbcode]'Based on a bradford6 example, modified to work with Sound3D
If Not OpenALInstalled()
runtimeerror "OpenAL is not installed on this system, "
Graphics3D 800, 600, 0
Local Cam:TCamera = CreateCamera()
Local CentralSphere:TEntity = CreateSphere()
'We associate the CentralSphere entity with the Sound3D listener:
Local cube:TMesh = CreateCube()
PositionEntity(cube , 0 , 0 , 10)
MoveEntity cam,0,10,20 ' this is 180 degrees
PointEntity cam, CentralSphere
Local Sound:T3DSound = Load3DSound("fire.wav")
Local time:Float = 0
Const Radius:Int = 10
While Not (KeyHit(KEY_ESCAPE) Or AppTerminate())
Local Z:Float = -Sin(Time)* radius
Local X:Float = Cos(Time) * radius
If KeyHit(KEY_SPACE) Then EmitSound(Sound, Cube, False)
DrawText("Press SPACE to make the cube emit a sound", 0, 0)
Place a wav file called fire.wav in the same folder as this example. remember that 3D positioning in OpenAL only work on SINGLE CHANNEL AUDIO FILES. Stereo files will not be 3D-located.
You can get a mono sample file here: http://www.blide.org/posts/fire.wav
[EDIT:]Source code modified to make it even simpler and Strict
Last edited show_time('2012-05-20 11:46:40')
| Thanks ziggy, it's work very well :D |
| forgot to mention that if you have a 7.1 set-up with an audio card that supports it... you'll get surround sound, wich is amazing.|
by the way, you should also thank Klepto2, I've only updated-mantained and modified slightly his work, adding a bit of functionality.
| I have 7.1 card, but I have only 2 speakers (yet). |
One more time thanks you ziggy and Klepto2 for this piece of code :)
| I've just commited some updates with small fixes, if anyone is using this, you better get latest SVN version.|
EDIT: You'll need the OpenAL library installed in your machine. Otherwise it won't work.
| Hello, I just noticed that the direction of the listener is set up by attaching two child Pivots to the listener Entity and later on retrieving the delta's of their positions to use as vectors.|
When updating the listener's position, all it's child entities run the UpdateMat() function from miniB3D, which incurs in the following:
'mat is the entity's matrix
')These are 3 transforms.
If you were to call TFormVector to grab the AT and UP vectors, you would save a few of those transforms as the TFormVector function is but the following:
With Translate being the only [almost free] transform (Overwrite is simply retrieving values). This of course, when used to extract the AT and UP vectors from the Listener (so the Dest entity of TFormVector is Null).
Therefore, I suggest to anyone who'd like to squeeze some more performance juice, to exchange the parts of the Core.BMX code of this module that involve the Up and At Dummies, for the TFormVector equivalents.
| If you have any modified version, I can update the repository at googlecode. |
| I'll see what I can do, hold on tight! EDIT: look below |
| Here's what needs to be modified:|
@ sListener3D declaration
Type sListener3D Abstract
'Global atDummy:TEntity -- no need for this, can erase it.
'Global upDummy:TEntity -- no need for this, can erase it.
sListener3D.ent = ent ' -- function TargetEntity just needs this line. No more pivot creation.
Function Update() '-- exchanged the parts about pivots for the TFormVector equivalents.
If ent <> Null Then
alListener3f(AL_POSITION, EntityX(ent, True) , EntityY(ent, True) , EntityZ(ent, True))
O = ent.tformed_x#
O = ent.tformed_y#
O = ent.tformed_z#
O = ent.tformed_x#
O = ent.tformed_y#
O = ent.tformed_z#
| I'll update them tomorrow. Thanks for sharing! |
| Is there a way to adjust the volume?! Or the strength of the emitter? |
| Nvm, just had to change the ScaleFactor :) |
| is this the best sound solution for minib3d ? |
| This is the most tangible one, if that's what you mean. It uses the BlitzMax native audio module with the OpenAL driver, so it's cross-platform and gives 3D sound support.|
Other solutions (such as FMod or IrrKLang) could offer more options but would need to be wrapped.
| @RofRaf: It's open source, you're free to improve it if you need anything else. I'm not improving it any more, as it does what I wanted it to do properly. If anyone wants to fork it in order to improve it or whatever, don't hesitate to do it, and remember to share... |
| Ah this is really cool. nice work. |
| Hey Ziggy, I'm having a real hard time with this piece of code |
SetPosition(TVector.Create(EntityX(Source, True) , EntityY(Source, True) , EntityZ(Source, True)))
Local ED:Float = Abs(EntityDistance(source, sListener3D.ent)) * sListener3D.ScaleFactor
If ED <.5 Then ED =.5
Channel.SetVolume(100:Float * _logicalvolume / ED)
'DebugStop() 'Somethimes the hook is fired before a died item is collected from the tlist!
Seems to work in debug mode but not in release
| @BLaBZ: Do you have any source code sample that replicates the issue? Are you using a threaded compilation of your game? It seems something related to the GC, we could add some additional checks to ensure enything is not null before it's referended inside this try/catch block |
| Found out I had to call TSource3d.Free() if I remove the mesh, otherwise the try catch failed and I get an exception access violation.|
Though now I'm getting a memory leak, I have around 250 simultaneous sounds, and calling Free() doesn't seem to free all of the resources :/
| I've changed to repository to Mercurial. Feel free to make a clone and pull any modifications that may be required. What makes you think you have a mem leak? |
| I'm having trouble getting the 'SetVolume' method of the TSource3D Type to work in the code below. I've tested and confirmed that SetVolume is being called when it should be and is being fed the correct values. The problem seem to lie with SetVolume itself. Basically the sound plays fine but I just can't change the volume level.|
' - Update avatar thruster sound.
' Note that the thruster sound will automaticlly stop playing if the avatar dies or runs out of fuel as the 'thruster_thrust_applied' flag is nulled at the start of the update loop.
If Self.thrust_on And thruster_thrust_applied
Local channel_restarted_flag = False
' If the channel is not playing then start a new one.
If Self.thruster_sound_channel <> Null ' If a channel exists.
If Not Self.thruster_sound_channel.isPlaying() ' If the channel has stopped playing
Self.thruster_sound_channel.Pause( False )
channel_restarted_flag = True
Else ' The channel does not exist so create a new one.
Self.thruster_sound_channel = EmitSound( G_avatar_thruster_sound, Self.feet_pivot, True ) ' Sound will loop.
channel_restarted_flag = True
' Select the volume level based on the thruster speed.
Case 0 ' Low speed mode.
thruster_channel_volume:Float = 0.25
Case 1 ' High speed mode.
thruster_channel_volume:Float = 0.5
' Set the volume level if the speed has changed or the channel has been re-started.
If ( thruster_channel_volume:Float <> Self.thruster_sound_channel_volume:Float ) Or channel_restarted_flag
Self.thruster_sound_channel_volume:Float = thruster_channel_volume:Float
Self.thruster_sound_channel.SetVolume( Self.thruster_sound_channel_volume:Float )
' If no thrust is being applied then pause the thruster sound.
If Self.thruster_sound_channel <> Null ' If the thruster sound channel exists.
If Self.thruster_sound_channel.isPlaying() Then Self.thruster_sound_channel.Pause( True )
Self.thruster_sound_channel = Null ' Null the sound channel variable to indicate that the sound has been stopped.
Last edited show_time('2012-12-03 00:19:54')
| There seems to be an error with this module, or at least that's what the OpenAL error function alGetError() is telling me on my system. |
core.bmx > Type TSource3D > Method Play > Line: alSourcef T3DChannel(Channel)._source._id, AL_MAX_GAIN, 100.0
This line causes an AL_INVALID_VALUE error to be returned from the OpenAL error function alGetError(). Changing the AL_MAX_GAIN value from 100.0 to 1.0 gets rid of the error.
To test, replace the error line with (AL_MAX_GAIN set to original value of 100.0):-
DebugLog "1: " + alGetError() ; alSourcef T3DChannel(Channel)._source._id, AL_MAX_GAIN, 100.0 ; DebugLog "2: " + alGetError()
And then change it to (AL_MAX_GAIN set to 1.0:-
DebugLog "1: " + alGetError() ; alSourcef T3DChannel(Channel)._source._id, AL_MAX_GAIN, 1.0 ; DebugLog "2: " + alGetError()
Don't forget to remove the debuglog statements when you're done.
This doesn't fix my problem with changing volume not working though.
the module is broken. i tried on Ubuntu 12.04, OSX 10.8, Windows XP SP3, and Windows 7.
| Captain Wicker, my last name is Wicker so I had to check your Email. As it's a domain I checked it too. And ... on page 2 of your intro it says, "... that solve porblems ..."|
You definitely wanna change that. :)
As for your tagline, I see boiled peanuts for sale in the store. Never had them, are they any good compared to roasted ?