Multiple Sound Files - one Audio Player, or Several?

Godot Version

4.2.1

Question

I am trying to recreate an old quiz program that I previously wrote in a Flash based language - using Godot as it seems the easiest for me to get my head around - or so I thought lol

2 of the rounds require music to be played for each question (12 questions in each round)
In my old system, the audio files were in a folder and numbered sequentially - the program would then load the file - file name being created by concatenating a String (i.e “R5_Q”) and the current question number.

I’ve managed to do this using load() but was wondering if this was the best way to do this, or if I’m missing something.

I know I could put them into a AudioStreamRandomizer - but that will only play sequentially and not let me skip back if I need to (as far as I can tell).

I’ll put the code I’ve been testing with below (new to the engine, so please don’t laugh too much lol) but all I was doing in there was seeing if I could skip backwards and forwards with tracks.

Hope this makes sense - my wife says that I don’t very often - and thanks in advance :slight_smile:

extends Node2D

@onready var music_player: AudioStreamPlayer = $AudioStreamPlayer
@onready var music_stream: AudioStream
@onready var next: Button = $ButtonNext
@onready var prev: Button = $ButtonPrev

var music_length: float
var music_time: float
var line_scale: float
var music_int: float

var temp: int =  0
var temptxt
var music_counter: int = 0
var music_counter_prev: int = 0

func _ready():
	pass

func _process(delta):
	
	if music_player:
		music_time = music_player.get_playback_position()
		$Label.text = "%.1f" % [(music_length - music_time)]
		line_scale = music_time/music_length
		$Line2D.scale.x = line_scale
			

func _on_button_next_pressed():
	temp = music_counter
	music_counter += 1
	if music_counter == 5:
		music_counter = 1
	
	play_music()
	

func _on_button_prev_pressed():
	temp = music_counter
	music_counter -= 1
	if music_counter == 0:
		music_counter = 4
		
	play_music()
	
func play_music():
	
	temptxt = load("res://MusicTemp/R5_EN_Q"+ str(music_counter)+".mp3")
	music_player.stream = temptxt
	music_player.play()
	music_length = music_player.stream.get_length()
	music_counter -= 1
	if music_counter == 0:
		music_counter = 4

Make sure to use <= instead of == for the counter. If it’s at 0 already, you’ll have a little problem.

1 Like

One of the alternatives I know is making an @export var that is an array of AudioStreams. With it you’ll be able to easily add new audio files from the editor, access it easily and manipulate them with ease:

@export var audio_list : Array[AudioStreamPlayer]
var current_index : int = 0
var current_audio : AudioStreamPlayer

# handle play music
func _play_music(index: int = 0) -> void:
    # prevents any errors
    if !audio_list.has(index): return
    if current_audio: current_audio.stop()

    audio_list[index].play()
    current_index = index
    current_audio = audio_list[index]

# handle skipping songs
func _nav_musiclist(direction: int = 0) -> void:
    # prevents any errors
    let new_index = current_index + direction
    if !audio_list.has(new_index): return

    _play_music(new_index)

The only downside is that you’ll need to know the specific index if you wanna play a specific track. It can be « fixed » by making a manifest-like dictionary variable:

var track_manifest : Dictionary = {
    "track_0": 0,
    "track_1": 1,
    "track_2": 2,
    "track_3": 3
}

func _play_from_name(audio_name: String) -> void:
    if !track_manifest.has(audio_name): return
    _play_music(track_manifest[audio_name])

1 Like

Good spot - Thank You :slight_smile:

Thanks Melide

I’ll have a look at that approach, but I am trying to avoid, if possible, having to add tracks into the project itself and just changing the files in the relevant folder - just thinking about making things a bit easier going forward.

Unless I’ve mis-understood in which case I apologise :slight_smile:

However, I like the simplicity of the code and the system you’ve used which I’d completely missed!

Thanks for the reply :slight_smile:

1 Like