java音频频谱_Android 音乐频谱实现
最近由于需要實現音樂頻譜,所以今天就為大家普及一下。關于音樂頻譜你需要了解數字信號處理的知識,尤其是FFT的知識。簡單說就是把時域上連續的信號(波形)強度轉換成離散的頻域信號(頻譜)。我理解波形就是信號的強度,或者說音響設備的輸出的功率,功率高,音量就大。但是歌曲的曲調是不會變的,因為頻譜是不會變的。
頻譜反映的是這個這個音樂在某個連續時間段內,聲音的震動頻率。不知道理解的對不對。
本文的音樂頻譜實現是仿照Android Api Demo 里的一個例子實現的,需要Android 2.3及以上系統,因為要用到Visualizer 類,這個類只在Android 2.3以上的API才支持。
首先實例化Visualizer,參數SessionId可以通過MediaPlayer的對象獲得
visualizer?=?new?Visualizer(mPlayerInstance.getAudioSessionId());
接著設置需要轉換的音樂內容長度,專業的說這就是采樣,該采樣值一般為2的指數倍,如64,128,256,512,1024。這里我設置了128,原因是長度越長,FFT算法運行時間更長。
visualizer.setCaptureSize(Visualizer.getCaptureSizeRange()[0]);
然后為visualizer設置監聽器,這樣當Capture一段數據后,就會觸發兩個函數進行處理。設置監聽函數為
setDataCaptureListener(OnDataCaptureListener?listener,?rata,iswave,isfft?)
參數解釋:
rate, 表示采樣的周期,即隔多久采樣一次,聯系前文就是隔多久采樣128個數據,本文設置為512mHz更新一次
iswave,是波形信號
isfft,是FFT信號,表示是獲取波形信號還是頻域信號
OnDataCaptureListener,表監聽函數,匿名內部類實現該接口,該接口需要實現兩個函數
onWaveFormDataCapture(Visualizer?visualizer,byte[]?waveform,?int?samplingRate)
和
public?void?onFftDataCapture(Visualizer?visualizer,byte[]?fft,?int?samplingRate)
samplingRate是采樣速率,即上文的rate值,512mHz。
其中兩個byte[] waveform和byte[] fft數組,分別是獲得波形數據和FFT的數據,該byte數組的大小即為之前設置的采樣值大小128,獲得數據如下圖所示。
其中n為采樣值,index 0 表示直流分量,Rf表示FFT計算后的實部,If表示FFT計算后的虛部。
如何計算出該頻率,就是將FFT的實部和對應的虛部先各自平方再相加然后開方,簡單說就是平方取模。
具體計算請看如下的代碼。
visualizer.setDataCaptureListener(
new?Visualizer.OnDataCaptureListener()?{
@Override
public?void?onWaveFormDataCapture(Visualizer?visualizer,
byte[]?waveform,?int?samplingRate)?{
//?這里添加獲得數據的處理?byte[]?數組?更新出去,并畫圖。這里可以把這個
//?數組傳到RunOnMusic里去
//?visualView.updateVisualizer(waveform);
}
@Override
public?void?onFftDataCapture(Visualizer?visualizer,
byte[]?fft,?int?samplingRate)?{
byte[]?model?=?new?byte[fft.length?/?2?+?1];
model[0]?=?(byte)?Math.abs(fft[1]);
int?j?=?1;
for?(int?i?=?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。
protected?void?onDraw(Canvas?canvas)?{
super.onDraw(canvas);
if?(mBytes?==?null)?{
return;
}
if?(mPoints?==?null?||?mPoints.length?
mPoints?=?new?float[mBytes.length?*?4];
mRect.set(0,?0,?getWidth(),?getHeight()?-?50);
for?(int?i?=?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);
}
}
總結
以上是生活随笔為你收集整理的java音频频谱_Android 音乐频谱实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2016TI杯智能电子秤的设计
- 下一篇: wpsmac和pc版的区别_WPS Ma