最近开发Android通讯录播报号码时需用到播放多个连续音频文件,用传统的MediaManager无法满足复杂性需求,而 SoundPool则满足,于是写了一个SoundPool的管理类SoundManager管理音频的播放。

代码如下:

package com.yous365.android.util;

import org.xml.sax.SAXException;

import android.content.Context;

import android.content.res.AssetFileDescriptor;

import android.media.AudioManager;

import android.media.SoundPool;

import android.os.Handler;

import android.util.Log;

import java.io.IOException;

import java.util.HashMap;

import java.util.Map;

import java.util.Vector;

import javax.xml.parsers.ParserConfigurationException;

public class SoundManager {

private SoundPool mSoundPool;

private HashMap mSoundPoolMap;

private AudioManager mAudioManager;

private Context mContext;

private Handler mHandler = new Handler();

private Vector mKillSoundQueue = new Vector();

private VoicePhoneNumberUtil util;

private long delay = 1000;

private long seperateTime = 700;

private float rate = 1.0f;

private String locale;

static private SoundManager _instance;

/**

* Requests the instance of the Sound Manager and creates it if it does not

* exist.

*

* @return Returns the single instance of the SoundManager

*/

static synchronized public SoundManager getInstance() {

if (_instance == null)

_instance = new SoundManager();

return _instance;

}

/**

*

*/

private SoundManager() {

util = VoicePhoneNumberUtil.getInstance();

}

/**

* Initialises the storage for the sounds

*

* @param theContext The Application context

*/

public void initSounds(Context theContext) {

mContext = theContext;

mSoundPool = new SoundPool(1,

AudioManager.STREAM_MUSIC, 0);

mSoundPoolMap = new HashMap();

mAudioManager = (AudioManager) mContext

.getSystemService(Context.AUDIO_SERVICE);

}

/**

* Add a new Sound to the SoundPool

*

* @param key - The Sound Index for Retrieval

* @param SoundID - The Android ID for the Sound asset.

*/

public void addSound(String key, int SoundID) {

mSoundPoolMap.put(key,

mSoundPool.load(mContext, SoundID, 1));

}

/**

*

* @param key the key we need to get the sound later

* @param afd  the fie store in the asset

*/

public void addSound(String key, AssetFileDescriptor afd) {

mSoundPoolMap.put(key, mSoundPool.load(

afd.getFileDescriptor(),

afd.getStartOffset(), afd.getLength(), 1));

}

/**

* play the sound loaded to the SoundPool by the key we set

* @param key  the key in the map

*/

public void playSound(String key) {

int streamVolume = mAudioManager

.getStreamVolume(AudioManager.STREAM_MUSIC);

streamVolume = streamVolume

/ mAudioManager

.getStreamMaxVolume(AudioManager.STREAM_MUSIC);

int soundId = mSoundPool.play(

mSoundPoolMap.get(key), streamVolume,

streamVolume, 1, 0, rate);

mKillSoundQueue.add(soundId);

// schedule the current sound to stop after set milliseconds

mHandler.postDelayed(new Runnable() {

public void run() {

if (!mKillSoundQueue.isEmpty()) {

mSoundPool.stop(mKillSoundQueue

.firstElement());

}

}

}, delay);

}

/**

*

* @param key  the key in the map

*/

public void playLoopedSound(String key) {

int streamVolume = mAudioManager

.getStreamVolume(AudioManager.STREAM_MUSIC);

streamVolume = streamVolume

/ mAudioManager

.getStreamMaxVolume(AudioManager.STREAM_MUSIC);

int soundId = mSoundPool.play(

mSoundPoolMap.get(key), streamVolume,

streamVolume, 1, -1, rate);

mKillSoundQueue.add(soundId);

// schedule the current sound to stop after set milliseconds

mHandler.postDelayed(new Runnable() {

public void run() {

if (!mKillSoundQueue.isEmpty()) {

mSoundPool.stop(mKillSoundQueue

.firstElement());

}

}

}, delay);

}

/**

* play the sounds have loaded in SoundPool

* @param keys the files key stored in the map

* @throws InterruptedException

*/

public void playMutilSounds(String keys[])

throws InterruptedException {

int streamVolume = mAudioManager

.getStreamVolume(AudioManager.STREAM_MUSIC);

streamVolume = streamVolume

/ mAudioManager

.getStreamMaxVolume(AudioManager.STREAM_MUSIC);

for (String key : keys) {

Log.d("playMutilSounds", key);

if (mSoundPoolMap.containsKey(key)) {

int soundId = mSoundPool.play(

mSoundPoolMap.get(key),

streamVolume, streamVolume, 1, 0,

rate);

//sleep for a while for SoundPool play

Thread.sleep(seperateTime);

mKillSoundQueue.add(soundId);

}

}

// schedule the current sound to stop after set milliseconds

mHandler.postDelayed(new Runnable() {

public void run() {

if (!mKillSoundQueue.isEmpty()) {

mSoundPool.stop(mKillSoundQueue

.firstElement());

}

}

}, delay);

}

/**

* Loads the various sound assets

* @param locale the load to load audio files

*/

public void loadSounds(String locale)

throws SAXException, IOException,

ParserConfigurationException {

Log.d("load locale", locale);

this.locale = locale;

AssetFileDescriptor afd;

Map audioFiles = util

.getAudioFileConfig(locale,

mContext.getAssets());

for (String key : audioFiles.keySet()) {

afd = mContext.getAssets().openFd(

audioFiles.get(key));

addSound(key, afd);

}

}

/**

* Stop a Sound

*

* @param index - index of the sound to be stopped

*/

public void stopSound(int index) {

mSoundPool.stop(mSoundPoolMap.get(index));

}

/**

* Deallocates the resources and Instance of SoundManager

*/

public void cleanup() {

mSoundPool.release();

mSoundPool = null;

mSoundPoolMap.clear();

mAudioManager.unloadSoundEffects();

_instance = null;

}

/**

* unload all resource in the sound pool

* support for user change VoiceLanguage or Locale or user close the voice function !

*/

public void unloadAllSoundsIn() {

if (mSoundPoolMap.size() > 0) {

for (String key : mSoundPoolMap.keySet()) {

mSoundPool.unload(mSoundPoolMap.get(key));

}

}

mKillSoundQueue.clear();

mSoundPoolMap.clear();

}

/**

* set the speed of soundPool

*

* @param i i<0 means slow i= 0 means normal i>0 means fast

*/

public void setVoiceSpeed(int i) {

if (i > 0) {

rate = 1.2f;

}

else if (i < 0) {

rate = 0.8f;

}

else {

rate = 1.0f;

}

}

/**

* set the delay after one number's sound have played

*

* @param i i<0 means short i= 0 means normal i>0 means long

*/

public void setVoiceDelay(int i) {

if (i > 0) {

seperateTime = 700;

}

else if (i < 0) {

seperateTime = 400;

}

else {

seperateTime = 500;

}

}

public String getLocale() {

return locale;

}

public void setLocale(String locale) {

this.locale = locale;

}

}

0b1331709591d260c1c78e86d0c51c18.png

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐