一、柱形图谱

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

音乐播放曲谱图(柱形和曲线图谱)相关推荐

  1. Vue实现仿音乐播放器6-实现新歌速递与swiper轮播图切换

    前言 前面在首页已经完成今日推荐以及访问百度API获取数据,现在继续来完善home主页. 效果 新歌速递 swiper实现轮播图 实现 实现新歌速递 在components下新建新歌速递组件News_ ...

  2. Android复习13【广播:思维导图、音乐播放器】

    音乐播放器Android代码下载:https://wws.lanzous.com/ifqzihaxvij 思维导图 https://share.weiyun.com/1vVLYnlb 音乐播放器

  3. Android---Service(生命周期、启动方式、服务通信、实战演练、思维导图、高级音乐播放器-源码)

    目   录 一.服务的创建 二.服务的生命周期 三.服务的启动方式 (1)startService 方式 启动 服务 实战演练---startService (2)bindService 方式 启动 ...

  4. 音频频谱显示-基于fmod设计音乐播放器并动态显示频谱图(二)

    音频频谱显示-显示音频文件静态频谱图(一) https://blog.csdn.net/xiaolong1126626497/article/details/126971535 音频频谱显示-基于fm ...

  5. 音乐播放器的设计与实现 功能要求:设计一款基于HTML5音频技术的音乐播放器,要求实现音乐的播放、暂停、音量大小调节、上一首和下一首切换,运行效果如图所示

    本地资源在谷歌浏览器上是无法快进的.这个是重点!!!有很多解决方法,我直接用火狐就ok了 https://www.gaitubao.com/# 改图宝链接 用于修改歌曲头像 大小标准显示才正常 我用的 ...

  6. Android音乐播放器(三)轮播图

    这是去年大二做的一个简单音乐播放器项目:是尽可能模仿酷狗音乐写的,具体实现的功能如下: 1:启动动画:点击运行程序会出现一个两秒钟的视频,类似酷狗音乐的启动动画一样,非常可观! 2:登录注册界面:输入 ...

  7. html音乐播放器 频谱,HTML5 Canvas 实现简易 绘制音乐环形频谱图

    0.启发 在B站我们有很多的小伙伴们应该都看到过用AE做的可视化音乐播放器播放音乐的视频,看着特别酷炫带感有木有. B站截图 B站截图 B站截图 所以今天我就用 Canvas 做个简单 环形频谱图. ...

  8. 计算机电子表格三维簇状柱形图怎么设置,Excel中怎么制作柱形对比图【excel表格数据生成柱形图】...

    怎么创建Excel簇状柱形图并设置图表的格 第一步:插入---图表----选择"簇状柱形图" 在图表区域右击---选择数据-----点击" "号-----选择系 ...

  9. 前端切图:自制简易音乐播放器

    音乐播放器是一个非常常见的应用,这篇博客就是介绍如何制作一个简单的音乐播放器,这款音乐播放器具有以下的功能:图片旋转功能,点击播放,点击暂停播放的功能,音量调大调小功能,设置音频的播放时间,循环播放, ...

最新文章

  1. pyBoard 基于MicroPython开发STM32FXX单片机
  2. customize shell prompt
  3. 由于c语言是由字符流组成的,C语言试题及答案
  4. php 数据库 文件转移 1146 错误
  5. ADO.NET中的五个主要对象
  6. sql点滴41—MyISAM 和 InnoDB 讲解
  7. 单片机两个正玄波信号的相位差计算_51单片机的定时器/计数器的原理与使用
  8. 怎么理解python循环_如何理解Python的循环设计
  9. [转]一阶自回归模型和二阶自回归模型
  10. 统计学中RR OR AR HR的区别
  11. python自动下载酷狗音乐_python获取酷狗音乐top500的下载地址 MP3格式
  12. SoundPool详解
  13. java提取jks文件提取私钥_如何从JKS文件中取出PEM格式证书
  14. Exception in thread “main“ java.io.NotSerializableException:
  15. Complementary Trilateral Decoder for Fast and Accurate Salient Object Detection(速读啊)内含与u-shape的对比
  16. Harpoon: an OSINT / Threat Intelligence tool
  17. ERP咨询顾问必备的7种公关能力
  18. CFileDialog类学习
  19. LS1046修改寄存器翻转SATA引脚的N/P极性
  20. micro SD(TF)卡详解

热门文章

  1. (转载) 提问的艺术
  2. 使用摩客原型托管,3分钟搞定原型发布分享预览
  3. lc0426lc0501
  4. Error:(4, 35) java: 程序包org.springframework.context不存在
  5. 中心极限与大数定理律的关系_深入浅出正态分布,大数定律,中心极限定理
  6. Android判断屏幕状态与屏幕解锁和锁定
  7. 总经理专访:Acer何谦永评谈08/09笔记本产业
  8. 【案例】正浩创新:多云多资产,实现敏捷云上运维
  9. 区块链项目的黑马——NGK超级公链
  10. 【VMware】【CentOS 7 】Docker第一课:安装Docker