From acc29d95be85c9cfd0d8f74dda813d7d1082e2ec Mon Sep 17 00:00:00 2001 From: Michael Sevakis Date: Sat, 18 Nov 2006 02:18:29 +0000 Subject: [PATCH] SWCODEC/IRAM: Save voice IRAM when a plugin initializes its IRAM. Defines two macros for declaring and initializing IRAM. Plugins should use these instead. See mp3_encoder, doom, etc. for details. Further tweaks in buffer restoration after other use. Hiding of some interfaces that should only be used by buffer management. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11544 a1c6a512-1295-4272-9138-f99709370657 --- apps/playback.c | 149 +++++++++++++++++++++++---- apps/playlist_viewer.c | 2 + apps/plugin.c | 16 ++- apps/plugin.h | 33 +++++- apps/plugins/doom/rockdoom.c | 19 +--- apps/plugins/midiplay.c | 15 +-- apps/plugins/mp3_encoder.c | 14 +-- apps/plugins/mpegplayer/mpegplayer.c | 14 +-- apps/plugins/pacbox/pacbox.c | 22 +--- apps/plugins/rockboy/rockboy.c | 16 +-- apps/plugins/zxbox/zxbox.c | 17 +-- apps/talk.c | 2 +- apps/talk.h | 2 + firmware/export/audio.h | 5 + 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 #define CODEC_IRAM_ORIGIN sim_iram #endif -static unsigned char *iram_buf[2]; /* Ptr to IRAM buffers for normal/voice codecs */ -static unsigned char *dram_buf[2]; /* Ptr to DRAM buffers for normal/voice codecs */ +static unsigned char *iram_buf[2] = { NULL, NULL }; /* Ptr to IRAM buffers for normal/voice codecs */ +static unsigned char *dram_buf[2] = { NULL, NULL }; /* Ptr to DRAM buffers for normal/voice codecs */ static struct mutex mutex_codecthread; /* Mutex to control which codec (normal/voice) is running */ /* Voice state */ @@ -307,6 +307,10 @@ static volatile bool voice_codec_loaded; /* Is voice codec loaded (V/A-) */ static char *voicebuf; static size_t voice_remaining; +#ifdef IRAM_STEAL +static bool voice_iram_stolen = false; /* Voice IRAM has been stolen for other use */ +#endif + static void (*voice_getmore)(unsigned char** start, int* size); struct voice_info { @@ -318,15 +322,21 @@ static void voice_thread(void); #endif /* PLAYBACK_VOICE */ +/* --- Shared semi-private interfaces --- */ + +/* imported */ +extern void talk_buffer_steal(void); +#ifdef HAVE_RECORDING +extern void pcm_rec_error_clear(void); +extern unsigned long pcm_rec_status(void); +#endif + + /* --- External interfaces --- */ void mp3_play_data(const unsigned char* start, int size, void (*get_more)(unsigned char** start, int* size)) { - /* must reset the buffer before any playback begins if needed */ - if (buffer_state == BUFFER_STATE_TRASHED) - audio_reset_buffer(pcmbuf_get_bufsize()); - #ifdef PLAYBACK_VOICE static struct voice_info voice_clip; voice_clip.callback = get_more; @@ -366,11 +376,20 @@ void mpeg_id3_options(bool _v1first) unsigned char *audio_get_buffer(bool talk_buf, size_t *buffer_size) { - unsigned char *buf = audiobuf; - unsigned char *end = audiobufend; + unsigned char *buf, *end; audio_stop(); + if (buffer_size == NULL) + { + /* Special case for talk_init to use */ + buffer_state = BUFFER_STATE_TRASHED; + return NULL; + } + + buf = audiobuf; + end = audiobufend; + if (talk_buf || !talk_voice_required() || buffer_state == BUFFER_STATE_TRASHED) { @@ -395,17 +414,57 @@ unsigned char *audio_get_buffer(bool talk_buf, size_t *buffer_size) return buf; } +#ifdef IRAM_STEAL +void audio_iram_steal(void) +{ + /* We need to stop audio playback in order to use codec IRAM */ + audio_stop(); + +#ifdef PLAYBACK_VOICE + if (NULL != iram_buf[CODEC_IDX_VOICE]) + { + /* Wait for voice to swap back in if current codec was audio */ + while (current_codec != CODEC_IDX_VOICE) + yield(); + + voice_stop(); + + /* Save voice IRAM - safe to do here since state is known */ + memcpy(iram_buf[CODEC_IDX_VOICE], (void *)CODEC_IRAM_ORIGIN, + CODEC_IRAM_SIZE); + voice_iram_stolen = true; + } + else + { + /* Nothing much to do if no voice */ + voice_iram_stolen = false; + } +#endif +} +#endif /* IRAM_STEAL */ + #ifdef HAVE_RECORDING unsigned char *audio_get_recording_buffer(size_t *buffer_size) { /* don't allow overwrite of voice swap area or we'll trash the swapped-out voice codec but can use whole thing if none */ - unsigned char *end = iram_buf[CODEC_IDX_VOICE] ? - iram_buf[CODEC_IDX_VOICE] : audiobufend; + unsigned char *end; audio_stop(); talk_buffer_steal(); +#ifdef PLAYBACK_VOICE +#ifdef IRAM_STEAL + end = dram_buf[CODEC_IDX_VOICE] ? + dram_buf[CODEC_IDX_VOICE] : audiobufend; +#else + end = iram_buf[CODEC_IDX_VOICE] ? + iram_buf[CODEC_IDX_VOICE] : audiobufend; +#endif /* IRAM_STEAL */ +#else + end = audiobufend; +#endif /* PLAYBACK_VOICE */ + buffer_state = BUFFER_STATE_TRASHED; *buffer_size = end - audiobuf; @@ -645,7 +704,6 @@ void audio_flush_and_reload_tracks(void) void audio_error_clear(void) { #ifdef AUDIO_HAVE_RECORDING - extern void pcm_rec_error_clear(void); pcm_rec_error_clear(); #endif } @@ -662,7 +720,6 @@ int audio_status(void) #ifdef HAVE_RECORDING /* Do this here for constitency with mpeg.c version */ - extern unsigned long pcm_rec_status(void); ret |= pcm_rec_status(); #endif @@ -820,7 +877,6 @@ void voice_stop(void) /* --- Routines called from multiple threads --- */ - #ifdef PLAYBACK_VOICE static void swap_codec(void) { @@ -829,8 +885,26 @@ static void swap_codec(void) logf("swapping out codec:%d", my_codec); /* Save our current IRAM and DRAM */ +#ifdef IRAM_STEAL + if (voice_iram_stolen) + { + logf("swap: iram restore"); + voice_iram_stolen = false; + /* Don't swap trashed data into buffer - _should_ always be the case + if voice_iram_stolen is true since the voice has been swapped in + before hand */ + if (my_codec == CODEC_IDX_VOICE) + goto skip_iram_swap; + } +#endif + memcpy(iram_buf[my_codec], (unsigned char *)CODEC_IRAM_ORIGIN, CODEC_IRAM_SIZE); + +#ifdef IRAM_STEAL +skip_iram_swap: +#endif + memcpy(dram_buf[my_codec], codecbuf, CODEC_SIZE); /* Release my semaphore */ @@ -1085,6 +1159,21 @@ static void* voice_request_buffer_callback(size_t *realsize, size_t reqsize) { /* Set up new voice data */ struct voice_info *voice_data; +#ifdef IRAM_STEAL + if (voice_iram_stolen) + { + logf("voice: iram restore"); + memcpy((void*)CODEC_IRAM_ORIGIN, + iram_buf[CODEC_IDX_VOICE], + CODEC_IRAM_SIZE); + voice_iram_stolen = false; + } +#endif + /* must reset the buffer before any playback + begins if needed */ + if (buffer_state == BUFFER_STATE_TRASHED) + audio_reset_buffer(pcmbuf_get_bufsize()); + voice_is_playing = true; trigger_cpu_boost(); voice_data = ev.data; @@ -2809,6 +2898,10 @@ static void audio_fill_file_buffer( bool had_next_track = audio_next_track() != NULL; bool continue_buffering; + /* must reset the buffer before use if trashed */ + if (buffer_state != BUFFER_STATE_NORMAL) + audio_reset_buffer(pcmbuf_get_bufsize()); + if (!audio_initialize_buffer_fill(!start_play)) return ; @@ -3156,10 +3249,6 @@ static void audio_play_start(size_t offset) /* Wait for any previously playing audio to flush - TODO: Not necessary? */ audio_stop_codec_flush(); - /* must reset the buffer before any playback begins if needed */ - if (buffer_state != BUFFER_STATE_NORMAL) - audio_reset_buffer(pcmbuf_get_bufsize()); - track_changed = true; playlist_end = false; @@ -3272,14 +3361,34 @@ static void audio_reset_buffer(size_t pcmbufsize) if (talk_voice_required()) { #ifdef PLAYBACK_VOICE +#ifdef IRAM_STEAL + filebuflen -= CODEC_IRAM_SIZE + 2*CODEC_SIZE; +#else + filebuflen -= 2*(CODEC_IRAM_SIZE + CODEC_SIZE); +#endif /* Allow 2 codecs at end of audio buffer */ - filebuflen -= 2 * (CODEC_IRAM_SIZE + CODEC_SIZE); - + /* If using IRAM for plugins voice IRAM swap buffer must be dedicated + and out of the way of buffer usage or else a call to audio_get_buffer + and subsequent buffer use might trash the swap space. A plugin + initializing IRAM after getting the full buffer would present similar + problem. Options include: failing the request if the other buffer + has been obtained already or never allowing use of the voice IRAM + buffer within the audio buffer. Using buffer_alloc basically + implements the second in a more convenient way. */ iram_buf[CODEC_IDX_AUDIO] = filebuf + filebuflen; dram_buf[CODEC_IDX_AUDIO] = iram_buf[CODEC_IDX_AUDIO] + CODEC_IRAM_SIZE; + +#ifdef IRAM_STEAL + /* Allocate voice IRAM swap buffer once */ + if (iram_buf[CODEC_IDX_VOICE] == NULL) + iram_buf[CODEC_IDX_VOICE] = buffer_alloc(CODEC_IRAM_SIZE); + dram_buf[CODEC_IDX_VOICE] = dram_buf[CODEC_IDX_AUDIO] + CODEC_SIZE; +#else iram_buf[CODEC_IDX_VOICE] = dram_buf[CODEC_IDX_AUDIO] + CODEC_SIZE; dram_buf[CODEC_IDX_VOICE] = iram_buf[CODEC_IDX_VOICE] + CODEC_IRAM_SIZE; -#endif +#endif /* IRAM_STEAL */ + +#endif /* PLAYBACK_VOICE */ } else { 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) if (current_track->display_index!=viewer.num_tracks || global_settings.repeat_mode == REPEAT_ALL) { +#if CONFIG_CODEC != SWCODEC talk_buffer_steal(); /* will use the mp3 buffer */ +#endif audio_play(0); viewer.current_playing_track = -1; } 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 = { lcd_set_backdrop, #endif +#ifdef IRAM_STEAL + plugin_iram_init, +#endif }; int plugin_load(const char* plugin, void* parameter) @@ -683,10 +686,21 @@ void* plugin_get_audio_buffer(int* buffer_size) audio_stop(); talk_buffer_steal(); /* we use the mp3 buffer, need to tell */ *buffer_size = audiobufend - audiobuf; -#endif return audiobuf; +#endif } +#ifdef IRAM_STEAL +/* Initializes plugin IRAM */ +void plugin_iram_init(char *iramstart, char *iramcopy, size_t iram_size, + char *iedata, size_t iedata_size) +{ + audio_iram_steal(); + memcpy(iramstart, iramcopy, iram_size); + memset(iedata, 0, iedata_size); +} +#endif /* IRAM_STEAL */ + /* The plugin wants to stay resident after leaving its main function, e.g. runs from timer or own thread. The callback is registered to later instruct it to free its resources before a new plugin gets loaded. */ 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 @@ #define PLUGIN_MAGIC 0x526F634B /* RocK */ /* increase this every time the api struct changes */ -#define PLUGIN_API_VERSION 35 +#define PLUGIN_API_VERSION 36 /* update this to latest version if a change to the api struct breaks backwards compatibility (and please take the opportunity to sort in any @@ -582,6 +582,11 @@ struct plugin_api { #if LCD_DEPTH > 1 void (*lcd_set_backdrop)(fb_data* backdrop); #endif + +#ifdef IRAM_STEAL + void (*plugin_iram_init)(char *iramstart, char *iramcopy, size_t iram_size, + char *iedata, size_t iedata_size); +#endif }; /* plugin header */ @@ -593,6 +598,7 @@ struct plugin_header { unsigned char *end_addr; enum plugin_status(*entry_point)(struct plugin_api*, void*); }; + #ifdef PLUGIN #ifndef SIMULATOR extern unsigned char plugin_start_addr[]; @@ -607,12 +613,33 @@ extern unsigned char plugin_end_addr[]; const struct plugin_header __header = { \ PLUGIN_MAGIC, TARGET_ID, PLUGIN_API_VERSION, \ NULL, NULL, plugin_start }; -#endif -#endif +#endif /* SIMULATOR */ + +#ifdef USE_IRAM +/* Declare IRAM variables */ +#define PLUGIN_IRAM_DECLARE \ + extern char iramcopy[]; \ + extern char iramstart[]; \ + extern char iramend[]; \ + extern char iedata[]; \ + extern char iend[]; +/* Initialize IRAM */ +#define PLUGIN_IRAM_INIT(api) \ + (api)->plugin_iram_init(iramstart, iramcopy, iramend-iramstart, \ + iedata, iend-iedata); +#else +#define PLUGIN_IRAM_DECLARE +#define PLUGIN_IRAM_INIT(api) +#endif /* USE_IRAM */ +#endif /* PLUGIN */ int plugin_load(const char* plugin, void* parameter); void* plugin_get_buffer(int *buffer_size); void* plugin_get_audio_buffer(int *buffer_size); +#ifdef IRAM_STEAL +void plugin_iram_init(char *iramstart, char *iramcopy, size_t iram_size, + char *iedata, size_t iedata_size); +#endif /* plugin_tsr, 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 @@ #include "st_stuff.h" PLUGIN_HEADER - -#ifdef USE_IRAM -extern char iramcopy[]; -extern char iramstart[]; -extern char iramend[]; -extern char iedata[]; -extern char iend[]; -#endif +PLUGIN_IRAM_DECLARE extern boolean timingdemo, singledemo, demoplayback, fastdemo; // killough @@ -785,13 +778,7 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) rb->cpu_boost(true); #endif -#ifdef USE_IRAM - /* We need to stop audio playback in order to use IRAM */ - rb->audio_stop(); - - memcpy(iramstart, iramcopy, iramend-iramstart); - memset(iedata, 0, iend - iedata); -#endif + PLUGIN_IRAM_INIT(rb) rb->lcd_setfont(0); @@ -830,7 +817,7 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) if (result < 0) { #ifdef HAVE_ADJUSTABLE_CPU_FREQ - rb->cpu_boost(false); + rb->cpu_boost(false); #endif if( result == -1 ) return PLUGIN_OK; // Quit was selected 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 @@ #include "../../plugin.h" PLUGIN_HEADER - +PLUGIN_IRAM_DECLARE /* variable button definitions */ #if CONFIG_KEYPAD == RECORDER_PAD @@ -102,14 +102,6 @@ short gmbuf[BUF_SIZE*NBUF] IBSS_ATTR; int quit=0; struct plugin_api * rb; -#ifdef USE_IRAM -extern char iramcopy[]; -extern char iramstart[]; -extern char iramend[]; -extern char iedata[]; -extern char iend[]; -#endif - enum plugin_status plugin_start(struct plugin_api* api, void* parameter) { int retval = 0; @@ -122,10 +114,7 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) } rb->lcd_setfont(0); -#ifdef USE_IRAM - rb->memcpy(iramstart, iramcopy, iramend-iramstart); - rb->memset(iedata, 0, iend - iedata); -#endif + PLUGIN_IRAM_INIT(rb) #if defined(HAVE_ADJUSTABLE_CPU_FREQ) 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 @@ #include "plugin.h" PLUGIN_HEADER +PLUGIN_IRAM_DECLARE static struct plugin_api* rb; -#ifdef USE_IRAM -extern char iramcopy[]; -extern char iramstart[]; -extern char iramend[]; -extern char iedata[]; -extern char iend[]; -#endif - #define SAMP_PER_FRAME 1152 #define SAMPL2 576 #define SBLIMIT 32 @@ -2377,10 +2370,7 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) asm volatile ("move.l #0, %macsr"); /* integer mode */ #endif -#ifdef USE_IRAM - memcpy(iramstart, iramcopy, iramend - iramstart); - memset(iedata, 0, iend - iedata); -#endif + PLUGIN_IRAM_INIT(rb) rb->lcd_setfont(FONT_SYSFIXED); 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 @@ #include "video_out.h" PLUGIN_HEADER - -#ifdef USE_IRAM -extern char iramcopy[]; -extern char iramstart[]; -extern char iramend[]; -extern char iedata[]; -extern char iend[]; -#endif +PLUGIN_IRAM_DECLARE struct plugin_api* rb; @@ -319,10 +312,7 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) if (buffer == NULL) return PLUGIN_ERROR; -#ifdef USE_IRAM - rb->memcpy(iramstart, iramcopy, iramend-iramstart); - rb->memset(iedata, 0, iend - iedata); -#endif + PLUGIN_IRAM_INIT(rb) rb->lcd_set_backdrop(NULL); 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 @@ #include "lib/configfile.h" PLUGIN_HEADER - -#ifdef USE_IRAM -extern char iramcopy[]; -extern char iramstart[]; -extern char iramend[]; -extern char iedata[]; -extern char iend[]; -#endif +PLUGIN_IRAM_DECLARE struct plugin_api* rb; @@ -370,21 +363,10 @@ static int gameProc( void ) enum plugin_status plugin_start(struct plugin_api* api, void* parameter) { (void)parameter; -#ifdef USE_IRAM - void* audiobuf; - int audiosize; -#endif rb = api; -#ifdef USE_IRAM - /* We need to stop audio playback in order to use IRAM, so we grab - the audio buffer - but we don't use it. */ - audiobuf = rb->plugin_get_audio_buffer(&audiosize); - - rb->memcpy(iramstart, iramcopy, iramend-iramstart); - rb->memset(iedata, 0, iend - iedata); -#endif + PLUGIN_IRAM_INIT(rb) #ifdef HAVE_ADJUSTABLE_CPU_FREQ 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 @@ #include "rockmacros.h" PLUGIN_HEADER - -#ifdef USE_IRAM -extern char iramcopy[]; -extern char iramstart[]; -extern char iramend[]; -extern char iedata[]; -extern char iend[]; -#endif +PLUGIN_IRAM_DECLARE /* here is a global api struct pointer. while not strictly necessary, 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) audio_buffer_free = plugin_start_addr - (unsigned char *)audio_bufferbase; #endif setoptions(); -#ifdef USE_IRAM - memcpy(iramstart, iramcopy, iramend-iramstart); - memset(iedata, 0, iend - iedata); -#endif + + PLUGIN_IRAM_INIT(rb) + shut=0; cleanshut=0; 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 @@ #include "zxconfig.h" PLUGIN_HEADER +PLUGIN_IRAM_DECLARE struct plugin_api* rb; @@ -37,14 +38,6 @@ int use_shm = 0; int small_screen,pause_on_iconify; int vga_pause_bg; -#ifdef USE_IRAM -extern char iramcopy[]; -extern char iramstart[]; -extern char iramend[]; -extern char iedata[]; -extern char iend[]; -#endif - #include "keymaps.h" #include "zxvid_com.h" #include "spmain.h" @@ -75,13 +68,7 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) rb->lcd_set_backdrop(NULL); rb->splash(HZ, true, "Welcome to ZXBox"); -#ifdef USE_IRAM - /* We need to stop audio playback in order to use IRAM */ - rb->audio_stop(); - - rb->memcpy(iramstart, iramcopy, iramend-iramstart); - rb->memset(iedata, 0, iend - iedata); -#endif + PLUGIN_IRAM_INIT(rb) sp_init(); 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) MAX_FILENAME); #if CONFIG_CODEC == SWCODEC - audio_stop(); + audio_get_buffer(false, NULL); /* Must tell audio to reinitialize */ #endif reset_state(); /* use this for most of our inits */ 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 */ void talk_init(void); bool talk_voice_required(void); /* returns true if voice codec required */ int talk_get_bufsize(void); /* get the loaded voice file size */ +#if CONFIG_CODEC != SWCODEC int talk_buffer_steal(void); /* claim the mp3 buffer e.g. for play/record */ +#endif int talk_id(long id, bool enqueue); /* play a voice ID from voicefont */ int talk_file(const char* filename, bool enqueue); /* play a thumbnail from file */ 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); int audio_get_file_pos(void); void audio_beep(int duration); void audio_init_playback(void); +/* Required call when audio buffer is require for some other purpose */ unsigned char *audio_get_buffer(bool talk_buf, size_t *buffer_size); +#ifdef USE_IRAM +/* Required call when codec IRAM is needed for some other purpose */ +void audio_iram_steal(void); +#endif /* channel modes */ 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 @@ #define IDATA_ATTR __attribute__ ((section(".idata"))) #define IBSS_ATTR __attribute__ ((section(".ibss"))) #define USE_IRAM +#if CONFIG_CPU != SH7034 +#define IRAM_STEAL +#endif #else #define ICODE_ATTR #define ICONST_ATTR