web-dev-qa-db-ja.com

サウンドプールサンプルの準備ができていません

ゲーム全体で使用したい.wavファイルがあります。現在、ゲームの各アクティビティのonCreate()にサウンドを読み込んでいます。

 soundCount = soundpool.load(this,R.raw.count, 1);

アクティビティが開始されると、サウンドが再生されます。

  soundpool.play(soundCount, 0.9f, 0.9f, 1, -1, 1f);

問題はときどきエラーが発生する"sample x not ready"。ゲームの開始時に.wavファイルを一度ロードしてメモリに保持し、後でゲーム全体で使用することはできますか?または、サウンドの読み込みが完了するまで1〜2秒待つことはできますか?

23
SteD

SoundPool.setOnLoadCompleteListener経由でリスナーを追加して、終了するまで待つ必要があります。

35
EboMike

私のプロジェクトはAndroid 1.5と互換性があり、setOnLoadCompleteListenerを使用できなかったため、サウンドの再生を遅延させることを解決しました。私のソースコードは次のとおりです。

    playSound_Delayed(soundId, 100);

//(..)

private void playSound_Delayed (final int soundId, final long millisec) {
    // TIMER
    final Handler mHandler = new Handler();
    final Runnable mDelayedTimeTask = new Runnable() {
    int counter = 0;
    public void run() {
        counter++;

        if (counter == 1) {
            boolean ret = mHandler.postDelayed(this, millisec); 
            if (ret==false) Log.w("playSound_Delayed", "mHandler.postAtTime FAILED!");
       } else {
           playSound(soundId);
       }
    }
    };
    mDelayedTimeTask.run();
}
5
Lisitso

可能な場合はsetOnLoadCompleteListenerを使用する必要があります。そうでない場合は、whileループを「play」への呼び出しにラップします。何かのようなもの:

int waitLimit = 1000;
int waitCounter = 0;
int throttle = 10;
while(soundPool.play(soundId, 1.f, 1.f, 1, 0, 1.f) == 0 && waitCounter < waitLimit)
 {waitCounter++; SystemClock.sleep(throttle);}

これにより、10ms間隔で「再生」が1000回再試行されます。もちろん、これは非UIスレッドで実行する必要があり、まだ理想的ではありません。しかし、任意の時間待機してプールの準備ができることを期待するよりも少し強力かもしれません。

4
newbyca

これは間違いなくあなたのために働くでしょう!

public void playWavFile() {

    Thread streamThread = new Thread(new Runnable() {           

        @Override
        public void run() {                 
            SoundPool soundPool;
            final int wav;
            String path = "/mnt/sdcard/AudioRecorder/record.wav";
            soundPool = new SoundPool(5,AudioManager.STREAM_MUSIC, 0);
            wav = soundPool.load(path, 1);
            soundPool.setOnLoadCompleteListener(new OnLoadCompleteListener() {
                @Override
                public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
                    // TODO Auto-generated method stub
                    soundPool.play(wav,100, 100, 0, 0, 1f);
                }
            });

        }        
    });

    streamThread.start();
}   
2
Mahe

SoundPoolライブラリはMediaPlayerサービスを使用して、オーディオを生の16ビットPCMモノラルまたはステレオストリームにデコードします。これは、単にStreamの準備と呼ばれ、サウンドファイルのサイズによっては時間がかかります。そして、そのプロセスが終了する前にサウンドを再生しようとすると、「sample x not ready」エラーが発生します。

これには2つの解決策があります

  1. setOnLoadCompleteListenerを実装するか、
  2. 準備が終わるまで任意の時間待機します

そして、それを再生します。この条件に例外はありません。または、アプリケーションは、try-catchなしではクラッシュしません。

2
CR Sardar
private SoundPool soundPool;
private int my_sound;
boolean loaded = false;

//コンストラクタ内

soundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
my_sound = soundPool.load(this, R.raw.blast_sound, 1);

soundPool.setOnLoadCompleteListener(new OnLoadCompleteListener() {
    public void onLoadComplete(SoundPool soundPool, int sampleId,int status) {
       loaded = true;
    }
});

//次に、サウンドを再生する場所に次のように入力します

if (loaded) {
soundPool.play(my_sound,  0.9f, 0.9f, 1, 0, 1f);
}
2
Mahesh

単純なdo-while cicleの問題で解決しました。 play()メソッドは、成功した場合はゼロ以外のstreamIDを返し、失敗した場合はゼロを返します。したがって、戻り値を確認するだけで十分です。

int streamID = -1;
do {
    streamID = soundPool.play(soundPoolMap.get(index), streamVolume, streamVolume, 1, 0, 1f);
} while(streamID==0);
2
DrFred

これはクレイジーに聞こえますが、すぐにサウンドを再生しないでください。アプリに数秒かけてSoundPoolを初期化します。私のアプリでは、これがまさに問題でした。約3秒の偽の「読み込み」画面を追加したところ、すべてが機能しました。 (サウンドをプリロードする必要すらありませんでした。)

1
ashes999