summaryrefslogtreecommitdiffstats
path: root/android
diff options
context:
space:
mode:
authorThomas Martitz <kugel@rockbox.org>2010-08-08 15:53:02 +0000
committerThomas Martitz <kugel@rockbox.org>2010-08-08 15:53:02 +0000
commit4aa3d010660dd5e785e02050ab9a87522f297f7a (patch)
tree1a32ad40a29b425a63ae953b2297447b5a87bf4f /android
parent446445e9162d19ceeabf889e6aa916ec9ec58b5b (diff)
downloadrockbox-4aa3d010660dd5e785e02050ab9a87522f297f7a.tar.gz
rockbox-4aa3d010660dd5e785e02050ab9a87522f297f7a.tar.bz2
rockbox-4aa3d010660dd5e785e02050ab9a87522f297f7a.zip
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
Diffstat (limited to 'android')
-rw-r--r--android/src/org/rockbox/RockboxPCM.java18
1 files 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");