Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 47d62885 authored by Narayan Kamath's avatar Narayan Kamath
Browse files

Wait until the audio track finishes playing before releasing it.

Release calls stop, which causes truncation of playback.
bug:5021056

Change-Id: I8eadcbf5622dab83be3c4dabfcc06629398f27ab
parent 622c03e6
Loading
Loading
Loading
Loading
+25 −6
Original line number Diff line number Diff line
@@ -384,7 +384,7 @@ class AudioPlaybackHandler {
            }
            count += written;
        }

        param.mBytesWritten += count;
        param.mLogger.onPlaybackStart();
    }

@@ -396,14 +396,16 @@ class AudioPlaybackHandler {
        params.mLogger.onWriteData();
    }

    // Flush all remaining data to the audio track, stop it and release
    // all it's resources.
    // Wait for the audio track to stop playing, and then release it's resources.
    private void handleSynthesisDone(SynthesisMessageParams params) {
        if (DBG) Log.d(TAG, "handleSynthesisDone()");
        final AudioTrack audioTrack = params.getAudioTrack();

        try {
            if (audioTrack != null) {
                if (DBG) Log.d(TAG, "Waiting for audio track to complete : " +
                        audioTrack.hashCode());
                blockUntilDone(params);
                if (DBG) Log.d(TAG, "Releasing audio track [" + audioTrack.hashCode() + "]");
                // The last call to AudioTrack.write( ) will return only after
                // all data from the audioTrack has been sent to the mixer, so
@@ -417,6 +419,18 @@ class AudioPlaybackHandler {
        }
    }

    private static void blockUntilDone(SynthesisMessageParams params) {
        if (params.mAudioTrack == null || params.mBytesWritten <= 0) {
            return;
        }

        final AudioTrack track = params.mAudioTrack;
        final int bytesPerFrame = getBytesPerFrame(params.mAudioFormat);
        final int lengthInBytes = params.mBytesWritten;

        blockUntilDone(track, bytesPerFrame, lengthInBytes);
    }

    private void handleSynthesisCompleteDataAvailable(MessageParams msg) {
        final SynthesisMessageParams params = (SynthesisMessageParams) msg;
        if (DBG) Log.d(TAG, "completeAudioAvailable(" + params + ")");
@@ -455,13 +469,18 @@ class AudioPlaybackHandler {
    }


    private static void blockUntilDone(AudioTrack audioTrack, int bytesPerFrame, int length) {
        int lengthInFrames = length / bytesPerFrame;
    private static void blockUntilDone(AudioTrack audioTrack, int bytesPerFrame,
            int lengthInBytes) {
        int lengthInFrames = lengthInBytes / bytesPerFrame;
        int currentPosition = 0;
        while ((currentPosition = audioTrack.getPlaybackHeadPosition()) < lengthInFrames) {
            if (audioTrack.getPlayState() != AudioTrack.PLAYSTATE_PLAYING) {
                break;
            }

            long estimatedTimeMs = ((lengthInFrames - currentPosition) * 1000) /
                    audioTrack.getSampleRate();
            audioTrack.getPlayState();

            if (DBG) Log.d(TAG, "About to sleep for : " + estimatedTimeMs + " ms," +
                    " Playback position : " + currentPosition);
            try {
+4 −1
Original line number Diff line number Diff line
@@ -32,7 +32,9 @@ final class SynthesisMessageParams extends MessageParams {
    final float mPan;
    final EventLogger mLogger;

    public volatile AudioTrack mAudioTrack;
    volatile AudioTrack mAudioTrack;
    // Not volatile, accessed only from the synthesis thread.
    int mBytesWritten;

    private final LinkedList<ListEntry> mDataBufferList = new LinkedList<ListEntry>();

@@ -52,6 +54,7 @@ final class SynthesisMessageParams extends MessageParams {

        // initially null.
        mAudioTrack = null;
        mBytesWritten = 0;
    }

    @Override