# Audio System

Audio in Unreal Engine covers SoundCues, MetaSounds, spatial audio, audio components, sound classes, and mixes.

## Architecture overview

The audio system is built on these core asset types:
- **SoundWave**: Raw imported audio file (WAV, OGG)
- **SoundCue**: Node-based audio graph for layering, randomization, and modulation
- **MetaSound Source** (UE5.1+): Next-generation procedural audio graph replacing SoundCues
- **MetaSound Patch**: Reusable audio sub-graph (analogous to Material Functions)
- **Sound Attenuation**: Settings asset controlling 3D falloff, spatialization, occlusion
- **Sound Concurrency**: Settings asset limiting simultaneous instances of a sound
- **Sound Class**: Category for volume grouping (Master, Music, SFX, Voice, Ambient, UI)
- **Sound Mix**: Modifier that adjusts Sound Class volumes (for game states like menus, combat)

## Adding audio components to Blueprints

To add an AudioComponent to a Blueprint's component hierarchy via Python:
1. Load the Blueprint asset
2. Access its SimpleConstructionScript (SCS)
3. Create a new SCS node for AudioComponent
4. Set the Sound property on the component template
5. Compile and save

Use `query_ue_api('AudioComponent')` to discover AudioComponent properties and methods. Use `dir()` on the loaded Blueprint and SCS objects to find available methods.

## Spawning sound actors in a level

To place an AmbientSound actor in a level via Python:
1. Use `query_ue_api('EditorActorSubsystem')` to find the actor spawning API
2. Spawn an AmbientSound actor at the desired location
3. Access its AudioComponent and set the Sound property
4. Set the actor label for identification

## Playing sounds at runtime (C++)

```cpp
// One-shot at location (fire-and-forget):
UGameplayStatics::PlaySoundAtLocation(this, SoundCue, GetActorLocation());

// One-shot 2D (UI sounds, music stingers):
UGameplayStatics::PlaySound2D(this, UIClickSound);

// Attached to component (follows actor):
UGameplayStatics::SpawnSoundAttached(
    FootstepSound, MeshComponent, NAME_None,
    FVector::ZeroVector, EAttachLocation::SnapToTarget,
    true,  // bStopWhenAttachedToDestroyed
    1.0f,  // VolumeMultiplier
    1.0f   // PitchMultiplier
);

// Persistent audio component:
AudioComp->SetSound(NewSound);
AudioComp->Play();
AudioComp->FadeIn(2.0f);          // Fade in over 2 seconds
AudioComp->FadeOut(1.0f, 0.0f);   // Fade out over 1 second to silence
AudioComp->Stop();
```

## Sound Attenuation (3D spatial audio)

```cpp
// Declare attenuation settings reference:
UPROPERTY(EditDefaultsOnly, Category = "Audio")
USoundAttenuation* AttenuationSettings;
```

Key attenuation properties (configured on the asset):
- **Inner Radius**: full volume within this distance
- **Falloff Distance**: distance over which sound fades to silence
- **Attenuation Shape**: Sphere, Capsule, Box, or Cone
- **Spatialization**: enable for 3D positioning (binaural, HRTF)

When setting attenuation on an AudioComponent via Python, use `set_editor_property('attenuation_settings', loaded_attenuation_asset)`.

## Sound Concurrency

```cpp
// Limit simultaneous instances of a sound:
UPROPERTY(EditDefaultsOnly, Category = "Audio")
USoundConcurrency* ConcurrencySettings;
// Key properties: MaxCount, ResolutionRule (StopOldest, StopLowest, etc.)
```

## MetaSound concepts (UE5.1+)

MetaSounds are a graph-based procedural audio authoring system. Key concepts:
- **MetaSound Source**: Playable audio asset (use in place of SoundCue for procedural audio)
- **MetaSound Patch**: Reusable audio graph fragment
- **Triggers**: Input events that fire audio behaviors within the graph
- **Audio Parameters**: Typed inputs (Float, Int, Bool, Trigger) controllable from gameplay code

MetaSound assets are typically created in the Content Browser. To reference an existing MetaSound from Python, load it with `load_asset` and verify it loaded successfully before assigning it.

## Audio parameters at runtime (C++)

```cpp
// Set MetaSound/SoundCue parameter:
AudioComp->SetFloatParameter(FName("Intensity"), 0.8f);
AudioComp->SetIntParameter(FName("SurfaceType"), 2);
AudioComp->SetBoolParameter(FName("IsRunning"), true);

// Trigger (MetaSound only):
AudioComp->SetTriggerParameter(FName("OnHit"));
```

## Sound Classes and Mixes (C++)

```cpp
// Sound Classes group sounds for volume control:
// Categories: Master, Music, SFX, Voice, Ambient, UI

// Override a sound class volume at runtime:
UGameplayStatics::SetSoundMixClassOverride(
    GetWorld(), MasterSoundMix, MusicSoundClass,
    0.5f,  // Volume
    1.0f,  // Pitch
    0.5f   // FadeInTime
);

// Activate a Sound Mix:
UGameplayStatics::PushSoundMixModifier(GetWorld(), MasterSoundMix);
```

## Naming conventions
- A_ prefix for generic audio assets: A_Fire_Loop, A_Explosion
- SC_ prefix for SoundCues: SC_Footstep, SC_WeaponFire
- MS_ prefix for MetaSounds: MS_Footstep, MS_Engine
- SA_ prefix for Sound Attenuation: SA_Weapon, SA_Ambient
- SMix_ prefix for Sound Mixes: SMix_InMenu, SMix_Combat

## Common audio patterns for games
- **Footsteps**: Physical material -> surface type -> select random sound variation
- **Music system**: Layered stems with crossfade, controlled by game state
- **Ambient**: Looping ambient audio with randomized one-shots via Sound Concurrency
- **Weapons**: Fire -> tail -> echo chain, with concurrency limits
- **UI**: 2D non-spatial sounds for clicks, hovers, notifications
- **Dialogue**: Voice with subtitle system, concurrency=1 per speaker

## Critical rules
- Always verify sound assets exist before assigning them (check load_asset result is not None)
- Use Sound Attenuation for all 3D gameplay sounds — never play 3D without attenuation
- Limit concurrent sounds with Sound Concurrency to prevent audio overload
- Use Sound Classes for volume categories (Music, SFX, Voice) — never hard-code volumes
- MetaSounds require "MetasoundEngine" in Build.cs dependencies
- Use `query_ue_api('AudioComponent')` or `query_ue_api('SoundCue play')` to discover audio-related classes and functions
- Use `dir()` on audio objects in Python to discover available properties and methods at runtime
