SoundPool —— 适合短促且对反应速度比较高的情况(游戏音效或按键声等)

下面介绍SoundPool的创建过程:

1. 创建一个SoundPool (构造函数)

public SoundPool(int maxStream, int streamType, int srcQuality) 
maxStream —— 同时播放的流的最大数量
streamType —— 流的类型,一般为STREAM_MUSIC(具体在AudioManager类中列出)
srcQuality —— 采样率转化质量,当前无效果,使用0作为默认值

初始化一个实例:
SoundPool soundPool = new SoundPool(5, AudioManager.STREAM_MUSIC, 0); 
创建了一个最多支持5个流同时播放的,类型标记为音乐的SoundPool。

2. 加载音频资源 

可以通过四种途径来记载一个音频资源:
int load(AssetFileDescriptor afd, int priority) 
通过一个AssetFileDescriptor对象
int load(Context context, int resId, int priority) 
通过一个资源ID
int load(String path, int priority) 
通过指定的路径加载
int load(FileDescriptor fd, long offset, long length, int priority) 
通过FileDescriptor加载

*API中指出,其中的priority参数目前没有效果,建议设置为1。

一个SoundPool能同时管理多个音频,所以可以通过多次调用load函数来记载,如果记载成功将返回一个非0的soundID ,用于播放时指定特定的音频。

int soundID1 = soundPool.load(this, R.raw.sound1, 1);
if(soundID1 ==0){
    // 记载失败
}else{
   // 加载成功
}
int soundID2 = soundPool.load(this, R.raw.sound2, 1);
... 
这里加载了两个流,并分别记录了返回的soundID 。

需要注意的是, 
流的加载过程是一个将音频解压为原始16位PCM数据的过程,由一个后台线程来进行处理异步,所以初始化后不能立即播放,需要等待一点时间。

3. 播放控制 

有以下几个函数可用于控制播放:
final int play(int soundID, float leftVolume, float rightVolume, int priority, int loop, float rate) 
播放指定音频的音效,并返回一个streamID 。
        priority —— 流的优先级,值越大优先级高,影响当同时播放数量超出了最大支持数时SoundPool对该流的处理;
        loop —— 循环播放的次数,0为值播放一次,-1为无限循环,其他值为播放loop+1次(例如,3为一共播放4次).
        rate —— 播放的速率,范围0.5-2.0(0.5为一半速率,1.0为正常速率,2.0为两倍速率)
final void pause(int streamID) 
暂停指定播放流的音效(streamID 应通过play()返回)。
final void resume(int streamID) 
继续播放指定播放流的音效(streamID 应通过play()返回)。
final void stop(int streamID) 
终止指定播放流的音效(streamID 应通过play()返回)。

这里需要注意的是, 
1.play()函数传递的是一个load()返回的soundID——指向一个被记载的音频资源 ,如果播放成功则返回一个非0的streamID——指向一个成功播放的流 ;同一个soundID 可以通过多次调用play()而获得多个不同的streamID (只要不超出同时播放的最大数量);
2.pause()、resume()和stop()是针对播放流操作的,传递的是play()返回的streamID ;
3.play()中的priority参数,只在同时播放的流的数量超过了预先设定的最大数量是起作用,管理器将自动终止优先级低的播放流。如果存在多个同样优先级的流,再进一步根据其创建事件来处理,新创建的流的年龄是最小的,将被终止;
4.无论如何,程序退出时,手动终止播放并释放资源是必要的。

4. 更多属性设置 

其实就是paly()中的一些参数的独立设置:
final void setLoop(int streamID, int loop) 
设置指定播放流的循环.
final void setVolume(int streamID, float leftVolume, float rightVolume) 
设置指定播放流的音量.
final void setPriority(int streamID, int priority) 
设置指定播放流的优先级,上面已说明priority的作用.
final void setRate(int streamID, float rate) 
设置指定播放流的速率,0.5-2.0.

5. 释放资源 

可操作的函数有:
final boolean unload(int soundID) 
卸载一个指定的音频资源.
final void release() 
释放SoundPool中的所有音频资源.

下面对以上进行总结:

一个SoundPool可以:
1.管理多个音频资源,通过load()函数,成功则返回非0的soundID;
2.同时播放多个音频,通过play()函数,成功则返回非0的streamID;
3.pause()、resume()和stop()等操作是针对streamID(播放流)的;
4.当设置为无限循环时,需要手动调用stop()来终止播放;
5.播放流的优先级(play()中的priority参数),只在同时播放数超过设定的最大数时起作用;
6.程序中不用考虑(play触发的)播放流的生命周期,无效的soundID/streamID不会导致程序错误。

示例代码:

SoundPool sp;
HashMap<Integer, Integer> sounddata;
Context mcontext;
Boolean isLoaded;
//初始化声音
public void InitSound() {sp = new SoundPool(5, AudioManager.STREAM_MUSIC, 0);sounddata = new HashMap<Integer, Integer>();sounddata.put(1, sp.load(this, R.raw.mp31, 1));sounddata.put(2, sp.load(this, R.raw.mp32, 1));sp.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener(){@Override public void onLoadComplete(SoundPool sound,int sampleId,int status){isLoaded=true;Toast.makeText(mcontext, "音效加载完成!",Toast.LENGTH_SHORT);}});}……public void playSound(int sound, int number) {AudioManager am = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);float audioMaxVolumn = am.getStreamMaxVolume(AudioManager.STREAM_MUSIC);float volumnCurrent = am.getStreamVolume(AudioManager.STREAM_MUSIC);float volumnRatio = volumnCurrent / audioMaxVolumn;sp.play(sounddata.get(sound),   volumnRatio,// 左声道音量  volumnRatio,// 右声道音量  1, // 优先级  number,// 循环播放次数  1);// 回放速度,该值在0.5-2.0之间 1为正常速度
    }……//2.播放声音if(isLoaded==true)playSound(1,1);

经常有人在使用Soundpool时会报错:

AudioFlinger could not create track, status: -12

SoundPool: Error creating AudioTrack

可以从以下几个方面解决此问题:

1.因为android系统一个设备只允许同时有32个音效文件播放,所以要你在程序中控制同时播放的音频数。并且在Activity被覆盖到下面或者锁屏时对资源进行回收,即调用Soundpool对象的Release()方法。

For audio, there's a hard limit of 32 active AudioTrack objects per device (not per app: you need to share those 32 with rest of the system), and AudioTrack is used internally beneath SoundPool, ToneGenerator, MediaPlayer, native audio based on OpenSL ES, etc. But the actual AudioTrack limit is < 32; it depends more on soft factors such as memory, CPU load, etc. Also note that the limiter in the Android audio mixer does not currently have dynamic range compression, so it is possible to clip if you have a large number of active sounds and they're all loud.

2.每个音频文件大小要小于100k;可以修改音频码率来压缩音频大小,把 128kbps改成32kbps ;

3.每次播放一次,soundpool.play方法有个参数是控制重复播放次数的,将之设置为0,即只播放一次;

转载于:https://www.cnblogs.com/tuyile006/p/4332464.html

Android音频播放之SoundPool 详解相关推荐

  1. Android 音频播放之SoundPool的使用和封装(自定义声音资源)

    例如,现在在一个五子棋游戏中,我们需要在棋子落盘的时候播放一段声音.我们可以利用SoundPool,因为它时间很短,而且需要反复播放,并且我们不希望声音占用太大资源. 一般大家使用的是MediaPla ...

  2. Android 音频播放之SoundPool的使用和封装

    一般大家使用的是MediaPlayer来播放音频,它的创建和销毁都是非常消耗资源的,如果我们的需求是播放一些短促而且频繁播放的音频的话MediaPlayer就有些不合适了,我们来讲讲SoundPool ...

  3. 关于iOS网络音频播放的一些详解(使用AVPlayer播放网络音频)

    在日常的iOS开发中,我们通常会遇到媒体播放的问题,XCode中已经为我们提供了功能非常强大的AVFoundation框架和MediaPlayer框架.其中AVFoundation框架中的AVAudi ...

  4. ffmpeg播放器实现详解 - 音频同步控制

    ffplay是ffmpeg源码中一个自带的开源播放器实例,同时支持本地视频文件的播放以及在线流媒体播放,功能非常强大. FFplay: FFplay is a very simple and port ...

  5. 《Android多媒体应用开发实战详解:图像、音频、视频、2D和3D》——1.3节搭建Android应用开发环境...

    本节书摘来自异步社区<Android多媒体应用开发实战详解:图像.音频.视频.2D和3D>一书中的第1章,第1.3节搭建Android应用开发环境,作者 王石磊 , 吴峥,更多章节内容可以 ...

  6. 《Android多媒体应用开发实战详解:图像、音频、视频、2D和3D》——2.3节简析Android安装文件...

    本节书摘来自异步社区<Android多媒体应用开发实战详解:图像.音频.视频.2D和3D>一书中的第2章,第2.3节简析Android安装文件,作者 王石磊 , 吴峥,更多章节内容可以访问 ...

  7. 《Android多媒体应用开发实战详解:图像、音频、视频、2D和3D》——2.1节简析Android安装文件...

    本节书摘来自异步社区<Android多媒体应用开发实战详解:图像.音频.视频.2D和3D>一书中的第2章,第2.1节简析Android安装文件,作者 王石磊 , 吴峥,更多章节内容可以访问 ...

  8. 《Android多媒体应用开发实战详解:图像、音频、视频、2D和3D》——1.2节Android的巨大优势...

    本节书摘来自异步社区<Android多媒体应用开发实战详解:图像.音频.视频.2D和3D>一书中的第1章,第1.2节Android的巨大优势,作者 王石磊 , 吴峥,更多章节内容可以访问云 ...

  9. java播放wma格式的音频文件,两种可将WMA文件在iPhone上播放的方法详解

    WMA是微软开发的一款音频数据压缩技术,也是现今使用非常广泛的音频格式之一.然而,由于它与苹果的iOS系统不兼容,所以该格式文件不能够在苹果系列数码产品如iPhone手机上播放.不过,只要有了方便快捷 ...

  10. android中oncreate方法,android开发之onCreate( )方法详解

    这里我们只关注一句话:This is where you should do all of your normal static set up.其中我们只关注normal static, normal ...

最新文章

  1. 使用grep过滤make的输出内容
  2. 【WA】九度OJ题目1435:迷瘴
  3. mysql 单标递归_MySQL递归CTE(公共表表达式)
  4. python xpath语法-Python爬虫 | 解析库Xpath的使用
  5. SpringBoot启动项目时提示:Error:(3, 32) java: 程序包org.springframework.boot不存在
  6. JavaFX官方教程(八)之JavaFX中的动画和视觉效果
  7. 为什么鞋带总是松开?罪魁祸首其实是…
  8. 数据结构基础(12) --双向循环链表的设计与实现
  9. 哈夫曼编解码原理与实现【转载】
  10. 被低估的“败家爷们”
  11. android判断正确密码,Android 监听EditText输入框 ,判断输入的密码是什么格式
  12. NetSuite 在中国 - 一个全程信息化管理平台
  13. C#基础精华05(正则表达式,)
  14. visio画图导入word公式符号发生变形
  15. 如何利用SPSS进行秩和检验
  16. livezilla账号或密码修改方法
  17. Action Recognition with Improved Trajectories
  18. Html-照片的逐步出现 、心形动画制作、3d立方体魔方、鼠标划过box阴影练习
  19. 摄影师眼中的爱情(完整版)▒┣
  20. jQuery 实现音乐导航案例

热门文章

  1. Big5和Gb编码转换
  2. 纯CSS实现button按钮
  3. 施耐德编程软件Unity Pro XL授权步骤
  4. 干掉 Jenkins?顶级 DevOps 工具链大盘点
  5. 计算机打印怎样添加PDF格式,电脑添加PDF打印机后如何将Excel打印成PDF
  6. 【笔记】QCA9531无线校准
  7. 安科瑞电力监控系统在上海平凉街道23街坊商办项目的应用
  8. lnmp一键安装包linux,lnmp一键安装包下载地址
  9. 请解释jsonp的工作原理
  10. 彻底理解js中的闭包