[4.7.1 : 2D] Audio issues when creating the audio object from scratch

Still working on the framework sim thing that I’ve been working on but now I have come back from a break yet I am stuck on the same issue.

Put simply, no object beyond the base Node2D that everything parents to is allowed. Not to start with. The code reads a txt file and deciphers a list of commands to build a scene. What I am having trouble with is the command(s) that manages sound, as it creates the object and assigns the path fine, but it is unable to load the stream and/or the resource.

I tried to decipher documentation to iron out the issue. I was never able to.

Code
elif Local[0].to_lower() == "sound" and len(Local) == 2: #120
	print("Command:Sound") #121
	ActiveInstances.append(AudioStreamPlayer.new()) #122
	add_child(ActiveInstances[-1]) #123
	var a = AudioStream.new() #124
	a.set_path(exePath + Local[1]) #125
	ActiveInstances[-1].stream = a #126
	ActiveInstances[-1].play() #127
	ActiveInstances[-1].set_script(load("res://SoundManager.gd")) #128
	ActiveInstances[-1].called() #129
Variables

Local → Splits the command into chunks and stores it as an array
ActiveInstances → A list of every object currently active. Meant for easy access, and mostly used to remove the objects when changing scenes.
exePath → The location of the executable
a → Often used when a command needs to create something then delete it immediately after.
res://SoundManager.gd → Two print commands. That’s it. Meant to delete the object once the audio completes, but thats not coded in at the moment

What I want to happen is as follows:

  • Player is created
  • Stream is created
  • Stream is assigned an audio file
  • Player is assigned the stream
  • Player plays the audio file

But unfortunately, that just doesn’t happen.

Errors
E 0:00:09:543   Maker.gd:127 @ Manage(): Required virtual method AudioStream::_instantiate_playback must be overridden before calling.
  <C++ Source>  servers/audio/audio_stream.h:172 @ _gdvirtual__instantiate_playback_call()
  <Stack Trace> Maker.gd:127 @ Manage()
                Maker.gd:239 @ _process()

E 0:00:09:543   Maker.gd:127 @ Manage(): Failed to instantiate playback.
  <C++ Error>   Condition "stream_playback.is_null()" is true. Returning: stream_playback
  <C++ Source>  scene/audio/audio_stream_player_internal.cpp:150 @ play_basic()
  <Stack Trace> Maker.gd:127 @ Manage()
                Maker.gd:239 @ _process()

To load an audio file, use one of the load_from_file() methods from AudioStreamMP3, AudioStreamOggVorbis or AudioStreamWAV class (depending on the file).

I cut the AudioStream and instead loaded it like this: ActiveInstances[-1].stream = AudioStreamMP3.load_from_file(exePath + Local[1])

That worked out fine. Is there any way to allow it to load any type of file? Without extra if-else arguments, rather?

(also I think the odd method I used was from an earlier version because i remember this not working lmao. Maybe I missed something.)

AudioStream is a base class. Creating AudioStream.new() gives you something that cannot play audio, that matches your error about _instantiate_playback not being overridden.set_path() also does not load a file. It only sets resource path metadata.

Since you’re loading from disk next to the executable (exePath + Local[1]), use load_from_file() as @hyvernox said, you can use something like:

elif Local[0].to_lower() == "sound" and Local.size() == 2:
	print("Command:Sound")

	var player := AudioStreamPlayer.new()
	add_child(player)
	ActiveInstances.append(player)

	var path := exePath.path_join(Local[1])
	var stream: AudioStream

	match path.get_extension().to_lower():
		"wav":
			stream = AudioStreamWAV.load_from_file(path)
		"ogg":
			stream = AudioStreamOggVorbis.load_from_file(path)
		"mp3":
			stream = AudioStreamMP3.load_from_file(path)
		_:
			push_error("Unsupported audio: " + path)
			return

	if stream == null:
		push_error("Couldn't load " + path)
		return

	player.stream = stream
	player.set_script(load("res://SoundManager.gd"))
	player.called()
	player.play()

I do wish there was an object that included the ability to play all three…but this is indeed a very nice way to do it lmao.

I did not know about match. I might redo the command system I have to use match instead.

Thank you both for the assistance!