summaryrefslogtreecommitdiff
path: root/firmware/target/hosted
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2012-02-23 08:14:46 -0500
committerMichael Sevakis <jethead71@rockbox.org>2012-03-03 07:23:38 +0100
commit286a4c5caa1945c8d1cb365a3d90fb09d5700cb2 (patch)
tree4835f46d16ec78d035ec9f49333079fe618384c1 /firmware/target/hosted
parent3f82f3aca14eb954e55f761721ffdd2684f0e812 (diff)
downloadrockbox-286a4c5caa1945c8d1cb365a3d90fb09d5700cb2.tar.gz
rockbox-286a4c5caa1945c8d1cb365a3d90fb09d5700cb2.zip
Revise the PCM callback system after adding multichannel audio.
Additional status callback is added to pcm_play/rec_data instead of using a special function to set it. Status includes DMA error reporting to the status callback. Playback and recording callback become more alike except playback uses "const void **addr" (because the data should not be altered) and recording uses "void **addr". "const" is put in place throughout where appropriate. Most changes are fairly trivial. One that should be checked in particular because it isn't so much is telechips, if anyone cares to bother. PP5002 is not so trivial either but that tested as working. Change-Id: I4928d69b3b3be7fb93e259f81635232df9bd1df2 Reviewed-on: http://gerrit.rockbox.org/166 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
Diffstat (limited to 'firmware/target/hosted')
-rw-r--r--firmware/target/hosted/android/pcm-android.c16
-rw-r--r--firmware/target/hosted/maemo/pcm-gstreamer.c7
-rw-r--r--firmware/target/hosted/pcm-alsa.c8
-rw-r--r--firmware/target/hosted/sdl/pcm-sdl.c66
4 files changed, 49 insertions, 48 deletions
diff --git a/firmware/target/hosted/android/pcm-android.c b/firmware/target/hosted/android/pcm-android.c
index 4e58707d0a..7a0f28634e 100644
--- a/firmware/target/hosted/android/pcm-android.c
+++ b/firmware/target/hosted/android/pcm-android.c
@@ -80,8 +80,8 @@ Java_org_rockbox_RockboxPCM_nativeWrite(JNIEnv *env, jobject this,
80 80
81 if (!pcm_data_size) /* get some initial data */ 81 if (!pcm_data_size) /* get some initial data */
82 { 82 {
83 new_buffer = true; 83 new_buffer = pcm_play_dma_complete_callback(PCM_DMAST_OK,
84 pcm_play_get_more_callback((void**) &pcm_data_start, &pcm_data_size); 84 (const void**)&pcm_data_start, &pcm_data_size);
85 } 85 }
86 86
87 while(left > 0 && pcm_data_size) 87 while(left > 0 && pcm_data_size)
@@ -99,7 +99,7 @@ Java_org_rockbox_RockboxPCM_nativeWrite(JNIEnv *env, jobject this,
99 if (new_buffer) 99 if (new_buffer)
100 { 100 {
101 new_buffer = false; 101 new_buffer = false;
102 pcm_play_dma_started_callback(); 102 pcm_play_dma_status_callback(PCM_DMAST_STARTED);
103 103
104 /* NOTE: might need to release the mutex and sleep here if the 104 /* NOTE: might need to release the mutex and sleep here if the
105 buffer is shorter than the required buffer (like pcm-sdl.c) to 105 buffer is shorter than the required buffer (like pcm-sdl.c) to
@@ -114,15 +114,15 @@ Java_org_rockbox_RockboxPCM_nativeWrite(JNIEnv *env, jobject this,
114 114
115 if (pcm_data_size == 0) /* need new data */ 115 if (pcm_data_size == 0) /* need new data */
116 { 116 {
117 new_buffer = true; 117 new_buffer = pcm_play_dma_complete_callback(PCM_DMAST_OK,
118 pcm_play_get_more_callback((void**)&pcm_data_start, &pcm_data_size); 118 (const void**)&pcm_data_start, &pcm_data_size);
119 } 119 }
120 else /* increment data pointer and feed more */ 120 else /* increment data pointer and feed more */
121 pcm_data_start += transfer_size; 121 pcm_data_start += transfer_size;
122 } 122 }
123 123
124 if (new_buffer && pcm_data_size) 124 if (new_buffer)
125 pcm_play_dma_started_callback(); 125 pcm_play_dma_status_callback(PCM_DMAST_STARTED);
126 126
127 unlock_audio(); 127 unlock_audio();
128 return max_size - left; 128 return max_size - left;
@@ -154,7 +154,7 @@ void pcm_play_dma_start(const void *addr, size_t size)
154 154
155void pcm_play_dma_stop(void) 155void pcm_play_dma_stop(void)
156{ 156{
157 /* NOTE: due to how pcm_play_get_more_callback() works, this is 157 /* NOTE: due to how pcm_play_dma_complete_callback() works, this is
158 * possibly called from nativeWrite(), i.e. another (host) thread 158 * possibly called from nativeWrite(), i.e. another (host) thread
159 * => need to discover the appropriate JNIEnv* */ 159 * => need to discover the appropriate JNIEnv* */
160 JNIEnv* env = getJavaEnvironment(); 160 JNIEnv* env = getJavaEnvironment();
diff --git a/firmware/target/hosted/maemo/pcm-gstreamer.c b/firmware/target/hosted/maemo/pcm-gstreamer.c
index e5620d0702..61f33cbadd 100644
--- a/firmware/target/hosted/maemo/pcm-gstreamer.c
+++ b/firmware/target/hosted/maemo/pcm-gstreamer.c
@@ -189,9 +189,8 @@ static void feed_data(GstElement * appsrc, guint size_hint, void *unused)
189 from inside gstreamer's stream thread as it will deadlock */ 189 from inside gstreamer's stream thread as it will deadlock */
190 inside_feed_data = 1; 190 inside_feed_data = 1;
191 191
192 pcm_play_get_more_callback((void **)&pcm_data, &pcm_data_size); 192 if (pcm_play_dma_complete_callback(PCM_DMAST_OK, (const void **)&pcm_data,
193 193 &pcm_data_size))
194 if (pcm_data_size != 0)
195 { 194 {
196 GstBuffer *buffer = gst_buffer_new (); 195 GstBuffer *buffer = gst_buffer_new ();
197 GstFlowReturn ret; 196 GstFlowReturn ret;
@@ -205,7 +204,7 @@ static void feed_data(GstElement * appsrc, guint size_hint, void *unused)
205 if (ret != 0) 204 if (ret != 0)
206 DEBUGF("push-buffer error result: %d\n", ret); 205 DEBUGF("push-buffer error result: %d\n", ret);
207 206
208 pcm_play_dma_started_callback(); 207 pcm_play_dma_status_callback(PCM_DMAST_STARTED);
209 } else 208 } else
210 { 209 {
211 DEBUGF("feed_data: No Data.\n"); 210 DEBUGF("feed_data: No Data.\n");
diff --git a/firmware/target/hosted/pcm-alsa.c b/firmware/target/hosted/pcm-alsa.c
index b78993dd0a..1385f75b34 100644
--- a/firmware/target/hosted/pcm-alsa.c
+++ b/firmware/target/hosted/pcm-alsa.c
@@ -223,9 +223,11 @@ static bool fill_frames(void)
223 if (!pcm_size) 223 if (!pcm_size)
224 { 224 {
225 new_buffer = true; 225 new_buffer = true;
226 pcm_play_get_more_callback((void **)&pcm_data, &pcm_size); 226 if (!pcm_play_dma_complete_callback(PCM_DMAST_OK,
227 if (!pcm_size || !pcm_data) 227 (const void **)&pcm_data, &pcm_size))
228 {
228 return false; 229 return false;
230 }
229 } 231 }
230 copy_n = MIN((ssize_t)pcm_size, frames_left*4); 232 copy_n = MIN((ssize_t)pcm_size, frames_left*4);
231 memcpy(&frames[2*(period_size-frames_left)], pcm_data, copy_n); 233 memcpy(&frames[2*(period_size-frames_left)], pcm_data, copy_n);
@@ -237,7 +239,7 @@ static bool fill_frames(void)
237 if (new_buffer) 239 if (new_buffer)
238 { 240 {
239 new_buffer = false; 241 new_buffer = false;
240 pcm_play_dma_started_callback(); 242 pcm_play_dma_status_callback(PCM_DMAST_STARTED);
241 } 243 }
242 } 244 }
243 return true; 245 return true;
diff --git a/firmware/target/hosted/sdl/pcm-sdl.c b/firmware/target/hosted/sdl/pcm-sdl.c
index 020928d572..2c535b2dc5 100644
--- a/firmware/target/hosted/sdl/pcm-sdl.c
+++ b/firmware/target/hosted/sdl/pcm-sdl.c
@@ -56,7 +56,7 @@ static int sim_volume = 0;
56#if CONFIG_CODEC == SWCODEC 56#if CONFIG_CODEC == SWCODEC
57static int cvt_status = -1; 57static int cvt_status = -1;
58 58
59static Uint8* pcm_data; 59static const Uint8* pcm_data;
60static size_t pcm_data_size; 60static size_t pcm_data_size;
61static size_t pcm_sample_bytes; 61static size_t pcm_sample_bytes;
62static size_t pcm_channel_bytes; 62static size_t pcm_channel_bytes;
@@ -109,7 +109,7 @@ void pcm_play_dma_start(const void *addr, size_t size)
109{ 109{
110 pcm_dma_apply_settings_nolock(); 110 pcm_dma_apply_settings_nolock();
111 111
112 pcm_data = (Uint8 *) addr; 112 pcm_data = addr;
113 pcm_data_size = size; 113 pcm_data_size = size;
114 114
115 SDL_PauseAudio(0); 115 SDL_PauseAudio(0);
@@ -245,48 +245,48 @@ static void sdl_audio_callback(struct pcm_udata *udata, Uint8 *stream, int len)
245 245
246 /* Audio card wants more? Get some more then. */ 246 /* Audio card wants more? Get some more then. */
247 while (len > 0) { 247 while (len > 0) {
248 new_buffer = true; 248 new_buffer = pcm_play_dma_complete_callback(PCM_DMAST_OK,
249 pcm_play_get_more_callback((void **)&pcm_data, &pcm_data_size); 249 (const void **)&pcm_data, &pcm_data_size);
250
251 if (!new_buffer) {
252 DEBUGF("sdl_audio_callback: No Data.\n");
253 break;
254 }
255
250 start: 256 start:
251 if (pcm_data_size != 0) { 257 udata->num_in = pcm_data_size / pcm_sample_bytes;
252 udata->num_in = pcm_data_size / pcm_sample_bytes; 258 udata->num_out = len / pcm_sample_bytes;
253 udata->num_out = len / pcm_sample_bytes;
254 259
255 write_to_soundcard(udata); 260 write_to_soundcard(udata);
256 261
257 udata->num_in *= pcm_sample_bytes; 262 udata->num_in *= pcm_sample_bytes;
258 udata->num_out *= pcm_sample_bytes; 263 udata->num_out *= pcm_sample_bytes;
259 264
265 if (new_buffer)
266 {
267 new_buffer = false;
268 pcm_play_dma_status_callback(PCM_DMAST_STARTED);
260 269
261 if (new_buffer) 270 if ((size_t)len > udata->num_out)
262 { 271 {
263 new_buffer = false; 272 int delay = pcm_data_size*250 / pcm_sampr - 1;
264 pcm_play_dma_started_callback();
265 273
266 if ((size_t)len > udata->num_out) 274 if (delay > 0)
267 { 275 {
268 int delay = pcm_data_size*250 / pcm_sampr - 1; 276 SDL_UnlockMutex(audio_lock);
269 277 SDL_Delay(delay);
270 if (delay > 0) 278 SDL_LockMutex(audio_lock);
271 { 279
272 SDL_UnlockMutex(audio_lock); 280 if (!pcm_is_playing())
273 SDL_Delay(delay); 281 break;
274 SDL_LockMutex(audio_lock);
275
276 if (!pcm_is_playing())
277 break;
278 }
279 } 282 }
280 } 283 }
281
282 pcm_data += udata->num_in;
283 pcm_data_size -= udata->num_in;
284 udata->stream += udata->num_out;
285 len -= udata->num_out;
286 } else {
287 DEBUGF("sdl_audio_callback: No Data.\n");
288 break;
289 } 284 }
285
286 pcm_data += udata->num_in;
287 pcm_data_size -= udata->num_in;
288 udata->stream += udata->num_out;
289 len -= udata->num_out;
290 } 290 }
291 291
292 SDL_UnlockMutex(audio_lock); 292 SDL_UnlockMutex(audio_lock);