Guidance / API reference
Enums & Data Structures
VoicePriority
public enum VoicePriority
{
Low = 0, // Least important: weighs 1/8
Medium = 64, // Standard priority: weighs 1/4
High = 128, // Important sounds: weighs 1/2
Critical = 255 // The strongest weight, 1: last to go, but still stealable (Persistent is the exemption)
}
A voice’s importance (AudioVoice.GetImportance) is how loud it is where it is heard times its priority’s weight: priority ÷ 255, but at least 1/8, so a Low sound’s distance and loudness count (since 3.1.0-dev.8; Low weighed 0, and always went first).
AudioSpatialMode
public enum AudioSpatialMode
{
Unity, // Unity's 3D from its AudioListener (default, as before 3.1)
Pepper // Pepper pans and attenuates from every listening point, weighted
}
AudioManager.SpatialMode (3.1.0-dev.8); see Listening Point Methods.
VoiceStealBehavior
public enum VoiceStealBehavior
{
Oldest, // Steal longest-playing voice
Quietest, // Steal quietest voice
Furthest, // Steal most distant voice
LowestPriority // Steal by priority only
}
MultiPositionType
public enum MultiPositionType
{
SingleEmitter, // Single voice, dynamically positioned at dominant emitter
Decorrelated // All emitters play with phase decorrelation
}
WeightedAudioClip
[Serializable]
public class WeightedAudioClip
{
public AudioClip clip;
public float weight = 1f; // Selection probability (0-10)
public float volumeMultiplier = 1f; // Per-clip volume (0-1)
}
SequenceEntry
[Serializable]
public class SequenceEntry
{
public AudioClip clip;
public float volumeMultiplier = 1f; // Per-clip volume
public bool loop = false; // Loop this clip
public float delayAfter = 0f; // Delay before next (0-5s)
}
SwitchEntry
[Serializable]
public class SwitchEntry
{
public string switchValue = ""; // Value to match
public AudioContainer container; // Container to play
}
ParameterSource
public enum ParameterSource { Game, Distance, ApproachSpeed, Angle } // AudioParameter.ValueFrom
AudioRandomSource
public enum AudioRandomSource { Pepper, Unity } // AudioManager.RandomNumbers
SwitchChangeMode, SwitchRange
public enum SwitchChangeMode { NextPlayOnly, Crossfade, Restart } // SwitchContainer.WhenSwitchChanges
[Serializable]
public struct SwitchRange // AudioSwitchGroup.Ranges
{
public string value; // the switch value in this range
public float from; // where it starts, in the driving parameter's unit
public SwitchRange(string value, float from)
}
BlendEntry
[Serializable]
public class BlendEntry
{
public AudioContainer container; // Layer container
public AnimationCurve volumeCurve = AnimationCurve.Linear(0,0,1,1); // VolumeCurves layout: value -> level (0-1).
// X: 0-1 for a named parameter, the
// asset's unit for a Parameter asset.
public float rootValue; // the value it was recorded at (pitch follow, Auto Layout); 0 = none
public float regionMin, regionMax; // Regions layout: where it plays
public float fadeInWidth, fadeOutWidth; // Regions layout: fade lengths inside the region
public bool followPitch = true; // pitch follow applies to this layer
public float followRangeSemitones = 12f; // pitch follow's limit, ±semitones
public List<ParameterCurve> curves; // curves for this layer only
}
ParameterCurve, CurveProperty
[Serializable]
public sealed class ParameterCurve
{
public AudioParameter parameter; // X axis; wins over parameterName
public string parameterName; // X axis by name (not clamped; 0 when unset)
public CurveProperty property; // VolumeDb, PitchCents, LowPassHz, HighPassHz
public AnimationCurve curve; // X: the parameter's unit; Y: dB, cents or Hz
public float Evaluate(float x); // filters: straight in octaves between keys
}
public enum CurveProperty { VolumeDb, PitchCents, LowPassHz, HighPassHz }
On AudioContainer.ParameterCurves (every sound below that container) or a BlendEntry’s curves (that layer). Read in the play’s scopes every frame. On one container, and down the tree: dB and cents add (into GainStack.CurveGain and PitchStack.Curve), the lowest low-pass and the highest high-pass win. Filter curves switch on the AudioLowPassFilter / AudioHighPassFilter every pooled voice has had, switched off, since the pool was built, ease the cutoff over about 20 ms (set at once before the first sample), and switch it off when fully open (22000 Hz / 10 Hz).
BlendLayout, CrossfadeShape, BlendLoopMode, SilentLayerBehaviour
public enum BlendLayout { VolumeCurves, Regions }
public enum CrossfadeShape { Linear, EqualPower, SCurve } // -6 dB, -3 dB, eased; each pair complementary
public enum BlendLoopMode { FromLayers, ForceLoop, ForceOneShot } // BlendContainer.LoopMode
public enum SilentLayerBehaviour { KeepPlaying, Virtualize } // BlendContainer.SilentLayers
SlewMode
public enum SlewMode
{
None, // heard at once
Rate, // fixed speed in units per second, rising and falling
Ease // closes 95% of the gap in a set time, rising and falling
}
See ParameterSlew.
AudioUpdateMode
public enum AudioUpdateMode
{
Automatic, // Pepper's per-frame step runs after every LateUpdate, before the audio is mixed
Manual // it runs only when you call AudioManager.Tick()
}
AudioStatistics
public class AudioStatistics
{
public int activeVoices; // real voices now
public int availableVoices; // free in the pool
public int totalVoices; // Max Real + Max Virtual
public int liveRealVoices; // every pooled AudioSource alive: playing, virtual or free
public int realVoiceBudget; // Max Real Voices
public int poolSize; // Max Real + Max Virtual + Steal Headroom: what liveRealVoices stays at
public int voicesLostToDestruction;
public int activeLoops;
public int registeredContainers;
}
Usage:
var stats = AudioManager.Instance.GetStatistics();
Debug.Log($"Real voices: {stats.activeVoices}/{stats.realVoiceBudget}, pool {stats.liveRealVoices}/{stats.poolSize}");
AudioVoiceDebugInfo
[Serializable]
public class AudioVoiceDebugInfo
{
public int id;
public string containerName;
public string eventName;
public string clipName;
public string busName;
public bool isPlaying;
public bool isVirtual;
public bool isLooping;
public float volume;
public float volumeDb;
public float pitch;
public float time;
public float length;
public float playTime;
public bool is3D;
public float distance;
public float distanceToListener;
public Vector3 position;
public AudioVoice voice;
public int priority;
public int playId; // one number per play: all of an engine's layers share it
public bool persistent;
public VoiceVirtualReason virtualReasonKind; // None while real
public string virtualReason; // its words, plus ", fading" while it fades down
public float levelDb; // its whole gain stack, in dB: Pepper's gain, before Unity's own 3D fade and the mixer ("Gain dB" in the windows)
public float pitchSemitones; // from the recording
public string region; // a Regions Blend layer's region and where the value is
public int listeningPoint; // its play's point, an index into ListeningPoints (-1: none) (3.1.0-dev.8)
public bool pepperPanned; // Spatial Mode = Pepper pans it
public float spatialGainDb; // Pepper's level from the points, dB
public float pan; // Pepper's pan, -1 left … 1 right
}
public enum VoiceVirtualReason
{
None, OverTheCap, SilentLayer, PastMaxDistance, HeldByCode, BusPaused, EmitterPaused, Stopping
}
public sealed class AudioPlayDebugInfo // AudioManager.GetPlaysDebug
{
public int playId;
public string eventName, containerName, busName;
public AudioEmitter emitter; // null: posted without one
public AudioHandle handle; // its own values: handle.ParameterCount and the listing beside it
public bool persistent, isVirtual;
public List<AudioVoiceDebugInfo> voices;
}
Why a voice is virtual (VoiceVirtualReason, checked in this order): Stopping (it ends once faded down), BusPaused (its bus or a parent is paused), EmitterPaused (its emitter is switched off with On Disable = Pause), HeldByCode (AudioVoice.MakeVirtual), PastMaxDistance (its Attenuation asset’s), SilentLayer (a Virtualize Blend’s layer below its threshold), else OverTheCap (more would be heard than Max Real Voices, and its play is among the least important).
Usage:
var voices = AudioManager.Instance.GetActiveVoicesDebug();
foreach (var v in voices)
Debug.Log($"{v.eventName}: {v.clipName} {v.levelDb:F1} dB {(v.isVirtual ? "virtual: " + v.virtualReason : "real")}"); From the Pepper.SFX 3.1 guides (API_REFERENCE.md). Something wrong or unclear? Tell me.