diff options
author | Martin Scarratt <mmmm@rockbox.org> | 2007-04-15 13:56:21 +0000 |
---|---|---|
committer | Martin Scarratt <mmmm@rockbox.org> | 2007-04-15 13:56:21 +0000 |
commit | 49952325c9d4a74225b3099eb61860bf4592022c (patch) | |
tree | 70302ab68faf2d231ee491c201dcc47736f852b4 /apps | |
parent | 3c6e46ce64297697bbd6c713da3d0ba7856d6ea9 (diff) | |
download | rockbox-49952325c9d4a74225b3099eb61860bf4592022c.tar.gz rockbox-49952325c9d4a74225b3099eb61860bf4592022c.zip |
Recording countdown timer and repeat timer - see FS #6297 for more details
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13165 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps')
-rw-r--r-- | apps/gui/statusbar.c | 104 | ||||
-rw-r--r-- | apps/gui/statusbar.h | 8 | ||||
-rw-r--r-- | apps/keymaps/keymap-h10.c | 7 | ||||
-rw-r--r-- | apps/keymaps/keymap-h1x0_h3x0.c | 11 | ||||
-rw-r--r-- | apps/keymaps/keymap-x5.c | 3 | ||||
-rw-r--r-- | apps/lang/english.lang | 100 | ||||
-rw-r--r-- | apps/menus/recording_menu.c | 73 | ||||
-rw-r--r-- | apps/recorder/icons.c | 10 | ||||
-rw-r--r-- | apps/recorder/icons.h | 7 | ||||
-rw-r--r-- | apps/recorder/recording.c | 152 | ||||
-rw-r--r-- | apps/recorder/recording.h | 17 | ||||
-rw-r--r-- | apps/settings.c | 188 | ||||
-rw-r--r-- | apps/settings.h | 9 |
13 files changed, 670 insertions, 19 deletions
diff --git a/apps/gui/statusbar.c b/apps/gui/statusbar.c index e082063a6f..157224f77d 100644 --- a/apps/gui/statusbar.c +++ b/apps/gui/statusbar.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include "action.h" /* for keys_locked */ | 33 | #include "action.h" /* for keys_locked */ |
34 | #include "statusbar.h" | 34 | #include "statusbar.h" |
35 | #ifdef HAVE_RECORDING | 35 | #ifdef HAVE_RECORDING |
36 | #include "recording.h" | ||
36 | #include "audio.h" | 37 | #include "audio.h" |
37 | #include "recording.h" | 38 | #include "recording.h" |
38 | #endif | 39 | #endif |
@@ -113,7 +114,11 @@ | |||
113 | #define STATUSBAR_LOCKR_WIDTH 5 | 114 | #define STATUSBAR_LOCKR_WIDTH 5 |
114 | 115 | ||
115 | #if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD) | 116 | #if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD) |
117 | #ifdef HAVE_MMC | ||
116 | #define STATUSBAR_DISK_WIDTH 12 | 118 | #define STATUSBAR_DISK_WIDTH 12 |
119 | #else | ||
120 | #define STATUSBAR_DISK_WIDTH 7 | ||
121 | #endif | ||
117 | #define STATUSBAR_DISK_X_POS(statusbar_width) statusbar_width - \ | 122 | #define STATUSBAR_DISK_X_POS(statusbar_width) statusbar_width - \ |
118 | STATUSBAR_DISK_WIDTH | 123 | STATUSBAR_DISK_WIDTH |
119 | #else | 124 | #else |
@@ -121,6 +126,15 @@ | |||
121 | #endif | 126 | #endif |
122 | #define STATUSBAR_TIME_X_END(statusbar_width) statusbar_width - 1 - \ | 127 | #define STATUSBAR_TIME_X_END(statusbar_width) statusbar_width - 1 - \ |
123 | STATUSBAR_DISK_WIDTH | 128 | STATUSBAR_DISK_WIDTH |
129 | #ifdef HAVE_RECORDING | ||
130 | #define TIMER_ICON_WIDTH 7 | ||
131 | #if CONFIG_RTC | ||
132 | #define CLOCK_WIDTH 35 | ||
133 | #else | ||
134 | #define CLOCK_WIDTH 0 | ||
135 | #endif | ||
136 | #endif | ||
137 | |||
124 | struct gui_syncstatusbar statusbars; | 138 | struct gui_syncstatusbar statusbars; |
125 | 139 | ||
126 | /* Prototypes */ | 140 | /* Prototypes */ |
@@ -140,9 +154,11 @@ static void gui_statusbar_led(struct screen * display); | |||
140 | #endif | 154 | #endif |
141 | #ifdef HAVE_RECORDING | 155 | #ifdef HAVE_RECORDING |
142 | static void gui_statusbar_icon_recording_info(struct screen * display); | 156 | static void gui_statusbar_icon_recording_info(struct screen * display); |
157 | static void gui_statusbar_timer(struct screen * display, int dy, int hr, int mn, int sc, bool recscreen); | ||
158 | static void gui_statusbar_timer_rep(struct screen * display); | ||
143 | #endif | 159 | #endif |
144 | #if CONFIG_RTC | 160 | #if CONFIG_RTC |
145 | static void gui_statusbar_time(struct screen * display, int hour, int minute); | 161 | static void gui_statusbar_time(struct screen * display, int hour, int minute, bool timer_display); |
146 | #endif | 162 | #endif |
147 | #endif | 163 | #endif |
148 | 164 | ||
@@ -245,6 +261,21 @@ void gui_statusbar_draw(struct gui_statusbar * bar, bool force_redraw) | |||
245 | bar->info.minute = tm->tm_min; | 261 | bar->info.minute = tm->tm_min; |
246 | } | 262 | } |
247 | #endif /* CONFIG_RTC */ | 263 | #endif /* CONFIG_RTC */ |
264 | #ifdef HAVE_RECORDING | ||
265 | struct timer* timer = get_timerstat(); | ||
266 | bar->info.timer_day = timer->days; | ||
267 | bar->info.timer_hour = timer->hrs; | ||
268 | bar->info.timer_min = timer->mins; | ||
269 | /* avoid an update every second unless less than one | ||
270 | minute remains on the timer */ | ||
271 | if (!bar->info.timer_day && !bar->info.timer_hour && !bar->info.timer_min) | ||
272 | bar->info.timer_sec = timer->secs; | ||
273 | else | ||
274 | bar->info.timer_sec = 0; | ||
275 | |||
276 | bar->info.timer_display = timer->timer_display; | ||
277 | bar->info.timer_repeat = timer->repeater; | ||
278 | #endif | ||
248 | 279 | ||
249 | /* only redraw if forced to, or info has changed */ | 280 | /* only redraw if forced to, or info has changed */ |
250 | if (force_redraw || bar->redraw_volume || | 281 | if (force_redraw || bar->redraw_volume || |
@@ -316,8 +347,16 @@ void gui_statusbar_draw(struct gui_statusbar * bar, bool force_redraw) | |||
316 | if (bar->info.keylockremote) | 347 | if (bar->info.keylockremote) |
317 | gui_statusbar_icon_lock_remote(display); | 348 | gui_statusbar_icon_lock_remote(display); |
318 | #endif | 349 | #endif |
350 | #ifdef HAVE_RECORDING | ||
351 | if (bar->info.timer_display) | ||
352 | gui_statusbar_timer(display, bar->info.timer_day, bar->info.timer_hour, | ||
353 | bar->info.timer_min, bar->info.timer_sec, recscreen_on); | ||
354 | else if ((bar->info.timer_repeat) && (recscreen_on)) | ||
355 | gui_statusbar_timer_rep(display); | ||
356 | #endif | ||
319 | #if CONFIG_RTC | 357 | #if CONFIG_RTC |
320 | gui_statusbar_time(display, bar->info.hour, bar->info.minute); | 358 | gui_statusbar_time(display, bar->info.hour, bar->info.minute, |
359 | bar->info.timer_display); | ||
321 | #endif /* CONFIG_RTC */ | 360 | #endif /* CONFIG_RTC */ |
322 | #if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD) | 361 | #if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD) |
323 | if(!display->has_disk_led && bar->info.led) | 362 | if(!display->has_disk_led && bar->info.led) |
@@ -577,7 +616,8 @@ static void gui_statusbar_led(struct screen * display) | |||
577 | /* | 616 | /* |
578 | * Print time to status bar | 617 | * Print time to status bar |
579 | */ | 618 | */ |
580 | static void gui_statusbar_time(struct screen * display, int hour, int minute) | 619 | static void gui_statusbar_time(struct screen * display, int hour, int minute, |
620 | bool timer_display) | ||
581 | { | 621 | { |
582 | unsigned char buffer[6]; | 622 | unsigned char buffer[6]; |
583 | unsigned int width, height; | 623 | unsigned int width, height; |
@@ -599,15 +639,73 @@ static void gui_statusbar_time(struct screen * display, int hour, int minute) | |||
599 | display->setfont(FONT_SYSFIXED); | 639 | display->setfont(FONT_SYSFIXED); |
600 | display->getstringsize(buffer, &width, &height); | 640 | display->getstringsize(buffer, &width, &height); |
601 | if (height <= STATUSBAR_HEIGHT) { | 641 | if (height <= STATUSBAR_HEIGHT) { |
642 | #ifdef HAVE_RECORDING | ||
643 | if (timer_display) | ||
644 | display->set_drawmode(DRMODE_INVERSEVID); | ||
645 | #else | ||
646 | (void)timer_display; | ||
647 | #endif | ||
602 | display->putsxy(STATUSBAR_TIME_X_END(display->width) - width, | 648 | display->putsxy(STATUSBAR_TIME_X_END(display->width) - width, |
603 | STATUSBAR_Y_POS, buffer); | 649 | STATUSBAR_Y_POS, buffer); |
604 | } | 650 | } |
651 | display->set_drawmode(DRMODE_SOLID); | ||
605 | display->setfont(FONT_UI); | 652 | display->setfont(FONT_UI); |
606 | 653 | ||
607 | } | 654 | } |
608 | #endif | 655 | #endif |
609 | 656 | ||
610 | #ifdef HAVE_RECORDING | 657 | #ifdef HAVE_RECORDING |
658 | static void gui_statusbar_timer(struct screen * display, int dy, int hr, int mn, | ||
659 | int sc, bool recscreen) | ||
660 | { | ||
661 | unsigned char buffer[8]; | ||
662 | int width, height; | ||
663 | |||
664 | /* vary the display depending on the remaining time to save space */ | ||
665 | if (dy) | ||
666 | snprintf(buffer, sizeof(buffer), " %dd%02dh", hr > 58 ? dy + 1 : dy, | ||
667 | hr > 58 ? 0 : hr + 1); | ||
668 | else if (!hr && !mn) | ||
669 | snprintf(buffer, sizeof(buffer), "%02ds", sc); | ||
670 | else | ||
671 | snprintf(buffer, sizeof(buffer), "%02dh%02dm", mn > 58 ? hr + 1: hr, | ||
672 | mn > 58 ? 0 : mn + 1); | ||
673 | |||
674 | display->setfont(FONT_SYSFIXED); | ||
675 | display->getstringsize(buffer, &width, &height); | ||
676 | |||
677 | if (height <= STATUSBAR_HEIGHT) | ||
678 | { | ||
679 | if(((display->width) >= (STATUSBAR_LOCKR_X_POS + STATUSBAR_LOCKR_WIDTH + | ||
680 | STATUSBAR_DISK_WIDTH + width + CLOCK_WIDTH + 1)) | ||
681 | && !recscreen) | ||
682 | display->putsxy(STATUSBAR_TIME_X_END(display->width) - width - | ||
683 | CLOCK_WIDTH, STATUSBAR_Y_POS, buffer); | ||
684 | /* display only an icon for small screens or when in recording screen*/ | ||
685 | else if ((display->width) >= (STATUSBAR_LOCKR_X_POS + | ||
686 | STATUSBAR_LOCKR_WIDTH + | ||
687 | STATUSBAR_DISK_WIDTH + | ||
688 | TIMER_ICON_WIDTH + CLOCK_WIDTH + 1)) | ||
689 | display->mono_bitmap(bitmap_icons_7x7[Icon_Timer], | ||
690 | STATUSBAR_TIME_X_END(display->width) - | ||
691 | TIMER_ICON_WIDTH - CLOCK_WIDTH, | ||
692 | STATUSBAR_Y_POS, | ||
693 | TIMER_ICON_WIDTH, STATUSBAR_HEIGHT); | ||
694 | } | ||
695 | |||
696 | display->setfont(FONT_UI); | ||
697 | |||
698 | } | ||
699 | |||
700 | static void gui_statusbar_timer_rep(struct screen * display) | ||
701 | { | ||
702 | display->mono_bitmap(bitmap_icons_7x7[Icon_Timer_rep], | ||
703 | STATUSBAR_TIME_X_END(display->width) - | ||
704 | TIMER_ICON_WIDTH - CLOCK_WIDTH, | ||
705 | STATUSBAR_Y_POS, | ||
706 | TIMER_ICON_WIDTH, STATUSBAR_HEIGHT); | ||
707 | } | ||
708 | |||
611 | #if CONFIG_CODEC == SWCODEC | 709 | #if CONFIG_CODEC == SWCODEC |
612 | /** | 710 | /** |
613 | * Write a number to the display using bitmaps and return new position | 711 | * Write a number to the display using bitmaps and return new position |
diff --git a/apps/gui/statusbar.h b/apps/gui/statusbar.h index 21f98336d0..660c657f29 100644 --- a/apps/gui/statusbar.h +++ b/apps/gui/statusbar.h | |||
@@ -37,6 +37,14 @@ struct status_info { | |||
37 | int hour; | 37 | int hour; |
38 | int minute; | 38 | int minute; |
39 | #endif | 39 | #endif |
40 | #ifdef HAVE_RECORDING | ||
41 | int timer_day; | ||
42 | int timer_hour; | ||
43 | int timer_min; | ||
44 | int timer_sec; | ||
45 | int timer_repeat; | ||
46 | #endif | ||
47 | int timer_display; | ||
40 | 48 | ||
41 | #if CONFIG_CHARGING | 49 | #if CONFIG_CHARGING |
42 | bool inserted; | 50 | bool inserted; |
diff --git a/apps/keymaps/keymap-h10.c b/apps/keymaps/keymap-h10.c index 1a3c81b989..b3586413dd 100644 --- a/apps/keymaps/keymap-h10.c +++ b/apps/keymaps/keymap-h10.c | |||
@@ -121,7 +121,10 @@ static const struct button_mapping button_context_settings[] = { | |||
121 | { ACTION_STD_PREVREPEAT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE }, | 121 | { ACTION_STD_PREVREPEAT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE }, |
122 | { ACTION_STD_NEXT, BUTTON_RIGHT, BUTTON_NONE }, | 122 | { ACTION_STD_NEXT, BUTTON_RIGHT, BUTTON_NONE }, |
123 | { ACTION_STD_NEXTREPEAT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE }, | 123 | { ACTION_STD_NEXTREPEAT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE }, |
124 | { ACTION_SETTINGS_RESET, BUTTON_PLAY, BUTTON_NONE }, | 124 | { ACTION_SETTINGS_RESET, BUTTON_POWER, BUTTON_NONE }, |
125 | { ACTION_NONE, BUTTON_LEFT|BUTTON_REL, BUTTON_LEFT }, | ||
126 | { ACTION_NONE, BUTTON_RIGHT|BUTTON_REL, BUTTON_RIGHT }, | ||
127 | { ACTION_STD_OK, BUTTON_PLAY, BUTTON_NONE }, | ||
125 | 128 | ||
126 | LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD), | 129 | LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD), |
127 | }; /* button_context_settings */ | 130 | }; /* button_context_settings */ |
@@ -303,6 +306,8 @@ static const struct button_mapping button_context_bmark[] = { | |||
303 | 306 | ||
304 | const struct button_mapping button_context_recscreen[] = { | 307 | const struct button_mapping button_context_recscreen[] = { |
305 | { ACTION_REC_PAUSE, BUTTON_PLAY, BUTTON_NONE }, | 308 | { ACTION_REC_PAUSE, BUTTON_PLAY, BUTTON_NONE }, |
309 | { ACTION_STD_CANCEL, BUTTON_REW, BUTTON_NONE }, | ||
310 | |||
306 | 311 | ||
307 | LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_SETTINGS) | 312 | LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_SETTINGS) |
308 | }; /* button_context_recscreen */ | 313 | }; /* button_context_recscreen */ |
diff --git a/apps/keymaps/keymap-h1x0_h3x0.c b/apps/keymaps/keymap-h1x0_h3x0.c index bbec420846..d3d5f8d35f 100644 --- a/apps/keymaps/keymap-h1x0_h3x0.c +++ b/apps/keymaps/keymap-h1x0_h3x0.c | |||
@@ -439,6 +439,10 @@ static const struct button_mapping button_context_settings_h100remote[] = { | |||
439 | { ACTION_SETTINGS_INCREPEAT, BUTTON_RC_REW|BUTTON_REPEAT, BUTTON_NONE }, | 439 | { ACTION_SETTINGS_INCREPEAT, BUTTON_RC_REW|BUTTON_REPEAT, BUTTON_NONE }, |
440 | { ACTION_SETTINGS_DEC, BUTTON_RC_FF, BUTTON_NONE }, | 440 | { ACTION_SETTINGS_DEC, BUTTON_RC_FF, BUTTON_NONE }, |
441 | { ACTION_SETTINGS_DECREPEAT, BUTTON_RC_FF|BUTTON_REPEAT, BUTTON_NONE }, | 441 | { ACTION_SETTINGS_DECREPEAT, BUTTON_RC_FF|BUTTON_REPEAT, BUTTON_NONE }, |
442 | { ACTION_STD_PREV, BUTTON_RC_SOURCE, BUTTON_NONE }, | ||
443 | { ACTION_STD_PREVREPEAT, BUTTON_RC_SOURCE|BUTTON_REPEAT, BUTTON_NONE }, | ||
444 | { ACTION_STD_NEXT, BUTTON_RC_BITRATE, BUTTON_NONE }, | ||
445 | { ACTION_STD_NEXTREPEAT, BUTTON_RC_BITRATE|BUTTON_REPEAT, BUTTON_NONE }, | ||
442 | /* { ACTION_NONE, BUTTON_RC_ON, BUTTON_NONE }, | 446 | /* { ACTION_NONE, BUTTON_RC_ON, BUTTON_NONE }, |
443 | { ACTION_NONE, BUTTON_RC_STOP, BUTTON_NONE }, | 447 | { ACTION_NONE, BUTTON_RC_STOP, BUTTON_NONE }, |
444 | { ACTION_NONE, BUTTON_RC_MENU|BUTTON_REL, BUTTON_NONE }, | 448 | { ACTION_NONE, BUTTON_RC_MENU|BUTTON_REL, BUTTON_NONE }, |
@@ -451,8 +455,11 @@ static const struct button_mapping button_context_settings_h300lcdremote[] = { | |||
451 | { ACTION_SETTINGS_INCREPEAT, BUTTON_RC_VOL_UP|BUTTON_REPEAT, BUTTON_NONE }, | 455 | { ACTION_SETTINGS_INCREPEAT, BUTTON_RC_VOL_UP|BUTTON_REPEAT, BUTTON_NONE }, |
452 | { ACTION_SETTINGS_DEC, BUTTON_RC_VOL_DOWN, BUTTON_NONE }, | 456 | { ACTION_SETTINGS_DEC, BUTTON_RC_VOL_DOWN, BUTTON_NONE }, |
453 | { ACTION_SETTINGS_DECREPEAT, BUTTON_RC_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE }, | 457 | { ACTION_SETTINGS_DECREPEAT, BUTTON_RC_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE }, |
454 | { ACTION_NONE, BUTTON_RC_REW, BUTTON_NONE }, | 458 | { ACTION_STD_PREV, BUTTON_RC_REW, BUTTON_NONE }, |
455 | { ACTION_NONE, BUTTON_RC_FF, BUTTON_NONE }, | 459 | { ACTION_STD_PREVREPEAT, BUTTON_RC_REW|BUTTON_REPEAT, BUTTON_NONE }, |
460 | { ACTION_STD_NEXT, BUTTON_RC_FF, BUTTON_NONE }, | ||
461 | { ACTION_STD_NEXTREPEAT, BUTTON_RC_FF|BUTTON_REPEAT, BUTTON_NONE }, | ||
462 | { ACTION_SETTINGS_RESET, BUTTON_RC_ON, BUTTON_NONE }, | ||
456 | 463 | ||
457 | LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD) | 464 | LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD) |
458 | }; /* button_context_settings */ | 465 | }; /* button_context_settings */ |
diff --git a/apps/keymaps/keymap-x5.c b/apps/keymaps/keymap-x5.c index b637e1ddd1..3dc69d767c 100644 --- a/apps/keymaps/keymap-x5.c +++ b/apps/keymaps/keymap-x5.c | |||
@@ -219,6 +219,9 @@ static const struct button_mapping button_context_settings[] = { | |||
219 | { ACTION_SETTINGS_DEC, BUTTON_DOWN, BUTTON_NONE }, | 219 | { ACTION_SETTINGS_DEC, BUTTON_DOWN, BUTTON_NONE }, |
220 | { ACTION_SETTINGS_DECREPEAT, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_NONE }, | 220 | { ACTION_SETTINGS_DECREPEAT, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_NONE }, |
221 | { ACTION_STD_PREV, BUTTON_LEFT, BUTTON_NONE }, | 221 | { ACTION_STD_PREV, BUTTON_LEFT, BUTTON_NONE }, |
222 | { ACTION_STD_PREVREPEAT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE }, | ||
223 | { ACTION_STD_NEXT, BUTTON_RIGHT, BUTTON_NONE }, | ||
224 | { ACTION_STD_NEXTREPEAT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE }, | ||
222 | { ACTION_STD_CANCEL, BUTTON_REC, BUTTON_NONE }, | 225 | { ACTION_STD_CANCEL, BUTTON_REC, BUTTON_NONE }, |
223 | 226 | ||
224 | LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD) | 227 | LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD) |
diff --git a/apps/lang/english.lang b/apps/lang/english.lang index 69900c5e6a..66b864e0cc 100644 --- a/apps/lang/english.lang +++ b/apps/lang/english.lang | |||
@@ -2720,16 +2720,16 @@ | |||
2720 | </phrase> | 2720 | </phrase> |
2721 | <phrase> | 2721 | <phrase> |
2722 | id: LANG_RECORD_TIMESPLIT | 2722 | id: LANG_RECORD_TIMESPLIT |
2723 | desc: Record split menu | 2723 | desc: Record timer menu |
2724 | user: | 2724 | user: |
2725 | <source> | 2725 | <source> |
2726 | *: "File Split Options" | 2726 | *: "File Split Options" |
2727 | </source> | 2727 | </source> |
2728 | <dest> | 2728 | <dest> |
2729 | *: "File Split Options" | 2729 | *: "Timer Options" |
2730 | </dest> | 2730 | </dest> |
2731 | <voice> | 2731 | <voice> |
2732 | *: "File Split Options" | 2732 | *: "Timer Options" |
2733 | </voice> | 2733 | </voice> |
2734 | </phrase> | 2734 | </phrase> |
2735 | <phrase> | 2735 | <phrase> |
@@ -10741,3 +10741,97 @@ | |||
10741 | *: "Context Menu" | 10741 | *: "Context Menu" |
10742 | </voice> | 10742 | </voice> |
10743 | </phrase> | 10743 | </phrase> |
10744 | <phrase> | ||
10745 | id: LANG_MULTIINT_CONFIRM | ||
10746 | desc: Confirm string for multi_int settings | ||
10747 | user: | ||
10748 | <source> | ||
10749 | *: "Press PLAY to confirm" | ||
10750 | </source> | ||
10751 | <dest> | ||
10752 | *: "Press PLAY to confirm" | ||
10753 | h100,h120,h300: "Press NAVI to confirm" | ||
10754 | ipod*,x5,gigabeat: "Press SELECT to confirm" | ||
10755 | </dest> | ||
10756 | <voice> | ||
10757 | *: "" | ||
10758 | </voice> | ||
10759 | </phrase> | ||
10760 | <phrase> | ||
10761 | id: LANG_TIMER_SET | ||
10762 | desc: Recording timer menu | ||
10763 | <source> | ||
10764 | *: "Set countdown timer" | ||
10765 | </source> | ||
10766 | <dest> | ||
10767 | *: "Set countdown timer" | ||
10768 | </dest> | ||
10769 | <voice> | ||
10770 | *: "Set countdown timer" | ||
10771 | </voice> | ||
10772 | </phrase> | ||
10773 | <phrase> | ||
10774 | id: LANG_TIMER_REPEAT | ||
10775 | desc: Recording timer menu | ||
10776 | <source> | ||
10777 | *: "Record repeat timer" | ||
10778 | </source> | ||
10779 | <dest> | ||
10780 | *: "Record repeat timer" | ||
10781 | </dest> | ||
10782 | <voice> | ||
10783 | *: "Record repeat timer" | ||
10784 | </voice> | ||
10785 | </phrase> | ||
10786 | <phrase> | ||
10787 | id: LANG_TIMER_DAYS | ||
10788 | desc: recording timer settings string | ||
10789 | <source> | ||
10790 | *: "Days" | ||
10791 | </source> | ||
10792 | <dest> | ||
10793 | *: "Days" | ||
10794 | </dest> | ||
10795 | <voice> | ||
10796 | *: "Days" | ||
10797 | </voice> | ||
10798 | </phrase> | ||
10799 | <phrase> | ||
10800 | id: LANG_TIMER_HRS | ||
10801 | desc: recording timer settings string | ||
10802 | <source> | ||
10803 | *: "Hrs" | ||
10804 | </source> | ||
10805 | <dest> | ||
10806 | *: "Hrs" | ||
10807 | </dest> | ||
10808 | <voice> | ||
10809 | *: "Hours" | ||
10810 | </voice> | ||
10811 | </phrase> | ||
10812 | <phrase> | ||
10813 | id: LANG_TIMER_MINS | ||
10814 | desc: recording timer settings string | ||
10815 | <source> | ||
10816 | *: "Mins" | ||
10817 | </source> | ||
10818 | <dest> | ||
10819 | *: "Mins" | ||
10820 | </dest> | ||
10821 | <voice> | ||
10822 | *: "Minutes" | ||
10823 | </voice> | ||
10824 | </phrase> | ||
10825 | <phrase> | ||
10826 | id: LANG_REC_TIMER | ||
10827 | desc: recording screen timer string | ||
10828 | <source> | ||
10829 | *: "Timer" | ||
10830 | </source> | ||
10831 | <dest> | ||
10832 | *: "Timer" | ||
10833 | </dest> | ||
10834 | <voice> | ||
10835 | *: "Timer" | ||
10836 | </voice> | ||
10837 | </phrase> | ||
diff --git a/apps/menus/recording_menu.c b/apps/menus/recording_menu.c index 1bc84e90d2..d37fe39bfe 100644 --- a/apps/menus/recording_menu.c +++ b/apps/menus/recording_menu.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include "sound.h" | 42 | #include "sound.h" |
43 | #ifdef HAVE_RECORDING | 43 | #ifdef HAVE_RECORDING |
44 | #include "audio.h" | 44 | #include "audio.h" |
45 | #include "recording.h" | ||
45 | #if CONFIG_TUNER | 46 | #if CONFIG_TUNER |
46 | #include "radio.h" | 47 | #include "radio.h" |
47 | #endif | 48 | #endif |
@@ -305,12 +306,78 @@ MENUITEM_SETTING(rec_quality, &global_settings.rec_quality, NULL); | |||
305 | MENUITEM_SETTING(rec_editable, &global_settings.rec_editable, NULL); | 306 | MENUITEM_SETTING(rec_editable, &global_settings.rec_editable, NULL); |
306 | #endif | 307 | #endif |
307 | 308 | ||
309 | /* Displays a menu for changing the countdown timer settings */ | ||
310 | static int countdown_timer_func(void) | ||
311 | { | ||
312 | bool retval; | ||
313 | bool changed = false; | ||
314 | struct timer* timer = get_timerstat(); | ||
315 | |||
316 | static const struct opt_items names[] = { | ||
317 | { STR(LANG_TIMER_DAYS) }, | ||
318 | { STR(LANG_TIMER_HRS) }, | ||
319 | { STR(LANG_TIMER_MINS) } | ||
320 | }; | ||
321 | |||
322 | struct opt_settings settings[] = { | ||
323 | { &timer->days, 6 }, | ||
324 | { &timer->hrs, 23 }, | ||
325 | { &timer->mins, 59 } | ||
326 | }; | ||
327 | |||
328 | retval = set_multi_int(str(LANG_TIMER_SET), names, settings, 3, &changed); | ||
329 | |||
330 | if (changed) | ||
331 | { | ||
332 | timer->countdown = false; | ||
333 | timer->secs = 0; | ||
334 | timer->timer_display = false; | ||
335 | } | ||
336 | |||
337 | return retval; | ||
338 | } | ||
339 | |||
340 | static int countdown_timer_repeat_func(void) | ||
341 | { | ||
342 | struct timer* timer = get_timerstat(); | ||
343 | bool retval; | ||
344 | |||
345 | static const struct opt_items names[] = { | ||
346 | { STR(LANG_TIMER_DAYS) }, | ||
347 | { STR(LANG_TIMER_HRS) }, | ||
348 | { STR(LANG_TIMER_MINS) } | ||
349 | }; | ||
350 | |||
351 | struct opt_settings settings[] = { | ||
352 | { &timer->days_rpt, 6 }, | ||
353 | { &timer->hrs_rpt, 23 }, | ||
354 | { &timer->mins_rpt, 59 } | ||
355 | }; | ||
356 | retval = set_multi_int(str(LANG_TIMER_REPEAT), names, settings, 3, NULL); | ||
357 | |||
358 | /* automatically select settings necessary for repeated recording */ | ||
359 | if (timer->days_rpt || timer->hrs_rpt || timer->mins_rpt) | ||
360 | { | ||
361 | global_settings.rec_split_type = 1; /* Stop */ | ||
362 | global_settings.rec_split_method = 0; /* Time */ | ||
363 | global_settings.rec_trigger_mode = 0; /* The repeat timer isn't | ||
364 | compatible with the trigger */ | ||
365 | } | ||
366 | |||
367 | return retval; | ||
368 | } | ||
369 | |||
370 | MENUITEM_FUNCTION(countdown_timer, 0, ID2P(LANG_TIMER_SET), | ||
371 | countdown_timer_func, NULL, NULL, Icon_Menu_setting); | ||
372 | MENUITEM_FUNCTION(countdown_timer_repeat, 0, ID2P(LANG_TIMER_REPEAT), | ||
373 | countdown_timer_repeat_func, NULL, NULL, Icon_Menu_setting); | ||
308 | MENUITEM_SETTING(rec_split_type, &global_settings.rec_split_type, NULL); | 374 | MENUITEM_SETTING(rec_split_type, &global_settings.rec_split_type, NULL); |
309 | MENUITEM_SETTING(rec_split_method, &global_settings.rec_split_method, NULL); | 375 | MENUITEM_SETTING(rec_split_method, &global_settings.rec_split_method, NULL); |
310 | MENUITEM_SETTING(rec_timesplit, &global_settings.rec_timesplit, NULL); | 376 | MENUITEM_SETTING(rec_timesplit, &global_settings.rec_timesplit, NULL); |
311 | MENUITEM_SETTING(rec_sizesplit, &global_settings.rec_sizesplit, NULL); | 377 | MENUITEM_SETTING(rec_sizesplit, &global_settings.rec_sizesplit, NULL); |
312 | MAKE_MENU(filesplitoptionsmenu, ID2P(LANG_RECORD_TIMESPLIT), NULL, Icon_NOICON, | 378 | MAKE_MENU(timermenu, ID2P(LANG_RECORD_TIMESPLIT), NULL, Icon_NOICON, |
313 | &rec_split_method, &rec_split_type, &rec_timesplit, &rec_sizesplit); | 379 | &countdown_timer, &countdown_timer_repeat, &rec_split_method, |
380 | &rec_split_type, &rec_timesplit, &rec_sizesplit); | ||
314 | 381 | ||
315 | 382 | ||
316 | MENUITEM_SETTING(rec_prerecord_time, &global_settings.rec_prerecord_time, NULL); | 383 | MENUITEM_SETTING(rec_prerecord_time, &global_settings.rec_prerecord_time, NULL); |
@@ -819,7 +886,7 @@ MAKE_MENU(recording_setting_menu, ID2P(LANG_RECORDING_SETTINGS), NULL, Icon_Reco | |||
819 | #if CONFIG_CODEC == MAS3587F | 886 | #if CONFIG_CODEC == MAS3587F |
820 | &rec_editable, | 887 | &rec_editable, |
821 | #endif | 888 | #endif |
822 | &filesplitoptionsmenu, | 889 | &timermenu, |
823 | &rec_prerecord_time, | 890 | &rec_prerecord_time, |
824 | &recdirectory, | 891 | &recdirectory, |
825 | #ifdef HAVE_BACKLIGHT | 892 | #ifdef HAVE_BACKLIGHT |
diff --git a/apps/recorder/icons.c b/apps/recorder/icons.c index ccb42d5919..bf6500fb1f 100644 --- a/apps/recorder/icons.c +++ b/apps/recorder/icons.c | |||
@@ -44,6 +44,14 @@ const unsigned char bitmap_icons_5x8[][5] = | |||
44 | #endif | 44 | #endif |
45 | }; | 45 | }; |
46 | 46 | ||
47 | const unsigned char bitmap_icons_7x7[][7] = | ||
48 | { | ||
49 | [Icon_Timer] = | ||
50 | {0x1c, 0x22, 0x41, 0x4f, 0x49, 0x22, 0x1d}, /* Recording timer icon */ | ||
51 | [Icon_Timer_rep]= | ||
52 | {0x17, 0x26, 0x45, 0x41, 0x51, 0x32, 0x74}, /* Recording repeat timer icon */ | ||
53 | }; | ||
54 | |||
47 | const unsigned char bitmap_icons_6x8[][6] = | 55 | const unsigned char bitmap_icons_6x8[][6] = |
48 | { | 56 | { |
49 | { 0x60, 0x7f, 0x03, 0x33, 0x3f, 0x00 }, /* Musical note */ | 57 | { 0x60, 0x7f, 0x03, 0x33, 0x3f, 0x00 }, /* Musical note */ |
@@ -159,7 +167,7 @@ const unsigned char bitmap_icon_disk[12] = | |||
159 | #ifdef HAVE_MMC | 167 | #ifdef HAVE_MMC |
160 | {0x15,0x3f,0x7d,0x7B,0x77,0x67,0x79,0x7b,0x57,0x4f,0x47,0x7f}; | 168 | {0x15,0x3f,0x7d,0x7B,0x77,0x67,0x79,0x7b,0x57,0x4f,0x47,0x7f}; |
161 | #else | 169 | #else |
162 | {0x00,0x00,0x00,0x1c,0x2e,0x4f,0x77,0x79,0x3a,0x1c,0x00,0x00}; | 170 | {0x1c,0x2e,0x4f,0x77,0x79,0x3a,0x1c,0x00,0x00,0x00,0x00,0x00}; |
163 | #endif | 171 | #endif |
164 | 172 | ||
165 | /* | 173 | /* |
diff --git a/apps/recorder/icons.h b/apps/recorder/icons.h index 7682d44733..09aadf0888 100644 --- a/apps/recorder/icons.h +++ b/apps/recorder/icons.h | |||
@@ -49,6 +49,12 @@ enum icons_5x8 { | |||
49 | Icon5x8Last | 49 | Icon5x8Last |
50 | }; | 50 | }; |
51 | 51 | ||
52 | enum icons_7x7 { | ||
53 | Icon_Timer, | ||
54 | Icon_Timer_rep, | ||
55 | Icon7x7Last | ||
56 | }; | ||
57 | |||
52 | /* If any icons are added to this enum, they must be | 58 | /* If any icons are added to this enum, they must be |
53 | added to the unused_but_needed enum in ../player/icons.h */ | 59 | added to the unused_but_needed enum in ../player/icons.h */ |
54 | enum icons_6x8 { | 60 | enum icons_6x8 { |
@@ -144,6 +150,7 @@ extern const unsigned char bitmap_formats_18x8[Format_18x8Last][18]; | |||
144 | #endif /* CONFIG_CODEC == SWCODEC && defined (HAVE_RECORDING) */ | 150 | #endif /* CONFIG_CODEC == SWCODEC && defined (HAVE_RECORDING) */ |
145 | 151 | ||
146 | extern const unsigned char bitmap_icons_5x8[Icon5x8Last][5]; | 152 | extern const unsigned char bitmap_icons_5x8[Icon5x8Last][5]; |
153 | extern const unsigned char bitmap_icons_7x7[Icon7x7Last][7]; | ||
147 | extern const unsigned char bitmap_icons_6x8[Icon6x8Last][6]; | 154 | extern const unsigned char bitmap_icons_6x8[Icon6x8Last][6]; |
148 | extern const unsigned char bitmap_icons_7x8[Icon7x8Last][7]; | 155 | extern const unsigned char bitmap_icons_7x8[Icon7x8Last][7]; |
149 | extern const unsigned char bitmap_icon_disk[]; | 156 | extern const unsigned char bitmap_icon_disk[]; |
diff --git a/apps/recorder/recording.c b/apps/recorder/recording.c index 025480cf91..7a332228e5 100644 --- a/apps/recorder/recording.c +++ b/apps/recorder/recording.c | |||
@@ -70,6 +70,8 @@ | |||
70 | #include "radio.h" | 70 | #include "radio.h" |
71 | #ifdef HAVE_RECORDING | 71 | #ifdef HAVE_RECORDING |
72 | 72 | ||
73 | static struct timer timer; | ||
74 | |||
73 | static bool in_screen = false; | 75 | static bool in_screen = false; |
74 | 76 | ||
75 | bool in_recording_screen(void) | 77 | bool in_recording_screen(void) |
@@ -745,6 +747,37 @@ static void trigger_listener(int trigger_status) | |||
745 | } | 747 | } |
746 | } | 748 | } |
747 | 749 | ||
750 | /* countdown timer tick task */ | ||
751 | void timer_tick_task(void) | ||
752 | { | ||
753 | static int mini_tick = 0; | ||
754 | |||
755 | mini_tick ++; | ||
756 | /* the countdown */ | ||
757 | if ((mini_tick >= HZ) && (timer.countdown)) | ||
758 | { | ||
759 | mini_tick = 0; | ||
760 | if (timer.secs) timer.secs -= 1; | ||
761 | else{ | ||
762 | timer.secs = 59; | ||
763 | if (timer.mins) timer.mins -= 1; | ||
764 | else{ | ||
765 | timer.mins = 59; | ||
766 | if (timer.hrs) timer.hrs -= 1; | ||
767 | else{ | ||
768 | timer.hrs = 23; | ||
769 | if (timer.days) timer.days -= 1; | ||
770 | else{ | ||
771 | timer.days = timer.hrs = timer.mins = timer.secs = 0; | ||
772 | /* switch timer display on/off when countdown finished */ | ||
773 | timer.timer_display = !timer.timer_display; | ||
774 | } | ||
775 | } | ||
776 | } | ||
777 | } | ||
778 | } | ||
779 | } | ||
780 | |||
748 | bool recording_start_automatic = false; | 781 | bool recording_start_automatic = false; |
749 | 782 | ||
750 | bool recording_screen(bool no_source) | 783 | bool recording_screen(bool no_source) |
@@ -756,7 +789,7 @@ bool recording_screen(bool no_source) | |||
756 | int w, h; | 789 | int w, h; |
757 | int update_countdown = 1; | 790 | int update_countdown = 1; |
758 | bool have_recorded = false; | 791 | bool have_recorded = false; |
759 | unsigned int seconds; | 792 | unsigned int seconds, prerec = 0; |
760 | int hours, minutes; | 793 | int hours, minutes; |
761 | char filename[13]; | 794 | char filename[13]; |
762 | bool been_in_usb_mode = false; | 795 | bool been_in_usb_mode = false; |
@@ -793,6 +826,9 @@ bool recording_screen(bool no_source) | |||
793 | int trig_xpos[NB_SCREENS]; | 826 | int trig_xpos[NB_SCREENS]; |
794 | int trig_ypos[NB_SCREENS]; | 827 | int trig_ypos[NB_SCREENS]; |
795 | int trig_width[NB_SCREENS]; | 828 | int trig_width[NB_SCREENS]; |
829 | int countdown_offset = 0; | ||
830 | bool repeat_timer_start = false; | ||
831 | unsigned int repeat_timer; | ||
796 | 832 | ||
797 | static const unsigned char *byte_units[] = { | 833 | static const unsigned char *byte_units[] = { |
798 | ID2P(LANG_BYTE), | 834 | ID2P(LANG_BYTE), |
@@ -804,6 +840,11 @@ bool recording_screen(bool no_source) | |||
804 | struct audio_recording_options rec_options; | 840 | struct audio_recording_options rec_options; |
805 | 841 | ||
806 | in_screen = true; | 842 | in_screen = true; |
843 | |||
844 | /* Stop countdown if countdown settings changed */ | ||
845 | if (!timer.countdown) | ||
846 | tick_remove_task(timer_tick_task); | ||
847 | |||
807 | cursor = 0; | 848 | cursor = 0; |
808 | #if (CONFIG_LED == LED_REAL) && !defined(SIMULATOR) | 849 | #if (CONFIG_LED == LED_REAL) && !defined(SIMULATOR) |
809 | ata_set_led_enabled(false); | 850 | ata_set_led_enabled(false); |
@@ -937,6 +978,25 @@ bool recording_screen(bool no_source) | |||
937 | last_audio_stat = audio_stat; | 978 | last_audio_stat = audio_stat; |
938 | } | 979 | } |
939 | 980 | ||
981 | /* repeat_timer is the repeat time in seconds */ | ||
982 | repeat_timer = (timer.mins_rpt * 60 + timer.hrs_rpt * | ||
983 | 3600 + timer.days_rpt * 3600 * 24); | ||
984 | |||
985 | /* decide on repeat timer status */ | ||
986 | if ((repeat_timer > rec_timesplit_seconds()) && | ||
987 | global_settings.rec_timesplit) | ||
988 | timer.repeater = true; | ||
989 | else | ||
990 | timer.repeater = false; | ||
991 | |||
992 | /* When countdown timer reaches zero fake a new file button press */ | ||
993 | if (timer.countdown && !timer.days && !timer.hrs && !timer.mins && | ||
994 | !timer.secs) | ||
995 | { | ||
996 | tick_remove_task(timer_tick_task); | ||
997 | button = ACTION_REC_NEWFILE; | ||
998 | timer.countdown = false; | ||
999 | } | ||
940 | 1000 | ||
941 | if (recording_start_automatic) | 1001 | if (recording_start_automatic) |
942 | { | 1002 | { |
@@ -991,7 +1051,27 @@ bool recording_screen(bool no_source) | |||
991 | case ACTION_REC_NEWFILE: | 1051 | case ACTION_REC_NEWFILE: |
992 | /* Only act if the mpeg is stopped */ | 1052 | /* Only act if the mpeg is stopped */ |
993 | if(!(audio_stat & AUDIO_STATUS_RECORD)) | 1053 | if(!(audio_stat & AUDIO_STATUS_RECORD)) |
994 | { | 1054 | { /* if countdown timer is set, start countdown */ |
1055 | if (timer.days || timer.hrs || timer.mins || timer.secs) | ||
1056 | { | ||
1057 | if (button == ACTION_REC_PAUSE) | ||
1058 | { | ||
1059 | timer.countdown = !timer.countdown; | ||
1060 | if (timer.countdown) | ||
1061 | tick_add_task(timer_tick_task); | ||
1062 | else | ||
1063 | tick_remove_task(timer_tick_task); | ||
1064 | break; | ||
1065 | } | ||
1066 | else | ||
1067 | { | ||
1068 | /* if newfile button pressed and countdown timer is on, | ||
1069 | start new file and reset timer */ | ||
1070 | tick_remove_task(timer_tick_task); | ||
1071 | timer.days = timer.hrs = timer.mins = timer.secs = 0; | ||
1072 | timer.countdown = false; | ||
1073 | } | ||
1074 | } | ||
995 | /* is this manual or triggered recording? */ | 1075 | /* is this manual or triggered recording? */ |
996 | if ((global_settings.rec_trigger_mode == TRIG_MODE_OFF) || | 1076 | if ((global_settings.rec_trigger_mode == TRIG_MODE_OFF) || |
997 | (peak_meter_trigger_status() != TRIG_OFF)) | 1077 | (peak_meter_trigger_status() != TRIG_OFF)) |
@@ -999,6 +1079,11 @@ bool recording_screen(bool no_source) | |||
999 | /* manual recording */ | 1079 | /* manual recording */ |
1000 | have_recorded = true; | 1080 | have_recorded = true; |
1001 | rec_record(); | 1081 | rec_record(); |
1082 | repeat_timer_start = true; /* allow access to repeat timer | ||
1083 | code */ | ||
1084 | /* amount of file that has been prerecorded - needed for | ||
1085 | syncing repeat timer */ | ||
1086 | prerec = audio_recorded_time() / HZ; | ||
1002 | last_seconds = 0; | 1087 | last_seconds = 0; |
1003 | if (talk_menu) | 1088 | if (talk_menu) |
1004 | { /* no voice possible here, but a beep */ | 1089 | { /* no voice possible here, but a beep */ |
@@ -1197,7 +1282,6 @@ bool recording_screen(bool no_source) | |||
1197 | #ifdef HAVE_FMRADIO_IN | 1282 | #ifdef HAVE_FMRADIO_IN |
1198 | const int prev_rec_source = global_settings.rec_source; | 1283 | const int prev_rec_source = global_settings.rec_source; |
1199 | #endif | 1284 | #endif |
1200 | |||
1201 | #if (CONFIG_LED == LED_REAL) | 1285 | #if (CONFIG_LED == LED_REAL) |
1202 | /* led is restored at begin of loop / end of function */ | 1286 | /* led is restored at begin of loop / end of function */ |
1203 | led(false); | 1287 | led(false); |
@@ -1221,6 +1305,10 @@ bool recording_screen(bool no_source) | |||
1221 | && prev_rec_source == AUDIO_SRC_FMRADIO) | 1305 | && prev_rec_source == AUDIO_SRC_FMRADIO) |
1222 | radio_status = FMRADIO_OFF; | 1306 | radio_status = FMRADIO_OFF; |
1223 | #endif | 1307 | #endif |
1308 | /* if countdown timer settings changed in menu, | ||
1309 | stop counting and reset */ | ||
1310 | if (!timer.countdown) | ||
1311 | tick_remove_task(timer_tick_task); | ||
1224 | 1312 | ||
1225 | #if CONFIG_CODEC == SWCODEC | 1313 | #if CONFIG_CODEC == SWCODEC |
1226 | /* reinit after submenu exit */ | 1314 | /* reinit after submenu exit */ |
@@ -1319,6 +1407,9 @@ bool recording_screen(bool no_source) | |||
1319 | break; | 1407 | break; |
1320 | } /* end switch */ | 1408 | } /* end switch */ |
1321 | 1409 | ||
1410 | /* display timer status in status bar if countdown enabled */ | ||
1411 | timer.timer_display = timer.countdown; | ||
1412 | |||
1322 | #ifdef HAVE_AGC | 1413 | #ifdef HAVE_AGC |
1323 | peak_read = !peak_read; | 1414 | peak_read = !peak_read; |
1324 | if (peak_read) { /* every 2nd run of loop */ | 1415 | if (peak_read) { /* every 2nd run of loop */ |
@@ -1369,11 +1460,13 @@ bool recording_screen(bool no_source) | |||
1369 | #endif /* CONFIG_CODEC == SWCODEC */ | 1460 | #endif /* CONFIG_CODEC == SWCODEC */ |
1370 | if ((global_settings.rec_sizesplit) && (global_settings.rec_split_method)) | 1461 | if ((global_settings.rec_sizesplit) && (global_settings.rec_split_method)) |
1371 | { | 1462 | { |
1463 | countdown_offset = 1; | ||
1372 | dmb = dsize/1024/1024; | 1464 | dmb = dsize/1024/1024; |
1373 | snprintf(buf, sizeof(buf), "%s %dMB", | 1465 | snprintf(buf, sizeof(buf), "%s %dMB", |
1374 | str(LANG_SYSFONT_SPLIT_SIZE), dmb); | 1466 | str(LANG_SYSFONT_SPLIT_SIZE), dmb); |
1375 | } | 1467 | } |
1376 | else | 1468 | /* only display recording time if countdown timer is off */ |
1469 | else if (!timer.days && !timer.hrs && !timer.mins && !timer.secs) | ||
1377 | { | 1470 | { |
1378 | hours = seconds / 3600; | 1471 | hours = seconds / 3600; |
1379 | minutes = (seconds - (hours * 3600)) / 60; | 1472 | minutes = (seconds - (hours * 3600)) / 60; |
@@ -1381,6 +1474,11 @@ bool recording_screen(bool no_source) | |||
1381 | str(LANG_SYSFONT_RECORDING_TIME), | 1474 | str(LANG_SYSFONT_RECORDING_TIME), |
1382 | hours, minutes, seconds%60); | 1475 | hours, minutes, seconds%60); |
1383 | } | 1476 | } |
1477 | else | ||
1478 | { | ||
1479 | countdown_offset = 0; | ||
1480 | snprintf(buf, 32, ""); | ||
1481 | } | ||
1384 | 1482 | ||
1385 | for(i = 0; i < screen_update; i++) | 1483 | for(i = 0; i < screen_update; i++) |
1386 | screens[i].puts(0, 0, buf); | 1484 | screens[i].puts(0, 0, buf); |
@@ -1404,7 +1502,8 @@ bool recording_screen(bool no_source) | |||
1404 | str(LANG_SYSFONT_RECORD_TIMESPLIT_REC), | 1502 | str(LANG_SYSFONT_RECORD_TIMESPLIT_REC), |
1405 | dhours, dminutes); | 1503 | dhours, dminutes); |
1406 | } | 1504 | } |
1407 | else | 1505 | /* only display recording size if countdown timer is off */ |
1506 | else if (!timer.days && !timer.hrs && !timer.mins && !timer.secs) | ||
1408 | { | 1507 | { |
1409 | output_dyn_value(buf2, sizeof buf2, | 1508 | output_dyn_value(buf2, sizeof buf2, |
1410 | num_recorded_bytes, | 1509 | num_recorded_bytes, |
@@ -1416,6 +1515,16 @@ bool recording_screen(bool no_source) | |||
1416 | for(i = 0; i < screen_update; i++) | 1515 | for(i = 0; i < screen_update; i++) |
1417 | screens[i].puts(0, 1, buf); | 1516 | screens[i].puts(0, 1, buf); |
1418 | 1517 | ||
1518 | /* display countdown timer if set */ | ||
1519 | if (timer.days || timer.hrs || timer.mins || timer.secs) | ||
1520 | { | ||
1521 | snprintf(buf, 32, "%s %d:%02d:%02d:%02d", str(LANG_REC_TIMER), | ||
1522 | timer.days, timer.hrs, timer.mins, timer.secs); | ||
1523 | |||
1524 | for(i = 0; i < screen_update; i++) | ||
1525 | screens[i].puts(0, countdown_offset, buf); | ||
1526 | } | ||
1527 | |||
1419 | for(i = 0; i < screen_update; i++) | 1528 | for(i = 0; i < screen_update; i++) |
1420 | { | 1529 | { |
1421 | if (filename_offset[i] > 0) | 1530 | if (filename_offset[i] > 0) |
@@ -1449,11 +1558,36 @@ bool recording_screen(bool no_source) | |||
1449 | rec_new_file(); | 1558 | rec_new_file(); |
1450 | last_seconds = 0; | 1559 | last_seconds = 0; |
1451 | } | 1560 | } |
1452 | else | 1561 | else if (repeat_timer_start) |
1453 | { | 1562 | { |
1454 | peak_meter_trigger(false); | 1563 | peak_meter_trigger(false); |
1455 | peak_meter_set_trigger_listener(NULL); | 1564 | peak_meter_set_trigger_listener(NULL); |
1456 | audio_stop_recording(); | 1565 | audio_stop_recording(); |
1566 | |||
1567 | /* stop any more attempts to access this code until a new | ||
1568 | recording is started */ | ||
1569 | repeat_timer_start = false; | ||
1570 | |||
1571 | /* start repeat countdown if set and only if | ||
1572 | stop time < repeat time */ | ||
1573 | if (timer.repeater) | ||
1574 | { | ||
1575 | repeat_timer -= dseconds; | ||
1576 | timer.days = repeat_timer / (3600 * 24); | ||
1577 | timer.hrs = (repeat_timer - (timer.days * 3600 * 24)) / | ||
1578 | 3600; | ||
1579 | timer.mins = (repeat_timer - (timer.hrs * 3600)) / 60; | ||
1580 | timer.secs = prerec; /* add prerecorded time to timer */ | ||
1581 | |||
1582 | /* This is not really a toggle so much as a safety feature | ||
1583 | so that it is impossible to start the timer more than | ||
1584 | once */ | ||
1585 | timer.countdown = !timer.countdown; | ||
1586 | if (timer.countdown) | ||
1587 | tick_add_task(timer_tick_task); | ||
1588 | else | ||
1589 | tick_remove_task(timer_tick_task); | ||
1590 | } | ||
1457 | } | 1591 | } |
1458 | update_countdown = 1; | 1592 | update_countdown = 1; |
1459 | } | 1593 | } |
@@ -2035,6 +2169,12 @@ static bool f3_rec_screen(void) | |||
2035 | } | 2169 | } |
2036 | #endif /* CONFIG_KEYPAD == RECORDER_PAD */ | 2170 | #endif /* CONFIG_KEYPAD == RECORDER_PAD */ |
2037 | 2171 | ||
2172 | struct timer *get_timerstat(void) | ||
2173 | { | ||
2174 | return &timer; | ||
2175 | } | ||
2176 | |||
2177 | |||
2038 | #if CONFIG_CODEC == SWCODEC | 2178 | #if CONFIG_CODEC == SWCODEC |
2039 | void audio_beep(int duration) | 2179 | void audio_beep(int duration) |
2040 | { | 2180 | { |
diff --git a/apps/recorder/recording.h b/apps/recorder/recording.h index 3ca1f35834..4fba37b68a 100644 --- a/apps/recorder/recording.h +++ b/apps/recorder/recording.h | |||
@@ -25,6 +25,22 @@ bool recording_screen(bool no_source); | |||
25 | char *rec_create_filename(char *buf); | 25 | char *rec_create_filename(char *buf); |
26 | int rec_create_directory(void); | 26 | int rec_create_directory(void); |
27 | 27 | ||
28 | struct timer | ||
29 | { | ||
30 | bool countdown; | ||
31 | bool timer_display; | ||
32 | unsigned int days; | ||
33 | unsigned int hrs; | ||
34 | unsigned int mins; | ||
35 | unsigned int secs; | ||
36 | unsigned int days_rpt; | ||
37 | unsigned int hrs_rpt; | ||
38 | unsigned int mins_rpt; | ||
39 | bool repeater; | ||
40 | }; | ||
41 | |||
42 | struct timer *get_timerstat(void); | ||
43 | |||
28 | /* If true, start recording automatically when recording_sreen() is entered */ | 44 | /* If true, start recording automatically when recording_sreen() is entered */ |
29 | extern bool recording_start_automatic; | 45 | extern bool recording_start_automatic; |
30 | 46 | ||
@@ -33,6 +49,7 @@ extern bool recording_start_automatic; | |||
33 | void rec_set_source(int source, unsigned flags); | 49 | void rec_set_source(int source, unsigned flags); |
34 | #endif /* CONFIG_CODEC == SW_CODEC */ | 50 | #endif /* CONFIG_CODEC == SW_CODEC */ |
35 | 51 | ||
52 | struct audio_recording_options; | ||
36 | /* Initializes a recording_options structure with global settings. | 53 | /* Initializes a recording_options structure with global settings. |
37 | pass returned data to audio_set_recording_options or | 54 | pass returned data to audio_set_recording_options or |
38 | rec_set_recording_options */ | 55 | rec_set_recording_options */ |
diff --git a/apps/settings.c b/apps/settings.c index 23b81173bd..e8963b05df 100644 --- a/apps/settings.c +++ b/apps/settings.c | |||
@@ -1245,6 +1245,194 @@ bool set_int(const unsigned char* string, | |||
1245 | return set_int_ex(string, unit, voice_unit, variable, function, | 1245 | return set_int_ex(string, unit, voice_unit, variable, function, |
1246 | step, min, max, formatter, NULL); | 1246 | step, min, max, formatter, NULL); |
1247 | } | 1247 | } |
1248 | |||
1249 | /* Useful for time and other multi integer settings */ | ||
1250 | bool set_multi_int(const char* string, | ||
1251 | const struct opt_items * names, | ||
1252 | struct opt_settings * variable, | ||
1253 | int varcount, | ||
1254 | bool *changes_accepted) | ||
1255 | { | ||
1256 | int i, j, w, h; | ||
1257 | char buf[32]; | ||
1258 | long button; | ||
1259 | int cursor = 0; | ||
1260 | bool done = false; | ||
1261 | int value[varcount]; | ||
1262 | int pos = 0; | ||
1263 | |||
1264 | /* store current values in temp array */ | ||
1265 | for(j = 0; j < varcount; j++) | ||
1266 | value[j] = *(int*)variable[j].setting; | ||
1267 | |||
1268 | /* initialize screen */ | ||
1269 | FOR_NB_SCREENS(i) | ||
1270 | { | ||
1271 | screens[i].clear_display(); | ||
1272 | #ifdef HAVE_LCD_BITMAP | ||
1273 | screens[i].setmargins(0, 8); | ||
1274 | #endif | ||
1275 | } | ||
1276 | |||
1277 | gui_syncstatusbar_draw(&statusbars, true); | ||
1278 | |||
1279 | FOR_NB_SCREENS(i) | ||
1280 | screens[i].getstringsize("3", &w, &h); | ||
1281 | |||
1282 | /* print title */ | ||
1283 | snprintf(buf, sizeof(buf), "%s", string); | ||
1284 | FOR_NB_SCREENS(i) | ||
1285 | screens[i].puts(0, 0, buf); | ||
1286 | |||
1287 | /* print variable names */ | ||
1288 | for(j = 0; j < varcount ; j++) | ||
1289 | { | ||
1290 | if (j > 0) | ||
1291 | { | ||
1292 | snprintf(buf, sizeof(buf), ":"); | ||
1293 | FOR_NB_SCREENS(i) | ||
1294 | screens[i].puts(pos - 2, 1, buf); | ||
1295 | } | ||
1296 | |||
1297 | snprintf(buf, sizeof(buf), "%s", P2STR(names[j].string)); | ||
1298 | FOR_NB_SCREENS(i) | ||
1299 | screens[i].puts(pos, 1, buf); | ||
1300 | |||
1301 | pos += strlen(buf) + 3; | ||
1302 | } | ||
1303 | |||
1304 | /* print button instructions */ | ||
1305 | snprintf(buf, sizeof(buf), "%s", str(LANG_MULTIINT_CONFIRM)); | ||
1306 | FOR_NB_SCREENS(i) | ||
1307 | screens[i].puts(0, 5, buf); | ||
1308 | |||
1309 | while(!done) | ||
1310 | { | ||
1311 | pos = 0; | ||
1312 | |||
1313 | /* print variables */ | ||
1314 | for(j = 0; j < varcount; j++) | ||
1315 | { | ||
1316 | if (j > 0) | ||
1317 | { | ||
1318 | snprintf(buf, sizeof(buf), " :"); | ||
1319 | FOR_NB_SCREENS(i) | ||
1320 | screens[i].puts(pos - 3, 3, buf); | ||
1321 | } | ||
1322 | |||
1323 | snprintf(buf, sizeof(buf), "%d", value[j]); | ||
1324 | |||
1325 | FOR_NB_SCREENS(i) | ||
1326 | screens[i].puts(pos, 3, buf); | ||
1327 | |||
1328 | snprintf(buf, sizeof(buf), "%d", variable[j].setting_max); | ||
1329 | |||
1330 | #ifdef HAVE_LCD_BITMAP | ||
1331 | /* highlight currently selected integer */ | ||
1332 | if (cursor == j) | ||
1333 | { | ||
1334 | FOR_NB_SCREENS(i) | ||
1335 | { | ||
1336 | screens[i].set_drawmode(DRMODE_COMPLEMENT); | ||
1337 | screens[i].fillrect(pos * w - 1, 8 + 3 * h, | ||
1338 | strlen(buf)*w + 1, h); | ||
1339 | screens[i].set_drawmode(DRMODE_SOLID); | ||
1340 | } | ||
1341 | } | ||
1342 | #endif | ||
1343 | |||
1344 | pos += strlen(buf) + 3; | ||
1345 | } | ||
1346 | |||
1347 | #ifdef HAVE_LCD_BITMAP | ||
1348 | FOR_NB_SCREENS(i) | ||
1349 | screens[i].update(); | ||
1350 | #endif | ||
1351 | |||
1352 | button = get_action(CONTEXT_SETTINGS, TIMEOUT_BLOCK); | ||
1353 | |||
1354 | switch (button) | ||
1355 | { | ||
1356 | case ACTION_STD_NEXT: | ||
1357 | cursor ++; | ||
1358 | |||
1359 | if (cursor >= varcount) | ||
1360 | cursor = varcount - 1; | ||
1361 | |||
1362 | if (global_settings.talk_menu) | ||
1363 | talk_id(names[cursor].voice_id, false); | ||
1364 | break; | ||
1365 | |||
1366 | case ACTION_STD_PREV: | ||
1367 | /* cancel if pressing left when cursor | ||
1368 | is already at the far left */ | ||
1369 | if (cursor == 0) | ||
1370 | { | ||
1371 | *changes_accepted = false; | ||
1372 | gui_syncsplash(HZ/2, str(LANG_MENU_SETTING_CANCEL)); | ||
1373 | done = true; | ||
1374 | } | ||
1375 | else | ||
1376 | { | ||
1377 | cursor --; | ||
1378 | |||
1379 | if (cursor < 0) | ||
1380 | cursor = 0; | ||
1381 | |||
1382 | if (global_settings.talk_menu) | ||
1383 | talk_id(names[cursor].voice_id, false); | ||
1384 | } | ||
1385 | break; | ||
1386 | |||
1387 | case ACTION_SETTINGS_INC: | ||
1388 | case ACTION_SETTINGS_INCREPEAT: | ||
1389 | value[cursor] += 1; | ||
1390 | |||
1391 | if (value[cursor] > variable[cursor].setting_max) | ||
1392 | value[cursor] = 0; | ||
1393 | |||
1394 | if (global_settings.talk_menu) | ||
1395 | talk_unit(INT, value[cursor], NULL); | ||
1396 | break; | ||
1397 | |||
1398 | case ACTION_SETTINGS_DEC: | ||
1399 | case ACTION_SETTINGS_DECREPEAT: | ||
1400 | value[cursor] -= 1; | ||
1401 | |||
1402 | if (value[cursor] < 0) | ||
1403 | value[cursor] = variable[cursor].setting_max; | ||
1404 | |||
1405 | if (global_settings.talk_menu) | ||
1406 | talk_unit(INT, value[cursor], NULL); | ||
1407 | break; | ||
1408 | |||
1409 | case ACTION_STD_OK: | ||
1410 | *changes_accepted = true; | ||
1411 | done = true; | ||
1412 | break; | ||
1413 | |||
1414 | case ACTION_STD_CANCEL: | ||
1415 | *changes_accepted = false; | ||
1416 | gui_syncsplash(HZ/2, str(LANG_MENU_SETTING_CANCEL)); | ||
1417 | done = true; | ||
1418 | |||
1419 | default: | ||
1420 | if (default_event_handler(button) == SYS_USB_CONNECTED) | ||
1421 | return true; | ||
1422 | } | ||
1423 | } | ||
1424 | /* store values if accepted */ | ||
1425 | if(*changes_accepted) | ||
1426 | { | ||
1427 | for(j = 0; j < varcount; j++) | ||
1428 | *(int*)variable[j].setting = value[j]; | ||
1429 | } | ||
1430 | |||
1431 | action_signalscreenchange(); | ||
1432 | |||
1433 | return false; | ||
1434 | } | ||
1435 | |||
1248 | /* NOTE: the 'type' parameter specifies the actual type of the variable | 1436 | /* NOTE: the 'type' parameter specifies the actual type of the variable |
1249 | that 'variable' points to. not the value within. Only variables with | 1437 | that 'variable' points to. not the value within. Only variables with |
1250 | type 'bool' should use parameter BOOL. | 1438 | type 'bool' should use parameter BOOL. |
diff --git a/apps/settings.h b/apps/settings.h index 33dfb8546a..9b1124dbae 100644 --- a/apps/settings.h +++ b/apps/settings.h | |||
@@ -247,6 +247,12 @@ struct opt_items { | |||
247 | unsigned const char* string; | 247 | unsigned const char* string; |
248 | long voice_id; | 248 | long voice_id; |
249 | }; | 249 | }; |
250 | |||
251 | struct opt_settings { | ||
252 | int* setting; | ||
253 | int setting_max; | ||
254 | }; | ||
255 | |||
250 | const struct settings_list* find_setting(void* variable, int *id); | 256 | const struct settings_list* find_setting(void* variable, int *id); |
251 | bool cfg_int_to_string(int setting_id, int val, char* buf, int buf_len); | 257 | bool cfg_int_to_string(int setting_id, int val, char* buf, int buf_len); |
252 | void talk_setting(void *global_settings_variable); | 258 | void talk_setting(void *global_settings_variable); |
@@ -264,6 +270,9 @@ bool set_int(const unsigned char* string, const char* unit, int voice_unit, | |||
264 | int* variable, | 270 | int* variable, |
265 | void (*function)(int), int step, int min, int max, | 271 | void (*function)(int), int step, int min, int max, |
266 | void (*formatter)(char*, int, int, const char*) ); | 272 | void (*formatter)(char*, int, int, const char*) ); |
273 | bool set_multi_int(const char* string, const struct opt_items * names, | ||
274 | struct opt_settings * variable, int varcount, | ||
275 | bool * changes_accepted); | ||
267 | /* use this one if you need to create a lang from the value (i.e with TALK_ID()) */ | 276 | /* use this one if you need to create a lang from the value (i.e with TALK_ID()) */ |
268 | bool set_int_ex(const unsigned char* string, const char* unit, int voice_unit, | 277 | bool set_int_ex(const unsigned char* string, const char* unit, int voice_unit, |
269 | int* variable, | 278 | int* variable, |