《Unity性能优化》之音频优化

Posted by LudoArt on July 24, 2022

Unity音频优化

原理

录制原始音频

采样频率:即每秒采样多少次,最常见的为44100Hz(CD音质),单调的短音效可以考虑22050Hz(广播音质)

采样精度:每次采样的结果用多少位保存,最常见的为16bits

采样时间:音频播放多久(秒)

通道(声道)数:在几个位置进行采样

未压缩音频

文件体积 = 内存占用大小 =采样频率 × 采样精度 × 通道数 × 采样时间 = 码率 × 采样时间

例1:2秒长度的双声道pcm,文件大小 = 44100 × 2byte × 2秒 × 2通道 = 352800字节 = 344.5KB(忽略文件头之类的元数据)

例2:游戏音频,常用的设置是单声道44.1KHZ + 16bit,也就是1秒 = 86KB左右

压缩音频

文件体积 = 原始文件体积 × 压缩率

  • 压缩格式
    1. Vorbis:压缩率大(3-40:1),解压(码)慢;
    2. Mp3:压缩率较大(4-12:1),解压较慢;
    3. ADPCM:压缩率小(3.5:1),解压较快;
    4. PCM:未压缩,速度最快,体积最大;
  • 加载音频的方式
    1. DecompressOnLoad
      1. 加载整个文件到内存,全部解压;
      2. 内存占用等于未压缩音频体积,和音频压缩格式无关,所有格式解压后的大小是一样的;
      3. 性能 = 播放,性能最好;
    2. CompressInMemory
      1. 加载整个文件到内存,不解压,播放时解压一部分播放一部分;
      2. 内存占用等于文件体积,压缩格式不同,则内存占用不同,解压重用缓存,所以不作为预估内存大小的数据;
      3. 性能 = 解码 + 播放,压缩格式不同,解压速度不同,播放时延不同;
    3. Streaming
      1. 播放时加载一部分解压一部分播放一部分,循环往复;
      2. 内存占用等于Streaming缓存大小(200KB左右),和文件格式以及大小无关;
      3. 性能 = 文件读取(I/O)+ 解码 + 播放,性能最差;
  • 音频播放
    1. 硬解码(DSP):专用硬件在子线程解码,同一时间只能有一个音频文件被解码;
    2. 软解码(CPU):在子线程中解码;

Unity音频设置

目标

  1. 文件体积尽可能小
    1. 查看:Editor中查看ImportedSize,即文件体积;
    2. 建议值:?
  2. 内存占用尽可能小
    1. 查看:
      1. DecompressOnLoad:选择PCM格式后,ImportedSize多大即内存占用是多大;
      2. CompressInMemory:内存占用等于ImportedSize,取决于压缩格式;
      3. Streaming:很小
    2. 建议值:全部播放时总内存占用 < 10MB
  3. 音质够用

统一要求

  • 单声道
    1. 勾选Force To Mono;
    2. 根据效果选择是否勾选Normalize;
  • 用自定义设置覆盖默认设置
    1. 勾选Override for Android/IOS;
  • 采样频率设置
    1. 采样频率设置为OverrideSampleRate,然后优先选择22050Hz,如果音质不能接受,就选择44100Hz,不允许高于44100Hz;
  • 最小化活动音源数量

  • 通过混音器组应用过滤效果以减少重复
  • 考虑用于背景音乐的音频模块文件

策略

  • 导入时按目录自动设置不同的参数

    • 长音频

      时长:≥ 5秒

      Load Type:Streaming

      Compression Format:Vorbis

      压缩质量(Quality):在保证音质可以接受的前提下,压缩质量尽可能小

      建议目录:Audio/Bgm

      预计最大内存占用:200KB

      加载时机:播放时加载

    • 时延敏感的短音频

      时长:< 1

      Load Type:Decompress On Load

      Compression Format:ADPCM

      建议目录:Audio/Short_NoDelay

      预计最大内存占用:86KB × 音频个数

      加载时机:游戏启动时异步预加载全部,永不释放

    • 时延敏感的中等长度音频

      时长:1 - 5秒

      Load Type:Compress In Memory

      Compression Format:ADPCM

      建议目录:Audio/Medium_NoDelay

      预计最大内存占用:ImportedSize × 音频个数

      加载时机:播放时加载

    • 时延不敏感的短音频

      时长:< 1

      Load Type:Compress In Memory

      Compression Format:ADPCM

      建议目录:Audio/Short

      预计最大内存占用:ImportedSize × 音频个数

      加载时机:播放时加载

    • 时延不敏感的中等长度音频

      时长:1 - 5秒

      Load Type:Compress In Memory

      Compression Format:Vorbis

      压缩质量(Quality):在保证音质可以接受的前提下,压缩质量尽可能小

      建议目录:Audio/Medium

      预计最大内存占用:ImportedSize × 音频个数

      加载时机:播放时加载

  • 其他

    1. Audio/Custom
    2. 纯手动设置音频参数
    3. 最小化活动音频数量:由于每个播放中的Audio Source消耗特定数量的CPU,因此禁用场景中冗余的Audio Source可以节省CPU周期;
    4. 通过混音器组应用过滤效果以减少重复:利用Unity的音频混音器(Window Adudio Mix)生成通用的过滤效果模板,多个音频源可以引用这些模板,以最小化内存开销;
    5. 考虑用于背景音乐的音频模块(Audio Module)文件:音频模块文件也称为音轨模块,是节省大量空间,并且没有任何明显质量损失的绝佳方式;

其他

IOS下用mp3解压速度会快一点(a little better),但Vorbis压缩率比mp3高很多,所以IOS也选择用Vorbis,另外这也是Unity的默认设置,更方便。