Android AudioTrack woes!

DSP, Plug-in and Host development discussion.
Ap0C552
KVRist
152 posts since 15 Feb, 2012

Post Thu Feb 21, 2019 6:41 pm

I am writing some code that intends to take a Wave file, and write it out to and AudioTrack in mode stream. This is a minimum viable test to get AudioTrack stream mode working. Eventually I am hoping to make a sampler app.

Hopefully I find an AudioTrack expert somewhere, because I am a little confused, and the unclear docs are not helping me!

Once I write some buffer of audio to the AudioTrack, and subsequently call play(), the method getPlaybackHeadPosition() continually returns 0.

I use the getPlackbackHeadPosition() to calculate the room in the buffer. If I ignore my available frames check, and just continually write buffers to the AudioTrack, the write method susequently returns 0 (after the the first buffer write), indicating that it simply did not write any more audio. So it seems that the AudioTrack just doesn't want to start playing.

My code is properly priming the audiotrack. The play method is not throwing any exceptions, so I am not sure what is going wrong.

When stepping through the code, everything on my end is exactly how I anticipate it, so I am thinking somehow I have the AudioTrack configured wrong.

Observe the following log write, which is a snippet from the larger chunk of code. This log write is never hitting...

Code: Select all

                    if (headPosition > 0)
                        Log.e("headPosition is greater than zero!!");
..


Code: Select all

public static void writeToAudioTrackStream(final WavFile wave) 
        {
        Log.e("writeToAudioTrackStream");

        Thread thread = new Thread()
        {
            public void run()
            {
                try {

                    final float[] data = wave.getData();
                    int format = -1;

                    if (wave.getChannel() == 1)
                        format = AudioFormat.CHANNEL_OUT_MONO;
                    else if (wave.getChannel() == 2)
                        format = AudioFormat.CHANNEL_OUT_STEREO;
                    else
                        throw new RuntimeException("writeToAudioTrackStatic() - unsupported number of channels value = "+wave.getChannel());

                    final int bufferSizeInFrames = 2048;
                    final int bytesPerSmp = wave.getBytesPerSmp();
                    final int bufferSizeInBytes = bufferSizeInFrames * bytesPerSmp * wave.getChannel();

                    AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, wave.getSmpRate(),
                            format,
                            AudioFormat.ENCODING_PCM_FLOAT,
                            bufferSizeInBytes,
                            AudioTrack.MODE_STREAM);

                    int index = 0;
                    float[] buffer = new float[bufferSizeInFrames * wave.getChannel()];
                    boolean started = false;
                    int framesWritten = 0;

                    while (index < data.length) {

                        // calculate the available space in the buffer
                        int headPosition = audioTrack.getPlaybackHeadPosition();
                        if (headPosition > 0)
                            Log.e("headPosition is greater than zero!!");
                        int framesInBuffer = framesWritten - headPosition;
                        int availableFrames = bufferSizeInFrames - framesInBuffer;

                        // once the buffer has no space, the prime is done, so start playing
                        if (availableFrames == 0) {
                            if (!started) {
                                audioTrack.play();
                                started = true;
                            }
                            continue;
                        }

                        int endOffset = availableFrames * wave.getChannel();

                        for (int i = 0; i < endOffset; i++)
                            buffer[i] = data[index + i];

                        int samplesWritten = audioTrack.write(buffer , 0 , endOffset , AudioTrack.WRITE_BLOCKING);

                        // could return error values
                        if (samplesWritten < 0)
                            throw new RuntimeException("AudioTrack write error.");

                        framesWritten += samplesWritten / wave.getChannel();
                        index = endOffset;
                    }
                }
                catch (Exception e) {
                    Log.e(e.toString());
                }     
            }
        };

        thread.start();
    }
Thanks for any insight or guidance you can provide!!!
Cheers

KBonzo
KVRer
6 posts since 21 Feb, 2019

Re: Android AudioTrack woes!

Post Sat Feb 23, 2019 11:47 am

I've messed with Android audio but don't claim to be expert... Have you created a debug build and installed it on a device? Are you using logcat to view debug messages? I would log the result of every step with Log.e and use logcat with the app on a real device.

Return to “DSP and Plug-in Development”