音频编解码器 - Opus

简介

Opus是一款完全开放、免版税、功能多样的音频编解码器。它适用于互联网上的交互式语音和音乐传输,但也适用于存储和流媒体应用。

Opus的前身是celt编码器。在当今的有损音频格式争夺上,拥有众多不同编码器的AAC格式打败了同样颇有潜力的Musepack、Vorbis等格式,而在Opus格式诞生后,情况似乎不同了。通过诸多的对比测试,低码率下Opus完胜曾经优势明显的HE AAC,中码率就已经可以媲敌码率高出30%左右的AAC格式,而高码率下更接近原始音频。

Opus可以处理各种音频应用,包括IP语音,视频会议,游戏内聊天,甚至远程现场音乐表演。它可以从低比特率窄带语音扩展到非常高质量的立体声音乐。支持的特性包括:

  • 比特率从 6kb/s 到 510 kb/s
  • 采样率从 8kHz(窄带)到 48kHz(全频段)
  • 帧大小从 2.5ms 到 60ms
  • 支持恒定比特率(CBR)和可变比特率(VBR)
  • 从窄带到全频带的音频带宽
  • 支持语音和音乐
  • 支持单声道和立体声
  • 支持多达255个通道(多流帧)
  • 动态可调比特率,音频带宽和帧大小
  • 良好的稳健性和隐蔽性
  • 浮点和定点实现

可以在RFC 6716中阅读完整说明书,包括参考实现。下载页面还提供了最新的Opus标准实现。

编译opus静态库

  • 从GitHub下载Opus-iOS编译工程
  • 在Opus-iOS编译工程根目录下创建Opus-iOS/build/src目录。
  • 下载opus稳定版,得到opus-xx.tar文件。
  • 将opus-xx.tar放到Opus-iOS/build/src目录下。
  • 如果你下载的opus版本和build-libopus.sh中的opus版本信息不一样,你要修改以下版本信息。
VERSION="1.2"       #这是opus版本
SDKVERSION="11.4"   #这是SDK版本
MINIOSVERSION="9.0" #这是最低iOS版本
  • 在命令行中执行编译:
$ ./build-libopus.sh
  • 编译完成后在Opus-iOS/dependencies中会看到includelib
  • 关于编译Static LibraryFramework 的详细步骤请看Opus-iOS/README.md

集成opus到Xcode工程

用Xcode新建OpusDemo,将includelib一同拷贝到工程中即可。
这一步就不细说了,新手请自行搜索Xcode集成静态库的方法。
不想往下看的话请直接看示例OpusDemo

opus主要接口

  • opus的接口声明在include/opus.h中,下面是四个主要的函数:
// 创建编码器
OpusEncoder *opus_encoder_create(
    opus_int32 Fs,
    int channels,
    int application,
    int *error
)

// 修改编码器参数
int opus_encoder_ctl(
    OpusEncoder *st, 
    int request, ...
)

// 创建解码器
OpusDecoder *opus_decoder_create(
    opus_int32 Fs,
    int channels,
    int *error
)

// 将PCM编码成opus
opus_int32 opus_encode(
    OpusEncoder *st,
    const opus_int16 *pcm,
    int frame_size,
    unsigned char *data,
    opus_int32 max_data_bytes
) 

// 从opus中译码出PCM
int opus_decode(
    OpusDecoder *st,
    const unsigned char *data,
    opus_int32 len,
    opus_int16 *pcm,
    int frame_size,
    int decode_fec
) 

Tips

  • 使用动态码率?

编码器默认使用动态码率,因此需要记录每一个帧编码之后的大小。我的demo使用2字节的头来记录每一块opus数据的大小,具体请看我的demo。

静态码率需要设置编码器的初始化参数如下,编码后产生固定的大小的opus块。

opus_encoder_ctl(_encoder, OPUS_SET_VBR(0));  // 0固定码率,1动态码率
  • 指定码率?

你可以指定opus编码的码率大小,比特率从 6kb/s 到 510 kb/s,想要压缩比大一些就设置码率小一点,但是相应的也会使声音失真多一些。

#define BITRATE 16000 
opus_encoder_ctl(_encoder, OPUS_SET_BITRATE(BITRATE));
  • 语音信号优化?

如果你用于语音而不是音乐,那你完全可以设置如下,以使编码器针对语音模式做优化处理。

opus_encoder_ctl(_encoder, 
OPUS_SET_APPLICATION(OPUS_APPLICATION_VOIP));

opus_encoder_ctl(_encoder, OPUS_SET_SIGNAL(OPUS_SIGNAL_VOICE));

一组测试数据

(以下结果只在本例参数条件下有效)

15:47:17.948335 WAV => PCM: 39584
15:47:17.958745 encodedBytes: 97
15:47:17.961646 encodedBytes: 116
15:47:17.964055 encodedBytes: 121
15:47:17.966504 encodedBytes: 112
15:47:17.969272 encodedBytes: 104
15:47:17.972323 encodedBytes: 118
15:47:17.975030 encodedBytes: 116
15:47:17.977766 encodedBytes: 115
15:47:17.980185 encodedBytes: 116
15:47:17.982257 encodedBytes: 101
15:47:17.984174 encodedBytes: 143
15:47:17.986285 encodedBytes: 147
15:47:17.988596 encodedBytes: 134
15:47:17.990366 encodedBytes: 112
15:47:17.991779 encodedBytes: 97
15:47:17.993259 encodedBytes: 93
15:47:17.994783 encodedBytes: 100
15:47:17.996292 encodedBytes: 105
15:47:17.997766 encodedBytes: 110
15:47:17.999361 encodedBytes: 94
15:47:17.999390 PCM => OPUS: 2291
15:47:17.999658 decodedSamples:960
15:47:17.999843 decodedSamples:960
15:47:17.999992 decodedSamples:960
15:47:18.000191 decodedSamples:960
15:47:18.000347 decodedSamples:960
15:47:18.000585 decodedSamples:960
15:47:18.000696 decodedSamples:960
15:47:18.000807 decodedSamples:960
15:47:18.000893 decodedSamples:960
15:47:18.001011 decodedSamples:960
15:47:18.001111 decodedSamples:960
15:47:18.001216 decodedSamples:960
15:47:18.001486 decodedSamples:960
15:47:18.001615 decodedSamples:960
15:47:18.002240 decodedSamples:960
15:47:18.002357 decodedSamples:960
15:47:18.002445 decodedSamples:960
15:47:18.002570 decodedSamples:960
15:47:18.002729 decodedSamples:960
15:47:18.002813 decodedSamples:960
15:47:18.002877 OPUS => PCM: 38400

采样率 16000
码率 16000
通道数 1
帧大小 960

--

压缩比: 13.4
编码耗时: 大约60ms
译码耗时: 大约10ms

示例

更多代码示例信息请移步OpusDemo

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容