godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
90.8k stars 21.13k forks source link

AudioPlaybackTrack forces unwanted polyphony and bypasses AudioStreamPlayer3D's `max_polyphony` limit. #83797

Open KnightNine opened 1 year ago

KnightNine commented 1 year ago

Godot version

4.X

System information

Windows 10

Issue description

I have a looping animation, I want the sound (AudioPlaybackTrack) within that animation to loop when the animation loops. But if the end_offset of the audio clip exists outside the animation length the audio is not stopped and then overlaps with itself, and it it's practically impossible to set the end_offset to the very end of the animation length. (Because the adjusting end_offset value manually to get the exact endpoint of the animation using the sound length and the animation length values is finnicky. I also can't snap the end offset to anything by dragging it in the timeline either.)

That aside, this sound overlapping shouldn't even happen anyways if the max_polyphony property of the AudioStreamPlayer3D being used by the audio track is set to 1. It should only be able to play one sound at a time so it should cut the last sound being played when the loop restarts to begin the sound again.


Note:

When the AudioPlaybackTrack makes the AudioStreamPlayer3D play a sound it creates and adds an "AudioStreamPolyphonic" resource to it, I assume that this resource ignores the max_polyphony property of the AudioStreamPlayer.

Steps to reproduce

The audio should continue to play and overlap with itself even after the loop ends.

Minimal reproduction project

To be added if necessary.

TokageItLab commented 1 year ago

Is it just an AudioPlaybackTrack issue, or does this issue also occur when using AudioStreamPolyphonic directly? It is needed to isolate the problem.

If it is the latter, I think it is more of an audio side issue, since on the AnimationMixer side we have set audio_max_polyphony for the audio stream.

In any case, it needs to be tested.

KnightNine commented 1 year ago

@TokageItLab tested this code, the issue relates to the AudioStreamPolyphonic directly:

@onready var player:AudioStreamPlayer = get_node("AudioStreamPlayer")
@onready var sound = preload("res://Objective Beam Idle.ogg")
@onready var sound2 = preload("res://Hiss.ogg")

func _ready():
    player.stream = AudioStreamPolyphonic.new()
    player.playing = true
    await get_tree().create_timer(1).timeout

    print(player.stream)
    var playback = player.get_stream_playback() as AudioStreamPlaybackPolyphonic
    var id = playback.play_stream(sound)
    await get_tree().create_timer(1).timeout
    var id2 = playback.play_stream(sound2) # 1 second later, start another clip
    await get_tree().create_timer(1).timeout

max_polyphony is ignored by AudioStreamPolyphonic

MJacred commented 10 months ago

@KnightNine: could you test https://github.com/godotengine/godot/pull/86054, please? Your issue of accidental sound overlapping reminds me of https://github.com/godotengine/godot/issues/86053

KnightNine commented 4 months ago

@MJacred Tested #86054 , the issue persists.

KnightNine commented 2 months ago

Just wondering how do I add looping audio to a looping animation (like an in game generator or radio where the noise needs to be constant) if this functionality doesn't work? Is there a workaround in 4.2 or 4.3?