Opus

Opus

Opus 简介

Opus 编码是一种有损音频编码的格式,由互联网工程任务组(IETF)进来开发,标准格式为RFC 6716。Opus 编码是由 Skype 的 SILK 编码及 Xiph.Org 的 CELT 编码融合而成,所以既适合语音又适合音乐编码,可以从低比特率窄带语音扩展到非常高质量的立体声音乐。

  • SILK 编码:由 skype 公司开源的一种语音编码,特别适合人声,适合于 Voip 语音通信。
  • CELT 编码:由 Xiph.Org 开源的编码格式,和 mp3, aac 类似,适合于传输音乐。

总结来说,Opus 是一个高保真的适合在网络中传输的开源的语音编码格式,相对于其他编码格式来讲,保真性更好,压缩比高,延迟低。

技术特点

  • 6 kb /s 到 510 kb / s 的编码码率,想要压缩比大一点就设置小一点,但是相应失真变大
  • 采样率从 8 kHz(窄带)到 48 kHz(全频),(8k, 12k, 16k, 24k, 48k)
  • 音频帧时长从 2.5 毫秒到 60 毫秒,(2.5, 5, 10, 20, 40, 60ms)
  • 支持恒定比特率(CBR)和可变比特率(VBR)
  • 支持语音和音乐
  • 支持单声道和立体声
  • 支持多达 255 个频道(多数据流的帧)
  • 可动态调节比特率,音频带宽和帧大小
  • 良好的鲁棒性丢失率和数据包丢失隐藏(PLC)
  • 浮点和定点实现

下载安装

tar -zxf opus-1.2.1.tar.gz
cd opus-1.2.1
./configure --prefix=$your_install_dir
make
make install

编译完之后, 在$your_install_dir目录下就有存在这三个文件夹include, lib, share,一般可以设置为自己的工程目录或者/usr/local/

Opus 主要接口

接口声明

opus 的接口声明在include/opus.h中,下面是四个主要的函数:

// 创建编码器
OpusEncoder *opus_encoder_create(
    opus_int32 Fs, // 采样率,8000, 12000, 16000, 24000, 48000
    int channels, // 声道数,网络实时音频数据一般为单通道
    int application, // 语音或音乐
    int *error // 是否创建成功,0为成功
)

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

opus_encoder_ctl(enc, OPUS_SET_BITRATE(24000)); // 编码比特率
opus_encoder_ctl(enc, OPUS_SET_VBR(0)); // 0恒定比特率,1可变比特率
opus_encoder_ctl(enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_VOICE)); // 指定编码类型,AUTO, VOICE, MUSIC可选


// PCM编码成opus
// 返回编码后的字节
// frame_size 必须是恰好是一帧(2.5, 5, 10, 20, 40, 60)ms的音频数据
// frame_size = 帧时长/(1/采样率)
opus_int32 opus_encode(
    OpusEncoder *st,
    const opus_int16 *pcm,
    int frame_size,
    unsigned char *data,
    opus_int32 max_data_bytes  // data的最大存储大小
)

// 释放编码器
void opus_encoder_destroy(OpusEncoder *st)

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

// opus解码成PCM
// **返回采样点的大小,而不是解码后的数据长度**
int opus_decode(
    OpusDecoder *st, // 解码器实例
    const unsigned char *data, // 要解码的数据
    opus_int32 len, // 解码数据长度
    opus_int16 *pcm, // 解码后的数据,是一个以16位为单位的数组
    int frame_size, // 每个声道给pcm数组的长度
    int decode_fec // 是否用inbandfec,0为不需要,1为需要
)

// 释放解码器
void opus_decoder_destroy(OpusDecoder *st)

opus 解码后返回的不是解码数据长度,而是采样点的大小,这应该时帧大小吧

使用技巧

动态编码码率

编码器默认使用动态码率,故需要在每个压缩数据帧头部记录每一个编码帧的大小,比如用 2 个字节的头部记录这个帧长。当然也可以使用静态编码码率,编码后总是返回固定大小的 opus 编码帧。

opus_encoder_ctl(enc, OPUS_SET_VBR(0)); // 0恒定比特率,1可变比特率
指定编码码率

在定义编码器后,可是修改编码器设置,指定静态码率,6 kb /s 到 510 kb / s 的编码比特率,想要压缩比大一点就设置小一点,但是相应失真变大。

opus_encoder_ctl(enc, OPUS_SET_BITRATE(24000)); // 编码比特率
语音信号优化

由于 opus 集成了语音和音乐两种优秀的编码算法,所以可以对指定的音频类型进行单独优化。

opus_encoder_ctl(enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_VOICE)); // 指定编码类型,AUTO, VOICE, MUSIC可选

示例

#include "opus.h"
#include "opus_types.h"
#include "opus_multistream.h"

#define SAMPLE_RATE 16000
#define CHANNEL_NUM 1
#define BIT
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Opus 是一种开源音频编解码器,适用于音频流传输和储存。以下是 Opus 编码和解码的示例代码: 编码: ```c #include <opus/opus.h> int main() { int error; OpusEncoder *encoder; int32_t sample_rate = 48000; int channels = 2; int application = OPUS_APPLICATION_AUDIO; int max_payload_bytes = 4000; encoder = opus_encoder_create(sample_rate, channels, application, &error); if (error != OPUS_OK) { fprintf(stderr, "failed to create encoder: %s\n", opus_strerror(error)); return -1; } error = opus_encoder_ctl(encoder, OPUS_SET_MAX_PAYLOAD_BYTES(max_payload_bytes)); if (error != OPUS_OK) { fprintf(stderr, "failed to set max payload bytes: %s\n", opus_strerror(error)); return -1; } int16_t pcm_frame[960 * channels]; uint8_t compressed_frame[max_payload_bytes]; int compressed_size; /* read a frame of audio data from somewhere */ while (1) { /* encode the frame */ compressed_size = opus_encode(encoder, pcm_frame, 960, compressed_frame, max_payload_bytes); if (compressed_size < 0) { fprintf(stderr, "opus_encode failed: %s\n", opus_strerror(compressed_size)); return -1; } /* send the compressed data over the network */ send_data_to_network(compressed_frame, compressed_size); } opus_encoder_destroy(encoder); } ``` 解码: ```c #include <opus/opus.h> int main() { int error; OpusDecoder *decoder; int32_t sample_rate = 48000; int channels = 2; int max_payload_bytes = 4000; decoder = opus_decoder_create(sample_rate, channels, &error); if (error != OPUS_OK) { fprintf(stderr, "failed to create decoder: %s\n", opus_strerror(error)); return -1; } error = opus_decoder_ctl(decoder, OPUS_SET_MAX_PAYLOAD_BYTES(max_payload_bytes)); if (error != OPUS_OK) { fprintf(stderr, "failed to set max payload bytes: %s\n", opus_strerror(error)); return -1; } uint8_t compressed_frame[max_payload_bytes]; int compressed_size; int16_t pcm_frame[960 * channels]; int pcm_size; /* receive a compressed frame of audio data from the network */ while (1) { /* decode the frame */ pcm_size = opus_decode(decoder, compressed_frame, compressed_size, pcm_frame, 960, 0); if (pcm_size < 0) { fprintf(stderr, "opus_decode failed: %s\n", opus_strerror(pcm_size)); return -1; } /* play the decoded audio */ play_audio(pcm_frame, pcm_size); } opus_decoder_destroy(decoder); } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值