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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > Android >内容正文

Android

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

發(fā)布時(shí)間:2024/3/26 Android 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java音频频谱_Android 音乐频谱实现 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

最近由于需要實(shí)現(xiàn)音樂頻譜,所以今天就為大家普及一下。關(guān)于音樂頻譜你需要了解數(shù)字信號(hào)處理的知識(shí),尤其是FFT的知識(shí)。簡單說就是把時(shí)域上連續(xù)的信號(hào)(波形)強(qiáng)度轉(zhuǎn)換成離散的頻域信號(hào)(頻譜)。我理解波形就是信號(hào)的強(qiáng)度,或者說音響設(shè)備的輸出的功率,功率高,音量就大。但是歌曲的曲調(diào)是不會(huì)變的,因?yàn)轭l譜是不會(huì)變的。

頻譜反映的是這個(gè)這個(gè)音樂在某個(gè)連續(xù)時(shí)間段內(nèi),聲音的震動(dòng)頻率。不知道理解的對(duì)不對(duì)。

本文的音樂頻譜實(shí)現(xiàn)是仿照Android Api Demo 里的一個(gè)例子實(shí)現(xiàn)的,需要Android 2.3及以上系統(tǒng),因?yàn)橐玫絍isualizer 類,這個(gè)類只在Android 2.3以上的API才支持。

首先實(shí)例化Visualizer,參數(shù)SessionId可以通過MediaPlayer的對(duì)象獲得

visualizer?=?new?Visualizer(mPlayerInstance.getAudioSessionId());

接著設(shè)置需要轉(zhuǎn)換的音樂內(nèi)容長度,專業(yè)的說這就是采樣,該采樣值一般為2的指數(shù)倍,如64,128,256,512,1024。這里我設(shè)置了128,原因是長度越長,FFT算法運(yùn)行時(shí)間更長。

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

然后為visualizer設(shè)置監(jiān)聽器,這樣當(dāng)Capture一段數(shù)據(jù)后,就會(huì)觸發(fā)兩個(gè)函數(shù)進(jìn)行處理。設(shè)置監(jiān)聽函數(shù)為

setDataCaptureListener(OnDataCaptureListener?listener,?rata,iswave,isfft?)

參數(shù)解釋:

rate, 表示采樣的周期,即隔多久采樣一次,聯(lián)系前文就是隔多久采樣128個(gè)數(shù)據(jù),本文設(shè)置為512mHz更新一次

iswave,是波形信號(hào)

isfft,是FFT信號(hào),表示是獲取波形信號(hào)還是頻域信號(hào)

OnDataCaptureListener,表監(jiān)聽函數(shù),匿名內(nèi)部類實(shí)現(xiàn)該接口,該接口需要實(shí)現(xiàn)兩個(gè)函數(shù)

onWaveFormDataCapture(Visualizer?visualizer,byte[]?waveform,?int?samplingRate)

public?void?onFftDataCapture(Visualizer?visualizer,byte[]?fft,?int?samplingRate)

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

其中兩個(gè)byte[] waveform和byte[] fft數(shù)組,分別是獲得波形數(shù)據(jù)和FFT的數(shù)據(jù),該byte數(shù)組的大小即為之前設(shè)置的采樣值大小128,獲得數(shù)據(jù)如下圖所示。

其中n為采樣值,index 0 表示直流分量,Rf表示FFT計(jì)算后的實(shí)部,If表示FFT計(jì)算后的虛部。

如何計(jì)算出該頻率,就是將FFT的實(shí)部和對(duì)應(yīng)的虛部先各自平方再相加然后開方,簡單說就是平方取模。

具體計(jì)算請(qǐng)看如下的代碼。

visualizer.setDataCaptureListener(

new?Visualizer.OnDataCaptureListener()?{

@Override

public?void?onWaveFormDataCapture(Visualizer?visualizer,

byte[]?waveform,?int?samplingRate)?{

//?這里添加獲得數(shù)據(jù)的處理?byte[]?數(shù)組?更新出去,并畫圖。這里可以把這個(gè)

//?數(shù)組傳到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);

}

}

總結(jié)

以上是生活随笔為你收集整理的java音频频谱_Android 音乐频谱实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。