android 游戏音效播放 SoundPool

游戏的音效由于比较特殊,使用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() {
			
				@Override
				public 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值