我正在尝试使用AudioTrack生成正弦、方波和锯齿波。然而,这个音频听起来并不像是一个纯正的正弦波,而像是有其他波形叠加在上面。如何在使用第一个示例中的方法时获得第二个示例中的纯正弦波?因为第一个示例只是在第二个示例中移动了一些算术运算,它们不应该产生相同的波形吗?
@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!
}
}
注意:这确实给我一个纯正的正弦波:
@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!
}
}
感谢Martijn:问题在于波在缓冲区的波长之间被截断了。增加缓冲区大小解决了第二个示例中的问题。似乎Math.PI * 2算术运算是循环中最密集的,因此将该值移动到仅计算一次的外部变量可以解决所有问题。