1
0
Fork 0
forked from len0rd/rockbox

Speech feedback in mpegplayer menus

Patch by Igor Poretsky

Change-Id: Idc6920e17be6537557f2b1cf00f7e559e30b45e8
This commit is contained in:
Solomon Peachy 2019-07-20 17:32:49 -04:00
parent 7234de58ae
commit 4ad76652ef
5 changed files with 556 additions and 66 deletions

View file

@ -15279,3 +15279,363 @@ id: VOICE_BAT_BENCH_KEYS
lcd_bitmap: "View Played Games" lcd_bitmap: "View Played Games"
</voice> </voice>
</phrase> </phrase>
<phrase>
id: LANG_MENU_AUDIO_OPTIONS
desc: in mpegplayer menus
user: core
<source>
*: none
swcodec: "Audio Options"
lowmem: none
</source>
<dest>
*: none
swcodec: "Audio Options"
lowmem: none
</dest>
<voice>
*: none
swcodec: "Audio Options"
lowmem: none
</voice>
</phrase>
<phrase>
id: LANG_MENU_RESUME_OPTIONS
desc: in mpegplayer menus
user: core
<source>
*: none
swcodec: "Resume Options"
lowmem: none
</source>
<dest>
*: none
swcodec: "Resume Options"
lowmem: none
</dest>
<voice>
*: none
swcodec: "Resume Options"
lowmem: none
</voice>
</phrase>
<phrase>
id: LANG_MENU_PLAY_MODE
desc: in mpegplayer menus
user: core
<source>
*: none
swcodec: "Play Mode"
lowmem: none
</source>
<dest>
*: none
swcodec: "Play Mode"
lowmem: none
</dest>
<voice>
*: none
swcodec: "Play Mode"
lowmem: none
</voice>
</phrase>
<phrase>
id: LANG_SINGLE
desc: in mpegplayer menus
user: core
<source>
*: none
swcodec: "Single"
lowmem: none
</source>
<dest>
*: none
swcodec: "Single"
lowmem: none
</dest>
<voice>
*: none
swcodec: "Single"
lowmem: none
</voice>
</phrase>
<phrase>
id: LANG_USE_SOUND_SETTING
desc: in mpegplayer menus
user: core
<source>
*: none
swcodec: "Use sound setting"
lowmem: none
</source>
<dest>
*: none
swcodec: "Use sound setting"
lowmem: none
</dest>
<voice>
*: none
swcodec: "Use sound setting"
lowmem: none
</voice>
</phrase>
<phrase>
id: LANG_RESTART_PLAYBACK
desc: in the mpegplayer settings menu
user: core
<source>
*: none
swcodec: "Play from beginning"
lowmem: none
</source>
<dest>
*: none
swcodec: "Play from beginning"
lowmem: none
</dest>
<voice>
*: none
swcodec: "Play from beginning"
lowmem: none
</voice>
</phrase>
<phrase>
id: LANG_SET_RESUME_TIME
desc: in the mpegplayer settings menu
user: core
<source>
*: none
swcodec: "Set resume time (min)"
lowmem: none
</source>
<dest>
*: none
swcodec: "Set resume time (min)"
lowmem: none
</dest>
<voice>
*: none
swcodec: "Set resume time"
lowmem: none
</voice>
</phrase>
<phrase>
id: LANG_DISPLAY_FPS
desc: in the mpegplayer settings menu
user: core
<source>
*: none
swcodec: "Display FPS"
lowmem: none
</source>
<dest>
*: none
swcodec: "Display FPS"
lowmem: none
</dest>
<voice>
*: none
swcodec: "Display FPS"
lowmem: none
</voice>
</phrase>
<phrase>
id: LANG_LIMIT_FPS
desc: in the mpegplayer settings menu
user: core
<source>
*: none
swcodec: "Limit FPS"
lowmem: none
</source>
<dest>
*: none
swcodec: "Limit FPS"
lowmem: none
</dest>
<voice>
*: none
swcodec: "Limit FPS"
lowmem: none
</voice>
</phrase>
<phrase>
id: LANG_SKIP_FRAMES
desc: in the mpegplayer settings menu
user: core
<source>
*: none
swcodec: "Skip frames"
lowmem: none
</source>
<dest>
*: none
swcodec: "Skip frames"
lowmem: none
</dest>
<voice>
*: none
swcodec: "Skip frames"
lowmem: none
</voice>
</phrase>
<phrase>
id: LANG_BACKLIGHT_BRIGHTNESS
desc: in the mpegplayer settings menu
user: core
<source>
*: none
swcodec: "Backlight brightness"
lowmem: none
</source>
<dest>
*: none
swcodec: "Backlight brightness"
lowmem: none
</dest>
<voice>
*: none
swcodec: "Backlight brightness"
lowmem: none
</voice>
</phrase>
<phrase>
id: LANG_USE_COMMON_SETTING
desc: in the mpegplayer settings menu
user: core
<source>
*: none
swcodec: "Use common setting"
lowmem: none
</source>
<dest>
*: none
swcodec: "Use common setting"
lowmem: none
</dest>
<voice>
*: none
swcodec: "Use common setting"
lowmem: none
</voice>
</phrase>
<phrase>
id: LANG_TONE_CONTROLS
desc: in the mpegplayer settings menu
user: core
<source>
*: none
swcodec: "Tone controls"
lowmem: none
</source>
<dest>
*: none
swcodec: "Tone controls"
lowmem: none
</dest>
<voice>
*: none
swcodec: "Tone controls"
lowmem: none
</voice>
</phrase>
<phrase>
id: LANG_FORCE_START_MENU
desc: in mpegplayer menus
user: core
<source>
*: none
swcodec: "Start menu"
lowmem: none
</source>
<dest>
*: none
swcodec: "Start menu"
lowmem: none
</dest>
<voice>
*: none
swcodec: "Start menu"
lowmem: none
</voice>
</phrase>
<phrase>
id: LANG_CONDITIONAL_START_MENU
desc: in mpegplayer menus
user: core
<source>
*: none
swcodec: "Start menu if not completed"
lowmem: none
</source>
<dest>
*: none
swcodec: "Start menu if not completed"
lowmem: none
</dest>
<voice>
*: none
swcodec: "Start menu if not completed"
lowmem: none
</voice>
</phrase>
<phrase>
id: LANG_AUTO_RESUME
desc: in mpegplayer menus
user: core
<source>
*: none
swcodec: "Resume automatically"
lowmem: none
</source>
<dest>
*: none
swcodec: "Resume automatically"
lowmem: none
</dest>
<voice>
*: none
swcodec: "Resume automatically"
lowmem: none
</voice>
</phrase>
<phrase>
id: LANG_CLEAR_ALL_RESUMES
desc: in the mpegplayer settings menu
user: core
<source>
*: none
swcodec: "Clear all resumes"
lowmem: none
</source>
<dest>
*: none
swcodec: "Clear all resumes"
lowmem: none
</dest>
<voice>
*: none
swcodec: "Clear all resumes"
lowmem: none
</voice>
</phrase>
<phrase>
id: LANG_UNAVAILABLE
desc: in mpegplayer settings
user: core
<source>
*: none
swcodec: "Unavailable"
lowmem: none
</source>
<dest>
*: none
swcodec: "Unavailable"
lowmem: none
</dest>
<voice>
*: none
swcodec: "Unavailable"
lowmem: none
</voice>
</phrase>

View file

@ -395,29 +395,20 @@ static struct configdata config[] =
}; };
static const struct opt_items noyes[2] = { static const struct opt_items noyes[2] = {
{ "No", -1 }, { STR(LANG_SET_BOOL_NO) },
{ "Yes", -1 }, { STR(LANG_SET_BOOL_YES) },
}; };
static const struct opt_items singleall[2] = { static const struct opt_items singleall[2] = {
{ "Single", -1 }, { STR(LANG_SINGLE) },
{ "All", -1 }, { STR(LANG_ALL) },
};
static const struct opt_items enabledisable[2] = {
{ "Disable", -1 },
{ "Enable", -1 },
}; };
static const struct opt_items globaloff[2] = { static const struct opt_items globaloff[2] = {
{ "Force off", -1 }, { STR(LANG_OFF) },
{ "Use sound setting", -1 }, { STR(LANG_USE_SOUND_SETTING) },
}; };
#ifdef HAVE_BACKLIGHT_BRIGHTNESS
#define BACKLIGHT_OPTION_DEFAULT "Use setting"
#endif
static void mpeg_settings(void); static void mpeg_settings(void);
static bool mpeg_set_option(const char* string, static bool mpeg_set_option(const char* string,
void* variable, void* variable,
@ -444,21 +435,28 @@ static bool mpeg_set_int(const char *string, const char *unit,
void (*function)(int), int step, void (*function)(int), int step,
int min, int min,
int max, int max,
const char* (*formatter)(char*, size_t, int, const char*)) const char* (*formatter)(char*, size_t, int, const char*),
int32_t (*get_talk_id)(int, int))
{ {
mpeg_sysevent_clear(); mpeg_sysevent_clear();
bool usb = rb->set_int(string, unit, voice_unit, variable, function, bool usb = rb->set_int_ex(string, unit, voice_unit, variable, function,
step, min, max, formatter); step, min, max, formatter, get_talk_id);
if (usb) if (usb)
mpeg_sysevent_set(); mpeg_sysevent_set();
return usb; return usb;
} }
#endif /* HAVE_BACKLIGHT_BRIGHTNESS */
#ifdef HAVE_BACKLIGHT_BRIGHTNESS static int32_t backlight_brightness_getlang(int value, int unit)
{
if (value < 0)
return LANG_USE_COMMON_SETTING;
return TALK_ID(value + MIN_BRIGHTNESS_SETTING, unit);
}
void mpeg_backlight_update_brightness(int value) void mpeg_backlight_update_brightness(int value)
{ {
if (value >= 0) if (value >= 0)
@ -483,7 +481,7 @@ static const char* backlight_brightness_formatter(char *buf, size_t length,
(void)input; (void)input;
if (value < 0) if (value < 0)
return BACKLIGHT_OPTION_DEFAULT; return rb->str(LANG_USE_COMMON_SETTING);
else else
rb->snprintf(buf, length, "%d", value + MIN_BRIGHTNESS_SETTING); rb->snprintf(buf, length, "%d", value + MIN_BRIGHTNESS_SETTING);
return buf; return buf;
@ -764,6 +762,7 @@ static int get_start_time(uint32_t duration)
uint32_t resume_time = settings.resume_time; uint32_t resume_time = settings.resume_time;
struct vo_rect rc_vid, rc_bound; struct vo_rect rc_vid, rc_bound;
uint32_t aspect_vid, aspect_bound; uint32_t aspect_vid, aspect_bound;
bool sliding = false;
enum state_enum slider_state = STATE0; enum state_enum slider_state = STATE0;
@ -937,7 +936,18 @@ static int get_start_time(uint32_t duration)
switch (slider_state) switch (slider_state)
{ {
case STATE0: case STATE0:
trigger_cpu_boost(); if (!sliding)
{
if (rb->global_settings->talk_menu)
{
rb->talk_disable(true);
#ifdef PLUGIN_USE_IRAM
mpegplayer_iram_restore();
#endif
}
trigger_cpu_boost();
sliding = true;
}
stream_seek(resume_time, SEEK_SET); stream_seek(resume_time, SEEK_SET);
show_loading(&rc_bound); show_loading(&rc_bound);
draw_slider(duration, resume_time, NULL); draw_slider(duration, resume_time, NULL);
@ -947,9 +957,21 @@ static int get_start_time(uint32_t duration)
case STATE1: case STATE1:
display_thumb_image(&rc_vid); display_thumb_image(&rc_vid);
slider_state = STATE2; slider_state = STATE2;
case STATE2:
cancel_cpu_boost();
tmo = TIMEOUT_BLOCK; tmo = TIMEOUT_BLOCK;
if (sliding)
{
cancel_cpu_boost();
if (rb->global_settings->talk_menu)
{
#ifdef PLUGIN_USE_IRAM
mpegplayer_iram_preserve();
#endif
rb->talk_disable(false);
rb->talk_value(resume_time / TS_SECOND, UNIT_TIME, false);
rb->talk_value(resume_time * 100 / duration, UNIT_PERCENT, true);
}
sliding = false;
}
default: default:
break; break;
} }
@ -977,19 +999,20 @@ static int show_start_menu(uint32_t duration)
int result = 0; int result = 0;
bool menu_quit = false; bool menu_quit = false;
/* add the resume time to the menu display */
static char resume_str[32];
char hms_str[32];
struct hms hms;
MENUITEM_STRINGLIST(menu, "Mpegplayer Menu", mpeg_sysevent_callback, MENUITEM_STRINGLIST(menu, "Mpegplayer Menu", mpeg_sysevent_callback,
"Play from beginning", resume_str, "Set start time", ID2P(LANG_RESTART_PLAYBACK),
"Settings", "Quit mpegplayer"); ID2P(LANG_RESUME_PLAYBACK),
ID2P(LANG_SET_RESUME_TIME),
ID2P(LANG_SETTINGS),
ID2P(LANG_MENU_QUIT));
ts_to_hms(settings.resume_time, &hms); if (rb->global_settings->talk_menu)
hms_format(hms_str, sizeof(hms_str), &hms); {
rb->snprintf(resume_str, sizeof (resume_str), #ifdef PLUGIN_USE_IRAM
"Resume at: %s", hms_str); mpegplayer_iram_preserve();
#endif
rb->talk_disable(false);
}
rb->button_clear_queue(); rb->button_clear_queue();
@ -1012,7 +1035,7 @@ static int show_start_menu(uint32_t duration)
case MPEG_START_SEEK: case MPEG_START_SEEK:
if (!stream_can_seek()) if (!stream_can_seek())
{ {
rb->splash(HZ, "Unavailable"); rb->splash(HZ, ID2P(LANG_UNAVAILABLE));
break; break;
} }
@ -1039,6 +1062,14 @@ static int show_start_menu(uint32_t duration)
} }
} }
if (rb->global_settings->talk_menu)
{
rb->talk_disable(true);
#ifdef PLUGIN_USE_IRAM
mpegplayer_iram_restore();
#endif
}
return result; return result;
} }
@ -1069,7 +1100,17 @@ int mpeg_menu(void)
int result; int result;
MENUITEM_STRINGLIST(menu, "Mpegplayer Menu", mpeg_sysevent_callback, MENUITEM_STRINGLIST(menu, "Mpegplayer Menu", mpeg_sysevent_callback,
"Settings", "Resume playback", "Quit mpegplayer"); ID2P(LANG_SETTINGS),
ID2P(LANG_RESUME_PLAYBACK),
ID2P(LANG_MENU_QUIT));
if (rb->global_settings->talk_menu)
{
#ifdef PLUGIN_USE_IRAM
mpegplayer_iram_preserve();
#endif
rb->talk_disable(false);
}
rb->button_clear_queue(); rb->button_clear_queue();
@ -1096,6 +1137,14 @@ int mpeg_menu(void)
if (mpeg_sysevent() != 0) if (mpeg_sysevent() != 0)
result = MPEG_MENU_QUIT; result = MPEG_MENU_QUIT;
if (rb->global_settings->talk_menu)
{
rb->talk_disable(true);
#ifdef PLUGIN_USE_IRAM
mpegplayer_iram_restore();
#endif
}
return result; return result;
} }
@ -1107,11 +1156,13 @@ static void display_options(void)
MENUITEM_STRINGLIST(menu, "Display Options", mpeg_sysevent_callback, MENUITEM_STRINGLIST(menu, "Display Options", mpeg_sysevent_callback,
#if MPEG_OPTION_DITHERING_ENABLED #if MPEG_OPTION_DITHERING_ENABLED
"Dithering", ID2P(LANG_DITHERING),
#endif #endif
"Display FPS", "Limit FPS", "Skip frames", ID2P(LANG_DISPLAY_FPS),
ID2P(LANG_LIMIT_FPS),
ID2P(LANG_SKIP_FRAMES),
#ifdef HAVE_BACKLIGHT_BRIGHTNESS #ifdef HAVE_BACKLIGHT_BRIGHTNESS
"Backlight brightness", ID2P(LANG_BACKLIGHT_BRIGHTNESS),
#endif #endif
); );
@ -1127,7 +1178,7 @@ static void display_options(void)
#if MPEG_OPTION_DITHERING_ENABLED #if MPEG_OPTION_DITHERING_ENABLED
case MPEG_OPTION_DITHERING: case MPEG_OPTION_DITHERING:
result = (settings.displayoptions & LCD_YUV_DITHER) ? 1 : 0; result = (settings.displayoptions & LCD_YUV_DITHER) ? 1 : 0;
mpeg_set_option("Dithering", &result, INT, noyes, 2, NULL); mpeg_set_option(rb->str(LANG_DITHERING), &result, INT, noyes, 2, NULL);
settings.displayoptions = settings.displayoptions =
(settings.displayoptions & ~LCD_YUV_DITHER) (settings.displayoptions & ~LCD_YUV_DITHER)
| ((result != 0) ? LCD_YUV_DITHER : 0); | ((result != 0) ? LCD_YUV_DITHER : 0);
@ -1136,17 +1187,17 @@ static void display_options(void)
#endif /* MPEG_OPTION_DITHERING_ENABLED */ #endif /* MPEG_OPTION_DITHERING_ENABLED */
case MPEG_OPTION_DISPLAY_FPS: case MPEG_OPTION_DISPLAY_FPS:
mpeg_set_option("Display FPS", &settings.showfps, INT, mpeg_set_option(rb->str(LANG_DISPLAY_FPS), &settings.showfps, INT,
noyes, 2, NULL); noyes, 2, NULL);
break; break;
case MPEG_OPTION_LIMIT_FPS: case MPEG_OPTION_LIMIT_FPS:
mpeg_set_option("Limit FPS", &settings.limitfps, INT, mpeg_set_option(rb->str(LANG_LIMIT_FPS), &settings.limitfps, INT,
noyes, 2, NULL); noyes, 2, NULL);
break; break;
case MPEG_OPTION_SKIP_FRAMES: case MPEG_OPTION_SKIP_FRAMES:
mpeg_set_option("Skip frames", &settings.skipframes, INT, mpeg_set_option(rb->str(LANG_SKIP_FRAMES), &settings.skipframes, INT,
noyes, 2, NULL); noyes, 2, NULL);
break; break;
@ -1154,10 +1205,11 @@ static void display_options(void)
case MPEG_OPTION_BACKLIGHT_BRIGHTNESS: case MPEG_OPTION_BACKLIGHT_BRIGHTNESS:
result = settings.backlight_brightness; result = settings.backlight_brightness;
mpeg_backlight_update_brightness(result); mpeg_backlight_update_brightness(result);
mpeg_set_int("Backlight brightness", NULL, -1, &result, mpeg_set_int(rb->str(LANG_BACKLIGHT_BRIGHTNESS), NULL, UNIT_INT, &result,
backlight_brightness_function, 1, -1, backlight_brightness_function, 1, -1,
MAX_BRIGHTNESS_SETTING - MIN_BRIGHTNESS_SETTING, MAX_BRIGHTNESS_SETTING - MIN_BRIGHTNESS_SETTING,
backlight_brightness_formatter); backlight_brightness_formatter,
backlight_brightness_getlang);
settings.backlight_brightness = result; settings.backlight_brightness = result;
mpeg_backlight_update_brightness(-1); mpeg_backlight_update_brightness(-1);
break; break;
@ -1173,6 +1225,7 @@ static void display_options(void)
} }
} }
#if CONFIG_CODEC == SWCODEC
static void audio_options(void) static void audio_options(void)
{ {
int selected = 0; int selected = 0;
@ -1180,8 +1233,11 @@ static void audio_options(void)
bool menu_quit = false; bool menu_quit = false;
MENUITEM_STRINGLIST(menu, "Audio Options", mpeg_sysevent_callback, MENUITEM_STRINGLIST(menu, "Audio Options", mpeg_sysevent_callback,
"Tone Controls", "Channel Modes", "Crossfeed", ID2P(LANG_TONE_CONTROLS),
"Equalizer", "Dithering"); ID2P(LANG_CHANNEL_CONFIGURATION),
ID2P(LANG_CROSSFEED),
ID2P(LANG_EQUALIZER),
ID2P(LANG_DITHERING));
rb->button_clear_queue(); rb->button_clear_queue();
@ -1193,31 +1249,31 @@ static void audio_options(void)
switch (result) switch (result)
{ {
case MPEG_AUDIO_TONE_CONTROLS: case MPEG_AUDIO_TONE_CONTROLS:
mpeg_set_option("Tone Controls", &settings.tone_controls, INT, mpeg_set_option(rb->str(LANG_TONE_CONTROLS), &settings.tone_controls, INT,
globaloff, 2, NULL); globaloff, 2, NULL);
sync_audio_setting(result, false); sync_audio_setting(result, false);
break; break;
case MPEG_AUDIO_CHANNEL_MODES: case MPEG_AUDIO_CHANNEL_MODES:
mpeg_set_option("Channel Modes", &settings.channel_modes, mpeg_set_option(rb->str(LANG_CHANNEL_CONFIGURATION), &settings.channel_modes,
INT, globaloff, 2, NULL); INT, globaloff, 2, NULL);
sync_audio_setting(result, false); sync_audio_setting(result, false);
break; break;
case MPEG_AUDIO_CROSSFEED: case MPEG_AUDIO_CROSSFEED:
mpeg_set_option("Crossfeed", &settings.crossfeed, INT, mpeg_set_option(rb->str(LANG_CROSSFEED), &settings.crossfeed, INT,
globaloff, 2, NULL); globaloff, 2, NULL);
sync_audio_setting(result, false); sync_audio_setting(result, false);
break; break;
case MPEG_AUDIO_EQUALIZER: case MPEG_AUDIO_EQUALIZER:
mpeg_set_option("Equalizer", &settings.equalizer, INT, mpeg_set_option(rb->str(LANG_EQUALIZER), &settings.equalizer, INT,
globaloff, 2, NULL); globaloff, 2, NULL);
sync_audio_setting(result, false); sync_audio_setting(result, false);
break; break;
case MPEG_AUDIO_DITHERING: case MPEG_AUDIO_DITHERING:
mpeg_set_option("Dithering", &settings.dithering, INT, mpeg_set_option(rb->str(LANG_DITHERING), &settings.dithering, INT,
globaloff, 2, NULL); globaloff, 2, NULL);
sync_audio_setting(result, false); sync_audio_setting(result, false);
break; break;
@ -1231,21 +1287,22 @@ static void audio_options(void)
menu_quit = true; menu_quit = true;
} }
} }
#endif
static void resume_options(void) static void resume_options(void)
{ {
static const struct opt_items items[MPEG_RESUME_NUM_OPTIONS] = { static const struct opt_items items[MPEG_RESUME_NUM_OPTIONS] = {
[MPEG_RESUME_MENU_ALWAYS] = [MPEG_RESUME_MENU_ALWAYS] =
{ "Start menu", -1 }, { STR(LANG_FORCE_START_MENU) },
[MPEG_RESUME_MENU_IF_INCOMPLETE] = [MPEG_RESUME_MENU_IF_INCOMPLETE] =
{ "Start menu if not completed", -1 }, { STR(LANG_CONDITIONAL_START_MENU) },
[MPEG_RESUME_ALWAYS] = [MPEG_RESUME_ALWAYS] =
{ "Resume automatically", -1 }, { STR(LANG_AUTO_RESUME) },
[MPEG_RESUME_RESTART] = [MPEG_RESUME_RESTART] =
{ "Play from beginning", -1 }, { STR(LANG_RESTART_PLAYBACK) },
}; };
mpeg_set_option("Resume Options", &settings.resume_options, mpeg_set_option(rb->str(LANG_MENU_RESUME_OPTIONS), &settings.resume_options,
INT, items, MPEG_RESUME_NUM_OPTIONS, NULL); INT, items, MPEG_RESUME_NUM_OPTIONS, NULL);
} }
@ -1261,11 +1318,13 @@ static void mpeg_settings(void)
int selected = 0; int selected = 0;
int result; int result;
bool menu_quit = false; bool menu_quit = false;
static char clear_str[32];
MENUITEM_STRINGLIST(menu, "Settings", mpeg_sysevent_callback, MENUITEM_STRINGLIST(menu, "Settings", mpeg_sysevent_callback,
"Display Options", "Audio Options", ID2P(LANG_MENU_DISPLAY_OPTIONS),
"Resume Options", "Play Mode", clear_str); ID2P(LANG_MENU_AUDIO_OPTIONS),
ID2P(LANG_MENU_RESUME_OPTIONS),
ID2P(LANG_MENU_PLAY_MODE),
ID2P(LANG_CLEAR_ALL_RESUMES));
rb->button_clear_queue(); rb->button_clear_queue();
@ -1273,10 +1332,6 @@ static void mpeg_settings(void)
{ {
mpeg_sysevent_clear(); mpeg_sysevent_clear();
/* Format and add resume option to the menu display */
rb->snprintf(clear_str, sizeof(clear_str),
"Clear all resumes: %u", settings.resume_count);
result = rb->do_menu(&menu, &selected, NULL, false); result = rb->do_menu(&menu, &selected, NULL, false);
switch (result) switch (result)
@ -1294,7 +1349,7 @@ static void mpeg_settings(void)
break; break;
case MPEG_SETTING_PLAY_MODE: case MPEG_SETTING_PLAY_MODE:
mpeg_set_option("Play mode", &settings.play_mode, mpeg_set_option(rb->str(LANG_MENU_PLAY_MODE), &settings.play_mode,
INT, singleall, 2, NULL); INT, singleall, 2, NULL);
break; break;

View file

@ -634,6 +634,54 @@ static unsigned draw_blendcolor(unsigned c1, unsigned c2, unsigned char amount)
} }
#endif #endif
#ifdef PLUGIN_USE_IRAM
/* IRAM preserving mechanism to enable talking menus */
static char *iram_saved_copy;
extern char iramstart[], iramend[];
static void iram_saving_init(void)
{
#ifndef SIMULATOR
size_t size;
iram_saved_copy = (char *)rb->plugin_get_buffer(&size);
if (size >= (size_t)(iramend-iramstart))
iram_saved_copy += size - (size_t)(iramend - iramstart);
else
#endif
iram_saved_copy = NULL;
return;
}
void mpegplayer_iram_preserve(void)
{
if (iram_saved_copy)
{
rb->memcpy(iram_saved_copy, iramstart, iramend-iramstart);
#ifdef HAVE_CPUCACHE_INVALIDATE
/* make the icache (if it exists) up to date with the new code */
rb->cpucache_invalidate();
#endif /* HAVE_CPUCACHE_INVALIDATE */
}
return;
}
void mpegplayer_iram_restore(void)
{
if (iram_saved_copy)
{
rb->audio_hard_stop();
rb->memcpy(iramstart, iram_saved_copy, iramend-iramstart);
#ifdef HAVE_CPUCACHE_INVALIDATE
/* make the icache (if it exists) up to date with the new code */
rb->cpucache_invalidate();
#endif /* HAVE_CPUCACHE_INVALIDATE */
}
return;
}
#endif
/* Drawing functions that operate rotated on LCD_PORTRAIT displays - /* Drawing functions that operate rotated on LCD_PORTRAIT displays -
* most are just wrappers of lcd_* functions with transforms applied. * most are just wrappers of lcd_* functions with transforms applied.
* The origin is the upper-left corner of the OSD area */ * The origin is the upper-left corner of the OSD area */
@ -2369,6 +2417,10 @@ enum plugin_status plugin_start(const void* parameter)
int status = PLUGIN_OK; /* assume success */ int status = PLUGIN_OK; /* assume success */
bool quit = false; bool quit = false;
#if defined(PLUGIN_USE_IRAM) && !defined(SIMULATOR)
bool preserved_talk_state;
#endif
if (parameter == NULL) { if (parameter == NULL) {
/* No file = GTFO */ /* No file = GTFO */
rb->splash(HZ*2, "No File"); rb->splash(HZ*2, "No File");
@ -2378,6 +2430,16 @@ enum plugin_status plugin_start(const void* parameter)
/* Disable all talking before initializing IRAM */ /* Disable all talking before initializing IRAM */
rb->talk_disable(true); rb->talk_disable(true);
#ifdef PLUGIN_USE_IRAM
iram_saving_init();
#ifndef SIMULATOR
preserved_talk_state = rb->global_settings->talk_menu;
if (!iram_saved_copy)
rb->global_settings->talk_menu = false;
#endif
#endif
#ifdef HAVE_LCD_COLOR #ifdef HAVE_LCD_COLOR
rb->lcd_set_backdrop(NULL); rb->lcd_set_backdrop(NULL);
rb->lcd_set_foreground(LCD_WHITE); rb->lcd_set_foreground(LCD_WHITE);
@ -2528,6 +2590,11 @@ enum plugin_status plugin_start(const void* parameter)
stream_exit(); stream_exit();
#if defined(PLUGIN_USE_IRAM) && !defined(SIMULATOR)
if (!iram_saved_copy)
rb->global_settings->talk_menu = preserved_talk_state;
#endif
rb->talk_disable(false); rb->talk_disable(false);
/* Actually handle delayed processing of system events of interest /* Actually handle delayed processing of system events of interest

View file

@ -86,4 +86,10 @@
#define LCD_ENABLE_EVENT_0 MAKE_SYS_EVENT(SYS_EVENT_CLS_PRIVATE, 0) #define LCD_ENABLE_EVENT_0 MAKE_SYS_EVENT(SYS_EVENT_CLS_PRIVATE, 0)
#define LCD_ENABLE_EVENT_1 MAKE_SYS_EVENT(SYS_EVENT_CLS_PRIVATE, 1) #define LCD_ENABLE_EVENT_1 MAKE_SYS_EVENT(SYS_EVENT_CLS_PRIVATE, 1)
#ifdef PLUGIN_USE_IRAM
/* IRAM preserving mechanism to enable talking menus */
extern void mpegplayer_iram_preserve(void);
extern void mpegplayer_iram_restore(void);
#endif
#endif /* MPEGPLAYER_H */ #endif /* MPEGPLAYER_H */

View file

@ -384,11 +384,13 @@ bool pcm_output_init(void)
old_sampr = rb->mixer_get_frequency(); old_sampr = rb->mixer_get_frequency();
rb->mixer_set_frequency(CLOCK_RATE); rb->mixer_set_frequency(CLOCK_RATE);
rb->pcmbuf_fade(false, true);
return true; return true;
} }
void pcm_output_exit(void) void pcm_output_exit(void)
{ {
rb->pcmbuf_fade(false, false);
if (old_sampr != 0) if (old_sampr != 0)
rb->mixer_set_frequency(old_sampr); rb->mixer_set_frequency(old_sampr);
} }