Thank you to anyone who has already donated - your generous donations helped make three months of treatment possible.
My brother Nate continues to fight stage IV Hodgkin's lymphoma. He's just 31, with a wife and baby girl. They have no active income (since he's been unable to return to work), no insurance, and cannot afford the treatment he needs. Nate and his family need your help. Please consider a donation, every dollar helps. Thanks.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
android/src/org/rockbox/RockboxPCM.java | 18 +++------ firmware/target/hosted/android/pcm-android.c | 56 ++++++++----------------- 2 files changed, 24 insertions(+), 50 deletions(-) diff --git a/android/src/org/rockbox/RockboxPCM.java b/android/src/org/rockbox/RockboxPCM.java index 146e639..1a123df 100644 public class RockboxPCM extends AudioTrack AudioFormat.CHANNEL_CONFIGURATION_STEREO; private static final int encoding = AudioFormat.ENCODING_PCM_16BIT; - /* 24k is plenty, but some devices may have a higher minimum */ + /* 48k is plenty, but some devices may have a higher minimum */ private static final int buf_len = - Math.max(24<<10, getMinBufferSize(samplerate, channels, encoding)); + Math.max(48<<10, getMinBufferSize(samplerate, channels, encoding)); private void LOG(CharSequence text) { public class RockboxPCM extends AudioTrack Process.THREAD_PRIORITY_URGENT_AUDIO); ht.start(); raw_data = new byte[buf_len]; /* in shorts */ - Arrays.fill(raw_data, (byte) 0); l = new PCMListener(buf_len); } public class RockboxPCM extends AudioTrack setPlaybackPositionUpdateListener(l, h); } /* need to fill with silence before starting playback */ + Arrays.fill(raw_data, (byte) 0); write(raw_data, frames2bytes(getPlaybackHeadPosition()), raw_data.length); } public class RockboxPCM extends AudioTrack setStereoVolume(fvolume, fvolume); } - public native void pcmSamplesToByteArray(byte[] dest); + public native int pcmSamplesToByteArray(); private class PCMListener implements OnPlaybackPositionUpdateListener { - private int max_len; private int refill_mark; - private byte[] buf; public PCMListener(int len) { - max_len = len; /* refill to 100% when reached the 25% */ - buf = new byte[max_len*3/4]; - refill_mark = max_len - buf.length; + refill_mark = len * 3/4; } public void onMarkerReached(AudioTrack track) { /* push new data to the hardware */ RockboxPCM pcm = (RockboxPCM)track; - int result = -1; - pcm.pcmSamplesToByteArray(buf); - result = track.write(buf, 0, buf.length); + int result = pcm.pcmSamplesToByteArray(); if (result >= 0) { switch(track.getPlayState()) diff --git a/firmware/target/hosted/android/pcm-android.c b/firmware/target/hosted/android/pcm-android.c index c8bc410..2cd7714 100644 static char *pcm_data_start; /* cache frequently called methods */ static jmethodID play_pause_method; static jmethodID stop_method; +static jmethodID write_method; static jmethodID set_volume_method; static jclass RockboxPCM_class; static jobject RockboxPCM_instance; static jobject RockboxPCM_instance; * * it is called from the PositionMarker callback of AudioTrack **/ -JNIEXPORT void JNICALL + +JNIEXPORT jint JNICALL Java_org_rockbox_RockboxPCM_pcmSamplesToByteArray(JNIEnv *env, - jobject this, - jbyteArray arr) + jobject this) { (void)this; - size_t len; - size_t array_size = (*env)->GetArrayLength(env, arr); - if (array_size > pcm_data_size) - len = pcm_data_size; - else - len = array_size; - - (*env)->SetByteArrayRegion(env, arr, 0, len, pcm_data_start); - - if (array_size > pcm_data_size) - { /* didn't have enough data for the array ? */ - size_t remaining = array_size - pcm_data_size; - size_t offset = len; - retry: + if (pcm_data_size == 0) pcm_play_get_more_callback((void**)&pcm_data_start, &pcm_data_size); - if (pcm_data_size == 0) - { - DEBUGF("out of data\n"); - return; - } - if (remaining > pcm_data_size) - { /* got too little data, get more ... */ - (*env)->SetByteArrayRegion(env, arr, offset, pcm_data_size, pcm_data_start); - /* advance in the java array by the amount we copied */ - offset += pcm_data_size; - /* we copied at least a bit */ - remaining -= pcm_data_size; - pcm_data_size = 0; - /* let's get another buch of data and try again */ - goto retry; - } - else - (*env)->SetByteArrayRegion(env, arr, offset, remaining, pcm_data_start); - len = remaining; + + if (pcm_data_size != 0) + { + jint result; + jbyteArray buf = (*env)->NewByteArray(env, (jsize)pcm_data_size); + (*env)->SetByteArrayRegion(env, buf, 0, (jsize)pcm_data_size, pcm_data_start); + result = (*env)->CallIntMethod(env, RockboxPCM_instance, write_method, + buf, 0, pcm_data_size); + pcm_data_size = 0; + return result; } - pcm_data_start += len; - pcm_data_size -= len; + + return -1; } void pcm_play_lock(void) void pcm_play_dma_init(void) play_pause_method = e->GetMethodID(env_ptr, RockboxPCM_class, "play_pause", "(Z)V"); set_volume_method = e->GetMethodID(env_ptr, RockboxPCM_class, "set_volume", "(I)V"); stop_method = e->GetMethodID(env_ptr, RockboxPCM_class, "stop", "()V"); + write_method = e->GetMethodID(env_ptr, RockboxPCM_class, "write", "([BII)I"); /* get initial pcm data, if any */ pcm_play_get_more_callback((void*)&pcm_data_start, &pcm_data_size); } |