OPUS里的Silk和原始Silk简单比较

OPUS是由Silk和CELT两个编码器组成的,用来处理全频带的语音和音乐信号,OPUS在集成Silk的时候,对Silk的一些细节做了改动,这里简单整理一下OPUS中的Silk模块和纯的Silk编解码器的不同之处。
一、预测部分:计算逻辑上来看,二者是相同的。不同之处有:
1、OPUS的整体计算精度更高一些,由Silk里的Q10转换成了Q14后进行判断,包括LPC、LTP和excition部分。
2、在做Delaydecision的时候,OPUS中对判断算法进行了重写,增加了一个quantoffset,重新规划了量化的范围,这里和Silk比较,带来的MOS分增益我自己测的是大约在0.05左右,不一定准确。
3、OPUS是使用SHIFT_ROUND将Q10转化成了Q0传入到编码模块,Silk使用的是SHIFT方法,两者的不同之处在于,SHIFT_ROUND会将[-512,512]的值都转化为0,而SHIFT的置零区间为[0,1024],这里使用不同的SHIFT算法会影响到后续编码激励时分配的码率。
4、OPUS的Delaydecision默认是计算40个采样点的总误差,Silk是32个,这两个我试了一下对MOS分的影响基本没有。
5、OPUS通过调整计算步骤,加新的参数(如delayedgain和diff等)等方法,减少了少量计算量。
二、编码部分:
1、OPUS中的编码模块由依赖Silk中的概率密度函数转成了逆概率密度函数,我这里也不清楚做这种改动的原因,从结果上来看,使用CDF和iCDF的编码效率是差不多的。
2、OPUS将编码index和excition的函数区分开了,但函数的实现及各个参数的编码顺序是相同的。Silk的编码函数都在了一起显得有点拥挤,也不太方便后续自己开发。
三、其余部分:
1、增益计算部分,OPUS在较多函数里使用的是Q7,Silk使用的是Q0,从代码上来看OPUS对增益的控制能稍微准一些
2、OPUS的码率控制算法进行了重写,但总体逻辑是一样的,我个人感觉OPUS的码率控制更为激进一点
3、OPUS的抖动算法中Seed的判断方法也改变了,OPUS中通过判断Seed是否小于0进行符号的转换,Silk通过把Seed右移31位后做异或后自减进行判断,其实这两种方法的结果是一样的,只是表现方法不一样。
先写到这里吧,以后有想起来的再补充。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 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、付费专栏及课程。

余额充值