Pepper.SFX
All Guidance pages

Guidance / API reference

AudioContainer (Base)

Namespace: AudioSystem Inheritance: ScriptableObject Abstract: Yes (use specific container types)

Properties

public string ContainerName { get; }
public string Description { get; }
public List<string> Tags { get; }
public AudioMixerGroup MixerGroup { get; set; }
public bool Is3D { get; }
public float MinDistance { get; }
public float MaxDistance { get; set; }      // the setter writes a runtime override, never the asset
public AudioRolloffMode RolloffMode { get; }
public AudioAttenuation Attenuation { get; } // a shared distance asset (a runtime override first); replaces the three above
public float DopplerLevel { get; set; }     // Unity's Doppler on 3D voices: 1 = Unity's default, 0 = none (0–5)
public DopplerMode Doppler { get; set; }    // Unity (default: DopplerLevel) or Pepper
public float DopplerExaggeration { get; set; }  // Pepper Doppler: ×1–3
public float DopplerMaxCents { get; set; }      // Pepper Doppler: the largest shift either way (0–2400 cents)
public float PitchLimitSemitones { get; }   // 0 = no limit; see PitchStack
public bool HasOverrides { get; }
public bool UsesParentPositioning { get; set; }  // inside a Blend or Switch: take the parent's 3D settings
public bool UsesParentOutput { get; set; }       // inside a Blend or Switch: play through the parent's Mixer Group
public List<ParameterCurve> ParameterCurves { get; }  // volume, pitch and filters driven by parameters

ParameterCurves: see ParameterCurve. A container with curves makes its plays update every frame.

DopplerLevel (inspector: Doppler Level, in 3D Settings) is written to every 3D voice’s AudioSource.dopplerLevel while Doppler is Unity; the pool puts 1 back. Unity’s Doppler changes a voice’s speed without Pepper seeing it, so a virtual voice can’t follow it: on looping layers that must stay in step (engine layers) use Pepper’s Doppler, or set 0. The Sound Builder’s Doppler Level slider writes it.

Doppler (3.1.0-dev.7; inspector: Doppler, with Doppler Exaggeration and Doppler Max Cents): with DopplerMode.Pepper, Unity’s Doppler Level is 0 on the voices and Pepper writes PitchStack.Doppler every step: ratio = c ÷ (c − v), c = 343 m/s, v the play’s closing speed on the listening point (its Approach Speed: the emitter’s velocity, or the play’s measured motion, against the point’s, eased over 50 ms), in cents × DopplerExaggeration, clamped to ± DopplerMaxCents. A play using it joins the per-frame pass. 50 m/s relative swings about 5.1 semitones at ×1. It is applied after the Pitch Limit and kept in a virtual voice’s place. See DopplerMath.

UsesParentPositioning and UsesParentOutput (inspector: Parent Settings) are off by default. When on, a container played inside a Blend or Switch uses that parent’s 3D settings (3D on or off, Min/Max Distance, Rolloff, Doppler Level, Doppler and its two settings) or Mixer Group instead of its own; if the parent passes the question on too, it goes up the play’s tree until a container answers it. A container’s own occlusion, reverb and propagation options always apply. A Blend’s or Switch’s own settings otherwise never reach its children.

Routing / Slot Pool Opt-Ins

public bool UseOcclusion { get; }          // raycast occlusion
public bool UsePropagation { get; }        // propagation cutoff (composes with raycast via min-wins)
public bool AllowReverbSend { get; }       // per-zone reverb sends
public float ReverbSendLevelDb { get; }    // per-container reverb send level (dB)
public bool StaticEmitter { get; }         // hint: this voice doesn't move during playback
public ReverbSendBus ExplicitReverbBus { get; }  // override zone-driven send routing

Setting any of UseOcclusion, UsePropagation, or AllowReverbSend to true causes the container to acquire an OcclusionSlot at play time. The slot carries the low-pass and the reverb sends; occlusion’s and propagation’s volume drop is written to the voice and applies even when no slot is available. See Manual chapter 14 for the slot pool architecture and chapter 15 for per-zone reverb sends.

StaticEmitter and ExplicitReverbBus are modifiers, not feature flags — they refine the behavior of the reverb-send driver but don’t on their own cause a slot to be acquired.


Methods

Play

public abstract AudioVoice Play(Vector3 position = default, GameObject parent = null)
public AudioVoice Play(Vector3 position, GameObject parent, List<AudioVoice> spawned)

Description: Plays the container. Containers that start several voices at once (a Routing container with more than one clip, every layer of a Blend, whatever a Switch selects) start all of them in both overloads. The first overload returns only the primary (first) voice. The second also appends every voice it started to spawned, primary first. Use the second when you need to control the whole sound. It also sets AudioVoice.RootContainer to this container on each of those voices.

Returns: The primary AudioVoice, or null if nothing played.

Custom containers: override the single-voice Play. If your container starts several voices per play, also override protected virtual AudioVoice PlayInto(List<AudioVoice> spawned, Vector3 position, GameObject parent), and implement the single-voice Play as Play(position, parent, new List<AudioVoice>()). Override EstimateVoiceCount too (below).

EstimateVoiceCount

public virtual int EstimateVoiceCount()

Description: How many voices one play of this container starts at once, at most. An event makes room for this many before it plays the container, and skips the play without stealing anything if it can’t. 1 by default (a Sequence plays one clip at a time); a Routing container counts its entries with a clip or an address, a Blend adds up its layers’ estimates, a Switch takes the largest of its choices. A play that starts more voices than its estimate still gets them, each stealing a whole play if the pool is full.

One play, one start time. All the voices a play starts are scheduled on one DSP time: one buffer ahead for a single voice, two for a play of several (so a walk through many layers can’t straddle a buffer), or the post’s explicit DSP time. A voice a container starts later (a Sequence’s next clip) starts one buffer ahead of when it starts.

Stop / StopImmediate

public abstract void Stop()
public abstract void StopImmediate()

Description: Stops every play of this container asset (with or without fade), including paused and virtualized voices. A SequenceContainer also ends its auto-advance run. Only voices the container still owns are stopped; a voice that has since been reused by another sound is left alone. To stop one play, stop its AudioHandle.

Concurrent plays: every container can be playing several times at once. BlendContainer used to stop its previous play on every post; it no longer does (set Max Instances 1 on the event to restart instead). A SequenceContainer keeps one position and one auto-advance run per asset; see USER_GUIDE §4.4.

Runtime Override Methods

public void SetOverride(ContainerOverrides overrides)
public void SetOverride3D(bool value)
public void ClearOverrides()

Description: Apply or clear non-serialized runtime 3D setting overrides. These do not persist to the asset.

Example:

// Override 3D settings at runtime
var overrides = new AudioContainer.ContainerOverrides
{
    is3D = true,
    minDistance = 2f,
    maxDistance = 30f
};
myContainer.SetOverride(overrides);

// Or just toggle 3D
myContainer.SetOverride3D(true);

// Clear all overrides
myContainer.ClearOverrides();

Voice Query Methods

public AudioSource GetFirstActiveSource()
public bool HasActiveVoices()
public int GetActiveVoiceCount()

Description: Query the state of voices currently playing from this container.


ContainerOverrides (Nested Struct)

public struct ContainerOverrides
{
    public bool? is3D;
    public float? minDistance;
    public float? maxDistance;
    public AudioRolloffMode? rolloffMode;
    public AudioAttenuation attenuation;   // in place of the container's own (null = no override)
    public void Clear();
}

Overrides are never saved to the asset. MaxDistance’s setter writes maxDistance here.

From the Pepper.SFX 3.1 guides (API_REFERENCE.md). Something wrong or unclear? Tell me.