Android 音频均衡器,可通过拖动调节音频EQ

it2022-05-09  31

  2.3之后,Google 为Mediaplayer 类添加了EQ支持,如果你需要使用这个EQ功能,有两点需要注意,分别为如下:

在配置文件中设置最小的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( " 播放中。。。 " );

 

 

 

完整运行效果:

 

试试改变一下拖动条,听一下音频有什么变化。

源码下载:

音频频谱操作

 

注:源码内没有包含音频文件,测试的话自行添加一个MP3文件即可。

转载于:https://www.cnblogs.com/TerryBlog/archive/2011/01/09/1931129.html

相关资源:数据结构—成绩单生成器

最新回复(0)