Wie generiere ich in Android leicht Synth -Akkorde?
-
27-10-2019 - |
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();
}
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));