Android播放音乐时跳动的屏谱demo

Android实现播放音频时的跳动频谱,并实现可以调节的均衡器。

Main.java

 
  1. package com.wjq.audiofx;  
  2.   
  3. import android.app.Activity;  
  4. import android.media.AudioManager;  
  5. import android.media.MediaPlayer;  
  6. import android.media.audiofx.Equalizer;  
  7. import android.media.audiofx.Visualizer;  
  8. import android.os.Bundle;  
  9. import android.util.Log;  
  10. import android.view.Gravity;  
  11. import android.view.ViewGroup;  
  12. import android.widget.LinearLayout;  
  13. import android.widget.SeekBar;  
  14. import android.widget.TextView;  
  15.   
  16. public class Main extends Activity {  
  17.     private static final String TAG = "AudioFxDemo";  
  18.   
  19.     private static final float VISUALIZER_HEIGHT_DIP = 50f;  
  20.   
  21.     private MediaPlayer mMediaPlayer;  
  22.     private Visualizer mVisualizer;  
  23.     private Equalizer mEqualizer;//均横器  
  24.   
  25.     private LinearLayout mLinearLayout;  
  26.     VisualizerView mVisualizerView;  
  27.     private TextView mStatusTextView;  
  28.   
  29.     @Override  
  30.     public void onCreate(Bundle icicle) {  
  31.         super.onCreate(icicle);  
  32.         setVolumeControlStream(AudioManager.STREAM_MUSIC);  
  33.         mStatusTextView = new TextView(this);  
  34.         mLinearLayout = new LinearLayout(this);  
  35.         mLinearLayout.setOrientation(LinearLayout.VERTICAL);  
  36.         mLinearLayout.addView(mStatusTextView);  
  37.         setContentView(mLinearLayout);  
  38.         // Create the MediaPlayer  
  39.         mMediaPlayer = MediaPlayer.create(this, R.raw.test_cbr);  
  40.         if( null == mMediaPlayer )  
  41.             return ;  
  42.         Log.d(TAG, "MediaPlayer audio session ID: " + mMediaPlayer.getAudioSessionId());  
  43.   
  44.         setupVisualizerFxAndUI();  
  45.         setupEqualizerFxAndUI();  
  46.         // Make sure the visualizer is enabled only when you actually want to receive data, and  
  47.         // when it makes sense to receive data.  
  48.         mVisualizer.setEnabled(true);  
  49.   
  50.         // When the stream ends, we don't need to collect any more data. We don't do this in  
  51.         // setupVisualizerFxAndUI because we likely want to have more, non-Visualizer related code  
  52.         // in this callback.  
  53.         mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {  
  54.             public void onCompletion(MediaPlayer mediaPlayer) {  
  55.                 mVisualizer.setEnabled(false);  
  56.             }  
  57.         });  
  58.   
  59.         mMediaPlayer.start();  
  60.         mStatusTextView.setText("播放音频...");  
  61.     }  
  62.   
  63.     /** 
  64.      * 通过mMediaPlayer返回的AudioSessionId创建一个优先级为0均衡器对象,并且通过频谱生成相应的UI和对应的事件 
  65.      */  
  66.     private void setupEqualizerFxAndUI() {  
  67.         mEqualizer = new Equalizer(0, mMediaPlayer.getAudioSessionId());  
  68.         // 启用均衡器  
  69.         mEqualizer.setEnabled(true);  
  70.       
  71.         TextView eqTextView = new TextView(this);  
  72.         eqTextView.setText("均横器:");  
  73.         mLinearLayout.addView(eqTextView);  
  74.         // 通过均衡器得到其支持的频谱引擎  
  75.         short bands = mEqualizer.getNumberOfBands();  
  76.         // getBandLevelRange是一个数组,返回一组频谱等级数组,返回一组频谱等级数组  
  77.         // 第一个下标为最低的限度范围,第二个下标为最高的限度范围  
  78.         // 依次取出  
  79.         final short minEQLevel = mEqualizer.getBandLevelRange()[0];  
  80.         final short maxEQLevel = mEqualizer.getBandLevelRange()[1];  
  81.       
  82.         for (short i = 0; i < bands; i++) {  
  83.             final short band = i;  
  84.       
  85.             TextView freqTextView = new TextView(this);  
  86.             freqTextView.setLayoutParams(new ViewGroup.LayoutParams(  
  87.                     ViewGroup.LayoutParams.FILL_PARENT,  
  88.                     ViewGroup.LayoutParams.WRAP_CONTENT));  
  89.             freqTextView.setGravity(Gravity.CENTER_HORIZONTAL);  
  90.             freqTextView.setText((mEqualizer.getCenterFreq(band) / 1000) + " Hz");  
  91.             mLinearLayout.addView(freqTextView);  
  92.       
  93.             LinearLayout row = new LinearLayout(this);  
  94.             row.setOrientation(LinearLayout.HORIZONTAL);  
  95.       
  96.             TextView minDbTextView = new TextView(this);  
  97.             minDbTextView.setLayoutParams(new ViewGroup.LayoutParams(  
  98.                     ViewGroup.LayoutParams.WRAP_CONTENT,  
  99.                     ViewGroup.LayoutParams.WRAP_CONTENT));  
  100.             minDbTextView.setText((minEQLevel / 100) + " dB");  
  101.       
  102.             TextView maxDbTextView = new TextView(this);  
  103.             maxDbTextView.setLayoutParams(new ViewGroup.LayoutParams(  
  104.                     ViewGroup.LayoutParams.WRAP_CONTENT,  
  105.                     ViewGroup.LayoutParams.WRAP_CONTENT));  
  106.             maxDbTextView.setText((maxEQLevel / 100) + " dB");  
  107.       
  108.             LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(  
  109.                     ViewGroup.LayoutParams.FILL_PARENT,  
  110.                     ViewGroup.LayoutParams.WRAP_CONTENT);  
  111.               
  112.             layoutParams.weight = 1;  
  113.               
  114.             SeekBar bar = new SeekBar(this);  
  115.             bar.setLayoutParams(layoutParams);  
  116.             bar.setMax(maxEQLevel - minEQLevel);  
  117.             bar.setProgress(mEqualizer.getBandLevel(band));  
  118.       
  119.             bar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {  
  120.                 public void onStopTrackingTouch(SeekBar seekBar) {}  
  121.                 public void onStartTrackingTouch(SeekBar seekBar) {}  
  122.                   
  123.                 public void onProgressChanged(SeekBar seekBar, int progress,  
  124.                         boolean fromUser) {  
  125.                     mEqualizer.setBandLevel(band, (short) (progress + minEQLevel));  
  126.                 }  
  127.       
  128.             });  
  129.       
  130.             row.addView(minDbTextView);  
  131.             row.addView(bar);  
  132.             row.addView(maxDbTextView);  
  133.       
  134.             mLinearLayout.addView(row);  
  135.         }  
  136.     }  
  137.   
  138.     /** 
  139.      * 生成一个VisualizerView对象,使音频频谱的波段能够反映到 VisualizerView上 
  140.      */  
  141.     private void setupVisualizerFxAndUI() {  
  142.         mVisualizerView = new VisualizerView(this);  
  143.         mVisualizerView.setLayoutParams(new ViewGroup.LayoutParams(  
  144.                 ViewGroup.LayoutParams.FILL_PARENT,  
  145.                 (int)(VISUALIZER_HEIGHT_DIP * getResources().getDisplayMetrics().density)));  
  146.         mLinearLayout.addView(mVisualizerView);  
  147.       
  148.         int sessId = mMediaPlayer.getAudioSessionId() ;  
  149.         mVisualizer = new Visualizer(sessId);  
  150.         // 参数必须是2的位数  
  151.         mVisualizer.setCaptureSize(Visualizer.getCaptureSizeRange()[1]);  
  152.         // 设置允许波形表示,并且捕获它  
  153.         mVisualizer.setDataCaptureListener(new Visualizer.OnDataCaptureListener() {  
  154.             public void onWaveFormDataCapture(Visualizer visualizer, byte[] bytes,  
  155.                     int samplingRate) {  
  156.                 mVisualizerView.updateVisualizer(bytes);  
  157.             }  
  158.       
  159.             public void onFftDataCapture(Visualizer visualizer, byte[] bytes, int samplingRate) {}  
  160.         }, Visualizer.getMaxCaptureRate() / 2, true, false);  
  161.     }  
  162.       
  163.     @Override  
  164.     protected void onPause() {  
  165.         super.onPause();  
  166.       
  167.         if (isFinishing() && mMediaPlayer != null) {  
  168.             mVisualizer.release();  
  169.             mEqualizer.release();  
  170.             mMediaPlayer.release();  
  171.             mMediaPlayer = null;  
  172.         }  
  173.     }  
  174. }  

 

VisualizerView.java

 
  1. package com.wjq.audiofx;  
  2.    
  3.  import android.content.Context;  
  4.  import android.graphics.Canvas;  
  5.  import android.graphics.Color;  
  6.  import android.graphics.Paint;  
  7.  import android.graphics.Rect;  
  8.  import android.view.View;  
  9.    
  10.  public class VisualizerView extends View {  
  11.    
  12.         private byte[] mBytes;  
  13.          private float[] mPoints;  
  14.          //矩形区域  
  15.          private Rect mRect = new Rect();  
  16.          // 画笔  
  17.          private Paint mForePaint = new Paint();  
  18.    
  19.          // 初始化画笔  
  20.          private void init() {  
  21.              mBytes = null;  
  22.              mForePaint.setStrokeWidth(1f);  
  23.              mForePaint.setAntiAlias(true);  
  24.              mForePaint.setColor(Color.GREEN);  
  25.          }  
  26.            
  27.          public VisualizerView(Context context) {  
  28.              super(context);  
  29.              init();  
  30.          }  
  31.    
  32.          public void updateVisualizer(byte[] bytes) {  
  33.              mBytes = bytes;  
  34.              invalidate();  
  35.          }  
  36.    
  37.          @Override  
  38.          protected void onDraw(Canvas canvas) {  
  39.              super.onDraw(canvas);  
  40.    
  41.              if (mBytes == null) {  
  42.                  return;  
  43.              }  
  44.    
  45.              if (mPoints == null || mPoints.length < mBytes.length * 4) {  
  46.                  mPoints = new float[mBytes.length * 4];  
  47.              }  
  48.    
  49.              mRect.set(0, 0, getWidth(), getHeight());  
  50.    
  51.              for (int i = 0; i < mBytes.length - 1; i++) {  
  52.                  mPoints[i * 4] = mRect.width() * i / (mBytes.length - 1);  
  53.                  mPoints[i * 4 + 1] = mRect.height() / 2  
  54.                          + ((byte) (mBytes[i] + 128)) * (mRect.height() / 2) / 128;  
  55.                  mPoints[i * 4 + 2] = mRect.width() * (i + 1) / (mBytes.length - 1);  
  56.                  mPoints[i * 4 + 3] = mRect.height() / 2  
  57.                          + ((byte) (mBytes[i + 1] + 128)) * (mRect.height() / 2) / 128;  
  58.              }  
  59.    
  60.              canvas.drawLines(mPoints, mForePaint);  
  61.          }  
  62.    
  63.  }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值