我的视频课程(基础):《(NDK)FFmpeg打造Android万能音频播放器》

我的视频课程(进阶):《(NDK)FFmpeg打造Android视频播放器》

我的视频课程(编码直播推流):《Android视频编码和直播推流》

我的视频课程(C++ OpenGL):《Android C++ OpenGL教程》

 

        

        最近开源了一个Android音频播放库《wlmusic》可以直接在gradle中导入集成。已经实现了音频播放所有逻辑,除了播放正常的网络音频和本地音频外,还可以播放raw和assets文件中的音频和循环不间断播放短音频等功能。这些做完了之后发现一个问题,怎么能动态显示声音的波形?于是想到了一个声音的关键词“分贝”,然后百度、谷歌了一番找到了一个有用的公式:

参数:Pref:就是声音总的振幅最大值;Prms:就是当前声音的振幅值;Lp:就是我们需要的声音分贝值了。

比如:我们声音是无符号16bit深度的,那么其每个采样点的值应该在(0~2^16-1既:0~65535)范围内,带入公式我们可以计算到(不用除以最大振幅值):20*log(65535)=96.32db,所以根据这个我们只要拿到某个采样点的振幅值,也就是当前声音采样点转成16bit后的值就可以计算出相应的分贝值了。那么怎么求声音采样点的振幅呢?这是一个问题,不过也有解决办法了。

获取pcm声音采样点的振幅:

        这里以我项目中用OpenSL来播放FFmpeg重采样生成的PCM声音为例,PCM声音是重采样为无符号16bit的深度的,然后我们需要得到某一时间(一般是零点几毫秒)PCM所在内存的地址和PCM声音的大小,而16bit也就是16bit/8bit=2byte,在c语言中2byte用short int来表示,因此我们可以从PCM所在地址里面按顺序取出2个byte的数据然后转化成short int的值就可以拿到当前采样点的振幅了,获取的方式是用c语言中的memcpy拷贝2个字节的数据求值就可以了。(注:因为采用点很密集,如果每个采用点都计算一下分贝的话,会消耗一定的性能或者导致声音播放不连贯,所这里采用取其绝对值和的平均值就可以了,因为在这段时间内,我们看不出任何的区别。)

代码实现:

/** * 获取所有振幅之平均值 计算db (振幅最大值 2^16-1 = 65535 最大值是 96.32db) * 16 bit == 2字节 == short int * 无符号16bit:96.32=20*lg(65535); *  * @param pcmdata 转换成char类型,才可以按字节操作 * @param size pcmdata的大小 * @return */int Audio::getPcmDB(const unsigned char *pcmdata, size_t size) {    int db = 0;    short int value = 0;    double sum = 0;    for(int i = 0; i < size; i += 2)    {        memcpy(&value, pcmdata+i, 2); //获取2个字节的大小(值)        sum += abs(value); //绝对值求和    }    sum = sum / (size / 2); //求平均值(2个字节表示一个振幅,所以振幅个数为:size/2个)    if(sum > 0)    {        db = (int)(20.0*log10(sum));    }    return db;}

这样就可以获取到PCM声音的分贝值,绘制波形图了。最后来一张pcm音频的分贝图,毕竟无图无真相:

获取PCM音频数据的声音分贝值_第1张图片

 

更多相关文章

  1. android获取音量分贝值
  2. Android中声音的管理类AudioManager
  3. Android如何关闭键盘声音
  4. android设备上视频只有声音没有图像
  5. Android MTK 修改默认音频和声音大小
  6. android 支持的声音格式详解
  7. Android Mediaplayer设置静音和恢复声音
  8. Android之声音管理器《AudioManager》的使用以及音量控制

随机推荐

  1. Android通知栏颜色改变方法
  2. Android笔记1——开发前奏1开发环境搭建
  3. Android(安卓)创世纪 第二天
  4. android 实现listView异步加载图片
  5. android画图----ShapeDrawable和shader
  6. Android(安卓)build system note
  7. [Android]RelativeLayout中最底的View其l
  8. Android(安卓)MenuItem 设置文本颜色-Tex
  9. 实现透明渐变的Activity
  10. Android(安卓)Studio OkHttpClient使用教