Frage

Wie generiere ich in Android leicht Synth -Akkorde? Ich möchte in der Lage sein, mit 8bit dynamisch eine in der Spielmusik zu generieren. Versucht mit Audiotrack, aber noch keine guten Ergebnisse von schönen Geräuschen erzielt.

Irgendwelche Beispiele da draußen?

Ich habe den folgenden Code ohne Erfolg ausprobiert:

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();
    }
War es hilfreich?

Lösung

Ich denke, dass ein schlechter Klang auf das Audio -Format zurückzuführen ist: AudioFormat.Coding_pcm_8bit verwendet unsignierte Proben, sodass eine Sinus zwischen 1 und -1 in 0-255 -Byte -Werte konvertiert werden muss, versuchen Sie Folgendes:

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

Versuchen Sie auch, die Stichprobenrate auf 11025 zu ändern, da 4200 auf einigen Geräten möglicherweise nicht unterstützt werden:

private final int sampleRate = 11025;

Andere Tipps

Abgesehen von Antwort 1 sollten Sie verwenden:
Beispiel [i] = Math.sin (2 * Math.pi * i / (((doppelt) Sampledel / freqoftone));
Anstatt von
Beispiel [i] = math.sin (2 * math.pi * i / (sampled / freqoftone));

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top