MCPInstall

ue-audio-system

Use when playing, mixing or debugging sound in Unreal Engine — one-shot SFX, looping ambience, music, dialogue or procedural audio. Also use when the user mentions 'UAudioComponent', 'PlaySoundAtLocation', 'SpawnSoundAttached', 'SoundCue', 'MetaSound', 'UMetaSoundSource', 'SetFloatParameter', 'sound attenuation', 'spatialization', 'occlusion', 'sound concurrency', 'submix', 'audio bus', 'sound mix', 'SetSubmixOutputVolume', 'reverb', 'Quartz', 'audio modulation' or 'subtitles'. For VFX timing, see ue-niagara-effects; for anim-notify sounds, see ue-animation-system; for component lifetime and attachment, see ue-actor-component-architecture.

Installs
1.1K
Last 24h
+12
Trending rank
#8037
Security
Not audited

Install

Works with every agent the skills CLI supports.

npx skills add https://github.com/quodsoler/unreal-engine-skills --skill ue-audio-system
  1. 01

    Install

    Run the command in your project. The CLI asks which agents to install for.

  2. 02

    Describe the task

    Ask your agent for something this skill covers. It loads ue-audio-system automatically when relevant.

  3. 03

    Review the result

    The agent follows the SKILL.md steps, scripts and references bundled with the skill.

SKILL.md

The instructions your agent reads when the skill is triggered.

UE Audio System

Target engine: UE 5.8. APIs below are verified against the 5.8 headers; older forms are listed under "Deprecated — do not use".

Covers sound assets, playback from C++, attenuation, concurrency, sound classes and mixes, submix/bus routing, MetaSounds, modulation, Quartz and analysis. Engine-side code lives in Engine/Classes/Sound and Components/AudioComponent.h (module Engine), the mixer in AudioMixer, and the parameter interface in AudioExtensions. Plugin modules: MetasoundEngine / MetasoundFrontend (MetaSounds), AudioModulation, AudioSynesthesia (Beta in 5.8), SubtitlesAndClosedCaptions (Beta in 5.8).

// MyGame.Build.cs
PublicDependencyModuleNames.AddRange(new string[] { "Engine", "AudioMixer", "AudioExtensions" });
PrivateDependencyModuleNames.AddRange(new string[] { "MetasoundEngine", "MetasoundFrontend", "AudioModulation" });

Context

Read .agents/ue-project-context.md if it exists (module names, conventions, enabled plugins, GAS/networking setup). Do not stop if it is missing.

Identify the area from the request and the codebase. Ask only when two plausible readings would produce different code.

Request is about…Go to
Which asset type to author (wave, cue, MetaSound), streamingSound Assets
Firing a sound from gameplay codePlaying Sounds
Fades, pause, volume/pitch, finish callbacks, per-instance sendsUAudioComponent Control
Falloff, 3D panning, HRTF, occlusion, reverb send, focusAttenuation and Spatialization
Too many voices, footsteps/gunshots stacking, voice stealingConcurrency
Volume sliders by category, ducking, context mixesSound Classes and Sound Mixes
Routing groups, master volume, audio buses, sidechain sourcesSubmixes, Buses and Sends
Reverb, EQ, compression on a group of soundsSubmix Effects
Procedural/adaptive audio, runtime parameters, graph buildingMetaSounds
Continuous parameter control from gameplay curves/LFOsModulation
Beat-synced stingers, tempo, musical quantizationQuartz Music Sync
Reacting to audio (FFT, envelope, offline beat maps)Analysis
Captions, dialogue textSubtitles
Mobile voice budgets, dedicated servers, backgrounding, VRPlatform Notes
Full worked systems (music manager, ambience, weapon audio)audio setup patterns

Sound Assets

USoundBase                    // abstract base (Sound/SoundBase.h)
  ├── USoundWave              // imported PCM/compressed asset (Sound/SoundWave.h)
  │     └── USoundSourceBus   // sonifies a UAudioBus (Sound/SoundSourceBus.h)
  ├── USoundCue               // node graph (Sound/SoundCue.h)
  └── UMetaSoundSource        // procedural graph, derives USoundWaveProcedural

Key USoundBase fields set on every asset: SoundClassObject, AttenuationSettings, ConcurrencySet (or ConcurrencyOverrides with bOverrideConcurrency), Priority (higher survives voice culling), SoundSubmixObject, SoundSubmixSends, BusSends / PreEffectBusSends / PostAttenuationBusSends, VirtualizationMode.

USoundCue nodes: USoundNodeRandom, USoundNodeModulator, USoundNodeMixer, USoundNodeAttenuation, USoundNodeLooping, USoundNodeDelay, USoundNodeDistanceCrossFade, USoundNodeConcatenator, USoundNodeSwitch, USoundNodeWavePlayer. USoundWave::LoadingBehavior (ESoundWaveLoadingBehavior, Sound/SoundWaveLoadingBehavior.h): Inherited, RetainOnLoad, PrimeOnLoad, LoadOnDemand, ForceInline. Use ForceInline for short SFX, LoadOnDemand for long music so minutes of audio never sit resident. Read it with GetLoadingBehavior(bCheckSoundClasses); override at runtime with OverrideLoadingBehavior(ESoundWaveLoadingBehavior::LoadOnDemand).

CriterionUSoundCueUMetaSoundSource
Runtime parametersWave params onlyTyped inputs (float, bool, int32, string, object, trigger)
Procedural DSPNoYes (oscillators, noise, filters)
Built at runtime from C++NoYes — UMetaSoundBuilderSubsystem
Use forRandomized pre-authored one-shotsAdaptive music, state-driven and synthesized SFX

Playing Sounds

All functions are UGameplayStatics statics in Kismet/GameplayStatics.h. Never call them on a dedicated server.

#include "Kismet/GameplayStatics.h"   // + Components/SkeletalMeshComponent.h for GetMesh() below
// PlaySound2D(WorldContext, Sound, Volume=1, Pitch=1, StartTime=0,
//             Concurrency=nullptr, OwningActor=nullptr, bIsUISound=true) — UI, music; no handle
UGameplayStatics::PlaySound2D(this, MenuSelectSound, 1.0f, 1.0f, 0.0f, nullptr, nullptr, true);

// PlaySoundAtLocation(WorldContext, Sound, Location, Rotation, Volume=1, Pitch=1, StartTime=0,
//                     Attenuation=nullptr, Concurrency=nullptr, OwningActor=nullptr, InitialParams=nullptr)
UGameplayStatics::PlaySoundAtLocation(this, GunShotSound, GetActorLocation(), FRotator::ZeroRotator,
    1.0f, 1.0f, 0.0f, WeaponAttenuation, FireConcurrency, this);

// SpawnSoundAtLocation(WorldContext, Sound, Location, Rotation=ZeroRotator, Volume=1, Pitch=1,
//                      StartTime=0, Attenuation=nullptr, Concurrency=nullptr, bAutoDestroy=true)
UAudioComponent* Boom = UGameplayStatics::SpawnSoundAtLocation(this, ExplosionSound, Location,
    FRotator::ZeroRotator, 1.0f, 1.0f, 0.0f, ExplosionAttenuation, nullptr, true);

// SpawnSoundAttached(Sound, AttachToComponent, AttachPointName=NAME_None, Location=FVector(ForceInit),
//                    Rotation=ZeroRotator, LocationType=EAttachLocation::KeepRelativeOffset,
//                    bStopWhenAttachedToDestroyed=false, Volume=1, Pitch=1, StartTime=0,
//                    Attenuation=nullptr, Concurrency=nullptr, bAutoDestroy=true)
UAudioComponent* EngineAudio = UGameplayStatics::SpawnSoundAttached(EngineLoopSound, GetMesh(),
    TEXT("AudioSocket"), FVector::ZeroVector, FRotator::ZeroRotator,
    EAttachLocation::SnapToTarget, /*bStopWhenAttachedToDestroyed=*/true,
    1.0f, 1.0f, 0.0f, EngineAttenuation, nullptr, /*bAutoDestroy=*/false);

OwningActor is what per-owner concurrency (bLimitToOwner) keys on — pass it whenever the sound belongs to an actor. SpawnSound2D has the same leading arguments as PlaySound2D but ends in bPersistAcrossLevelTransition, bAutoDestroy (no OwningActor/bIsUISound) and returns a component; CreateSound2D takes the same arguments as SpawnSound2D but returns a component that is not playing — call Play() yourself.

Choose: fire-and-forget for one-shots, a spawned handle for anything you must fade, stop or re-parameterise, and a CreateDefaultSubobject<UAudioComponent> member for a permanent per-actor loop.

UAudioComponent Control

UAudioComponent (Components/AudioComponent.h) derives USceneComponent and implements ISoundParameterControllerInterface.

// Constructor
AudioComponent = CreateDefaultSubobject<UAudioComponent>(TEXT("AudioComponent"));
AudioComponent->SetupAttachment(RootComponent);
AudioComponent->bAutoActivate = false;
AudioComponent->bStopWhenOwnerDestroyed = true;
AudioComponent->bIsUISound = false;   // true = keeps playing while the game is paused

// Playback — EAudioFaderCurve: Linear, Logarithmic, SCurve, Sin
AudioComponent->SetSound(EngineLoopSound);
AudioComponent->Play(/*StartTime=*/0.0f);
AudioComponent->FadeIn(0.5f, /*FadeVolumeLevel=*/1.0f, /*StartTime=*/0.0f, EAudioFaderCurve::Linear);
AudioComponent->AdjustVolume(/*Duration=*/0.25f, /*Level=*/0.3f, EAudioFaderCurve::Linear);
AudioComponent->FadeOut(1.0f, /*FadeVolumeLevel=*/0.0f, EAudioFaderCurve::Linear);
AudioComponent->SetVolumeMultiplier(0.5f);
AudioComponent->SetPitchMultiplier(1.2f);
AudioComponent->SetPaused(true);
AudioComponent->Stop();

const bool bPlaying = AudioComponent->IsPlaying();
// EAudioComponentPlayState: Playing, Stopped, Paused, FadingIn, FadingOut
const EAudioComponentPlayState State = AudioComponent->GetPlayState();

Per-instance routing and filtering, without touching the asset: SetSubmixSend(USoundSubmixBase*, float), SetSourceBusSendPreEffect / PostEffect / PostAttenuation, SetAudioBusSendPostEffect, SetLowPassFilterEnabled / SetLowPassFilterFrequency, the matching high-pass pair, and SetOutputToBusOnly. For inline attenuation, set bOverrideAttenuation = true and fill AttenuationOverrides (an FSoundAttenuationSettings).

Each delegate comes in two forms (Components/AudioComponent.h:441-481). The dynamic, Blueprint-visible form binds a UFUNCTION with AddDynamic. The ...Native twin binds with AddUObject and also passes the UAudioComponent*. The pairs are OnAudioFinished, OnAudioPlayStateChanged, OnAudioVirtualizationChanged, OnAudioPlaybackPercent, OnAudioSingleEnvelopeValue and OnAudioMultiEnvelopeValue. Unbind with RemoveAll(this) in EndPlay. The code for both lists is in references/audio-component-reference.md.

Attenuation and Spatialization

USoundAttenuation assets wrap FSoundAttenuationSettings (Sound/SoundAttenuation.h), which derives FBaseAttenuationSettings (Engine/Attenuation.h).

Shape (EAttenuationShape::Type): Sphere, Capsule, Box, Cone. Curve (EAttenuationDistanceModel): Linear, Logarithmic, Inverse, LogReverse, NaturalSound, Custom. NaturalSound matches perceived loudness best for gameplay sources.

FSoundAttenuationSettings Settings;
Settings.DistanceAlgorithm = EAttenuationDistanceModel::NaturalSound;  // FBaseAttenuationSettings
Settings.AttenuationShape  = EAttenuationShape::Sphere;
Settings.FalloffDistance   = 3000.0f;

Settings.bAttenuate  = true;
Settings.bSpatialize = true;
// ESoundSpatializationAlgorithm: SPATIALIZATION_Default (panning), SPATIALIZATION_HRTF (plugin)
Settings.SpatializationAlgorithm = SPATIALIZATION_Default;
// Air absorption
Settings.bAttenuateWithLPF  = true;
Settings.LPFRadiusMin       = 1000.0f;
Settings.LPFRadiusMax       = 6000.0f;
Settings.LPFFrequencyAtMin  = 20000.0f;
Settings.LPFFrequencyAtMax  = 800.0f;
// Occlusion
Settings.bEnableOcclusion                = true;
Settings.OcclusionTraceChannel           = ECC_Visibility;
Settings.OcclusionLowPassFilterFrequency = 300.0f;
Settings.OcclusionVolumeAttenuation      = 0.5f;
Settings.OcclusionInterpolationTime      = 0.1f;
// Reverb send — EReverbSendMethod: Linear | CustomCurve | Manual
Settings.bEnableReverbSend = true;
Settings.ReverbSendMethod  = EReverbSendMethod::Linear;
Settings.ReverbWetLevelMin = 0.3f;
Settings.ReverbWetLevelMax = 0.95f;
Settings.ReverbDistanceMin = 400.0f;
Settings.ReverbDistanceMax = 4000.0f;
// Distant sounds lose the voice-budget fight first
Settings.bEnablePriorityAttenuation = true;
Settings.PriorityAttenuationMin     = 1.0f;
Settings.PriorityAttenuationMax     = 0.0f;

Listener focus (bEnableListenerFocus, FocusAzimuth, NonFocusAzimuth, FocusDistanceScale, NonFocusDistanceScale, NonFocusVolumeAttenuation) lets sounds the player is looking at cut through. bEnableSendToAudioLink controls external AudioLink routing — leave it off for background ambience.

Concurrency

USoundConcurrency (Sound/SoundConcurrency.h) wraps FSoundConcurrencySettings. Assign through USoundBase::ConcurrencySet, or set bOverrideConcurrency and fill ConcurrencyOverrides.

FSoundConcurrencySettings& Rules = FireConcurrency->Concurrency;   // struct ctor is not ENGINE_API — edit an asset's copy
Rules.MaxCount      = 4;
Rules.bLimitToOwner = false;
// EMaxConcurrentResolutionRule::Type — PreventNew, StopOldest, StopFarthestThenPreventNew,
// StopFarthestThenOldest, StopLowestPriority, StopQuietest, StopLowestPriorityThenPreventNew
Rules.ResolutionRule         = EMaxConcurrentResolutionRule::StopFarthestThenOldest;
Rules.RetriggerTime          = 0.05f;   // minimum seconds between plays in this group
Rules.VoiceStealReleaseTime  = 0.08f;   // fade for evicted voices; 0 clicks
Rules.VolumeScaleMode        = EConcurrencyVolumeScaleMode::Distance;  // Default | Distance | Priority
Rules.bVolumeScaleCanRelease = true;
Rules.VolumeScaleAttackTime  = 0.01f;
Rules.VolumeScaleReleaseTime = 0.5f;

One shared concurrency asset per sound family (footsteps, impacts, bullet whizzes). USoundBase::Priority decides who survives once MaxCount is reached.

Sound Classes and Sound Mixes

USoundClass gives every sound a category with its own Volume/Pitch in FSoundClassProperties, and a parent/child hierarchy. USoundMix holds TArray<FSoundClassAdjuster> SoundClassEffects (SoundClassObject, VolumeAdjuster, PitchAdjuster, bApplyToChildren) plus FadeInTime.

UGameplayStatics::SetBaseSoundMix(this, DefaultMix);          // usually once, or via AudioSettings
UGameplayStatics::PushSoundMixModifier(this, CombatMix);      // layers on top
UGameplayStatics::PopSoundMixModifier(this, CombatMix);
UGameplayStatics::ClearSoundMixModifiers(this);

// Duck one class inside an already-pushed mix
UGameplayStatics::SetSoundMixClassOverride(this, CombatMix, MusicClass,
    /*Volume=*/0.3f, /*Pitch=*/1.0f, /*FadeInTime=*/0.5f, /*bApplyToChildren=*/true);
UGameplayStatics::ClearSoundMixClassOverride(this, CombatMix, MusicClass, /*FadeOutTime=*/1.0f);

Sound classes are for gameplay-driven ducking. For player volume sliders use submix output volume instead — it is a single linear gain with no stack to unwind.

Submixes, Buses and Sends

USoundSubmixBase (Sound/SoundSubmix.h)
  ├── USoundSubmixWithParentBase
  │     ├── USoundSubmix          // effect chain, analysis, recording
  │     └── USoundfieldSubmix     // ambisonics / soundfield
  ├── UEndpointSubmix
  └── USoundfieldEndpointSubmix
MusicSubmix->SetSubmixOutputVolume(this, 0.5f);   // linear gain
MusicSubmix->SetSubmixWetLevel(this, 1.0f);
MusicSubmix->SetSubmixDryLevel(this, 0.0f);

MusicSubmix->DynamicConnect(this, MasterSubmix);  // re-parent at runtime
MusicSubmix->DynamicDisconnect(this);

Set bMuteWhenBackgrounded = true on music/SFX submixes so they stop when the app loses focus.

Sends. FSoundSubmixSendInfo (Sound/SoundSubmixSend.h) and FSoundSourceBusSendInfo (Sound/SoundSourceBusSend.h) share the same shape: a control method (ESendLevelControlMethod / ESourceBusSendLevelControlMethod — Linear, CustomCurve, Manual), SendLevel or MinSendLevel/MaxSendLevel + MinSendDistance/MaxSendDistance, CustomSendLevelCurve, and in 5.8 an explicit filter pair:

FSoundSubmixSendInfo Send;
Send.SoundSubmix           = ReverbSubmix;
Send.SendLevelControlMethod = ESendLevelControlMethod::Manual;
Send.SendLevel             = 0.35f;
Send.SendStage             = ESubmixSendStage::PostDistanceAttenuation;  // or PreDistanceAttenuation
Send.bEnableLPFCutoff      = true;
Send.LPFCutoff             = 3000.0f;   // Hz, 20..20000
Send.bEnableHPFCutoff      = false;
Send.HPFCutoff             = 20.0f;

Audio buses. UAudioBus (Sound/AudioBus.h, AudioBusChannels of EAudioBusChannels) is a runtime patch point: sounds send into it, a USoundSourceBus sonifies it back, and submixes can register it. Buses are how you feed a sidechain compressor or an analyser without an extra playback path.

UAudioMixerBlueprintLibrary::StartAudioBus(this, DuckingBus);
UAudioMixerBlueprintLibrary::RegisterAudioBusToSubmix(this, AnalysisSubmix, DuckingBus);
const bool bActive = UAudioMixerBlueprintLibrary::IsAudioBusActive(this, DuckingBus);
UAudioMixerBlueprintLibrary::UnregisterAudioBusFromSubmix(this, AnalysisSubmix, DuckingBus);
UAudioMixerBlueprintLibrary::StopAudioBus(this, DuckingBus);

Submix Effects

USoundSubmix::SubmixEffectChain is a TArray<TObjectPtr<USoundEffectSubmixPreset>>. Shipping presets in AudioMixer/Classes/SubmixEffects: USubmixEffectReverbPreset, USubmixEffectSubmixEQPreset, USubmixEffectDynamicsProcessorPreset.

#include "AudioMixerBlueprintLibrary.h"
#include "SubmixEffects/AudioMixerSubmixEffectReverb.h"

USubmixEffectReverbPreset* Preset = NewObject<USubmixEffectReverbPreset>(this);
FSubmixEffectReverbSettings ReverbSettings;
ReverbSettings.DecayTime  = 2.5f;
ReverbSettings.Density    = 0.85f;
ReverbSettings.Diffusion  = 0.8f;
ReverbSettings.WetLevel   = 0.4f;
Preset->SetSettings(ReverbSettings);   // thread-safe; assigning Settings directly is editor-time only

const int32 ChainIndex = UAudioMixerBlueprintLibrary::AddSubmixEffect(this, ReverbSubmix, Preset);
UAudioMixerBlueprintLibrary::RemoveSubmixEffect(this, ReverbSubmix, Preset);
UAudioMixerBlueprintLibrary::RemoveSubmixEffectAtIndex(this, ReverbSubmix, ChainIndex);
UAudioMixerBlueprintLibrary::ClearSubmixEffects(this, ReverbSubmix);

Swap whole chains for an environment with SetSubmixEffectChainOverride(WorldContext, Submix, Chain, FadeTimeSec) and ClearSubmixEffectChainOverride(WorldContext, Submix, FadeTimeSec). AddMasterSubmixEffect / RemoveMasterSubmixEffect / ClearMasterSubmixEffects act on the master submix.

Source-side effects use USoundEffectSourcePreset inside a USoundEffectSourcePresetChain (Sound/SoundEffectSource.h). AAudioVolume applies FReverbSettings, FInteriorSettings and submix send/override settings by volume, ordered by Priority.

MetaSounds

UMetaSoundSource derives USoundWaveProcedural → USoundWave → USoundBase, so it plays through every function above. Drive its typed inputs through ISoundParameterControllerInterface, which UAudioComponent implements (base interface IAudioParameterControllerInterface in AudioExtensions/Public/AudioParameterControllerInterface.h).

EngineAudioComp->SetFloatParameter(FName("RPM"), CurrentRPM);
EngineAudioComp->SetBoolParameter(FName("Engaged"), bEngaged);
EngineAudioComp->SetIntParameter(FName("GearIndex"), Gear);
EngineAudioComp->SetStringParameter(FName("SurfaceName"), TEXT("Gravel"));
EngineAudioComp->SetObjectParameter(FName("ImpactWave"), ImpactWave);
EngineAudioComp->SetTriggerParameter(FName("OnGearShift"));
EngineAudioComp->ResetParameters();

// Batch — cheaper than one call per value; SetParameters takes an rvalue array
TArray<FAudioParameter> Batch;
Batch.Emplace(FAudioParameter(FName("RPM"), CurrentRPM));
Batch.Emplace(FAudioParameter(FName("Engaged"), bEngaged));
EngineAudioComp->SetParameters(MoveTemp(Batch));

Parameter names must match the MetaSound graph inputs exactly. Setting a parameter on a component whose sound is not a MetaSound is a no-op, not an error.

UMetasoundGeneratorHandle::CreateMetaSoundGeneratorHandle(AudioComponent) (MetasoundGeneratorHandle.h) gives access to the running generator: IsValid(), GetAudioComponentId(), ApplyParameterPack(UMetasoundParameterPack*), GetGenerator(), plus OnGeneratorHandleAttached / OnGeneratorHandleDetached. Read graph outputs with UMetaSoundOutputSubsystem::WatchOutput.

Build graphs from code with UMetaSoundBuilderSubsystem::Get() → CreateSourceBuilder / CreatePatchBuilder / CreateSourcePresetBuilder, then AddGraphInputNode, AddNodeByClassName, ConnectNodes, SetNodeInputDefault and Audition. Build(const FMetaSoundBuilderOptions&) is WITH_EDITORONLY_DATA; at runtime use Audition or BuildNewMetaSound(FName) (MetasoundBuilderBase.h:586). The underlying document API is FMetaSoundFrontendDocumentBuilder (MetasoundFrontend/Public/MetasoundFrontendDocumentBuilder.h). Worked example: audio setup patterns.

Modulation

The AudioModulation plugin routes continuous control signals into volume, pitch and filter cutoffs. USoundControlBus carries a value, USoundModulationGenerator produces one (LFO, envelope follower), USoundControlBusMix sets bus targets, USoundModulationPatch maps between parameters. Bus, generator and patch derive USoundModulatorBase; USoundControlBusMix is a plain UObject (SoundControlBusMix.h:37).

// EModulationDestination: Volume, Pitch, Lowpass, Highpass
// EModulationRouting: Disable, Inherit, Override, Union
TSet<USoundModulatorBase*> Modulators;
Modulators.Add(TensionControlBus);
AudioComponent->SetModulationRouting(Modulators, EModulationDestination::Volume, EModulationRouting::Override);
AudioComponent->AddModulationRouting(Modulators, EModulationDestination::Lowpass);
AudioComponent->RemoveModulationRouting(Modulators, EModulationDestination::Lowpass);
const TSet<USoundModulatorBase*> Current = AudioComponent->GetModulators(EModulationDestination::Volume);

On assets, modulation lives in FSoundModulationDestinationSettings (Sound/SoundModulationDestination.h): a base Value plus a TSet<TObjectPtr<USoundModulatorBase>> Modulators. In native Audio::FModulationDestination code the setter is SetModulators.

Quartz Music Sync

UQuartzSubsystem is a UTickableWorldSubsystem (AudioMixer/Public/Quartz/QuartzSubsystem.h) that runs sample-accurate musical clocks.

#include "Quartz/QuartzSubsystem.h"
#include "Quartz/AudioMixerClockHandle.h"

UQuartzSubsystem* Quartz = GetWorld()->GetSubsystem<UQuartzSubsystem>();
FQuartzClockSettings ClockSettings;                    // TimeSignature defaults to 4/4
// Handle-taking calls use UQuartzClockHandle*& — pass a raw local, not a TObjectPtr member
UQuartzClockHandle* ClockHandle = Quartz->CreateNewClock(this, TEXT("MusicClock"), ClockSettings,
    /*bOverrideSettingsIfClockExists=*/false, /*bUseAudioEngineClockManager=*/true);
ClockHandle->StartClock(this, ClockHandle);

// EQuartzCommandQuantization: Bar, Beat, ThirtySecondNote and the other note values
FQuartzQuantizationBoundary Boundary;
Boundary.Quantization           = EQuartzCommandQuantization::Bar;
Boundary.Multiplier             = 1.0f;
Boundary.CountingReferencePoint = EQuarztQuantizationReference::BarRelative;
Boundary.bFireOnClockStart      = true;
FOnQuartzCommandEventBP OnQueued;
StingerComponent->PlayQuantized(this, ClockHandle, Boundary, OnQueued,
    /*InStartTime=*/0.0f, /*InFadeInDuration=*/0.0f, /*InFadeVolumeLevel=*/1.0f, EAudioFaderCurve::Linear);

Subscribe to the metronome with ClockHandle->SubscribeToQuantizationEvent(this, EQuartzCommandQuantization::Beat, OnBeat, ClockHandle) (or SubscribeToAllQuantizationEvents); the FOnQuartzMetronomeEventBP callback receives (FName ClockName, EQuartzCommandQuantization, int32 NumBars, int32 Beat, float BeatFraction). Tempo changes go through SetBeatsPerMinute, which is itself quantized.

Analysis

Real time, on a USoundSubmix:

MySFXSubmix->StartEnvelopeFollowing(this);
FOnSubmixEnvelopeBP EnvelopeDelegate;
EnvelopeDelegate.BindDynamic(this, &AMyActor::OnSubmixEnvelope);
MySFXSubmix->AddEnvelopeFollowerDelegate(this, EnvelopeDelegate);
MySFXSubmix->StartSpectralAnalysis(this, EFFTSize::Medium, EFFTPeakInterpolationMethod::Linear,
    EFFTWindowType::Hann, /*HopSize=*/0.0f, EAudioSpectrumType::MagnitudeSpectrum);
MySFXSubmix->StopSpectralAnalysis(this);
MySFXSubmix->StopEnvelopeFollowing(this);

Band-based FFT callbacks go through AddSpectralAnalysisDelegate(WorldContext, BandSettings, Delegate, UpdateRate, DecibelNoiseFloor, bDoNormalize, bDoAutoRange, AutoRangeAttackTime, AutoRangeReleaseTime) with an array of FSoundSubmixSpectralAnalysisBandSettings — see audio setup patterns. UAudioMixerBlueprintLibrary::MakeMusicalSpectralAnalysisBandSettings, MakeFullSpectrumSpectralAnalysisBandSettings and MakePresetSpectralAnalysisBandSettings build those arrays for you; StartAnalyzingOutput / StopAnalyzingOutput plus GetMagnitudeForFrequencies / GetPhaseForFrequencies give a polling API. Recording uses StartRecordingOutput / StopRecordingOutput (EAudioRecordingExportType::SoundWave or WavFile).

Offline, with the AudioSynesthesia plugin (Beta in 5.8): ULoudnessNRT and UOnsetNRT derive UAudioSynesthesiaNRT → UAudioAnalyzerNRT. AnalyzeAudio() is WITH_EDITOR only — bake beat maps at cook time, then read them at runtime with GetLoudnessAtTime / GetNormalizedChannelOnsetsBetweenTimes. Full example in audio setup patterns.

Subtitles

The SubtitlesAndClosedCaptions plugin (Beta in 5.8) drives captions from USubtitlesBlueprintFunctionLibrary:

#include "SubtitlesBlueprintFunctionLibrary.h"

USubtitlesBlueprintFunctionLibrary::QueueSingleSubtitle(
    FText::FromString(TEXT("Contact, north ridge.")), /*Duration=*/2.5f, /*StartOffset=*/0.0f,
    /*Priority=*/1.0f, ESubtitleType::Subtitle, ESubtitleTiming::InternallyTimed);
USubtitlesBlueprintFunctionLibrary::StopAllSubtitles();

QueueSubtitlesFromAsset / StopSubtitlesInAsset take a USubtitleAssetUserData attached to the sound. The engine-side FSubtitleManager (Engine/Public/SubtitleManager.h) still exists for USoundWave::Subtitles cues.

Platform Notes

  • Windows backend — AudioMixerModuleName=AudioMixerWasapi in Config/Windows/BaseWindowsEngine.ini. XAudio2 (AudioMixerXAudio2) is still selectable per project.
  • Dedicated servers — no audio device. Guard every play call with GetNetMode() != NM_DedicatedServer.
  • Mobile — tight voice budgets. Lean on concurrency and Priority, avoid SPATIALIZATION_HRTF, prefer ForceInline for short SFX.
  • Backgrounding — bMuteWhenBackgrounded on submixes, or hook FCoreDelegates::ApplicationWillDeactivateDelegate and call FAudioDevice::SetTransientPrimaryVolume(0.0f) on GEngine->GetMainAudioDevice().
  • VR — bSpatialize = true with SPATIALIZATION_HRTF on 3D attenuation assets, backed by a spatialization plugin.
  • Pitch range — clamped by UAudioSettings::GlobalMinPitchScale / GlobalMaxPitchScale.

Deprecated — do not use

Do not emitUse in 5.8Source
USubmixEffectEQPresetUSubmixEffectSubmixEQPresetnever existed; real class in SubmixEffects/AudioMixerSubmixEffectEQ.h:110
FSoundSubmixSendInfo::LPFCutoffFrequencybEnableLPFCutoff + LPFCutoffUE_DEPRECATED(5.8) in Sound/SoundSubmixSend.h:157
FSoundSubmixSendInfo::HPFCutoffFrequencybEnableHPFCutoff + HPFCutoffUE_DEPRECATED(5.8) in Sound/SoundSubmixSend.h:161
FSoundSourceBusSendInfo::LPFCutoffFrequencybEnableLPFCutoff + LPFCutoffUE_DEPRECATED(5.8) in Sound/SoundSourceBusSend.h:86
Audio::FModulationDestination::UpdateModulatorsSetModulatorsUE_DEPRECATED(5.8) in Sound/SoundModulationDestination.h:198
Audio::FModulationDestination::UpdateModulatorSetModulatorsUE_DEPRECATED(5.1) in Sound/SoundModulationDestination.h:195
USoundWave::CreateSoundWaveProxyGetSoundWaveProxy()UE_DEPRECATED(5.8) in Sound/SoundWave.h:1204
FSoundWaveProxy::GetZerothChunk and the other proxy accessorshold the result of GetSoundWaveDataRef()UE_DEPRECATED(5.8) in Sound/SoundWave.h:1813
FSoundWaveProxyReaderFSoundWaveProxyPlayerUE_DEPRECATED(5.8) in Sound/SoundWaveProxyReader.h:19
USubtitlesBlueprintFunctionLibrary::QueueSubtitleQueueSingleSubtitleUE_DEPRECATED(5.8) in SubtitlesBlueprintFunctionLibrary.h:32
UAudioBusSubsystem::StartAudioBus(Key, Channels, bAutomatic)overload taking InAudioBusNameUE_DEPRECATED(5.6) in AudioMixer/Public/AudioBusSubsystem.h:83
UAudioMixerBlueprintLibrary::RemoveSubmixEffectPresetRemoveSubmixEffectUE_DEPRECATED(4.27) in AudioMixerBlueprintLibrary.h:242
UAudioMixerBlueprintLibrary::ReplaceSoundEffectSubmixReplaceSubmixEffectUE_DEPRECATED(4.27) in AudioMixerBlueprintLibrary.h:258
FAudioDevice::SetTransientMasterVolumeSetTransientPrimaryVolumeUE_DEPRECATED(5.1) in Engine/Public/AudioDevice.h:1892
FAudioComponentParamFAudioParameterUE_DEPRECATED(5.0) in Components/AudioComponent.h:133
USoundBase::SoundConcurrencySettings_DEPRECATEDConcurrencySet / ConcurrencyOverrides_DEPRECATED property in Sound/SoundBase.h:183

Common Mistakes

Spawning a component per one-shot: NewObject<UAudioComponent> leaves an unattached, unregistered component behind on every call.

// WRONG
UAudioComponent* Comp = NewObject<UAudioComponent>(this);
Comp->SetSound(FireSound);
Comp->Play();
// RIGHT — one-shot
UGameplayStatics::PlaySoundAtLocation(this, FireSound, GetActorLocation());

Playing audio on a dedicated server: there is no audio device, so the call is wasted work and floods the log.

if (GetNetMode() != NM_DedicatedServer)
{
    UGameplayStatics::PlaySoundAtLocation(this, FireSound, GetActorLocation());
}

PlaySound2D for a world sound: 2D playback skips attenuation and spatialization entirely, so a gunshot across the map is full volume and centred. Use PlaySoundAtLocation with a USoundAttenuation.

A looping sound with bAutoDestroy = true: the handle dies the first time the sound reports finished, and later FadeOut calls hit a dangling component. Pass bAutoDestroy = false for anything you keep a pointer to.

Forgetting OwningActor on PlaySoundAtLocation: bLimitToOwner concurrency then falls back to group-wide limiting (FConcurrencyHandle::GetMode, SoundConcurrency.cpp:179), so per-actor limits silently become global.

Leaving delegates bound past EndPlay: call OnAudioFinished.RemoveAll(this) and Stop() in EndPlay, otherwise a pooled or auto-destroyed component fires into a stale object.

Volume sliders via sound mixes: push/pop mixes are a stack, and a missed pop leaves the game permanently ducked. Use USoundSubmix::SetSubmixOutputVolume for user settings; reserve mixes for transient gameplay ducking.

Assigning Preset->Settings at runtime: the audio render thread reads its own copy. Call SetSettings on the preset instead.

Related Skills

  • ue-niagara-effects — particle systems and VFX timing that audio events are synchronized with
  • ue-animation-system — anim notifies that trigger footsteps, foley and dialogue
  • ue-actor-component-architecture — component lifetime, attachment and replication for audio components
  • ue-gameplay-framework — where audio managers live (GameInstance, subsystems, player controller)
  • ue-data-assets-tables — data-driven sound banks and lookup tables for surface/impact audio
  • ue-sequencer-cinematics — audio tracks, dialogue and music in Level Sequences
  • ue-cpp-foundations — delegate binding, UPROPERTY/UFUNCTION and subsystem access patterns

FAQ

What does the ue-audio-system skill do?

Use when playing, mixing or debugging sound in Unreal Engine — one-shot SFX, looping ambience, music, dialogue or procedural audio. Also use when the user mentions 'UAudioComponent', 'PlaySoundAtLocation', 'SpawnSoundAttached', 'SoundCue', 'MetaSound', 'UMetaSoundSource', 'SetFloatParameter', 'sound attenuation', 'spatialization', 'occlusion', 'sound concurrency', 'submix', 'audio bus', 'sound mix', 'SetSubmixOutputVolume', 'reverb', 'Quartz', 'audio modulation' or 'subtitles'. For VFX timing, see ue-niagara-effects; for anim-notify sounds, see ue-animation-system; for component lifetime and attachment, see ue-actor-component-architecture.

How do I install ue-audio-system?

Run npx skills add https://github.com/quodsoler/unreal-engine-skills --skill ue-audio-system in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/ue-audio-system/ (personal) or .claude/skills/ue-audio-system/ (project).

Which AI agents can use ue-audio-system?

Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.

Is ue-audio-system safe to install?

No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.

Who maintains ue-audio-system?

It is published by quodsoler in quodsoler/unreal-engine-skills. It has 1,110 recorded installs.

More from quodsoler/unreal-engine-skills

View all →

ue-cpp-foundations

quodsoler/unreal-engine-skills

Use when writing Unreal Engine C++ that touches the reflection system or core types: UCLASS, UPROPERTY, UFUNCTION, USTRUCT, UENUM, GENERATEDBODY, TObjectPtr, TWeakObjectPtr, TSharedPtr, FGCObject, TArray, TMap, TSet, TOptional, TVariant, DECLAREDYNAMICMULTICASTDELEGATE, AddDynamic, FName, FString, FText, UGameInstanceSubsystem, UWorldSubsystem, GetDefault, TNotNull. Also use when the user mentions 'UE C++', 'garbage collection', 'CDO', 'smart pointers' or 'specifiers'. For Actor and component lifecycle, see ue-actor-component-architecture; for Build.cs and modules, see ue-module-build-system; for Blueprint-facing functions and latent actions, see ue-blueprint-cpp-interop.

Frontend & Design1.4K installs

ue-ui-umg-slate

quodsoler/unreal-engine-skills

Use when writing or fixing Unreal Engine UI in C++ — UMG user widgets, Slate widgets, Common UI screens, or MVVM view models. Also use when the user mentions 'UUserWidget', 'NativeConstruct', 'BindWidget', 'CreateWidget', 'AddToViewport', 'ESlateVisibility', 'OnClicked', 'UListView', 'widget animation', 'SNew', 'SLATEBEGINARGS', 'SCompoundWidget', 'UCommonActivatableWidget', 'activatable widget stack', 'UCommonButtonBase', 'gamepad focus', 'FUIInputConfig', 'UMVVMViewModelBase', 'FieldNotify', or 'WidgetComponent'. For input modes and Enhanced Input, see ue-input-system; for Slate in editor tooling, see ue-editor-tools.

Frontend & Design1.4K installs

ue-editor-tools

quodsoler/unreal-engine-skills

Use when extending the Unreal Editor from C++ with detail customizations, editor utility widgets, menus, editor modes, asset definitions or editor subsystems. Also use when the user mentions 'IDetailCustomization', 'IPropertyTypeCustomization', 'CustomizeDetails', 'RegisterCustomClassLayout', 'IDetailLayoutBuilder', 'AddCustomRow', 'IPropertyHandle', 'UToolMenus', 'ExtendMenu', 'FToolMenuEntry', 'UEditorUtilityWidget', 'Blutility', 'UAssetActionUtility', 'UEditorSubsystem', 'UEdMode', 'UAssetDefinition', 'UFactory', 'FScopedTransaction', or 'editor module'. For Slate fundamentals, see ue-ui-umg-slate; for Build.cs wiring, see ue-module-build-system.

Frontend & Design1.3K installs

ue-project-context

quodsoler/unreal-engine-skills

Use when creating, refreshing or repairing .agents/ue-project-context.md, the project document every other UE skill reads first. Also use when the user says 'project context', 'set up context', 'UE context', 'scan my project', 'onboard the agent to my project', 'update project context', 'configure project', 'what engine version is this project on', 'which plugins do we have enabled', or complains that UE advice keeps coming out generic. For Build.cs and Target.cs mechanics, see ue-module-build-system; for naming and API-macro conventions, see ue-cpp-foundations; for GAS specifics, see ue-gameplay-abilities.

Backend & APIs1.3K installs

ue-testing-debugging

quodsoler/unreal-engine-skills

Use when writing or running Unreal Engine tests, adding logging, or profiling a build. Also use when the user mentions 'UELOG', 'log category', 'DEFINELOGCATEGORY', 'UELOGFMT', 'verbosity', 'check', 'ensure', 'ensureMsgf', 'verify', 'IMPLEMENTSIMPLEAUTOMATIONTEST', 'automation test', 'TESTCLASS', 'CQTest', 'AFunctionalTest', 'latent command', 'Unreal Insights', 'TRACECPUPROFILEREVENTSCOPE', 'TRACEBOOKMARK', 'stat unit', 'SCOPECYCLECOUNTER', 'memreport', 'DrawDebugLine', 'UEVLOG', 'gameplay debugger', 'ShowDebug', 'console command', 'CVar', or 'why is my frame time bad'. For module and target wiring, see ue-module-build-system; for editor tooling, see ue-editor-tools.

Testing & QA1.3K installs

ue-module-build-system

quodsoler/unreal-engine-skills

Use when writing or fixing Build.cs, Target.cs, .uproject or .uplugin files, creating a module or plugin, or resolving an Unreal build error. Also use when the user mentions 'unresolved external symbol', 'LNK2019', 'cannot open include file', 'C1083', 'MODULENAMEAPI', 'PublicDependencyModuleNames', 'IWYU', 'PCHUsage', 'IMPLEMENTMODULE', 'IMPLEMENTPRIMARYGAMEMODULE', 'LoadingPhase', 'circular dependency', 'Missing precompiled manifest', 'EngineAssociation', 'IncludeOrderVersion', 'Live Coding'. For UCLASS/UPROPERTY rules see ue-cpp-foundations; for editor modules see ue-editor-tools; for Game Feature plugins see ue-game-features.

Media & Creative1.3K installs

Popular media & creative skills

View category →

hyperframes

heygen-com/hyperframes

Read first to make, edit, animate or render any video with HyperFrames (HTML rendered to video), including launch films, explainers, music videos, charts, maps, vertical clips, title cards, captions and overlays. Holds the render contract, the work loop and what each kind of video needs.

Media & Creative1.2M installs

media-use

heygen-com/hyperframes

Get or make any media for a HyperFrames video - music, sound effects, images, icons, logos, voiceover, avatar and generated video, transcripts, cutouts, colour grades and looks - with HeyGen or free local tools, and mix placed audio. Also for footage that looks dark, flat or dull, or should be stylized or hidden.

Media & Creative1.1M installs

hyperframes-registry

heygen-com/hyperframes

About 450 ready-made HyperFrames blocks and components installed as editable source - transitions, overlays, titles, kinetic type, captions, charts, map overlays, 3D, camera moves. Use it before hand-building any named visual (CRT scanlines, glitch, film grain, a chart); also for hyperframes add and catalog.

Media & Creative1M installs

hyperframes-creative

heygen-com/hyperframes

Non-animation creative direction for HyperFrames videos. Use for design spec (frame.md / design.md) handling, palettes, typography, narration, beat planning, audio-reactive visuals, composition patterns, and brand / style decisions. For atomic motion patterns and scene blueprints, use hyperframes-animation.

Media & Creative916.5K installs

ai-video-generation

101-skills/superpowers

Generate AI videos with Google Veo, Seedance 2.0, HappyHorse, Wan, Grok and 40+ models via inference.sh CLI. Models: Veo 3.1, Veo 3, Seedance 2.0, HappyHorse 1.0, Wan 2.5, Grok Imagine Video, OmniHuman, Fabric, HunyuanVideo. Capabilities: text-to-video, image-to-video, reference-to-video, video editing, lipsync, avatar animation, video upscaling, foley sound. Use for: social media videos, marketing content, explainer videos, product demos, AI avatars. Triggers: video generation, ai video, text to video, image to video, veo, animate image, video from image, ai animation, video generator, generate video, t2v, i2v, ai video maker, create video with ai, runway alternative, pika alternative, sora alternative, kling alternative, seedance, happyhorse

Media & Creative881.5K installs

ai-image-generation

101-skills/superpowers

Generate AI images with GPT-Image-2, FLUX, Gemini, Grok, Seedream, Reve and 50+ models via inference.sh CLI. Models: GPT-Image-2, FLUX Dev LoRA, FLUX.2 Klein LoRA, Gemini 3 Pro Image, Grok Imagine, Seedream 4.5, Reve, ImagineArt. Capabilities: text-to-image, image-to-image, inpainting, LoRA, image editing, upscaling, text rendering. Use for: AI art, product mockups, concept art, social media graphics, marketing visuals, illustrations. Triggers: flux, image generation, ai image, text to image, stable diffusion, generate image, ai art, midjourney alternative, dall-e alternative, text2img, t2i, image generator, ai picture, create image with ai, generative ai, ai illustration, grok image, gemini image, gpt image, openai image, chatgpt image

Media & Creative880.3K installs