From 4aa3d010660dd5e785e02050ab9a87522f297f7a Mon Sep 17 00:00:00 2001 From: Thomas Martitz Date: Sun, 8 Aug 2010 15:53:02 +0000 Subject: [PATCH] Run the pcm callback from a separate OS thread, that seems to make audio playback much more reliable. Especially on the broken HTC phones. Now it recovers from stuttering instead of simply stopping playback on my phone. Previously it was run on the main/UI thread (the docs lie in that regard), which I suspect happened to be blocked if it's in the background and tries to get too much CPU. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@27753 a1c6a512-1295-4272-9138-f99709370657 --- android/src/org/rockbox/RockboxPCM.java | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/android/src/org/rockbox/RockboxPCM.java b/android/src/org/rockbox/RockboxPCM.java index 631d925b12..eef56f501d 100644 --- a/android/src/org/rockbox/RockboxPCM.java +++ b/android/src/org/rockbox/RockboxPCM.java @@ -24,6 +24,9 @@ package org.rockbox; import android.media.AudioFormat; import android.media.AudioManager; import android.media.AudioTrack; +import android.os.Handler; +import android.os.HandlerThread; +import android.os.Process; import android.util.Log; public class RockboxPCM extends AudioTrack @@ -31,6 +34,8 @@ public class RockboxPCM extends AudioTrack byte[] raw_data; private int buf_len; private PCMListener l; + private HandlerThread ht; + private Handler h = null; private void LOG(CharSequence text) { @@ -46,6 +51,8 @@ public class RockboxPCM extends AudioTrack AudioFormat.ENCODING_PCM_16BIT, 24<<10, AudioTrack.MODE_STREAM); + ht = new HandlerThread("audio thread", Process.THREAD_PRIORITY_URGENT_AUDIO); + ht.start(); buf_len = 24<<10; /* in bytes */ raw_data = new byte[buf_len]; /* in shorts */ @@ -76,10 +83,12 @@ public class RockboxPCM extends AudioTrack RockboxService.startForeground(); if (getState() == AudioTrack.STATE_INITIALIZED) { + if (h == null) + h = new Handler(ht.getLooper()); if (setNotificationMarkerPosition(bytes2frames(buf_len)/4) != AudioTrack.SUCCESS) LOG("setNotificationMarkerPosition Error"); else - setPlaybackPositionUpdateListener(l); + setPlaybackPositionUpdateListener(l, h); } /* need to fill with silence before starting playback */ write(raw_data, frames2bytes(getPlaybackHeadPosition()), raw_data.length); @@ -140,10 +149,11 @@ public class RockboxPCM extends AudioTrack { case AudioTrack.PLAYSTATE_PLAYING: case AudioTrack.PLAYSTATE_PAUSED: - /* recharge */ - setPlaybackPositionUpdateListener(this); /* refill at 25% no matter of how many bytes we've written */ - setNotificationMarkerPosition(bytes2frames(refill_mark)); + if (setNotificationMarkerPosition(bytes2frames(refill_mark)) != AudioTrack.SUCCESS) + LOG("Error in onMarkerReached: Could not set notification marker"); + else /* recharge */ + setPlaybackPositionUpdateListener(this, h); break; case AudioTrack.PLAYSTATE_STOPPED: LOG("State STOPPED");