2019独角兽企业重金招聘Python工程师标准>>>

  在Android2.3中增加了对音频混响的支持,这些API包含在android.media.audiofx包中。 

  一、概述

  AudioEffect是android audio framework(android 音频框架)提供的音频效果控制的基类。开发者不能直接使用此类,应该使用它的派生类。 下面列出它的派生类。 

    Equalizer
    Virtualizer
    BassBoost
    PresetReverb
    EnvironmentalReverb

  当创建AudioEffect时,如果音频效果应用到一个具体的AudioTrack和MediaPlayer的实例,应用程序必须指定该实例的音频session ID,如果要应用Global音频输出混响的效果必须制定Session 0。

  要创建音频输出混响(音频 Session 0)要求要有 MODIFY_AUDIO_SETTINGS权限。

  如果要创建的效果在audio framework不存在,那么直接创建该效果,如果已经存在那么直接使用此效果。如果优先级高的对象要在低级别的对象使用该效果时,那么控制将转移到优先级高的对象上,否则继续停留在此对象上。在这种情况下,新的申请将被监听器通知。

  二、嵌套类

  1.AudioEffect.Descriptor:效果描述符包含在音频框架内实现某种特定的效果的信息。
  2.AudioEffect.OnControlStatusChangeListener:此接口定义了当应用程序的音频效果的控制状态改变时由AudioEffect调用的方法。

  3.AudioEffect.OnEnableStatusChangeListener:此接口定义了当应用程序的音频效果的启用状态改变时由AudioEffect调用的方法。

  三、常量

String ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION 关闭音频效果
String ACTION_DISPLAY_AUDIO_EFFECT_CONTROL_PANEL 启动一个音频效果控制面板UI。
String ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION 打开音频效果。
int ALREADY_EXISTS 内部操作状态。
int CONTENT_TYPE_GAME 当播放内容的类型是游戏音频时EXTRA_CONTENT_TYPE的值。
int CONTENT_TYPE_MOVIE 当播放内容的类型是电影时EXTRA_CONTENT_TYPE的值。
int CONTENT_TYPE_MUSIC 当播放内容的类型是音乐时EXTRA_CONTENT_TYPE的值。
int CONTENT_TYPE_VOICE 当播放内容的类型是话音时EXTRA_CONTENT_TYPE的值。                  
String EFFECT_AUXILIARY Effect connection mode 是auxiliary
String EFFECT_INSERT Effect connection mode 是insert.
int ERROR 指示操作错误。
int ERROR_BAD_VALUE 指示由于错误的参数导致的操作失败。
int ERROR_DEAD_OBJECT 指示由于已关闭的远程对象导致的操作失败。
int ERROR_INVALID_OPERATION 指示由于错误的请求状态导致的操作失败。
int ERROR_NO_INIT 指示由于错误的对象初始化导致的操作失败。
int ERROR_NO_MEMORY 指示由于内存不足导致的操作失败。
String EXTRA_AUDIO_SESSION 包含使用效果的音频会话ID。
String EXTRA_CONTENT_TYPE 指示应用程序播放内容的类型。
String EXTRA_PACKAGE_NAME 包含调用应用程序的包名。
int SUCCESS 操作成功。

  四、公有方法

 

AudioEffect.Descriptor getDescriptor()

获取效果描述符。
boolean getEnabled()

返回效果的启用状态。
int getId()

返回效果的标识符
boolean hasControl()

检查该AudioEffect 对象是否拥有效果引擎的控制。如果有,则返回true。
static Descriptor[] queryEffects()

查询平台上的所有有效的音频效果。
void release()

释放本地AudioEffect资源。
void setControlStatusListener(AudioEffect.OnControlStatusChangeListener listener)

注册音频效果的控制状态监听器.当控制状态改变时AudioEffect发出通知。
void setEnableStatusListener(AudioEffect.OnEnableStatusChangeListener listener)

设置音频效果的启用状态监听器。当启用状态改变时AudioEffect发出通知。
int setEnabled(boolean enabled)

Enable or disable the effect.

  五、应用(此应用来自于SDK包)

  1.新建项目

  

  你或许已经发现在2.3的项目中比2.2多一个配置文件proguard.cfg,包含混淆所需的proguard脚本。

  

  2.打开AndroidManifest.xml文件

  添加权限“android.permission.RECORD_AUDIO”。

  3.可视化工具类VisualizerView.java

  

        效果图  

  4.Main.java

  

package com.wjq.audiofx; import android.app.Activity; import android.media.AudioManager; import android.media.MediaPlayer; import android.media.audiofx.Equalizer; import android.media.audiofx.Visualizer; import android.os.Bundle; import android.util.Log; import android.view.Gravity; import android.view.ViewGroup; import android.widget.LinearLayout; import android.widget.SeekBar; import android.widget.TextView; public class Main 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); Log.d(TAG, " MediaPlayer audio session ID: " + mMediaPlayer.getAudioSessionId()); 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() { // Create the Equalizer object (an AudioEffect subclass) and attach it to our media player, // with a default priority (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); // Create the Visualizer object and attach it to our media player. mVisualizer = new Visualizer(mMediaPlayer.getAudioSessionId()); 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(); mEqualizer.release(); mMediaPlayer.release(); mMediaPlayer = null ; } } }

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 private Rect mRect = new Rect(); 15 16 private Paint mForePaint = new Paint(); 17 18 public VisualizerView(Context context) { 19 super (context); 20 init(); 21 } 22 23 private void init() { 24 mBytes = null ; 25 26 mForePaint.setStrokeWidth(1f); 27 mForePaint.setAntiAlias( true ); 28 mForePaint.setColor(Color.rgb( 0 , 128 , 255 )); 29 } 30 31 public void updateVisualizer( byte [] bytes) { 32 mBytes = bytes; 33 invalidate(); 34 } 35 36 @Override 37 protected void onDraw(Canvas canvas) { 38 super .onDraw(canvas); 39 40 if (mBytes == null ) { 41 return ; 42 } 43 44 if (mPoints == null || mPoints.length < mBytes.length * 4 ) { 45 mPoints = new float [mBytes.length * 4 ]; 46 } 47 48 mRect.set( 0 , 0 , getWidth(), getHeight()); 49 50 for ( int i = 0 ; i < mBytes.length - 1 ; i ++ ) { 51 mPoints[i * 4 ] = mRect.width() * i / (mBytes.length - 1 ); 52 mPoints[i * 4 + 1 ] = mRect.height() / 2 53 + (( byte ) (mBytes[i] + 128 )) * (mRect.height() / 2 ) / 128 ; 54 mPoints[i * 4 + 2 ] = mRect.width() * (i + 1 ) / (mBytes.length - 1 ); 55 mPoints[i * 4 + 3 ] = mRect.height() / 2 56 + (( byte ) (mBytes[i + 1 ] + 128 )) * (mRect.height() / 2 ) / 128 ; 57 } 58 59 canvas.drawLines(mPoints, mForePaint); 60 } 61 62 }

转载于:https://my.oschina.net/u/1049180/blog/140174

android 音频开发之混响效果相关推荐

  1. Android音频开发(3):如何播放一帧音频

    本文重点关注如何在Android平台上播放一帧音频数据.阅读本文之前,建议先读一下<Android音频开发(1):基础知识>,因为音频开发过程中,经常要涉及到这些基础知识,掌握了这些重要的 ...

  2. Android 音频开发(四) 如何播放一帧音频数据下

    再看这一篇文章前,如果你是小白,我建议你先看一下Android 音频开发(一) 基础入门篇这一篇.今天继续讲解如何通过Android SDK自带API实现播放一帧音频数据. 我们都知道,Android ...

  3. Android音频开发(4):如何存储和解析wav文件

    2019独角兽企业重金招聘Python工程师标准>>> 无论是文字.图像还是声音,都必须以一定的格式来组织和存储起来,这样播放器才知道以怎样的方式去解析这一段数据,例如,对于原始的图 ...

  4. Android音频开发(六)音频编解码之初识MediaCodec上

    前五篇我们介绍了关于音频的基础知识,今天来讲述一下音频的重点和难点部分,这一节依然是分上下俩个节点,深入讲述Android音频开发的编解码技术. 1.MediaCodec 介绍 MediaCodeC是 ...

  5. Android 音频开发(二) 采集一帧音频数据

    这一节主要介绍如何采集一帧音频数据,如果你对音频的基础概念比较陌生,建议看我的上一篇Android 音频开发(一) 基础入门篇.因为音频开发过程中,经常要涉及到这些基础知识,掌握了这些重要的基础知识后 ...

  6. Android 音频开发(一) 基础入门篇

    今天主要讲解下Android音频开发的入门知识,希望对想入门却不知如何下手的朋友有所帮助,同时希望能得到高手的指点和帮助. 深入细化基础技能知识点 大致细化如下10个知识点. 音频开发的主要应用有哪些 ...

  7. Android音频开发(2):如何采集一帧音频

    本文重点关注如何在Android平台上采集一帧音频数据.阅读本文之前,建议先读一下我的上一篇文章<Android音频开发(1):基础知识>,因为音频开发过程中,经常要涉及到这些基础知识,掌 ...

  8. 一次搞懂 Android 音频开发

    在接触Android音频开发后,陆陆续续的看了不少的文章,如果说查缺补漏把这些文章梳理清楚,然后逐个整合,那么确实也能完整的推导出音频开发需要掌握的技术.但是对于初学者来说,可能在开发中产生很多障碍以 ...

  9. android 音乐 简书,Android音频开发(7):音乐可视化-FFT频谱图

    Android 音频开发 目录 一.演示 image 二.实现 实现流程: 使用MediaPlayer播放传入的音乐,并拿到mediaPlayerId 使用Visualizer类拿到拿到MediaPl ...

最新文章

  1. HiCar基本功能介绍
  2. CUDA Samples: Julia
  3. MySql 删除重复数据
  4. 招财铃:即时通信整合,
  5. 警惕技术人员的极端性
  6. Tensorflow get_variable和Varialbe的区别
  7. 【TensorFlow】实现简单的鸢尾花分类器
  8. Expected tensor for argument #1 ‘input‘ to have the same device as tensor for argument #2 ‘weight‘;
  9. drupal php filter,Drupal A-Z and number filter
  10. pytorch resnet50_用Pytorch手工实现ResNet50
  11. POJ1664 放苹果【递推+记忆化递归】
  12. C#中用WinAPI调用外部程序
  13. 计算机专业显示器英语,电脑显示器词汇 计算机英语词汇
  14. C++ 实现单例模式的代码。
  15. 技术人员的等级划分和资质要求
  16. Linux环境下安装tomcat并配置开机自启
  17. 逆天改命,Java 反射的黑科技
  18. Java 练习题:求平方根
  19. 学习单片机的几点经验之谈
  20. (Error -6311) PRSC module failed to write to a register. 问题的探讨

热门文章

  1. VC代码设置禁用窗口最大化按钮禁用拖拽
  2. 三菱FX3U PID恒速控制变频器实例 编码器测电机转速,当负载变化引起转速变化
  3. hta 窗口,如何获取HTA窗口的大小?
  4. 基于javaweb,ssm公交查询系统
  5. 账套显示到期怎么弄_我注册完了,为什么还是显示账套过期
  6. OpenWrt安装ser2net.ipk软件包
  7. ethtool用法 linux_ethtool用法
  8. 我为什么推荐你使用kindle
  9. python 数组排序sort_Python之排序函数sort() 和 sorted()
  10. 计算机在智能交通系统中应用,计算机技术在智能交通系统中的应用.doc