Audio glitches when changing position and volume of AudioStreams in Linux

lawnjellylawnjelly Posts: 25Member

I'm trying to play positional sound effects in Godot 3.1 in Linux Mint using pulse audio, and I've been having trouble with glitches in my short sounds (imported from wav) when changing the position of the AudioStream3D node and volume (using either set_max_db or set_unit_db, it's not clear which should be used) immediately prior to playing the sound.

I was originally using is_playing() on the audiostream to determine whether a previous sound was finished before playing the next, however this didn't work reliably in my tests so I've also tested using in addition a manual timer for each AudioStream, to prevent playing again until after a delay for the length of the sound + a bit extra. The problem persists.

I've tried an original approach of using a pool of AudioStreams and moving their translation at the point of playing the sound, and also simply attaching AudioStreams to moving objects in the game. The AudioStreams attached to moving objects don't seem to suffer from glitches from changing translation as this is not necessary, but do glitch from changing the volume of the sound each play.

I've tried it using AudioStream2D and AudioStream3D, both have same problem. I've also tried exporting the project to linux and exporting to windows and running under wine, same problem. Unfortunately I don't have a windows machine to test, but will make an example test project if this a bug.

Am I using Godot in the expected manner to play sounds? I would like to check this before adding as a bug to the issue tracker, maybe I am making an obvious mistake.

image
This is an audio capture showing an example glitch, a sine wave test sound is being interrupted / glitched after 0.05 second (bottom left) even though the sound should last a second or so.

I suspect there is some issue with the changes to the volume and position being applied out of order compared to the order in which they were issued to godot.

Comments

  • lawnjellylawnjelly Posts: 25Member

    I figured out how to post it to soundcloud:

  • lawnjellylawnjelly Posts: 25Member

    Ok the plot thickens, I by chance found another method someone else was using, slightly adapted it is this:
    func PlaySound_Node(var stype, var node, var volume = 1.0): if m_bSoundOn == false: return assert (node != null) var player = AudioStreamPlayer3D.new() node.add_child(player) player.bus = "Short" player.stream = StreamFromSType(stype) player.set_max_db(-60 + (volume * 60.0)) player.connect("finished", player, "queue_free") player.play()
    This seems (touchwood) to be curing the issue. The question is why?

    It's pretty horrific to be creating new objects and placing on the scene graph every time a sound is played, so not ideal. But why does reusing the same AudioStreamPlayer cause problems? My best guess is behind the scenes that maybe it is creating a new mini buffer for the stream in each new AudioStreamPlayer, whereas reusing such a buffer for multiple plays might be causing glitches. I suspect it is a bug rather than intended behaviour. Anyway this (ugly) fix will hopefully work for now at least. :neutral:

  • MegalomaniakMegalomaniak Posts: 1,173Admin

    @lawnjelly said:

    My best guess is behind the scenes that maybe it is creating a new mini buffer for the stream in each new AudioStreamPlayer, whereas reusing such a buffer for multiple plays might be causing glitches. I suspect it is a bug rather than intended behaviour. Anyway this (ugly) fix will hopefully work for now at least. :neutral:

    Sounds like a bug report is in order then, though don't forget to search the issue tracker for duplicates and similar issues first. And if you miss some, don't worry about it, someone will mention it to link the issues together, then close one of them. Better to have duplicates than no report of the issue at all.

  • CalinouCalinou Posts: 233Admin Godot Developer
    edited April 5

    @lawnjelly said:
    It's pretty horrific to be creating new objects and placing on the scene graph every time a sound is played, so not ideal.

    You need to do this to be able to play multiple sounds at once anyway ("polyphony"), and there shouldn't be performance issues when doing this. Just make sure to free the AudioStreamPlayer when the sound is done playing, which is easily done by connecting a signal to queue_free().

  • lawnjellylawnjelly Posts: 25Member

    Hi Calinou I have replied on the issue tracker now:

    https://github.com/godotengine/godot/issues/22016

    Your method does work yes, but it is working around a potential bug so I wonder if for other people in future it may be good to fix multiple plays (if it is indeed a bug). :smile:

Sign In or Register to comment.