Android: geração de onda senoidal
Estou tentando usar o AudioTrack para gerar ondas senoidais, quadradas e dente de serra. No entanto, o áudio que está criando não soa como uma onda senoidal pura, mas como se tivesse algum tipo de onda sobreposta. Como eu iria obter a onda senoidal pura como no segundo exemplo de código, enquanto usava o método no meu primeiro exemplo? Uma vez que o exemplo de cima apenas se move ao redor da aritmética usada no segundo, eles não deveriam produzir uma onda idêntica?
@Override
protected Void doInBackground(Void... foo) {
short[] buffer = new short[1024];
this.track = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, minBufferSize, AudioTrack.MODE_STREAM);
float samples[] = new float[1024];
this.track.play();
while (true) {
for (int i = 0; i < samples.length; i++) {
samples[i] = (float) Math.sin( (float)i * ((float)(2*Math.PI) * frequency / 44100)); //the part that makes this a sine wave....
buffer[i] = (short) (samples[i] * Short.MAX_VALUE);
}
this.track.write( buffer, 0, samples.length ); //write to the audio buffer.... and start all over again!
}
}
Nota: Isso me dá uma onda senoidal pura:
@Override
protected Void doInBackground(Void... foo) {
short[] buffer = new short[1024];
this.track = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, minBufferSize, AudioTrack.MODE_STREAM);
float increment = (float)(2*Math.PI) * frequency / 44100; // angular increment for each sample
float angle = 0;
float samples[] = new float[1024];
this.track.play();
while (true) {
for (int i = 0; i < samples.length; i++) {
samples[i] = (float) Math.sin(angle); //the part that makes this a sine wave....
buffer[i] = (short) (samples[i] * Short.MAX_VALUE);
angle += increment;
}
this.track.write( buffer, 0, samples.length ); //write to the audio buffer.... and start all over again!
}
}
Graças a Martijn: O problema é que a onda está sendo cortada entre comprimentos de onda no buffer. Aumentar o tamanho do buffer resolve o problema no segundo exemplo. Parece que a aritmética Math.PI * 2 foi a mais intensiva do loop, então mover esse valor para uma variável externa que é apenas computada uma vez resolve tudo.