Android: Sine Wave Generation

Estoy tratando de usar AudioTrack para generar ondas sinusoidales, cuadradas y de diente de sierra. Sin embargo, el audio que está creando no suena como una onda sinusoidal pura, sino que tiene una especie de otra onda superpuesta. ¿Cómo haría para obtener la onda sinusoidal pura como en el segundo ejemplo de código, al usar el método en mi primer ejemplo? Como el ejemplo superior solo se mueve alrededor de la aritmética utilizada en el segundo, ¿no deberían producir una 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: Esto me da una onda sinusoidal 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!

            }           
        }

Gracias a Martijn: El problema es que la onda se está cortando entre las longitudes de onda en el búfer. Aumentar el tamaño del búfer resuelve el problema en el segundo ejemplo. Parece que la aritmética Math.PI * 2 fue la más intensiva del bucle, por lo que mover ese valor a una variable externa que solo se calcula una vez que resuelve todo.

Respuestas a la pregunta(3)

Su respuesta a la pregunta