diff options
author | Solomon Peachy <pizza@shaftnet.org> | 2019-07-20 17:32:49 -0400 |
---|---|---|
committer | Solomon Peachy <pizza@shaftnet.org> | 2019-08-04 22:47:00 +0200 |
commit | 4ad76652ef19daf6404e8a97eb73aeadfe1e66fb (patch) | |
tree | b54be971440fcd96879973f088bd20e00e687c7f /apps/plugins | |
parent | 7234de58ae69b4ecbd97efd77a61bf0cfc1737bf (diff) | |
download | rockbox-4ad76652ef19daf6404e8a97eb73aeadfe1e66fb.tar.gz rockbox-4ad76652ef19daf6404e8a97eb73aeadfe1e66fb.zip |
Speech feedback in mpegplayer menus
Patch by Igor Poretsky
Change-Id: Idc6920e17be6537557f2b1cf00f7e559e30b45e8
Diffstat (limited to 'apps/plugins')
-rw-r--r-- | apps/plugins/mpegplayer/mpeg_settings.c | 187 | ||||
-rw-r--r-- | apps/plugins/mpegplayer/mpegplayer.c | 67 | ||||
-rw-r--r-- | apps/plugins/mpegplayer/mpegplayer.h | 6 | ||||
-rw-r--r-- | apps/plugins/mpegplayer/pcm_output.c | 2 |
4 files changed, 196 insertions, 66 deletions
diff --git a/apps/plugins/mpegplayer/mpeg_settings.c b/apps/plugins/mpegplayer/mpeg_settings.c index d6b4fd4b84..8427db12b4 100644 --- a/apps/plugins/mpegplayer/mpeg_settings.c +++ b/apps/plugins/mpegplayer/mpeg_settings.c | |||
@@ -395,29 +395,20 @@ static struct configdata config[] = | |||
395 | }; | 395 | }; |
396 | 396 | ||
397 | static const struct opt_items noyes[2] = { | 397 | static const struct opt_items noyes[2] = { |
398 | { "No", -1 }, | 398 | { STR(LANG_SET_BOOL_NO) }, |
399 | { "Yes", -1 }, | 399 | { STR(LANG_SET_BOOL_YES) }, |
400 | }; | 400 | }; |
401 | 401 | ||
402 | static const struct opt_items singleall[2] = { | 402 | static const struct opt_items singleall[2] = { |
403 | { "Single", -1 }, | 403 | { STR(LANG_SINGLE) }, |
404 | { "All", -1 }, | 404 | { STR(LANG_ALL) }, |
405 | }; | ||
406 | |||
407 | static const struct opt_items enabledisable[2] = { | ||
408 | { "Disable", -1 }, | ||
409 | { "Enable", -1 }, | ||
410 | }; | 405 | }; |
411 | 406 | ||
412 | static const struct opt_items globaloff[2] = { | 407 | static const struct opt_items globaloff[2] = { |
413 | { "Force off", -1 }, | 408 | { STR(LANG_OFF) }, |
414 | { "Use sound setting", -1 }, | 409 | { STR(LANG_USE_SOUND_SETTING) }, |
415 | }; | 410 | }; |
416 | 411 | ||
417 | #ifdef HAVE_BACKLIGHT_BRIGHTNESS | ||
418 | #define BACKLIGHT_OPTION_DEFAULT "Use setting" | ||
419 | #endif | ||
420 | |||
421 | static void mpeg_settings(void); | 412 | static void mpeg_settings(void); |
422 | static bool mpeg_set_option(const char* string, | 413 | static bool mpeg_set_option(const char* string, |
423 | void* variable, | 414 | void* variable, |
@@ -444,21 +435,28 @@ static bool mpeg_set_int(const char *string, const char *unit, | |||
444 | void (*function)(int), int step, | 435 | void (*function)(int), int step, |
445 | int min, | 436 | int min, |
446 | int max, | 437 | int max, |
447 | const char* (*formatter)(char*, size_t, int, const char*)) | 438 | const char* (*formatter)(char*, size_t, int, const char*), |
439 | int32_t (*get_talk_id)(int, int)) | ||
448 | { | 440 | { |
449 | mpeg_sysevent_clear(); | 441 | mpeg_sysevent_clear(); |
450 | 442 | ||
451 | bool usb = rb->set_int(string, unit, voice_unit, variable, function, | 443 | bool usb = rb->set_int_ex(string, unit, voice_unit, variable, function, |
452 | step, min, max, formatter); | 444 | step, min, max, formatter, get_talk_id); |
453 | 445 | ||
454 | if (usb) | 446 | if (usb) |
455 | mpeg_sysevent_set(); | 447 | mpeg_sysevent_set(); |
456 | 448 | ||
457 | return usb; | 449 | return usb; |
458 | } | 450 | } |
459 | #endif /* HAVE_BACKLIGHT_BRIGHTNESS */ | ||
460 | 451 | ||
461 | #ifdef HAVE_BACKLIGHT_BRIGHTNESS | 452 | static int32_t backlight_brightness_getlang(int value, int unit) |
453 | { | ||
454 | if (value < 0) | ||
455 | return LANG_USE_COMMON_SETTING; | ||
456 | |||
457 | return TALK_ID(value + MIN_BRIGHTNESS_SETTING, unit); | ||
458 | } | ||
459 | |||
462 | void mpeg_backlight_update_brightness(int value) | 460 | void mpeg_backlight_update_brightness(int value) |
463 | { | 461 | { |
464 | if (value >= 0) | 462 | if (value >= 0) |
@@ -483,7 +481,7 @@ static const char* backlight_brightness_formatter(char *buf, size_t length, | |||
483 | (void)input; | 481 | (void)input; |
484 | 482 | ||
485 | if (value < 0) | 483 | if (value < 0) |
486 | return BACKLIGHT_OPTION_DEFAULT; | 484 | return rb->str(LANG_USE_COMMON_SETTING); |
487 | else | 485 | else |
488 | rb->snprintf(buf, length, "%d", value + MIN_BRIGHTNESS_SETTING); | 486 | rb->snprintf(buf, length, "%d", value + MIN_BRIGHTNESS_SETTING); |
489 | return buf; | 487 | return buf; |
@@ -764,6 +762,7 @@ static int get_start_time(uint32_t duration) | |||
764 | uint32_t resume_time = settings.resume_time; | 762 | uint32_t resume_time = settings.resume_time; |
765 | struct vo_rect rc_vid, rc_bound; | 763 | struct vo_rect rc_vid, rc_bound; |
766 | uint32_t aspect_vid, aspect_bound; | 764 | uint32_t aspect_vid, aspect_bound; |
765 | bool sliding = false; | ||
767 | 766 | ||
768 | enum state_enum slider_state = STATE0; | 767 | enum state_enum slider_state = STATE0; |
769 | 768 | ||
@@ -937,7 +936,18 @@ static int get_start_time(uint32_t duration) | |||
937 | switch (slider_state) | 936 | switch (slider_state) |
938 | { | 937 | { |
939 | case STATE0: | 938 | case STATE0: |
940 | trigger_cpu_boost(); | 939 | if (!sliding) |
940 | { | ||
941 | if (rb->global_settings->talk_menu) | ||
942 | { | ||
943 | rb->talk_disable(true); | ||
944 | #ifdef PLUGIN_USE_IRAM | ||
945 | mpegplayer_iram_restore(); | ||
946 | #endif | ||
947 | } | ||
948 | trigger_cpu_boost(); | ||
949 | sliding = true; | ||
950 | } | ||
941 | stream_seek(resume_time, SEEK_SET); | 951 | stream_seek(resume_time, SEEK_SET); |
942 | show_loading(&rc_bound); | 952 | show_loading(&rc_bound); |
943 | draw_slider(duration, resume_time, NULL); | 953 | draw_slider(duration, resume_time, NULL); |
@@ -947,9 +957,21 @@ static int get_start_time(uint32_t duration) | |||
947 | case STATE1: | 957 | case STATE1: |
948 | display_thumb_image(&rc_vid); | 958 | display_thumb_image(&rc_vid); |
949 | slider_state = STATE2; | 959 | slider_state = STATE2; |
950 | case STATE2: | ||
951 | cancel_cpu_boost(); | ||
952 | tmo = TIMEOUT_BLOCK; | 960 | tmo = TIMEOUT_BLOCK; |
961 | if (sliding) | ||
962 | { | ||
963 | cancel_cpu_boost(); | ||
964 | if (rb->global_settings->talk_menu) | ||
965 | { | ||
966 | #ifdef PLUGIN_USE_IRAM | ||
967 | mpegplayer_iram_preserve(); | ||
968 | #endif | ||
969 | rb->talk_disable(false); | ||
970 | rb->talk_value(resume_time / TS_SECOND, UNIT_TIME, false); | ||
971 | rb->talk_value(resume_time * 100 / duration, UNIT_PERCENT, true); | ||
972 | } | ||
973 | sliding = false; | ||
974 | } | ||
953 | default: | 975 | default: |
954 | break; | 976 | break; |
955 | } | 977 | } |
@@ -977,19 +999,20 @@ static int show_start_menu(uint32_t duration) | |||
977 | int result = 0; | 999 | int result = 0; |
978 | bool menu_quit = false; | 1000 | bool menu_quit = false; |
979 | 1001 | ||
980 | /* add the resume time to the menu display */ | ||
981 | static char resume_str[32]; | ||
982 | char hms_str[32]; | ||
983 | struct hms hms; | ||
984 | |||
985 | MENUITEM_STRINGLIST(menu, "Mpegplayer Menu", mpeg_sysevent_callback, | 1002 | MENUITEM_STRINGLIST(menu, "Mpegplayer Menu", mpeg_sysevent_callback, |
986 | "Play from beginning", resume_str, "Set start time", | 1003 | ID2P(LANG_RESTART_PLAYBACK), |
987 | "Settings", "Quit mpegplayer"); | 1004 | ID2P(LANG_RESUME_PLAYBACK), |
1005 | ID2P(LANG_SET_RESUME_TIME), | ||
1006 | ID2P(LANG_SETTINGS), | ||
1007 | ID2P(LANG_MENU_QUIT)); | ||
988 | 1008 | ||
989 | ts_to_hms(settings.resume_time, &hms); | 1009 | if (rb->global_settings->talk_menu) |
990 | hms_format(hms_str, sizeof(hms_str), &hms); | 1010 | { |
991 | rb->snprintf(resume_str, sizeof (resume_str), | 1011 | #ifdef PLUGIN_USE_IRAM |
992 | "Resume at: %s", hms_str); | 1012 | mpegplayer_iram_preserve(); |
1013 | #endif | ||
1014 | rb->talk_disable(false); | ||
1015 | } | ||
993 | 1016 | ||
994 | rb->button_clear_queue(); | 1017 | rb->button_clear_queue(); |
995 | 1018 | ||
@@ -1012,7 +1035,7 @@ static int show_start_menu(uint32_t duration) | |||
1012 | case MPEG_START_SEEK: | 1035 | case MPEG_START_SEEK: |
1013 | if (!stream_can_seek()) | 1036 | if (!stream_can_seek()) |
1014 | { | 1037 | { |
1015 | rb->splash(HZ, "Unavailable"); | 1038 | rb->splash(HZ, ID2P(LANG_UNAVAILABLE)); |
1016 | break; | 1039 | break; |
1017 | } | 1040 | } |
1018 | 1041 | ||
@@ -1039,6 +1062,14 @@ static int show_start_menu(uint32_t duration) | |||
1039 | } | 1062 | } |
1040 | } | 1063 | } |
1041 | 1064 | ||
1065 | if (rb->global_settings->talk_menu) | ||
1066 | { | ||
1067 | rb->talk_disable(true); | ||
1068 | #ifdef PLUGIN_USE_IRAM | ||
1069 | mpegplayer_iram_restore(); | ||
1070 | #endif | ||
1071 | } | ||
1072 | |||
1042 | return result; | 1073 | return result; |
1043 | } | 1074 | } |
1044 | 1075 | ||
@@ -1069,7 +1100,17 @@ int mpeg_menu(void) | |||
1069 | int result; | 1100 | int result; |
1070 | 1101 | ||
1071 | MENUITEM_STRINGLIST(menu, "Mpegplayer Menu", mpeg_sysevent_callback, | 1102 | MENUITEM_STRINGLIST(menu, "Mpegplayer Menu", mpeg_sysevent_callback, |
1072 | "Settings", "Resume playback", "Quit mpegplayer"); | 1103 | ID2P(LANG_SETTINGS), |
1104 | ID2P(LANG_RESUME_PLAYBACK), | ||
1105 | ID2P(LANG_MENU_QUIT)); | ||
1106 | |||
1107 | if (rb->global_settings->talk_menu) | ||
1108 | { | ||
1109 | #ifdef PLUGIN_USE_IRAM | ||
1110 | mpegplayer_iram_preserve(); | ||
1111 | #endif | ||
1112 | rb->talk_disable(false); | ||
1113 | } | ||
1073 | 1114 | ||
1074 | rb->button_clear_queue(); | 1115 | rb->button_clear_queue(); |
1075 | 1116 | ||
@@ -1096,6 +1137,14 @@ int mpeg_menu(void) | |||
1096 | if (mpeg_sysevent() != 0) | 1137 | if (mpeg_sysevent() != 0) |
1097 | result = MPEG_MENU_QUIT; | 1138 | result = MPEG_MENU_QUIT; |
1098 | 1139 | ||
1140 | if (rb->global_settings->talk_menu) | ||
1141 | { | ||
1142 | rb->talk_disable(true); | ||
1143 | #ifdef PLUGIN_USE_IRAM | ||
1144 | mpegplayer_iram_restore(); | ||
1145 | #endif | ||
1146 | } | ||
1147 | |||
1099 | return result; | 1148 | return result; |
1100 | } | 1149 | } |
1101 | 1150 | ||
@@ -1107,11 +1156,13 @@ static void display_options(void) | |||
1107 | 1156 | ||
1108 | MENUITEM_STRINGLIST(menu, "Display Options", mpeg_sysevent_callback, | 1157 | MENUITEM_STRINGLIST(menu, "Display Options", mpeg_sysevent_callback, |
1109 | #if MPEG_OPTION_DITHERING_ENABLED | 1158 | #if MPEG_OPTION_DITHERING_ENABLED |
1110 | "Dithering", | 1159 | ID2P(LANG_DITHERING), |
1111 | #endif | 1160 | #endif |
1112 | "Display FPS", "Limit FPS", "Skip frames", | 1161 | ID2P(LANG_DISPLAY_FPS), |
1162 | ID2P(LANG_LIMIT_FPS), | ||
1163 | ID2P(LANG_SKIP_FRAMES), | ||
1113 | #ifdef HAVE_BACKLIGHT_BRIGHTNESS | 1164 | #ifdef HAVE_BACKLIGHT_BRIGHTNESS |
1114 | "Backlight brightness", | 1165 | ID2P(LANG_BACKLIGHT_BRIGHTNESS), |
1115 | #endif | 1166 | #endif |
1116 | ); | 1167 | ); |
1117 | 1168 | ||
@@ -1127,7 +1178,7 @@ static void display_options(void) | |||
1127 | #if MPEG_OPTION_DITHERING_ENABLED | 1178 | #if MPEG_OPTION_DITHERING_ENABLED |
1128 | case MPEG_OPTION_DITHERING: | 1179 | case MPEG_OPTION_DITHERING: |
1129 | result = (settings.displayoptions & LCD_YUV_DITHER) ? 1 : 0; | 1180 | result = (settings.displayoptions & LCD_YUV_DITHER) ? 1 : 0; |
1130 | mpeg_set_option("Dithering", &result, INT, noyes, 2, NULL); | 1181 | mpeg_set_option(rb->str(LANG_DITHERING), &result, INT, noyes, 2, NULL); |
1131 | settings.displayoptions = | 1182 | settings.displayoptions = |
1132 | (settings.displayoptions & ~LCD_YUV_DITHER) | 1183 | (settings.displayoptions & ~LCD_YUV_DITHER) |
1133 | | ((result != 0) ? LCD_YUV_DITHER : 0); | 1184 | | ((result != 0) ? LCD_YUV_DITHER : 0); |
@@ -1136,17 +1187,17 @@ static void display_options(void) | |||
1136 | #endif /* MPEG_OPTION_DITHERING_ENABLED */ | 1187 | #endif /* MPEG_OPTION_DITHERING_ENABLED */ |
1137 | 1188 | ||
1138 | case MPEG_OPTION_DISPLAY_FPS: | 1189 | case MPEG_OPTION_DISPLAY_FPS: |
1139 | mpeg_set_option("Display FPS", &settings.showfps, INT, | 1190 | mpeg_set_option(rb->str(LANG_DISPLAY_FPS), &settings.showfps, INT, |
1140 | noyes, 2, NULL); | 1191 | noyes, 2, NULL); |
1141 | break; | 1192 | break; |
1142 | 1193 | ||
1143 | case MPEG_OPTION_LIMIT_FPS: | 1194 | case MPEG_OPTION_LIMIT_FPS: |
1144 | mpeg_set_option("Limit FPS", &settings.limitfps, INT, | 1195 | mpeg_set_option(rb->str(LANG_LIMIT_FPS), &settings.limitfps, INT, |
1145 | noyes, 2, NULL); | 1196 | noyes, 2, NULL); |
1146 | break; | 1197 | break; |
1147 | 1198 | ||
1148 | case MPEG_OPTION_SKIP_FRAMES: | 1199 | case MPEG_OPTION_SKIP_FRAMES: |
1149 | mpeg_set_option("Skip frames", &settings.skipframes, INT, | 1200 | mpeg_set_option(rb->str(LANG_SKIP_FRAMES), &settings.skipframes, INT, |
1150 | noyes, 2, NULL); | 1201 | noyes, 2, NULL); |
1151 | break; | 1202 | break; |
1152 | 1203 | ||
@@ -1154,10 +1205,11 @@ static void display_options(void) | |||
1154 | case MPEG_OPTION_BACKLIGHT_BRIGHTNESS: | 1205 | case MPEG_OPTION_BACKLIGHT_BRIGHTNESS: |
1155 | result = settings.backlight_brightness; | 1206 | result = settings.backlight_brightness; |
1156 | mpeg_backlight_update_brightness(result); | 1207 | mpeg_backlight_update_brightness(result); |
1157 | mpeg_set_int("Backlight brightness", NULL, -1, &result, | 1208 | mpeg_set_int(rb->str(LANG_BACKLIGHT_BRIGHTNESS), NULL, UNIT_INT, &result, |
1158 | backlight_brightness_function, 1, -1, | 1209 | backlight_brightness_function, 1, -1, |
1159 | MAX_BRIGHTNESS_SETTING - MIN_BRIGHTNESS_SETTING, | 1210 | MAX_BRIGHTNESS_SETTING - MIN_BRIGHTNESS_SETTING, |
1160 | backlight_brightness_formatter); | 1211 | backlight_brightness_formatter, |
1212 | backlight_brightness_getlang); | ||
1161 | settings.backlight_brightness = result; | 1213 | settings.backlight_brightness = result; |
1162 | mpeg_backlight_update_brightness(-1); | 1214 | mpeg_backlight_update_brightness(-1); |
1163 | break; | 1215 | break; |
@@ -1173,6 +1225,7 @@ static void display_options(void) | |||
1173 | } | 1225 | } |
1174 | } | 1226 | } |
1175 | 1227 | ||
1228 | #if CONFIG_CODEC == SWCODEC | ||
1176 | static void audio_options(void) | 1229 | static void audio_options(void) |
1177 | { | 1230 | { |
1178 | int selected = 0; | 1231 | int selected = 0; |
@@ -1180,8 +1233,11 @@ static void audio_options(void) | |||
1180 | bool menu_quit = false; | 1233 | bool menu_quit = false; |
1181 | 1234 | ||
1182 | MENUITEM_STRINGLIST(menu, "Audio Options", mpeg_sysevent_callback, | 1235 | MENUITEM_STRINGLIST(menu, "Audio Options", mpeg_sysevent_callback, |
1183 | "Tone Controls", "Channel Modes", "Crossfeed", | 1236 | ID2P(LANG_TONE_CONTROLS), |
1184 | "Equalizer", "Dithering"); | 1237 | ID2P(LANG_CHANNEL_CONFIGURATION), |
1238 | ID2P(LANG_CROSSFEED), | ||
1239 | ID2P(LANG_EQUALIZER), | ||
1240 | ID2P(LANG_DITHERING)); | ||
1185 | 1241 | ||
1186 | rb->button_clear_queue(); | 1242 | rb->button_clear_queue(); |
1187 | 1243 | ||
@@ -1193,31 +1249,31 @@ static void audio_options(void) | |||
1193 | switch (result) | 1249 | switch (result) |
1194 | { | 1250 | { |
1195 | case MPEG_AUDIO_TONE_CONTROLS: | 1251 | case MPEG_AUDIO_TONE_CONTROLS: |
1196 | mpeg_set_option("Tone Controls", &settings.tone_controls, INT, | 1252 | mpeg_set_option(rb->str(LANG_TONE_CONTROLS), &settings.tone_controls, INT, |
1197 | globaloff, 2, NULL); | 1253 | globaloff, 2, NULL); |
1198 | sync_audio_setting(result, false); | 1254 | sync_audio_setting(result, false); |
1199 | break; | 1255 | break; |
1200 | 1256 | ||
1201 | case MPEG_AUDIO_CHANNEL_MODES: | 1257 | case MPEG_AUDIO_CHANNEL_MODES: |
1202 | mpeg_set_option("Channel Modes", &settings.channel_modes, | 1258 | mpeg_set_option(rb->str(LANG_CHANNEL_CONFIGURATION), &settings.channel_modes, |
1203 | INT, globaloff, 2, NULL); | 1259 | INT, globaloff, 2, NULL); |
1204 | sync_audio_setting(result, false); | 1260 | sync_audio_setting(result, false); |
1205 | break; | 1261 | break; |
1206 | 1262 | ||
1207 | case MPEG_AUDIO_CROSSFEED: | 1263 | case MPEG_AUDIO_CROSSFEED: |
1208 | mpeg_set_option("Crossfeed", &settings.crossfeed, INT, | 1264 | mpeg_set_option(rb->str(LANG_CROSSFEED), &settings.crossfeed, INT, |
1209 | globaloff, 2, NULL); | 1265 | globaloff, 2, NULL); |
1210 | sync_audio_setting(result, false); | 1266 | sync_audio_setting(result, false); |
1211 | break; | 1267 | break; |
1212 | 1268 | ||
1213 | case MPEG_AUDIO_EQUALIZER: | 1269 | case MPEG_AUDIO_EQUALIZER: |
1214 | mpeg_set_option("Equalizer", &settings.equalizer, INT, | 1270 | mpeg_set_option(rb->str(LANG_EQUALIZER), &settings.equalizer, INT, |
1215 | globaloff, 2, NULL); | 1271 | globaloff, 2, NULL); |
1216 | sync_audio_setting(result, false); | 1272 | sync_audio_setting(result, false); |
1217 | break; | 1273 | break; |
1218 | 1274 | ||
1219 | case MPEG_AUDIO_DITHERING: | 1275 | case MPEG_AUDIO_DITHERING: |
1220 | mpeg_set_option("Dithering", &settings.dithering, INT, | 1276 | mpeg_set_option(rb->str(LANG_DITHERING), &settings.dithering, INT, |
1221 | globaloff, 2, NULL); | 1277 | globaloff, 2, NULL); |
1222 | sync_audio_setting(result, false); | 1278 | sync_audio_setting(result, false); |
1223 | break; | 1279 | break; |
@@ -1231,21 +1287,22 @@ static void audio_options(void) | |||
1231 | menu_quit = true; | 1287 | menu_quit = true; |
1232 | } | 1288 | } |
1233 | } | 1289 | } |
1290 | #endif | ||
1234 | 1291 | ||
1235 | static void resume_options(void) | 1292 | static void resume_options(void) |
1236 | { | 1293 | { |
1237 | static const struct opt_items items[MPEG_RESUME_NUM_OPTIONS] = { | 1294 | static const struct opt_items items[MPEG_RESUME_NUM_OPTIONS] = { |
1238 | [MPEG_RESUME_MENU_ALWAYS] = | 1295 | [MPEG_RESUME_MENU_ALWAYS] = |
1239 | { "Start menu", -1 }, | 1296 | { STR(LANG_FORCE_START_MENU) }, |
1240 | [MPEG_RESUME_MENU_IF_INCOMPLETE] = | 1297 | [MPEG_RESUME_MENU_IF_INCOMPLETE] = |
1241 | { "Start menu if not completed", -1 }, | 1298 | { STR(LANG_CONDITIONAL_START_MENU) }, |
1242 | [MPEG_RESUME_ALWAYS] = | 1299 | [MPEG_RESUME_ALWAYS] = |
1243 | { "Resume automatically", -1 }, | 1300 | { STR(LANG_AUTO_RESUME) }, |
1244 | [MPEG_RESUME_RESTART] = | 1301 | [MPEG_RESUME_RESTART] = |
1245 | { "Play from beginning", -1 }, | 1302 | { STR(LANG_RESTART_PLAYBACK) }, |
1246 | }; | 1303 | }; |
1247 | 1304 | ||
1248 | mpeg_set_option("Resume Options", &settings.resume_options, | 1305 | mpeg_set_option(rb->str(LANG_MENU_RESUME_OPTIONS), &settings.resume_options, |
1249 | INT, items, MPEG_RESUME_NUM_OPTIONS, NULL); | 1306 | INT, items, MPEG_RESUME_NUM_OPTIONS, NULL); |
1250 | } | 1307 | } |
1251 | 1308 | ||
@@ -1261,11 +1318,13 @@ static void mpeg_settings(void) | |||
1261 | int selected = 0; | 1318 | int selected = 0; |
1262 | int result; | 1319 | int result; |
1263 | bool menu_quit = false; | 1320 | bool menu_quit = false; |
1264 | static char clear_str[32]; | ||
1265 | 1321 | ||
1266 | MENUITEM_STRINGLIST(menu, "Settings", mpeg_sysevent_callback, | 1322 | MENUITEM_STRINGLIST(menu, "Settings", mpeg_sysevent_callback, |
1267 | "Display Options", "Audio Options", | 1323 | ID2P(LANG_MENU_DISPLAY_OPTIONS), |
1268 | "Resume Options", "Play Mode", clear_str); | 1324 | ID2P(LANG_MENU_AUDIO_OPTIONS), |
1325 | ID2P(LANG_MENU_RESUME_OPTIONS), | ||
1326 | ID2P(LANG_MENU_PLAY_MODE), | ||
1327 | ID2P(LANG_CLEAR_ALL_RESUMES)); | ||
1269 | 1328 | ||
1270 | rb->button_clear_queue(); | 1329 | rb->button_clear_queue(); |
1271 | 1330 | ||
@@ -1273,10 +1332,6 @@ static void mpeg_settings(void) | |||
1273 | { | 1332 | { |
1274 | mpeg_sysevent_clear(); | 1333 | mpeg_sysevent_clear(); |
1275 | 1334 | ||
1276 | /* Format and add resume option to the menu display */ | ||
1277 | rb->snprintf(clear_str, sizeof(clear_str), | ||
1278 | "Clear all resumes: %u", settings.resume_count); | ||
1279 | |||
1280 | result = rb->do_menu(&menu, &selected, NULL, false); | 1335 | result = rb->do_menu(&menu, &selected, NULL, false); |
1281 | 1336 | ||
1282 | switch (result) | 1337 | switch (result) |
@@ -1294,7 +1349,7 @@ static void mpeg_settings(void) | |||
1294 | break; | 1349 | break; |
1295 | 1350 | ||
1296 | case MPEG_SETTING_PLAY_MODE: | 1351 | case MPEG_SETTING_PLAY_MODE: |
1297 | mpeg_set_option("Play mode", &settings.play_mode, | 1352 | mpeg_set_option(rb->str(LANG_MENU_PLAY_MODE), &settings.play_mode, |
1298 | INT, singleall, 2, NULL); | 1353 | INT, singleall, 2, NULL); |
1299 | break; | 1354 | break; |
1300 | 1355 | ||
diff --git a/apps/plugins/mpegplayer/mpegplayer.c b/apps/plugins/mpegplayer/mpegplayer.c index 6a33a544db..39ea484ff2 100644 --- a/apps/plugins/mpegplayer/mpegplayer.c +++ b/apps/plugins/mpegplayer/mpegplayer.c | |||
@@ -634,6 +634,54 @@ static unsigned draw_blendcolor(unsigned c1, unsigned c2, unsigned char amount) | |||
634 | } | 634 | } |
635 | #endif | 635 | #endif |
636 | 636 | ||
637 | #ifdef PLUGIN_USE_IRAM | ||
638 | /* IRAM preserving mechanism to enable talking menus */ | ||
639 | static char *iram_saved_copy; | ||
640 | extern char iramstart[], iramend[]; | ||
641 | |||
642 | static void iram_saving_init(void) | ||
643 | { | ||
644 | #ifndef SIMULATOR | ||
645 | size_t size; | ||
646 | iram_saved_copy = (char *)rb->plugin_get_buffer(&size); | ||
647 | |||
648 | if (size >= (size_t)(iramend-iramstart)) | ||
649 | iram_saved_copy += size - (size_t)(iramend - iramstart); | ||
650 | else | ||
651 | #endif | ||
652 | iram_saved_copy = NULL; | ||
653 | |||
654 | return; | ||
655 | } | ||
656 | |||
657 | void mpegplayer_iram_preserve(void) | ||
658 | { | ||
659 | if (iram_saved_copy) | ||
660 | { | ||
661 | rb->memcpy(iram_saved_copy, iramstart, iramend-iramstart); | ||
662 | #ifdef HAVE_CPUCACHE_INVALIDATE | ||
663 | /* make the icache (if it exists) up to date with the new code */ | ||
664 | rb->cpucache_invalidate(); | ||
665 | #endif /* HAVE_CPUCACHE_INVALIDATE */ | ||
666 | } | ||
667 | return; | ||
668 | } | ||
669 | |||
670 | void mpegplayer_iram_restore(void) | ||
671 | { | ||
672 | if (iram_saved_copy) | ||
673 | { | ||
674 | rb->audio_hard_stop(); | ||
675 | rb->memcpy(iramstart, iram_saved_copy, iramend-iramstart); | ||
676 | #ifdef HAVE_CPUCACHE_INVALIDATE | ||
677 | /* make the icache (if it exists) up to date with the new code */ | ||
678 | rb->cpucache_invalidate(); | ||
679 | #endif /* HAVE_CPUCACHE_INVALIDATE */ | ||
680 | } | ||
681 | return; | ||
682 | } | ||
683 | #endif | ||
684 | |||
637 | /* Drawing functions that operate rotated on LCD_PORTRAIT displays - | 685 | /* Drawing functions that operate rotated on LCD_PORTRAIT displays - |
638 | * most are just wrappers of lcd_* functions with transforms applied. | 686 | * most are just wrappers of lcd_* functions with transforms applied. |
639 | * The origin is the upper-left corner of the OSD area */ | 687 | * The origin is the upper-left corner of the OSD area */ |
@@ -2369,6 +2417,10 @@ enum plugin_status plugin_start(const void* parameter) | |||
2369 | int status = PLUGIN_OK; /* assume success */ | 2417 | int status = PLUGIN_OK; /* assume success */ |
2370 | bool quit = false; | 2418 | bool quit = false; |
2371 | 2419 | ||
2420 | #if defined(PLUGIN_USE_IRAM) && !defined(SIMULATOR) | ||
2421 | bool preserved_talk_state; | ||
2422 | #endif | ||
2423 | |||
2372 | if (parameter == NULL) { | 2424 | if (parameter == NULL) { |
2373 | /* No file = GTFO */ | 2425 | /* No file = GTFO */ |
2374 | rb->splash(HZ*2, "No File"); | 2426 | rb->splash(HZ*2, "No File"); |
@@ -2378,6 +2430,16 @@ enum plugin_status plugin_start(const void* parameter) | |||
2378 | /* Disable all talking before initializing IRAM */ | 2430 | /* Disable all talking before initializing IRAM */ |
2379 | rb->talk_disable(true); | 2431 | rb->talk_disable(true); |
2380 | 2432 | ||
2433 | #ifdef PLUGIN_USE_IRAM | ||
2434 | iram_saving_init(); | ||
2435 | |||
2436 | #ifndef SIMULATOR | ||
2437 | preserved_talk_state = rb->global_settings->talk_menu; | ||
2438 | if (!iram_saved_copy) | ||
2439 | rb->global_settings->talk_menu = false; | ||
2440 | #endif | ||
2441 | #endif | ||
2442 | |||
2381 | #ifdef HAVE_LCD_COLOR | 2443 | #ifdef HAVE_LCD_COLOR |
2382 | rb->lcd_set_backdrop(NULL); | 2444 | rb->lcd_set_backdrop(NULL); |
2383 | rb->lcd_set_foreground(LCD_WHITE); | 2445 | rb->lcd_set_foreground(LCD_WHITE); |
@@ -2528,6 +2590,11 @@ enum plugin_status plugin_start(const void* parameter) | |||
2528 | 2590 | ||
2529 | stream_exit(); | 2591 | stream_exit(); |
2530 | 2592 | ||
2593 | #if defined(PLUGIN_USE_IRAM) && !defined(SIMULATOR) | ||
2594 | if (!iram_saved_copy) | ||
2595 | rb->global_settings->talk_menu = preserved_talk_state; | ||
2596 | #endif | ||
2597 | |||
2531 | rb->talk_disable(false); | 2598 | rb->talk_disable(false); |
2532 | 2599 | ||
2533 | /* Actually handle delayed processing of system events of interest | 2600 | /* Actually handle delayed processing of system events of interest |
diff --git a/apps/plugins/mpegplayer/mpegplayer.h b/apps/plugins/mpegplayer/mpegplayer.h index 4ddf0ca7b1..51fb9a8f8a 100644 --- a/apps/plugins/mpegplayer/mpegplayer.h +++ b/apps/plugins/mpegplayer/mpegplayer.h | |||
@@ -86,4 +86,10 @@ | |||
86 | #define LCD_ENABLE_EVENT_0 MAKE_SYS_EVENT(SYS_EVENT_CLS_PRIVATE, 0) | 86 | #define LCD_ENABLE_EVENT_0 MAKE_SYS_EVENT(SYS_EVENT_CLS_PRIVATE, 0) |
87 | #define LCD_ENABLE_EVENT_1 MAKE_SYS_EVENT(SYS_EVENT_CLS_PRIVATE, 1) | 87 | #define LCD_ENABLE_EVENT_1 MAKE_SYS_EVENT(SYS_EVENT_CLS_PRIVATE, 1) |
88 | 88 | ||
89 | #ifdef PLUGIN_USE_IRAM | ||
90 | /* IRAM preserving mechanism to enable talking menus */ | ||
91 | extern void mpegplayer_iram_preserve(void); | ||
92 | extern void mpegplayer_iram_restore(void); | ||
93 | #endif | ||
94 | |||
89 | #endif /* MPEGPLAYER_H */ | 95 | #endif /* MPEGPLAYER_H */ |
diff --git a/apps/plugins/mpegplayer/pcm_output.c b/apps/plugins/mpegplayer/pcm_output.c index 82e3584277..5e95d16316 100644 --- a/apps/plugins/mpegplayer/pcm_output.c +++ b/apps/plugins/mpegplayer/pcm_output.c | |||
@@ -384,11 +384,13 @@ bool pcm_output_init(void) | |||
384 | 384 | ||
385 | old_sampr = rb->mixer_get_frequency(); | 385 | old_sampr = rb->mixer_get_frequency(); |
386 | rb->mixer_set_frequency(CLOCK_RATE); | 386 | rb->mixer_set_frequency(CLOCK_RATE); |
387 | rb->pcmbuf_fade(false, true); | ||
387 | return true; | 388 | return true; |
388 | } | 389 | } |
389 | 390 | ||
390 | void pcm_output_exit(void) | 391 | void pcm_output_exit(void) |
391 | { | 392 | { |
393 | rb->pcmbuf_fade(false, false); | ||
392 | if (old_sampr != 0) | 394 | if (old_sampr != 0) |
393 | rb->mixer_set_frequency(old_sampr); | 395 | rb->mixer_set_frequency(old_sampr); |
394 | } | 396 | } |