Android P SoundPool简介

简介

看名字的话SoundPool就是一个声音池,里面存放了一系列的声音资源可供随时使用。优点如下:

  • 适合短且对反应速度要求比较高、也就是要求低延时的情况(游戏音效或按键声等),文件大小一般控制在几十K到几百K,最好不超过1M
  • SoundPool与MediaPlayer不同的地方就是SoundPool可以同时播放多个声音
  • 将音频从文件系统加载进内存后就一直在内存上托管着不释放。并为每个音频生成一个索引号,以后每次需要播放时就直接顺着这个索引号找到已经位于内存中的音频进行解码并播放即可

上面是优点,看了之后缺点也很明显空间换时间那就是耗内存

SoundPool构造

第一种,通过SoundPool推荐通过 SoundPool.Builder 来创建对象,比较推荐这种方式

mSoundPool = new SoundPool.Builder()
        .setMaxStreams(NUM_SOUNDPOOL_CHANNELS) //传入最多播放音频数量
        .setAudioAttributes(new AudioAttributes.Builder()
            .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION) 
            .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
            .setInternalLegacyStreamType(AudioManager.STREAM_MUSIC) //设置合适的流类型
            .build())// 构造一个AudioAttributes,里面封装了音频的各种描述属性(后面还会讲到)
        .build();

第二种,直接通过public的构造方法创建

   /**
     * 第一个参数:int maxStreams:SoundPool对象的最大并发流数
     * 第二个参数:int streamType:AudioManager中描述的音频流类型
     *第三个参数:int srcQuality:采样率转换器的质量。 目前没有效果。 使用0作为默认值。
     */
mSoundPool = new SoundPool(1, AudioManager.STREAM_MUSIC, 0);

看起来是两种方法,但是实际都会调用到SoundPool的native_setup

SoundPool::SoundPool(int maxChannels, const audio_attributes_t* pAttributes)
{
	//根据传入的参数初始化多个SoundChanel,最多32个
    mChannelPool = new SoundChannel[mMaxChannels];
    for (int i = 0; i < mMaxChannels; ++i) {
        mChannelPool[i].init(this);
        mChannels.push_back(&mChannelPool[i]);
    }
	
    // start decode thread  //开始一个解码的线程
    startThreads();
}

SoundPoolThread 跑起来之后就等着Load资源文件

int SoundPoolThread::run() {
    ALOGV("run");
    for (;;) {
        SoundPoolMsg msg = read();
        ALOGV("Got message m=%d, mData=%d", msg.mMessageType, msg.mData);
        switch (msg.mMessageType) {
        case SoundPoolMsg::KILL:
            ALOGV("goodbye");
            return NO_ERROR;
        case SoundPoolMsg::LOAD_SAMPLE:
            doLoadSample(msg.mData);
            break;
        default:
            ALOGW("run: Unrecognized message %d\n",
                    msg.mMessageType);
            break;
        }
    }
}

在这里插入图片描述

SoundPool load

可以通过四种途径来记载一个音频资源:

  1. int load(AssetFileDescriptor afd, int priority) 通过一个AssetFileDescriptor对象
  2. int load(Context context, int resId, int priority) 通过一个资源ID
  3. int load(String path, int priority) 通过指定的路径加载
  4. int load(FileDescriptor fd, long offset, long length, int priority) 通过FileDescriptor加载

在AudioService中,按键音用的 int load(String path, int priority) 这种方式,我们就看下这种方式吧。

    public int load(String path, int priority) {
        int id = 0;
        try {
            File f = new File(path);
            ParcelFileDescriptor fd = ParcelFileDescriptor.open(f,
                    ParcelFileDescriptor.MODE_READ_ONLY);
            if (fd != null) {
                id = _load(fd.getFileDescriptor(), 0, f.length
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值