DEV Community

GameDevToolLab
GameDevToolLab

Posted on

WAV Is Not Automatically High Quality in Unity: PCM, ADPCM, Vorbis, and Load Types

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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);
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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

  1. Keep an uncompressed or lossless source master.
  2. Classify clips by behavior: long/short BGM, UI/frequent/medium SFX, dialogue/bark/long voice.
  3. 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.
  4. 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.
  5. Preload input-, hit-, physics-, and animation-driven sounds instead of streaming them.
  6. Review mono and sample-rate options by content, not folder name alone.
  7. Prefetch dialogue and music; align synchronized assets and use PlayScheduled() for DSP-timeline starts.
  8. 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 ADPCM and preload event-driven clips;
  • medium SFX: Vorbis + Compressed In Memory;
  • dialogue: Mono + Vorbis + Compressed In Memory with 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.

References

Top comments (0)