android在播放音乐时如何实现动态波形?

包裹?com。AudioFx

进口?Android . app . activity;

进口?Android . content . context;

进口?Android . graphics . canvas;

进口?Android . graphics . color;

进口?Android . graphics . paint;

进口?Android . graphics . rect;

进口?Android . media . audio manager;

进口?Android . media . media player;

进口?android.media.audiofx .均衡器;

进口?Android . media . audio FX . visualizer;

进口?Android . OS . bundle;

进口?Android . util . log;

进口?Android . view . gravity;

进口?Android . view . view;

进口?Android . view . view group;

进口?Android . view . window manager;

进口?Android . widget . linear layout;

进口?Android . widget . seek bar;

进口?Android . widget . textview;

公共?班级?AudioFxActivity?延伸?活动

{

私人?静电?决赛?字符串?标签?=?”AudioFxActivity”;

私人?静电?决赛?浮动?VISUALIZER_HEIGHT_DIP?=?160 f;

私人?MediaPlayer?多媒体播放器;

私人?可视化工具?mVisualizer

私人?均衡器?mEqualizer

私人?LinearLayout?mLinearLayout

私人?VisualizerView?mVisualizerView

私人?TextView?mStatusTextView

私人?TextView?mInfoView

@覆盖

公共?作废?onCreate(捆绑?冰柱)

{

super . oncreate(icicle);

mStatusTextView?=?新的?TextView(这个);

mLinearLayout?=?新的?LinearLayout(这个);

mlinearlayout . set orientation(linear layout。垂直);

mlinearlayout . add view(mStatusTextView);

setContentView(mLinearLayout);

//?创造?那个?媒体播放器

多媒体播放器?=?MediaPlayer.create(this,?r . raw . my _ life);

Log.d(标签,

“MediaPlayer?音频?会话?ID:?"

+?mmediaplayer . getaudiosessionid());

setup visualizerfxandui();

setupequilizerfxandui();

//?制造?确定吗?那个?可视化工具?是吗?启用?只有?什么时候?你呢。真的吗?想要吗?到

//?接收?数据,?和

//?什么时候?它?制造?感觉?去哪?接收?数据。

mvisualizer . set enabled(true);

//?什么时候?那个?溪流?结束吗?我们?不要?需要?去哪?收藏?有吗?更多?数据。?我们

//?不要?做什么?这个?在

//?setupVisualizerFxAndUI?因为?我们?可能吗?想要吗?去哪?有吗?更多,

//?非可视化者?相关?密码

//?在?这个?回电。

mmediaplayer . setoncompletionlistener(新?媒体播放器。OnCompletionListener()

{

公共?作废?onCompletion(MediaPlayer?媒体播放器)

{

mvisualizer . set enabled(false);

getWindow()。clearFlags(WindowManager。layout params . FLAG _ KEEP _ SCREEN _ ON);

setVolumeControlStream(audio manager。STREAM _ SYSTEM);

MStatusTextView.setText("音乐完成");

}

});

getWindow()。addFlags(WindowManager。layout params . FLAG _ KEEP _ SCREEN _ ON);

setVolumeControlStream(audio manager。STREAM _ MUSIC);

mmediaplayer . start();

MStatusTextView.setText("播放音乐...");

}

私人?作废?setupEqualizerFxAndUI()

{

//?创造?那个?均衡器?对象?(安?音效?子类)?然后呢。附上?它

//?去哪?我们的?媒体?玩家,

//?用什么?答?违约?优先?(0).

mEqualizer?=?新的?均衡器(0,?mmediaplayer . getaudiosessionid());

me qualizer . set enabled(true);

TextView?eqTextView?=?新的?TextView(这个);

EqTextView.setText("均衡器:");

mlinearlayout . addview(eqTextView);

矮?乐队?=?me qualizer . getnumberofbands();

决赛?矮?minEQLevel?=?me qualizer . getbandlevelrange()[0];

决赛?矮?maxEQLevel?=?me qualizer . getbandlevelrange()[1];

为了什么?(短?我?=?0;?我?& lt?乐队;?i++)

{

决赛?矮?乐队?=?我;

TextView?freqTextView?=?新的?TextView(这个);

freqTextView.setLayoutParams(新?视图组。布局参数(

视图组。LayoutParams.FILL_PARENT,

视图组。layout params . WRAP _ CONTENT));

freqtextview . set Gravity(Gravity。居中_水平);

freqtextview . settext((me qualifier . getcenterfreq(band)?/?1000)

+?"?Hz”);

mlinearlayout . add view(freqTextView);

LinearLayout?划?=?新的?LinearLayout(这个);

row . set orientation(linear layout。横向);

TextView?minDbTextView?=?新的?TextView(这个);

minDbTextView.setLayoutParams(新?视图组。布局参数(

视图组。LayoutParams.WRAP_CONTENT,

视图组。layout params . WRAP _ CONTENT));

mindbtextview . settext((minEQLevel?/?100)?+?"?dB”);

TextView?maxDbTextView?=?新的?TextView(这个);

maxDbTextView.setLayoutParams(新?视图组。布局参数(

视图组。LayoutParams.WRAP_CONTENT,

视图组。layout params . WRAP _ CONTENT));

maxdbtextview . settext((maxEQLevel?/?100)?+?"?dB”);

线性布局。LayoutParams?layoutParams?=?新的?线性布局。布局参数(

视图组。LayoutParams.FILL_PARENT,

视图组。layout params . WRAP _ CONTENT);

布局参数。重量?=?1;

SeekBar?酒吧?=?新的?SeekBar(这个);

bar . setlayoutparams(layout params);

bar.setMax(maxEQLevel?-?minEQLevel);

bar . set progress(me qualizer . get band level(band));

bar.setOnSeekBarChangeListener(新?SeekBar。OnSeekBarChangeListener()

{

公共?作废?onProgressChanged(SeekBar?seekBar?int?进步,

布尔?fromUser)

{

mEqualizer.setBandLevel(band,?(短)?(进步?+?minEQLevel));

}

公共?作废?onStartTrackingTouch(参见kBar?seekBar)

{

}

公共?作废?onStopTrackingTouch(SeekBar?seekBar)

{

}

});

row . add view(minDbTextView);

row . add view(bar);

row . addview(maxDbTextView);

mlinearlayout . add view(row);

}

}

私人?作废?setupVisualizerFxAndUI()

{

mVisualizerView?=?新的?visualizer view(this);

mvisualizerview . setlayoutparams(新?视图组。布局参数(

视图组。LayoutParams.FILL_PARENT,

(int)?(VISUALIZER_HEIGHT_DIP?*?getResources()

。getDisplayMetrics()。密度)));

mlinearlayout . add view(mVisualizerView);

mInfoView?=?新的?TextView(这个);

字符串?infoStr?=?"";

int[]?csr?=?visualizer . getcapturesizerange();

如果(csr?!=?空)

{

字符串?csrStr?=?" CaptureSizeRange:";

for(int?我?=?0;?我?& lt?csr .长度;?我?++)

{

csrStr?+=?CSR[I];

csrStr?+="?";

}

infoStr?+=?csrStr

}

决赛?int?maxCR?=?visualizer . getmaxcapturerate();

infoStr?=?infoStr?+?" nMaxCaptureRate:?"?+?maxCR

minfoview . settext(infoStr);

mlinearlayout . add view(mInfoView);

mVisualizer?=?新的?可视化工具(mmediaplayer . getaudiosessionid());

mvisualizer . setcapturesize(256);

mvisualizer . setdatacapturelistener(

新的?可视化工具。OnDataCaptureListener()

{

公共?作废?onWaveFormDataCapture(可视化工具?可视化工具,

byte[]?字节,?int?采样率)

{

mvisualizerview . update visualizer(字节);

}

公共?作废?onFftDataCapture(可视化工具?可视化工具,

byte[]?fft,?int?采样率)

{

mvisualizerview . update visualizer(FFT);

}

},?maxCR?/?2,?假的,?真);

}

@覆盖

受保护?作废?onPause()

{

super . on pause();

如果?(isFinishing()?& amp& amp?多媒体播放器?!=?空)

{

mvisualizer . release();

me qualizer . release();

mmediaplayer . release();

多媒体播放器?=?null

}

}

/**

?*?答?简单?班级?那个?平局?波形?数据?收到?从哪里?a

?*?{@link?可视化工具。ondatapturelistener # onWaveFormDataCapture?}

?*/

班级?VisualizerView?延伸?视角

{

私人?byte[]?兆字节;

私人?float[]?mPoints

私人?Rect?mRect?=?新的?rect();

私人?油漆?mForePaint?=?新的?paint();

私人?int?mSpectrumNum?=?48;

私人?布尔?mFirst?=?真实;

公共?VisualizerView(上下文?上下文)

{

超级(上下文);

init();

}

私人?作废?初始化()

{

兆字节?=?null

mfore paint . setstrokewidth(8f);

mfore paint . setantialias(true);

mfore paint . set color(color . RGB(0,?128,?255));

}

公共?作废?updateVisualizer(byte[]?fft)

{

if(mFirst?)

{

minfoview . settext(minfoview . gettext()。toString()?+?" \ n捕获大小:"?+?FFT . length);

mFirst?=?假的;

}

byte[]?模特?=?新的?byte[fft.length?/?2?+?1];

型号[0]?=?(字节)?math . ABS(FFT[0]);

为了什么?(int?我?=?2,?j?=?1;?j?& lt?光谱图;)

{

型号[j]?=?(字节)?Math.hypot(fft[i],?fft【我?+?1]);

我?+=?2;

j++;

}

兆字节?=?模型;

invalidate();

}

@覆盖

受保护?作废?onDraw(画布?画布)

{

super.onDraw(画布);

如果?(兆字节?==?空)

{

返回;

}

如果?(mPoints?==?null?||?mPoints.length?& lt?兆字节。长度?*?4)

{

mPoints?=?新的?float[mBytes.length?*?4];

}

mRect.set(0,0,?getWidth(),?getHeight());

//绘制波形

//?为了什么?(int?我?=?0;?我?& lt?兆字节。长度?-?1;?i++)?{

//?mPoints[i?*?4]?=?mRect.width()?*?我?/?(兆字节.长度?-?1);

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

//?+?((字节)?(mBytes[i]?+?128))?*?(mRect.height()?/?2)?/?128;

//?mPoints[i?*?4?+?2]?=?mRect.width()?*?(我?+?1)?/?(兆字节.长度?-?1);

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

//?+?((字节)?(mBytes[i?+?1]?+?128))?*?(mRect.height()?/?2)?/?128;

//?}

//绘制频谱

决赛?int?baseX?=?mrect . width()/mSpectrumNum;

决赛?int?身高?=?mrect . height();

为了什么?(int?我?=?0;?我?& lt?mSpectrumNum?;?i++)

{

如果?(mBytes[i]?& lt?0)

{

兆字节[i]?=?127;

}

决赛?int?xi?=?baseX*i?+?baseX/2;

mPoints[i?*?4]?=?Xi;

mPoints[i?*?4?+?1]?=?身高;

mPoints[i?*?4?+?2]?=?Xi;

mPoints[i?*?4?+?3]?=?身高?-?兆字节[I];

}

canvas.drawLines(mPoints,?mfore paint);

}

}

}