Scope
This article is based mainly on the Unity 6.5 documentation available on August 4, 2026. I did not run device benchmarks or controlled listening tests. Treat every recommendation as a starting point, then verify it in a Player build on the target device with the actual maximum voice count, the Audio Profiler, and representative speakers or headphones.
WAV is only the source
Importing a high-quality WAV file does not guarantee that the shipped game plays the same uncompressed waveform.
WAV is an input container. Unity can convert it to PCM, ADPCM, Vorbis, MP3, or another platform-supported format. Load Type then decides whether Unity keeps decoded samples in memory, keeps compressed data in memory and decodes during playback, or reads the clip progressively from storage.
The runtime result depends on the combination:
source file
× Compression Format
× Quality / Sample Rate / channels
× Load Type
× Preload Audio Data / Load In Background
× simultaneous playback
× target platform
This is why “WAV means high quality,” “Vorbis always saves memory,” and “Streaming is always lighter” are unreliable rules.
In this article, BGM means background music and SFX means sound effects.
Practical starting points
| Use case | Format | Load Type | Channels | Why |
|---|---|---|---|---|
| Long BGM | Vorbis | Streaming | Stereo | The start is predictable, and full decoded residency is avoided |
| Short jingle | Vorbis or PCM | Compressed In Memory or Decompress On Load | Stereo | Streaming overhead may not be worthwhile for a few seconds |
| UI click | PCM | Decompress On Load | Depends | It should follow an unpredictable input without runtime I/O |
| Footstep, weapon, impact | ADPCM or PCM | Start with Decompress On Load | Mono | It should follow gameplay events without playback-time decoding |
| Medium SFX | Vorbis | Compressed In Memory | Depends | A middle ground between decoded memory and CPU |
| Typical dialogue | Vorbis | Compressed In Memory | Mono candidate | The next line can be prefetched |
| Long narration | Vorbis | Streaming | Mono candidate | Several minutes do not need to be fully decoded |
| Battle bark | PCM or ADPCM | Decompress On Load | Mono candidate | Combat feedback should start immediately |
These are baselines for native builds, not final presets. Web builds require a separate policy.
Keep three decisions separate
Source file
The file under Assets: WAV, AIFF, MP3, Ogg Vorbis, FLAC, and so on. Prefer an uncompressed or lossless production master. Converting MP3 to WAV does not restore discarded information, and encoding that WAV to Vorbis adds another lossy generation.
Compression Format
PCM, ADPCM, and Vorbis affect build size, compression artifacts, compressed-data size, and decoding cost.
Load Type
Decompress On Load, Compressed In Memory, and Streaming decide where data lives and when decoding and storage access occur.
Compression Format and Load Type are independent. A Vorbis clip using Decompress On Load is decoded during loading, so “Vorbis” alone does not imply low runtime memory.
PCM, ADPCM, and Vorbis
PCM
PCM is uncompressed. It avoids lossy artifacts and playback-time decompression, making it a simple choice for tiny, timing-critical sounds.
A rough payload estimate is:
bytes per second
= sample rate × bytes per sample × channel count
A 44.1 kHz, 16-bit stereo clip lasting 60 seconds is about 10.1 MiB before Unity-specific buffers. PCM is easy to justify for a click, but expensive as a blanket policy for music.
ADPCM
ADPCM is smaller than PCM and generally cheaper to decode than Vorbis. Unity documents roughly 3.5:1 compression compared with PCM and suggests footsteps, impacts, and weapon sounds as examples.
It can expose artifacts in tonal or smooth content. Also, ADPCM + Decompress On Load still needs decoded sample memory after loading; the compression ratio does not produce the same reduction in runtime memory.
Vorbis
Vorbis offers a quality setting that trades size against audible loss. It is a common candidate for BGM, dialogue, narration, ambience, and medium-to-long effects.
With Compressed In Memory, decoding contributes to mixer work. With Streaming, work moves to the streaming path. Test difficult material such as cymbals, sibilance, reverb tails, quiet ambience, and high-frequency synthetic sounds.
| Property | PCM | ADPCM | Vorbis |
|---|---|---|---|
| Compression | None | Lightweight fixed compression | High-ratio lossy compression |
| Build size | Large | About one third of PCM as a guideline | Often smaller than ADPCM |
| Playback CPU | Low | Moderate | Higher decoding cost |
| Good starting use | Tiny critical SFX | Footsteps, impacts, weapons | BGM, voice, medium/long SFX |
| Main risk | Long clips consume space and memory | Artifacts in tonal content | Many decoders can raise CPU |
The three Load Types
Decompress On Load
Unity decodes the clip while loading it and keeps decoded samples available. It suits short clips where the decoded total is small and playback-time work or startup uncertainty matters more than memory.
Unity 6.5 gives rough warnings that decoded Vorbis can require about ten times the compressed size and ADPCM about 3.5 times. These are planning guidelines, not fixed measurements.
Compressed In Memory
Unity keeps compressed data in memory and decodes it during playback. This often fits medium SFX and dialogue libraries that are too large to keep fully decoded but too short to stream individually.
The trade-off is mixer-side CPU. Test the real worst case with effects, spatialization, pitch changes, and overlapping voices.
Streaming
Unity reads compressed data progressively from storage and decodes through the streaming path. It is a natural baseline for long BGM, narration, and ambience.
Streaming is not free. Unity 6.5 lists approximately 200 KB of overhead per streaming clip. Hundreds of short streams can therefore be worse than a few long ones. Profile Streaming CPU, Streaming File Memory, and Streaming Decode Memory in a Player build.
| Load Type | Memory behavior | Playback work | Typical use |
|---|---|---|---|
| Decompress On Load | Holds decoded samples | Low decoding work during playback | Short, timing-critical SFX |
| Compressed In Memory | Holds compressed data | Decodes on the mixer path | Medium SFX and dialogue |
| Streaming | Avoids full decoded residency | Progressive I/O and decoding | BGM and long voice |
Choose by playback timing, not only duration
Unpredictable gameplay sounds
A UI click, attack, perfect dodge, landing, hit confirmation, or Animation Event cannot always be scheduled ahead. Its timing is part of the control feedback.
Streaming introduces storage access, stream initialization, and buffering. This does not mean every streamed sound is always audibly late. It means there is little reason to add that I/O risk to a tiny sound whose main job is immediate response.
Start with:
Decompress On Load
+ Preload Audio Data enabled
If Preload is disabled, call LoadAudioData() early and verify loadState before gameplay. Decompress On Load alone does not guarantee that the first Play() call performs no loading work.
Predictable audio
BGM, narration, cutscene audio, and the next dialogue line normally have preparation time. Long clips can stream; shorter voice lines can stay compressed in memory and be prefetched.
For music and synchronized stems, use AudioSettings.dspTime and PlayScheduled() rather than frame timing. loadState == Loaded is only a minimum precondition: it does not guarantee that storage and decoding remain safe during scene loading, AssetBundle work, crossfades, or long playback.
BGM
For music lasting several minutes, start with Vorbis + Streaming + Stereo. Begin loading before the transition, check readiness, and schedule precise starts or crossfades. Test loop boundaries, two-track overlap, scene loading, slower storage, long playback, and suspend/resume.
Do not apply the same rule to a three-second logo sound. Compare Vorbis + Compressed In Memory with PCM/Vorbis + Decompress On Load; per-stream overhead may cost more than the clip justifies.
Adaptive music must be measured at the maximum stem count. Four outgoing stems overlapping four incoming stems can briefly create eight streams. Synchronized assets should share the intended sample rate, duration, and loop boundaries and be ready before the same DSP-time start is scheduled.
Addressables and AssetBundles are a separate I/O layer
Load Type = Streaming describes the AudioClip. It does not complete the distribution design.
Bundle grouping, bundle compression, local or remote placement, caching, pre-download, custom encryption, and concurrent loading all affect startup and I/O contention. AudioClip Vorbis compression and AssetBundle LZ4/LZMA compression are separate layers.
A remote BGM flow may look like this:
Download required dependencies
→ LoadAssetAsync<AudioClip>() and keep the handle
→ wait for the required audio-data preparation
→ schedule or start playback
Pre-downloading a bundle does not by itself mean that the AudioClip asset and its audio data are ready.
SFX
UI and action feedback
Use PCM + Decompress On Load as the baseline for tiny clicks, confirm/cancel sounds, attack starts, perfect-input feedback, and hit confirmation. Ensure the audio data is loaded before the player can trigger them.
If hundreds are resident, inspect the decoded total. Mono is a candidate when stereo carries no information, but do not automatically collapse deliberately stereo UI sounds.
Footsteps, impacts, and weapons
Short, noisy, frequently repeated sounds are good ADPCM candidates. Start with ADPCM + Decompress On Load + Mono, then evaluate the worst-case soundscape rather than one isolated clip: maximum enemies, surface variations, BGM, voice, effects, and the minimum-spec device.
Medium effects
Mechanical loops and cinematic effects lasting several to tens of seconds often justify testing Vorbis + Compressed In Memory. It reduces decoded residency but spends DSP CPU, so maximum concurrency decides whether it works.
Voice
Typical dialogue is usually a mono candidate unless stereo carries real information such as binaural recording or intentional movement. Listen for phase and normalization changes when using Force To Mono.
For lines lasting a few to several seconds, start with Mono + Vorbis + Compressed In Memory. If Preload is off, call LoadAudioData() while the current line plays and check loadState before advancing.
With Addressables, release responsibility should belong to the layer that owns the AudioClip. Keep the handle while an AudioSource, pool, scheduled playback, Timeline/Playable, or next-line queue still references it.
optionally pre-download the bundle
→ LoadAssetAsync<AudioClip>() and keep the handle
→ LoadAudioData() if required, then verify loadState
→ play the clip
→ finish playback and clear references or schedules
→ UnloadAudioData() if appropriate
→ release the handle
For several minutes of narration, use Mono + Vorbis + Streaming as the baseline and test interruption, seeking, suspend/resume, and long-session stability.
Battle barks behave more like SFX. Combat shouts and damage reactions should usually be prepared as PCM/ADPCM + Decompress On Load because delayed playback weakens feedback.
When runtime code needs AudioClip.GetData(), Unity 6.5 requires compressed audio to use Decompress On Load, and Streaming clips are unavailable through that path. For long streamed voice, generate visemes, amplitude envelopes, or subtitle timing offline and read that lightweight data at runtime.
Channels, sample rate, preload, and background loading
Converting stereo to mono roughly halves the sample count. Point-source 3D effects and typical dialogue are common candidates; music, wide ambience, and binaural content should normally remain stereo.
Begin with Preserve Sample Rate or Optimize Sample Rate. Override only after a category creates a meaningful size problem, then listen carefully to sibilance, metallic transients, high electronic tones, airy ambience, and clips pitched upward.
Preload Audio Data prepares audio data with the asset according to the import configuration. When disabled, the first Play() or PlayOneShot() can start loading unless runtime code explicitly loads it first. Disabling Preload is not an optimization by itself; it moves responsibility into code.
Load In Background can reduce main-thread blocking, but it does not guarantee immediate playback. A request made before completion can wait. Prefetch sounds with a required start time and use DSP scheduling for synchronization.
Practical presets
| Preset | Format | Load Type | Preload | Mono | Main use |
|---|---|---|---|---|---|
| BGM_Long | Vorbis | Streaming | Usually Off | Off | Long-form BGM |
| BGM_Short | Vorbis | Compressed In Memory | Project-dependent | Off | Jingles |
| SFX_UI | PCM | Decompress On Load | On | Depends | UI feedback |
| SFX_Frequent | ADPCM | Decompress On Load | On | Candidate | Footsteps and impacts |
| SFX_Medium | Vorbis | Compressed In Memory | Project-dependent | Depends | Medium effects |
| Voice_Dialogue | Vorbis | Compressed In Memory | Usually Off with prefetch | Candidate | Dialogue |
| Voice_Bark | PCM/ADPCM | Decompress On Load | On | Candidate | Combat voice |
| Voice_Long | Vorbis | Streaming | Usually Off | Candidate | Narration |
“Project-dependent” means the loading and distribution design decides. “Candidate” means a reasonable first comparison, not a rule.
Import automation: unverified template
Manual settings drift in a large project. AssetPostprocessor.OnPreprocessAudio() can encode a folder policy.
Important: This follows the public Unity 6.5 API shape but was not compiled or reimport-tested for this article. Validate compilation, target and non-target folders, reimport behavior, and Inspector results in a test project before adoption.
using System;
using UnityEditor;
using UnityEngine;
public sealed class ProjectAudioImportPolicy : AssetPostprocessor
{
private const uint PolicyVersion = 1;
public override uint GetVersion() => PolicyVersion;
private void OnPreprocessAudio()
{
var importer = (AudioImporter)assetImporter;
var settings = importer.defaultSampleSettings;
settings.sampleRateSetting = AudioSampleRateSetting.PreserveSampleRate;
if (IsUnder("Assets/Audio/BGM/Long/"))
{
importer.forceToMono = false;
importer.loadInBackground = true;
settings.preloadAudioData = false;
settings.loadType = AudioClipLoadType.Streaming;
settings.compressionFormat = AudioCompressionFormat.Vorbis;
settings.quality = 0.8f;
}
else if (IsUnder("Assets/Audio/SFX/UI/"))
{
importer.forceToMono = false;
importer.loadInBackground = false;
settings.preloadAudioData = true;
settings.loadType = AudioClipLoadType.DecompressOnLoad;
settings.compressionFormat = AudioCompressionFormat.PCM;
}
else if (IsUnder("Assets/Audio/Voice/Dialogue/"))
{
// This template does not enforce a Normalize policy.
importer.forceToMono = true;
importer.loadInBackground = true;
settings.preloadAudioData = false;
settings.loadType = AudioClipLoadType.CompressedInMemory;
settings.compressionFormat = AudioCompressionFormat.Vorbis;
settings.quality = 0.7f;
}
else
{
return;
}
importer.defaultSampleSettings = settings;
}
private bool IsUnder(string folder) =>
assetPath.StartsWith(folder, StringComparison.Ordinal);
}
The quality values are comparison starting points, not universal recommendations. Perform level-matched A/B listening and adjust per platform.
The template changes only three folders. Platform overrides can use SetOverrideSampleSettings(), but its return value should be checked because unsupported combinations can fail. It also does not force Normalize; verify that policy through Presets, the Inspector, or version-tested automation.
Automation does not replace judgment. It consistently applies a decision the team has already validated.
Platform overrides and Web
Windows, Android, iOS, and Web have different decoding performance, memory budgets, storage behavior, and implementation constraints. Use Default as a baseline, then override platforms that need a different policy.
For Web, Unity 6.5 documentation directs developers toward Compressed In Memory and Decompress On Load; do not blindly copy the native long BGM = Streaming rule. Browser and Unity behavior can change, so recheck the exact Unity version and supported browsers.
Browsers also generally require a click, tap, or key input before playback can begin. Initialize or resume audio after a user gesture, and test output latency and background-tab recovery separately. Load Type alone cannot solve these constraints.
Unity also documents a possible Web loop glitch caused by AAC encoding and a workaround involving at least 1,024 silent samples at the beginning of a WAV plus loop information in the smpl chunk. Verify it on the browsers you support.
Profile the built game
Connect the Audio Profiler to a Player build and reproduce the maximum realistic overlap.
| Metric | What it helps explain |
|---|---|
| DSP CPU | Mixer, effects, and Compressed In Memory decoding |
| Streaming CPU | Streaming work |
| Total Audio Memory | Overall audio-engine allocation |
| Sample Sound Memory | Decoded sample residency |
| Streaming File / Decode Memory | Streaming buffers |
| Playing Audio Sources / Audio Voices | Playback and voice count |
| Virtual / Plays | Virtualization and unexpected repeats |
more Decompress On Load → watch Sample Sound Memory
more Compressed In Memory → watch DSP CPU
more Streaming → watch Streaming CPU and memory
Memory can retain a high-water mark for reuse, so it may not return to the startup value immediately. Compare clean startup, maximum combat, repeated scene transitions, large dialogue sessions, and long play sessions.
Change one axis at a time. When comparing Load Types, keep format, quality, channels, sample rate, and simultaneous count fixed. Record the Unity version, platform, device, importer settings, clip count, total duration, CPU, memory, startup delay, underruns, loop problems, and audible differences.
Common mistakes
| Mistake | Better interpretation |
|---|---|
| WAV means the shipped game is uncompressed | Unity re-encodes for the target platform |
| Everything should be PCM | Long clips inflate build size and decoded memory |
| ADPCM makes runtime memory 3.5 times smaller | Decompress On Load still needs decoded samples |
| Vorbis is always optimal | Many simultaneous decoders can raise CPU |
| Every short voice line should stream | Per-stream overhead accumulates |
| Turning Preload off fixes memory | It can move loading to the first playback request |
| Background loading means instant playback | Playback can wait for completion |
| BGM, SFX, and Voice are enough categories | Duration, concurrency, trigger timing, and platform matter |
Production decision flow
- Keep an uncompressed or lossless source master.
- Classify clips by behavior: long/short BGM, UI/frequent/medium SFX, dialogue/bark/long voice.
- Use PCM for tiny timing-critical sounds, test ADPCM for repeated noisy SFX, and use Vorbis as the default candidate for medium and long content.
- Use Decompress On Load when the decoded total is small, Compressed In Memory when compressed residency is preferable, and Streaming for genuinely long predictable audio.
- Preload input-, hit-, physics-, and animation-driven sounds instead of streaming them.
- Review mono and sample-rate options by content, not folder name alone.
- Prefetch dialogue and music; align synchronized assets and use
PlayScheduled()for DSP-timeline starts. - Measure and listen on the minimum-spec device at maximum realistic load.
Conclusion
The runtime quality and cost of Unity audio are not decided when a WAV enters the Assets folder. Platform conversion, Compression Format, quality, sample rate, channel count, Load Type, preload policy, distribution pipeline, and concurrency determine the shipped result.
A reasonable first pass is:
- long BGM:
Vorbis + Streaming; - UI and action feedback:
PCM + Decompress On Load + preloading; - footsteps, impacts, and weapons: test
ADPCMand preload event-driven clips; - medium SFX:
Vorbis + Compressed In Memory; - dialogue:
Mono + Vorbis + Compressed In Memorywith prefetching; - long narration:
Mono + Vorbis + Streaming; - battle barks:
PCM/ADPCM + Decompress On Load.
The final choice belongs to the real clip duration, loaded and playing counts, trigger timing, target device, profiler data, and listening result.
Top comments (0)