summaryrefslogtreecommitdiff
path: root/apps/recorder
diff options
context:
space:
mode:
Diffstat (limited to 'apps/recorder')
-rw-r--r--apps/recorder/icons.c10
-rw-r--r--apps/recorder/icons.h7
-rw-r--r--apps/recorder/recording.c152
-rw-r--r--apps/recorder/recording.h17
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
47const 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
47const unsigned char bitmap_icons_6x8[][6] = 55const 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
52enum 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 */
54enum icons_6x8 { 60enum 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
146extern const unsigned char bitmap_icons_5x8[Icon5x8Last][5]; 152extern const unsigned char bitmap_icons_5x8[Icon5x8Last][5];
153extern const unsigned char bitmap_icons_7x7[Icon7x7Last][7];
147extern const unsigned char bitmap_icons_6x8[Icon6x8Last][6]; 154extern const unsigned char bitmap_icons_6x8[Icon6x8Last][6];
148extern const unsigned char bitmap_icons_7x8[Icon7x8Last][7]; 155extern const unsigned char bitmap_icons_7x8[Icon7x8Last][7];
149extern const unsigned char bitmap_icon_disk[]; 156extern 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
73static struct timer timer;
74
73static bool in_screen = false; 75static bool in_screen = false;
74 76
75bool in_recording_screen(void) 77bool 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 */
751void 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
748bool recording_start_automatic = false; 781bool recording_start_automatic = false;
749 782
750bool recording_screen(bool no_source) 783bool 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
2172struct timer *get_timerstat(void)
2173{
2174 return &timer;
2175}
2176
2177
2038#if CONFIG_CODEC == SWCODEC 2178#if CONFIG_CODEC == SWCODEC
2039void audio_beep(int duration) 2179void 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);
25char *rec_create_filename(char *buf); 25char *rec_create_filename(char *buf);
26int rec_create_directory(void); 26int rec_create_directory(void);
27 27
28struct 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
42struct 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 */
29extern bool recording_start_automatic; 45extern bool recording_start_automatic;
30 46
@@ -33,6 +49,7 @@ extern bool recording_start_automatic;
33void rec_set_source(int source, unsigned flags); 49void rec_set_source(int source, unsigned flags);
34#endif /* CONFIG_CODEC == SW_CODEC */ 50#endif /* CONFIG_CODEC == SW_CODEC */
35 51
52struct 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 */