ApiDemos学习知识点之media-AudioFx(9)
来源:互联网 发布:ip网络电话机 编辑:程序博客网 时间:2024/06/08 12:38
本demo主要针对于声音波形播放的演示。
本demo中应用了很多知识点,在后面一一进行介绍和解读,现在先上一下本demo的运行界面。
接下来看一下简单的波形控件自定义类
class VisualizerView extends View { private byte[] mBytes; private float[] mPoints; private Rect mRect = new Rect(); private Paint mForePaint = new Paint(); public VisualizerView(Context context) { super(context); init(); } private void init() { mBytes = null; mForePaint.setStrokeWidth(1f); mForePaint.setAntiAlias(true); mForePaint.setColor(Color.rgb(0, 128, 255)); } public void updateVisualizer(byte[] bytes) { mBytes = bytes; invalidate(); } @Override protected void onDraw(Canvas canvas) { 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, mForePaint); }}
自定义控件的知识,就不在此处赘述了,有兴趣的小伙伴可以翻阅之前的自定义控件章节。
接下来看下运行时的Activity
做频谱应用到了Visualizer 类,这个类只在Android 2.3以上的API才支持
public class AudioFxDemo extends Activity { private static final String TAG = "AudioFxDemo"; private static final float VISUALIZER_HEIGHT_DIP = 50f; private MediaPlayer mMediaPlayer; private Visualizer mVisualizer; private Equalizer mEqualizer; private LinearLayout mLinearLayout; private VisualizerView mVisualizerView; private TextView mStatusTextView; @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); setVolumeControlStream(AudioManager.STREAM_MUSIC); mStatusTextView = new TextView(this); mLinearLayout = new LinearLayout(this); mLinearLayout.setOrientation(LinearLayout.VERTICAL); mLinearLayout.addView(mStatusTextView); setContentView(mLinearLayout); //创建媒体播放器Create the MediaPlayer mMediaPlayer = MediaPlayer.create(this, R.raw.test_cbr); / /创建一个VisualizerView(自定义),它将呈现简化的音频波浪形式到画布。 setupVisualizerFxAndUI(); setupEqualizerFxAndUI(); // Make sure the visualizer is enabled only when you actually want to receive data, and // when it makes sense to receive data. mVisualizer.setEnabled(true); // When the stream ends, we don't need to collect any more data. We don't do this in // setupVisualizerFxAndUI because we likely want to have more, non-Visualizer related code // in this callback. mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { public void onCompletion(MediaPlayer mediaPlayer) { mVisualizer.setEnabled(false); } }); mMediaPlayer.start(); mStatusTextView.setText("Playing audio..."); } private void setupEqualizerFxAndUI() { / /创建均衡器对象(一个AudioEffect子类)并将其附加到我们的媒体播放器上, 具有默认优先级(0)。 mEqualizer = new Equalizer(0, mMediaPlayer.getAudioSessionId()); mEqualizer.setEnabled(true); TextView eqTextView = new TextView(this); eqTextView.setText("Equalizer:"); mLinearLayout.addView(eqTextView); short bands = mEqualizer.getNumberOfBands(); final short minEQLevel = mEqualizer.getBandLevelRange()[0]; final short maxEQLevel = 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"); mLinearLayout.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((minEQLevel / 100) + " dB"); TextView maxDbTextView = new TextView(this); maxDbTextView.setLayoutParams(new ViewGroup.LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)); maxDbTextView.setText((maxEQLevel / 100) + " dB"); LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams( ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); layoutParams.weight = 1; SeekBar bar = new SeekBar(this); bar.setLayoutParams(layoutParams); bar.setMax(maxEQLevel - minEQLevel); bar.setProgress(mEqualizer.getBandLevel(band)); bar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { mEqualizer.setBandLevel(band, (short) (progress + minEQLevel)); } public void onStartTrackingTouch(SeekBar seekBar) {} public void onStopTrackingTouch(SeekBar seekBar) {} }); row.addView(minDbTextView); row.addView(bar); row.addView(maxDbTextView); mLinearLayout.addView(row); } } private void setupVisualizerFxAndUI() { // Create a VisualizerView (defined below), which will render the simplified audio // wave form to a Canvas. mVisualizerView = new VisualizerView(this); mVisualizerView.setLayoutParams(new ViewGroup.LayoutParams( ViewGroup.LayoutParams.FILL_PARENT, (int)(VISUALIZER_HEIGHT_DIP * getResources().getDisplayMetrics().density))); mLinearLayout.addView(mVisualizerView); // 首先实例化Visualizer,参数SessionId可以通过MediaPlayer的对象获得 mVisualizer = new Visualizer(mMediaPlayer.getAudioSessionId());
//接着设置需要转换的音乐内容长度,专业的说这就是采样,该采样值一般为2的指数倍,如64,128,256,512,1024 mVisualizer.setCaptureSize(Visualizer.getCaptureSizeRange()[1]);
//为visualizer设置监听器,当Capture一段数据后,就会触发两个函数进行处理samplingRate是采样速率,即rate值,512mHz。其中两个byte[] waveform和byte[] fft数组,分别是获得波形数据和FFT的数据,该byte数组的大小即为之前设置的采样值大小128,获得数据如下图所示。其中n为采样值,index 0 表示直流分量,Rf表示FFT计算后的实部,If表示FFT计算后的虚部。 mVisualizer.setDataCaptureListener(new Visualizer.OnDataCaptureListener() { public void onWaveFormDataCapture(Visualizer visualizer, byte[] bytes, int samplingRate) { mVisualizerView.updateVisualizer(bytes); } public void onFftDataCapture(Visualizer visualizer, byte[] bytes, int samplingRate) {} }, Visualizer.getMaxCaptureRate() / 2, true, false); }//暂停播放器 @Override protected void onPause() { super.onPause(); if (isFinishing() && mMediaPlayer != null) { mVisualizer.release(); mEqualizer.release(); mMediaPlayer.release(); mMediaPlayer = null; } }}
阅读全文
0 0
- ApiDemos学习知识点之media-AudioFx(9)
- ApiDemos学习知识点之media-MediaPlayer_Audio&MediaPlayer_Video(11)
- ApiDemos学习知识点之media-MediaPlayerDemo(12)
- ApiDemos学习知识点之media-VideoView(10)
- Android Api Demos登顶之路(九十五)Media-->AudioFx
- ApiDemos学习知识点之Sensors
- ApiDemos学习知识点之os-MorseCode(13)
- ApiDemos学习知识点之os-RotationVector(14)
- ApiDemos学习知识点之Animation-AnimationCloing
- ApiDemos学习知识点Content-InstallApk(6)
- ApiDemos知识点学习(一)
- ApiDemos知识点之Text(2)
- ApiDemos学习知识点Content-ClipBoard(3)
- ApiDemos学习知识点Content-Asset(4)
- ApiDemos学习知识点Content-PickContacts(5)
- ApiDemos学习知识点Content-Rescoures(7)
- ApiDemos学习知识点Content-ExternalStorage(8)
- Android学习四之APIDemos
- 对于html的data属性做些笔记
- maven常用命令
- 电子书:《Linux Perf Master》
- 知识众筹第9期 一个经典案例学会数据分析 | 开始分红报名
- 禅道BUG解决方案的各种说辞
- ApiDemos学习知识点之media-AudioFx(9)
- idea新建sourceFolder
- 触发器
- malloc()函数练习
- 线性回归
- C++ Primer 第四章 表达式
- MyBatis所有的JdbcType
- CAS服务端及客户端下载
- Java学习,你需要走哪些路