Android 音乐频谱实现
来源:互联网 发布:wps怎么删除筛选数据 编辑:程序博客网 时间:2024/05/01 00:05
最近在做一款音乐播放器,设计人员新设计样图时加了一个音乐频谱展示界面,如上图所示。这东西在Window的MediaPlayer中很常见,而且有多种效果。
但不知道怎么实现,我在文档的开发者指南里没有讲任何有关音乐频谱的东西,最后还是在google的源码示例中找到了。
你可以直接去参看源代码中更多内容。
所有以下所讲的功能,均需要在2.3以上的sdk中才能实现。
音频频谱的获取
首先音频的频谱相关的类叫做 android.media.audiofx.Visualizer;
需要权限 ,所以要做的第一件事 是初始化一个visualizer出来。
//使用音乐的sessionId来实例化这个类
mVisualizer = new Visualizer(mMediaPlayer.getAudioSessionId());
//设置每次捕获频谱的大小,音乐在播放中的时候采集的数据的大小或者说是采集的精度吧,我的理解,而且getCaptureSizeRange()所返回的数组里面就两个值 .文档里说数组[0]是最小值(128),数组[1]是最大值(1024)。
mVisualizer.setCaptureSize(Visualizer.getCaptureSizeRange()[1]);
//接下来就好理解了,设置一个监听器来监听不断而来的所采集的数据。一共有4个参数,第一个是监听者,第二个单位是毫赫兹,表示的是采集的频率,第三个是是否采集波形,第四个是是否采集频率
mVisualizer.setDataCaptureListener(new Visualizer.OnDataCaptureListener() {
//这个回调应该采集的是波形数据
@Override
public void onWaveFormDataCapture(Visualizer visualizer, byte[] waveform,
int samplingRate) {
//waveformView 是一个自定义的view用来按照波形来画图 一会后面再讲
waveformView.updateVisualizer(waveform);
}
//这个回调应该采集的是快速傅里叶变换有关的数据,没试过,回头有空了再试试
@Override
public void onFftDataCapture(Visualizer visualizer, byte[] fft,
int samplingRate) {
// TODO Auto-generated method stub
}
}, Visualizer.getMaxCaptureRate() / 2, true, false);
以上波形的数据采集就完成了,需要注意的一个点是mVisualizer.setEnabled(true);
如果你见到了以下这个错误,那基本上就是因为没有及时setEnable(false),导致setCaptureSize()这个方法出错。
E/AndroidRuntime(22259): Caused by: java.lang.IllegalStateException: setCaptureSize() called in wrong state: 2
顺带再说一个bug 如果你得到的错误代码是 -1 那么基本上的原因是你忘记了声明权限
音频频谱的展示
上面已经通过监听器获得了波形数据,那么如何展示?这仅仅是一个自定义view的问题,简单废话一下:重点提一下view中的onDraw()方法:
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//mBytes就是采集来的数据 这里是个大小为1024的数组,里面的数据都是byts类型,所以大小为-127到128
if (mBytes == null) {
return;
}
if (mPoints == null || mPoints.length < mBytes.length * 4) {
//mPoints主要用来存储要画直线的4个坐标(每个点两个坐标,所以一条直线需要两个点,也就是4个坐标)
mPoints = new float[mBytes.length * 4];
}
mRect.set(0, 0, getWidth(), getHeight());
//xOrdinate是x轴的总刻度,因为一次会传输过来1024个数据,每两个数据要画成一条直线,所以x轴我们分成1023段。你要是觉的太多了,也可以像我一样除以2,看自己需求了。
int xOrdinate = (mBytes.length - 1)/2;
//以下的for循环将利用mBytes[i] mBytes[i+1] 这两个数据去生成4个坐标值,从而在刻画成两个坐标,来画线条
for (int i = 0; i
//第i个点在总横轴上的坐标,
mPoints[i * 4] = mRect.width() * i / xOrdinate;
//第i个点的在总纵轴上的坐标。他在画线上以总纵轴的1/2为基准线(mRect.height() / 2),所有的点或正或负以此线为基础标记。
//((byte) (mBytes[i] + 128))这个一直没有理解,如果+128是为了将数据全部换算为正整数,那么强转为byte后不又变回-127到128了么??要是谁知道原因可以留言告诉我.....
//(mRect.height() / 2) / 128就是将二分之一的总长度换算成128个刻度,因为我们的数据是byte类型,所以刻画成128个刻度正好
mPoints[i * 4 + 1] = mRect.height() / 2+ ((byte) (mBytes[i] + 128)) * (mRect.height() / 2) / 128;
//以下就是刻画第i+1个数据了,原理和刻画第i个一样
mPoints[i * 4 + 2] = mRect.width() * (i + 1) / xOrdinate;
mPoints[i * 4 + 3] = mRect.height() / 2 + ((byte) (mBytes[i + 1] + 128)) * (mRect.height() / 2) / 128;
}
//循环结束后,就得到了这一次波形的所有刻画坐标,直接画在画布上就好了
canvas.drawLines(mPoints, mForePaint);
}
参考:
http://blog.csdn.net/caryee89/article/details/6935237
开源组件
此外,通过还可以通过示波器实现话筒声音效果:
http://blog.csdn.net/hellogv/article/details/6032046
音乐文件 字符乱码问题解决
这几天做 音乐播放器的时候遇到这个问题,在我的Nexus S上 音乐歌曲名获取没有问题,但是歌手和 专辑总是显示乱码。HTC不会显示乱码这个不知道为何呢。。。。。。于是Google之 ,发现这个Android不能解析“gbk 32”编码的音乐文件。
后来我就 new String( str.getBytes("utf-8"))
就解决了这个问题
- Android 音乐频谱实现
- Android 音乐频谱实现
- Android 音乐频谱实现
- Android 音乐频谱实现
- android音乐柱状频谱实现
- android音乐柱状频谱实现
- android音乐柱状频谱实现
- android音乐柱状频谱实现
- android 音乐频谱
- android 音乐频谱
- android音乐频谱解析
- android音乐频谱解析
- Android 音乐柱状频谱控件
- android获取和展示音乐的频谱
- android获取和展示音乐的频谱
- android获取和展示音乐的频谱
- android获取和展示音乐的频谱
- android音乐播放器频谱图控件
- Python程序员最常犯的十个错误
- OpenCV中的CV_EXPORT是什么意思
- HDU 1056 HangOver(数学题)
- 为什么有人说不建议建立表与表之间的主外键关系
- eclipse调试百度地图demo提示 230错误 Scode码校验失败
- Android 音乐频谱实现
- 深入浅出Java并发包—锁机制(三)
- 栈的压入、弹出序列
- LeetCode 146. LRU Cache
- kubernetes安装教程(CentOS7 )
- maven如何修改本地仓库与中央仓库
- JavaScript和Java的区别
- MAC下 Redis php扩展安装
- 欢迎使用CSDN-markdown编辑器