600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > java音频频谱_Android 音乐频谱实现

java音频频谱_Android 音乐频谱实现

时间:2020-01-08 12:51:44

相关推荐

java音频频谱_Android 音乐频谱实现

最近由于需要实现音乐频谱,所以今天就为大家普及一下。关于音乐频谱你需要了解数字信号处理的知识,尤其是FFT的知识。简单说就是把时域上连续的信号(波形)强度转换成离散的频域信号(频谱)。我理解波形就是信号的强度,或者说音响设备的输出的功率,功率高,音量就大。但是歌曲的曲调是不会变的,因为频谱是不会变的。

频谱反映的是这个这个音乐在某个连续时间段内,声音的震动频率。不知道理解的对不对。

本文的音乐频谱实现是仿照Android Api Demo 里的一个例子实现的,需要Android 2.3及以上系统,因为要用到Visualizer 类,这个类只在Android 2.3以上的API才支持。

首先实例化Visualizer,参数SessionId可以通过MediaPlayer的对象获得

visualizer=newVisualizer(mPlayerInstance.getAudioSessionId());

接着设置需要转换的音乐内容长度,专业的说这就是采样,该采样值一般为2的指数倍,如64,128,256,512,1024。这里我设置了128,原因是长度越长,FFT算法运行时间更长。

visualizer.setCaptureSize(Visualizer.getCaptureSizeRange()[0]);

然后为visualizer设置监听器,这样当Capture一段数据后,就会触发两个函数进行处理。设置监听函数为

setDataCaptureListener(OnDataCaptureListenerlistener,rata,iswave,isfft)

参数解释:

rate, 表示采样的周期,即隔多久采样一次,联系前文就是隔多久采样128个数据,本文设置为512mHz更新一次

iswave,是波形信号

isfft,是FFT信号,表示是获取波形信号还是频域信号

OnDataCaptureListener,表监听函数,匿名内部类实现该接口,该接口需要实现两个函数

onWaveFormDataCapture(Visualizervisualizer,byte[]waveform,intsamplingRate)

publicvoidonFftDataCapture(Visualizervisualizer,byte[]fft,intsamplingRate)

samplingRate是采样速率,即上文的rate值,512mHz。

其中两个byte[] waveform和byte[] fft数组,分别是获得波形数据和FFT的数据,该byte数组的大小即为之前设置的采样值大小128,获得数据如下图所示。

其中n为采样值,index 0 表示直流分量,Rf表示FFT计算后的实部,If表示FFT计算后的虚部。

如何计算出该频率,就是将FFT的实部和对应的虚部先各自平方再相加然后开方,简单说就是平方取模。

具体计算请看如下的代码。

visualizer.setDataCaptureListener(

newVisualizer.OnDataCaptureListener(){

@Override

publicvoidonWaveFormDataCapture(Visualizervisualizer,

byte[]waveform,intsamplingRate){

//这里添加获得数据的处理byte[]数组更新出去,并画图。这里可以把这个

//数组传到RunOnMusic里去

//visualView.updateVisualizer(waveform);

}

@Override

publicvoidonFftDataCapture(Visualizervisualizer,

byte[]fft,intsamplingRate){

byte[]model=newbyte[fft.length/2+1];

model[0]=(byte)Math.abs(fft[1]);

intj=1;

for(inti=2;i

model[j]=(byte)Math.hypot(fft[i],fft[i+1]);

i+=2;

j++;

}

visualView.updateVisualizer(model);

}

},Visualizer.getMaxCaptureRate()/2,false,true);

}

其中visualView是显示程序,updateVisulizer是将model获取的频谱值更新到要显示的view。

protectedvoidonDraw(Canvascanvas){

super.onDraw(canvas);

if(mBytes==null){

return;

}

if(mPoints==null||mPoints.length

mPoints=newfloat[mBytes.length*4];

mRect.set(0,0,getWidth(),getHeight()-50);

for(inti=0;i

if(mBytes[i]

mBytes[i]=127;

mPoints[i*4]=mRect.width()*i/9;

mPoints[i*4+1]=mRect.height()/2;

mPoints[i*4+2]=mRect.width()*i/9;

mPoints[i*4+3]=2+mRect.height()/2+mBytes[i];

}

canvas.drawLines(mPoints,mForePaint);

}

}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。