精华内容
下载资源
问答
  • 主要为大家详细介绍了Android使用SoundPool实现播放音频,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • 的opensl-soundpool 这是我的旧项目,已从code.google.com/p/opensl-soundpool移至安全区域。 我怀疑当前是否有主流手机出现Android SoundPool崩溃的问题。 原始自述文件: SoundPool似乎遭受了三星Galaxy S2...
  • 大家知道MediaPlayer占用的资源比较多,且不可以同时支持播放多个音频,所以我们有一种叫做SoundPool,比如我们常见的按键音或者是手机提示音,还比如我们在游戏的开发中会有大量的音效效果等,下边介绍一下她的用法...
  • 使用 SoundPool

    2018-09-18 18:13:46
    一个简单的sample , 用来理解及测试SoundPool的相关功能 https://blog.csdn.net/qq_28261343
  • SoundPool

    2020-04-13 14:27:23
    1、SoundPool基本用法 2、Android SoundPool 的使用 3、Android SoundPool的简单使用 4、SoundPool的介绍和使用
    展开全文
  • 本文实例讲述了Android编程实现使用SoundPool播放音乐的方法。分享给大家供大家参考,具体如下: 如果应用程序要播放密集、短促的音效,这时还用MediaPlayer就显得不合适了。MediaPlayer存在如下缺点: 1、资源占用...
  • Android设备的一些较短的声音可以用SoundPool来做,如消息提醒等,此例子介绍了SoundPool的用法。
  • 摘要:Java源码,Android,Soundpool Android中的soundpool实例源码下载,播放音乐的例子,还是比较实用的,很基础的例子,几乎在Android多媒体中经常用到的。
  • SoundPool 的使用

    2018-09-23 22:04:27
    一个简单的sample , 用来理解及测试SoundPool的相关功能 相关博客 https://blog.csdn.net/qq_28261343/article/details/82818868
  • SoundPool实例Demo

    2018-03-11 21:53:10
    soundPool在Android5.0后Api有了改变,这个Demo就是为解决这种变化的,它可以在Android4.+----7.+系统正常播放音频文件!
  • SoundPool音效播放

    2019-03-28 01:49:42
    NULL 博文链接:https://rayln.iteye.com/blog/1224594
  • soundpool

    2019-05-13 20:17:00
    Soundpool soundpool = Soundpool(streamType: StreamType.music, maxStreams: 4); PlaySound(){ scheduleMicrotask(()async{ for(var value in _SOUNDS){ var data = await rootBundle.load('assets/audios/$...

    A Flutter Sound Pool for playing short media files.

    Sound Pool caches audio tracks in memory. This can be useful in following scenarios:

    • lower latency between play signal and actual playing of the sound (audio does not need to be read from disc/web),
    • the same sound may be used multiple times.

    Inspired by Android SoundPool API.

     

    import 'dart:async';
    
    import 'package:flutter/material.dart';
    import 'package:flutter/services.dart';
    import 'package:soundpool/soundpool.dart';
    
    class Sound extends StatefulWidget {
      final Widget child;
    
      const Sound({Key key, this.child}) : super(key: key);
    
      @override
      SoundState createState() => SoundState();
    
      static SoundState of(BuildContext context) {
        final state = context.ancestorStateOfType(const TypeMatcher<SoundState>());
        assert(state != null, 'can not find Sound widget');
        return state;
      }
    }
    
    const _SOUNDS = [
      'clean.mp3',
      'drop.mp3',
      'explosion.mp3',
      'move.mp3',
      'rotate.mp3',
      'start.mp3'
    ];
    
    class SoundState extends State<Sound> {
      Soundpool _pool;
    
      Map<String, int> _soundIds;
    
      bool mute = false;
    
      void _play(String name) {
        final soundId = _soundIds[name];
        if (soundId != null && !mute) {
          _pool.play(soundId);
        }
      }
    
      @override
      void initState() {
        super.initState();
        _pool = Soundpool(streamType: StreamType.music, maxStreams: 4);
        _soundIds = Map();
        for (var value in _SOUNDS) {
          scheduleMicrotask(() async {
            final data = await rootBundle.load('assets/audios/$value');
            _soundIds[value] = await _pool.load(data);
          });
        }
      }
    
      @override
      void dispose() {
        super.dispose();
        _pool.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return widget.child;
      }
    
      void start() {
        _play('start.mp3');
      }
    
      void clear() {
        _play('clean.mp3');
      }
    
      void fall() {
        _play('drop.mp3');
      }
    
      void rotate() {
        _play('rotate.mp3');
      }
    
      void move() {
        _play('move.mp3');
      }
    }
    

      

     

     

     


    class PlaySound {
    final _SOUNDS = [
    'clean.mp3',
    'drop.mp3',
    'explosion.mp3',
    'move.mp3',
    'rotate.mp3',
    'start.mp3'
    ];

    Map soundIds = Map();

    play(String name){
    soundpool.play(soundIds[name]);
    }

    Soundpool soundpool = Soundpool(streamType: StreamType.music, maxStreams: 4);

    PlaySound(){
    scheduleMicrotask(()async{
    for(var value in _SOUNDS){
    var data = await rootBundle.load('assets/audios/$value');
    soundIds[value] = await soundpool.load(data);
    }
    });
    }
    }

    转载于:https://www.cnblogs.com/pythonClub/p/10858758.html

    展开全文
  • 收集到的一个非常好的安卓组件播放声音的小实例,区分了MediaPlayer和SoundPool两种方法的不同用法,会给初学者带来很大的帮助
  • Android soundpool播放音乐声音池应用举例,基础的例子,使用SoundPool进行简单的音乐播放功能,由此可扩展成一个音乐播放器,编写音频处理相关的应用时,可用上的基础代码。
  • 使用教程: 使用: VoiceSpeak.util.playVoicePool(MoneyUtil.readString("30.57"),this) VoiceSpeak.util.playVoicePool(MoneyUtil.readString("108"),this) VoiceSpeak.util.playVoicePool(MoneyUtil.readString(...
  • android背景音乐、背景音效实例,其中大音频音乐播放使用MediaPlayer实现,小音频音效播放使用SoundPool实现
  • 使用 SoundPool 同时播放多个音频 具体详情请参见 http://blog.csdn.net/aduovip/article/details/14695779
  • Android--SoundPool详解

    2019-09-12 00:05:38
    在游戏开发中,我们经常需要播放一些游戏的音效,这些音效的都需要是短促、密集、延迟小的,在这种场景下,需要使用到SoundPool来替代MediaPlayer播放这些音效,本篇博客就主要讲解SoundPool的使用以及需要注意的...

    前言

      在Android中播放音频文件经常会用到MediaPlayer,但是MediaPlayer存在一些不足的地方,如:资源占用量较高、加载延迟时间较长、不支持多个音频同时播放等。这些缺点决定了MediaPlayer在某些需要密集使用不同音频的情况不会理想,例如游戏开发。在游戏开发中,我们经常需要播放一些游戏的音效,这些音效的都需要是短促、密集、延迟小的,在这种场景下,需要使用到SoundPool来替代MediaPlayer播放这些音效,本篇博客就主要讲解SoundPool的使用以及需要注意的地方,最后将以一个示例演示SoundPool的使用。

      本篇博客的主要内容:

    1. SoundPool
    2. SoundPool的简单示例
    3. SoundPool的注意事项 

      

    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方法:(更多 :http://developer.android.com/reference/android/media/SoundPool.html)

    • 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。

     

    使用SoundPool示例

      上面已经介绍了SoundPool的使用所涉及到的内容,下面通过一个简单的示例来演示一下SoundPool的使用,播放的音频资源都是我从其他app中拷贝出来的,没有实际意义。示例中的注释写的比较全,这里不再累述了。

    复制代码
    1 package cn.bgxt.soundpooldemo;
     2 
     3 import java.util.HashMap;
     4 import java.util.Map;
     5 
     6 import android.media.AudioManager;
     7 import android.media.SoundPool;
     8 import android.media.SoundPool.OnLoadCompleteListener;
     9 import android.os.Bundle;
    10 import android.app.Activity;
    11 import android.util.Log;
    12 import android.view.View;
    13 import android.view.View.OnClickListener;
    14 import android.widget.Button;
    15 import android.widget.Toast;
    16 
    17 public class MainActivity extends Activity {
    18     private Button btn_newqqmsg, btn_newweibontf, btn_newweibotoast;
    19     private SoundPool pool;
    20     private Map<String, Integer> poolMap;
    21 
    22     @Override
    23     protected void onCreate(Bundle savedInstanceState) {
    24         super.onCreate(savedInstanceState);
    25         setContentView(R.layout.activity_main);
    26         btn_newqqmsg = (Button) findViewById(R.id.btn_newqqmsg);
    27         btn_newweibontf = (Button) findViewById(R.id.btn_newweibontf);
    28         btn_newweibotoast = (Button) findViewById(R.id.btn_newweibotoast);
    29 
    30         poolMap = new HashMap<String, Integer>();
    31         // 实例化SoundPool,大小为3
    32         pool = new SoundPool(3, AudioManager.STREAM_MUSIC, 0);
    33         // 装载音频进音频池,并且把ID记录在Map中
    34         poolMap.put("newqqmsg", pool.load(this, R.raw.qqmsg, 1));
    35         poolMap.put("newweibontf", pool.load(this, R.raw.notificationsound, 1));
    36         poolMap.put("newweibotoast", pool.load(this, R.raw.newblogtoast, 1));
    37 
    38         pool.setOnLoadCompleteListener(new OnLoadCompleteListener() {
    39 
    40             @Override
    41             public void onLoadComplete(SoundPool soundPool, int sampleId,
    42                     int status) {
    43                 // 每次装载完成均会回调
    44                 Log.i("main", "音频池资源id为:" + sampleId + "的资源装载完成");
    45                 // 当前装载完成ID为map的最大值,即为最后一次装载完成
    46                 if (sampleId == poolMap.size()) {
    47                     Toast.makeText(MainActivity.this, "加载声音池完成!",
    48                             Toast.LENGTH_SHORT).show();
    49                     btn_newqqmsg.setOnClickListener(click);
    50                     btn_newweibontf.setOnClickListener(click);
    51                     btn_newweibotoast.setOnClickListener(click);
    52                     // 进入应用播放四次声音
    53                     pool.play(poolMap.get("newweibotoast"), 1.0f, 1.0f, 0, 3,
    54                             1.0f);
    55                 }
    56             }
    57         });
    58     }
    59 
    60     private View.OnClickListener click = new OnClickListener() {
    61 
    62         @Override
    63         public void onClick(View v) {
    64 
    65             switch (v.getId()) {
    66             case R.id.btn_newqqmsg:
    67                 if (pool != null) {
    68                     pool.play(poolMap.get("newqqmsg"), 1.0f, 1.0f, 0, 0, 1.0f);
    69                 }
    70                 break;
    71             case R.id.btn_newweibontf:
    72                 if (pool != null) {
    73                     pool.play(poolMap.get("newweibontf"), 1.0f, 1.0f, 0, 0,
    74                             1.0f);
    75                 }
    76                 break;
    77             case R.id.btn_newweibotoast:
    78                 if (pool != null) {
    79                     pool.play(poolMap.get("newweibotoast"), 1.0f, 1.0f, 0, 0,
    80                             1.0f);
    81                 }
    82                 break;
    83             default:
    84                 break;
    85             }
    86         }
    87     };
    88 
    89     @Override
    90     protected void onDestroy() {
    91         // 销毁的时候释放SoundPool资源
    92         if (pool != null) {
    93             pool.release();
    94             pool = null;
    95         }
    96         super.onDestroy();
    97     }
    98 }
    复制代码

      效果展示:

     

    SoundPool使用的注意事项

      因为SoundPool的一些设计上的BUG,从固件版本1.0开始就有些没有修复的,以后应该会慢慢修复。这里简单提一下:

    1. 虽然SoundPool可以装载多个音频资源,但是最大只能申请1MB的内存空间,这就意味着只能用使用它播放一些很短的声音片段,而不是用它来播放歌曲或者做游戏背景音乐。
    2. SoundPool提供的pause()、resume()、stop()最好不要轻易使用,因为它有时候会使程序莫名其妙的终止,如果使用,最好做大量的测试。而且有时候也不会立即终止播放声音,而是会等缓冲区的音频数据播放完才会停止。
    3. 虽然SoundPool比MediaPlayer的效率好,但也不是绝对不存在延迟的问题,尤其在那些性能不太好的手机中,SoundPool的延迟问题会更严重,但是现在一般的手机配置,那一点的延迟还是可以接受的。

     

      源码下载


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

    http://blog.csdn.net/brooknew/article/details/6663802

    http://blog.csdn.net/qq435757399/article/details/8010015  Android开发之为按钮添加音效

    转载于:https://my.oschina.net/u/3579120/blog/1508519

    展开全文
  • 应用场景如:钢琴弹奏 APP,可用 SoundPool 播放每个琴键的音频资源。 先看应用场景效果: 为使用方便,封装 SoundPool 如下: package com.alan.audioio.audio; import android.content.res.AssetFileDescr.

    Android SoundPool 主要用于快速播放多个短音频,开发文档链接。应用场景如:钢琴弹奏 APP,可用 SoundPool 播放每个琴键的音频资源。

    先看应用场景效果:
    在这里插入图片描述

    为使用方便,封装 SoundPool 如下:

    package com.alan.audioio.audio;
    
    import android.content.res.AssetFileDescriptor;
    import android.media.AudioAttributes;
    import android.media.AudioManager;
    import android.media.SoundPool;
    import android.os.Build;
    import android.os.Handler;
    import android.os.HandlerThread;
    import android.os.Looper;
    import android.os.Message;
    import com.alan.audioio.audio.common.APPContext;
    import com.alan.audioio.audio.common.AudioConstants;
    import com.alan.audioio.audio.exception.AudioException;
    import com.alan.audioio.utils.ALog;
    import java.io.IOException;
    import java.lang.ref.WeakReference;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.CountDownLatch;
    import java.util.concurrent.TimeUnit;
    
    /**
     * Author: AlanWang4523.
     * Date: 2020/10/17 14:57.
     * Mail: alanwang4523@gmail.com
     */
    public class AndroidSoundPool {
        private static final String TAG = AndroidSoundPool.class.getSimpleName();
        private static final int MSG_FADE_OUT = 1001;
        private static final int FADE_DURATION = 30;
        private static final int FADE_INTERVAL_TIME = 6;
        private static final float FADE_INTERVAL_VOLUME = (1.0f / (1.0f * FADE_DURATION / FADE_INTERVAL_TIME));
    
        private SoundPool mSoundPool;
        private int mMaxStreamCount;
        private ArrayList<Integer> mSoundIdList;
        private ArrayList<Integer> mPlayingIdList;
        private CountDownLatch mCountDownLatch;
        private Handler mHandler;
        private HandlerThread mHandlerThread;
        private float mCurPlayVolume = 1.0f;
    
        /**
         * 构造函数
         */
        public AndroidSoundPool(int maxStreamCount) {
            mMaxStreamCount = maxStreamCount;
            mSoundIdList = new ArrayList<>();
            mPlayingIdList = new ArrayList<>();
    
            mSoundPool = createSoundPool(mMaxStreamCount);
            mSoundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
                @Override
                public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
                    ALog.d("onLoadComplete()--->>sampleId = " + sampleId + ", status = " + status);
                    if (mCountDownLatch != null) {
                        mCountDownLatch.countDown();
                    }
                }
            });
    
            mHandlerThread = new HandlerThread(TAG);
            mHandlerThread.start();
            mHandler = new InternalHandler(mHandlerThread.getLooper(), this);
        }
    
        /**
         * 创建 SoundPool
         * @param maxStream 同时播放的最大流数量
         * @return SoundPool
         */
        private SoundPool createSoundPool(int maxStream) {
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
                SoundPool.Builder builder = new SoundPool.Builder();
                builder.setMaxStreams(maxStream);
                AudioAttributes.Builder attributesBuilder = new AudioAttributes.Builder();
                attributesBuilder.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC);
                attributesBuilder.setFlags(256);
                attributesBuilder.setUsage(AudioAttributes.USAGE_MEDIA);
                attributesBuilder.setLegacyStreamType(3);
                builder.setAudioAttributes(attributesBuilder.build());
                return builder.build();
            } else {
                return new SoundPool(maxStream, AudioManager.STREAM_MUSIC, 0);
            }
        }
    
        /**
         * 加载资源列表
         * @param audioPathList 要加载的音频资源列表
         * @return soundIDList
         * @throws AudioException 加载失败会抛出 AudioException
         */
        public List<Integer> load(List<String> audioPathList) throws AudioException {
            mSoundIdList.clear();
            ArrayList<Integer> soundIDList = new ArrayList<>();
            if (audioPathList == null) {
                return soundIDList;
            }
    
            mCountDownLatch = new CountDownLatch(audioPathList.size());
            for (String audioPath : audioPathList) {
                int soundID = this.load(audioPath);
                soundIDList.add(soundID);
            }
            try {
                mCountDownLatch.await(audioPathList.size() * 2, TimeUnit.SECONDS);
            } catch (InterruptedException e) {
                // do nothing
            }
            return soundIDList;
        }
    
        /**
         * 加载资源文件
         * @param audioPath 音频资源路径,支持协议如下:
         *        assets://piano/A.m4a
         *        exfile:///sdcard/Alan/Audio/piano/A.m4a
         *        /sdcard/Alan/Audio/piano/A.m4a
         *
         * @return soundID,可以用于播放或 unload
         * @throws AudioException 加载失败抛出 AudioException
         */
        private int load(String audioPath) throws AudioException {
            int soundID;
            String realPath;
            if (AudioConstants.isAssetsPath(audioPath)) {
                // assets 文件
                realPath = audioPath.replace(AudioConstants.HOST_ASSETS, "");
                try {
                    AssetFileDescriptor assetFileDescriptor = APPContext.getAssetManager().openFd(realPath);
                    soundID = mSoundPool.load(assetFileDescriptor, 0);
                } catch (IOException e) {
                    throw new AudioException("Load asset file failed.", e);
                }
            } else if (AudioConstants.isExFilePath(audioPath)) {
                // 外部存储文件
                realPath = audioPath.replace(AudioConstants.HOST_EXFILE, "");
                soundID = mSoundPool.load(realPath, 0);
            } else {
                // 其他绝对路径不带前缀的文件
                realPath = audioPath;
                soundID = mSoundPool.load(realPath, 0);
            }
            mSoundIdList.add(soundID);
            return soundID;
        }
    
        /**
         * 播放某个资源
         * @param soundID soundID,由 {@link #load(String)} 返回
         */
        public void play(int soundID) {
            mCurPlayVolume = 1.0f;
            int playingId = mSoundPool.play(soundID,
                    1.0f, 1.0f, 0, 0, 1.0f);
            synchronized (AndroidSoundPool.this) {
                if ((playingId != 0) && !mPlayingIdList.contains(playingId)) {
                    mPlayingIdList.add(playingId);
                }
                if (mPlayingIdList.size() > mMaxStreamCount) {
                    mPlayingIdList.remove(0);
                }
            }
        }
    
        /**
         * 停止播放,停止时会做 fade out
         */
        public void stopPlay() {
            mHandler.removeMessages(MSG_FADE_OUT);
            mHandler.sendEmptyMessage(MSG_FADE_OUT);
            try {
                Thread.sleep(FADE_DURATION + FADE_INTERVAL_TIME);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 卸载某个资源
         * @param soundID soundID,由 {@link #load(String)} 返回
         */
        public void unload(int soundID) {
            mSoundPool.unload(soundID);
            int idIndex = -1;
            for (int i = 0; i < mSoundIdList.size(); i++) {
                if (soundID == mSoundIdList.get(i)) {
                    idIndex = i;
                }
            }
            if (idIndex >= 0) {
                mSoundIdList.size();
                mSoundIdList.remove(idIndex);
            }
        }
    
        /**
         * 卸载所有资源
         */
        public void unloadAll() {
            for (Integer soundID : mSoundIdList) {
                mSoundPool.unload(soundID);
            }
            mSoundIdList.clear();
        }
    
        /**
         * 释放资源
         */
        public void release() {
            unloadAll();
            mSoundPool.release();
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
                mHandlerThread.quitSafely();
            } else {
                mHandlerThread.quit();
            }
        }
    
        private void handleFadeOut() {
            mCurPlayVolume -= FADE_INTERVAL_VOLUME;
            setVolume(mCurPlayVolume);
            if (mCurPlayVolume > 0) {
                mHandler.sendEmptyMessageDelayed(MSG_FADE_OUT, FADE_INTERVAL_TIME);
            } else {
                synchronized (AndroidSoundPool.this) {
                    for (Integer playingId : mPlayingIdList) {
                        mSoundPool.stop(playingId);
                    }
                    mPlayingIdList.clear();
                }
            }
        }
    
        private void setVolume(float volume) {
            ALog.d("setVolume()----->>>" + volume + ", PlayingIdList = " + mPlayingIdList.toString());
            if (volume > 1.0f) {
                volume = 1.0f;
            } else if (volume < 0.01f) {
                volume = 0.0f;
            }
            synchronized (AndroidSoundPool.this) {
                try {
                    for (Integer playingId : mPlayingIdList) {
                        mSoundPool.setVolume(playingId, volume, volume);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    
        private static class InternalHandler extends Handler {
            private WeakReference<AndroidSoundPool> weakRefSoundPool;
            public InternalHandler(Looper looper, AndroidSoundPool androidSoundPool) {
                super(looper);
                weakRefSoundPool = new WeakReference<>(androidSoundPool);
            }
    
            @Override
            public void handleMessage(Message msg) {
                AndroidSoundPool androidSoundPool = weakRefSoundPool.get();
                if (androidSoundPool == null) {
                    return;
                }
                if (msg.what == MSG_FADE_OUT) {
                    androidSoundPool.handleFadeOut();
                }
            }
        }
    }
    

    调用逻辑如下:

    package com.alan.audioio.app;
    
    import android.app.ProgressDialog;
    import android.content.Context;
    import android.content.Intent;
    import android.os.AsyncTask;
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.view.View;
    import android.widget.TextView;
    import com.alan.audioio.R;
    import com.alan.audioio.app.ui.PianoKeyItemView;
    import com.alan.audioio.audio.AndroidSoundPool;
    import com.alan.audioio.audio.common.APPContext;
    import com.alan.audioio.audio.exception.AudioException;
    import com.alan.audioio.utils.ALog;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    
    /**
     * Author: AlanWang4523.
     * Date: 2020/10/17 18:38.
     * Mail: alanwang4523@gmail.com
     */
    public class TestSoundPoolActivity  extends AppCompatActivity implements View.OnClickListener {
    
        public static void launchMe(Context context) {
            context.startActivity(new Intent(context, TestSoundPoolActivity.class));
        }
    
        private static final String MUSIC_PIANO_DIR = "assets://piano/";
        private static final String[] KEY_NAMES = {"A", "B", "C", "D", "E",};
        private static final String FILE_SUFFIX = ".m4a";
    
        private static final int PIANO_KEYS_COUNT = 5;
        private static final int MAX_SOUND_COUNT = 5;
        private int[] btnPianoKeysIdArr;// 按钮id
        private PianoKeyItemView[] pianoKeyItemViewArr;
        private HashMap<Integer, Integer> btnIdIndexMap = new HashMap<>(PIANO_KEYS_COUNT);
        private HashMap<Integer, Integer> btnIdAndSoundIdMap = new HashMap<>(PIANO_KEYS_COUNT);
        private TextView btnStopPlay;
        private ProgressDialog mProgressDialog;
        private AndroidSoundPool mAndroidSoundPool;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_sound_pool);
    
            btnStopPlay = findViewById(R.id.btn_stop);
            btnStopPlay.setOnClickListener(this);
    
            APPContext.getInstance().setContext(this);
    
            btnPianoKeysIdArr = new int[PIANO_KEYS_COUNT];
            btnPianoKeysIdArr[0] = R.id.btn_key_A;
            btnPianoKeysIdArr[1] = R.id.btn_key_B;
            btnPianoKeysIdArr[2] = R.id.btn_key_C;
            btnPianoKeysIdArr[3] = R.id.btn_key_D;
            btnPianoKeysIdArr[4] = R.id.btn_key_E;
    
            pianoKeyItemViewArr = new PianoKeyItemView[PIANO_KEYS_COUNT];
            for (int i = 0; i < pianoKeyItemViewArr.length; i++) {
                btnIdIndexMap.put(btnPianoKeysIdArr[i], i);
                pianoKeyItemViewArr[i] = findViewById(btnPianoKeysIdArr[i]);
                pianoKeyItemViewArr[i].setOnClickListener(this);
            }
    
            loadMusicInstrument();
        }
    
        private void loadMusicInstrument() {
            ALog.e("loadMusicInstrument--------------->>");
    
            if (mProgressDialog == null) {
                mProgressDialog = new ProgressDialog(this);
                mProgressDialog.setMessage("正在加载乐器...");
            }
            mProgressDialog.show();
    
            if (mAndroidSoundPool != null) {
                mAndroidSoundPool.release();
            }
            mAndroidSoundPool = new AndroidSoundPool(MAX_SOUND_COUNT);
    
            final ArrayList<String> audioFileList = new ArrayList<>();
            for (int i = 0; i < pianoKeyItemViewArr.length; i++) {
                audioFileList.add(getAudioPath(i));
            }
    
            AsyncTask.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        List<Integer> soundIdList = mAndroidSoundPool.load(audioFileList);
                        for (int i = 0; i < soundIdList.size(); i++) {
                            ALog.e("loadAudioAsync:: i = " + i + ", soundId = " + soundIdList.get(i)
                                    + ", keyPath = " + getAudioPath(i));
                            btnIdAndSoundIdMap.put(btnPianoKeysIdArr[i], soundIdList.get(i));
                        }
                        TestSoundPoolActivity.this.runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                mProgressDialog.dismiss();
                            }
                        });
                    } catch (AudioException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    
        private String getAudioPath(int i) {
            return MUSIC_PIANO_DIR + KEY_NAMES[i] + FILE_SUFFIX;
        }
    
        @Override
        protected void onDestroy() {
            if (mProgressDialog != null && mProgressDialog.isShowing()) {
                mProgressDialog.dismiss();
            }
            if (mAndroidSoundPool != null) {
                mAndroidSoundPool.stopPlay();
                mAndroidSoundPool.release();
            }
            super.onDestroy();
        }
    
        @Override
        public void onClick(View view) {
            if (view.getId() == R.id.btn_stop) {
                if (mAndroidSoundPool != null) {
                    mAndroidSoundPool.stopPlay();
                }
            } else {
                int index = btnIdIndexMap.get(view.getId());
                if (index >= 0) {
                    PianoKeyItemView keyItemView = pianoKeyItemViewArr[index];
                    int soundId = btnIdAndSoundIdMap.get(view.getId());
                    ALog.e("PlayPiano--->> " + keyItemView.getKeyName() + ", soundId = " + soundId);
                    if (mAndroidSoundPool != null) {
                        mAndroidSoundPool.play(soundId);
                    }
                }
            }
        }
    }
    

    完整 Demo

    展开全文
  • Android Soundpool Demo

    2014-05-25 16:15:45
    在开发的时候,可能会用到播放一些短暂声音。播放多媒体,最先想到的可能是MediaPlay这个类。... Soundpool的加载最好是放在程序初始化的时候,如果在用的时候才去加载的话,调用play的时候是会抛异常的
  • SoundPool播放音效

    2021-11-04 12:40:10
    这些缺点决定了MediaPlayer在某些场合的使用情况不会很理想,例如在时间精准度要求较高的场景,而SoundPool一般用来 播放密集、急促而又短暂的音效,比如:”滴滴一下,马上出发"。 这里我们实现一个页面内有多个...
  • 使用 SoundPool 播放音效,SoundPool 还支持自行设置声音的品质、音量、 播放比率等参数
  • SoundPool使用Example

    2015-04-16 14:15:59
    SoundPool使用,主要实现了SoundPool加载、播放、释放声音资源的完整过程

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,181
精华内容 1,272
关键字:

soundpool