summaryrefslogtreecommitdiff
path: root/android
diff options
context:
space:
mode:
authorThomas Martitz <kugel@rockbox.org>2010-08-04 18:34:32 +0000
committerThomas Martitz <kugel@rockbox.org>2010-08-04 18:34:32 +0000
commitbd9c0b21d6209b687be5f0006c0d9dc68aefbccf (patch)
tree900f199596e0442f1e52753a0b225cceffb93664 /android
parentc216100f843d5ec0fba5a4f49907d666a65028b1 (diff)
downloadrockbox-bd9c0b21d6209b687be5f0006c0d9dc68aefbccf.tar.gz
rockbox-bd9c0b21d6209b687be5f0006c0d9dc68aefbccf.zip
A bit of work in the pcm driver. Should be a bit more efficient, but more importantly more dependable. Stopping playback now properly recovers if playback crashed for some reason (shouldn't happen of course).
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@27698 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'android')
-rw-r--r--android/src/org/rockbox/RockboxPCM.java69
1 files changed, 37 insertions, 32 deletions
diff --git a/android/src/org/rockbox/RockboxPCM.java b/android/src/org/rockbox/RockboxPCM.java
index f2568d8406..631d925b12 100644
--- a/android/src/org/rockbox/RockboxPCM.java
+++ b/android/src/org/rockbox/RockboxPCM.java
@@ -29,10 +29,12 @@ import android.util.Log;
29public class RockboxPCM extends AudioTrack 29public class RockboxPCM extends AudioTrack
30{ 30{
31 byte[] raw_data; 31 byte[] raw_data;
32 private int buf_len;
33 private PCMListener l;
32 34
33 private void LOG(CharSequence text) 35 private void LOG(CharSequence text)
34 { 36 {
35 Log.d("RockboxBootloader", (String) text); 37 Log.d("Rockbox", (String) text);
36 } 38 }
37 39
38 public RockboxPCM() 40 public RockboxPCM()
@@ -44,18 +46,11 @@ public class RockboxPCM extends AudioTrack
44 AudioFormat.ENCODING_PCM_16BIT, 46 AudioFormat.ENCODING_PCM_16BIT,
45 24<<10, 47 24<<10,
46 AudioTrack.MODE_STREAM); 48 AudioTrack.MODE_STREAM);
47 int buf_len = 24<<10; 49 buf_len = 24<<10; /* in bytes */
48 50
49 raw_data = new byte[buf_len*2]; 51 raw_data = new byte[buf_len]; /* in shorts */
50 for(int i = 0; i < raw_data.length; i++) raw_data[i] = (byte) 0x00; 52 for(int i = 0; i < raw_data.length; i++) raw_data[i] = (byte)0;
51 /* fill with silence */ 53 l = new PCMListener(buf_len);
52 write(raw_data, 0, raw_data.length);
53 if (getState() == AudioTrack.STATE_INITIALIZED)
54 {
55 if (setNotificationMarkerPosition(bytes2frames(buf_len*2)/4) != AudioTrack.SUCCESS)
56 LOG("setNotificationMarkerPosition Error");
57 setPlaybackPositionUpdateListener(new PCMListener(buf_len*2));
58 }
59 } 54 }
60 55
61 int bytes2frames(int bytes) { 56 int bytes2frames(int bytes) {
@@ -70,28 +65,37 @@ public class RockboxPCM extends AudioTrack
70 65
71 @SuppressWarnings("unused") 66 @SuppressWarnings("unused")
72 private void play_pause(boolean pause) { 67 private void play_pause(boolean pause) {
73 LOG("play_pause()");
74 if (pause) 68 if (pause)
69 {
75 pause(); 70 pause();
71 }
76 else 72 else
77 { 73 {
78 if (getPlayState() == AudioTrack.PLAYSTATE_STOPPED) 74 if (getPlayState() == AudioTrack.PLAYSTATE_STOPPED)
79 { 75 {
80 for(int i = 0; i < raw_data.length; i++) raw_data[i] = (byte) 0x00;
81 LOG("Writing silence");
82 /* fill with silence */
83 write(raw_data, 0, raw_data.length);
84 RockboxService.startForeground(); 76 RockboxService.startForeground();
77 if (getState() == AudioTrack.STATE_INITIALIZED)
78 {
79 if (setNotificationMarkerPosition(bytes2frames(buf_len)/4) != AudioTrack.SUCCESS)
80 LOG("setNotificationMarkerPosition Error");
81 else
82 setPlaybackPositionUpdateListener(l);
83 }
84 /* need to fill with silence before starting playback */
85 write(raw_data, frames2bytes(getPlaybackHeadPosition()), raw_data.length);
85 } 86 }
86 play(); 87 play();
87 } 88 }
88 LOG("play_pause() return");
89 } 89 }
90 90
91 @Override 91 @Override
92 public void stop() throws IllegalStateException 92 public void stop() throws IllegalStateException
93 { 93 {
94 super.stop(); 94 try {
95 super.stop();
96 } catch (IllegalStateException e) {
97 throw new IllegalStateException(e);
98 }
95 RockboxService.stopForeground(); 99 RockboxService.stopForeground();
96 } 100 }
97 101
@@ -115,30 +119,31 @@ public class RockboxPCM extends AudioTrack
115 119
116 private class PCMListener implements OnPlaybackPositionUpdateListener { 120 private class PCMListener implements OnPlaybackPositionUpdateListener {
117 int max_len; 121 int max_len;
122 int refill_mark;
118 byte[] buf; 123 byte[] buf;
119 public PCMListener(int len) { 124 public PCMListener(int len) {
120 max_len = len; 125 max_len = len;
121 buf = new byte[len/2]; 126 /* refill to 100% when reached the 25% */
127 buf = new byte[max_len*3/4];
128 refill_mark = max_len - buf.length;
122 } 129 }
123 @Override 130 @Override
124 public void onMarkerReached(AudioTrack track) { 131 public void onMarkerReached(AudioTrack track) {
125 // push new data to the hardware 132 // push new data to the hardware
126 int result = 1; 133 RockboxPCM pcm = (RockboxPCM)track;
127 pcmSamplesToByteArray(buf); 134 int result = -1;
128 //LOG("Trying to write " + buf.length + " bytes"); 135 pcm.pcmSamplesToByteArray(buf);
129 result = track.write(buf, 0, buf.length); 136 result = track.write(buf, 0, buf.length);
130 if (result > 0) 137 if (result >= 0)
131 { 138 {
132 //LOG(result + " bytes written");
133 track.setPlaybackPositionUpdateListener(this);
134 track.setNotificationMarkerPosition(bytes2frames(max_len)/4);
135 switch(track.getPlayState()) 139 switch(track.getPlayState())
136 { 140 {
137 case AudioTrack.PLAYSTATE_PLAYING: 141 case AudioTrack.PLAYSTATE_PLAYING:
138 //LOG("State PLAYING");
139 break;
140 case AudioTrack.PLAYSTATE_PAUSED: 142 case AudioTrack.PLAYSTATE_PAUSED:
141 LOG("State PAUSED"); 143 /* recharge */
144 setPlaybackPositionUpdateListener(this);
145 /* refill at 25% no matter of how many bytes we've written */
146 setNotificationMarkerPosition(bytes2frames(refill_mark));
142 break; 147 break;
143 case AudioTrack.PLAYSTATE_STOPPED: 148 case AudioTrack.PLAYSTATE_STOPPED:
144 LOG("State STOPPED"); 149 LOG("State STOPPED");
@@ -147,8 +152,8 @@ public class RockboxPCM extends AudioTrack
147 } 152 }
148 else 153 else
149 { 154 {
150 LOG("Error in onMarkerReached"); 155 LOG("Error in onMarkerReached (result="+result+")");
151 track.stop(); 156 stop();
152 } 157 }
153 } 158 }
154 159