[RELEASED] Stem: Lightweight Audio Manager

https://www.youtube.com/watch?v=zA00DvbHOK0

AVAILABLE ON UNITY ASSET STORE
Stem is a robust and versatile audio manager that helps you with SFX, layered music, crossfades, music events without additional scene setup.

Features

• Supports layered music playback with independent playback controls
• Supports sound variations: use multiple audio clips, randomize volume/pitch/delay for each clip
• Supports 2d and 3d sound: tune the most important settings within the asset
• Persistent playback: keep playing music and sounds while transitioning between scenes
• Music events: handle playback and track changes in an easy way
• Requires no scene setup: create a few assets and that's it
• Optimized for runtime use: great performance, zero memory allocations per frame
• Integrates with Unity 5 Audio: easily connect to a Unity mixer
• Saves time with the batch import feature
• All source code included

DOCUMENTATION | API REFERENCE | ROADMAP

Stem v1.1.1 is out!

What's new

  1. Replaced 'edit' button to standard foldouts in bank inspectors;

  1. Improved API so it's possible to create sounds with variations and playlists from the code;
  2. Bugfixes and improvements (see changelog below)

Stem v1.1 is out!

What's new

  1. Support for old versions starting from Unity 5.5;
  2. Undo/Redo support for bank assets;
  3. ID system & custom attribute drawers (no directly typed string values in prefabs anymore);

using UnityEngine;

public class IDTester : MonoBehaviour
{
    [Stem.SoundID]
    public int soundId = 0;

    [Stem.SoundBusID]
    public int soundBusId = 0;

    [Stem.PlaylistID]
    public int playlistId = 0;

    [Stem.MusicPlayerID]
    public int musicPlayerId = 0;

    private void Start()
    {
        Stem.Sound sound = Stem.SoundManager.GetSound(soundId);
        if (sound != null)
            Debug.LogFormat("Found sound: {0}", sound.Name);

        Stem.SoundBus soundBus = Stem.SoundManager.GetSoundBus(soundBusId);
        if (soundBus != null)
            Debug.LogFormat("Found sound bus: {0}", soundBus.Name);

        Stem.Playlist playlist = Stem.MusicManager.GetPlaylist(playlistId);
        if (playlist != null)
            Debug.LogFormat("Found playlist: {0}", playlist.Name);

        Stem.MusicPlayer musicPlayer = Stem.MusicManager.GetMusicPlayer(musicPlayerId);
        if (musicPlayer != null)
            Debug.LogFormat("Found music player: {0}", musicPlayer.Name);
    }
}
  1. Music callbacks (playback change, track change);

Could be global:

using UnityEngine;

public class MusicManagerCallbacks : MonoBehaviour
{
    private void Start()
    {
        Stem.MusicManager.OnPlaybackStarted += OnPlaybackStarted;
        Stem.MusicManager.OnPlaybackStopped += OnPlaybackStopped;
        Stem.MusicManager.OnPlaybackPaused += OnPlaybackPaused;
        Stem.MusicManager.OnTrackChanged += OnTrackChanged;
    }

    private void OnDestroy()
    {
        Stem.MusicManager.OnPlaybackStarted -= OnPlaybackStarted;
        Stem.MusicManager.OnPlaybackStopped -= OnPlaybackStopped;
        Stem.MusicManager.OnPlaybackPaused -= OnPlaybackPaused;
        Stem.MusicManager.OnTrackChanged -= OnTrackChanged;
    }

    private void OnPlaybackStarted(Stem.MusicPlayer player)
    {
        Debug.LogFormat("[Global Callback] {0}: playback started", player.Name);
    }

    private void OnPlaybackStopped(Stem.MusicPlayer player)
    {
        Debug.LogFormat("[Global Callback] {0}: playback stopped", player.Name);
    }

    private void OnPlaybackPaused(Stem.MusicPlayer player)
    {
        Debug.LogFormat("[Global Callback] {0}: playback paused", player.Name);
    }

    private void OnTrackChanged(Stem.MusicPlayer player, Stem.PlaylistTrack track)
    {
        Debug.LogFormat("[Global Callback] {0}: track changed to {1}", player.Name, (track != null) ? track.Name : "none");
    }
}

Or local:

using UnityEngine;

public class MusicPlayerCallbacks : MonoBehaviour
{
    [Stem.MusicPlayerID]
    public int id = 0;

    private Stem.MusicPlayer cachedPlayer;

    private void Start()
    {
        cachedPlayer = Stem.MusicManager.GetMusicPlayer(id);
        if (cachedPlayer != null)
        {
            cachedPlayer.OnPlaybackStarted += OnPlaybackStarted;
            cachedPlayer.OnPlaybackStopped += OnPlaybackStopped;
            cachedPlayer.OnPlaybackPaused += OnPlaybackPaused;
            cachedPlayer.OnTrackChanged += OnTrackChanged;
        }
    }

    private void OnDestroy()
    {
        Stem.MusicManager.Stop(id);

        if (cachedPlayer != null)
        {
            cachedPlayer.OnPlaybackStarted -= OnPlaybackStarted;
            cachedPlayer.OnPlaybackStopped -= OnPlaybackStopped;
            cachedPlayer.OnPlaybackPaused -= OnPlaybackPaused;
            cachedPlayer.OnTrackChanged -= OnTrackChanged;
        }
    }

    private void OnPlaybackStarted(Stem.MusicPlayer player)
    {
        Debug.LogFormat("[Local Callback] {0}: playback started", player.Name);
    }

    private void OnPlaybackStopped(Stem.MusicPlayer player)
    {
        Debug.LogFormat("[Local Callback] {0}: playback stopped", player.Name);
    }

    private void OnPlaybackPaused(Stem.MusicPlayer player)
    {
        Debug.LogFormat("[Local Callback] {0}: playback paused", player.Name);
    }

    private void OnTrackChanged(Stem.MusicPlayer player, Stem.PlaylistTrack track)
    {
        Debug.LogFormat("[Local Callback] {0}: track changed to {1}", player.Name, (track != null) ? track.Name : "none");
    }
}
  1. The ability to play the playlist from the startup (no coding required);

4080541--424045--music_player_play_on_start.gif

  1. Play button in sound bank inspector allowing to easily test & tune sounds;

4080541--424042--sound_play_in_editor.gif

  1. New music player sample & sample selector.

4080541--424039--music_players_sample.gif

Change Log

v1.0
- Initial asset release

v1.0.1
- Persistent: fixed crash caused by wrong sound bus polyphony default value - Runtime: fixed music player shuffle

v1.0.2
- Persistent: added default bus property to SoundBus class
- UI: fixed sounds not resetting the bus to default once the target bus was removed

v1.0.3
- Build: fixed crash due to attempt to save all assets including internal ones

v1.0.4
- UI: fixed inability to set a sound bus from the drop-down list in sound bank inspector

v1.1
- Feature: undo/redo support for bank assets
- Feature: unique & persistent IDs for sounds, sound buses, music player and playlists
- Feature: custom attribute drawers for sounds, sound buses, music players and playlists allowing easier selection (no directly typed string values in prefabs anymore)
- Feature: music player callbacks (playback change, track change)
- Feature: sound bank callbacks (sound add/remove/rename, sound bus add/remove/rename)
- Feature: music bank callbacks (playlist add/remove/rename, music player add/remove/rename)
- Feature: the ability to play the playlist from the startup
- Feature: 'play' button in sound bank inspector allowing to easily test & tune sounds

  • API: added SoundInstance.Target property allowing to easily attach sound instances to game objects
  • API: added MusicManager / SoundManager method overrides that take IDs
  • API: added MusicManager.IsPlaying method
  • API: added index based MusicManager.Seek method
  • API: removed internal SoundBank.AddSound / AddSoundBus and MusicBank.AddPlaylist / AddMusicPlayer methods from API
  • API: removed MusicManager.UnPause method, improved music player play/stop logic
  • API: removed SoundInstance.Transform property, use SoundInstance.Target instead

  • Improvement: a drag-n-drop area for music banks allowing to quickly create playlists

  • Improvement: added two float fields under range slider for precise edits

  • Improvement: better sound & music bank inspector performance

  • Improvement: support for old Unity versions starting from 5.5

  • Improvement: added workaround for Unity popups so they'll show items with duplicate names

  • Samples: music player samples covering all basic features

  • Samples: added sample selector

  • Documentation: new articles in programming section covering bank management, id system and more

  • Fix: crash in MusicManager.Next / MusicManager.Prev due to zero tracks in playlist

  • Fix: crash caused by sound instance deletion if it was attached to a game object

  • Fix: crash for sounds with no variations

  • Fix: music player not stopping on track end with the auto advance flag set to false

  • Fix: music player not properly advancing playlist with the loop flag set to false

  • Fix: bank initialization & registration order

v1.1.1

  • API: added Sound.AddVariation / Sound.AddVariations methods allowing to create sounds with variations from the code
  • API: added Playlist.AddTrack / Playlist.AddTracks methods allowing to create playlists full of tracks from the code

  • Improvement: added meaningful error messages to all SoundManager API methods

  • Improvement:

  • Fix: Stem won't create any game object during application quit

  • Fix: bank inspectors will take drag-drop events into account for undo/redo system

  • Fix: 'play' button now works if a sound was assigned to a newly created sound bus

  • Fix: fixed bank drawers not showing correct values in the play mode

4080541--370579--LogoLight516px389px.png

3 Likes

Hi all, just a quick update here!

Made online documentation with API reference and quickstart section, go check it out here: https://aviktorov.github.io/stem/

The asset is almost ready. Video showcase will be soon.

Looks pretty nice, but calling/referencing sounds by string seems kinda icky...

[quote=“christoph_r”, post:3, topic: 727878]
Looks pretty nice, but calling/referencing sounds by string seems kinda icky…
[/quote]

Thanks for the feedback! I’m also working on the ID system so the user will choose what suits the best. I’ll deliver it in version 1.1. By the way, what would you suggest to use instead of names?

1 Like

Also, there's a SoundInstance class designed for manual work with a particular sound. That may help you with custom mixing logic. Here you can find more details: https://aviktorov.github.io/stem/manual/code_sound_instance.html

1 Like

[quote=“aviktorov”, post:4, topic: 727878]
Thanks for the feedback! I’m also working on the ID system so the user will choose what suits the best. I’ll deliver it in version 1.1. By the way, what would you suggest to use instead of names?
[/quote]

I’d suggest looking into the addressable assets system - it’s still only in preview but seems like the best way to handle asset references in unity going forward. I do see that this would likely need to be optional for an asset, as a lot of people likely wouldn’t be happy to be ‘forced’ to use addressables (in spite of how cool a system it is.)
I’m not sure if you already handle sounds as nested ScriptableObjects, but that’d be a necessity for that. If you do set things up that way, you could also let users come up with their own in-code referencing system that they hook up to in-editor references to those nested SO instances.

I have to admit that I don’t quite see the use of sound banks quite yet (at least in the way they’re used in your examples) - Sound Banks would make sense (for me) for sounds that are basically just variations of each other, where it makes sense to have the same pitch and volume variations. So, footsteps, impact sounds… In which case I’d just want to be playing a randomized sound from the bank, with randomized pitch etc.

Another concept that I find very important for environment sound are ‘soundscapes’ - I believe there is an asset like that on the store already. In short though, they consist of various sounds (or in this case soundbanks?), paired with a probability for each sound/sound bank. I know that you’re going for a lightweight approach, but I think that’s a fairly common approach and IMO might be worth adding.

I’m also quite interested in the music bank - will it also support per-layer sequential playback? That would be really sweet for dynamic soundtracks. EDIT: Just read in your first post that playback control is separate per layer. Sweet!

[quote=“christoph_r”, post:6, topic: 727878]
I’d suggest looking into the addressable assets system - it’s still only in preview but seems like the best way to handle asset references in unity going forward. I do see that this would likely need to be optional for an asset, as a lot of people likely wouldn’t be happy to be ‘forced’ to use addressables (in spite of how cool a system it is.)
I’m not sure if you already handle sounds as nested ScriptableObjects, but that’d be a necessity for that. If you do set things up that way, you could also let users come up with their own in-code referencing system that they hook up to in-editor references to those nested SO instances.
[/quote]

I assume two things when I think about ids: they must be persistent (i.e. somehow stored on the disk) and unique (i.e. it should be possible to identify the instance and the bank). Your suggestion looks very good because it adds the ability to manipulate with bank parts as individual assets so it might be more native for the user. However, it’ll restrict the asset to use latest Unity version.

[quote=“christoph_r”, post:6, topic: 727878]
I have to admit that I don’t quite see the use of sound banks quite yet (at least in the way they’re used in your examples) - Sound Banks would make sense (for me) for sounds that are basically just variations of each other, where it makes sense to have the same pitch and volume variations. So, footsteps, impact sounds… In which case I’d just want to be playing a randomized sound from the bank, with randomized pitch etc.
[/quote]

I see the whole sound bank concept as persistent storage for sound effects. Each sound effect is a collection of audio clips (variations) + audio and randomization settings.

The main profit from having a ‘sound bank’ is a single place where you can find sound data. Stem will automatically load all available banks so you don’t have to do anything other than creating a sound bank.

If you like to organize stuff, you can split sound data into several sound banks. That way you’re able not only to organize stuff but also add new content even during runtime (imagine a new asset bundle just came into the build and it contains new sound bank with new stuff). The cool thing is that you don’t have to add or do something with that bank. It’ll be automatically handled by Stem.

Another use case is ‘sound skins’. Imagine you have a sound bank full of player sound effects and then you have a level where you want to replace player sound effects. What you can do is create another sound bank with the same sound names and assign different clips to them. After that, all you need to do is to tell Stem which sound bank will be the primary bank. That way you’ll be able to switch sound banks for different levels.

Also, the cool thing is that when you work with SoundManager or MusicManager and access sounds by their names, the target bank the sound/music came from is hidden from you.

[quote=“christoph_r”, post:6, topic: 727878]
Another concept that I find very important for environment sound are ‘soundscapes’ - I believe there is an asset like that on the store already. In short though, they consist of various sounds (or in this case soundbanks?), paired with a probability for each sound/sound bank. I know that you’re going for a lightweight approach, but I think that’s a fairly common approach and IMO might be worth adding.
[/quote]

Yeah, I like soundscape concept too! I’m thinking of creating a platform (like FMOD or WWise) where you’ll be able to create an instruments and the whole sound scene. Think of if as DSP engine + Node Graph + 3rd party integration.

[quote=“christoph_r”, post:6, topic: 727878]
I’m also quite interested in the music bank - will it also support per-layer sequential playback? That would be really sweet for dynamic soundtracks. EDIT: Just read in your first post that playback control is separate per layer. Sweet!
[/quote]

You’re absolutely right! Each music bank can contain multiple music players. Each music player has individual playback control and track advance logic (shuffle or sequential) so can do layered music.

By the way, the asset is available on the asset store! https://assetstore.unity.com/packages/tools/audio/stem-lightweight-audio-manager-135461

1 Like

[quote=“aviktorov”, post:7, topic: 727878]
I assume two things when I think about ids: they must be persistent (i.e. somehow stored on the disk) and unique (i.e. it should be possible to identify the instance and the bank). Your suggestion looks very good because it adds the ability to manipulate with bank parts as individual assets so it might be more native for the user. However, it’ll restrict the asset to use latest Unity version.
[/quote]

These are definitely must-haves, I agree. By allowing users to also reference nested scriptable objects (not prefabs! nested scriptable objects have been possible for a long time) in the ‘classical’ unity way, you could let users create custom alternatives to string and/or addressables.

[quote=“aviktorov”, post:7, topic: 727878]
The main profit from having a ‘sound bank’ is a single place where you can find sound data. Stem will automatically load all available banks so you don’t have to do anything other than creating a sound bank.
[/quote]

That’s the thing where I’m a little confused - on a functional part, sound banks appear to have a sound bus. So it also appears to be a functional grouping? Other than that, I’m not sure I see the benefit over sounds being regular files which can be sorted into folders - and with an individually assigned sound bus, which would also be an asset file? As you said further down, it’s also a way of organizing things, and I personally think it’s not so great to bundle organizing assets and assigning functional information like a sound bus. Or am I missing something here?

[quote=“aviktorov”, post:7, topic: 727878]
If you like to organize stuff, you can split sound data into several sound banks. That way you’re able not only to organize stuff but also add new content even during runtime (imagine a new asset bundle just came into the build and it contains new sound bank with new stuff). The cool thing is that you don’t have to add or do something with that bank. It’ll be automatically handled by Stem.
[/quote]

Great! That’s also essential for supporting user mods.

[quote=“aviktorov”, post:7, topic: 727878]
Yeah, I like soundscape concept too! I’m thinking of creating a platform (like FMOD or WWise) where you’ll be able to create an instruments and the whole sound scene. Think of if as DSP engine + Node Graph + 3rd party integration.
[/quote]

Quite interested to see how that turns out! In the meantime, it sounds like it would be simple enough to build a simple system on top of this asset by adding information how often a certain sound should be played.

Btw, sorry for seeming a bit negative or critical - this is actually because I think it’s a good approach and I’m very interested :slight_smile:

Looks good.
I am searching for a Soundsystem for my MMO. Thats why for me it's really important having mulitple random sounds in different locations like for example having 10 possible bird sounds in a forrest that can play randomly in different time intervals with random volume etc.

Also for example having nice transitions of soundtracks / music when entering a fight. Same for different music when entering different zones like different cities or houses.

Is this possible with your asset? How do you handle zones? Trough trigger colliders?
Do you support networking for example with Mirror?

Cheers
Ronny

[quote=“christoph_r”, post:9, topic: 727878]
These are definitely must-haves, I agree. By allowing users to also reference nested scriptable objects (not prefabs! nested scriptable objects have been possible for a long time) in the ‘classical’ unity way, you could let users create custom alternatives to string and/or addressables.
[/quote]

I’ll dig more into that, thanks!

[quote=“christoph_r”, post:9, topic: 727878]
That’s the thing where I’m a little confused - on a functional part, sound banks appear to have a sound bus. So it also appears to be a functional grouping? Other than that, I’m not sure I see the benefit over sounds being regular files which can be sorted into folders - and with an individually assigned sound bus, which would also be an asset file? As you said further down, it’s also a way of organizing things, and I personally think it’s not so great to bundle organizing assets and assigning functional information like a sound bus. Or am I missing something here?
[/quote]

Yup, a sound bank could have a few sound buses which are used not only to group sounds but also to control how many of them could be played simultaneously. Think of it as a sound collection + mixer.

The main reason why I decided to put everything in one place is ease of use because when you tune sound effects (especially if you delegate this job to another non-programmer person like composer or sound designer) it’s very important to keep all stuff in one place just to have a better overview. The fewer mouse clicks you need to make a change the better. And yes, that lacks some cool features that are native to the asset system like duplication, referencing, ids, etc.

I also thought it’s easier to organize and manage a large sound library within a few sound banks, just because you don’t have to remember every time where is the content. Please take note here that I’m looking from a sound designer perspective here (they tend to use DAWs with their sound libraries).

[quote=“christoph_r”, post:9, topic: 727878]
Quite interested to see how that turns out! In the meantime, it sounds like it would be simple enough to build a simple system on top of this asset by adding information how often a certain sound should be played.
[/quote]

You’re right! Sounds like an interesting task to research. Might possibly ship it in the next version.

[quote=“christoph_r”, post:9, topic: 727878]
Btw, sorry for seeming a bit negative or critical - this is actually because I think it’s a good approach and I’m very interested :slight_smile:
[/quote]

That’s why I created this thread in the first place — to get user feedback and suggestions so thank you so much!

By the way, if I gave you a voucher for the asset would you use it and give me detailed feedback?

[quote=“RonnyDance”, post:10, topic: 727878]
Looks good.
I am searching for a Soundsystem for my MMO. Thats why for me it’s really important having mulitple random sounds in different locations like for example having 10 possible bird sounds in a forrest that can play randomly in different time intervals with random volume etc.
[/quote]

There is no special component like “Soundspace” or “Environment sounds”, however, it’s really easy to build such a thing on top of Stem. All you need to do is to create a sound bank, organize sounds within the bank, create a “Soundscape” C# script and then use “Stem.SoundManager.Play” to play one-shot sounds. Stem will do the rest.

Within the sound bank, you can group sounds to sound buses. In every sound bus, it’s possible to set the maximum allowed simultaneously playing sounds. That way you can control your sound scene.

[quote=“RonnyDance”, post:10, topic: 727878]
Also for example having nice transitions of soundtracks / music when entering a fight. Same for different music when entering different zones like different cities or houses.

Is this possible with your asset? How do you handle zones? Trough trigger colliders?
[/quote]

In Stem it’s possible to create music banks where you organize music into playlists. Each music bank can have multiple music players with individual volume & playbacks controls. For example, you can create multiple playlists (like “peaceful ost”, “battle ost”, “zone1 ambience”, “zone2 ambience”, etc.) and two music players (like “music” and “environment”) as well as set the crossfade duration. Then it’s up to you which playlist to set in both music players.

[quote=“RonnyDance”, post:10, topic: 727878]
Do you support networking for example with Mirror?
[/quote]

Could you be more specific of what you’re trying to achieve?

[quote=“aviktorov”, post:11, topic: 727878]
I’ll dig more into that, thanks!
[/quote]

Not sure if you’re familiar with it already - but AddObjectToAsset is essentially what I was thinking/talking about - now that I think about it, I must admit I haven’t tried out yet whether nested assets can be made addressable though…

[quote=“aviktorov”, post:11, topic: 727878]
I also thought it’s easier to organize and manage a large sound library within a few sound banks, just because you don’t have to remember every time where is the content. Please take note here that I’m looking from a sound designer perspective here (they tend to use DAWs with their sound libraries).
[/quote]

Ah, good point - you’re of course right that it’s a good idea to stick with conventions of other sound middlewares to make it easier to learn for sound designers.

[quote=“aviktorov”, post:11, topic: 727878]
That’s why I created this thread in the first place — to get user feedback and suggestions so thank you so much!

By the way, if I gave you a voucher for the asset would you use it and give me detailed feedback?
[/quote]

Definitely! I happen to be working on a small-ish project right now that would be a great testbed. I’d also try my hand at creating a small soundscape system on top of it. Plus I’m curious to see how nicely it can be integrated with some of the other architectural stuff I’m using, like dependency injection and a ScriptableObject database. So, yeah, I’m definitely interested!

[quote=“christoph_r”, post:13, topic: 727878]
Definitely! I happen to be working on a small-ish project right now that would be a great testbed. I’d also try my hand at creating a small soundscape system on top of it. Plus I’m curious to see how nicely it can be integrated with some of the other architectural stuff I’m using, like dependency injection and a ScriptableObject database. So, yeah, I’m definitely interested!
[/quote]

Sent the voucher, check your conversations. Please leave any feedback here even if it’s not good. I’d very appreciate if you leave as many details as you can. Thanks again!

Ok, so bug is:
when I create my own sound bank and call:
Stem.SoundManager.Play("Coin");
I get error of null at
(class = SoundBusRuntime, line 95) -> oldestSound.Sound = sound;
BUT
when i use your bank from sample and and there "Coin" - it work...
Unity 2018.3.4f1.
Sorry but i dont have time to fix it for you :/
I do it few times with documentation, repo 100%.

SS from hierarchy:
4218178--374539--upload_2019-2-15_0-11-33.png

Ah. I'm having the same issue but I thought I broke it by my tinkering - so I didn't report it because I didn't manage to look into it yet further. On a quick glance it seems to be somehow tied to the sound banks - calling a sound from one of the sample sound banks works just fine, but fails with a custom sound bank. Seems quite weird that for custom sound banks the buses don't seem to get set up right?

[quote=“ArkadiuszR”, post:15, topic: 727878]
Ok, so bug is:
when I create my own sound bank and call:
Stem.SoundManager.Play(“Coin”);
I get error of null at
(class = SoundBusRuntime, line 95) → oldestSound.Sound = sound;
BUT
when i use your bank from sample and and there “Coin” - it work…
Unity 2018.3.4f1.
Sorry but i dont have time to fix it for you :confused:
I do it few times with documentation, repo 100%.
[/quote]

Thanks for report! Will send the fix ASAP.

1 Like

[quote=“ArkadiuszR”, post:15, topic: 727878]
Ok, so bug is:
when I create my own sound bank and call:
Stem.SoundManager.Play(“Coin”);
I get error of null at
(class = SoundBusRuntime, line 95) → oldestSound.Sound = sound;
BUT
when i use your bank from sample and and there “Coin” - it work…
Unity 2018.3.4f1.
Sorry but i dont have time to fix it for you :confused:
I do it few times with documentation, repo 100%.
[/quote]

Fixed. Please check your email for updated source code. The new version will be available soon on the asset store.

1 Like

After tinkering with this for a bit my thoughts so far are:

  • The source code is clean and well commented. Definitely above common asset store code quality.
  • As can be seen in this thread, @aviktorov replies quickly and has patched the asset. I assume these to be initial woes but can't comment much yet on how stable/reliable it is because I haven't tested the asset in-depth for a longer time.
  • It's refreshingly simple to play a sound (once you have your sound bank(s) ready). It really reduces the amount of boilerplate setup and/or code around audio management.

  • Setting up sound banks is very quick and straightforward too and has a handy multi-audioclip import option

  • I haven't played around with the music manager yet, but based from my experience so far I'm looking forward to it.

My personal suggestions/wishes:

  • The "edit" button for the foldout is a bit inconvenient as it breaks unity UI convention. I'm used to opening foldouts with the default arrow toggles in the inspector. Having to click that edit button still frequently requires conscious thought to do, which is slightly annoying.

  • Since sounds and buses are quite strictly tied to banks, I'd like to have more than one "primary bank". With the suggested use of "sound skins", I wouldn't necessarily want to swap out my entire bank of game sounds if I just want to change the sound set the UI is using.

  • An option to play/test single sounds & variations from the inspector to finetune pitch and volume variations

As pointed out above, for a larger projects with stricter rules on software/project architecture it would be great to:

  • Reference sounds through something other than a string (ideally directly?), and by extension, be able to play a sound directly by reference. Maybe also the ability to specify buses outside of banks (and the ability to assign them to sounds.) I use a ScriptableObject based database and it would suit my workflow a lot better if I could just assign sounds there. It seems an ID system is already in the works, though!
  • I do get that the system with buses is designed with audio designers in mind, but as an allround dev it would feel more flexible, powerful and convenient if I didn't have to use banks on top of the core components of sounds and buses. It feels like it's a layer on top that could easily be stripped, but despite the code being well written and commented, the "automagical" setup and static API makes it a bit tricky to quickly create a workaround for that.

  • While I think that for smaller projects/teams who aren't as fixated on their architecture the setup is perfectly fine (and should stay the default), it would be nice to have an easy way to control the setup & lifetime of the stem manager, i. e. allowing devs to set it up ourselves via dependency injection, allowing devs more control over which sound banks are loaded etc. This is personal preference regarding architecture, though, and not a shortcoming of the asset per se.

Even though it may seem like there's a lot of things I'd like changed, it's because I like the other stuff about this asset enough so far that I'd love to use it for larger projects with these requirements as well :)

1 Like

Thanks a lot for suggestions! This would definitely affect Stem architecture in a good way.

P.S. Thanks to William Chyr, I'm currently watching how the music system is implemented in Manifold Garden, the video has so many insights on requirements, problems and solutions!

https://www.youtube.com/watch?v=efifZwwcXtA

1 Like