I'm trying to make a real-time audio application on android.
As OnPlaybackPositionUpdateListener seems never working on any versions of android, I'm on a workaround using separate thread that keeps writing on a buffer of an AudioTrack instance. track.write()
seems to be a blocking call and it doesn't insanely write data on the buffer.
Below is a simple program that repeats 12 notes from A to G#.
It makes all 12 kinds of sounds right after it launches, but within a minute it makes only 2 kinds of sounds (A# and F). track.getPlaybackHeadPosition()
returns ~ 4,000,000 when it's playing 2 notes. It was reproduced on nexus one and emulator running froyo.
Would there be any workaround like resetting AudioTrack periodically?
public class Sound extends Activity
{
static final String TAG="Sound";
AudioTrack track;
float increment;
float angle = 0;
float step = 0;
short[] buffer;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final int minSize = AudioTrack.getMinBufferSize( 48000, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT );
buffer = new short[minSize];
track = new AudioTrack( AudioManager.STREAM_MUSIC, 48000,
AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT,
minSize, AudioTrack.MODE_STREAM);
track.play();
new Thread(new Runnable() {
public void run() {
while(true) {
float frequency=880*(float)Math.pow(2.0,step);
increment = (float)(2*Math.PI) * frequency / 48000.0f;
step+=1.0f/12;
if(step>=0.99) step=0;
for( int i = 0; i < buffer.length; i++, angle += increment) {
buffer[i] = (short)(Short.MAX_VALUE/2 * Math.sin( angle ));
}
track.flush();
track.write(buffer, 0, buffer.length);
}
}
}).start();
}
Thanks