The Godot Q&A is currently undergoing maintenance!

Your ability to ask and answer questions is temporarily disabled. You can browse existing threads in read-only mode.

We are working on bringing this community platform back to its full functionality, stay tuned for updates.

godotengine.org | Twitter

0 votes

I have the following script to play audio from an array:

var should_play = $PlaybackSwitch.active and source != null
if should_play:
    var empty_frames = playback.get_frames_available()
    while empty_frames > 0:
        playback.push_frame(source.audio_data[playback_index])
        playback_index += 1
        empty_frames -= 1
if should_play and not $Player.playing:
    playback.clear_buffer()
    $Player.play()
if not should_play and $Player.playing:
    $Player.stop()
    playback_index = 0

But I have the problem that when I stop and restart playback, a snippet of audio from the end of what was previously playing makes it in. Calling clear_buffer is supposed to help with this, but it produces the error Condition "active" is true. Looking at the C++ source, I can't figure out where this is getting set. What do I need to do to make the stream not active so I can clear it?

Godot version 3.5.stable
in Engine by (21 points)
edited by

Just guessing here, but is this as intended?

var should_play = playing and source != null

So, should_play is only set if the track is already playing?

Should that not be !playing and source != null?

Also, it seems odd that you might start the track playing with...

$Player.play()

and then start mucking around with the audio frames via:

playback.push_frame(...)

playing is poorly named, it is a boolean used by an on/off switch. Maybe should_play or play_requested would be more appropriate.

Yeah, putting Player.play after the generation would make sense.

I've updated the code accordingly.

Seems like you could still arrive at the posted code with the source already playing and end up setting should_play = true. In that case, you'd still be fiddling with the frames of a currently playing audio source - which seems likely to be the cause of the original issue (?).

Should should_play only be set if the source isn't already playing? That'd eliminate the possibility described above...

But, really just guessing here...

The example of how to use the classes I'm using does this. There is no other code that plays the audio source, and it is not set to auto-play, so it can only be started and stopped by this particular piece of code. As far as I can tell the problem is with playback.clear_buffer(). It is only called while the audio source is stopped but still produces the error mentioned. Looking at the C++ code, clear_buffer never actually gets to the part of the code that clears the buffer if the error is triggered.

1 Answer

0 votes

For now I've "fixed" this by creating a new stream every time playback stops:

var should_play = $PlaybackSwitch.active and source != null
if should_play:
    var empty_frames = playback.get_frames_available()
    while empty_frames > 0:
        playback.push_frame(source.audio_data[playback_index])
        playback_index += 1
        empty_frames -= 1
if should_play and not $Player.playing:
    $Player.play()
if not should_play and $Player.playing:
    $Player.stop()
    playback_index = 0
    $Player.stream = AudioStreamGenerator.new()
    playback = $Player.get_stream_playback()
by (21 points)
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.