diff options
-rw-r--r-- | apps/playback.c | 149 | ||||
-rw-r--r-- | apps/playlist_viewer.c | 2 | ||||
-rw-r--r-- | apps/plugin.c | 16 | ||||
-rw-r--r-- | apps/plugin.h | 33 | ||||
-rw-r--r-- | apps/plugins/doom/rockdoom.c | 19 | ||||
-rw-r--r-- | apps/plugins/midiplay.c | 15 | ||||
-rw-r--r-- | apps/plugins/mp3_encoder.c | 14 | ||||
-rw-r--r-- | apps/plugins/mpegplayer/mpegplayer.c | 14 | ||||
-rw-r--r-- | apps/plugins/pacbox/pacbox.c | 22 | ||||
-rw-r--r-- | apps/plugins/rockboy/rockboy.c | 16 | ||||
-rw-r--r-- | apps/plugins/zxbox/zxbox.c | 17 | ||||
-rw-r--r-- | apps/talk.c | 2 | ||||
-rw-r--r-- | apps/talk.h | 2 | ||||
-rw-r--r-- | firmware/export/audio.h | 5 | ||||
-rw-r--r-- | firmware/export/config.h | 3 |
15 files changed, 204 insertions, 125 deletions
diff --git a/apps/playback.c b/apps/playback.c index 279fb15482..9bf6942e7f 100644 --- a/apps/playback.c +++ b/apps/playback.c | |||
@@ -296,8 +296,8 @@ static unsigned char sim_iram[CODEC_IRAM_SIZE]; /* IRAM codec swap buffer for si | |||
296 | #define CODEC_IRAM_ORIGIN sim_iram | 296 | #define CODEC_IRAM_ORIGIN sim_iram |
297 | #endif | 297 | #endif |
298 | 298 | ||
299 | static unsigned char *iram_buf[2]; /* Ptr to IRAM buffers for normal/voice codecs */ | 299 | static unsigned char *iram_buf[2] = { NULL, NULL }; /* Ptr to IRAM buffers for normal/voice codecs */ |
300 | static unsigned char *dram_buf[2]; /* Ptr to DRAM buffers for normal/voice codecs */ | 300 | static unsigned char *dram_buf[2] = { NULL, NULL }; /* Ptr to DRAM buffers for normal/voice codecs */ |
301 | static struct mutex mutex_codecthread; /* Mutex to control which codec (normal/voice) is running */ | 301 | static struct mutex mutex_codecthread; /* Mutex to control which codec (normal/voice) is running */ |
302 | 302 | ||
303 | /* Voice state */ | 303 | /* Voice state */ |
@@ -307,6 +307,10 @@ static volatile bool voice_codec_loaded; /* Is voice codec loaded (V/A-) */ | |||
307 | static char *voicebuf; | 307 | static char *voicebuf; |
308 | static size_t voice_remaining; | 308 | static size_t voice_remaining; |
309 | 309 | ||
310 | #ifdef IRAM_STEAL | ||
311 | static bool voice_iram_stolen = false; /* Voice IRAM has been stolen for other use */ | ||
312 | #endif | ||
313 | |||
310 | static void (*voice_getmore)(unsigned char** start, int* size); | 314 | static void (*voice_getmore)(unsigned char** start, int* size); |
311 | 315 | ||
312 | struct voice_info { | 316 | struct voice_info { |
@@ -318,15 +322,21 @@ static void voice_thread(void); | |||
318 | 322 | ||
319 | #endif /* PLAYBACK_VOICE */ | 323 | #endif /* PLAYBACK_VOICE */ |
320 | 324 | ||
325 | /* --- Shared semi-private interfaces --- */ | ||
326 | |||
327 | /* imported */ | ||
328 | extern void talk_buffer_steal(void); | ||
329 | #ifdef HAVE_RECORDING | ||
330 | extern void pcm_rec_error_clear(void); | ||
331 | extern unsigned long pcm_rec_status(void); | ||
332 | #endif | ||
333 | |||
334 | |||
321 | /* --- External interfaces --- */ | 335 | /* --- External interfaces --- */ |
322 | 336 | ||
323 | void mp3_play_data(const unsigned char* start, int size, | 337 | void mp3_play_data(const unsigned char* start, int size, |
324 | void (*get_more)(unsigned char** start, int* size)) | 338 | void (*get_more)(unsigned char** start, int* size)) |
325 | { | 339 | { |
326 | /* must reset the buffer before any playback begins if needed */ | ||
327 | if (buffer_state == BUFFER_STATE_TRASHED) | ||
328 | audio_reset_buffer(pcmbuf_get_bufsize()); | ||
329 | |||
330 | #ifdef PLAYBACK_VOICE | 340 | #ifdef PLAYBACK_VOICE |
331 | static struct voice_info voice_clip; | 341 | static struct voice_info voice_clip; |
332 | voice_clip.callback = get_more; | 342 | voice_clip.callback = get_more; |
@@ -366,11 +376,20 @@ void mpeg_id3_options(bool _v1first) | |||
366 | 376 | ||
367 | unsigned char *audio_get_buffer(bool talk_buf, size_t *buffer_size) | 377 | unsigned char *audio_get_buffer(bool talk_buf, size_t *buffer_size) |
368 | { | 378 | { |
369 | unsigned char *buf = audiobuf; | 379 | unsigned char *buf, *end; |
370 | unsigned char *end = audiobufend; | ||
371 | 380 | ||
372 | audio_stop(); | 381 | audio_stop(); |
373 | 382 | ||
383 | if (buffer_size == NULL) | ||
384 | { | ||
385 | /* Special case for talk_init to use */ | ||
386 | buffer_state = BUFFER_STATE_TRASHED; | ||
387 | return NULL; | ||
388 | } | ||
389 | |||
390 | buf = audiobuf; | ||
391 | end = audiobufend; | ||
392 | |||
374 | if (talk_buf || !talk_voice_required() | 393 | if (talk_buf || !talk_voice_required() |
375 | || buffer_state == BUFFER_STATE_TRASHED) | 394 | || buffer_state == BUFFER_STATE_TRASHED) |
376 | { | 395 | { |
@@ -395,17 +414,57 @@ unsigned char *audio_get_buffer(bool talk_buf, size_t *buffer_size) | |||
395 | return buf; | 414 | return buf; |
396 | } | 415 | } |
397 | 416 | ||
417 | #ifdef IRAM_STEAL | ||
418 | void audio_iram_steal(void) | ||
419 | { | ||
420 | /* We need to stop audio playback in order to use codec IRAM */ | ||
421 | audio_stop(); | ||
422 | |||
423 | #ifdef PLAYBACK_VOICE | ||
424 | if (NULL != iram_buf[CODEC_IDX_VOICE]) | ||
425 | { | ||
426 | /* Wait for voice to swap back in if current codec was audio */ | ||
427 | while (current_codec != CODEC_IDX_VOICE) | ||
428 | yield(); | ||
429 | |||
430 | voice_stop(); | ||
431 | |||
432 | /* Save voice IRAM - safe to do here since state is known */ | ||
433 | memcpy(iram_buf[CODEC_IDX_VOICE], (void *)CODEC_IRAM_ORIGIN, | ||
434 | CODEC_IRAM_SIZE); | ||
435 | voice_iram_stolen = true; | ||
436 | } | ||
437 | else | ||
438 | { | ||
439 | /* Nothing much to do if no voice */ | ||
440 | voice_iram_stolen = false; | ||
441 | } | ||
442 | #endif | ||
443 | } | ||
444 | #endif /* IRAM_STEAL */ | ||
445 | |||
398 | #ifdef HAVE_RECORDING | 446 | #ifdef HAVE_RECORDING |
399 | unsigned char *audio_get_recording_buffer(size_t *buffer_size) | 447 | unsigned char *audio_get_recording_buffer(size_t *buffer_size) |
400 | { | 448 | { |
401 | /* don't allow overwrite of voice swap area or we'll trash the | 449 | /* don't allow overwrite of voice swap area or we'll trash the |
402 | swapped-out voice codec but can use whole thing if none */ | 450 | swapped-out voice codec but can use whole thing if none */ |
403 | unsigned char *end = iram_buf[CODEC_IDX_VOICE] ? | 451 | unsigned char *end; |
404 | iram_buf[CODEC_IDX_VOICE] : audiobufend; | ||
405 | 452 | ||
406 | audio_stop(); | 453 | audio_stop(); |
407 | talk_buffer_steal(); | 454 | talk_buffer_steal(); |
408 | 455 | ||
456 | #ifdef PLAYBACK_VOICE | ||
457 | #ifdef IRAM_STEAL | ||
458 | end = dram_buf[CODEC_IDX_VOICE] ? | ||
459 | dram_buf[CODEC_IDX_VOICE] : audiobufend; | ||
460 | #else | ||
461 | end = iram_buf[CODEC_IDX_VOICE] ? | ||
462 | iram_buf[CODEC_IDX_VOICE] : audiobufend; | ||
463 | #endif /* IRAM_STEAL */ | ||
464 | #else | ||
465 | end = audiobufend; | ||
466 | #endif /* PLAYBACK_VOICE */ | ||
467 | |||
409 | buffer_state = BUFFER_STATE_TRASHED; | 468 | buffer_state = BUFFER_STATE_TRASHED; |
410 | 469 | ||
411 | *buffer_size = end - audiobuf; | 470 | *buffer_size = end - audiobuf; |
@@ -645,7 +704,6 @@ void audio_flush_and_reload_tracks(void) | |||
645 | void audio_error_clear(void) | 704 | void audio_error_clear(void) |
646 | { | 705 | { |
647 | #ifdef AUDIO_HAVE_RECORDING | 706 | #ifdef AUDIO_HAVE_RECORDING |
648 | extern void pcm_rec_error_clear(void); | ||
649 | pcm_rec_error_clear(); | 707 | pcm_rec_error_clear(); |
650 | #endif | 708 | #endif |
651 | } | 709 | } |
@@ -662,7 +720,6 @@ int audio_status(void) | |||
662 | 720 | ||
663 | #ifdef HAVE_RECORDING | 721 | #ifdef HAVE_RECORDING |
664 | /* Do this here for constitency with mpeg.c version */ | 722 | /* Do this here for constitency with mpeg.c version */ |
665 | extern unsigned long pcm_rec_status(void); | ||
666 | ret |= pcm_rec_status(); | 723 | ret |= pcm_rec_status(); |
667 | #endif | 724 | #endif |
668 | 725 | ||
@@ -820,7 +877,6 @@ void voice_stop(void) | |||
820 | 877 | ||
821 | 878 | ||
822 | /* --- Routines called from multiple threads --- */ | 879 | /* --- Routines called from multiple threads --- */ |
823 | |||
824 | #ifdef PLAYBACK_VOICE | 880 | #ifdef PLAYBACK_VOICE |
825 | static void swap_codec(void) | 881 | static void swap_codec(void) |
826 | { | 882 | { |
@@ -829,8 +885,26 @@ static void swap_codec(void) | |||
829 | logf("swapping out codec:%d", my_codec); | 885 | logf("swapping out codec:%d", my_codec); |
830 | 886 | ||
831 | /* Save our current IRAM and DRAM */ | 887 | /* Save our current IRAM and DRAM */ |
888 | #ifdef IRAM_STEAL | ||
889 | if (voice_iram_stolen) | ||
890 | { | ||
891 | logf("swap: iram restore"); | ||
892 | voice_iram_stolen = false; | ||
893 | /* Don't swap trashed data into buffer - _should_ always be the case | ||
894 | if voice_iram_stolen is true since the voice has been swapped in | ||
895 | before hand */ | ||
896 | if (my_codec == CODEC_IDX_VOICE) | ||
897 | goto skip_iram_swap; | ||
898 | } | ||
899 | #endif | ||
900 | |||
832 | memcpy(iram_buf[my_codec], (unsigned char *)CODEC_IRAM_ORIGIN, | 901 | memcpy(iram_buf[my_codec], (unsigned char *)CODEC_IRAM_ORIGIN, |
833 | CODEC_IRAM_SIZE); | 902 | CODEC_IRAM_SIZE); |
903 | |||
904 | #ifdef IRAM_STEAL | ||
905 | skip_iram_swap: | ||
906 | #endif | ||
907 | |||
834 | memcpy(dram_buf[my_codec], codecbuf, CODEC_SIZE); | 908 | memcpy(dram_buf[my_codec], codecbuf, CODEC_SIZE); |
835 | 909 | ||
836 | /* Release my semaphore */ | 910 | /* Release my semaphore */ |
@@ -1085,6 +1159,21 @@ static void* voice_request_buffer_callback(size_t *realsize, size_t reqsize) | |||
1085 | { | 1159 | { |
1086 | /* Set up new voice data */ | 1160 | /* Set up new voice data */ |
1087 | struct voice_info *voice_data; | 1161 | struct voice_info *voice_data; |
1162 | #ifdef IRAM_STEAL | ||
1163 | if (voice_iram_stolen) | ||
1164 | { | ||
1165 | logf("voice: iram restore"); | ||
1166 | memcpy((void*)CODEC_IRAM_ORIGIN, | ||
1167 | iram_buf[CODEC_IDX_VOICE], | ||
1168 | CODEC_IRAM_SIZE); | ||
1169 | voice_iram_stolen = false; | ||
1170 | } | ||
1171 | #endif | ||
1172 | /* must reset the buffer before any playback | ||
1173 | begins if needed */ | ||
1174 | if (buffer_state == BUFFER_STATE_TRASHED) | ||
1175 | audio_reset_buffer(pcmbuf_get_bufsize()); | ||
1176 | |||
1088 | voice_is_playing = true; | 1177 | voice_is_playing = true; |
1089 | trigger_cpu_boost(); | 1178 | trigger_cpu_boost(); |
1090 | voice_data = ev.data; | 1179 | voice_data = ev.data; |
@@ -2809,6 +2898,10 @@ static void audio_fill_file_buffer( | |||
2809 | bool had_next_track = audio_next_track() != NULL; | 2898 | bool had_next_track = audio_next_track() != NULL; |
2810 | bool continue_buffering; | 2899 | bool continue_buffering; |
2811 | 2900 | ||
2901 | /* must reset the buffer before use if trashed */ | ||
2902 | if (buffer_state != BUFFER_STATE_NORMAL) | ||
2903 | audio_reset_buffer(pcmbuf_get_bufsize()); | ||
2904 | |||
2812 | if (!audio_initialize_buffer_fill(!start_play)) | 2905 | if (!audio_initialize_buffer_fill(!start_play)) |
2813 | return ; | 2906 | return ; |
2814 | 2907 | ||
@@ -3156,10 +3249,6 @@ static void audio_play_start(size_t offset) | |||
3156 | /* Wait for any previously playing audio to flush - TODO: Not necessary? */ | 3249 | /* Wait for any previously playing audio to flush - TODO: Not necessary? */ |
3157 | audio_stop_codec_flush(); | 3250 | audio_stop_codec_flush(); |
3158 | 3251 | ||
3159 | /* must reset the buffer before any playback begins if needed */ | ||
3160 | if (buffer_state != BUFFER_STATE_NORMAL) | ||
3161 | audio_reset_buffer(pcmbuf_get_bufsize()); | ||
3162 | |||
3163 | track_changed = true; | 3252 | track_changed = true; |
3164 | playlist_end = false; | 3253 | playlist_end = false; |
3165 | 3254 | ||
@@ -3272,14 +3361,34 @@ static void audio_reset_buffer(size_t pcmbufsize) | |||
3272 | if (talk_voice_required()) | 3361 | if (talk_voice_required()) |
3273 | { | 3362 | { |
3274 | #ifdef PLAYBACK_VOICE | 3363 | #ifdef PLAYBACK_VOICE |
3364 | #ifdef IRAM_STEAL | ||
3365 | filebuflen -= CODEC_IRAM_SIZE + 2*CODEC_SIZE; | ||
3366 | #else | ||
3367 | filebuflen -= 2*(CODEC_IRAM_SIZE + CODEC_SIZE); | ||
3368 | #endif | ||
3275 | /* Allow 2 codecs at end of audio buffer */ | 3369 | /* Allow 2 codecs at end of audio buffer */ |
3276 | filebuflen -= 2 * (CODEC_IRAM_SIZE + CODEC_SIZE); | 3370 | /* If using IRAM for plugins voice IRAM swap buffer must be dedicated |
3277 | 3371 | and out of the way of buffer usage or else a call to audio_get_buffer | |
3372 | and subsequent buffer use might trash the swap space. A plugin | ||
3373 | initializing IRAM after getting the full buffer would present similar | ||
3374 | problem. Options include: failing the request if the other buffer | ||
3375 | has been obtained already or never allowing use of the voice IRAM | ||
3376 | buffer within the audio buffer. Using buffer_alloc basically | ||
3377 | implements the second in a more convenient way. */ | ||
3278 | iram_buf[CODEC_IDX_AUDIO] = filebuf + filebuflen; | 3378 | iram_buf[CODEC_IDX_AUDIO] = filebuf + filebuflen; |
3279 | dram_buf[CODEC_IDX_AUDIO] = iram_buf[CODEC_IDX_AUDIO] + CODEC_IRAM_SIZE; | 3379 | dram_buf[CODEC_IDX_AUDIO] = iram_buf[CODEC_IDX_AUDIO] + CODEC_IRAM_SIZE; |
3380 | |||
3381 | #ifdef IRAM_STEAL | ||
3382 | /* Allocate voice IRAM swap buffer once */ | ||
3383 | if (iram_buf[CODEC_IDX_VOICE] == NULL) | ||
3384 | iram_buf[CODEC_IDX_VOICE] = buffer_alloc(CODEC_IRAM_SIZE); | ||
3385 | dram_buf[CODEC_IDX_VOICE] = dram_buf[CODEC_IDX_AUDIO] + CODEC_SIZE; | ||
3386 | #else | ||
3280 | iram_buf[CODEC_IDX_VOICE] = dram_buf[CODEC_IDX_AUDIO] + CODEC_SIZE; | 3387 | iram_buf[CODEC_IDX_VOICE] = dram_buf[CODEC_IDX_AUDIO] + CODEC_SIZE; |
3281 | dram_buf[CODEC_IDX_VOICE] = iram_buf[CODEC_IDX_VOICE] + CODEC_IRAM_SIZE; | 3388 | dram_buf[CODEC_IDX_VOICE] = iram_buf[CODEC_IDX_VOICE] + CODEC_IRAM_SIZE; |
3282 | #endif | 3389 | #endif /* IRAM_STEAL */ |
3390 | |||
3391 | #endif /* PLAYBACK_VOICE */ | ||
3283 | } | 3392 | } |
3284 | else | 3393 | else |
3285 | { | 3394 | { |
diff --git a/apps/playlist_viewer.c b/apps/playlist_viewer.c index 87bbaa4b11..8670f0ad46 100644 --- a/apps/playlist_viewer.c +++ b/apps/playlist_viewer.c | |||
@@ -467,7 +467,9 @@ static int onplay_menu(int index) | |||
467 | if (current_track->display_index!=viewer.num_tracks || | 467 | if (current_track->display_index!=viewer.num_tracks || |
468 | global_settings.repeat_mode == REPEAT_ALL) | 468 | global_settings.repeat_mode == REPEAT_ALL) |
469 | { | 469 | { |
470 | #if CONFIG_CODEC != SWCODEC | ||
470 | talk_buffer_steal(); /* will use the mp3 buffer */ | 471 | talk_buffer_steal(); /* will use the mp3 buffer */ |
472 | #endif | ||
471 | audio_play(0); | 473 | audio_play(0); |
472 | viewer.current_playing_track = -1; | 474 | viewer.current_playing_track = -1; |
473 | } | 475 | } |
diff --git a/apps/plugin.c b/apps/plugin.c index 90b3837cf8..a00a54e4ec 100644 --- a/apps/plugin.c +++ b/apps/plugin.c | |||
@@ -471,6 +471,9 @@ static const struct plugin_api rockbox_api = { | |||
471 | lcd_set_backdrop, | 471 | lcd_set_backdrop, |
472 | #endif | 472 | #endif |
473 | 473 | ||
474 | #ifdef IRAM_STEAL | ||
475 | plugin_iram_init, | ||
476 | #endif | ||
474 | }; | 477 | }; |
475 | 478 | ||
476 | int plugin_load(const char* plugin, void* parameter) | 479 | int plugin_load(const char* plugin, void* parameter) |
@@ -683,9 +686,20 @@ void* plugin_get_audio_buffer(int* buffer_size) | |||
683 | audio_stop(); | 686 | audio_stop(); |
684 | talk_buffer_steal(); /* we use the mp3 buffer, need to tell */ | 687 | talk_buffer_steal(); /* we use the mp3 buffer, need to tell */ |
685 | *buffer_size = audiobufend - audiobuf; | 688 | *buffer_size = audiobufend - audiobuf; |
686 | #endif | ||
687 | return audiobuf; | 689 | return audiobuf; |
690 | #endif | ||
691 | } | ||
692 | |||
693 | #ifdef IRAM_STEAL | ||
694 | /* Initializes plugin IRAM */ | ||
695 | void plugin_iram_init(char *iramstart, char *iramcopy, size_t iram_size, | ||
696 | char *iedata, size_t iedata_size) | ||
697 | { | ||
698 | audio_iram_steal(); | ||
699 | memcpy(iramstart, iramcopy, iram_size); | ||
700 | memset(iedata, 0, iedata_size); | ||
688 | } | 701 | } |
702 | #endif /* IRAM_STEAL */ | ||
689 | 703 | ||
690 | /* The plugin wants to stay resident after leaving its main function, e.g. | 704 | /* The plugin wants to stay resident after leaving its main function, e.g. |
691 | runs from timer or own thread. The callback is registered to later | 705 | runs from timer or own thread. The callback is registered to later |
diff --git a/apps/plugin.h b/apps/plugin.h index e9a6cfdaed..608009d549 100644 --- a/apps/plugin.h +++ b/apps/plugin.h | |||
@@ -107,7 +107,7 @@ | |||
107 | #define PLUGIN_MAGIC 0x526F634B /* RocK */ | 107 | #define PLUGIN_MAGIC 0x526F634B /* RocK */ |
108 | 108 | ||
109 | /* increase this every time the api struct changes */ | 109 | /* increase this every time the api struct changes */ |
110 | #define PLUGIN_API_VERSION 35 | 110 | #define PLUGIN_API_VERSION 36 |
111 | 111 | ||
112 | /* update this to latest version if a change to the api struct breaks | 112 | /* update this to latest version if a change to the api struct breaks |
113 | backwards compatibility (and please take the opportunity to sort in any | 113 | backwards compatibility (and please take the opportunity to sort in any |
@@ -582,6 +582,11 @@ struct plugin_api { | |||
582 | #if LCD_DEPTH > 1 | 582 | #if LCD_DEPTH > 1 |
583 | void (*lcd_set_backdrop)(fb_data* backdrop); | 583 | void (*lcd_set_backdrop)(fb_data* backdrop); |
584 | #endif | 584 | #endif |
585 | |||
586 | #ifdef IRAM_STEAL | ||
587 | void (*plugin_iram_init)(char *iramstart, char *iramcopy, size_t iram_size, | ||
588 | char *iedata, size_t iedata_size); | ||
589 | #endif | ||
585 | }; | 590 | }; |
586 | 591 | ||
587 | /* plugin header */ | 592 | /* plugin header */ |
@@ -593,6 +598,7 @@ struct plugin_header { | |||
593 | unsigned char *end_addr; | 598 | unsigned char *end_addr; |
594 | enum plugin_status(*entry_point)(struct plugin_api*, void*); | 599 | enum plugin_status(*entry_point)(struct plugin_api*, void*); |
595 | }; | 600 | }; |
601 | |||
596 | #ifdef PLUGIN | 602 | #ifdef PLUGIN |
597 | #ifndef SIMULATOR | 603 | #ifndef SIMULATOR |
598 | extern unsigned char plugin_start_addr[]; | 604 | extern unsigned char plugin_start_addr[]; |
@@ -607,12 +613,33 @@ extern unsigned char plugin_end_addr[]; | |||
607 | const struct plugin_header __header = { \ | 613 | const struct plugin_header __header = { \ |
608 | PLUGIN_MAGIC, TARGET_ID, PLUGIN_API_VERSION, \ | 614 | PLUGIN_MAGIC, TARGET_ID, PLUGIN_API_VERSION, \ |
609 | NULL, NULL, plugin_start }; | 615 | NULL, NULL, plugin_start }; |
610 | #endif | 616 | #endif /* SIMULATOR */ |
611 | #endif | 617 | |
618 | #ifdef USE_IRAM | ||
619 | /* Declare IRAM variables */ | ||
620 | #define PLUGIN_IRAM_DECLARE \ | ||
621 | extern char iramcopy[]; \ | ||
622 | extern char iramstart[]; \ | ||
623 | extern char iramend[]; \ | ||
624 | extern char iedata[]; \ | ||
625 | extern char iend[]; | ||
626 | /* Initialize IRAM */ | ||
627 | #define PLUGIN_IRAM_INIT(api) \ | ||
628 | (api)->plugin_iram_init(iramstart, iramcopy, iramend-iramstart, \ | ||
629 | iedata, iend-iedata); | ||
630 | #else | ||
631 | #define PLUGIN_IRAM_DECLARE | ||
632 | #define PLUGIN_IRAM_INIT(api) | ||
633 | #endif /* USE_IRAM */ | ||
634 | #endif /* PLUGIN */ | ||
612 | 635 | ||
613 | int plugin_load(const char* plugin, void* parameter); | 636 | int plugin_load(const char* plugin, void* parameter); |
614 | void* plugin_get_buffer(int *buffer_size); | 637 | void* plugin_get_buffer(int *buffer_size); |
615 | void* plugin_get_audio_buffer(int *buffer_size); | 638 | void* plugin_get_audio_buffer(int *buffer_size); |
639 | #ifdef IRAM_STEAL | ||
640 | void plugin_iram_init(char *iramstart, char *iramcopy, size_t iram_size, | ||
641 | char *iedata, size_t iedata_size); | ||
642 | #endif | ||
616 | 643 | ||
617 | /* plugin_tsr, | 644 | /* plugin_tsr, |
618 | callback returns true to allow the new plugin to load, | 645 | callback returns true to allow the new plugin to load, |
diff --git a/apps/plugins/doom/rockdoom.c b/apps/plugins/doom/rockdoom.c index 2b42322daa..8b73a5bb96 100644 --- a/apps/plugins/doom/rockdoom.c +++ b/apps/plugins/doom/rockdoom.c | |||
@@ -39,14 +39,7 @@ | |||
39 | #include "st_stuff.h" | 39 | #include "st_stuff.h" |
40 | 40 | ||
41 | PLUGIN_HEADER | 41 | PLUGIN_HEADER |
42 | 42 | PLUGIN_IRAM_DECLARE | |
43 | #ifdef USE_IRAM | ||
44 | extern char iramcopy[]; | ||
45 | extern char iramstart[]; | ||
46 | extern char iramend[]; | ||
47 | extern char iedata[]; | ||
48 | extern char iend[]; | ||
49 | #endif | ||
50 | 43 | ||
51 | extern boolean timingdemo, singledemo, demoplayback, fastdemo; // killough | 44 | extern boolean timingdemo, singledemo, demoplayback, fastdemo; // killough |
52 | 45 | ||
@@ -785,13 +778,7 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) | |||
785 | rb->cpu_boost(true); | 778 | rb->cpu_boost(true); |
786 | #endif | 779 | #endif |
787 | 780 | ||
788 | #ifdef USE_IRAM | 781 | PLUGIN_IRAM_INIT(rb) |
789 | /* We need to stop audio playback in order to use IRAM */ | ||
790 | rb->audio_stop(); | ||
791 | |||
792 | memcpy(iramstart, iramcopy, iramend-iramstart); | ||
793 | memset(iedata, 0, iend - iedata); | ||
794 | #endif | ||
795 | 782 | ||
796 | rb->lcd_setfont(0); | 783 | rb->lcd_setfont(0); |
797 | 784 | ||
@@ -830,7 +817,7 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) | |||
830 | if (result < 0) | 817 | if (result < 0) |
831 | { | 818 | { |
832 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ | 819 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ |
833 | rb->cpu_boost(false); | 820 | rb->cpu_boost(false); |
834 | #endif | 821 | #endif |
835 | if( result == -1 ) return PLUGIN_OK; // Quit was selected | 822 | if( result == -1 ) return PLUGIN_OK; // Quit was selected |
836 | else if( result == -2 ) return PLUGIN_ERROR; // Missing base wads | 823 | else if( result == -2 ) return PLUGIN_ERROR; // Missing base wads |
diff --git a/apps/plugins/midiplay.c b/apps/plugins/midiplay.c index 585c7eec25..a0e7d0e3c2 100644 --- a/apps/plugins/midiplay.c +++ b/apps/plugins/midiplay.c | |||
@@ -19,7 +19,7 @@ | |||
19 | #include "../../plugin.h" | 19 | #include "../../plugin.h" |
20 | 20 | ||
21 | PLUGIN_HEADER | 21 | PLUGIN_HEADER |
22 | 22 | PLUGIN_IRAM_DECLARE | |
23 | 23 | ||
24 | /* variable button definitions */ | 24 | /* variable button definitions */ |
25 | #if CONFIG_KEYPAD == RECORDER_PAD | 25 | #if CONFIG_KEYPAD == RECORDER_PAD |
@@ -102,14 +102,6 @@ short gmbuf[BUF_SIZE*NBUF] IBSS_ATTR; | |||
102 | int quit=0; | 102 | int quit=0; |
103 | struct plugin_api * rb; | 103 | struct plugin_api * rb; |
104 | 104 | ||
105 | #ifdef USE_IRAM | ||
106 | extern char iramcopy[]; | ||
107 | extern char iramstart[]; | ||
108 | extern char iramend[]; | ||
109 | extern char iedata[]; | ||
110 | extern char iend[]; | ||
111 | #endif | ||
112 | |||
113 | enum plugin_status plugin_start(struct plugin_api* api, void* parameter) | 105 | enum plugin_status plugin_start(struct plugin_api* api, void* parameter) |
114 | { | 106 | { |
115 | int retval = 0; | 107 | int retval = 0; |
@@ -122,10 +114,7 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) | |||
122 | } | 114 | } |
123 | rb->lcd_setfont(0); | 115 | rb->lcd_setfont(0); |
124 | 116 | ||
125 | #ifdef USE_IRAM | 117 | PLUGIN_IRAM_INIT(rb) |
126 | rb->memcpy(iramstart, iramcopy, iramend-iramstart); | ||
127 | rb->memset(iedata, 0, iend - iedata); | ||
128 | #endif | ||
129 | 118 | ||
130 | #if defined(HAVE_ADJUSTABLE_CPU_FREQ) | 119 | #if defined(HAVE_ADJUSTABLE_CPU_FREQ) |
131 | rb->cpu_boost(true); | 120 | rb->cpu_boost(true); |
diff --git a/apps/plugins/mp3_encoder.c b/apps/plugins/mp3_encoder.c index 6d66111d16..5bfd384349 100644 --- a/apps/plugins/mp3_encoder.c +++ b/apps/plugins/mp3_encoder.c | |||
@@ -14,17 +14,10 @@ | |||
14 | #include "plugin.h" | 14 | #include "plugin.h" |
15 | 15 | ||
16 | PLUGIN_HEADER | 16 | PLUGIN_HEADER |
17 | PLUGIN_IRAM_DECLARE | ||
17 | 18 | ||
18 | static struct plugin_api* rb; | 19 | static struct plugin_api* rb; |
19 | 20 | ||
20 | #ifdef USE_IRAM | ||
21 | extern char iramcopy[]; | ||
22 | extern char iramstart[]; | ||
23 | extern char iramend[]; | ||
24 | extern char iedata[]; | ||
25 | extern char iend[]; | ||
26 | #endif | ||
27 | |||
28 | #define SAMP_PER_FRAME 1152 | 21 | #define SAMP_PER_FRAME 1152 |
29 | #define SAMPL2 576 | 22 | #define SAMPL2 576 |
30 | #define SBLIMIT 32 | 23 | #define SBLIMIT 32 |
@@ -2377,10 +2370,7 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) | |||
2377 | asm volatile ("move.l #0, %macsr"); /* integer mode */ | 2370 | asm volatile ("move.l #0, %macsr"); /* integer mode */ |
2378 | #endif | 2371 | #endif |
2379 | 2372 | ||
2380 | #ifdef USE_IRAM | 2373 | PLUGIN_IRAM_INIT(rb) |
2381 | memcpy(iramstart, iramcopy, iramend - iramstart); | ||
2382 | memset(iedata, 0, iend - iedata); | ||
2383 | #endif | ||
2384 | 2374 | ||
2385 | rb->lcd_setfont(FONT_SYSFIXED); | 2375 | rb->lcd_setfont(FONT_SYSFIXED); |
2386 | 2376 | ||
diff --git a/apps/plugins/mpegplayer/mpegplayer.c b/apps/plugins/mpegplayer/mpegplayer.c index 980061f050..0fbd0f01e6 100644 --- a/apps/plugins/mpegplayer/mpegplayer.c +++ b/apps/plugins/mpegplayer/mpegplayer.c | |||
@@ -31,14 +31,7 @@ | |||
31 | #include "video_out.h" | 31 | #include "video_out.h" |
32 | 32 | ||
33 | PLUGIN_HEADER | 33 | PLUGIN_HEADER |
34 | 34 | PLUGIN_IRAM_DECLARE | |
35 | #ifdef USE_IRAM | ||
36 | extern char iramcopy[]; | ||
37 | extern char iramstart[]; | ||
38 | extern char iramend[]; | ||
39 | extern char iedata[]; | ||
40 | extern char iend[]; | ||
41 | #endif | ||
42 | 35 | ||
43 | struct plugin_api* rb; | 36 | struct plugin_api* rb; |
44 | 37 | ||
@@ -319,10 +312,7 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) | |||
319 | if (buffer == NULL) | 312 | if (buffer == NULL) |
320 | return PLUGIN_ERROR; | 313 | return PLUGIN_ERROR; |
321 | 314 | ||
322 | #ifdef USE_IRAM | 315 | PLUGIN_IRAM_INIT(rb) |
323 | rb->memcpy(iramstart, iramcopy, iramend-iramstart); | ||
324 | rb->memset(iedata, 0, iend - iedata); | ||
325 | #endif | ||
326 | 316 | ||
327 | rb->lcd_set_backdrop(NULL); | 317 | rb->lcd_set_backdrop(NULL); |
328 | 318 | ||
diff --git a/apps/plugins/pacbox/pacbox.c b/apps/plugins/pacbox/pacbox.c index 7c2d1e21ca..62f5bcd413 100644 --- a/apps/plugins/pacbox/pacbox.c +++ b/apps/plugins/pacbox/pacbox.c | |||
@@ -29,14 +29,7 @@ | |||
29 | #include "lib/configfile.h" | 29 | #include "lib/configfile.h" |
30 | 30 | ||
31 | PLUGIN_HEADER | 31 | PLUGIN_HEADER |
32 | 32 | PLUGIN_IRAM_DECLARE | |
33 | #ifdef USE_IRAM | ||
34 | extern char iramcopy[]; | ||
35 | extern char iramstart[]; | ||
36 | extern char iramend[]; | ||
37 | extern char iedata[]; | ||
38 | extern char iend[]; | ||
39 | #endif | ||
40 | 33 | ||
41 | struct plugin_api* rb; | 34 | struct plugin_api* rb; |
42 | 35 | ||
@@ -370,21 +363,10 @@ static int gameProc( void ) | |||
370 | enum plugin_status plugin_start(struct plugin_api* api, void* parameter) | 363 | enum plugin_status plugin_start(struct plugin_api* api, void* parameter) |
371 | { | 364 | { |
372 | (void)parameter; | 365 | (void)parameter; |
373 | #ifdef USE_IRAM | ||
374 | void* audiobuf; | ||
375 | int audiosize; | ||
376 | #endif | ||
377 | 366 | ||
378 | rb = api; | 367 | rb = api; |
379 | 368 | ||
380 | #ifdef USE_IRAM | 369 | PLUGIN_IRAM_INIT(rb) |
381 | /* We need to stop audio playback in order to use IRAM, so we grab | ||
382 | the audio buffer - but we don't use it. */ | ||
383 | audiobuf = rb->plugin_get_audio_buffer(&audiosize); | ||
384 | |||
385 | rb->memcpy(iramstart, iramcopy, iramend-iramstart); | ||
386 | rb->memset(iedata, 0, iend - iedata); | ||
387 | #endif | ||
388 | 370 | ||
389 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ | 371 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ |
390 | rb->cpu_boost(true); | 372 | rb->cpu_boost(true); |
diff --git a/apps/plugins/rockboy/rockboy.c b/apps/plugins/rockboy/rockboy.c index f82b0c283a..6a72856bbb 100644 --- a/apps/plugins/rockboy/rockboy.c +++ b/apps/plugins/rockboy/rockboy.c | |||
@@ -21,14 +21,7 @@ | |||
21 | #include "rockmacros.h" | 21 | #include "rockmacros.h" |
22 | 22 | ||
23 | PLUGIN_HEADER | 23 | PLUGIN_HEADER |
24 | 24 | PLUGIN_IRAM_DECLARE | |
25 | #ifdef USE_IRAM | ||
26 | extern char iramcopy[]; | ||
27 | extern char iramstart[]; | ||
28 | extern char iramend[]; | ||
29 | extern char iedata[]; | ||
30 | extern char iend[]; | ||
31 | #endif | ||
32 | 25 | ||
33 | /* here is a global api struct pointer. while not strictly necessary, | 26 | /* here is a global api struct pointer. while not strictly necessary, |
34 | it's nice not to have to pass the api pointer in all function calls | 27 | it's nice not to have to pass the api pointer in all function calls |
@@ -187,10 +180,9 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) | |||
187 | audio_buffer_free = plugin_start_addr - (unsigned char *)audio_bufferbase; | 180 | audio_buffer_free = plugin_start_addr - (unsigned char *)audio_bufferbase; |
188 | #endif | 181 | #endif |
189 | setoptions(); | 182 | setoptions(); |
190 | #ifdef USE_IRAM | 183 | |
191 | memcpy(iramstart, iramcopy, iramend-iramstart); | 184 | PLUGIN_IRAM_INIT(rb) |
192 | memset(iedata, 0, iend - iedata); | 185 | |
193 | #endif | ||
194 | shut=0; | 186 | shut=0; |
195 | cleanshut=0; | 187 | cleanshut=0; |
196 | 188 | ||
diff --git a/apps/plugins/zxbox/zxbox.c b/apps/plugins/zxbox/zxbox.c index 54a11d010e..753fb1ff5b 100644 --- a/apps/plugins/zxbox/zxbox.c +++ b/apps/plugins/zxbox/zxbox.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include "zxconfig.h" | 20 | #include "zxconfig.h" |
21 | 21 | ||
22 | PLUGIN_HEADER | 22 | PLUGIN_HEADER |
23 | PLUGIN_IRAM_DECLARE | ||
23 | 24 | ||
24 | struct plugin_api* rb; | 25 | struct plugin_api* rb; |
25 | 26 | ||
@@ -37,14 +38,6 @@ int use_shm = 0; | |||
37 | int small_screen,pause_on_iconify; | 38 | int small_screen,pause_on_iconify; |
38 | int vga_pause_bg; | 39 | int vga_pause_bg; |
39 | 40 | ||
40 | #ifdef USE_IRAM | ||
41 | extern char iramcopy[]; | ||
42 | extern char iramstart[]; | ||
43 | extern char iramend[]; | ||
44 | extern char iedata[]; | ||
45 | extern char iend[]; | ||
46 | #endif | ||
47 | |||
48 | #include "keymaps.h" | 41 | #include "keymaps.h" |
49 | #include "zxvid_com.h" | 42 | #include "zxvid_com.h" |
50 | #include "spmain.h" | 43 | #include "spmain.h" |
@@ -75,13 +68,7 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) | |||
75 | rb->lcd_set_backdrop(NULL); | 68 | rb->lcd_set_backdrop(NULL); |
76 | rb->splash(HZ, true, "Welcome to ZXBox"); | 69 | rb->splash(HZ, true, "Welcome to ZXBox"); |
77 | 70 | ||
78 | #ifdef USE_IRAM | 71 | PLUGIN_IRAM_INIT(rb) |
79 | /* We need to stop audio playback in order to use IRAM */ | ||
80 | rb->audio_stop(); | ||
81 | |||
82 | rb->memcpy(iramstart, iramcopy, iramend-iramstart); | ||
83 | rb->memset(iedata, 0, iend - iedata); | ||
84 | #endif | ||
85 | 72 | ||
86 | sp_init(); | 73 | sp_init(); |
87 | 74 | ||
diff --git a/apps/talk.c b/apps/talk.c index 018f6ed5ab..cabc93576b 100644 --- a/apps/talk.c +++ b/apps/talk.c | |||
@@ -522,7 +522,7 @@ void talk_init(void) | |||
522 | MAX_FILENAME); | 522 | MAX_FILENAME); |
523 | 523 | ||
524 | #if CONFIG_CODEC == SWCODEC | 524 | #if CONFIG_CODEC == SWCODEC |
525 | audio_stop(); | 525 | audio_get_buffer(false, NULL); /* Must tell audio to reinitialize */ |
526 | #endif | 526 | #endif |
527 | reset_state(); /* use this for most of our inits */ | 527 | reset_state(); /* use this for most of our inits */ |
528 | 528 | ||
diff --git a/apps/talk.h b/apps/talk.h index bfd08354aa..4c1ef7c625 100644 --- a/apps/talk.h +++ b/apps/talk.h | |||
@@ -62,7 +62,9 @@ extern const char* const file_thumbnail_ext; /* ".talk" for file voicing */ | |||
62 | void talk_init(void); | 62 | void talk_init(void); |
63 | bool talk_voice_required(void); /* returns true if voice codec required */ | 63 | bool talk_voice_required(void); /* returns true if voice codec required */ |
64 | int talk_get_bufsize(void); /* get the loaded voice file size */ | 64 | int talk_get_bufsize(void); /* get the loaded voice file size */ |
65 | #if CONFIG_CODEC != SWCODEC | ||
65 | int talk_buffer_steal(void); /* claim the mp3 buffer e.g. for play/record */ | 66 | int talk_buffer_steal(void); /* claim the mp3 buffer e.g. for play/record */ |
67 | #endif | ||
66 | int talk_id(long id, bool enqueue); /* play a voice ID from voicefont */ | 68 | int talk_id(long id, bool enqueue); /* play a voice ID from voicefont */ |
67 | int talk_file(const char* filename, bool enqueue); /* play a thumbnail from file */ | 69 | int talk_file(const char* filename, bool enqueue); /* play a thumbnail from file */ |
68 | int talk_number(long n, bool enqueue); /* say a number */ | 70 | int talk_number(long n, bool enqueue); /* say a number */ |
diff --git a/firmware/export/audio.h b/firmware/export/audio.h index 42d94a9158..573252e938 100644 --- a/firmware/export/audio.h +++ b/firmware/export/audio.h | |||
@@ -101,7 +101,12 @@ void audio_error_clear(void); | |||
101 | int audio_get_file_pos(void); | 101 | int audio_get_file_pos(void); |
102 | void audio_beep(int duration); | 102 | void audio_beep(int duration); |
103 | void audio_init_playback(void); | 103 | void audio_init_playback(void); |
104 | /* Required call when audio buffer is require for some other purpose */ | ||
104 | unsigned char *audio_get_buffer(bool talk_buf, size_t *buffer_size); | 105 | unsigned char *audio_get_buffer(bool talk_buf, size_t *buffer_size); |
106 | #ifdef USE_IRAM | ||
107 | /* Required call when codec IRAM is needed for some other purpose */ | ||
108 | void audio_iram_steal(void); | ||
109 | #endif | ||
105 | 110 | ||
106 | /* channel modes */ | 111 | /* channel modes */ |
107 | enum rec_channel_modes | 112 | enum rec_channel_modes |
diff --git a/firmware/export/config.h b/firmware/export/config.h index 440c0faef3..74c7e924ff 100644 --- a/firmware/export/config.h +++ b/firmware/export/config.h | |||
@@ -283,6 +283,9 @@ | |||
283 | #define IDATA_ATTR __attribute__ ((section(".idata"))) | 283 | #define IDATA_ATTR __attribute__ ((section(".idata"))) |
284 | #define IBSS_ATTR __attribute__ ((section(".ibss"))) | 284 | #define IBSS_ATTR __attribute__ ((section(".ibss"))) |
285 | #define USE_IRAM | 285 | #define USE_IRAM |
286 | #if CONFIG_CPU != SH7034 | ||
287 | #define IRAM_STEAL | ||
288 | #endif | ||
286 | #else | 289 | #else |
287 | #define ICODE_ATTR | 290 | #define ICODE_ATTR |
288 | #define ICONST_ATTR | 291 | #define ICONST_ATTR |