2011-03-18 7 views
7

Comment générer facilement des sons Synth Chords dans Android? Je veux être capable de générer dynamiquement un jeu en musique en utilisant 8bit. Essayé avec AudioTrack, mais n'a pas encore obtenu de bons résultats de beaux sons pour le moment.Comment générer facilement des sons Synth Chords dans Android?

Des exemples là-bas?

J'ai essayé le code suivant sans succès:

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

Répondre

2

Je pense que son mauvais est dû au format audio: AudioFormat.ENCODING_PCM_8BIT utilise des échantillons non signés, donc une condition sine entre 1 et -1 doit être converti en 0-255 valeurs d'octets, essayez ceci:

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

essayez également de changer la fréquence d'échantillonnage à 11025, parce que 4200 peut être non pris en charge sur certains appareils:

private final int sampleRate = 11025; 
0

En dehors de réponse 1 vous devez utiliser:
échantillon [i] = Math.sin (2 * Math.PI. * i/((double) sampleRate/freqOfTone));
au lieu de
exemple [i] = Math.sin (2 * Math.PI * i/(sampleRate/freqOfTone));

Questions connexes