summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
Diffstat (limited to 'apps')
-rw-r--r--apps/playback.c149
-rw-r--r--apps/playlist_viewer.c2
-rw-r--r--apps/plugin.c16
-rw-r--r--apps/plugin.h33
-rw-r--r--apps/plugins/doom/rockdoom.c19
-rw-r--r--apps/plugins/midiplay.c15
-rw-r--r--apps/plugins/mp3_encoder.c14
-rw-r--r--apps/plugins/mpegplayer/mpegplayer.c14
-rw-r--r--apps/plugins/pacbox/pacbox.c22
-rw-r--r--apps/plugins/rockboy/rockboy.c16
-rw-r--r--apps/plugins/zxbox/zxbox.c17
-rw-r--r--apps/talk.c2
-rw-r--r--apps/talk.h2
13 files changed, 196 insertions, 125 deletions
diff --git a/apps/playback.c b/apps/playback.c
index 279fb15..9bf6942 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 87bbaa4..8670f0a 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 90b3837..a00a54e 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,9 +686,20 @@ 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
diff --git a/apps/plugin.h b/apps/plugin.h
index e9a6cfd..608009d 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 2b42322..8b73a5b 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 585c7ee..a0e7d0e 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 6d66111..5bfd384 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 980061f..0fbd0f0 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 7c2d1e2..62f5bcd 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 f82b0c2..6a72856 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 54a11d0..753fb1f 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 018f6ed..cabc935 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 bfd0835..4c1ef7c 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 */