日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

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

發布時間:2024/3/26 Android 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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 音乐频谱实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。