2011-03-18 14 views
7

Cómo generar fácilmente sonidos de acordes Synth en Android? Quiero ser capaz de generar dinámicamente una música en el juego utilizando 8 bits. Probado con AudioTrack, pero no obtuvo buenos resultados de sonidos agradables todavía.Cómo generar fácilmente sonidos de acordes Synth en Android?

¿Hay algún ejemplo?

He probado el siguiente código sin éxito:

public class BitLoose { 
    private final int duration = 1; // seconds 
    private final int sampleRate = 4200; 
    private final int numSamples = duration * sampleRate; 
    private final double sample[] = new double[numSamples]; 

    final AudioTrack audioTrack; 

    public BitLoose() { 
     audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 
       sampleRate, AudioFormat.CHANNEL_CONFIGURATION_MONO, 
       AudioFormat.ENCODING_PCM_8BIT, numSamples, 
       AudioTrack.MODE_STREAM); 
     audioTrack.play(); 
    } 

    public void addTone(final int freqOfTone) { 
     // fill out the array 
     for (int i = 0; i < numSamples; ++i) { 
      sample[i] = Math.sin(2 * Math.PI * i/(sampleRate/freqOfTone)); 
     } 

     // convert to 16 bit pcm sound array 
     // assumes the sample buffer is normalised. 
     final byte generatedSnd[] = new byte[numSamples]; 

     int idx = 0; 
     for (final double dVal : sample) { 
      // scale to maximum amplitude 
      final short val = (short) ((((dVal * 255))) % 255); 
      // in 16 bit wav PCM, first byte is the low order byte 
      generatedSnd[idx++] = (byte) (val); 
     } 
     audioTrack.write(generatedSnd, 0, sampleRate); 
    } 

    public void stop() { 
     audioTrack.stop(); 
    } 

Respuesta

2

creo que mal sonido se debe al formato de audio: AudioFormat.ENCODING_PCM_8BIT utiliza muestras sin firmar, por lo que una condición sine entre 1 y -1 se debe convertir a 0-255 valores de bytes, intente esto:

for (final double dVal : sample) { 
    final short val = (short) ((dVal + 1)/2 * 255) ; 
    generatedSnd[idx++] = (byte) val; 
} 

además, trate de cambiar la frecuencia de muestreo a 11025, porque 4200 puede ser soportada en algunos dispositivos:

private final int sampleRate = 11025; 
0

Aparte de respuesta 1 se debe utilizar:
muestra [i] = Math.sin (2 * Math.PI * i/((doble) de sampleRate/freqOfTone));
en lugar de
muestra [i] = Math.sin (2 * Math.PI * i/(sampleRate/freqOfTone));