SILK编码语音转WAV格式

摘要:
SILK音频编码格式介绍WAV文件封装格式介绍和SILK音频代码到WAV转换“一般来说,语音编码数据不能直接显示。首先,使用相应的解码库将音频编码数据解码为PCM流。最后,获得通用播放器支持的代码和格式。部分功能是在网络中直接传输未加密的语音流。SILK编码的音频文件被解码并封装为WAV总体安排因此,SILK编码的实现代码可以在Opus编码的源文件中找到。

  SILK音频编码格式介绍、WAV文件封装格式介绍以及SILK音频编码到WAV的转换


在语音相关的协议还原中,经常会遇到语音编码的问题,通常语音编码的数据无法直接展示,需要转换成WAV,MP3等格式,才能播放。这个转换过程,是首先将音频编码数据使用对应解码库解码为PCM流,然后再将PCM流根据封装格式的要求,进行编码封装,最后得到可供通用播放器支持的编码和格式。


音频编码有很多,各有特色,本文首选介绍目前最流行的SILK编码。


SILK编码最早在Skype中使用,它在编码效率和质量之间取得了很好的平衡,因此被广泛应用在互联网的音频相关产品中,目前广泛使用的是SILK V3。


腾讯系产品,包括QQ、微信、小程序,在语音相关的实现中,也大量使用到SILK编码,并且,部分功能是直接让未加密的语音流在网络中传输,这是协议还原很感兴趣的部分。毕竟,腾讯的产品防守相当严密,不宜突破。


WAV作为古老的音频文件格式,虽然有很多缺点,但使用仍然相当广泛,本文将对其关键点进行介绍,SILK编码音频文件解码并封装为WAV格式的方法。


01

SILK编码


SILK采样率可为8、12、16或24 kHz,比特率可为6至40 kbit/s。对应到报文层面的直观印象,即SILK编码的语音数据每帧长度是不等的。


SILK编码已经开源,目前可下载到的版本为V1.0.9,它是Opus编码的基础。因此可以在Opus编码的源文件中找到SILK编码的实现代码,下载地址如下:

http://www.opus-codec.org/release/stable/2017/06/26/libopus-1_2_1.html


当然,其它地方也能很容易找到SILK编码的实现,比如GitHub上:

640?wx_fmt=png

当前经常遇到的SILK V3的编码就是SILK编码,在SILK的V1.0.9版SDK中的编码就是SILK V3编码,另外SILK库版本差异对语音解码基本可以忽略。如果各位朋友需要下载SILK编码库,可关注本公众号后发送关键词“silk”获取。


SILK编码库的功能是提供接口将SILK格式音频数据解码为PCM流以及将PCM流编码为SILk格式。在库内提供了编解码的例子,很容易懂。


02


WAV封装格式


语音编码后,如果一个软件不支持该编码,则语音是无法解码的,因此,语音数据的播放,首先需要的是将编码数据解码。如上一部分中的SILK编码库,就是用来将语音的原始PCM数据编码为SILK编码数据,以及将SILK编码数据解码为PCM数据流的。


各类通用的音视频播放器,对一个编码的支持,首先是根据文件名称后缀或者文件的内容进行封装格式识别,再根据封装格式中对编码的描述来进行编码的识别,如果编码被识别,并且集成了该编码库,则该编码的语音数据就可以被播放,也就是被支持了。


在当前技术发展阶段,对音频播放器而言,WAV格式和MP3格式是最基本的封装格式,基本上都会被支持,WAV格式支持原始的音频流即PCM流,这是最简单的格式,只需要将所有语音编码数据解码保存,然后在文件头部加上WAV格式结构体,即可进行封装。


当然,WAV格式缺点明显,其数据相当于未压缩,体积很大。


WAV格式头共44字节,定义及描述如下:

struct WAVHeader {     char Riff[4];     uint32 ChunkSize;     char Format[4];     char SubChunkID[4];     uint32 SubChunkSize;     uint16 AudioFormat;     uint16 NumChannels;     uint32 SampleRate;     uint32 ByteRate;     uint16 BlockAlign;     uint16 BitsPerSample;     char Data[4];     uint32 DataLen; };
Riff:4字节,固定值“RIFF”。ChunkSize:4字节,整个文件不包含Riff及ChunkSize的8字节。Format:4字节,固定值“WAVE”。SubChunkID:4字节,固定值“fmt ”,注意最后1字节为空格0x20。SubChunkSize:4字节,对应WAV,值为0x10。AudioFormat:2字节,格式类型,线性PCM则值为1,其它值则为压缩的编码格式,如0x06为PCMA,0x07为PCMU。NumChannels:2字节,声道数,1或者2。SampleRate:4字节,采样频率,如11025,44100等。ByteRate:4字节,码率=采样频率*PCM采样位深/8*声道数。BlockAlign:2字节,采样一次占内存的长度=声道数*PCM采样位深/8。BitsPerSample:2字节,PCM采样位深,如8、16。Data:4字节,固定值“data”。DataLen:4字节,PCM数据总长度。

一个典型的WAV头部数据如下:

640?wx_fmt=png


03


SILK V3转换到WAV


SILK编码到WAV的转换,当然要用到SILK编码库,供下载的SILK编码库内,提供了4个不同的平台版本,功能基本相同。


在SILK编码库的SDK内,test目录下,有一个Decoder.c文件,是解码的示例文件,编译后它能够直接解码如下格式的SILK音频文件:

640?wx_fmt=png

如上图所示,SILK文件格式以"#!SILK_V3"开始,之后就是一帧帧的语音内容块,每帧的帧长占两字节,然后为帧内容,这是因为SILk编码是变长编码,每帧的长度是不同的。


在各个test_vectorsitstream目录下的.bit文件,即为SILK格式文件,可以被解码程序Decoder.c支持。


解码程序将SILK文件解码为PCM流文件,但缺少WAV头,无法直接用播放器播放。


如果需要使解码后的PCM流能够播放,则需要PCM流前面添加WAV头。对微信语音短消息,WAV头赋值如下(pcmsize为PCM流的字节数):

whead.DataLen = pcmsize;

memcpy(whead.Riff,"RIFF",4);

memcpy(whead.Format,"WAVE",4);

memcpy(whead.SubChunkID,"fmt ",4);

memcpy(whead.Data,"data",4);

whead.ChunkSize =whead.DataLen+44-8;

whead.SubChunkSize = 0x10;

whead.AudioFormat = 1;

whead.NumChannels = 1;

whead.SampleRate = DecControl.API_sampleRate;

whead.BitsPerSample = 16;

whead.BlockAlign = whead.NumChannels*whead.BitsPerSample/8;

whead.ByteRate = whead.SampleRate*whead.BlockAlign;


其中NumChannels、SampleRate和BitsPerSample等参数需要根据具体情况进行填充,否则,声音会很怪异。


对SILK编码转换为WAV语音文件,如果有疑惑,可以咨询我。


640?wx_fmt=jpeg

长按进行关注。





免责声明:文章转载自《SILK编码语音转WAV格式》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇OAuth中client id的处理C#.NET防止SQL注入式攻击下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

脚本中的无效字符

脚本被保存后 就无法解析 报无效字符 是编码的问题  用ue 的16进制查看 发现 开头多了EFBBBF  (本身是没有的 ) 选 另存为 utf—8 无 bom utf—8 是一种unicode 用ansi虽然也没有efbbbf但是 里面的 汉字编码就不对了 ...

Python之字符编码与文件操作

目录 字符编码 Python2和Python3中字符串类型的差别 文件操作 文件操作的方式 文件内光标的移动 文件修改 字符编码 什么是字符编码? ''' 字符编码就是制定的一个将人类的语言的字符与二进制数据一一对应地翻译过来的标准。 ''' 字符编码的发展史与分类: 计算机最早的字符编码为ASCII,只规定了英文字母、数字和一些特殊字符与数字一一...

各种移动GPU压缩纹理的使用方法

本文系原创整理,欢迎转载,请标明链接 http://www.cnblogs.com/luming1979 有问题欢迎加qq群讨论:366239605   介绍了各种移动设备所使用的GPU,以及各个GPU所支持的压缩纹理的格式和使用方法。1. 移动GPU大全 目前移动市场的GPU主要有四大厂商系列: 1)Imagination Technologies的P...

微信公众平台开发(75) 语音识别

本文介绍如何使用微信公众平台高级接口中的语音识别功能,做出一个语音版的天气预报查询功能。根据这个模型,你可以扩展到所有的语音查询。 一、接收语音识别结果 开通语音识别功能以后,用户每次发送语音给公众号时,微信会在推送的语音消息XML数据包中,增加一个Recongnition字段。该字段为语音识别出的文本内容。 用户发送语音: 语音XML数据包如下 <...

关于base64编码Encode和Decode编码的几种方式

关于base64编码Encode和Decode编码的几种方式 Base64是一种能将任意Binary资料用64种字元组合成字串的方法,而这个Binary资料和字串资料彼此之间是可以互相转换的,十分方便。在实际应用上,Base64除了能将Binary资料可视化之外,也常用来表示字串加密过后的内容。如果要使用Java 程式语言来实作Base64的编码与解码功能...

GB2312/GBK/GB18030/BIG5/UNICODE/UTF8编码

GB2312/GBK/GB18030/BIG5/UNICODE/UTF-8编码 - 3※5不甘平淡 - 51Testing软件测试网 51Testing软件测试网-中国软件测试人的精神家园 - Powered by X-SpaceGB2312/GBK/GB18030/BIG5/UNICODE/UTF-8编码经常会碰到一些关于编码的名词,特意收录了些资料以备...