GarageGames / Torque3D

MIT Licensed Open Source version of Torque 3D from GarageGames
http://torque3d.org
MIT License
3.35k stars 1.2k forks source link

Changes for SFXSound::setPosition(time) #2220

Closed irei1as closed 5 years ago

irei1as commented 6 years ago

Note: Only tested with OpenAL.

The method sfxSound.setPosition(time) has some issues: -The engine method has a miscalculation in some values. -It doesn't work when the sound is stopped (so you can't modify the time before play). -It doesn't work at all for files longer than 24 seconds that are streaming and looping (if they're shorter than 24 s, internally they're changed to not-streaming -sfxSystem.cpp: ~line 714-).

To check that you need a datablock SFXProfile with looping and streaming like:

datablock SFXProfile(SoundLength31sLS) { filename = "data/sfxSetPosTest/scripts/atime_31s"; description = AudioMusicLoop2D; };

With that datablock loaded you create the sound with: $sound_object = sfxCreateSource(SoundLength31sLS);

Then you can test various things like:

$sound_object.play(); $sound_object.setPosition(24); $sound_object.stop() $sound_object.getPosition(); $sound_object.setPosition(10); $sound_object.play();

This pull request tries to fix those issues. I'm not 100% sure if all it is alright. Specially the changes to asyncPacketStream.h. But I don't see anywhere else where it is used. Also not sure the effect with internet streaming sounds. The SFXSound::_play() part is a bit "hack" but I don't know how to easily add the option for setPosition to work before playing.

Finally let me warn about a possible issue: source\sfx\openal\sfxALBuffer.cpp(156,0): {Fatal} - SFXALBuffer::write() - buffer invalid

That may happen when setting the position immediatly after sfxCreateSource all in one line very fast like:

$sound_object = sfxCreateSource(SoundLength31sLS); $sound_object.play(); $sound_object.setPosition(28);

But it's very hard for it to appear, as: -It seems to appear only the first time a datablock is used. -It seems to be affected by buffer load so you have to force continuous loads of sound.

I have no idea how to fix it. I'd love any help on that. Probably a while(true){ -check if buffer is ready then break the while;- } is needed somewhere.

To try to replicate it you can use the module I include at the end. With that loaded start any level and just call stop_create_play_setpos(500)

If it doesn't explode then you need to restart the game to try again (for the datablocks to be again 1st time). You can change that 500 to change how fast the files are reload, too. And actually it is troublesome because the sound plays but the setPosition fails.

Ah, that error appears too before these pull request changes. But only in the cases where setPosition worked.

Example with some files you can use in this module: sfxSetPosTest.zip