Estoy desarrollando una aplicación de metrónomo. El usuario puede seleccionar en tiempo de ejecución los bpm, y mi aplicación reproducirá el sonido "tick" en consecuencia. El "tic" es un solo metrónomo "shot" (mp3). Intenté implementarlo usando Handler y MediaPlayer, pero el metrónomo no es preciso en absoluto. así que pensé en cambiar todo el enfoque: cuando el usuario seleccione un nuevo valor de BPM, sintetizo un nuevo sonido mediante la repetición de los X veces de sonido tic cada N milisegundos, a continuación, un bucle sobre este sonido creado en tiempo de ejecución. ¿Es esta una alternativa válida? ¿Cómo se puede implementar en Android?reproducir un sonido cada N milisegundos
Respuesta
La alternativa de bucle a través de un sonido sintetizado parece ser la mejor opción por el momento. Hubo una gran sesión sobre audio en Google I/O 2013 llamado High Performance Audio que sin duda viendo consejos para tener una comprensión más profunda de cómo funciona el sistema y qué problemas los desarrolladores se enfrentan cuando se trata de la latencia de audio. Aproximadamente a las 17:00 del video, hay un gráfico que muestra jitter frente a devoluciones de llamada. En el mundo perfecto que no existe (¿en serio?), El jitter sería cero para todas las devoluciones programadas de audio realizadas. Pero ese no es el caso, ya que hay temblores de hasta 35 milisegundos o incluso más, ya que los datos en el gráfico se hicieron usando un dispositivo ICS no especificado y ciertamente hay peores escenarios que eso.
lo tanto, como un metrónomo es una herramienta de precisión y estos nervios no son buenos en todo, el enfoque de la reproducción programada se debe dejar a un lado. Incluso hice un metrónomo razonablemente confiable con un sonido sintetizado usando AudioTrack
.
creo que sirve ^^
Disculpe si esto es tarde, ¿podría publicar su código donde implementó con éxito un metrónomo utilizando 'AudioTrack'? –
Aquí: http://masterex.github.io/archive/2012/05/28/android-audio-synthesis.html –
Puede intentar utilizar un TimerTask programado para la ejecución de tasa fija en un Timer.
temporizador y TimerTask son tanto parte del SDK de Android (y Java SE). Las ejecuciones no se retrasan debido al tiempo de ejecución del evento anterior.
Timer timer = new Timer("MetronomeTimer", true);
TimerTask tone = new TimerTask(){
@Override
public void run(){
//Play sound
}
};
timer.scheduleAtFixedRate(tone, 500, 500); //120 BPM. Executes every 500 ms.
Puede cancelar el TimerTask cuando necesite cambiar los BPM.
tone.cancel();
tone = new TimerTask(){...}
timer.scheduleAtFixedRate(tone, 1000, 1000); //60 BPM. Executes every 1000 ms.
Otra posibilidad que puede satisfacer sus necesidades (de sus comentarios) está haciendo girar un hilo y la comprobación System.nanoTime() y durmiendo en incrementos pero girando cuando se acerque a despertar.
long delayNanos = 500000000;
long wakeup = System.nanoTime() + delayNanos; //Half second from right now
long now;
while(!done){
now = System.nanoTime();
//If we are less than 50 milliseconds from wake up. Spin away.
if(now <= wakeup - 50000000){
//Sleep in very small increments, so we don't spin unrestricted.
Thread.sleep(10);
}
if(now >= wakeup){
//Play sound
wakeup += delayNanos;
}
}
Las implementaciones de subprocesos no son buenas para esta tarea, tanto en el sabor de Java (Timer + TimerTask) como en el de Android (Handler + Message). El tiempo en los móviles es absolutamente malo – Raffaele
Para evitar el problema de granularidad con respecto a las esperas, existe la posibilidad de que haya un hilo que siga funcionando (utilizando Thread.yield()), verificando constantemente el tiempo y despertando el otro hilo. Podría ser una solución. –
@chris ya lo intenté. No resuelve el problema – Raffaele
Cuando este sonido juego se llama
mSoundManager.playSound(1);
espera Android hasta que se termine la llamada, a continuación, se llama a
mHandler.postAtTime(this, SystemClock.uptimeMillis() + 200);
Sin embargo, si invierte los llamadas, puede encontrar que el tiempo es más preciso.
mHandler.postAtTime(this, SystemClock.uptimeMillis() + 200);
mSoundManager.playSound(1);
No se puede contar con su sonido teniendo exactamente la misma cantidad de tiempo para jugar, por lo que dice el manejador de la publicación, en primer lugar es un poco mejor. Todavía no es ideal, sin embargo.
- 1. Reproducir sonido con SoundPool
- 2. Reproducir (y reproducir) un sonido en safari mobile
- 3. Cómo reproducir un archivo de sonido
- 4. ¿Cómo puedo reproducir un sonido en WinForms?
- 5. ¿Cómo reproducir un sonido de Windows estándar?
- 6. Cómo reproducir un sonido en C#, .NET
- 7. Cómo reproducir sonido con Qt
- 8. Reproducir un sonido en un complemento de Firefox
- 9. ¿Grabar sonido y reproducir sonido modulado en Android?
- 10. Reproducir un sonido cuando se presiona una tecla
- 11. Qt - cómo grabar y reproducir sonido simultáneamente
- 12. Notificación de Android para reproducir sonido solo
- 13. Reproducir sonido múltiple al mismo tiempo
- 14. ¿Cómo puedo reproducir sonido en Java?
- 15. Reproducir un sonido cuando se hace clic en Android
- 16. ¿Cómo hago para reproducir un sonido de alarma en Python?
- 17. Cómo reproducir un sonido de notificación de Android
- 18. Reproducir sonido al recibir un mensaje de chat web
- 19. Cómo reproducir un efecto de sonido en Android
- 20. Manera simple de reproducir un archivo de sonido (.aif)
- 21. Cómo usar AudioQueue para reproducir un sonido para Mac OSX en C++
- 22. ¿Establecer ToggleButton para reproducir el sonido predeterminado al hacer clic?
- 23. Cómo reproducir tono de llamada/sonido de alarma en Android
- 24. La mejor manera de reproducir sonido con HTML5 y Javascript
- 25. Mala calidad de sonido al grabar/reproducir sonidos - Android SDK
- 26. Reproducir clip de sonido Mp3 en mouseclick usando jplayer?
- 27. Reproducir sonido en iPhone incluso en modo silencioso
- 28. ¿Cómo realizar operaciones al reproducir sonido en iPhone?
- 29. Cómo reproducir el sonido de la cámara nativa en Android
- 30. ¿Cómo grabar y reproducir sonido en la aplicación iPhone?
bucle será, de nuevo, crear una demora inexacta. Por lo tanto, debe usar un sonido de metrónomo largo, el más largo, mejor, para evitar o, al menos, minimizar la demora entre reproducciones en el ciclo.Y, a continuación, utilice algún método para hacer frente al retraso introducido, comparando el tiempo actual con el tiempo de ejecución y avanzando hacia adelante el flujo de reproducción para compensar el desplazamiento. –
En realidad, implementé esto a través de AudioTrack y la demora de bucle de la que está hablando no se nota en absoluto. Comparado con un metrónomo real, es de aproximadamente 0.5 bpm, por lo que es definitivamente aceptable. – Raffaele
¿Puede mostrarme algún código sobre cómo lo ha hecho? ¡Estoy bastante interesado! – MartijnG