android soundpool

android - La muestra de Soundpool no está lista



(8)

Como mi proyecto es compatible con Android 1.5 y no pude usar setOnLoadCompleteListener, resolví hacer que el juego de sonido se retrasara. Mi código fuente sigue:

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(); }

Tengo un archivo .wav que me gustaría usar en mi juego, actualmente estoy cargando el sonido en onCreate() de cada actividad en el juego.

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

El sonido se reproducirá una vez que comience la actividad.

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

El problema es que a veces daré el error "sample x not ready" . ¿Es posible cargar el archivo .wav una vez al iniciar el juego, guardarlo en la memoria y usarlo más tarde en todo el juego? ¿O es posible esperar 1-2 segundos para que finalice la carga del sonido?


Esto suena loco, pero no juegues sonidos de inmediato. Dale a tu aplicación un par de segundos para inicializar el SoundPool. En mi aplicación, este era exactamente el problema; Agregué una pantalla de "carga" falsa de ~ 3 segundos, y luego todo funcionó. (Ni siquiera necesité precargar los sonidos).


La biblioteca de SoundPool usa el servicio MediaPlayer para decodificar el audio en un flujo de video en mono o estéreo PCM de 16 bits sin formato que simplemente podemos llamar preparación de Stream, que toma algunas veces según el tamaño del archivo de sonido. Y si intentamos reproducir el sonido antes de que finalice el proceso, obtenemos el error "muestra x no está listo".

Hay dos soluciones para esto.

  1. implementar setOnLoadCompleteListener o
  2. Espere una cantidad de tiempo arbitraria para que la preparación haya terminado.

y luego jugar. Tenga en cuenta que no hay ninguna excepción para esta condición o la aplicación no se bloquea sin ningún intento de captura


Resolví el problema con un ciclo de do-while simple. El método play () devuelve un ID de secuencia distinto de cero si tiene éxito, cero si falla. Por lo tanto, es suficiente para comprobar el valor de retorno.

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


Tendrá que esperar a que termine agregando un escucha a través de SoundPool.setOnLoadCompleteListener .


debe usar setOnLoadCompleteListener si es posible ... si no, envuelva un bucle de tiempo alrededor de su llamada para ''jugar''. algo como:

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);}

esto volverá a intentar ''jugar'' 1000 veces en un intervalo de 10 ms. esto debería ejecutarse en un subproceso que no sea de interfaz de usuario, por supuesto, y todavía no es ideal. pero tal vez un poco más fuerte que esperar un tiempo arbitrario y esperar que la piscina esté lista.


¡Esto funcionaría para ti definitivamente!

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(); }


private SoundPool soundPool; private int my_sound; boolean loaded = false;

// En el constructor

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; } });

// entonces donde quiera que quiera reproducir el sonido, escriba

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