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/recorder | |
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/recorder')
-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 |
4 files changed, 179 insertions, 7 deletions
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 */ |