0 votes

I am trying to make a sound happen when a button is pressed but for some reason it makes a popping sound. If i make the sound happen on ready func it will sound normal. The sound is mp3, how can i fix this?

in Engine by (17 points)

1 Answer

+1 vote

I had an issue where I was trying to play a sound when an object was destroyed but I couldn't hear those sounds. The problem was that by calling queue_free to remove the object, the playing sound terminated instantly as well.

It looked like the way to solve this (your situation might be something similar) was to have an AudioStreamPlayer someplace else in the Scene Tree and send it signals. I was trying to plug this together, when I found this bit of code for an audio manager script: https://kidscancode.org/godot_recipes/audio/audio_manager/

extends Node

var num_players = 8
var bus = "master"

var available = []  # The available players.
var queue = []  # The queue of sounds to play.


func _ready():
    # Create the pool of AudioStreamPlayer nodes.
    for i in num_players:
        var p = AudioStreamPlayer.new()
        add_child(p)
        available.append(p)
        p.connect("finished", self, "_on_stream_finished", [p])
        p.bus = bus


func _on_stream_finished(stream):
    # When finished playing a stream, make the player available again.
    available.append(stream)


func play(sound_path):
    queue.append(sound_path)


func _process(delta):
    # Play a queued sound if any players are available.
    if not queue.empty() and not available.empty():
        available[0].stream = load(queue.pop_front())
        available[0].play()
        available.pop_front()

I named this script AudioManager and set it to autoload in Project Settings. Now I just need to "AudioManager.play("res://sound.mp3") from anywhere in the scene tree. This works very nicely and is how I plan to set up all my Godot audio from now on. You might want to try it because it sounds like something might be terminating your sound prematurely.

by (20 points)

Another option is spawning StreamPlayers without pooling them. When a (oneshot) sfx is needed, simply create a new StreamPlayer and connect its "finished" signal to its queue_free method, so it self-destructs.
You might want to also add them to an array in case you need to stop/free all the audio at once, for example when changing scenes.

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.