- 在配置文件中设置最小的SDK版本为9
- 添加权限android.permission.RECORD_AUDIO 即可使用,具体的使用方法,下文会介绍
-
为了使应用程序能够支持波段变化,我们需要重新定义一个VIEW对象,在onDraw 方法画频谱,代码如下:
-
-
class VisualizerView extends View {
-
-
private byte[] mBytes;
-
private float[] mPoints;
-
// 矩形区域
-
private Rect mRect = new Rect();
-
// 画笔
-
private Paint mPaint = new Paint();
-
-
// 初始化画笔
-
private void init() {
-
mBytes = null;
-
mPaint.setStrokeWidth(1f);
-
mPaint.setAntiAlias(true);
-
mPaint.setColor(Color.BLUE);
-
}
-
-
public VisualizerView(Context context) {
-
super(context);
-
init();
-
}
-
-
public void updateVisualizer(byte[] mbyte) {
-
mBytes = mbyte;
-
invalidate();
-
}
-
-
@Override
-
protected void onDraw(Canvas canvas) {
-
// TODO Auto-generated method stub
-
super.onDraw(canvas);
-
-
if (mBytes == null) {
-
return;
-
}
-
if (mPoints == null || mPoints.length < mBytes.length * 4) {
-
mPoints = new float[mBytes.length * 4];
-
}
-
-
mRect.set(0, 0, getWidth(), getHeight());
-
-
for (int i = 0; i < mBytes.length - 1; i++) {
-
mPoints[i * 4] = mRect.width() * i / (mBytes.length - 1);
-
mPoints[i * 4 + 1] = mRect.height() / 2
-
+ ((byte) (mBytes[i] + 128)) * (mRect.height() / 2)
-
/ 128;
-
mPoints[i * 4 + 2] = mRect.width() * (i + 1)
-
/ (mBytes.length - 1);
-
mPoints[i * 4 + 3] = mRect.height() / 2
-
+ ((byte) (mBytes[i + 1] + 128)) * (mRect.height() / 2)
-
/ 128;
-
}
-
-
canvas.drawLines(mPoints, mPaint);
-
}
-
}
-
-
-
另外,为了使用EQ和频谱可视化,我们必须了解以下两个类:
-
Visualizer
此类能使应用程序获取当前有效的一部分音频可视化的目的。使用此类必须添加上面提到的权限。
-
Equalizer
一个均衡器的类,使用此类可以轻松的操纵音频的频段,和输出的混合 。 -
具体使用代码和注释见下面:
-
-
/**
-
* 通过mMediaPlayer返回的AudioSessionId创建一个优先级为0均衡器对象 并且通过频谱生成相应的UI和对应的事件
-
*/
-
private void setupEqualizeFxAndUi() {
-
mEqualizer = new Equalizer(0, mMediaPlayer.getAudioSessionId());
-
mEqualizer.setEnabled(true);// 启用均衡器
-
TextView eqTextView = new TextView(this);
-
eqTextView.setText("均衡器:");
-
mLayout.addView(eqTextView);
- // 通过均衡器得到其支持的频谱引擎
- short bands = mEqualizer.getNumberOfBands();
- // getBandLevelRange 是一个数组,返回一组频谱等级数组,
- // 第一个下标为最低的限度范围
- // 第二个下标为最大的上限,依次取出
- final short minEqualizer = mEqualizer.getBandLevelRange()[0];
- final short maxEqualizer = mEqualizer.getBandLevelRange()[1];
- for (short i = 0; i < bands; i++) {
- final short band = i;
- TextView freqTextView = new TextView(this);
- freqTextView.setLayoutParams(new ViewGroup.LayoutParams(
- ViewGroup.LayoutParams.FILL_PARENT,
- ViewGroup.LayoutParams.WRAP_CONTENT));
- freqTextView.setGravity(Gravity.CENTER_HORIZONTAL);
- // 取出中心频率
- freqTextView
- .setText((mEqualizer.getCenterFreq(band) / 1000) + "HZ");
- mLayout.addView(freqTextView);
- LinearLayout row = new LinearLayout(this);
- row.setOrientation(LinearLayout.HORIZONTAL);
- TextView minDbTextView = new TextView(this);
- minDbTextView.setLayoutParams(new ViewGroup.LayoutParams(
- ViewGroup.LayoutParams.WRAP_CONTENT,
- ViewGroup.LayoutParams.WRAP_CONTENT));
- minDbTextView.setText((minEqualizer / 100) + " dB");
- TextView maxDbTextView = new TextView(this);
- maxDbTextView.setLayoutParams(new ViewGroup.LayoutParams(
- ViewGroup.LayoutParams.WRAP_CONTENT,
- ViewGroup.LayoutParams.WRAP_CONTENT));
- maxDbTextView.setText((maxEqualizer / 100) + " dB");
- LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
- ViewGroup.LayoutParams.FILL_PARENT,
- ViewGroup.LayoutParams.WRAP_CONTENT);
- layoutParams.weight = 1;
- SeekBar seekbar = new SeekBar(this);
- seekbar.setLayoutParams(layoutParams);
- seekbar.setMax(maxEqualizer - minEqualizer);
- seekbar.setProgress(mEqualizer.getBandLevel(band));
- seekbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
- @Override
- public void onStopTrackingTouch(SeekBar seekBar) {
- }
- @Override
- public void onStartTrackingTouch(SeekBar seekBar) {
- }
- @Override
- public void onProgressChanged(SeekBar seekBar, int progress,
- boolean fromUser) {
- // TODO Auto-generated method stub
- mEqualizer.setBandLevel(band,
- (short) (progress + minEqualizer));
- }
- });
- row.addView(minDbTextView);
- row.addView(seekbar);
- row.addView(maxDbTextView);
- mLayout.addView(row);
- }
- }
-
-
-
-
-
- /**
- * 生成一个VisualizerView对象,使音频频谱的波段能够反映到 VisualizerView上
- */
- private void setupVisualizerFxAndUi() {
- mVisualizerView = new VisualizerView(this);
- mVisualizerView.setLayoutParams(new ViewGroup.LayoutParams(
- ViewGroup.LayoutParams.FILL_PARENT,
- (int) (VISUALIZER_HEIGHT_DIP * getResources()
- .getDisplayMetrics().density)));
- mLayout.addView(mVisualizerView);
- mVisualizer = new Visualizer(mMediaPlayer.getAudioSessionId());
- // 参数内必须是2的位数
- mVisualizer.setCaptureSize(Visualizer.getCaptureSizeRange()[1]);
- // 设置允许波形表示,并且捕获它
- mVisualizer.setDataCaptureListener(new OnDataCaptureListener() {
- @Override
- public void onWaveFormDataCapture(Visualizer visualizer,
- byte[] waveform, int samplingRate) {
- // TODO Auto-generated method stub
- mVisualizerView.updateVisualizer(waveform);
- }
- @Override
- public void onFftDataCapture(Visualizer visualizer, byte[] fft,
- int samplingRate) {
- // TODO Auto-generated method stub
- }
- }, Visualizer.getMaxCaptureRate() / 2, true, false);
- }
-
-
-
- 进入程序后,在程序入口加载如下代码:
-
- mStatusTextView = new TextView(this);
- mLayout = new LinearLayout(this);
- mLayout.setOrientation(LinearLayout.VERTICAL);
- mLayout.addView(mStatusTextView);
- setContentView(mLayout);
- mMediaPlayer = MediaPlayer.create(this, R.raw.eason);
- setupVisualizerFxAndUi();
- setupEqualizeFxAndUi();
- mVisualizer.setEnabled(true);
- mMediaPlayer.setOnCompletionListener(new OnCompletionListener() {
- @Override
- public void onCompletion(MediaPlayer mp) {
- // TODO Auto-generated method stub
- mVisualizer.setEnabled(false);
- }
- });
- mMediaPlayer.start();
- mStatusTextView.setText("播放中。。。");
-
-
-
- 完整运行效果:
![]()
-
- 试试改变一下拖动条,听一下音频有什么变化。
- 源码下载:
posted @
2014-11-20 19:30
bug2048
阅读(
30)
评论()
收藏
举报