Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Audio mixers #5554

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open

Audio mixers #5554

wants to merge 1 commit into from

Conversation

stalengd
Copy link
Contributor

@stalengd stalengd commented Dec 8, 2024

What

Brings audio mixers functionality to the engine similar how they works in unity or generally any other software I believe. Thus:

  • The audio source can be assigned to the mixer, which will modify its parameters, only gain at this moment.
  • Mixers can be also hooked up to one another to create hierarchy and modify each other's output.
  • Mixer's gain can be loaded and saved to CVar.
  • Mixers can be configured from prototypes.
  • Custom mixers can be created at runtime from client or server.
  • Both entity-based and plain object mixers for places where entities are a no-go (e.g. user interface).

Why

Fixes #5462 and space-wizards/space-station-14#22710, corresponding PR to SS14 will fix some other issues there, generally a must-have tool for the engine.

Technical details

Underlying tech

This audio mixers implementation does not use OpenAL auxiliary slots (if they even can be used to implement this) or any other fancy low-level stuff. Instead, simple mechanism of storing references in mixers and sources to each other is used, and when gain of any mixer is changed, all connected mixers and sources modify their gain value (see AudioMixer.cs). However, I see no problems to seamlessly re-implement internal work of audio mixers to use OpenAL auxiliary later, this will need to be done to support the audio mixer effects as well.

MixableAudioSource

I did not dare to put mixers support into AudioSource, since it is a rather thin interface with OpenAL, so the MixableAudioSource wrapper is used to support audio mixers. AudioComponent has now reference to IMixableAudioSource, not IAudioSource.

Audio mixer prototypes

This is a way to have "audio categories", game can define any number of mixer prototypes and use their IDs to assign corresponding mixer to audio sources. This replaces dubious pattern of handling subscriptions to CVars for every source and for the most cases this is nearly impossible to do manually. "Prototyped" audio mixers can be assigned via AudioParams, so it is really easy to manage. There are also a problem of many sources not having any mixers assigned at the moment in SS14, but customizable default mixer can be handy in this case.

Plain object mixers

AudioMixer is a plain object and AudioSource counterpart, so exists only on client side and managed by AudioMixersManager. Manager creates custom mixers and stores mixers from prototypes, so only one AudioMixer instance corresponding to any AudioMixerPrototype id can exist.

Entity-based mixers

AudioMixerComponent is a counterpart of AudioComponent and they are used together. Mixer component on client obtains reference to plain object mixer and system will assign this mixer to internal audio source component when needed. Mixer component fully supports synchronization, so can be assigned to audio sources on the server side, Mixer components are spawned on separate global entities.

Entity-based mixers from prototypes problem

The concept of "prototyped" mixers conflicts with entity-based mixers in terms of lifetimes.

My first implementation of this was lazily creating mixers for prototype when requested, newly created mixer then stored in dictionary indefinitely. Unfortunately, some SS14 integration tests does not like this idea when any entity creates more other entities than deletes after got deleted.

This implementation creates all mixer entities from prototypes at start of the simulation (check out the funny way how system knows when its time to spawn entities) and when entities flushed. Set of such entities exists separately on client and server though because single-player games may exist and (probably) entities from server may not be sent to the client fast enough. The problem with this implementation is that other SS14 integration test (DeleteAllThenGhost this time) can't handle that deleting all entities on the server leaves mixer entities on client.

So this problem is relevant and PR probably should not be merged like this, either mixers should be implemented differently (but I don't know how at this point) or SS14 integration tests should be adjusted.

Discussion

As you can see, there are plenty of debatable decisions in this PR, so maintainers may fell free to discuss and request changes to implementation here, or for quicker communication in discord (stalengd, DM or ping).

PR to SS14 repo

space-wizards/space-station-14#33816

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Need audio / sound categories
1 participant