tonos - Audio de Android: cambio de tono
tono de alarma predeterminado silenciado motorola (2)
Aunque la documentación de Androids sugiere que puede usar setRate()
para producir efectos Doppler, no confiaría en una implementación lo suficientemente rápida o suficientemente buena en cada dispositivo Android.
Los circuitos integrados de audio asequibles requieren una frecuencia de muestreo fija de 44 kHz o 48 kHz. Por lo tanto, la conversión de frecuencia de muestreo (es decir, la modificación de tono) debe realizarse en el software. Debido a que esto incluye el crujido de números de bajo nivel, estoy seguro de que esto es implementado por el fabricante del dispositivo y no por Google. Dada la amplia variedad de fabricantes de dispositivos Android y el hardware a menudo de bajo costo utilizado, sin duda hay muchas implementaciones de conversión de frecuencia de muestreo. Algunos más rápido, otros más lento. Algunos suaves, otros irregulares.
¿Qué sucede al cambiar la tasa de conversión durante la reproducción? Si el algoritmo no hace coincidir las piezas exactamente juntas, puede haber una pequeña grieta en la reproducción de audio. Cambia la tasa de conversión cada 10 milisegundos. Si hay una grieta cada 10 ms, eso corresponde a una frecuencia de 100 Hz, que es un tono en sí mismo. Es probable que esto sea lo que escuchas como "harapiento".
En general, no creo que sea posible emular instrumentos musicales en tiempo real en una amplia gama de dispositivos Android que usan Android API de alto nivel. Sin embargo, una aplicación nativa puede ser lo suficientemente rápida.
La documentación de Android para SoundPool dice que "la aplicación también puede alterar el tono ajustando la velocidad de reproducción en tiempo real para efectos Doppler o de síntesis". Así que traté de hacerlo, utilizando el método setRate para variar sin problemas de una nota a otra, pero el resultado es horrible: la variación del sonido es muy desigual. Aquí está el código que probé. Por favor dime si hay una mejor manera.
int streamId = soundPool.play (soundId, 1, 1, 1, 0, 1.0f);
for (float x = 0; x < 1; x += 0.005) {
SystemClock.sleep (10);
soundPool.setRate (streamId, 1 + x);
}
Después de probar todo, decidí ir con SoundPool para cambiar el tono, una velocidad de reproducción de 2.0 hace que el sonido se reproduzca a una frecuencia doble a su original, y una velocidad de reproducción de 0,5 hace que se reproduzca a la mitad de su frecuencia original. El rango de velocidad de reproducción es de 0.5 a 2.0. Pero funcionó con frecuencia más baja y más alta que 0.5 y 2.0.
Estoy publicando mi código de trabajo,
pero como es solo para fines de demostración, aquí necesita cambiar manualmente la "tasa de reproducción", cada vez que instale la aplicación, por ejemplo: "sp.play (explosion, 1,1,0,0,1.5f)" here "1.5 f "es la velocidad de reproducción. Uno puede crear fácilmente un EditView, o algo similar para establecer el valor de la velocidad de reproducción en tiempo de ejecución.
En esta aplicación, solo necesita tocar en la pantalla de la aplicación para reproducir la música a la velocidad de reproducción establecida.
import java.io.IOException;
import android.app.Activity;
import android.content.res.AssetFileDescriptor;
import android.media.AudioManager;
import android.media.SoundPool;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class SoundPoolActivity extends Activity implements OnClickListener {
SoundPool sp;
int explosion = 0;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View v = new View(this);
v.setOnClickListener(this);
setContentView(v);
sp = new SoundPool(1,AudioManager.STREAM_MUSIC,0);
//explosion = sp.load(this, R.raw.hh,0);
explosion = sp.load("/sdcard/hh.m4a",0);
}
public void onClick(View v){
if (explosion!=0){
sp.play(explosion, 1,1,0,0,2.3f);
}
}
}