快速体验

在开始今天关于 音频编码入门:深入理解AAC与PCM的核心差异与应用场景 的探讨之前,我想先分享一个最近让我觉得很有意思的全栈技术挑战。

我们常说 AI 是未来,但作为开发者,如何将大模型(LLM)真正落地为一个低延迟、可交互的实时系统,而不仅仅是调个 API?

这里有一个非常硬核的动手实验:基于火山引擎豆包大模型,从零搭建一个实时语音通话应用。它不是简单的问答,而是需要你亲手打通 ASR(语音识别)→ LLM(大脑思考)→ TTS(语音合成)的完整 WebSocket 链路。对于想要掌握 AI 原生应用架构的同学来说,这是个绝佳的练手项目。

架构图

点击开始动手实验

从0到1构建生产级别应用,脱离Demo,点击打开 从0打造个人豆包实时通话AI动手实验

音频编码入门:深入理解AAC与PCM的核心差异与应用场景

刚接触音频开发的程序员们,是否经常被各种音频格式搞得晕头转向?今天我们就来聊聊最常见的两种格式——PCM和AAC,它们就像音频世界的"原材料"和"压缩包",用对了能让应用如虎添翼,用错了可能导致音质惨不忍睹或者流量爆炸。

为什么需要了解音频编码?

想象一下,你开发了一个语音聊天App,用户抱怨通话时声音断断续续,或者发现App特别耗流量。这些问题很可能就出在音频编码的选择上。PCM和AAC是两种完全不同的编码思路:

  • PCM(Pulse Code Modulation,脉冲编码调制)是原始音频数据,相当于未经压缩的"数字录音"
  • AAC(Advanced Audio Coding,高级音频编码)是经过智能压缩的音频格式,会舍弃人耳不易察觉的声音细节

新手最容易犯的错就是无脑使用PCM传输音频,导致:

  1. 带宽浪费:1分钟立体声PCM音频可能占用10MB流量
  2. 存储压力:用户录音文件体积暴涨
  3. 延迟增加:大数据量导致网络传输变慢

反过来,如果对音质要求高的场景(如音乐制作)错误使用AAC,会导致:

  1. 高频细节丢失:乐器声音变得"闷闷的"
  2. 多次转码损耗:每次编辑保存都造成音质下降

PCM vs AAC技术参数对比

先看一个直观的参数对比表:

特性 PCM AAC
数据性质 原始音频数据 压缩音频数据
压缩率 无压缩(1:1) 通常10:1~20:1
采样率支持 任意(常见44.1kHz/48kHz) 固定(8kHz-96kHz)
位深 16bit/24bit/32bit 压缩后无固定位深
音质 无损 有损(但人耳难察觉差异)
典型文件扩展名 .wav .pcm .aac .m4a .mp4
CPU占用 编码时较高

AAC的压缩原理很有意思,它利用了"心理声学模型"——简单说就是人耳对某些频率不敏感,比如:

  • 同时出现强音和弱音时,弱音会被掩盖
  • 极高和极低频率人耳分辨能力差
  • 某些方向的声波人耳难以定位

通过频谱图可以明显看到,AAC会智能保留主要频率(下图红色部分),而舍弃次要信息(蓝色部分):

AAC压缩频谱对比图

实战代码示例

FFmpeg格式转换

最常用的PCM转AAC命令(需要安装FFmpeg):

ffmpeg -f s16le -ar 44100 -ac 2 -i input.pcm \
       -c:a aac -b:a 128k -profile:a aac_low output.aac

关键参数说明:

  • -f s16le: 指定输入是16bit小端PCM
  • -ar 44100: 采样率44.1kHz
  • -ac 2: 双声道立体声
  • -b:a 128k: 设置比特率为128kbps(音质与体积的平衡点)
  • -profile:a aac_low: 使用低复杂度配置(适合移动设备)

Android实时编码示例

Android上采集PCM并实时编码为AAC的代码框架:

// 1. 配置AudioRecord采集PCM
int bufferSize = AudioRecord.getMinBufferSize(44100, 
    AudioFormat.CHANNEL_IN_STEREO, AudioFormat.ENCODING_PCM_16BIT);
AudioRecord recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,
    44100, AudioFormat.CHANNEL_IN_STEREO, 
    AudioFormat.ENCODING_PCM_16BIT, bufferSize);

// 2. 创建AAC编码器
MediaCodec encoder = MediaCodec.createEncoderByType("audio/mp4a-latm");
MediaFormat format = MediaFormat.createAudioFormat("audio/mp4a-latm", 44100, 2);
format.setInteger(MediaFormat.KEY_BIT_RATE, 128000);
format.setInteger(MediaFormat.KEY_AAC_PROFILE, 
    MediaCodecInfo.CodecProfileLevel.AACObjectLC);
encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);

// 3. 启动编码线程(简略版)
encoder.start();
while (recording) {
    ByteBuffer[] inputBuffers = encoder.getInputBuffers();
    int inputIndex = encoder.dequeueInputBuffer(10000);
    if (inputIndex >= 0) {
        ByteBuffer buffer = inputBuffers[inputIndex];
        int readSize = recorder.read(buffer, buffer.remaining());
        if (readSize > 0) {
            encoder.queueInputBuffer(inputIndex, 0, readSize, 
                System.nanoTime()/1000, 0);
        }
    }
    // ...处理输出数据
}

进阶优化与注意事项

实时编码延迟优化

移动端实时通话场景下,这三个参数直接影响延迟:

  1. 采集缓冲区大小:太小会导致CPU负载高,太大会增加延迟
  2. 编码帧大小:AAC通常每帧1024个样本(约23ms@44.1kHz)
  3. 网络发送间隔:建议累积2-3帧再发送减少包头开销

经验值参考:

  • 语音通话:20ms采集缓冲区+64kbps码率
  • 音乐直播:50ms缓冲区+128kbps码率

法律风险提示

注意:AAC是专利技术,商业应用需要获得授权!个人学习和非商业应用通常没问题,但产品化前请务必确认授权情况。作为替代方案可以考虑Opus编码(后面会提到)。

常见问题排查指南

遇到音频问题?先检查这三个典型场景:

  1. 杂音/爆音问题

    • 现象:播放时有"噼啪"声
    • 原因:采样率不匹配(如44.1kHz转48kHz未重采样)
    • 解决:统一所有环节的采样率,或用swresample正确转换
  2. AAC编码失败

    • 现象:MediaCodec报错"配置失败"
    • 原因:不支持的参数组合(如采样率32000+HE-AAC)
    • 解决:改用标准参数,或检查设备支持的编码规格
  3. 音量突然变小

    • 现象:转码后音量降低30%
    • 原因:PCM是整数格式而AAC使用浮点,未做归一化处理
    • 解决:编码前对PCM数据进行峰值检测和增益调整

思考与拓展

现在你已经掌握了AAC和PCM的核心知识,不妨尝试以下实验:

  1. 用FFmpeg将同一段音乐分别保存为PCM和不同码率的AAC,用频谱分析工具观察差异
  2. 在Android设备上测试实时编码的CPU占用与延迟关系
  3. 探索Opus编码——一种更适合实时通信的开源编码格式,对比它与AAC在语音通话中的表现

想亲手实践更多AI与音视频技术的结合?推荐体验从0打造个人豆包实时通话AI实验,用火山引擎的语音大模型构建属于你的智能语音助手,实战中巩固音频处理知识。我自己尝试后发现,把理论知识和实际应用结合起来学习,效果会事半功倍。

实验介绍

这里有一个非常硬核的动手实验:基于火山引擎豆包大模型,从零搭建一个实时语音通话应用。它不是简单的问答,而是需要你亲手打通 ASR(语音识别)→ LLM(大脑思考)→ TTS(语音合成)的完整 WebSocket 链路。对于想要掌握 AI 原生应用架构的同学来说,这是个绝佳的练手项目。

你将收获:

  • 架构理解:掌握实时语音应用的完整技术链路(ASR→LLM→TTS)
  • 技能提升:学会申请、配置与调用火山引擎AI服务
  • 定制能力:通过代码修改自定义角色性格与音色,实现“从使用到创造”

点击开始动手实验

从0到1构建生产级别应用,脱离Demo,点击打开 从0打造个人豆包实时通话AI动手实验

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐