音乐播放曲谱图(柱形和曲线图谱)
生活随笔
收集整理的這篇文章主要介紹了
音乐播放曲谱图(柱形和曲线图谱)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一、柱形圖譜
MainActivity.class
package im.com.work.qupudemo;import android.content.Intent; import android.media.AudioManager; import android.media.MediaPlayer; import android.media.audiofx.Visualizer; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.LinearLayout;public class ZhuxingActivity extends AppCompatActivity {Button qxbtn1;private static final String TAG = "AudioFxActivity";private static final float VISUALIZER_HEIGHT_DIP = 50f;private MediaPlayer mMediaPlayer;private Visualizer mVisualizer;BaseVisualizerView mBaseVisualizerView;LinearLayout ll;public void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_zhuxing);qxbtn1 = (Button) findViewById(R.id.qxbtn1);ll = (LinearLayout) findViewById(R.id.ll);setVolumeControlStream(AudioManager.STREAM_MUSIC);mMediaPlayer = MediaPlayer.create(this, R.raw.test);setupVisualizerFxAndUi();mVisualizer.setEnabled(true);mMediaPlayer.start();mMediaPlayer.setLooping(true);mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {public void onCompletion(MediaPlayer mediaPlayer) {mVisualizer.setEnabled(false);}});qxbtn1.setOnClickListener(new View.OnClickListener() {@Override public void onClick(View v) {mMediaPlayer.stop();Intent intent =new Intent(ZhuxingActivity.this,MainActivity.class);startActivity(intent);}});}/** * 生成一個VisualizerView對象,使音頻頻譜的波段能夠反映到 VisualizerView上 */ private void setupVisualizerFxAndUi(){mBaseVisualizerView = new BaseVisualizerView(this);mBaseVisualizerView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,(int) (VISUALIZER_HEIGHT_DIP * getResources().getDisplayMetrics().density)));ll.addView(mBaseVisualizerView);mVisualizer = new Visualizer(mMediaPlayer.getAudioSessionId());// 參數內必須是2的位數 mVisualizer.setCaptureSize(Visualizer.getCaptureSizeRange()[1]);// 設置允許波形表示,并且捕獲它 mBaseVisualizerView.setVisualizer(mVisualizer);}@Override protected void onPause(){// TODO Auto-generated method stub super.onPause();if (isFinishing() && mMediaPlayer != null){ mMediaPlayer.stop();mVisualizer.release();mMediaPlayer.release();mMediaPlayer = null;}}}
VisualizerView.class
package im.com.work.qupudemo;import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.view.View;/** * Created by 何 禮 波 on 2017/1/2. */ public class VisualizerView extends View {private byte[] mBytes;private float[] mPoints;//矩形區域 private Rect mRect = new Rect();// 畫筆 private Paint mForePaint = new Paint();// 初始化畫筆 private void init() {mBytes = null;mForePaint.setStrokeWidth(1f);mForePaint.setAntiAlias(true);mForePaint.setColor(Color.GREEN);}public VisualizerView(Context context) {super(context);init();}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);}}
BaseVisualizerView.class
package im.com.work.qupudemo;import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Cap;
import android.graphics.Paint.Join;
import android.media.audiofx.Visualizer;
import android.view.View;public class BaseVisualizerView extends View implements Visualizer.OnDataCaptureListener{private static final int DN_W = 480;private static final int DN_H = 160;private static final int DN_SL =14;private static final int DN_SW = 6;private int hgap = 0;private int vgap = 0;private int levelStep = 0;private float strokeWidth = 0;private float strokeLength = 0;/**
* It is the max level.
*/
protected final static int MAX_LEVEL = 13;/**
* It is the cylinder number.
*/
protected final static int CYLINDER_NUM = 20;/**
* It is the visualizer.
*/
protected Visualizer mVisualizer = null;/**
* It is the paint which is used to draw to visual effect.
*/
protected Paint mPaint = null;/**
* It is the buffer of fft.
*/
protected byte[] mData = new byte[CYLINDER_NUM];boolean mDataEn = true;/**
* It constructs the base visualizer view.
* @param context It is the context of the view owner.
*/
public BaseVisualizerView(Context context) {super(context);mPaint = new Paint();mPaint.setAntiAlias(true);mPaint.setColor(0xFFd60d25);//0x3001FFFF 0xFFd60d25
mPaint.setStrokeJoin(Join.ROUND);mPaint.setStrokeCap(Cap.ROUND);}@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {super.onLayout(changed, left, top, right, bottom);float w, h, xr, yr;w = right - left;h = bottom - top;xr = w / (float)DN_W;yr = h / (float)DN_H;strokeWidth = DN_SW * yr;strokeLength = DN_SL * xr;hgap = (int)((w - strokeLength * CYLINDER_NUM) / (CYLINDER_NUM + 1) );vgap = (int)(h / (MAX_LEVEL + 2));mPaint.setStrokeWidth(strokeWidth);}protected void drawCylinder(Canvas canvas, float x, byte value) {if (value < 0) value = 0;for (int i = 0; i < value; i++) {float y = getHeight() - i * vgap - vgap;canvas.drawLine(x, y, x + strokeLength, y, mPaint);}}@Override
public void onDraw(Canvas canvas) {for (int i = 0; i < CYLINDER_NUM; i ++) {drawCylinder(canvas, strokeWidth / 2 + hgap + i * (hgap + strokeLength), mData[i]);}}/**
* It sets the visualizer of the view. DO set the viaulizer to null when exit the program.
* @parma visualizer It is the visualizer to set.
*/
public void setVisualizer(Visualizer visualizer) {if (visualizer != null) {if (!visualizer.getEnabled()) {visualizer.setCaptureSize(Visualizer.getCaptureSizeRange()[0]);}levelStep = 128 / MAX_LEVEL;visualizer.setDataCaptureListener(this, Visualizer.getMaxCaptureRate() / 2, false, true);} else {if (mVisualizer != null) {mVisualizer.setEnabled(false);mVisualizer.release();}}mVisualizer = visualizer;}@Override
public void onFftDataCapture(Visualizer visualizer, byte[] fft,int samplingRate) {byte[] model = new byte[fft.length / 2 + 1];if (mDataEn) {model[0] = (byte) Math.abs(fft[1]); int j = 1; for (int i = 2; i < fft.length;) {model[j] = (byte) Math.hypot(fft[i], fft[i + 1]); i += 2; j++; }} else {for (int i = 0; i < CYLINDER_NUM; i ++) {model[i] = 0;}}for (int i = 0; i < CYLINDER_NUM; i ++) {final byte a = (byte)(Math.abs(model[CYLINDER_NUM - i]) / levelStep);final byte b = mData[i];if (a > b) {mData[i] = a;} else {if (b > 0) {mData[i]--;}}}postInvalidate();}@Override
public void onWaveFormDataCapture(Visualizer visualizer, byte[] waveform,int samplingRate) {// Do nothing.
}/**
* It enables or disables the data processs.
* @param en If this value is true it enables the data process..
*/
public void enableDataProcess(boolean en) {mDataEn = en;}
}
activity_zhuxing.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="im.com.work.qupudemo.ZhuxingActivity"> <Button android:id="@+id/qxbtn1" android:text="曲線圖" android:layout_width="match_parent" android:layout_height="wrap_content" /><LinearLayout android:id="@+id/ll" android:layout_width="200dp" android:background="#000" android:layout_height="match_parent" android:layout_gravity="center" android:orientation="vertical"></LinearLayout> </LinearLayout>
AndroidManifest.xml
記得加權限(有些手機加了權限后還要去手機“設置”那,應用的權限打開)
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /> <uses-permission android:name="android.permission.RECORD_AUDIO" />
2、曲線曲譜
package im.com.work.qupudemo;import android.media.AudioManager; import android.media.MediaPlayer; import android.media.audiofx.Visualizer; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.ViewGroup; import android.widget.LinearLayout;public class MainActivity extends AppCompatActivity {private static final String TAG = "AudioFxDemo";private static final float VISUALIZER_HEIGHT_DIP = 50f;private MediaPlayer mMediaPlayer;private Visualizer mVisualizer;private LinearLayout mLinearLayout;VisualizerView mVisualizerView;;@Override protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);setVolumeControlStream(AudioManager.STREAM_MUSIC);mLinearLayout = new LinearLayout(this);mLinearLayout.setOrientation(LinearLayout.VERTICAL);setContentView(mLinearLayout);// Create the MediaPlayer mMediaPlayer = MediaPlayer.create(this, R.raw.test);if( null == mMediaPlayer )return ;setupVisualizerFxAndUI();mVisualizer.setEnabled(true);mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {public void onCompletion(MediaPlayer mediaPlayer) {mVisualizer.setEnabled(false);}});mMediaPlayer.start();}/** * 生成一個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)));mLinearLayout.addView(mVisualizerView);int sessId = mMediaPlayer.getAudioSessionId() ;mVisualizer = new Visualizer(sessId);// 參數必須是2的位數 mVisualizer.setCaptureSize(Visualizer.getCaptureSizeRange()[1]);// 設置允許波形表示,并且捕獲它 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();mMediaPlayer.release();mMediaPlayer = null;}} }
Demo下載地址: http://download.csdn.net/detail/pigseesunset/9728509
總結
以上是生活随笔為你收集整理的音乐播放曲谱图(柱形和曲线图谱)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: guacamole协议及命令详解
- 下一篇: 神经网络模型的实际案例,神经网络模型数据