屏幕闪动是怎么回事成这样怎么回事

Multimedia(108)
编解码(28)
1. 音频简介
& & &经常见到这样的描述: 44100HZ 16bit stereo 或者 22050HZ 8bit mono 等等.
& & &44100HZ 16bit stereo: 每秒钟有 44100 次采样, 采样数据用 16 位(2字节)记录, 双声道(立体声);
& & &22050HZ 8bit& mono: 每秒钟有 22050 次采样, 采样数据用 8 位(1字节)记录, 单声道;
& & 当然也可以有 16bit 的单声道或 8bit 的立体声, 等等。&
& & 采样率是指:声音信号在“模→数”转换过程中单位时间内采样的次数。采样值是指每一次采样周期内声音模拟信号的积分值。
& & &对于单声道声音文件,采样数据为八位的短整数(short int 00H-FFH);
& & &而对于双声道立体声声音文件,每次采样数据为一个16位的整数(int),高八位(左声道)和低八位(右声道)分别代表两个声道。
& & 人对频率的识别范围是 20HZ - 20000HZ, 如果每秒钟能对声音做 20000 个采样, 回放时就足可以满足人耳的需求. 所以 22050 的采样频率是常用的, 44100已是CD音质, 超过48000的采样对人耳已经没有意义。这和电影的每秒 24 帧图片的道理差不多。
& & 每个采样数据记录的是振幅, 采样精度取决于储存空间的大小:
& &1 字节(也就是8bit) 只能记录 256 个数, 也就是只能将振幅划分成 256 个等级;
& &2 字节(也就是16bit) 可以细到 65536 个数, 这已是 CD 标准了;
& &4 字节(也就是32bit) 能把振幅细分到
个等级, 实在是没必要了.
& &如果是双声道(stereo), 采样就是双份的, 文件也差不多要大一倍.
这样我们就可以根据一个 wav 文件的大小、采样频率和采样大小估算出一个 wav 文件的播放长度。
譬如 &Windows XP 启动.wav& 的文件长度是 424,644 字节, 它是 &22050HZ / 16bit / 立体声& 格式(这可以从其 &属性-&摘要& 里看到),
那么它的每秒的传输速率(位速, 也叫比特率、取样率)是
= 705600(bit/s),&换算成字节单位就是
= 88200(字节/秒),&
播放时间:424644(总字节数) / 88200(每秒字节数) ≈ 4.8145578(秒)。
但是这还不够精确, 包装标准的 PCM 格式的 WAVE 文件(*.wav)中至少带有 42 个字节的头信息, 在计算播放时间时应该将其去掉,&
所以就有:() / (/8) ≈ 4.8140816(秒). 这样就比较精确了.
关于声音文件还有一个概念: &位速&, 也有叫做比特率、取样率, 譬如上面文件的位速是 705.6kbps 或 705600bps, 其中的 b 是 bit, ps 是每秒的意思;
压缩的音频文件常常用位速来表示, 譬如达到 CD 音质的 MP3 是: 128kbps / 44100HZ.
2. PCM数据格式
& & PCM(Pulse Code Modulation)也被称为 脉码编码调制。PCM中的声音数据没有被压缩,如果是单声道的文件,采样数据按时间的先后顺序依次存入。(它的基本组织单位是BYTE(8bit)或WORD(16bit))
& & 一般情况下,一帧PCM是由2048次采样组成的(
& & 如果是双声道的文件,采样数据按时间先后顺序交叉地存入。如图所示:
& &PCM的每个样本值包含在一个整数i中,i的长度为容纳指定样本长度所需的最小字节数。
首先存储低有效字节,表示样本幅度的位放在i的高有效位上,剩下的位置为0,这样8位和16位的PCM波形样本的数据格式如下所示。
&&&&样本大小&&&&& 数据格式&&&&&&&&&&& 最小值&&& 最大值
&&& 8位PCM&&&&&& unsigned int&&&&&&&& 0&&&&&& 225
&&& 16位PCM&&&&& int&&&&&&&&&&&&&&& -32767&&& 32767
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:313020次
积分:4788
积分:4788
排名:第5815名
原创:98篇
转载:417篇
评论:23条
(8)(16)(2)(3)(35)(19)(1)(3)(2)(10)(15)(5)(20)(7)(12)(1)(2)(5)(16)(3)(20)(32)(138)(74)(20)(5)(5)(1)(4)(1)(1)(1)(1)(18)(6)(4)(3)(1)(5)(1)3942人阅读
other(53)
& & & & PCM是英文Pulse-code modulation的缩写,中文译名是脉冲编码调制。它是70年代末发展起来的,记录媒体之一的CD,在80年代初由飞利浦和索尼公司共同推出。脉码调制的音频格式也被DVD-A所采用,它支持立体声和5.1环绕声,
把这些脉冲的幅值按一定的精度进行量化,这些量化后的数值还要进行编码,就是用一组二进制码组来表示每一个量化值,然后记录到存储介质中,所有这些组成了数字音频的产生过程。采样、量化如下图所示。
& & & & 根据数字音频的产生过程可知,相对自然界的信号,音频编码最多只能做到无限接近,至少目前的技术只能这样了,任何数字音频编码方案都是有损的,因为无法完全还原。在计算机应用中,能够达到最高保真水平的就是PCM编码,被广泛用于素材保存及音乐欣赏,CD、DVD以及我们常见的WAV 文件中均有应用。因此,PCM约定俗成了无损编码,因为PCM代表了数字音频中最佳的保真水准。
& & & & 对于我们最常说的“无损音频”来说,一般都是指传统CD格式中的16bit/44.1kHz采样率的文件格式,而之所以称其为无损,也是因为其包含了20Hz-22.05kHz这个完全覆盖人耳可闻范围的频响频率而得名。要做到真正的无损是困难的,就像用数字去表达圆周率,不管精度多高,也只是无限接近,而不是真正等于圆周率的值。
& & & & 常见的无损音频格式有WAV、FLAC和APE。
& & & & WAV格式文件是音响设备和很多软件可以直接读取的音频文件,基本上不存在编解码问题。FLAC和APE都对WAV进行了编码,故能换取较小的体积,但同时造成解码播放时,因播放器材解析力很敏感(或者说技术所限),会出现一定的jitter抖动(解析复杂编码所致)而导致播放效果不够饱满和流畅。这点你可以通过统一转换为WAV格式来试听解决。
& & & &对于WAV格式来说,是目前的常规无损压缩格式中体积最大的文件格式,由于FLAC和APE都对WAV进行了更高技术的编码,所以换取了较小的体积,这也是这两种格式之所以出现的根本原因。而对于FLAC和APE两种格式来说,虽然体积大小差不多,但是采用了不同的压缩格式,所以对于设备来说在播放时候需要占用的资源多少也并不相同,简单地说占用资源多少的比例为:APE最大、FLAC中、WAV占用最小。
三、PCM编码与WAV格式的关系
& & & & 单独的PCM编码文件是不能直接播放的,这种文件通常称为PCM裸流。PCM裸流经过封装后,就可以正常播放了。
下自带的那个录音机录下的WAV,文件头有58个字节。
个字节,就可以读到文件尾。如下图所示,用UltraEdit打开一个WAV文件,可以看到关键字data,data之后红框中的四个字节就是length。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:300899次
积分:6686
积分:6686
排名:第3397名
原创:143篇
转载:127篇
评论:260条
文章:11篇
阅读:13953
(5)(8)(6)(3)(8)(11)(22)(45)(74)(6)(6)(3)(4)(26)(30)(10)为何一直推荐WebRTC? - 知乎53被浏览11927分享邀请回答81 条评论分享收藏感谢收起与世界分享知识、经验和见解PCM音频处理——使用WebRTC音频降噪模块与其他方式的对比 - 简书
PCM音频处理——使用WebRTC音频降噪模块与其他方式的对比
公司有一个产品,喊话的时候语音效果很不理想,产品端呈现的时候噪音掩盖了实际喊话的声音,硬件工程师在产品端简单的放大信号来播放网络传输过去的喊话信号,个人觉得是产品的问题,但是硬件工程师不肯处理,一直强调客户端需要降噪,僵持不下,领导最后发话:先客户端降噪,一定要解决。
以下比较的都是开源的降噪方法,Speex音频降噪模块,WebRTC音频降噪模块和自己制作的简单的降噪方法。对于降噪前后的对比,从三个方面进行评价:时域,频域,个人听觉感受。必备工具:1.音频处理软件:Audacity(简单分析降噪效果)2.翻墙工具(我使用的是同事共享的蓝灯,为的是下载WebRTC源码,需要翻墙到谷歌下载,如果有其他途径也可以)
关于音频来源的一点说明,这边的音频数据都是PCM数据,无论是PC端采集的,还是iOS端采集的,只要得到了PCM码流,就可以进行降噪处理。
方法比较:
1.Speex音频降噪模块
相关文章链接:,Speex是很强大的编解码库,也包含一些降噪,自动增益,回音消除等模块功能,Speex是开源的,Opus是Speex的更优替代方案,但是Opus没有降噪去噪模块,就具体我所在公司,我们公司使用的是Speex编码,没有使用更新的Opus,经过实际实验,Speex的去噪效果有效,话不多说,上过程:部分代码:
#define USE_SPEEX_DENOISE 0
class CHHAudioEncoderG711ADenoise:public IHHAudioEncoder
CHHAudioEncoderG711ADenoise(int samplerate,int bitsize):m_RetainCount(1)
m_encoder = new CHHAudioEncoderG711A;
#if USE_SPEEX_DENOISE
//帧长度,以20ms为例,帧长度=20*采样率/1000=(20ms内的采样点数量)
int framesize = 20*samplerate/1000;
m_context = speex_preprocess_state_init(framesize, samplerate);
int i=1;//1表示开启,0表示关闭
//SPEEX_PREPROCESS_SET_DENOISE表示降噪
speex_preprocess_ctl(m_context, SPEEX_PREPROCESS_SET_DENOISE, &i);//降噪
int noiseSuppress = -25;//噪音分贝数,是一个负值
//Speex的降噪是通过简单的设置音频数据的阀值,过滤掉低分贝的声音来实现的
//优点是简单,使用Speex编解码库时可以直接使用
//缺点是会把声音细节抹掉
speex_preprocess_ctl(m_context, SPEEX_PREPROCESS_SET_NOISE_SUPPRESS, &noiseSuppress);
virtual ~CHHAudioEncoderG711ADenoise(void)
if (m_encoder){
m_encoder-&Release();
m_encoder = NULL;
#if USE_SPEEX_DENOISE
if (m_context){
speex_preprocess_state_destroy(m_context);
m_context = NULL;
protected:
virtual void Retain()
++m_RetainC
virtual void Release()
if (--m_RetainCount==0) {
virtual bool Encode(unsigned char *pInData,int nInLen,onAudioEncodeResultCallback func,void* param)
#if USE_SPEEX_DENOISE
//pInData是采集到的音频数据,因为上层的原因,采集到的缓存长度是320个字节
speex_preprocess_run(m_context, (short*)pInData);
m_encoder-&Encode(pInData,nInLen,func,param);
unsigned long m_RetainC
IHHAudioEncoder* m_
#if USE_SPEEX_DENOISE
SpeexPreprocessState* m_//Speex预处理器指针
使用过程很简单,依次顺序为:
1.创建Speex预处理器指针:speex_preprocess_state_init
支持的采样率有3种:8K,16K,44K,采样送进去降噪的数据需要控制在20ms,也就是(20采样率/1000)*个采样点。
2.设置预处理器的参数:speex_preprocess_ctl
包括SPEEX_PREPROCESS_SET_DENOISE和SPEEX_PREPROCESS_SET_NOISE_SUPPRESS
3.处理一帧音频数据:speex_preprocess_run
第二个参数是音频数据指针,处理完成后也会保存在这个指针,另外注意指针类型应该为short*
4.销毁预处理器:speex_preprocess_state_destroy
效果:(使用Audacity分析)语音内容:“Speex降噪效果对比”
Speex降噪效果对比:时域(降噪前为上面那个,降噪后为下面那个)
降噪前频域分析
降噪后频域分析
从图片上看,不管是时域还是频域,效果都不明显,实际听的效果的话,降噪后,背景的沙沙声有所减弱,但是总体效果还是不佳。
2.WebRTC音频降噪模块
相关的文章推荐:WebRTC源码链接:说句题外话,不得不佩服谷歌,只要是个做开发的,这辈子估计都离不开谷歌了,对于咱们这种小喽啰来说,只要记住“谷歌出品,必属精品”就好了,当然,这里用到的WebRTC也是谷歌的,感兴趣的可以自己去找相关的信息。WebRTC是最近几年比较火的技术,原谅我原先都不知道~~~,WebRTC提供了视频会议的核心技术,包括音视频的采集、编解码、网络传输、显示等功能,并且还支持跨平台:Windows,Linux,Mac,Android(这句来自百度……)。我们这里使用的就是WebRTC的音频处理模块——audio_processing,源代码在目录下。
温馨提示:部分谷歌链接需要翻墙打开
部分代码:
#define USE_WEBRTC_NOISESUPPRESSION 1
#if USE_WEBRTC_NOISESUPPRESSION
#include "../WebRtcModule/signal_processing_library.h"
#include "../WebRtcModule/noise_suppression_x.h"
#include "../WebRtcModule/noise_suppression.h"
#include "../WebRtcModule/gain_control.h"
class CHHAudioEncoderG711ADenoise:public IHHAudioEncoder
CHHAudioEncoderG711ADenoise(int samplerate,int bitsize):m_RetainCount(1)
m_encoder = new CHHAudioEncoderG711A;
#if USE_WEBRTC_NOISESUPPRESSION
m_pNSinst = NULL;
//创建降噪处理句柄
if (0 != WebRtcNsx_Create(&m_pNSinst))
WRITELOG(LL_Debug,"Noise_Suppression WebRtcNs_Create err!\n");
//WebRTC只支持三种采样率,8K,16K和32K,如果超过32K,则需要重采样成符合要求的采样率,这边不做处理
if (samplerate != 8000 && samplerate != 16000 && samplerate != 32000){
WRITELOG(LL_Debug,"Noise_Suppression samplerate err! \n");
m_samplerate =
//根据采样率初始化降噪处理句柄
WebRtcNsx_Init(m_pNSinst,samplerate))
WRITELOG(LL_Debug,"Noise_Suppression WebRtcNs_Init err! \n");
int nMode = 3;
//设置降噪处理策略,nMode值只能取四个值:0,1,2,3,越高效果越好
WebRtcNsx_set_policy(m_pNSinst,nMode))
WRITELOG(LL_Debug,"Noise_Suppression WebRtcNs_set_policy err! \n");
memset(filter_state1,0,sizeof(filter_state1));
memset(filter_state12,0,sizeof(filter_state12));
memset(Synthesis_state1,0,sizeof(Synthesis_state1));
memset(Synthesis_state12,0,sizeof(Synthesis_state12));
virtual ~CHHAudioEncoderG711ADenoise(void)
if (m_encoder){
m_encoder-&Release();
m_encoder = NULL;
#if USE_WEBRTC_NOISESUPPRESSION
if (m_pNSinst){
WebRtcNsx_Free(m_pNSinst);
m_pNSinst = NULL;
protected:
virtual void Retain()
++m_RetainC
virtual void Release()
if (--m_RetainCount==0) {
virtual bool Encode(unsigned char *pInData,int nInLen,onAudioEncodeResultCallback func,void* param)
#if USE_WEBRTC_NOISESUPPRESSION
//每次取一帧10ms数据的采样点进行循环降噪
//如果是8K采样率的,则对应=80个采样点
//16K采样率对应*10=160个采样点
//32K采样率对应的是320个采样点
for (int i = 0; i & nInL i += sizeof(short)*m_samplerate/100){
//这里没有明确写出,但是实际上在项目中做了限制,每次传进来的长度是320个字节
//也就是说采样率为8K16位的话,会循环两次,16K16位的话,只会循环一次,32K8位的话也只会循环一次,具体需要根据采样率和位宽计算
if (m_samplerate == 8000){
if (nInLen - i &= 160){
short shBufferIn[80] = {0};
short shBufferOut[80] = {0};
memcpy(shBufferIn,(char*)(pInData+i),80*sizeof(short));
//将需要降噪的数据作为低频数据传入对应接口,高频数据为空,同时需要注意返回数据也是分高频和低频,此处低频数据为降噪结果
if (0 != WebRtcNsx_Process(m_pNSinst ,shBufferIn
,NULL ,shBufferOut , NULL)){
WRITELOG(LL_Debug,"Noise_Suppression WebRtcNs_Process err! \n");
memcpy(pInData+i,shBufferOut,80*sizeof(short));
}else if (m_samplerate == 16000){
if (nInLen - i &= 320){
short shBufferIn[160] = {0};
short shBufferOut[160] = {0};
memcpy(shBufferIn,(char*)(pInData+i),160*sizeof(short));
if (0 != WebRtcNsx_Process(m_pNSinst ,shBufferIn
,NULL ,shBufferOut , NULL)){
WRITELOG(LL_Debug,"Noise_Suppression WebRtcNs_Process err! \n");
memcpy(pInData+i,shBufferOut,160*sizeof(short));
//因为项目的特殊性,每次传进来的数据长度,长度只有320个字节,如果是采样率是32K的话,进来的帧长度只有5ms,并不能满足降噪处理的最低要求,为避免数据异常,不处理32K数据
//根据前辈的说法,32K数据需要分为高频和低频两个部分进行降噪,降噪后再合并为降噪后数据
//else if (m_samplerate == 32000){
if (nInLen - i &= 640)
short shBufferIn[320] = {0};
short shInL[160],shInH[160];
short shOutL[160] = {0},shOutH[160] = {0};
memcpy(shBufferIn,(char*)(pInData+i),320*sizeof(short));
//首先需要使用滤波函数将音频数据分高低频,以高频和低频的方式传入降噪函数内部
WebRtcSpl_AnalysisQMF(shBufferIn,320,shInL,shInH,filter_state1,filter_state12);
//将需要降噪的数据以高频和低频传入对应接口,同时需要注意返回数据也是分高频和低频
if (0 == WebRtcNsx_Process(m_pNSinst ,shInL
,shInH ,shOutL , shOutH))
short shBufferOut[320];
//如果降噪成功,则根据降噪后高频和低频数据传入滤波接口,然后用将返回的数据写入文件
WebRtcSpl_SynthesisQMF(shOutL,shOutH,160,shBufferOut,Synthesis_state1,Synthesis_state12);
memcpy(pInData+i,shBufferOut,320*sizeof(short));
m_encoder-&Encode(pInData,nInLen,func,param);
unsigned long m_RetainC
IHHAudioEncoder* m_
#if USE_WEBRTC_NOISESUPPRESSION
NsxHandle* m_pNS
filter_state1[6],filter_state12[6];//滤波分频需要用到的参数
Synthesis_state1[6],Synthesis_state12[6];//合并高低频数据需要用到的参数
int m_//采样率
使用过程如下:
1.创建WebRTC降噪处理句柄:WebRtcNsx_Create
2.初始化WebRTC降噪处理句柄:WebRtcNsx_Init
参数是WebRTC降噪句柄和采样率,WebRTC只支持三种采样率,8K,16K和32K,如果超过32K,则需要重采样成符合要求的采样率,这边不考虑采样率超出32K需要重采样的情况。
3.设置WebRTC降噪处理策略:WebRtcNsx_set_policy
nMode是策略的选项,但是数值越高,效果越好,估计对性能有影响,不建议在CPU性能不佳的环境使用。只能取4个值:0,1,2,3。
4.降噪处理,按帧循环处理音频数据直到数据处理完毕
要求每次取一帧长度为10ms的数据进行降噪处理,如果采样率是8K,则对应=80个采样点,16K是160个采样点,32K是320个采样点。具体到我的程序中,因为每次传进入的音频数据是8K16位的,而且缓存长度固定是320个字节,计算一下,一次送进去160个字节数据降噪,所以可以预知,循环两次。
根据前辈的说法,32K数据需要分为高频和低频两个部分进行降噪,降噪后再合并为降噪后数据
1.(可选)使用滤波函数将音频数据分为高频,低频:WebRtcSpl_AnalysisQMF将需要降噪的数据作为低频数据传入对应接口,高频数据为空,同时需要注意返回数据也是分高频和低频,此处低频数据为降噪结果。但是,如果是8K和16K数据,不需要这个步骤,可以作为低频数据直接降噪,所以这个是可选步骤。
2.降噪处理:WebRtcNsx_Process将需要降噪的数据以高频和低频传入对应接口,同时需要注意返回数据也是分高频和低频。如果是8K或者16K的数据,则作为低频数据输入,输出也是通过低频数据返回。
3.(可选)降噪成功后,将高频,低频数据合并后输出:WebRtcSpl_SynthesisQMF如果降噪成功,则根据降噪后高频和低频数据传入滤波接口,然后用将返回的数据写入文件。这一步是可选的,根据上面是否分成高低频来使用。
5.释放WebRTC降噪句柄:WebRtcNsx_Free
效果:(使用Audacity分析)语音内容:“WebRTC降噪效果对比”
WebRTC降噪效果对比:时域(降噪前为上面那个,降噪后为下面那个)
降噪前频域分析
降噪后频域分析
从图片上看,时域上音量较低的数据基本被抹平,但是不影响波形清晰,频域上,频率峰值明显加强,1500Hz到3500Hz区域,能量普遍下降,实际听的效果的话,降噪后,背景的沙沙声基本没有,但是音量也有所下降,直观感觉上,比Speex好一些。
3.根据PCM文件的音量进行阀值限制
以二进制方式打开,PCM数据其实就是音量数据,如果把音量小的声音默认为噪声,则可以通过把音量小的数值替换为0,来实现降噪,这就是第三个方法的原理,但是这个方法的缺点也是明显的,会把很多的比较小的细节声音直接去掉了。部分代码:
class CHHAudioEncoderG711ADenoise:public IHHAudioEncoder
CHHAudioEncoderG711ADenoise(int samplerate,int bitsize):m_RetainCount(1)
m_encoder = new CHHAudioEncoderG711A;
virtual ~CHHAudioEncoderG711ADenoise(void)
if (m_encoder){
m_encoder-&Release();
m_encoder = NULL;
protected:
virtual void Retain()
++m_RetainC
virtual void Release()
if (--m_RetainCount==0) {
virtual bool Encode(unsigned char *pInData,int nInLen,onAudioEncodeResultCallback func,void* param)
static const short NOISE_SIZE =256;
short* pdata = (short*)pInD
for (int i=0;i&nInLen/2;i++)
if (pdata[i]&NOISE_SIZE && pdata[i]&-NOISE_SIZE) {
pdata[i]=0;
}else if(pdata[i]&NOISE_SIZE){
pdata[i]=pdata[i]-NOISE_SIZE;
else if (pdata[i]&-NOISE_SIZE){
pdata[i]=pdata[i]+NOISE_SIZE;
m_encoder-&Encode(pInData,nInLen,func,param);
unsigned long m_RetainC
IHHAudioEncoder* m_
1.设置噪声阀值
这个数值是用来和PCM数据中的数值进行比较的,这里会使用到音量计算公式dB = 20×log(data),data就是这里的噪声阀值,如果设25dB为界点,则data 约等于18,如果设置为48
2.替换噪声
简单判断大小后就替换从实际效果上看,和Speex差不多,噪音有所减弱,但是会变为另一种方式的噪音,实际上只是把一部分数据给抹平而已,简单粗暴。
Speex因为比较早出现,相关的东西也不在更新,实际上降噪的话还是不推荐使用的;WebRTC属于兴起的技术,而且应用效果不错,比较推荐。至于自己写的基于音量阀值的那种方法,虽然效果最差,不过有时候场景简单的话,也可以考虑。一句话,不管白猫黑猫,能抓老鼠的就是好猫!写的比较简单,各位看官有高见的话可以指点一下或者讨论一下,谢谢!
参考资料链接
Speex音频降噪模块:
WebRTC音频降噪模块:
iOS开发程序猿一枚

我要回帖

更多关于 电脑屏幕闪烁 的文章

 

随机推荐