summaryrefslogtreecommitdiff
path: root/apps/recorder
diff options
context:
space:
mode:
authorPeter D'Hoye <peter.dhoye@gmail.com>2010-03-03 22:16:08 +0000
committerPeter D'Hoye <peter.dhoye@gmail.com>2010-03-03 22:16:08 +0000
commitbe90f74e89978224a169c793d4e688867dc38b41 (patch)
treedce0af0eb60cd29e421b55a213a3fbfdb993031f /apps/recorder
parent5c80a838e4f6217970998df9d2bef44a9dddc795 (diff)
downloadrockbox-be90f74e89978224a169c793d4e688867dc38b41.zip
rockbox-be90f74e89978224a169c793d4e688867dc38b41.tar.gz
rockbox-be90f74e89978224a169c793d4e688867dc38b41.tar.bz2
rockbox-be90f74e89978224a169c793d4e688867dc38b41.tar.xz
Histogram display on recording screen. Based on the work of Jvo Studer in FS #5021 but reduced and reworked since the recording screen code changed quite a bit since his patch. For now enabled on iriver h1x0 and h3x0 only.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@25007 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/recorder')
-rw-r--r--apps/recorder/peakmeter.c36
-rw-r--r--apps/recorder/recording.c238
2 files changed, 209 insertions, 65 deletions
diff --git a/apps/recorder/peakmeter.c b/apps/recorder/peakmeter.c
index fc68ce4..8f32a83 100644
--- a/apps/recorder/peakmeter.c
+++ b/apps/recorder/peakmeter.c
@@ -66,7 +66,7 @@ static int pm_cur_left; /* current values (last peak_meter_peek) */
static int pm_cur_right;
static int pm_max_left; /* maximum values between peak meter draws */
static int pm_max_right;
-#ifdef HAVE_AGC
+#if defined(HAVE_AGC) || defined(HAVE_RECORDING_HISTOGRAM)
static int pm_peakhold_left; /* max. peak values between peakhold calls */
static int pm_peakhold_right; /* used for AGC and histogram display */
#endif
@@ -799,9 +799,16 @@ static int peak_meter_read_l(void)
{
/* pm_max_left contains the maximum of all peak values that were read
by peak_meter_peek since the last call of peak_meter_read_l */
- int retval = pm_max_left;
+ int retval;
+
+#if defined(SIMULATOR) && (CONFIG_CODEC != SWCODEC)
+ srand(current_tick);
+ pm_max_left = rand()%MAX_PEAK;
+#endif
-#ifdef HAVE_AGC
+ retval = pm_max_left;
+
+#if defined(HAVE_RECORDING_HISTOGRAM) || defined(HAVE_AGC)
/* store max peak value for peak_meter_get_peakhold_x readout */
pm_peakhold_left = MAX(pm_max_left, pm_peakhold_left);
#endif
@@ -812,11 +819,6 @@ static int peak_meter_read_l(void)
get fooled by an old maximum value */
pm_max_left = pm_cur_left;
-#if defined(SIMULATOR) && (CONFIG_CODEC != SWCODEC)
- srand(current_tick);
- retval = rand()%MAX_PEAK;
-#endif
-
return retval;
}
@@ -830,9 +832,16 @@ static int peak_meter_read_r(void)
{
/* peak_meter_r contains the maximum of all peak values that were read
by peak_meter_peek since the last call of peak_meter_read_r */
- int retval = pm_max_right;
+ int retval;
+
+#if defined(SIMULATOR) && (CONFIG_CODEC != SWCODEC)
+ srand(current_tick);
+ pm_max_right = rand()%MAX_PEAK;
+#endif
-#ifdef HAVE_AGC
+ retval = pm_max_right;
+
+#if defined(HAVE_RECORDING_HISTOGRAM) || defined(HAVE_AGC)
/* store max peak value for peak_meter_get_peakhold_x readout */
pm_peakhold_right = MAX(pm_max_right, pm_peakhold_right);
#endif
@@ -843,15 +852,10 @@ static int peak_meter_read_r(void)
get fooled by an old maximum value */
pm_max_right = pm_cur_right;
-#if defined(SIMULATOR) && (CONFIG_CODEC != SWCODEC)
- srand(current_tick);
- retval = rand()%MAX_PEAK;
-#endif
-
return retval;
}
-#ifdef HAVE_AGC
+#if defined(HAVE_AGC) || defined(HAVE_RECORDING_HISTOGRAM)
/**
* Reads out the current peak-hold values since the last call.
* This is used by the histogram feature in the recording screen.
diff --git a/apps/recorder/recording.c b/apps/recorder/recording.c
index 8b52b7c..2c8e473 100644
--- a/apps/recorder/recording.c
+++ b/apps/recorder/recording.c
@@ -219,7 +219,6 @@ static char path_buffer[MAX_PATH];
* overflow every 13 years 8-)
*/
static long peak_time = 0;
-static long hist_time = 0;
static short peak_valid_mem[4];
#define BAL_MEM_SIZE 24
@@ -269,6 +268,38 @@ static short agc_baltime = 0;
/* AGC maximum gain */
static short agc_maxgain;
#endif /* HAVE_AGC */
+#if defined(HAVE_AGC) || defined(HAVE_RECORDING_HISTOGRAM)
+static long hist_time = 0;
+#endif /* HAVE_AGC or HAVE_RECORDING_HISTOGRAM */
+/* Histogram data */
+/* TO DO: move some of this stuff inside the recording function? */
+#ifdef HAVE_RECORDING_HISTOGRAM
+static int hist_l = 0;
+static int hist_r = 0;
+#define HIST_Y (hist_pos_y+hist_size_h-1)
+#define HIST_W (LCD_WIDTH / 2 - 4)
+#if LCD_DEPTH > 1
+#ifdef HAVE_LCD_COLOR
+#define LCD_BAL_L LCD_RGBPACK(0, 0, 255)
+#define LCD_BAL_R LCD_RGBPACK(204, 0, 0)
+#define LCD_HIST_OVER LCD_RGBPACK(204, 0, 0)
+#define LCD_HIST_HI LCD_RGBPACK(255, 204, 0)
+#define LCD_HIST_OK LCD_RGBPACK(51, 153, 0)
+#else /* HAVE_LCD_COLOR */
+#define LCD_BATT_OK LCD_BLACK
+#define LCD_BATT_LO LCD_DARKGRAY
+#define LCD_DISK_OK LCD_BLACK
+#define LCD_DISK_LO LCD_DARKGRAY
+#define LCD_HIST_OVER LCD_BLACK
+#define LCD_HIST_OK LCD_DARKGRAY
+#define LCD_BAL LCD_DARKGRAY
+#endif /* HAVE_LCD_COLOR */
+#else /* LCD_DEPTH > 1 */
+#define LCD_HIST_OVER LCD_DEFAULT_FG
+#define LCD_HIST_OK LCD_DEFAULT_FG
+#define LCD_BAL LCD_DEFAULT_FG
+#endif /* LCD_DEPTH > 1 */
+#endif /* HAVE_RECORDING_HISTOGRAM */
static void set_gain(void)
{
@@ -317,6 +348,13 @@ static bool read_peak_levels(int *peak_l, int *peak_r, int *balance)
*balance += balance_mem[i];
*balance = *balance / BAL_MEM_SIZE;
+#ifdef HAVE_RECORDING_HISTOGRAM
+ if (*peak_l > hist_l)
+ hist_l = *peak_l;
+ if (*peak_r > hist_r)
+ hist_r = *peak_r;
+#endif
+
return true;
}
@@ -1015,7 +1053,6 @@ bool recording_screen(bool no_source)
#endif
#ifdef HAVE_AGC
bool peak_read = false;
- bool peak_valid = false;
int peak_l, peak_r;
int balance = 0;
#endif
@@ -1025,9 +1062,21 @@ bool recording_screen(bool no_source)
int pm_h[NB_SCREENS]; /* peakmeter height */
int trig_ypos[NB_SCREENS]; /* trigger bar y pos */
int trig_width[NB_SCREENS]; /* trigger bar width */
+ int top_height_req[NB_SCREENS]; /* required height for top half */
bool compact_view[NB_SCREENS]; /* tweak layout tiny screens / big fonts */
-
struct gui_synclist lists; /* the list in the bottom vp */
+#if defined(HAVE_AGC) || defined(HAVE_RECORDING_HISTOGRAM)
+ bool peak_valid = false;
+#endif
+#if defined(HAVE_RECORDING_HISTOGRAM)
+ unsigned short hist_pos_y = 0;
+ unsigned short hist_size_h = 0;
+ int history_pos = 0;
+ short hist_time_interval = 1; /* 1, 2, 4, 8 */
+ unsigned char history_l[HIST_W];
+ unsigned char history_r[HIST_W];
+ const char hist_level_marks[6] = { 29, 26, 23, 17, 9, 2};
+#endif
#ifdef HAVE_FMRADIO_REC
int prev_rec_source = global_settings.rec_source; /* detect source change */
#endif
@@ -1084,49 +1133,6 @@ bool recording_screen(bool no_source)
rec_init_filename();
#endif
- /* viewport init and calculations that only needs to be done once */
- FOR_NB_SCREENS(i)
- {
- struct viewport *v;
- /* top vp, 4 lines, force sys font if total screen < 6 lines
- NOTE: one could limit the list to 1 line and get away with 5 lines */
- v = &vp_top[i];
- viewport_set_defaults(v, i);
- if (viewport_get_nb_lines(v) < 4)
- {
- /* compact needs 4 lines total */
- v->font = FONT_SYSFIXED;
- compact_view[i] = false;
- }
- else
- {
- if (viewport_get_nb_lines(v) < (4+2)) /*top=4,list=2*/
- compact_view[i] = true;
- else
- compact_view[i] = false;
- }
- vp_list[i] = *v; /* get a copy now so it can be sized more easily */
- v->height = (font_get(v->font)->height)*(compact_view[i] ? 3 : 4);
-
- /* list section, rest of the screen */
- vp_list[i].y += vp_top[i].height;
- vp_list[i].height -= vp_top[i].height;
- screens[i].set_viewport(&vp_top[i]); /* req for next calls */
-
- screens[i].getstringsize("W", &w, &h);
- pm_y[i] = font_get(vp_top[i].font)->height * 2;
- trig_ypos[i] = font_get(vp_top[i].font)->height * 3;
- if(compact_view[i])
- trig_ypos[i] -= (font_get(vp_top[i].font)->height)/2;
- }
-
- /* init the bottom list */
- gui_synclist_init(&lists, reclist_get_name, NULL, false, 1, vp_list);
- gui_synclist_set_title(&lists, NULL, Icon_NOICON);
-
-
- send_event(GUI_EVENT_ACTIONUPDATE, (void*)1); /* force a redraw */
-
/* start of the loop: we stay in this loop until user quits recscreen */
while(done <= 0)
{
@@ -1143,6 +1149,65 @@ bool recording_screen(bool no_source)
prev_rec_source = global_settings.rec_source;
#endif
+ /* viewport init and calculations that only needs to be done once */
+ FOR_NB_SCREENS(i)
+ {
+ struct viewport *v;
+ /* top vp, 4 lines, force sys font if total screen < 6 lines
+ NOTE: one could limit the list to 1 line and get away with 5 lines */
+ top_height_req[i] = 4;
+#if defined(HAVE_RECORDING_HISTOGRAM)
+ if((global_settings.rec_histogram_interval) && (!i))
+ top_height_req[i] += 1; /* use one line for histogram */
+ hist_time_interval = 1 << global_settings.rec_histogram_interval;
+#endif
+ v = &vp_top[i];
+ viewport_set_defaults(v, i);
+ if (viewport_get_nb_lines(v) < top_height_req[i])
+ {
+ /* compact needs 4 lines total */
+ v->font = FONT_SYSFIXED;
+ compact_view[i] = false;
+ }
+ else
+ {
+ /*top=4,list=2*/
+ if (viewport_get_nb_lines(v) < (top_height_req[i]+2))
+ compact_view[i] = true;
+ else
+ compact_view[i] = false;
+ }
+ vp_list[i] = *v; /* get a copy now so it can be sized more easily */
+ v->height = (font_get(v->font)->height)*(compact_view[i] ? 3 :
+ top_height_req[i]);
+
+ /* list section, rest of the screen */
+ vp_list[i].y += vp_top[i].height;
+ vp_list[i].height -= vp_top[i].height;
+ screens[i].set_viewport(&vp_top[i]); /* req for next calls */
+
+ screens[i].getstringsize("W", &w, &h);
+ pm_y[i] = font_get(vp_top[i].font)->height * 2;
+ trig_ypos[i] = font_get(vp_top[i].font)->height * 3;
+ if(compact_view[i])
+ trig_ypos[i] -= (font_get(vp_top[i].font)->height)/2;
+ }
+
+ /* init the bottom list */
+ gui_synclist_init(&lists, reclist_get_name, NULL, false, 1, vp_list);
+ gui_synclist_set_title(&lists, NULL, Icon_NOICON);
+
+ send_event(GUI_EVENT_ACTIONUPDATE, (void*)1); /* force a redraw */
+
+#if defined(HAVE_RECORDING_HISTOGRAM)
+ history_pos = 0;
+ hist_pos_y = (compact_view[0] ? 3 : 4) * (font_get(vp_top[0].font)->height)
+ + 1;
+ hist_size_h = font_get(vp_top[0].font)->height - 2;
+ memset(history_l, 0, sizeof(unsigned char)*HIST_W);
+ memset(history_r, 0, sizeof(unsigned char)*HIST_W);
+#endif
+
FOR_NB_SCREENS(i)
{
pm_x[i] = 0;
@@ -1673,12 +1738,11 @@ bool recording_screen(bool no_source)
unsigned int dseconds, dhours, dminutes;
unsigned long num_recorded_bytes, dsize, dmb;
-
FOR_NB_SCREENS(i)
{
screens[i].set_viewport(&vp_top[i]);
screens[i].clear_viewport();
- }
+ }
update_countdown = 5;
last_seconds = seconds;
@@ -1796,6 +1860,83 @@ bool recording_screen(bool no_source)
}
}
+#ifdef HAVE_RECORDING_HISTOGRAM
+ if(global_settings.rec_histogram_interval)
+ {
+ if (peak_valid && !(hist_time % hist_time_interval) && hist_l)
+ {
+ history_l[history_pos] = hist_l * hist_size_h / 32767;
+ history_r[history_pos] = hist_r * hist_size_h / 32767;
+ history_pos = (history_pos + 1) % HIST_W;
+ history_l[history_pos] = history_r[history_pos] = 0;
+ history_l[(history_pos + 1) % HIST_W] = 0;
+ history_r[(history_pos + 1) % HIST_W] = 0;
+ hist_l = 0;
+ hist_r = 0;
+ }
+ lcd_set_drawmode(DRMODE_SOLID);
+ lcd_drawrect(0, hist_pos_y - 1,
+ HIST_W + 2, hist_size_h + 1);
+ lcd_drawrect(HIST_W + 6, hist_pos_y - 1,
+ HIST_W + 2, hist_size_h + 1);
+ lcd_set_drawmode(DRMODE_FG);
+#ifdef HAVE_LCD_COLOR
+ for (i = 0; i < HIST_W; i++)
+ {
+ if (history_l[i])
+ {
+ if (history_l[i] == hist_size_h)
+ lcd_set_foreground(LCD_HIST_OVER);
+ else if (history_l[i] > hist_level_marks[1])
+ lcd_set_foreground(LCD_HIST_HI);
+ else
+ lcd_set_foreground(LCD_HIST_OK);
+ lcd_vline(1 + i, HIST_Y-1, HIST_Y - history_l[i]);
+ }
+ if (history_r[i])
+ {
+ if (history_r[i] == hist_size_h)
+ lcd_set_foreground(LCD_HIST_OVER);
+ else if (history_r[i] > hist_level_marks[1])
+ lcd_set_foreground(LCD_HIST_HI);
+ else
+ lcd_set_foreground(LCD_HIST_OK);
+ lcd_vline(HIST_W+7 + i, HIST_Y-1, HIST_Y - history_r[i]);
+ }
+ }
+#else
+ for (i = 0; i < HIST_W; i++)
+ {
+ if (history_l[i])
+ {
+ if (history_l[i] == hist_size_h)
+ lcd_set_foreground(LCD_HIST_OVER);
+ else
+ lcd_set_foreground(LCD_HIST_OK);
+ lcd_vline(1 + i, HIST_Y-1, HIST_Y - history_l[i]);
+ }
+ if (history_r[i])
+ {
+ if (history_r[i] == hist_size_h)
+ lcd_set_foreground(LCD_HIST_OVER);
+ else
+ lcd_set_foreground(LCD_HIST_OK);
+ lcd_vline(HIST_W+7 + i, HIST_Y-1, HIST_Y - history_r[i]);
+ }
+ }
+#endif /* HAVE_LCD_COLOR */
+ lcd_set_foreground(
+#ifdef HAVE_LCD_COLOR
+ global_settings.fg_color);
+#else
+ LCD_DEFAULT_FG);
+#endif
+ for (i = 0; i < 6; i++)
+ lcd_hline(HIST_W + 3, HIST_W + 4,
+ HIST_Y - hist_level_marks[i]);
+ }
+#endif /* HAVE_RECORDING_HISTOGRAM */
+
#ifdef HAVE_AGC
hist_time++;
#endif
@@ -1922,7 +2063,6 @@ rec_abort:
FOR_NB_SCREENS(i)
screens[i].setfont(FONT_UI);
-
/* if the directory was created or recording happened, make sure the
browser is updated */