Android新增API之AudioEffect中文API与应用实例
在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 }
Android新增API之AudioEffect中文API与应用实例的更多相关文章
- AudioEffect中文API
在Android2.3中增加了对音频混响的支持,这些API包含在android.media.audiofx包中. 一.概述 AudioEffect是android audio framework(an ...
- android SDK下载及中文API地址
中文API:http://wiki.eoeandroid.com/Android_API_Guides Android Dev Tools官网地址:www.androiddevtools.cn 收集整 ...
- Android 中文 API (40) —— RatingBar
Android 中文 API (40) —— RatingBar 前言 本章内容是 android.widget.RatingBar,译为"评分条",版本为Android 2.2 ...
- Android 中文API (70) —— BluetoothDevice[蓝牙]
前言 本章内容是 android.bluetooth.BluetoothDevice,为Android蓝牙部分的章节翻译.蓝牙设备类,代表了蓝牙通讯国足中的远端设备.版本为 Android 2.3 ...
- Android 中文API (69) —— BluetoothAdapter[蓝牙]
前言 本章内容是 android.bluetooth.BluetoothAdapter,为Android蓝牙部分的章节翻译.本地蓝牙设备的适配类,所有的蓝牙操作都要通过该类完成.版本为 Androi ...
- Android 中文API (68) —— BluetoothClass.Service
前言 本章内容是 android.bluetooth.BluetoothClass.Service,为Android蓝牙部分的章节翻译,版本为 Android 2.3 r1,翻译来自中山大学的&q ...
- Android 中文API (67) —— BluetoothClass.Device.Major
前言 本章内容是android.bluetooth.BluetoothClass.Device.Major,为Android蓝牙部分的章节翻译,版本为Android 2.3 r1,翻译来自中山大学 ...
- Android 中文API (66) —— BluetoothClass.Device
前言 本章内容是android.bluetooth.BluetoothClass.Device,为Android蓝牙部分的章节翻译,版本为Android 2.3 r1,翻译来自中山大学的" ...
- Android 中文API (65) —— BluetoothClass[蓝牙]
前言 本章内容是android.bluetooth.BluetoothClass,为Android蓝牙部分的章节翻译.用于描述远端设备的类型,特点等信息,通过getBluetoothClass()方法 ...
随机推荐
- [C++ Basic]C++与Java的主要区别
1.编译运行 java是解释性语言,java程序在运行时类加载器从类路经中加载相关的类,然后java虚拟机读取该类文件的字节,执行相应操作.而C++编译的 时候将程序编译成本地机器码.一般来说java ...
- java线程学习——汉堡销售问题
汉堡店中有一个负责做汉堡的厨师,一个负责销售的营业员,用java线程表示他们的营业过程: 问题原型就是生产者与消费者的问题. 首先定义一个汉堡包箱子类与几个相关的变量类: public class H ...
- python实现的文本编辑器 - Skycrab - 博客频道 - CSDN.NET
Download Qt, the cross-platform application framework | Qt Project Qt 5.2.1 for Windows 64-bit (VS 2 ...
- 如何让Table显示滚动条
Table显示滚动条,要先把table放到一个div中,div的长度和宽度要固定,控制overflow属性为scroll <div style="width:700px; height ...
- HA for openstack
mysql ha instance ha openstack博客:http://blog.csdn.net/tantexian/article/list/2 使用eclipse远程调试openstac ...
- Compare the value of entity field.
public class Program { static void Main(string[] args) { Program p = new Program(); p.Test(); Consol ...
- Hadoop运行中遇到的错误调试
在运行Hadoop的过程中遇到的最多的问题就是DataNode不能正常的启动,各种问题都有可能,说一下我遇到的两种情况: (1)第一种情况是Master的防火墙没有关闭.这样在启动Hadoop的时候, ...
- day1作业脚本
1.编写登录接口: - 输入用户名和密码 - 认证成功后显示欢迎信息 - 输错三次后锁定 2.编写多级菜单 - 三级菜单 - 可依次进入子菜单 第一次写python脚本,因为没有学到函数,所以写的有点 ...
- QT动画介绍(有例子可以下载)
所谓动画就是在一个时间段内的不同时间点有不同的状态,只要定义好这样状态,实现动画就是水到渠成的事情.当然做这件事情,最好用的就是状态机,点击这里查看Qt使用状态机实现动画效果实例. 不过,实现动画也有 ...
- VC++对象布局的奥秘:虚函数、多继承、虚拟继承
哈哈,从M$ Visual C++ Team的Andy Rich那里又偷学到一招:VC8的隐含编译项/d1reportSingleClassLayout和/d1reportAllClassLayout ...