diff --git a/apps/lang/english.lang b/apps/lang/english.lang index 02296bd2ab..de696c6648 100644 --- a/apps/lang/english.lang +++ b/apps/lang/english.lang @@ -11122,3 +11122,31 @@ rtc: "oh" + + id: LANG_PM_CLIPCOUNTER + desc: in settings, for recording peak meter + user: + + *: "Peak meter clipcounter" + + + *: "Peak meter clipcounter" + + + *: "" + + + + id: LANG_PM_CLIPCOUNT + desc: in recording GUI, for recording peak meter + user: + + *: "CLIP:" + + + *: "CLIP:" + + + *: "" + + diff --git a/apps/menus/display_menu.c b/apps/menus/display_menu.c index 92afc304db..a523753119 100644 --- a/apps/menus/display_menu.c +++ b/apps/menus/display_menu.c @@ -401,7 +401,8 @@ MENUITEM_SETTING(peak_meter_hold, &global_settings.peak_meter_hold, peakmeter_callback); MENUITEM_SETTING(peak_meter_clip_hold, &global_settings.peak_meter_clip_hold, peakmeter_callback); - +MENUITEM_SETTING(peak_meter_clipcounter, + &global_settings.peak_meter_clipcounter, NULL); MENUITEM_SETTING(peak_meter_release, &global_settings.peak_meter_release, peakmeter_callback); /** @@ -529,7 +530,7 @@ MENUITEM_FUNCTION(peak_meter_max_item, 0, ID2P(LANG_PM_MAX), peak_meter_max, NULL, NULL, Icon_NOICON); MAKE_MENU(peak_meter_menu, ID2P(LANG_PM_MENU), NULL, Icon_NOICON, &peak_meter_release, &peak_meter_hold, - &peak_meter_clip_hold, + &peak_meter_clip_hold, &peak_meter_clipcounter, &peak_meter_scale_item, &peak_meter_min_item, &peak_meter_max_item); #endif /* HAVE_LCD_BITMAP */ /* PEAK METER MENU */ diff --git a/apps/misc.c b/apps/misc.c index 23c332af2f..3d361f4ccb 100644 --- a/apps/misc.c +++ b/apps/misc.c @@ -53,7 +53,9 @@ #endif #include "tree.h" #include "eeprom_settings.h" - +#ifdef HAVE_RECORDING +#include "recording.h" +#endif #ifdef HAVE_LCD_BITMAP #include "bmp.h" #include "icons.h" @@ -659,7 +661,7 @@ static bool clean_shutdown(void (*callback)(void *), void *parameter) #if defined(HAVE_RECORDING) && CONFIG_CODEC == SWCODEC if (audio_stat & AUDIO_STATUS_RECORD) { - audio_stop_recording(); + rec_command(RECORDING_CMD_STOP); /* wait for stop to complete */ while (audio_status() & AUDIO_STATUS_RECORD) sleep(1); 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 @@ * KIND, either express or implied. * ****************************************************************************/ +#ifdef SIMULATOR +#include /* sim uses rand for peakmeter simulation */ +#endif #include "config.h" #include "mas.h" #include "thread.h" @@ -47,7 +50,6 @@ #endif static bool pm_playback = true; /* selects between playback and recording peaks */ - #endif static struct meter_scales scales[NB_SCREENS]; @@ -74,6 +76,10 @@ static bool pm_clip_right = false; static long pm_clip_timeout_l; /* clip hold timeouts */ static long pm_clip_timeout_r; +/* clipping counter (only used for recording) */ +static unsigned int pm_clipcount = 0; /* clipping count */ +static bool pm_clipcount_active = false; /* counting or not */ + /* Temporarily en- / disables peak meter. This is especially for external applications to detect if the peak_meter is in use and needs drawing at all */ bool peak_meter_enabled = true; @@ -490,6 +496,30 @@ void peak_meter_init_times(int release, int hold, int clip_hold) pm_clip_hold = clip_hold; } +/** + * Enable/disable clip counting + */ +void pm_activate_clipcount(bool active) +{ + pm_clipcount_active = active; +} + +/** + * Get clipping counter value + */ +int pm_get_clipcount(void) +{ + return pm_clipcount; +} + +/** + * Set clipping counter to zero (typically at start of recording or playback) + */ +void pm_reset_clipcount(void) +{ + pm_clipcount = 0; +} + /** * Set the source of the peak meter to playback or to * record. @@ -523,6 +553,7 @@ static void set_trig_status(int new_state) } } } + #endif /** @@ -535,6 +566,7 @@ static void set_trig_status(int new_state) void peak_meter_peek(void) { int left, right; + bool was_clipping = pm_clip_left || pm_clip_right; /* read current values */ #if CONFIG_CODEC == SWCODEC if (pm_playback) @@ -585,6 +617,12 @@ void peak_meter_peek(void) current_tick + clip_time_out[pm_clip_hold]; } + if(!was_clipping && (pm_clip_left || pm_clip_right)) + { + if(pm_clipcount_active) + pm_clipcount++; + } + /* peaks are searched -> we have to find the maximum. When many calls of peak_meter_peek the maximum value will be stored in pm_max_xxx. This maximum is reset by the @@ -757,6 +795,12 @@ static int peak_meter_read_l(void) /* reset pm_max_left so that subsequent calls of peak_meter_peek don't get fooled by an old maximum value */ pm_max_left = pm_cur_left; + +#ifdef SIMULATOR + srand(current_tick); + retval = rand()%MAX_PEAK; +#endif + return retval; } @@ -782,6 +826,12 @@ static int peak_meter_read_r(void) /* reset pm_max_right so that subsequent calls of peak_meter_peek don't get fooled by an old maximum value */ pm_max_right = pm_cur_right; + +#ifdef SIMULATOR + srand(current_tick); + retval = rand()%MAX_PEAK; +#endif + return retval; } @@ -860,7 +910,7 @@ unsigned short peak_meter_scale_value(unsigned short val, int meterwidth) void peak_meter_screen(struct screen *display, int x, int y, int height) { peak_meter_draw(display, &scales[display->screen_type], x, y, - display->width, height); + display->width - x, height); } /** * 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) for(i = 0; i < nb_screens; i++) { peak_meter_screen(&screens[i], x, y[i], height); - screens[i].update_rect(x, y[i], screens[i].width, height); + screens[i].update_rect(x, y[i], screens[i].width - x, height); } next_refresh += HZ / PEAK_METER_FPS; 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 @@ extern bool peak_meter_histogram(void); #endif +extern int pm_get_clipcount(void); +extern void pm_reset_clipcount(void); +extern void pm_activate_clipcount(bool active); + extern bool peak_meter_enabled; extern 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) #ifndef SIMULATOR if(audio_status() == AUDIO_STATUS_RECORD) { - rec_new_file(); + rec_command(RECORDING_CMD_START_NEWFILE); update_screen = true; } else { have_recorded = true; - rec_record(); + rec_command(RECORDING_CMD_START); update_screen = true; } #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) audio_set_recording_options(options); } -/* steals mp3 buffer, creates unique filename and starts recording */ -void rec_record(void) +void rec_command(enum recording_command cmd) { + switch(cmd) + { + case RECORDING_CMD_STOP: + pm_activate_clipcount(false); + audio_stop_recording(); + break; + case RECORDING_CMD_START: + /* steal mp3 buffer, create unique filename and start recording */ + pm_reset_clipcount(); + pm_activate_clipcount(true); #if CONFIG_CODEC != SWCODEC - talk_buffer_steal(); /* we use the mp3 buffer */ + talk_buffer_steal(); /* we use the mp3 buffer */ #endif - audio_record(rec_create_filename(path_buffer)); -} - -/* creates unique filename and starts recording */ -void rec_new_file(void) -{ - audio_new_file(rec_create_filename(path_buffer)); + audio_record(rec_create_filename(path_buffer)); + break; + case RECORDING_CMD_START_NEWFILE: + /* create unique filename and start recording*/ + pm_reset_clipcount(); + pm_activate_clipcount(true); /* just to be sure */ + audio_new_file(rec_create_filename(path_buffer)); + break; + case RECORDING_CMD_PAUSE: + pm_activate_clipcount(false); + audio_pause_recording(); + break; + case RECORDING_CMD_RESUME: + pm_activate_clipcount(true); + audio_resume_recording(); + break; + } } /* used in trigger_listerner and recording_screen */ @@ -725,7 +744,7 @@ static void trigger_listener(int trigger_status) if(!(audio_status() & AUDIO_STATUS_RECORD)) { rec_status |= RCSTAT_HAVE_RECORDED; - rec_record(); + rec_command(RECORDING_CMD_START); #if CONFIG_CODEC != SWCODEC /* give control to mpeg thread so that it can start recording */ @@ -738,11 +757,13 @@ static void trigger_listener(int trigger_status) { if((audio_status() & AUDIO_STATUS_PAUSE) && (global_settings.rec_trigger_type == 1)) - audio_resume_recording(); + { + rec_command(RECORDING_CMD_RESUME); + } /* New file on trig start*/ else if (global_settings.rec_trigger_type != 2) { - rec_new_file(); + rec_command(RECORDING_CMD_START_NEWFILE); /* tell recording_screen to reset the time */ last_seconds = 0; } @@ -756,15 +777,15 @@ static void trigger_listener(int trigger_status) switch(global_settings.rec_trigger_type) { case 0: /* Stop */ - audio_stop_recording(); + rec_command(RECORDING_CMD_STOP); break; case 1: /* Pause */ - audio_pause_recording(); + rec_command(RECORDING_CMD_PAUSE); break; case 2: /* New file on trig stop*/ - rec_new_file(); + rec_command(RECORDING_CMD_START_NEWFILE); /* tell recording_screen to reset the time */ last_seconds = 0; break; @@ -825,6 +846,9 @@ bool recording_screen(bool no_source) int trig_xpos[NB_SCREENS]; int trig_ypos[NB_SCREENS]; int trig_width[NB_SCREENS]; + /* pm_x = offset pm to put clipcount in front. + Use lcd_getstringsize() when not using SYSFONT */ + int pm_x = global_settings.peak_meter_clipcounter ? 30 : 0; static const unsigned char *byte_units[] = { ID2P(LANG_BYTE), @@ -881,6 +905,8 @@ bool recording_screen(bool no_source) rec_init_filename(); #endif + pm_reset_clipcount(); + pm_activate_clipcount(false); settings_apply_trigger(); #ifdef HAVE_AGC @@ -973,7 +999,7 @@ bool recording_screen(bool no_source) #endif /* CONFIG_LED */ /* Wait for a button a while (HZ/10) drawing the peak meter */ - button = peak_meter_draw_get_btn(0, pm_y, h * PM_HEIGHT, screen_update); + button = peak_meter_draw_get_btn(pm_x, pm_y, h * PM_HEIGHT, screen_update); if (last_audio_stat != audio_stat) { @@ -1021,7 +1047,7 @@ bool recording_screen(bool no_source) if(audio_stat & AUDIO_STATUS_RECORD) { - audio_stop_recording(); + rec_command(RECORDING_CMD_STOP); } else { @@ -1045,7 +1071,7 @@ bool recording_screen(bool no_source) { /* manual recording */ rec_status |= RCSTAT_HAVE_RECORDED; - rec_record(); + rec_command(RECORDING_CMD_START); last_seconds = 0; if (global_settings.talk_menu) { @@ -1068,7 +1094,7 @@ bool recording_screen(bool no_source) /*if new file button pressed, start new file */ if (button == ACTION_REC_NEWFILE) { - rec_new_file(); + rec_command(RECORDING_CMD_START_NEWFILE); last_seconds = 0; } else @@ -1076,7 +1102,7 @@ bool recording_screen(bool no_source) { if(audio_stat & AUDIO_STATUS_PAUSE) { - audio_resume_recording(); + rec_command(RECORDING_CMD_RESUME); if (global_settings.talk_menu) { /* no voice possible here, but a beep */ @@ -1085,7 +1111,7 @@ bool recording_screen(bool no_source) } else { - audio_pause_recording(); + rec_command(RECORDING_CMD_PAUSE); } } } @@ -1332,7 +1358,7 @@ bool recording_screen(bool no_source) case ACTION_REC_F3: if(audio_stat & AUDIO_STATUS_RECORD) { - rec_new_file(); + rec_command(RECORDING_CMD_START_NEWFILE); last_seconds = 0; } else @@ -1497,18 +1523,33 @@ bool recording_screen(bool no_source) if (!(global_settings.rec_split_type) || (num_recorded_bytes >= MAX_FILE_SIZE)) { - rec_new_file(); + rec_command(RECORDING_CMD_START_NEWFILE); last_seconds = 0; } else { peak_meter_trigger(false); peak_meter_set_trigger_listener(NULL); - audio_stop_recording(); + rec_command(RECORDING_CMD_STOP); } update_countdown = 1; } + /* draw the clipcounter just in front of the peakmeter */ + if(global_settings.peak_meter_clipcounter) + { + char clpstr[32]; + snprintf(clpstr, 32, "%4d", pm_get_clipcount()); + for(i = 0; i < screen_update; i++) + { + if(PM_HEIGHT > 1) + screens[i].puts(0, 2 + filename_offset[i], + str(LANG_PM_CLIPCOUNT)); + screens[i].puts(0, 1 + PM_HEIGHT + filename_offset[i], + clpstr); + } + } + snprintf(buf, sizeof(buf), "%s: %s", str(LANG_SYSFONT_VOLUME), fmt_gain(SOUND_VOLUME, global_settings.volume, @@ -1749,7 +1790,7 @@ bool recording_screen(bool no_source) for(i = 0; i < screen_update; i++) { gui_statusbar_draw(&(statusbars.statusbars[i]), true); - peak_meter_screen(&screens[i], 0, pm_y[i], h*PM_HEIGHT); + peak_meter_screen(&screens[i], pm_x, pm_y[i], h*PM_HEIGHT); screens[i].update(); } @@ -1805,7 +1846,7 @@ bool recording_screen(bool no_source) } #if CONFIG_CODEC == SWCODEC - audio_stop_recording(); + rec_command(RECORDING_CMD_STOP); audio_close_recording(); #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); /* SRCF_RECORDING is implied for SWCODEC */ void rec_set_recording_options(struct audio_recording_options *options); -/* steals mp3 buffer, creates unique filename and starts recording */ -void rec_record(void); +enum recording_command +{ + RECORDING_CMD_STOP, + RECORDING_CMD_START, /* steal mp3 buffer, create unique filename and + start recording */ + RECORDING_CMD_START_NEWFILE, /* create unique filename and start recording*/ + RECORDING_CMD_PAUSE, + RECORDING_CMD_RESUME +}; -/* creates unique filename and starts recording */ -void rec_new_file(void); +/* centralized way to start/stop/... recording */ +void rec_command(enum recording_command rec_cmd); #endif /* RECORDING_H */ diff --git a/apps/settings.h b/apps/settings.h index 0dd21a33eb..39263f8256 100644 --- a/apps/settings.h +++ b/apps/settings.h @@ -465,6 +465,7 @@ struct user_settings bool peak_meter_dbfs; /* show linear or dbfs values */ int peak_meter_min; /* range minimum */ int peak_meter_max; /* range maximum */ + bool peak_meter_clipcounter; /* clipping count indicator */ bool car_adapter_mode; /* 0=off 1=on */ /* show status bar */ diff --git a/apps/settings_list.c b/apps/settings_list.c index 1634a89873..0fc5cd7d4f 100644 --- a/apps/settings_list.c +++ b/apps/settings_list.c @@ -712,6 +712,8 @@ const struct settings_list settings[] = { OFFON_SETTING(0,peak_meter_dbfs,LANG_PM_DBFS,true,"peak meter dbfs",NULL), {F_T_INT,&global_settings.peak_meter_min,LANG_PM_MIN,INT(60),"peak meter min",NULL,UNUSED}, {F_T_INT,&global_settings.peak_meter_max,LANG_PM_MAX,INT(0),"peak meter max",NULL,UNUSED}, + OFFON_SETTING(0,peak_meter_clipcounter,LANG_PM_CLIPCOUNTER,false, + "peak meter clipcounter",NULL), #endif #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) SOUND_SETTING(0, mdb_strength, LANG_MDB_STRENGTH,