class_name Music extends Node ## While the instruments are manipulated individually to match the gameplay, ## they are all regrouped in a single bus dedicated to this specific music. ## So we also manipulate the bus itself for the purposes of applying ## audio balance and settings and the such more efficiently. var bus_index: int = -1 var instruments: Array[AudioStreamPlayer] = [] func _ready() -> void: bus_index = AudioServer.get_bus_index(self.name) if bus_index == -1: AudioServer.add_bus() AudioServer.set_bus_name(AudioServer.bus_count - 1, self.name) bus_index = AudioServer.get_bus_index(self.name) changeVolume(0) var current_effects = AudioServer.get_bus_effect_count(bus_index) for i in current_effects: AudioServer.remove_bus_effect(bus_index, i) var children = get_children() for child in children: if child is AudioStreamPlayer: instruments.push_back(child) child.bus = AudioServer.get_bus_name(bus_index) child.volume_db = -50 var stream: AudioStreamOggVorbis = child.stream if stream is AudioStreamOggVorbis: stream.loop = true stream.bpm = 124 for instrument in instruments: if instrument is AudioStreamPlayer: instrument.play() func changeVolume(db: float) -> void: AudioServer.set_bus_volume_db(bus_index, db + Settings.volume_music) AudioServer.set_bus_mute(bus_index, Settings.volume_music <= -15.0) func adaptInstrumentsToVelocity(velocity: float) -> void: ## temp const delta = 0.00833333333333 var instruments_needed = floor(velocity / 8) var instruments_playing = instruments.filter(func(i: AudioStreamPlayer): return i.volume_db > -50) for index_p in len(instruments_playing): var playing = instruments_playing[index_p] if index_p + 1 > instruments_needed: playing.volume_db = max(playing.volume_db - (delta * 32), -50) elif playing.volume_db <= 0: playing.volume_db = min(playing.volume_db + (delta * 8), 0) if instruments_needed > len(instruments_playing): var instruments_not_playing = instruments.filter(func(i: AudioStreamPlayer): return i.volume_db <= -50) if len(instruments_not_playing): var to_play = instruments_not_playing.pick_random() if is_instance_valid(to_play): to_play.volume_db = min(to_play.volume_db + (delta * 16), 0) func fadeOut(seconds: float) -> void: var tween: Tween = create_tween() # https://github.com/godotengine/godot/issues/32882 AudioServer.add_bus_effect(bus_index, AudioEffectAmplify.new()) var effect_index: int = AudioServer.get_bus_effect_count(bus_index) - 1 var effect: AudioEffectAmplify = AudioServer.get_bus_effect(bus_index, effect_index) tween.tween_property(effect, "volume_linear", 0, seconds)