android 游戏音效播放 SoundPool

来源:互联网 发布:围棋中的算法 编辑:程序博客网 时间:2024/04/29 08:23

游戏的音效由于比较特殊,使用MediaPlay会占用太多的资源,所以使用SoundPlay,它将音频文件预先保存在内存中,所以在调用的时候会大大节省CPU资源,其他的一些原因网上一大堆。

使用:

转自:http://www.cnblogs.com/plokmju/p/android_SoundPool.html

SoundPool

  SoundPool(声音池),所处于"android.media.SoundPool"包下,主要用于播放一些较短的声音片段,支持从程序的资源或文件系统加载。与MediaPlayer相比,SoundPool的优势在于CPU的资源占用量低、反应延迟小,并且可以加载多个音频到SoundPool中,通过资源ID来管理。另外SoundPool还支持执行设置声音的品质、音量、播放比率等参数。

  SoundPool提供一个构造函数,以下是它的完整签名:

    SoundPool(int maxStreams,int streamType,int srcQuality)

  通过上面的构造函数即可完成SoundPool的初始化,第一个参数为音频池最多支持装载多少个音频,就是音频池的大小;第二个参数指定声音的类型,在AudioManager类中以常量的形式定义,一般指定为AudioManager.STREAM_MUSIC即可;第三个参数为音频的质量,默认为0,这个参数为预留参数,现在没有实际意义,为扩展预留字段,一般传0即可。

 

  对于一个音频池,涉及到音频的加载、播放、暂停、继续、释放资源等操作,SoundPool也为我们提供了相应的方法,其底层也是用C++编写的native方法。以下介绍一些常用的SoundPool方法:

  • int load(Context context,int resId,int priority):从一个文件夹raw下装载一段音频资源,返回值为音频资源在SoundPool的ID。
  • int load(String path,int priority):从一个资源文件的路径装载一段音频资源,返回值为音频资源在SoundPool的ID。
  • final int play(int soundID,float leftVolume,float rightVolume,int priority,int loop,float rate):根据资源ID,播放一段音频资源。
  • final void pause(int streamID):根据装载资源ID,暂停音频资源的播放。
  • final void resume(int streamID):根据装载资源ID,继续播放暂停的音频资源。
  • final void stop(int streamID):根据装载资源ID,停止音频资源的播放。
  • final boolean unload(int soundID) :从音频池中卸载音频资源ID为soundID的资源。
  • final void release():释放音频池资源。

  上面方法无疑Load()和play()是最重要的,Load()具有多种重载方法,从参数名就可以看出是什么意思。这里讲解一下play()方法,soundID参数为资源ID;leftVolume和rightVolume个参数为左右声道的音量,从大到小取0.0f~1.0f之间的值;priority为音频质量,暂时没有实际意义,传0即可;loop为循环次数,0为播放一次,-1为无线循环,其他正数+1为播放次数,如传递3,循环播放4次;rate为播放速率,从大到小取0.0f~2.0f,1.0f为正常速率播放。

  在使用load()装载音频的时候需要注意,load()方法是一个异步的方法,也就是说,在播放音频的时候,很可能此段音频还没有装载到音频池中,这里可以借助SoundPool的一个装载完成的监听事件SoundPool.setOnLoadCompleteListener来保证装载完成在播放声音。SoundPool.setOnLoadCompleteListener()需要实现一个SoundPool.OnLoadCompleteListener接口,其中需要实现onLoadComplete()方法,一下是onLoadComplete()方法的完整签名:

    onLoadComplete(SoundPool soundPool, int sampleId, int status)

  • soundPool:当前触发事件的声音池。
  • sampleId:当前装载完成的音频资源在音频池中的ID。
  • status:状态码,展示没有意义,为预留参数,会传递0。

源码:

package com.example.jigsaw.util;import java.io.IOException;import java.util.ArrayList;import java.util.HashMap;import java.util.Map;import android.content.Context;import android.content.res.AssetFileDescriptor;import android.media.AudioManager;import android.media.SoundPool;import android.media.SoundPool.OnLoadCompleteListener;import android.util.Log;import android.util.SparseIntArray;/** * 播放游戏背景音乐和音效 * @author LuZiQi * */public class GameMusic {private SoundPool mPool;private SparseIntArray mArray;private Map<String , Integer> map;private Context mContext;private static GameMusic instance;public static GameMusic getInstanc(Context context){if(instance == null)instance = new GameMusic(context);return instance;}private GameMusic(Context context){mContext = context;}/** * 初始化背景音乐和音效 * @param list 音效音乐的文件名集合 * @param backMusic 背景音乐的文件名 * @throws IOException  */public void init(ArrayList<String> list) throws IOException{// 初始化音频池 参数:池中有多少个音频(音频池的大小), 第二个是类型(使用AudioManager.STREAM_MUSIC就行了),第三个预留参数0。mPool = new SoundPool(list.size(), AudioManager.STREAM_MUSIC, 0);map = new HashMap<String, Integer>();// 初始化SparseIntArray 它是android特有的稀有数集合,替代HASHMAP最佳办法,如果一个集合相当多的元素并不是经常使用,只使用其中的少数元素,使用它可以节省资源mArray = new SparseIntArray();// 注册加载完毕监听器,加载完成时mPool.setOnLoadCompleteListener(new OnLoadCompleteListener() {@Overridepublic void onLoadComplete(SoundPool soundPool, int sampleId, int status) {Log.i("luziqi", "ok");}});// 将音效音乐加载到音频池for (int i = 0; i < list.size(); i++) {// 由于音乐放在assets文件夹下 所以要用AssetManeger来获取文件AssetFileDescriptor afd = mContext.getAssets().openFd(list.get(i));// SoundPool的load方法会返回一个该资源在池中的对应ID,这里吧他记录到SparseIntArray数组中。mArray.put(i+1, mPool.load(afd, 1));map.put(list.get(i), i+1);}}public void play(String fileName){if(mPool == null)return;int priority = map.get(fileName);// 从音频池中取出对应的音频文件播放  参数:load时返回的ID , 左声道音量 , 右声道音量 , 优先级 , 重复次数(0是不重复,-1是一只重复),播放速率 0~2.0 1.0是正常速率。mPool.play(priority, 0.7f, 0.7f, 1, 0, 1.0f);}public void close(){if(mPool == null)return;mPool.release();}}


0 0
原创粉丝点击