summaryrefslogtreecommitdiff
path: root/apps/recorder
diff options
context:
space:
mode:
Diffstat (limited to 'apps/recorder')
-rw-r--r--apps/recorder/peakmeter.c56
-rw-r--r--apps/recorder/peakmeter.h4
-rw-r--r--apps/recorder/radio.c4
-rw-r--r--apps/recorder/recording.c95
-rw-r--r--apps/recorder/recording.h15
5 files changed, 138 insertions, 36 deletions
diff --git a/apps/recorder/peakmeter.c b/apps/recorder/peakmeter.c
index 7d97bd3b02..f3f5d67c9c 100644
--- a/apps/recorder/peakmeter.c
+++ b/apps/recorder/peakmeter.c
@@ -16,6 +16,9 @@
16 * KIND, either express or implied. 16 * KIND, either express or implied.
17 * 17 *
18 ****************************************************************************/ 18 ****************************************************************************/
19#ifdef SIMULATOR
20#include <stdlib.h> /* sim uses rand for peakmeter simulation */
21#endif
19#include "config.h" 22#include "config.h"
20#include "mas.h" 23#include "mas.h"
21#include "thread.h" 24#include "thread.h"
@@ -47,7 +50,6 @@
47#endif 50#endif
48 51
49static bool pm_playback = true; /* selects between playback and recording peaks */ 52static bool pm_playback = true; /* selects between playback and recording peaks */
50
51#endif 53#endif
52 54
53static struct meter_scales scales[NB_SCREENS]; 55static struct meter_scales scales[NB_SCREENS];
@@ -74,6 +76,10 @@ static bool pm_clip_right = false;
74static long pm_clip_timeout_l; /* clip hold timeouts */ 76static long pm_clip_timeout_l; /* clip hold timeouts */
75static long pm_clip_timeout_r; 77static long pm_clip_timeout_r;
76 78
79/* clipping counter (only used for recording) */
80static unsigned int pm_clipcount = 0; /* clipping count */
81static bool pm_clipcount_active = false; /* counting or not */
82
77/* Temporarily en- / disables peak meter. This is especially for external 83/* Temporarily en- / disables peak meter. This is especially for external
78 applications to detect if the peak_meter is in use and needs drawing at all */ 84 applications to detect if the peak_meter is in use and needs drawing at all */
79bool peak_meter_enabled = true; 85bool peak_meter_enabled = true;
@@ -491,6 +497,30 @@ void peak_meter_init_times(int release, int hold, int clip_hold)
491} 497}
492 498
493/** 499/**
500 * Enable/disable clip counting
501 */
502void pm_activate_clipcount(bool active)
503{
504 pm_clipcount_active = active;
505}
506
507/**
508 * Get clipping counter value
509 */
510int pm_get_clipcount(void)
511{
512 return pm_clipcount;
513}
514
515/**
516 * Set clipping counter to zero (typically at start of recording or playback)
517 */
518void pm_reset_clipcount(void)
519{
520 pm_clipcount = 0;
521}
522
523/**
494 * Set the source of the peak meter to playback or to 524 * Set the source of the peak meter to playback or to
495 * record. 525 * record.
496 * @param: bool playback - If true playback peak meter is used. 526 * @param: bool playback - If true playback peak meter is used.
@@ -523,6 +553,7 @@ static void set_trig_status(int new_state)
523 } 553 }
524 } 554 }
525} 555}
556
526#endif 557#endif
527 558
528/** 559/**
@@ -535,6 +566,7 @@ static void set_trig_status(int new_state)
535void peak_meter_peek(void) 566void peak_meter_peek(void)
536{ 567{
537 int left, right; 568 int left, right;
569 bool was_clipping = pm_clip_left || pm_clip_right;
538 /* read current values */ 570 /* read current values */
539#if CONFIG_CODEC == SWCODEC 571#if CONFIG_CODEC == SWCODEC
540 if (pm_playback) 572 if (pm_playback)
@@ -585,6 +617,12 @@ void peak_meter_peek(void)
585 current_tick + clip_time_out[pm_clip_hold]; 617 current_tick + clip_time_out[pm_clip_hold];
586 } 618 }
587 619
620 if(!was_clipping && (pm_clip_left || pm_clip_right))
621 {
622 if(pm_clipcount_active)
623 pm_clipcount++;
624 }
625
588 /* peaks are searched -> we have to find the maximum. When 626 /* peaks are searched -> we have to find the maximum. When
589 many calls of peak_meter_peek the maximum value will be 627 many calls of peak_meter_peek the maximum value will be
590 stored in pm_max_xxx. This maximum is reset by the 628 stored in pm_max_xxx. This maximum is reset by the
@@ -757,6 +795,12 @@ static int peak_meter_read_l(void)
757 /* reset pm_max_left so that subsequent calls of peak_meter_peek don't 795 /* reset pm_max_left so that subsequent calls of peak_meter_peek don't
758 get fooled by an old maximum value */ 796 get fooled by an old maximum value */
759 pm_max_left = pm_cur_left; 797 pm_max_left = pm_cur_left;
798
799#ifdef SIMULATOR
800 srand(current_tick);
801 retval = rand()%MAX_PEAK;
802#endif
803
760 return retval; 804 return retval;
761} 805}
762 806
@@ -782,6 +826,12 @@ static int peak_meter_read_r(void)
782 /* reset pm_max_right so that subsequent calls of peak_meter_peek don't 826 /* reset pm_max_right so that subsequent calls of peak_meter_peek don't
783 get fooled by an old maximum value */ 827 get fooled by an old maximum value */
784 pm_max_right = pm_cur_right; 828 pm_max_right = pm_cur_right;
829
830#ifdef SIMULATOR
831 srand(current_tick);
832 retval = rand()%MAX_PEAK;
833#endif
834
785 return retval; 835 return retval;
786} 836}
787 837
@@ -860,7 +910,7 @@ unsigned short peak_meter_scale_value(unsigned short val, int meterwidth)
860void peak_meter_screen(struct screen *display, int x, int y, int height) 910void peak_meter_screen(struct screen *display, int x, int y, int height)
861{ 911{
862 peak_meter_draw(display, &scales[display->screen_type], x, y, 912 peak_meter_draw(display, &scales[display->screen_type], x, y,
863 display->width, height); 913 display->width - x, height);
864} 914}
865/** 915/**
866 * Draws a peak meter in the specified size at the specified position. 916 * Draws a peak meter in the specified size at the specified position.
@@ -1282,7 +1332,7 @@ int peak_meter_draw_get_btn(int x, int y[], int height, int nb_screens)
1282 for(i = 0; i < nb_screens; i++) 1332 for(i = 0; i < nb_screens; i++)
1283 { 1333 {
1284 peak_meter_screen(&screens[i], x, y[i], height); 1334 peak_meter_screen(&screens[i], x, y[i], height);
1285 screens[i].update_rect(x, y[i], screens[i].width, height); 1335 screens[i].update_rect(x, y[i], screens[i].width - x, height);
1286 } 1336 }
1287 next_refresh += HZ / PEAK_METER_FPS; 1337 next_refresh += HZ / PEAK_METER_FPS;
1288 dopeek = true; 1338 dopeek = true;
diff --git a/apps/recorder/peakmeter.h b/apps/recorder/peakmeter.h
index a521f975fa..be121b1aaf 100644
--- a/apps/recorder/peakmeter.h
+++ b/apps/recorder/peakmeter.h
@@ -26,6 +26,10 @@
26extern bool peak_meter_histogram(void); 26extern bool peak_meter_histogram(void);
27#endif 27#endif
28 28
29extern int pm_get_clipcount(void);
30extern void pm_reset_clipcount(void);
31extern void pm_activate_clipcount(bool active);
32
29extern bool peak_meter_enabled; 33extern bool peak_meter_enabled;
30 34
31extern void peak_meter_playback(bool playback); 35extern void peak_meter_playback(bool playback);
diff --git a/apps/recorder/radio.c b/apps/recorder/radio.c
index 7513a26a1f..b95bffe696 100644
--- a/apps/recorder/radio.c
+++ b/apps/recorder/radio.c
@@ -582,13 +582,13 @@ int radio_screen(void)
582#ifndef SIMULATOR 582#ifndef SIMULATOR
583 if(audio_status() == AUDIO_STATUS_RECORD) 583 if(audio_status() == AUDIO_STATUS_RECORD)
584 { 584 {
585 rec_new_file(); 585 rec_command(RECORDING_CMD_START_NEWFILE);
586 update_screen = true; 586 update_screen = true;
587 } 587 }
588 else 588 else
589 { 589 {
590 have_recorded = true; 590 have_recorded = true;
591 rec_record(); 591 rec_command(RECORDING_CMD_START);
592 update_screen = true; 592 update_screen = true;
593 } 593 }
594#endif /* SIMULATOR */ 594#endif /* SIMULATOR */
diff --git a/apps/recorder/recording.c b/apps/recorder/recording.c
index 68528c71c0..053eecd844 100644
--- a/apps/recorder/recording.c
+++ b/apps/recorder/recording.c
@@ -694,19 +694,38 @@ void rec_set_recording_options(struct audio_recording_options *options)
694 audio_set_recording_options(options); 694 audio_set_recording_options(options);
695} 695}
696 696
697/* steals mp3 buffer, creates unique filename and starts recording */ 697void rec_command(enum recording_command cmd)
698void rec_record(void)
699{ 698{
699 switch(cmd)
700 {
701 case RECORDING_CMD_STOP:
702 pm_activate_clipcount(false);
703 audio_stop_recording();
704 break;
705 case RECORDING_CMD_START:
706 /* steal mp3 buffer, create unique filename and start recording */
707 pm_reset_clipcount();
708 pm_activate_clipcount(true);
700#if CONFIG_CODEC != SWCODEC 709#if CONFIG_CODEC != SWCODEC
701 talk_buffer_steal(); /* we use the mp3 buffer */ 710 talk_buffer_steal(); /* we use the mp3 buffer */
702#endif 711#endif
703 audio_record(rec_create_filename(path_buffer)); 712 audio_record(rec_create_filename(path_buffer));
704} 713 break;
705 714 case RECORDING_CMD_START_NEWFILE:
706/* creates unique filename and starts recording */ 715 /* create unique filename and start recording*/
707void rec_new_file(void) 716 pm_reset_clipcount();
708{ 717 pm_activate_clipcount(true); /* just to be sure */
709 audio_new_file(rec_create_filename(path_buffer)); 718 audio_new_file(rec_create_filename(path_buffer));
719 break;
720 case RECORDING_CMD_PAUSE:
721 pm_activate_clipcount(false);
722 audio_pause_recording();
723 break;
724 case RECORDING_CMD_RESUME:
725 pm_activate_clipcount(true);
726 audio_resume_recording();
727 break;
728 }
710} 729}
711 730
712/* used in trigger_listerner and recording_screen */ 731/* used in trigger_listerner and recording_screen */
@@ -725,7 +744,7 @@ static void trigger_listener(int trigger_status)
725 if(!(audio_status() & AUDIO_STATUS_RECORD)) 744 if(!(audio_status() & AUDIO_STATUS_RECORD))
726 { 745 {
727 rec_status |= RCSTAT_HAVE_RECORDED; 746 rec_status |= RCSTAT_HAVE_RECORDED;
728 rec_record(); 747 rec_command(RECORDING_CMD_START);
729#if CONFIG_CODEC != SWCODEC 748#if CONFIG_CODEC != SWCODEC
730 /* give control to mpeg thread so that it can start 749 /* give control to mpeg thread so that it can start
731 recording */ 750 recording */
@@ -738,11 +757,13 @@ static void trigger_listener(int trigger_status)
738 { 757 {
739 if((audio_status() & AUDIO_STATUS_PAUSE) && 758 if((audio_status() & AUDIO_STATUS_PAUSE) &&
740 (global_settings.rec_trigger_type == 1)) 759 (global_settings.rec_trigger_type == 1))
741 audio_resume_recording(); 760 {
761 rec_command(RECORDING_CMD_RESUME);
762 }
742 /* New file on trig start*/ 763 /* New file on trig start*/
743 else if (global_settings.rec_trigger_type != 2) 764 else if (global_settings.rec_trigger_type != 2)
744 { 765 {
745 rec_new_file(); 766 rec_command(RECORDING_CMD_START_NEWFILE);
746 /* tell recording_screen to reset the time */ 767 /* tell recording_screen to reset the time */
747 last_seconds = 0; 768 last_seconds = 0;
748 } 769 }
@@ -756,15 +777,15 @@ static void trigger_listener(int trigger_status)
756 switch(global_settings.rec_trigger_type) 777 switch(global_settings.rec_trigger_type)
757 { 778 {
758 case 0: /* Stop */ 779 case 0: /* Stop */
759 audio_stop_recording(); 780 rec_command(RECORDING_CMD_STOP);
760 break; 781 break;
761 782
762 case 1: /* Pause */ 783 case 1: /* Pause */
763 audio_pause_recording(); 784 rec_command(RECORDING_CMD_PAUSE);
764 break; 785 break;
765 786
766 case 2: /* New file on trig stop*/ 787 case 2: /* New file on trig stop*/
767 rec_new_file(); 788 rec_command(RECORDING_CMD_START_NEWFILE);
768 /* tell recording_screen to reset the time */ 789 /* tell recording_screen to reset the time */
769 last_seconds = 0; 790 last_seconds = 0;
770 break; 791 break;
@@ -825,6 +846,9 @@ bool recording_screen(bool no_source)
825 int trig_xpos[NB_SCREENS]; 846 int trig_xpos[NB_SCREENS];
826 int trig_ypos[NB_SCREENS]; 847 int trig_ypos[NB_SCREENS];
827 int trig_width[NB_SCREENS]; 848 int trig_width[NB_SCREENS];
849 /* pm_x = offset pm to put clipcount in front.
850 Use lcd_getstringsize() when not using SYSFONT */
851 int pm_x = global_settings.peak_meter_clipcounter ? 30 : 0;
828 852
829 static const unsigned char *byte_units[] = { 853 static const unsigned char *byte_units[] = {
830 ID2P(LANG_BYTE), 854 ID2P(LANG_BYTE),
@@ -881,6 +905,8 @@ bool recording_screen(bool no_source)
881 rec_init_filename(); 905 rec_init_filename();
882#endif 906#endif
883 907
908 pm_reset_clipcount();
909 pm_activate_clipcount(false);
884 settings_apply_trigger(); 910 settings_apply_trigger();
885 911
886#ifdef HAVE_AGC 912#ifdef HAVE_AGC
@@ -973,7 +999,7 @@ bool recording_screen(bool no_source)
973#endif /* CONFIG_LED */ 999#endif /* CONFIG_LED */
974 1000
975 /* Wait for a button a while (HZ/10) drawing the peak meter */ 1001 /* Wait for a button a while (HZ/10) drawing the peak meter */
976 button = peak_meter_draw_get_btn(0, pm_y, h * PM_HEIGHT, screen_update); 1002 button = peak_meter_draw_get_btn(pm_x, pm_y, h * PM_HEIGHT, screen_update);
977 1003
978 if (last_audio_stat != audio_stat) 1004 if (last_audio_stat != audio_stat)
979 { 1005 {
@@ -1021,7 +1047,7 @@ bool recording_screen(bool no_source)
1021 1047
1022 if(audio_stat & AUDIO_STATUS_RECORD) 1048 if(audio_stat & AUDIO_STATUS_RECORD)
1023 { 1049 {
1024 audio_stop_recording(); 1050 rec_command(RECORDING_CMD_STOP);
1025 } 1051 }
1026 else 1052 else
1027 { 1053 {
@@ -1045,7 +1071,7 @@ bool recording_screen(bool no_source)
1045 { 1071 {
1046 /* manual recording */ 1072 /* manual recording */
1047 rec_status |= RCSTAT_HAVE_RECORDED; 1073 rec_status |= RCSTAT_HAVE_RECORDED;
1048 rec_record(); 1074 rec_command(RECORDING_CMD_START);
1049 last_seconds = 0; 1075 last_seconds = 0;
1050 if (global_settings.talk_menu) 1076 if (global_settings.talk_menu)
1051 { 1077 {
@@ -1068,7 +1094,7 @@ bool recording_screen(bool no_source)
1068 /*if new file button pressed, start new file */ 1094 /*if new file button pressed, start new file */
1069 if (button == ACTION_REC_NEWFILE) 1095 if (button == ACTION_REC_NEWFILE)
1070 { 1096 {
1071 rec_new_file(); 1097 rec_command(RECORDING_CMD_START_NEWFILE);
1072 last_seconds = 0; 1098 last_seconds = 0;
1073 } 1099 }
1074 else 1100 else
@@ -1076,7 +1102,7 @@ bool recording_screen(bool no_source)
1076 { 1102 {
1077 if(audio_stat & AUDIO_STATUS_PAUSE) 1103 if(audio_stat & AUDIO_STATUS_PAUSE)
1078 { 1104 {
1079 audio_resume_recording(); 1105 rec_command(RECORDING_CMD_RESUME);
1080 if (global_settings.talk_menu) 1106 if (global_settings.talk_menu)
1081 { 1107 {
1082 /* no voice possible here, but a beep */ 1108 /* no voice possible here, but a beep */
@@ -1085,7 +1111,7 @@ bool recording_screen(bool no_source)
1085 } 1111 }
1086 else 1112 else
1087 { 1113 {
1088 audio_pause_recording(); 1114 rec_command(RECORDING_CMD_PAUSE);
1089 } 1115 }
1090 } 1116 }
1091 } 1117 }
@@ -1332,7 +1358,7 @@ bool recording_screen(bool no_source)
1332 case ACTION_REC_F3: 1358 case ACTION_REC_F3:
1333 if(audio_stat & AUDIO_STATUS_RECORD) 1359 if(audio_stat & AUDIO_STATUS_RECORD)
1334 { 1360 {
1335 rec_new_file(); 1361 rec_command(RECORDING_CMD_START_NEWFILE);
1336 last_seconds = 0; 1362 last_seconds = 0;
1337 } 1363 }
1338 else 1364 else
@@ -1497,18 +1523,33 @@ bool recording_screen(bool no_source)
1497 if (!(global_settings.rec_split_type) 1523 if (!(global_settings.rec_split_type)
1498 || (num_recorded_bytes >= MAX_FILE_SIZE)) 1524 || (num_recorded_bytes >= MAX_FILE_SIZE))
1499 { 1525 {
1500 rec_new_file(); 1526 rec_command(RECORDING_CMD_START_NEWFILE);
1501 last_seconds = 0; 1527 last_seconds = 0;
1502 } 1528 }
1503 else 1529 else
1504 { 1530 {
1505 peak_meter_trigger(false); 1531 peak_meter_trigger(false);
1506 peak_meter_set_trigger_listener(NULL); 1532 peak_meter_set_trigger_listener(NULL);
1507 audio_stop_recording(); 1533 rec_command(RECORDING_CMD_STOP);
1508 } 1534 }
1509 update_countdown = 1; 1535 update_countdown = 1;
1510 } 1536 }
1511 1537
1538 /* draw the clipcounter just in front of the peakmeter */
1539 if(global_settings.peak_meter_clipcounter)
1540 {
1541 char clpstr[32];
1542 snprintf(clpstr, 32, "%4d", pm_get_clipcount());
1543 for(i = 0; i < screen_update; i++)
1544 {
1545 if(PM_HEIGHT > 1)
1546 screens[i].puts(0, 2 + filename_offset[i],
1547 str(LANG_PM_CLIPCOUNT));
1548 screens[i].puts(0, 1 + PM_HEIGHT + filename_offset[i],
1549 clpstr);
1550 }
1551 }
1552
1512 snprintf(buf, sizeof(buf), "%s: %s", str(LANG_SYSFONT_VOLUME), 1553 snprintf(buf, sizeof(buf), "%s: %s", str(LANG_SYSFONT_VOLUME),
1513 fmt_gain(SOUND_VOLUME, 1554 fmt_gain(SOUND_VOLUME,
1514 global_settings.volume, 1555 global_settings.volume,
@@ -1749,7 +1790,7 @@ bool recording_screen(bool no_source)
1749 for(i = 0; i < screen_update; i++) 1790 for(i = 0; i < screen_update; i++)
1750 { 1791 {
1751 gui_statusbar_draw(&(statusbars.statusbars[i]), true); 1792 gui_statusbar_draw(&(statusbars.statusbars[i]), true);
1752 peak_meter_screen(&screens[i], 0, pm_y[i], h*PM_HEIGHT); 1793 peak_meter_screen(&screens[i], pm_x, pm_y[i], h*PM_HEIGHT);
1753 screens[i].update(); 1794 screens[i].update();
1754 } 1795 }
1755 1796
@@ -1805,7 +1846,7 @@ bool recording_screen(bool no_source)
1805 } 1846 }
1806 1847
1807#if CONFIG_CODEC == SWCODEC 1848#if CONFIG_CODEC == SWCODEC
1808 audio_stop_recording(); 1849 rec_command(RECORDING_CMD_STOP);
1809 audio_close_recording(); 1850 audio_close_recording();
1810 1851
1811#ifdef HAVE_FMRADIO_REC 1852#ifdef HAVE_FMRADIO_REC
diff --git a/apps/recorder/recording.h b/apps/recorder/recording.h
index 2c3869a4fb..a622f01d40 100644
--- a/apps/recorder/recording.h
+++ b/apps/recorder/recording.h
@@ -42,10 +42,17 @@ void rec_init_recording_options(struct audio_recording_options *options);
42/* SRCF_RECORDING is implied for SWCODEC */ 42/* SRCF_RECORDING is implied for SWCODEC */
43void rec_set_recording_options(struct audio_recording_options *options); 43void rec_set_recording_options(struct audio_recording_options *options);
44 44
45/* steals mp3 buffer, creates unique filename and starts recording */ 45enum recording_command
46void rec_record(void); 46{
47 RECORDING_CMD_STOP,
48 RECORDING_CMD_START, /* steal mp3 buffer, create unique filename and
49 start recording */
50 RECORDING_CMD_START_NEWFILE, /* create unique filename and start recording*/
51 RECORDING_CMD_PAUSE,
52 RECORDING_CMD_RESUME
53};
47 54
48/* creates unique filename and starts recording */ 55/* centralized way to start/stop/... recording */
49void rec_new_file(void); 56void rec_command(enum recording_command rec_cmd);
50 57
51#endif /* RECORDING_H */ 58#endif /* RECORDING_H */