【问题标题】:How to play a sound simultaneously using SoundPool for a specific period of time如何在特定时间段内使用 SoundPool 同时播放声音
【发布时间】:2013-07-07 05:41:34
【问题描述】:

我正在使用一个 android 媒体应用程序,我想在特定时间段内同时播放声音文件。所以我创建了一个类,我在这个类中使用SoundPoolThread 概念来播放声音,但是当我运行我的应用程序时,它会进入 ANR 状态并在 log-cat 中显示警告

样本 2130968576 未就绪

请大家帮我解决这个问题...

    package com.kodspider.funk;
import android.content.Context;
import android.media.AudioManager;
import android.media.SoundPool;

public class CustomPlayer implements Runnable{

int song_id;
long time;
int button_id;
Context ctx;
SoundPool soundpool;

public CustomPlayer(int s_id, long Time, Context ct){

song_id = load(ctx, s_id, 0);
time = Time;
ctx = ct;

}
public void run(){
long start = System.currentTimeMillis();
System.out.println("set_time:"+time+"Song_id:"+song_id+"current_time:"+start);
long end = start + time;
while (System.currentTimeMillis() < end){

    //Initialization 
    soundpool = new SoundPool(8, AudioManager.STREAM_MUSIC, 0);
    soundpool.play(song_id, 1.0f, 1.0f, 1, -1, 1.0f);

                    }
                    }
public int load (Context context, int resId, int priority){
    return resId;

}

                    }

logcat

07-07 10:57:51.828: I/ApplicationPackageManager(13625): cscCountry is not German : INS
07-07 10:57:57.656: I/ApplicationPackageManager(13625): cscCountry is not German : INS
07-07 10:57:59.343: W/KeyCharacterMap(13625): Can't open keycharmap file
07-07 10:57:59.343: W/KeyCharacterMap(13625): Error loading keycharmap file
07-07 10:57:59.343: W/KeyCharacterMap(13625): Using default keymap
07-07 10:58:44.820: I/ApplicationPackageManager(13625): cscCountry is not German : INS
07-07 10:58:49.718: I/System.out(13625): TAG------->60000---->2130968576
07-07 10:58:49.726: W/SoundPool(13625):   sample 2130968576 not READY

【问题讨论】:

    标签: android multithreading android-mediaplayer soundpool


    【解决方案1】:

    我正在用我的应用程序 Beat Shaker 做类似的事情,我遇到了同样的问题。我使用 onLoadCompleteListener 解决了它:

    // Sound pool new instance
    SoundPool spool = new SoundPool(3, AudioManager.STREAM_MUSIC, 0);
    // Sound pool on load complete listener
    spool.setOnLoadCompleteListener(new OnLoadCompleteListener() {
        @Override
        public void onLoadComplete(SoundPool soundPool, int sampleId,
                            int status) {
            Log.i("OnLoadCompleteListener","Sound "+sampleId+" loaded.");
            boolean loaded = true;
        }
    });       
    // Load the sample IDs
    int soundId = new int[3];
    soundId[0] = spool.load(this, R.raw.sound1, 1);
    soundId[1] = spool.load(this, R.raw.sound2, 1);
    soundId[2] = spool.load(this, R.raw.sound3, 1);
    

    稍后在播放声音之前,您可以使用布尔值“loaded”检查它是否正确加载。

    【讨论】:

      【解决方案2】:

      您需要先load() 您的声音。这会将它们加载到内存中,为play() 做好准备。这将返回一个您需要存储并传递给 play()

      的 id

      来自SoundPool 文档:

      让我们来看看一个典型的用例:一个游戏包含多个级别的游戏。对于每个级别,都有一组仅由该级别使用的独特声音。在这种情况下,游戏逻辑应该在加载第一个关卡时创建一个新的 SoundPool 对象。关卡数据本身可能包含该关卡要使用的声音列表。加载逻辑遍历调用适当 SoundPool.load() 函数的声音列表。这通常应在流程的早期完成,以便在需要播放之前留出时间将音频解压缩为原始 PCM 格式。

      http://developer.android.com/reference/android/media/SoundPool.html#load(android.content.res.AssetFileDescriptor, int)

      查看此示例中的 SoundPool 部分:http://www.vogella.com/articles/AndroidMedia/

      【讨论】:

      • 我编辑了你在回答中提到的类文件,我仍然处于同样的情况意味着它没有播放任何声音,但在 logcat 中没有显示任何警告。
      • 对不起,我忘了从活动中调用构造函数。现在它在 logcat 中返回相同的警告,直到 while 循环结束。
      • 确保将load() 返回的id 传递给play()。在上面的代码中,您只是返回resId。另外我根本看不到你在哪里打电话给load()
      • 签入构造函数有类似song_id = load(ctx, s_id, 0);的行
      • 我明白了,我的错误。你的架构是错误的,当你调用.play() 它会播放声音,你不应该把它放在一个while循环中。这是错误的,因为你一遍又一遍地调用 play。要在特定时间停止它,您应该使用处理程序并在适当的时间调用 stop()。
      【解决方案3】:

      你可以看到代码

      public class SoundManager {
      
          public static int SOUNDPOOLSND_MENU_BTN = 0;
          public static int SOUNDPOOLSND_WIN = 1;
          public static int SOUNDPOOLSND_LOOSE = 2;
          public static int SOUNDPOOLSND_DRAW = 3;
          public static int SOUNDPOOLSND_TICK1 = 4;
          public static int SOUNDPOOLSND_TICK2 = 5;
          public static int SOUNDPOOLSND_OUT_OF_TIME = 6;
          public static int SOUNDPOOLSND_HISCORE = 7;
          public static int SOUNDPOOLSND_CORRECT_LETTER = 8;
      
          public static boolean isSoundTurnedOff;
      
          private static SoundManager mSoundManager;
      
          private SoundPool mSoundPool;
          private SparseArray<Integer> mSoundPoolMap;
          private AudioManager mAudioManager;
      
          public static final int maxSounds = 4;
      
          public static SoundManager getInstance(Context context) {
              if (mSoundManager == null) {
                  mSoundManager = new SoundManager(context);
              }
      
              return mSoundManager;
          }
      
          public SoundManager(Context mContext) {
              mAudioManager = (AudioManager) mContext
                      .getSystemService(Context.AUDIO_SERVICE);
              mSoundPool = new SoundPool(maxSounds, AudioManager.STREAM_MUSIC, 0);
      
              mSoundPool.setOnLoadCompleteListener(new OnLoadCompleteListener() {
                  public void onLoadComplete(SoundPool soundPool, int sampleId,
                          int status) {
                      boolean loaded = true;
                  }
              });
      
              mSoundPoolMap = new SparseArray<Integer>();
              mSoundPoolMap.put(SOUNDPOOLSND_MENU_BTN,
                      mSoundPool.load(mContext, R.raw.rain, 0));
              mSoundPoolMap.put(SOUNDPOOLSND_WIN,
                      mSoundPool.load(mContext, R.raw.nature, 1));
              mSoundPoolMap.put(SOUNDPOOLSND_LOOSE,
                      mSoundPool.load(mContext, R.raw.piano, 2));
              mSoundPoolMap.put(SOUNDPOOLSND_TICK1,
                      mSoundPool.load(mContext, R.raw.relax, 3));
              mSoundPoolMap.put(SOUNDPOOLSND_TICK2,
                      mSoundPool.load(mContext, R.raw.storm, 4));
      
      
              // testing simultaneous playing
              int streamVolume = mAudioManager
                      .getStreamVolume(AudioManager.STREAM_MUSIC);
              mSoundPool.play(mSoundPoolMap.get(0), streamVolume, streamVolume, 1,
                      0, 1f);
              mSoundPool.play(mSoundPoolMap.get(1), streamVolume, streamVolume, 1, 0,
                      1f);
              mSoundPool.play(mSoundPoolMap.get(2), streamVolume, streamVolume, 1, 0,
                      1f);
      
          }
      
          public void playSound(int index) {
              if (isSoundTurnedOff)
                  return;
      
              int streamVolume = mAudioManager
                      .getStreamVolume(AudioManager.STREAM_MUSIC);
              mSoundPool.play(mSoundPoolMap.get(index), streamVolume, streamVolume,
                      1, 0, 1f);
          }
      
          public static void clear() {
              if (mSoundManager != null) {
                  mSoundManager.mSoundPool = null;
                  mSoundManager.mAudioManager = null;
                  mSoundManager.mSoundPoolMap = null;
              }
              mSoundManager = null;
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-14
        相关资源
        最近更新 更多