Android OpenGLES3绘图 - 音频可视化(模仿MIUI系统效果)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android OpenGLES3绘图 - 音频可视化(模仿MIUI系统效果)相关的知识,希望对你有一定的参考价值。

参考技术A

小米手机播放音乐时锁屏页面可以设置音频可视化效果,这是用OpenGL绘制出来的,我们来实现一下。

首先简单分析一下原理:
图形的每一行代表一个声音片段,它就是一个一维数组,按照数值大小绘制不同的高度,就形成了一条“山脉”;获取到下一个声音片段后,将它绘制到下面一行,然后画面整体向上滚动就可以了。整体类似于绘制一张游戏里常见的3D地形图。

创建一个MediaPlayer,它可以直接读取res/raw里面的音频文件,start()开始播放

Visualizer是android SDK里面提供的音频分析工具,它可以直接获取播放的音频的波形和频谱。onWaveFormDataCapture回调方法里返回的是原始的PCM波形数组,onFftDataCapture回调方法里返回的是经过快速傅里叶方法转换后的声音频谱数组,数组的第一位是直流分量,后面是不同频率的数值。

每次获取到的是一组声音数据,将它传给Render绘制。

首先确定图形的长宽,宽度w其实是由每组音频的数组长度决定,可以由Visualizer.getCaptureSizeRange()[0]获取,这里获取的是最小的数组,也可以用Visualizer.getCaptureSizeRange()[1]获取最大的数组;长度h可以自己设置想展示多长。

绘制地形图也就是绘制w * h * 2个三角形,创建vao、vbo和ebo,由于顶点的位置都是固定的,可以在顶点着色器中用gl_VertexID获取,所以vbo里面不用传顶点数据,直接传声音数组。

由于图形是不断刷新最后一行并向上滚动的,那么需要使用一个队列,为了每一帧数据改变最小,不至于进行大量的数组复制和移动。我们 用ByteBuffer vertexBuffer模拟一个循环队列,使用一个行号int lineNum来标记队列的头部。每添加一行数据后,lineNum会加上w,这样ByteBuffer分成了两部分:lineNum * w之后的是新旧数据,之前的是旧数据

现在我们需要将数据从主内存(vertexBuffer)复制到GPU显存(vbo)。vertexBuffer里是一个循环队列,而vbo里面只能顺序保存(因为ebo序号是顺序的,vbo不是顺序图形就会错乱),更新vbo数据缓存的glBufferSubData方法支持设置偏移位置部分更新。那么我们 先将vertexBuffer定位到lineNum * w,将它后面的旧数据复制到vbo的前面;然后将vertexBuffer定位到0,将剩下的新数据复制到vbo的后面 。这样就保证了绘制时从上到下,从旧到新。

为了让颜色更丰富,这里用了地形图中常用的热度渐变色数组。
理论上音频数值是unsigned byte格式的,但是着色器不支持byte格式,我直接用int vPosition接收数据,然而数值范围不再是0~255了,这有点奇怪,我没有深入研究。简单测试了一下,发现取int的前8位,再进行一点比例缩放,用它去渐变色数组里取颜色,会取得较好的显示效果。

顶点着色器
shader_audio_v.glsl

将颜色传给片段着色器显示
shader_audio_f.glsl

最终效果如下图,录屏设置的码率比较低,实际上是很清晰的。

完整项目在 SurfacePaint 项目下的 opengles3 模块里的audio。

WebGL-为浏览器提供3D显示支持

WebGL是一种3D绘图标准,这种绘图技术标准允许把JavaScript和OpenGL ES 2.0结合在一起,通过增加OpenGL ES 2.0的一个JavaScript绑定,WebGL可以为HTML5 Canvas提供硬件3D加速渲染,这样Web开发人员就可以借助系统显卡来在浏览器里更流畅地展示3D场景和模型了,还能创建复杂的导航和数据视觉化。显然,WebGL技术标准免去了开发网页专用渲染插件的麻烦,可被用于创建具有复杂3D结构的网站页面,甚至可以用来设计3D网页游戏等等。


WebGL完美地解决了现有的Web交互式三维动画的两个问题:第一,它通过HTML脚本本身实现Web交互式三维动画的制作,无需任何浏览器插件支持;第二,它利用底层的图形硬件加速功能进行的图形渲染,是通过统一的、标准的、跨平台的OpenGL接口实现的。


在去年Google就已经利用WebGL开发出了一个Bookcase的3D书架网页应用,可展示超过一万本图书,有28个分类,用鼠标即可让书架一直滚动下去,找到你想要的书,整个网页的3D效果赞到爆,这应该算是Google最早的一个3D网页应用吧,大家应该也早就体验过了,一起来看一段关于这个书架的视频演示:


Google搜索于近日悄然上线了一个基于WebGL技术的全新功能,能把你的浏览器变成3D计算器,也就是说当你在搜索框中输入一段公式,Google就会为你绘制出该公式的模型来,甚至还是3D的立体模型,另外你还可以自由调整和编辑曲线以及方程,这一点对数学和物理爱好者来说是非常强大的一个功能。如果你急需画出一个方程的曲线而手头又没有称手的工具的时候,Google这项功能就可以应急一下了。不过各位需要注意的一点就是,该功能只能运行在支持WebGL 的浏览器中,例如 Chrome 和 Firefox,而不是 IE!下图就是一个方程公式的3D展示:


HTML5时代即将来临,WebGL技术无疑为HTML5中3D显示提供了强有力的保障,相信用不了多久就会有越来越多的浏览器3D应用乃至大型浏览器3D游戏与大家见面。


以上是关于Android OpenGLES3绘图 - 音频可视化(模仿MIUI系统效果)的主要内容,如果未能解决你的问题,请参考以下文章

Android音视频(六) 使用OpenGL ES 3.0预览Camera

错误记录Unity 安卓打包报错( Platform Android with graphics API OpenGLES3 is not supported with HDRP )

Android 支持库 23.2 矢量绘图模糊

android 图片选择,可选择图片,视频,音频,文件,方便扩展

android 图片选择,可选择图片,视频,音频,文件,方便扩展

将原始音频字节记录到 Android 中的局部变量