AmbienceSource

AmbienceSource is a MonoBehaviour component to play an Ambience.
How it works

When it plays an Ambience connected to the slot, each AmbienceLayer listed inside that asset gets a corresponding GameObject which runs the layer. The parent is the object with AmbienceSource.
You can clearly see them in Play Mode. (If "Layers Debugging" is still checked.)
On each child, you can inspect to see how each layer works :
- Looping Clip (LC) : An
AudioSourcewith Loop checked, playing a singleAudioClip. It potentially hasAnimationattached if you use automations. - One Shot Program (OSP) : An
AudioSourcewith noAudioClipassigned, stationed to be a target ofPlayOneShot. - Timeline (TL) : A
PlayableDirectorwithAmbienceLayerassigned, looping just that layer.
Where to attach AmbienceSource
As explained, the parent of corresponding child GameObject of each layer is the object with AmbienceSource.
Ambiences are usually positional on your scene, so it is a good idea to attach this to an object that would make the sound. Though, what determines positional or global nature of an ambience is the connected AudioSource, not AmbienceSource
Or you can create an empty object floating around the area that make sounds. e.g. an ambience representing groups of tree, you don't have any specific tree to attach.
Sometimes ambience can be global, such as constantly running wind ambience. In that case you can create an empty object at 0,0,0 and set the source to 2D.
Ambience

Attach an Ambience you want to play here. The component has Play method that use an asset connected to this slot, parallels to AudioSource and AudioClip.
Additionally, the component also has a Play overload that accepts any Ambience via scripting, ignoring this slot.
Play On Awake always use Ambience connected here. It is also the most popular use case, because usually you don't manually want to tell the trees and rivers to start playing audio. Ambience is a part of scene design and you want to do as many things as possible without scripting.
Audio Source
The AudioSource field will become an output for all AmbienceLayer.
Where to attach AudioSource
The AudioSource component is usually attached right next to this AmbienceSource component, though this component does not force you to do so. Just don't forget to connect the AudioSource or it won't work.
How it works
Exact implementation differs between layer modes :
Looping Clip : The
AudioSourceacts as a template. Each layer gets a personal copy ofAudioSourcewith inherited values from the template on play.The personal copy of
AudioSourcecan have Volume, Pitch, and Stereo Pan animated live via additionalAnimationcomponent, due to automations.One Shot Program : Again, the
AudioSourceacts as a template. Each layer gets a personal copy ofAudioSourcewith inherited values from the template on play.The personal copy is the target of
PlayOneShot. The reason why we cannotPlayOneShotdirectly on the template is that pitch adjustment is shared for all shots played on that source. Each ourAmbienceLayercan have different Speed (Pitch) Adjustment.Timeline : The
AudioSourceis a binding target for everyAudioTrackthatPlayableDirectoris directing. Timeline layers do not get a personal copy ofAudioSourcebut directly output audio stream to it.
Useful settings

You need not to worry about ticking Loop, it will be ticked for you when the recipient layer is on Looping Clip. AudioClip can always be left empty. Play On Awake does not matter, as we have our own Play On Awake on the AmbienceSource.
While you can set any other settings you want, there are some settings that ambience author likely wants to do :
- Output : It is very useful to have an
AudioMixerGroupexclusively for ambiences in your project. After directing all ambiences in the game to one mixer, you can then fade everything out smoothly, for example. - Priority : Unity has a maximum limit of concurrent audio for mixing, which at that point it will begin cutting out sounds. Priority of ambiences likely needs to be 0 (the same as BGM). Otherwise, it is possible for the player to perform attacks so rapidly that it permanently removes forest ambience...
- Volume, Pitch, Stereo Pan : These are inherited on top of what the layer wants to do. Normally you will adjust these on
Ambienceadjustments, or adjust on theAmbienceLayerdirectly and leave these at1,1, and0respectively. - Spatial Blend : This starts at 2D. But ambiences are often positional (3D) so set it accordingly, unless it is an ambience that affects an entire scene.
- Reverb Zone Mix : Unity Audio Effects is quite useful for ambiences! It can blends together your field recordings to be more cohesive. Something that maybe annoying to get reverbs like wind ambience can get different mix by this settings.
- 3D Sound Settings : When ambience is positional, you will want to tune how close the player (
AudioListener) has to be to hear the audio. Very important settings if Spatial Blend is 3D. This deserves its own page here : Advanced/3D Sound Settings.
Time Source
Choose from :
- Unscaled : Nothing happens to the ambience when you change
Time.timeScale. This is howAudioSourceworks by default. - Scaled : Ambience speed up and slow down together with
Time.timeScale. (Which is weird, but I learned from both Introloop and Native Audio customers that someone will eventually ask for it...)
Implementation details is described in Advanced/Time Source.
Adjusting "master volume"
You may occasionally want to fade out the ambience instead of just stopping them. (If you fade them out a bit slower than BGM, that feels good too!)
The solution is on the Output field on your AudioSource that is connected with AmbienceSource. It let you specify AudioMixerGroup. All 3 kinds of layers can output to this mixer. After routing everything, you can then fade out on the mixer's fader, completely unrelated to Tiny Ambience now.
Scripting API
Methods you can call on AmbienceSource are as you typically expected from an audio player :
// Use the `Ambience` connected on the slot.
public void Play() { /** impl **/ }
public void Play(PlayOptions playOptions) { /** impl **/ }
// Ignores `Ambience` connected on the slot.
public void Play(Ambience a) { /** impl **/ }
public void Play(IAmbienceLayerProvider a) { /** impl **/ }
public void Play(Ambience a, PlayOptions playOptions) { /** impl **/ }
public void Play(IAmbienceLayerProvider a, PlayOptions playOptions) { /** impl **/ }
// Playback controls.
public void Stop() { /** impl **/ }
public void Pause() { /** impl **/ }
public void Resume() { /** impl **/ }
PlayOptions currently can't do anything, but they are there so I could add some special features without breaking your code in the future, like fast-forwarding to the virtual future time on start playing.
Also, IAmbienceLayerProvider is the same as Ambience right now. There is currently no other thing that could provide layers in the package.
UnityEvent targeting Play
This Play overload in particular is extra cool because if you connect UnityEvent to it, editor will draw a nice asset picker to pick your Ambience!
public void Play(Ambience a) { /** impl **/ }
It maybe useful in niche use case where one source may need to play many kinds of ambience, commanded by some other things on the scene.
[SerializeField] private UnityEvent eventTargetingPlay;

Bonus dynamic UnityEvent variations
UnityEvent is a cool class which the invoke target is serializable. UnityEvent<T> is even cooler as the invoker can specify arguments, making it dynamic instead of static. But a caveat is that Unity can't serialize generic classes, you must declare a new subclass that is solid.
The package provide some subclassed types which pairs with those Play overloads :
public class UnityEventAmbience
: UnityEvent<Ambience> { /** impl **/ }
public class UnityEventAmbienceWithOption
: UnityEvent<Ambience, PlayOptions> { /** impl **/ }
public class UnityEventAmbienceOnlyOption
: UnityEvent<PlayOptions> { /** impl **/ }