Introducing Resonate — An all-in-one audio manager (sound & music)

Introducing Resonate — an all-in-one sound and music management addon for the Godot game engine. Features:

  • Pooled audio stream players.
  • Automatic 2D and 3D space detection.
  • Polyphonic playback.
  • Stemmed music tracks.
  • Music crossfading.

Resonate has two core systems: the SoundManager and the MusicManager.

The SoundManager automatically pools and orchestrates AudioStreamPlayers for you and gives you control over the players when needed.

The MusicManager composes music tracks built from stems and supports the (cross)fading of tracks or stems out of the box.

For full details, visit the GitHub page.

Open to feedback and contributions.

8 Likes

Seems pretty cool! 2 things I noted:

  1. The ability to set per-stream volume variation in resource/config seems missing. Sure, I can call trigger_varied, but when balancing volume of individual sounds, I want to set it in config somewhere and then all calling code will use that default volume, it’s easier. For ex, in my game, most sounds do not play at 0db, but instead at -2, -4, or +3db. Fixing volume level in each sound file is just more work than using a config. Not sure if the same is true for music, didnt’ look at music stuff, but per-stream config of volume is also good for music files.

  2. Super minor this, but noticed this code in sound_manager.gd:


	if event.streams.size() == 0:
		push_error("Resonate - The music track [%s] on bank [%s] has no stems, you'll need to add one at minimum." % [p_event_name, p_bank_label])
		return
		
	var player = get_player(p_attachment)
	
	if event.streams.size() == 0 or player == null:
		push_error("Resonate - The event [%s] on bank [%s] can't be played; no streams or players available." % [p_event_name, p_bank_label])
		return null

The “event.streams.size() == 0 or” in the second “if” seems unnecessary since the code will never get there if indeed that condition is true. Error message should be updated respectively, if you update the if statement.

Congrats on releasing an addon, cheers!

1 Like

Thanks for the feedback! I agree with both points, so I’ll action those and include them in the next release, which might be out later today.

1 Like

Version 2.3.0 has just been released!

Features:

  • add a volume variable to sound events (bank-configured)
  • add enhanced return types, signals, and helper methods to the music manager
  • add null object pattern to the sound manager for instances and some additional helper methods and events for implementation
  • add pitch variable to sound event resources and fix pitch and volume behaviour across audio stream players
  • add play_varied, play_at_position_varied, and play_on_node_varied methods to the sound manager
  • add reset_volume, reset_pitch, and reset_all methods to pooled audio stream players
  • add the quick_instance method to the sound manager for bulk instances, or for shorter registration calls

Bug fixes:

  • ensure that pooled audio stream players return the player volume back to the base volume when calling trigger after trigger_varied, and that trigger_varied isn’t affected by the base volume on polyphonic playback
  • fix the “signal already connected” error in multiple single-script auto_released instances and ensure the connection is deferred
  • fix the error handling & messages for missing streams or players in the sound manager
  • fix the volume adjustment in the trigger_varied method on non-polyphonic pooled audio stream players
  • increase the volume step resolution on music stem resources to allow for fractional dBs
  • push a warning when instanced sound events that contain looping variations are released with “finish playing” - these will be forced to stop playback

The new version may take a little time to appear on the Godot Asset Library. However, you can always grab the latest version from the GitHub releases page if you don’t want to wait.

2 Likes

Version 2.3.1 has been released.

This version fixes up a couple of loose ends in the 2.3.0 release.

Bug fixes:

  • ensure 3D players registered as auto-released aren’t lost during scene tree exiting events
  • fix the project settings registration process when the addon loads

This version may take a little time to appear on the Godot Asset Library. However, you can always grab the latest version from the GitHub releases page if you don’t want to wait.

1 Like

Version 2.3.2 has been released.

Bug fixes:

  • add missing reset_* methods to the null audio players
  • alter the attachment logic for 2D and 3D players to avoid issues with players being freed before returning to the pool (deprecates auto_release)
  • replace the remote transform behaviour with an inbuilt follow-target mechanism to avoid audio artifacts

This version may take a little time to appear on the Godot Asset Library. However, you can always grab the latest version from the GitHub releases page if you don’t want to wait.

1 Like

Version 2.3.3 has been released.

Bug Fixes:

  • ensure that the Sound and Music managers ref-count banks to avoid unexpected removal for multi-users
  • fix the Music and Sound manager default bank bus settings and migrate older addon values if present

This version may take a little time to appear on the Godot Asset Library. However, you can always grab the latest version from the GitHub releases page if you don’t want to wait.

1 Like

Version 2.3.4 has been released.

Bug Fixes:

  • fix sound and music manager parse errors on exported projects

This version may take a little time to appear on the Godot Asset Library. However, you can always grab the latest version from the GitHub releases page if you don’t want to wait.

Resonate version 2.4.0 has been released.

Features

  • add an auto-loop option to the MusicManager’s play method to allow non-looping tracks to repeat playback with an integrated crossfade
  • allow polyphonic players to be stopped and synchronise the is_playing state with the underlying polyphonic streams

This version may take a little time to appear on the Godot Asset Library. However, you can always grab the latest version from the GitHub releases page if you don’t want to wait.

Love the plugin btw.

how do I access this?
“add an auto-loop option to the MusicManager’s play method to allow non-looping tracks to repeat playback with an integrated crossfade”

do I need to instance the Soundmanger for this? as I can’t seem to adjust it in the editor

1 Like

Hello, and thank you!

You can access that feature by passing true to the p_auto_loop parameter of the MusicManager’s play function: resonate/addons/resonate/music_manager/music_manager.gd at e1cf2cff9b91c2672fa49c8518703e97e8ece5c0 · hugemenace/resonate · GitHub

For example:

MusicManager.play("my_bank", "my_track", 5.0, true)
                                              ^^^^

Spectacular!

Does this functionality work on the SoundManager as well?

What I’m trying to do is a have a sound effect loop from the SoundManger. For example a sound of rustling leaves while my player is moving in a bush and then stop when the player stops.

I just dont quite understand how to make that work quite yet lol… its entirely possible Im am the issue… which is usually the case lol

Thanks for the reply and I really appreciate your hard work on this project. Made my life 100000% easier lol

There isn’t an equivalent function on the SoundManager, as the SoundManager is there to manage one-shot sounds or sounds tied to game events (collisions, footsteps, power-ups, gunshots, spells, UI button clicks, etc.).

If you wanted a “sound” to continue looping, the easiest way would be to set the audio clip’s loop property to true in the Godot inspector panel. That way, when the SoundManager triggers the sound, it won’t automatically stop. But keep in mind a looping sound will never get returned into the pool (as it technically will never stop playing unless you manually tell it to do so.)

Glad you’re enjoying Resonate, and it’s proving helpful in your project(s) :slight_smile:

Yeah I tried that and it tells me

W 0:00:06:0640 pool_entity.gd:165 @ release(): Resonate - The player [@AudioStreamPlayer@25] has looping streams and therefore will never release itself back to the pool (as playback continues indefinitely). It will be forced to stop.
<C++ Source> core\variant\variant_utility.cpp:1111 @ VariantUtilityFunctions::push_warning()
pool_entity.gd:165 @ release()
pooled_audio_stream_player.gd:110 @ release()
sound_manager.gd:151 @ play()
forest_floor_tutroial.gd:51 @ _process()

Basically, it tells me its a looping track and it wont release so we are shutting you down lol…

I will just make the track way longer than it needs to be I suppose. How do you manually stop a specific track?

also I apologize for all the questions :slight_smile:

1 Like

I can’t see a way to stop a track that is currently playing. Is this a thing that can be done?