Index: apps/action.h
===================================================================
--- apps/action.h (revision 14742)
+++ apps/action.h (working copy)
@@ -156,6 +156,7 @@
ACTION_REC_NEWFILE,
ACTION_REC_F2,
ACTION_REC_F3,
+ ACTION_REC_HIST_TOGGLE,
/* main menu */
/* These are not strictly actions, but must be here
Index: apps/recorder/icons.h
===================================================================
--- apps/recorder/icons.h (revision 14742)
+++ apps/recorder/icons.h (working copy)
@@ -45,6 +45,12 @@
Icon5x8Last
};
+enum icons_7x7 {
+ Icon_Timer,
+ Icon_Timer_rep,
+ Icon7x7Last
+};
+
enum icons_7x8 {
Icon_Plug,
Icon_USBPlug,
@@ -100,6 +106,7 @@
#endif /* CONFIG_CODEC == SWCODEC && defined (HAVE_RECORDING) */
extern const unsigned char bitmap_icons_5x8[Icon5x8Last][5];
+extern const unsigned char bitmap_icons_7x7[Icon7x7Last][7];
extern const unsigned char bitmap_icons_7x8[Icon7x8Last][7];
extern const unsigned char bitmap_icon_disk[];
Index: apps/recorder/recording.h
===================================================================
--- apps/recorder/recording.h (revision 14742)
+++ apps/recorder/recording.h (working copy)
@@ -26,6 +26,22 @@
int rec_create_directory(void);
void settings_apply_trigger(void);
+struct timer
+{
+ bool countdown;
+ bool timer_display;
+ unsigned int days;
+ unsigned int hrs;
+ unsigned int mins;
+ unsigned int secs;
+ unsigned int days_rpt;
+ unsigned int hrs_rpt;
+ unsigned int mins_rpt;
+ bool repeater;
+};
+
+struct timer *get_timerstat(void);
+
/* If true, start recording automatically when recording_sreen() is entered */
extern bool recording_start_automatic;
@@ -34,6 +50,7 @@
void rec_set_source(int source, unsigned flags);
#endif /* CONFIG_CODEC == SW_CODEC */
+struct audio_recording_options;
/* Initializes a recording_options structure with global settings.
pass returned data to audio_set_recording_options or
rec_set_recording_options */
Index: apps/recorder/peakmeter.h
===================================================================
--- apps/recorder/peakmeter.h (revision 14742)
+++ apps/recorder/peakmeter.h (working copy)
@@ -33,7 +33,7 @@
extern bool peak_meter_enabled;
extern void peak_meter_playback(bool playback);
-extern int peak_meter_draw_get_btn(int x, int y[], int height, int nb_screens);
+extern int peak_meter_draw_get_btn(int x, int y[], int height[], int nb_screens);
extern void peak_meter_set_clip_hold(int time);
extern void peak_meter_peek(void);
extern void peak_meter_init_range( bool dbfs, int range_min, int range_max);
Index: apps/recorder/icons.c
===================================================================
--- apps/recorder/icons.c (revision 14742)
+++ apps/recorder/icons.c (working copy)
@@ -44,6 +44,14 @@
#endif
};
+const unsigned char bitmap_icons_7x7[][7] =
+{
+ [Icon_Timer] =
+ {0x1c, 0x22, 0x41, 0x4f, 0x49, 0x22, 0x1d}, /* Recording timer icon */
+ [Icon_Timer_rep]=
+ {0x17, 0x26, 0x45, 0x41, 0x51, 0x32, 0x74} /* Recording repeat timer icon */
+};
+
const unsigned char bitmap_icons_7x8[][7] =
{
{0x08,0x1c,0x3e,0x3e,0x3e,0x14,0x14}, /* Power plug */
@@ -121,7 +129,7 @@
#ifdef HAVE_MMC
{0x15,0x3f,0x7d,0x7B,0x77,0x67,0x79,0x7b,0x57,0x4f,0x47,0x7f};
#else
- {0x00,0x00,0x00,0x1c,0x2e,0x4f,0x77,0x79,0x3a,0x1c,0x00,0x00};
+ {0x1c,0x2e,0x4f,0x77,0x79,0x3a,0x1c,0x00,0x00,0x00,0x00,0x00};
#endif
/*
Index: apps/recorder/recording.c
===================================================================
--- apps/recorder/recording.c (revision 14742)
+++ apps/recorder/recording.c (working copy)
@@ -68,6 +68,11 @@
#include "screen_access.h"
#include "action.h"
#include "radio.h"
+#include "fat.h"
+#include "power.h"
+#include "powermgmt.h"
+#include "backlight.h"
+
#ifdef HAVE_RECORDING
/* This array holds the record timer interval lengths, in seconds */
static const unsigned long rec_timer_seconds[] =
@@ -165,14 +170,20 @@
return (rec_status & RCSTAT_IN_RECSCREEN) != 0;
}
-#define PM_HEIGHT ((LCD_HEIGHT >= 72) ? 2 : 1)
+static struct timer timer;
#if CONFIG_KEYPAD == RECORDER_PAD
static bool f2_rec_screen(void);
static bool f3_rec_screen(void);
#endif
+#if defined(HAVE_LCD_BITMAP) && (LCD_HEIGHT > 111) && defined(HAVE_AGC)
+#define HAVE_HISTOGRAM /* only for bigger screens */
+#endif
+
#define MAX_FILE_SIZE 0x7F800000 /* 2 GB - 4 MB */
+#define MIN_DISK_SPACE 48 /* minimum remaining disk space */
+unsigned long disk_space = 0;
static int screen_update = NB_SCREENS;
#ifdef HAVE_REMOTE_LCD
@@ -210,10 +221,11 @@
* peak_time is the counter of the peak hold read and agc process,
* overflow every 13 years 8-)
*/
+
static long peak_time = 0;
+static short peak_valid_mem[4];
static long hist_time = 0;
-static short peak_valid_mem[4];
#define BAL_MEM_SIZE 24
static short balance_mem[BAL_MEM_SIZE];
@@ -262,6 +274,43 @@
static short agc_maxgain;
#endif /* HAVE_AGC */
+/* Histogram data, only for bigger screens */
+#ifdef HAVE_HISTOGRAM
+#define HIST_Y (LCD_HEIGHT - 1)
+#define HIST_W (LCD_WIDTH / 2 - 4)
+static short history_mode;
+static short hist_time_interval = 1; /* 1, 2, 4, 8 */
+static int hist_l = 0;
+static int hist_r = 0;
+static unsigned char history_l[HIST_W];
+static unsigned char history_r[HIST_W];
+#if LCD_DEPTH > 1
+#ifdef HAVE_LCD_COLOR
+#define LCD_BATT_OK LCD_RGBPACK(63, 63, 63)
+#define LCD_BATT_LO LCD_RGBPACK(159, 0, 0)
+#define LCD_DISK_OK LCD_RGBPACK(0, 0, 143)
+#define LCD_DISK_LO LCD_RGBPACK(127, 0, 0)
+#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
+#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
+#else
+#define LCD_HIST_OVER LCD_DEFAULT_FG
+#define LCD_HIST_OK LCD_DEFAULT_FG
+#define LCD_BAL LCD_DEFAULT_FG
+#endif
+#endif /* HAVE_HISTOGRAM */
+
static void set_gain(void)
{
if(global_settings.rec_source == AUDIO_SRC_MIC)
@@ -307,6 +356,12 @@
for (i = 0; i < BAL_MEM_SIZE; i++)
*balance += balance_mem[i];
*balance = *balance / BAL_MEM_SIZE;
+#ifdef HAVE_HISTOGRAM
+ if (*peak_l > hist_l)
+ hist_l = *peak_l;
+ if (*peak_r > hist_r)
+ hist_r = *peak_r;
+#endif
return true;
}
@@ -548,8 +603,25 @@
{
int max_cursor;
- if(cursor < 0)
+ if(cursor < 0) {
cursor = 0;
+#ifdef HAVE_HISTOGRAM
+ int i;
+ history_mode++;
+ if (history_mode == 2) {
+ for (i=0; i < HIST_W; i++) {
+ history_l[i] = history_l[i] * 2;
+ history_r[i] = history_r[i] * 2;
+ }
+ } else if (history_mode == 4) {
+ for (i=0; i < HIST_W; i++) {
+ history_l[i] = history_l[i] / 2;
+ history_r[i] = history_r[i] / 2;
+ }
+ history_mode = 0;
+ }
+#endif
+ }
#ifdef HAVE_AGC
switch(global_settings.rec_source)
@@ -801,6 +873,37 @@
}
}
+/* countdown timer tick task */
+void timer_tick_task(void)
+{
+ static int mini_tick = 0;
+
+ mini_tick ++;
+ /* the countdown */
+ if ((mini_tick >= HZ) && (timer.countdown))
+ {
+ mini_tick = 0;
+ if (timer.secs) timer.secs -= 1;
+ else{
+ timer.secs = 59;
+ if (timer.mins) timer.mins -= 1;
+ else{
+ timer.mins = 59;
+ if (timer.hrs) timer.hrs -= 1;
+ else{
+ timer.hrs = 23;
+ if (timer.days) timer.days -= 1;
+ else{
+ timer.days = timer.hrs = timer.mins = timer.secs = 0;
+ /* switch timer display on/off when countdown finished */
+ timer.timer_display = !timer.timer_display;
+ }
+ }
+ }
+ }
+ }
+}
+
bool recording_start_automatic = false;
bool recording_screen(bool no_source)
@@ -809,9 +912,18 @@
bool done = false;
char buf[32];
char buf2[32];
- int w, h;
+ int w[NB_SCREENS], h[NB_SCREENS];
+ int font[NB_SCREENS];
+ int pm_h[NB_SCREENS];
int update_countdown = 1;
- unsigned int seconds;
+#ifndef SIMULATOR
+ bool disk_was_active = false;
+ bool warn_message = true;
+#endif
+ unsigned long disk_free;
+ int bitrate;
+ int disk_time = 0;
+ unsigned int seconds, prerec = 0;
int hours, minutes;
char filename[13];
int last_audio_stat = -1;
@@ -833,10 +945,10 @@
int led_countdown = 2;
#endif
#ifdef HAVE_AGC
+ bool peak_valid = false;
+ int balance = 0;
bool peak_read = false;
- bool peak_valid = false;
int peak_l, peak_r;
- int balance = 0;
bool display_agc[NB_SCREENS];
#endif
int line[NB_SCREENS];
@@ -849,6 +961,13 @@
/* 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;
+ int agc_line = 0;
+ bool histogram_on = global_settings.hist_def;
+ bool font_check = true;
+ int pm_height[NB_SCREENS];
+ int countdown_offset = 0;
+ bool repeat_timer_start = false;
+ unsigned int repeat_timer;
static const unsigned char *byte_units[] = {
ID2P(LANG_BYTE),
@@ -869,6 +988,68 @@
}
rec_status = RCSTAT_IN_RECSCREEN;
+
+
+ /* Stop countdown if countdown settings changed */
+ if (!timer.countdown)
+ tick_remove_task(timer_tick_task);
+
+#ifdef HAVE_AGC
+ memset(balance_mem, 0x00, BAL_MEM_SIZE);
+#endif
+
+#ifdef HAVE_HISTOGRAM
+ int history_pos = 0;
+ int hist_height;
+ const short hist_size_h[2] = {17, 31};
+ /*
+ * Peak histogram linear to logarithmic [dB] table.
+ * The thresholds are scaled between the corresponding
+ * dispayed values, e.g. -6dB is -5.5dB < level <= 6.5dB
+ */
+ const short hist_peak_lin2dB[2][31] =
+ {
+ /* Clip, 0, -2, -4, -6, -8, -10 */
+ { 32767, 28539, 23197, 18427, 14637, 11627, 9236,
+ /* -12, -14, -16, -18, -20, -24, -30, -36, -48, -inf */
+ 7336, 5828, 4629, 3677, 2602, 1642, 734, 328, 104, 0 },
+ /* Clip, 0, -1, -2, -3, -4, -5, -6, -7, -8 */
+ { 32767, 30579, 27569, 24573, 21901, 19519, 17397, 15505, 13819, 12316,
+ /* -9, -10, -11, -12, -13, -14, -15, -16, -18, -20, -22 */
+ 10977, 9783, 8719, 7771, 6926, 6173, 5502, 4629, 3677, 2921, 2320,
+ /* -24, -27, -30, -33, -36, -39, -42, -48, -60, -inf */
+ 1842, 1232, 872, 618, 437, 310, 207, 124, 33, 0 }
+ };
+ const char hist_level_marks[4][6] =
+ {
+ /* linear: 0, -6, -12, -24, -inf [dB] */
+ { 15, 8, 4, 1, 0, 0},
+ /* logarithmic: 0, -6, -12, -24, -48 [dB] */
+ { 15, 12, 9, 4, 1, 1},
+ /* linear: 0, -3, -6, -12, -24, -inf [dB] */
+ { 29, 21, 15, 7, 2, 0},
+ /* logarithmic: 0, -3, -6, -12, -24, -48 [dB] */
+ { 29, 26, 23, 17, 9, 2}
+ };
+ const short hist_balance_marks[12] =
+ /* -6, -5, -4, -3, -2, -1, 1, 2, 3, 4, 5, 6 */
+ {-4988, -4377, -3690, -2920, -2057, -1087,
+ 1087, 2057, 2920, 3690, 4377, 4988};
+
+ const unsigned char rec_icons_6x8[][6] =
+ {
+ {0x00,0x1c,0x3e,0x36,0x3e,0x1c}
+ };
+ enum icons_6x8
+ {
+ Icon_Disk,
+ Icon_6x8end
+ };
+
+ memset(history_l, 0x00, sizeof(history_l));
+ memset(history_r, 0x00, sizeof(history_r));
+#endif /* HAVE_HISTOGRAM */
+
cursor = 0;
#if (CONFIG_LED == LED_REAL) && !defined(SIMULATOR)
ata_set_led_enabled(false);
@@ -884,7 +1065,7 @@
peak_meter_enabled = true;
peak_meter_playback(true);
#endif
-
+ gui_syncsplash(1, "%s...", str(LANG_RECORDING));
audio_init_recording(0);
sound_set_volume(global_settings.volume);
@@ -926,29 +1107,109 @@
}
#endif /* HAVE_AGC */
- FOR_NB_SCREENS(i)
- {
- screens[i].setfont(FONT_SYSFIXED);
- screens[i].getstringsize("M", &w, &h);
- screens[i].setmargins(global_settings.invert_cursor ? 0 : w, 8);
- filename_offset[i] = ((screens[i].height >= 80) ? 1 : 0);
- pm_y[i] = 8 + h * (2 + filename_offset[i]);
- }
-
#ifdef HAVE_REMOTE_LCD
if (!remote_display_on)
{
screens[1].clear_display();
snprintf(buf, sizeof(buf), str(LANG_REMOTE_LCD_ON));
- screens[1].puts((screens[1].width/w - strlen(buf))/2 + 1,
- screens[1].height/(h*2) + 1, buf);
+ screens[1].puts((screens[1].width/w[1] - strlen(buf))/2 + 1,
+ screens[1].height/(h[1]*2) + 1, buf);
screens[1].update();
gui_syncsplash(0, str(LANG_REMOTE_LCD_OFF));
}
#endif
+ /* store the free disk space for this session [MBytes] */
+ fat_size(IF_MV2(0,) NULL, &disk_free); /* free KBytes */
+ disk_free = disk_free / 1024;
+ if (disk_free > disk_space)
+ disk_space = disk_free;
+ bitrate = 1411; /* [kbps] default for 44kHz stereo 16bit WAV */
+
+#ifdef HAVE_HISTOGRAM
+ history_mode = global_settings.rec_histogram_mode;
+ hist_time_interval = 1 << global_settings.rec_histogram_interval;
+#endif
+
while(!done)
{
+ switch(global_settings.rec_source)
+ {
+ case AUDIO_SRC_LINEIN:
+#ifdef HAVE_FMRADIO_IN
+ case AUDIO_SRC_FMRADIO:
+#endif
+ FOR_NB_SCREENS(i)
+ line[i] = 5;
+ agc_line = 1;
+ break;
+ case AUDIO_SRC_MIC:
+ FOR_NB_SCREENS(i)
+ line[i] = 4;
+ agc_line = 1;
+ break;
+#ifdef HAVE_SPDIF_IN
+ case AUDIO_SRC_SPDIF:
+ FOR_NB_SCREENS(i)
+ line[i] = 3;
+ agc_line = 0; /* no agc line for Spdif in */
+ break;
+#endif
+ default:
+ FOR_NB_SCREENS(i)
+ line[i] = 5;
+ break;
+ }
+ /* check and change font only if source has been changed */
+ if (font_check)
+ {
+ FOR_NB_SCREENS(i)
+ pm_height[i] = global_settings.peak_size + 1;
+
+ FOR_NB_SCREENS(i)
+ {
+ filename_offset[i] = ((screens[i].height >= 80) ? 1 : 0);
+
+ while(screens[i].height < (line[i] + 1 + filename_offset[i] + pm_height[i]) * 8)
+ {
+ pm_height[i] -= 1;
+ if (pm_height[i] < 1)
+ { pm_height[i] = 1;
+ break;
+ }
+ }
+
+ screens[i].setfont(FONT_UI);
+ screens[i].getstringsize("M", &w[i], &h[i]);
+
+ if (i == SCREEN_MAIN) {
+ if (h[i] <= ((LCD_HEIGHT - (histogram_on ? 25 : 8)) / (line[i] +
+ filename_offset[0] + pm_height[i] + agc_line)))
+ font[i] = FONT_UI;
+ else
+ font[i] = FONT_SYSFIXED;
+ }
+ else if (h[i] <= ((screens[i].height - 8) / (line[i] + filename_offset[i] + pm_height[i])))
+ font[i] = FONT_UI;
+ else
+ font[i] = FONT_SYSFIXED;
+
+ screens[i].setfont(font[i]);
+ screens[i].getstringsize("M", &w[i], &h[i]);
+ screens[i].setmargins(global_settings.invert_cursor ? 0 : w[i], 8);
+ if (h[i] > 8) {
+ pm_y[i] = 9 + h[i] * (2 + filename_offset[i]);
+ pm_h[i] = (h[i] - 1) * pm_height[i];
+ }
+ else {
+ pm_y[i] = 8 + h[i] * (2 + filename_offset[i]);
+ pm_h[i] = h[i] * pm_height[i];
+ }
+ }
+ font_check = false;
+ }
+
+
audio_stat = audio_status();
#if (CONFIG_LED == LED_REAL)
@@ -999,7 +1260,7 @@
#endif /* CONFIG_LED */
/* Wait for a button a while (HZ/10) drawing the peak meter */
- button = peak_meter_draw_get_btn(pm_x, pm_y, h * PM_HEIGHT, screen_update);
+ button = peak_meter_draw_get_btn(pm_x, pm_y, pm_h, screen_update);
if (last_audio_stat != audio_stat)
{
@@ -1010,7 +1271,6 @@
last_audio_stat = audio_stat;
}
-
if (recording_start_automatic)
{
/* simulate a button press */
@@ -1018,9 +1278,33 @@
recording_start_automatic = false;
}
+ /* repeat_timer is the repeat time in seconds */
+ repeat_timer = (timer.mins_rpt * 60 + timer.hrs_rpt *
+ 3600 + timer.days_rpt * 3600 * 24);
+
+ /* decide on repeat timer status */
+ if ((repeat_timer > rec_timesplit_seconds()) &&
+ global_settings.rec_timesplit)
+ timer.repeater = true;
+ else
+ timer.repeater = false;
+
+ /* When countdown timer reaches zero fake a new file button press */
+ if (timer.countdown && !timer.days && !timer.hrs && !timer.mins &&
+ !timer.secs)
+ {
+ tick_remove_task(timer_tick_task);
+ button = ACTION_REC_NEWFILE;
+ timer.countdown = false;
+ }
+
switch(button)
{
#ifdef HAVE_REMOTE_LCD
+ case ACTION_REC_HIST_TOGGLE:
+ histogram_on = !histogram_on;
+ font_check = true;
+ break;
case ACTION_REC_LCD:
if (remote_display_on)
{
@@ -1028,8 +1312,8 @@
screen_update = 1;
screens[1].clear_display();
snprintf(buf, sizeof(buf), str(LANG_REMOTE_LCD_ON));
- screens[1].puts((screens[1].width/w - strlen(buf))/2 + 1,
- screens[1].height/(h*2) + 1, buf);
+ screens[1].puts((screens[1].width/w[1] - strlen(buf))/2 + 1,
+ screens[1].height/(h[1]*2) + 1, buf);
screens[1].update();
gui_syncsplash(0, str(LANG_REMOTE_LCD_OFF));
}
@@ -1064,7 +1348,27 @@
case ACTION_REC_NEWFILE:
/* Only act if the mpeg is stopped */
if(!(audio_stat & AUDIO_STATUS_RECORD))
- {
+ { /* if countdown timer is set, start countdown */
+ if (timer.days || timer.hrs || timer.mins || timer.secs)
+ {
+ if (button == ACTION_REC_PAUSE)
+ {
+ timer.countdown = !timer.countdown;
+ if (timer.countdown)
+ tick_add_task(timer_tick_task);
+ else
+ tick_remove_task(timer_tick_task);
+ break;
+ }
+ else
+ {
+ /* if newfile button pressed and countdown timer is on,
+ start new file and reset timer */
+ tick_remove_task(timer_tick_task);
+ timer.days = timer.hrs = timer.mins = timer.secs = 0;
+ timer.countdown = false;
+ }
+ }
/* is this manual or triggered recording? */
if ((global_settings.rec_trigger_mode == TRIG_MODE_OFF) ||
(peak_meter_trigger_status() != TRIG_OFF))
@@ -1072,6 +1376,11 @@
/* manual recording */
rec_status |= RCSTAT_HAVE_RECORDED;
rec_command(RECORDING_CMD_START);
+ repeat_timer_start = true; /* allow access to repeat timer
+ code */
+ /* amount of file that has been prerecorded - needed for
+ syncing repeat timer */
+ prerec = audio_recorded_time() / HZ;
last_seconds = 0;
if (global_settings.talk_menu)
{
@@ -1272,7 +1581,6 @@
#ifdef HAVE_FMRADIO_REC
const int prev_rec_source = global_settings.rec_source;
#endif
-
#if (CONFIG_LED == LED_REAL)
/* led is restored at begin of loop / end of function */
led(false);
@@ -1294,6 +1602,10 @@
&& prev_rec_source == AUDIO_SRC_FMRADIO)
radio_status = FMRADIO_OFF;
#endif
+ /* if countdown timer settings changed in menu,
+ stop counting and reset */
+ if (!timer.countdown)
+ tick_remove_task(timer_tick_task);
#if CONFIG_CODEC == SWCODEC
/* reinit after submenu exit */
@@ -1326,14 +1638,17 @@
adjust_cursor();
set_gain();
update_countdown = 1; /* Update immediately */
+#ifdef HAVE_HISTOGRAM
+ hist_time_interval = 1 << global_settings.rec_histogram_interval;
+#endif
FOR_NB_SCREENS(i)
{
- screens[i].setfont(FONT_SYSFIXED);
- screens[i].setmargins(
- global_settings.invert_cursor ? 0 : w, 8);
+ screens[i].setfont(font[i]);
+ screens[i].setmargins(global_settings.invert_cursor ? 0 : w[i], 8);
}
}
+ font_check = true;
}
break;
@@ -1396,6 +1711,9 @@
break;
} /* end switch */
+ /* display timer status in status bar if countdown enabled */
+ timer.timer_display = timer.countdown;
+
#ifdef HAVE_AGC
peak_read = !peak_read;
if (peak_read) { /* every 2nd run of loop */
@@ -1409,7 +1727,7 @@
#endif
FOR_NB_SCREENS(i)
- screens[i].setfont(FONT_SYSFIXED);
+ screens[i].setfont(font[i]);
seconds = audio_recorded_time() / HZ;
@@ -1423,12 +1741,23 @@
update_countdown = 5;
last_seconds = seconds;
+ /* Get free disk space and calculate remain time */
+ fat_size( IF_MV2(0,) NULL, &disk_free ); /* [KBytes] */
+ disk_free = disk_free / 1024;
+ if (disk_free < MIN_DISK_SPACE)
+ disk_free = MIN_DISK_SPACE;
+ disk_free -= MIN_DISK_SPACE;
+ disk_time = 140 * (int)disk_free / bitrate; /* rough estimation */
+
dseconds = rec_timesplit_seconds();
dsize = rec_sizesplit_bytes();
num_recorded_bytes = audio_num_recorded_bytes();
for(i = 0; i < screen_update; i++)
+ {
screens[i].clear_display();
+ screens[i].setfont(font[i]);
+ }
#if CONFIG_CODEC == SWCODEC
if ((audio_stat & AUDIO_STATUS_WARNING)
@@ -1446,11 +1775,13 @@
#endif /* CONFIG_CODEC == SWCODEC */
if ((global_settings.rec_sizesplit) && (global_settings.rec_split_method))
{
+ countdown_offset = 1;
dmb = dsize/1024/1024;
snprintf(buf, sizeof(buf), "%s %dMB",
str(LANG_SYSFONT_SPLIT_SIZE), dmb);
}
- else
+ /* only display recording time if countdown timer is off */
+ else if (!timer.days && !timer.hrs && !timer.mins && !timer.secs)
{
hours = seconds / 3600;
minutes = (seconds - (hours * 3600)) / 60;
@@ -1458,6 +1789,11 @@
str(LANG_SYSFONT_RECORDING_TIME),
hours, minutes, seconds%60);
}
+ else
+ {
+ countdown_offset = 0;
+ snprintf(buf, 32, "");
+ }
for(i = 0; i < screen_update; i++)
screens[i].puts(0, 0, buf);
@@ -1481,7 +1817,8 @@
str(LANG_SYSFONT_RECORD_TIMESPLIT_REC),
dhours, dminutes);
}
- else
+ /* only display recording size if countdown timer is off */
+ else if (!timer.days && !timer.hrs && !timer.mins && !timer.secs)
{
output_dyn_value(buf2, sizeof buf2,
num_recorded_bytes,
@@ -1493,6 +1830,16 @@
for(i = 0; i < screen_update; i++)
screens[i].puts(0, 1, buf);
+ /* display countdown timer if set */
+ if (timer.days || timer.hrs || timer.mins || timer.secs)
+ {
+ snprintf(buf, 32, "%s %d:%02d:%02d:%02d", str(LANG_REC_TIMER),
+ timer.days, timer.hrs, timer.mins, timer.secs);
+
+ for(i = 0; i < screen_update; i++)
+ screens[i].puts(0, countdown_offset, buf);
+ }
+
for(i = 0; i < screen_update; i++)
{
if (filename_offset[i] > 0)
@@ -1526,11 +1873,36 @@
rec_command(RECORDING_CMD_START_NEWFILE);
last_seconds = 0;
}
- else
+ else if (repeat_timer_start)
{
peak_meter_trigger(false);
peak_meter_set_trigger_listener(NULL);
rec_command(RECORDING_CMD_STOP);
+
+ /* stop any more attempts to access this code until a new
+ recording is started */
+ repeat_timer_start = false;
+
+ /* start repeat countdown if set and only if
+ stop time < repeat time */
+ if (timer.repeater)
+ {
+ repeat_timer -= dseconds;
+ timer.days = repeat_timer / (3600 * 24);
+ timer.hrs = (repeat_timer - (timer.days * 3600 * 24)) /
+ 3600;
+ timer.mins = (repeat_timer - (timer.hrs * 3600)) / 60;
+ timer.secs = prerec; /* add prerecorded time to timer */
+
+ /* This is not really a toggle so much as a safety feature
+ so that it is impossible to start the timer more than
+ once */
+ timer.countdown = !timer.countdown;
+ if (timer.countdown)
+ tick_add_task(timer_tick_task);
+ else
+ tick_remove_task(timer_tick_task);
+ }
}
update_countdown = 1;
}
@@ -1542,10 +1914,10 @@
snprintf(clpstr, 32, "%4d", pm_get_clipcount());
for(i = 0; i < screen_update; i++)
{
- if(PM_HEIGHT > 1)
+ if(pm_height[i] > 1)
screens[i].puts(0, 2 + filename_offset[i],
str(LANG_SYSFONT_PM_CLIPCOUNT));
- screens[i].puts(0, 1 + PM_HEIGHT + filename_offset[i],
+ screens[i].puts(0, 1 + pm_height[i] + filename_offset[i],
clpstr);
}
}
@@ -1559,12 +1931,12 @@
{
for(i = 0; i < screen_update; i++)
screens[i].puts_style_offset(0, filename_offset[i] +
- PM_HEIGHT + 2, buf, STYLE_INVERT,0);
+ pm_height[i] + 2, buf, STYLE_INVERT,0);
}
else
{
for(i = 0; i < screen_update; i++)
- screens[i].puts(0, filename_offset[i] + PM_HEIGHT + 2, buf);
+ screens[i].puts(0, filename_offset[i] + pm_height[i] + 2, buf);
}
if(global_settings.rec_source == AUDIO_SRC_MIC)
@@ -1578,13 +1950,13 @@
{
for(i = 0; i < screen_update; i++)
screens[i].puts_style_offset(0, filename_offset[i] +
- PM_HEIGHT + 3, buf, STYLE_INVERT,0);
+ pm_height[i] + 3, buf, STYLE_INVERT,0);
}
else
{
for(i = 0; i < screen_update; i++)
screens[i].puts(0, filename_offset[i] +
- PM_HEIGHT + 3, buf);
+ pm_height[i] + 3, buf);
}
}
else if(0
@@ -1602,13 +1974,13 @@
{
for(i = 0; i < screen_update; i++)
screens[i].puts_style_offset(0, filename_offset[i] +
- PM_HEIGHT + 3, buf, STYLE_INVERT,0);
+ pm_height[i] + 3, buf, STYLE_INVERT,0);
}
else
{
for(i = 0; i < screen_update; i++)
screens[i].puts(0, filename_offset[i] +
- PM_HEIGHT + 3, buf);
+ pm_height[i] + 3, buf);
}
snprintf(buf, sizeof(buf), "%s:%s",
@@ -1620,16 +1992,18 @@
{
for(i = 0; i < screen_update; i++)
screens[i].puts_style_offset(0, filename_offset[i] +
- PM_HEIGHT + 4, buf, STYLE_INVERT,0);
+ pm_height[i] + 4, buf, STYLE_INVERT,0);
}
else
{
for(i = 0; i < screen_update; i++)
screens[i].puts(0, filename_offset[i] +
- PM_HEIGHT + 4, buf);
+ pm_height[i] + 4, buf);
}
}
+ yield();
+
FOR_NB_SCREENS(i)
{
switch (global_settings.rec_source)
@@ -1653,7 +2027,7 @@
break;
} /* end switch */
#ifdef HAVE_AGC
- if (screens[i].height < h * (2 + filename_offset[i] + PM_HEIGHT + line[i]))
+ if (screens[i].height < 8 + h[i] * (1 + filename_offset[i] + pm_height[i] + line[i]))
{
line[i] -= 1;
display_agc[i] = false;
@@ -1705,7 +2079,7 @@
{
for(i = 0; i < screen_update; i++)
screens[i].puts_style_offset(0, filename_offset[i] +
- PM_HEIGHT + line[i], buf, STYLE_INVERT,0);
+ pm_height[i] + line[i], buf, STYLE_INVERT,0);
}
else if (
global_settings.rec_source == AUDIO_SRC_MIC
@@ -1716,7 +2090,7 @@
for(i = 0; i < screen_update; i++) {
if (display_agc[i]) {
screens[i].puts(0, filename_offset[i] +
- PM_HEIGHT + line[i], buf);
+ pm_height[i] + line[i], buf);
}
}
}
@@ -1744,27 +2118,27 @@
for(i = 0; i < screen_update; i++)
screen_put_cursorxy(&screens[i], 0,
filename_offset[i] +
- PM_HEIGHT + 3, true);
+ pm_height[i] + 3, true);
if(global_settings.rec_source != AUDIO_SRC_MIC)
{
for(i = 0; i < screen_update; i++)
screen_put_cursorxy(&screens[i], 0,
filename_offset[i] +
- PM_HEIGHT + 4, true);
+ pm_height[i] + 4, true);
}
break;
case 2:
for(i = 0; i < screen_update; i++)
screen_put_cursorxy(&screens[i], 0,
filename_offset[i] +
- PM_HEIGHT + 3, true);
+ pm_height[i] + 3, true);
break;
case 3:
for(i = 0; i < screen_update; i++)
screen_put_cursorxy(&screens[i], 0,
filename_offset[i] +
- PM_HEIGHT + 4, true);
+ pm_height[i] + 4, true);
break;
#ifdef HAVE_AGC
case 4:
@@ -1772,14 +2146,14 @@
for(i = 0; i < screen_update; i++)
screen_put_cursorxy(&screens[i], 0,
filename_offset[i] +
- PM_HEIGHT + line[i], true);
+ pm_height[i] + line[i], true);
break;
#endif /* HAVE_AGC */
default:
for(i = 0; i < screen_update; i++)
screen_put_cursorxy(&screens[i], 0,
filename_offset[i] +
- PM_HEIGHT + 2, true);
+ pm_height[i] + 2, true);
}
}
@@ -1787,23 +2161,268 @@
hist_time++;
#endif
+#ifdef HAVE_HISTOGRAM
+ /* Draw histogram graphs (on main unit only).
+ * 4 modes: low size linear or logarithmic histogram with
+ * disk space usage, battery level and balance meter or
+ * high size linear or logarithmic peak histogram.
+ */
+#define HIST_BAL_X (LCD_WIDTH/2 + 4)
+#define HIST_BAL_W (LCD_WIDTH/2 - 5)
+#define BAL_MAX_R 4988
+#define BAL_MAX_L (-BAL_MAX_R * (HIST_BAL_W/2 + 1) / (HIST_BAL_W/2))
+ int hist_bal_y;
+ if (histogram_on)
+ hist_bal_y = HIST_Y - hist_size_h[history_mode/2] - 11;
+ else
+ hist_bal_y = HIST_Y - 11;
+
+ if((global_settings.rec_source == AUDIO_SRC_MIC)||
+ (global_settings.rec_source == AUDIO_SRC_LINEIN)||
+ (global_settings.rec_source == AUDIO_SRC_FMRADIO))
+ agc_line = 1;
+ else
+ agc_line = 0; /* no agc line for Spdif in */
+
+ if ((hist_bal_y) > (8 + ((line[0] + filename_offset[0] +
+ pm_height[0] + agc_line + (global_settings.rec_trigger_mode >
+ 0 ? 1 : 0)) * h[0])))
+ {
+ lcd_setfont(FONT_SYSFIXED);
+ lcd_set_drawmode(DRMODE_FG);
+#if LCD_DEPTH > 1
+ if (battery_level() > 10)
+ lcd_set_foreground(LCD_BATT_OK);
+ else
+ lcd_set_foreground(LCD_BATT_LO);
+#else
+ lcd_set_foreground(
+#ifdef HAVE_LCD_COLOR
+ global_settings.fg_color);
+#else
+ LCD_DEFAULT_FG);
+#endif
+#endif /* LCD_DEPTH > 1 */
+ lcd_fillrect(0, hist_bal_y,
+ (30 * battery_level() + 60) / 100, 9);
+#if LCD_DEPTH > 1
+ if (disk_time > 59)
+ lcd_set_foreground(LCD_DISK_OK);
+ else
+ lcd_set_foreground(LCD_DISK_LO);
+#endif /* LCD_DEPTH > 1 */
+ if ((LCD_WIDTH/2 - 36)*(disk_space-disk_free-3) / disk_space)
+ lcd_fillrect(35, hist_bal_y, (LCD_WIDTH/2 - 37) *
+ (disk_space - disk_free - 1) / disk_space, 9);
+ lcd_set_drawmode(DRMODE_COMPLEMENT);
+ lcd_set_foreground(
+#ifdef HAVE_LCD_COLOR
+ global_settings.fg_color);
+#else
+ LCD_DEFAULT_FG);
+#endif
+#ifndef SIMULATOR
+ if (charger_inserted())
+ lcd_mono_bitmap(bitmap_icons_7x8[Icon_Plug],
+ 2 + 19*(battery_level() > 48),
+ hist_bal_y + 1, 7, 8);
+#endif
+ if (battery_time() > 90)
+ snprintf(buf, 32, "%dh", (battery_time() + 10) / 60);
+ else
+ snprintf(buf,32, "%dm", battery_time());
+ if (battery_level() > 48)
+ i = 1;
+ else if ((battery_time() < 590) && (battery_time() > 90))
+ i = 15;
+ else
+ i = 10;
+ lcd_putsxy(i, hist_bal_y + 1, buf);
+ if (disk_time > 90)
+ snprintf(buf, 32, "%dh", (disk_time + 10) / 60);
+ else
+ snprintf(buf, 32, "%dm", disk_time);
+ i = ((disk_time < 91) || (disk_time > 589))? 30:26;
+
+ if ((hist_time % 2)
+#ifndef SIMULATOR
+ || !ata_disk_is_active()
+#endif
+ )
+ lcd_mono_bitmap(rec_icons_6x8[Icon_Disk],
+ LCD_WIDTH/2 - 11,
+ hist_bal_y + 1, 6, 8);
+ lcd_putsxy((5*disk_free > 3*disk_space) ?
+ (LCD_WIDTH/2 - i) : 37,
+ hist_bal_y + 1, buf);
+ lcd_drawrect(34, hist_bal_y - 1, LCD_WIDTH/2 - 36, 11);
+ lcd_set_drawmode(DRMODE_SOLID);
+ lcd_drawrect(0, hist_bal_y - 1, 30, 11);
+ lcd_vline(30, hist_bal_y + 2, hist_bal_y + 6);
+ lcd_vline(31, hist_bal_y + 2, hist_bal_y + 6);
+
+ int bal;
+ lcd_drawrect(HIST_BAL_X-2, hist_bal_y-1, HIST_BAL_W+3, 11);
+ lcd_hline(HIST_BAL_X + HIST_BAL_W/2 - 1,
+ HIST_BAL_X + HIST_BAL_W/2 + 1,
+ hist_bal_y - 2);
+ lcd_hline(HIST_BAL_X + HIST_BAL_W/2 - 1,
+ HIST_BAL_X + HIST_BAL_W/2 + 1,
+ hist_bal_y + 10);
+ lcd_set_drawmode(DRMODE_FG);
+#ifndef HAVE_LCD_COLOR
+ lcd_set_foreground(LCD_BAL);
+#endif
+ for (i = 0; i < BAL_MEM_SIZE; i++) {
+ bal = MIN(balance_mem[i], BAL_MAX_R);
+ bal = MAX(bal, BAL_MAX_L);
+#ifdef HAVE_LCD_COLOR
+ if (bal > 142)
+ lcd_set_foreground(LCD_BAL_L);
+ else if (bal < 142)
+ lcd_set_foreground(LCD_BAL_R);
+ else
+ lcd_set_foreground(LCD_DARKGRAY);
+#endif
+ /* every 0.2 seconds a balance measure is taken,
+ draw a vline for each */
+ lcd_vline(HIST_BAL_X + HIST_BAL_W/2 +
+ HIST_BAL_W * bal / 9976,
+ hist_bal_y + 1, hist_bal_y + 7);
+ }
+ lcd_set_foreground(LCD_BLACK);
+ bal = MAX(balance, BAL_MAX_L);
+ bal = MIN(bal, BAL_MAX_R);
+ /* draw the 3 pixel wide balance measure,
+ average measure of the last 24 measures (5 seconds) */
+ lcd_fillrect(HIST_BAL_X-1 + HIST_BAL_W/2 +
+ HIST_BAL_W * bal / 9976,
+ hist_bal_y, 3, 9);
+ lcd_drawpixel(HIST_BAL_X + HIST_BAL_W/2, hist_bal_y + 4);
+ lcd_set_drawmode(DRMODE_COMPLEMENT);
+ lcd_drawpixel(HIST_BAL_X + HIST_BAL_W/2, hist_bal_y - 1);
+ lcd_drawpixel(HIST_BAL_X + HIST_BAL_W/2, hist_bal_y + 9);
+ for (i = 0; i < 12; i++)
+ lcd_drawpixel(HIST_BAL_X + HIST_BAL_W/2 +
+ HIST_BAL_W * hist_balance_marks[i] / 9976,
+ hist_bal_y + 4);
+ }
+
+ if (histogram_on)
+ {
+ hist_height = hist_size_h[history_mode/2] - 1;
+ if (peak_valid && !(hist_time % hist_time_interval) && hist_l)
+ {
+ if (history_mode % 2) {
+ i = 0;
+ while (hist_l < hist_peak_lin2dB[history_mode / 2][i])
+ i++;
+ history_l[history_pos] = hist_height - i;
+ i = 0;
+ while (hist_r < hist_peak_lin2dB[history_mode / 2][i])
+ i++;
+ history_r[history_pos] = hist_height - i;
+ } else {
+ history_l[history_pos] = hist_l * hist_height / 32767;
+ history_r[history_pos] = hist_r * hist_height / 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_Y - hist_height,
+ HIST_W + 2, hist_height + 1);
+ lcd_drawrect(HIST_W + 6, HIST_Y - hist_height,
+ HIST_W + 2, hist_height + 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_height)
+ lcd_set_foreground(LCD_HIST_OVER);
+ else if (history_l[i] > hist_level_marks[history_mode][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_height)
+ lcd_set_foreground(LCD_HIST_OVER);
+ else if (history_r[i] > hist_level_marks[history_mode][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_height)
+ 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_height)
+ 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]);
+ }
+ }
+ lcd_set_foreground(LCD_WHITE);
+ for (i = 0; i < HIST_W; i++) {
+ if (history_l[i] == hist_height)
+ lcd_drawpixel(1 + i, HIST_Y - 1);
+ if (history_r[i] == hist_height)
+ lcd_drawpixel(HIST_W + 7 + i, HIST_Y - 1);
+ }
+#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[history_mode][i]);
+ }
+#endif /* HAVE_HISTOGRAM */
+
+#ifdef HAVE_AGC
+ hist_time++;
+#endif
+
for(i = 0; i < screen_update; i++)
{
gui_statusbar_draw(&(statusbars.statusbars[i]), true);
- peak_meter_screen(&screens[i], pm_x, pm_y[i], h*PM_HEIGHT);
+ peak_meter_screen(&screens[i], pm_x, pm_y[i], pm_h[i]);
+
screens[i].update();
}
/* draw the trigger status */
FOR_NB_SCREENS(i)
{
- trig_width[i] = ((screens[i].height < 64) ||
- ((screens[i].height < 72) && (PM_HEIGHT > 1))) ?
- screens[i].width - 14 * w : screens[i].width;
+ trig_width[i] = (screens[i].height < (h[i] * (2 +
+ filename_offset[i] + pm_height[i] +
+ line[i]) + (histogram_on ? 25 : 8))) ?
+ screens[i].width -
+ 14 * w[i] : screens[i].width;
trig_xpos[i] = screens[i].width - trig_width[i];
- trig_ypos[i] = ((screens[i].height < 72) && (PM_HEIGHT > 1)) ?
- h*2 :
- h*(1 + filename_offset[i] + PM_HEIGHT + line[i]
+ trig_ypos[i] = (screens[i].height < (h[i] * (2 +
+ filename_offset[i] + pm_height[i] +
+ line[i]) + (histogram_on ? 25 : 8))) ? h[i]*2
+ : h[i]*(1 + filename_offset[i] +
+ pm_height[i] + line[i]
#ifdef HAVE_AGC
+ 1
#endif
@@ -1821,6 +2440,51 @@
}
}
+ /* check battery level & free disk space */
+#ifndef SIMULATOR
+ if (ata_disk_is_active())
+ disk_was_active = true;
+ else if (disk_was_active)
+ {
+ lcd_setfont(FONT_UI);
+ if (disk_time == 0) {
+ backlight_on();
+#ifdef HAVE_REMOTE_LCD
+ remote_backlight_on();
+#endif
+ if (audio_stat & AUDIO_STATUS_RECORD) {
+ gui_syncsplash(HZ, "%s %s",
+ str(LANG_WARNING_DISK_FULL),
+ str(LANG_WARNING_STOP_RECORDING));
+ rec_command(RECORDING_CMD_STOP);
+ }
+ else {
+ gui_syncsplash(2*HZ,
+ str(LANG_WARNING_DISK_FULL));
+ }
+ }
+ else if (warn_message && (battery_level() < 10)) {
+ backlight_on();
+#ifdef HAVE_REMOTE_LCD
+ remote_backlight_on();
+#endif
+ gui_syncsplash(3*HZ,
+ str(LANG_WARNING_BATTERY_LOW));
+ }
+ else if (!warn_message && (disk_free < 512)) {
+ backlight_on();
+#ifdef HAVE_REMOTE_LCD
+ remote_backlight_on();
+#endif
+ gui_syncsplash(3*HZ,
+ str(LANG_WARNING_DISKSPACE_LOW));
+ }
+ lcd_setfont(FONT_SYSFIXED);
+ warn_message = !warn_message;
+ disk_was_active = false;
+ }
+#endif
+
if(audio_stat & AUDIO_STATUS_ERROR)
{
done = true;
@@ -1881,6 +2545,10 @@
if (rec_status & (RCSTAT_CREATED_DIRECTORY | RCSTAT_HAVE_RECORDED))
reload_directory();
+#ifdef HAVE_HISTOGRAM
+ global_settings.rec_histogram_mode = history_mode;
+#endif
+
#if (CONFIG_LED == LED_REAL) && !defined(SIMULATOR)
ata_set_led_enabled(true);
#endif
@@ -2129,6 +2797,12 @@
}
#endif /* CONFIG_KEYPAD == RECORDER_PAD */
+struct timer *get_timerstat(void)
+{
+ return &timer;
+}
+
+
#if CONFIG_CODEC == SWCODEC
void audio_beep(int duration)
{
Index: apps/recorder/peakmeter.c
===================================================================
--- apps/recorder/peakmeter.c (revision 14742)
+++ apps/recorder/peakmeter.c (working copy)
@@ -150,17 +150,17 @@
/* precalculated peak values that represent magical
dBfs values. Used to draw the scale */
static const int db_scale_src_values[DB_SCALE_SRC_VALUES_SIZE] = {
- 32736, /* 0 db */
- 22752, /* - 3 db */
- 16640, /* - 6 db */
- 11648, /* - 9 db */
- 8320, /* -12 db */
- 4364, /* -18 db */
- 2064, /* -24 db */
- 1194, /* -30 db */
- 363, /* -40 db */
- 101, /* -50 db */
- 34, /* -60 db */
+ 32752, /* 0 db */
+ 22784, /* - 3 db */
+ 14256, /* - 6 db */
+ 11752, /* - 9 db */
+ 9256, /* -12 db */
+ 4256, /* -18 db */
+ 2186, /* -24 db */
+ 1186, /* -30 db */
+ 373, /* -40 db */
+ 102, /* -50 db */
+ 33, /* -60 db */
0, /* -inf */
};
@@ -193,69 +193,81 @@
long m;
int istart;
- if (isample < 2308) { /* Range 1-5 */
+ /* Range 1-4 */
+ if (isample < 119) {
- if (isample < 115) { /* Range 1-3 */
+ /* Range 1-2 */
+ if (isample < 5) {
- if (isample < 24) {
+ /* Range 1 */
+ if (isample < 1) {
+ istart = 0;
+ n = 0;
+ m = 5900;
+ }
- if (isample < 5) {
- istart = 1; /* Range 1 */
- n = 98;
+ /* Range 2 */
+ else {
+ istart = 1;
+ n = 59;
m = 34950;
}
+ }
+
+ /* Range 3-4 */
else {
- istart = 5; /* Range 2 */
- n = 1496;
+
+ /* Range 3 */
+ if (isample < 24) {
+ istart = 5;
+ n = 1457;
m = 7168;
}
- }
- else {
- istart = 24; /* Range 3 */
- n = 2858;
- m = 1498;
- }
- }
- else { /* Range 4-5 */
- if (isample < 534) {
- istart = 114; /* Range 4 */
- n = 4207;
- m = 319;
- }
+ /* Range 4 */
else {
- istart = 588; /* Range 5 */
- n = 5583;
- m = 69;
+ istart = 24;
+ n = 2819;
+ m = 1464;
}
}
}
- else { /* Range 6-9 */
+ /* Range 5-8 */
+ else {
- if (isample < 12932) {
+ /* Range 5-6 */
+ if (isample < 2918) {
- if (isample < 6394) {
- istart = 2608; /* Range 6 */
- n = 6832;
- m = 21;
+ /* Range 5 */
+ if (isample < 592) {
+ istart = 119;
+ n = 4210;
+ m = 295;
}
+
+ /* Range 6 */
else {
- istart = 7000; /* Range 7 */
- n = 7682;
- m = 9;
+ istart = 592;
+ n = 5605;
+ m = 60;
}
}
+
+ /* Range 7-8 */
else {
- if (isample < 22450) {
- istart = 13000; /* Range 8 */
- n = 8219;
- m = 5;
+ /* Range 7 */
+ if (isample < 15352) {
+ istart = 2918;
+ n = 7001;
+ m = 12;
}
+
+ /* Range 8 */
else {
- istart = 22636; /* Range 9 */
- n = 8697;
+ istart = 15352;
+ n = 8439;
m = 3;
}
}
@@ -1309,12 +1321,13 @@
}
#endif
-int peak_meter_draw_get_btn(int x, int y[], int height, int nb_screens)
+int peak_meter_draw_get_btn(int x, int y[], int height[], int nb_screens)
{
int button = BUTTON_NONE;
long next_refresh = current_tick;
long next_big_refresh = current_tick + HZ / 10;
int i;
+
#ifndef SIMULATOR
bool highperf = !ata_disk_is_active();
#else
@@ -1337,8 +1350,8 @@
if (TIME_AFTER(current_tick, next_refresh)) {
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 - x, height);
+ peak_meter_screen(&screens[i], x, y[i], height[i]);
+ screens[i].update_rect(x, y[i], screens[i].width - x, height[i]);
}
next_refresh += HZ / PEAK_METER_FPS;
dopeek = true;
Index: apps/lang/english.lang
===================================================================
--- apps/lang/english.lang (revision 14742)
+++ apps/lang/english.lang (working copy)
@@ -1300,6 +1300,115 @@
+ id: LANG_MULTIINT_CONFIRM
+ desc: Confirm string for multi_int settings
+ user:
+
+ *: "Press PLAY to confirm"
+
+
+ *: "Press PLAY to confirm"
+ h100,h120,h300: "Press NAVI to confirm"
+ ipod*,x5,gigabeat: "Press SELECT to confirm"
+ ondio*: "Press MODE to confirm"
+
+
+ *: ""
+
+
+
+ id: LANG_RECORD_TIMER
+ desc: Record timer menu
+ user:
+
+ *: "Timer Options"
+
+
+ *: "Timer Options"
+
+
+ *: "Timer Options"
+
+
+
+ id: LANG_TIMER_SET
+ desc: Recording timer menu
+
+ *: "Set countdown timer"
+
+
+ *: "Set countdown timer"
+
+
+ *: "Set countdown timer"
+
+
+
+ id: LANG_TIMER_REPEAT
+ desc: Recording timer menu
+
+ *: "Record repeat timer"
+
+
+ *: "Record repeat timer"
+
+
+ *: "Record repeat timer"
+
+
+
+ id: LANG_TIMER_DAYS
+ desc: recording timer settings string
+
+ *: "Days"
+
+
+ *: "Days"
+
+
+ *: "Days"
+
+
+
+ id: LANG_TIMER_HRS
+ desc: recording timer settings string
+
+ *: "Hrs"
+
+
+ *: "Hrs"
+
+
+ *: "Hrs"
+
+
+
+ id: LANG_TIMER_MINS
+ desc: recording timer settings string
+
+ *: "Mins"
+
+
+ *: "Mins"
+
+
+ *: "Mins"
+
+
+
+ id: LANG_REC_TIMER
+ desc: recording screen timer string
+
+ *: "Timer"
+
+
+ *: "Timer"
+
+
+ *: "Timer"
+
+
+
id: LANG_DITHERING
desc: in the sound settings menu
user:
@@ -2481,6 +2590,62 @@
+ id: LANG_RECORDING_HISTOGRAM_INTERVAL
+ desc: in record settings menu
+ user:
+
+ *: "Histogram interval"
+
+
+ *: "Histogram interval"
+
+
+ *: ""
+
+
+
+ id: LANG_WARNING_DISKSPACE_LOW
+ desc: in recording screen
+ user:
+
+ *: "WARNING! Low Disk-Space!"
+
+
+ *: "WARNING! Low Disk-Space!"
+
+
+ *: ""
+
+
+
+ id: LANG_WARNING_DISK_FULL
+ desc: in recording screen
+ user:
+
+ *: "Disk is full!"
+
+
+ *: "Disk is full!"
+
+
+ *: ""
+
+
+
+ id: LANG_WARNING_STOP_RECORDING
+ desc: in recording screen
+ user:
+
+ *: "Stopping Recording..."
+
+
+ *: "Stopping Recording..."
+
+
+ *: ""
+
+
+
id: LANG_TAGCACHE_UPDATE
desc: in tag cache settings
user:
@@ -9462,6 +9627,45 @@
+ id: LANG_RECORD_HIST_OPTIONS
+ desc: histogram on/off
+
+ *: "Histogram options"
+
+
+ *: "Histogram options"
+
+
+ *: "Histogram options"
+
+
+
+ id: LANG_RECORD_PEAKMETER_SIZE
+ desc: Size of peakmeter
+
+ *: "Size of peakmeter"
+
+
+ *: "Size of peakmeter"
+
+
+ *: "Size of peakmeter"
+
+
+
+ id: LANG_RECORD_HIST_DRAW
+ desc: Draw histogram default
+
+ *: "Draw histogram default"
+
+
+ *: "Draw histogram default"
+
+
+ *: "Draw histogram default"
+
+
+
id: VOICE_KBIT_PER_SEC
desc: spoken only, a unit postfix
user:
Index: apps/settings.c
===================================================================
--- apps/settings.c (revision 14742)
+++ apps/settings.c (working copy)
@@ -989,7 +989,207 @@
step, min, max, formatter, NULL);
}
+ /* The type separation is necessary since int and bool are fundamentally
+ different and bit-incompatible types and can not share the same access
+ code. */
+/* Useful for time and other multi integer settings */
+bool set_multi_int(const char* string,
+ const struct opt_items * names,
+ struct opt_settings * variable,
+ const int varcount,
+ bool *changes_accepted)
+{
+ int i, j, w, h, space_width;
+ char buf[32];
+ long button;
+ int cursor = 0;
+ bool done = false;
+ int value[varcount];
+ int pos = 0;
+ bool changed;
+
+ if(changes_accepted)
+ changed = *changes_accepted;
+ else
+ changed = false;
+
+ /* store current values in temp array */
+ for(j = 0; j < varcount; j++)
+ value[j] = *(int*)variable[j].setting;
+
+ /* initialize screen */
+ FOR_NB_SCREENS(i)
+ screens[i].clear_display();
+
+ gui_syncstatusbar_draw(&statusbars, true);
+ screens[0].getstringsize(" ", &space_width, &h);
+
+ /* print title */
+ snprintf(buf, sizeof(buf), "%s", string);
+ FOR_NB_SCREENS(i)
+ screens[i].puts(0, 0, buf);
+
+ /* print variable names */
+ for(j = 0; j < varcount ; j++)
+ {
+ if (j > 0)
+ {
+ snprintf(buf, sizeof(buf), ":");
+ screens[0].getstringsize(buf, &w, &h);
+ FOR_NB_SCREENS(i)
+ screens[i].putsxy(pos, 8 + h, buf);
+ pos += w + space_width;
+
+ }
+
+ snprintf(buf, sizeof(buf), "%s", P2STR(names[j].string));
+ FOR_NB_SCREENS(i)
+ screens[i].putsxy(pos, 8 + h, buf);
+
+ screens[0].getstringsize(buf, &w, &h);
+ pos += w + space_width;
+ }
+
+ /* print button instructions */
+ snprintf(buf, sizeof(buf), "%s", str(LANG_MULTIINT_CONFIRM));
+ FOR_NB_SCREENS(i)
+ screens[i].puts(0, 6, buf);
+
+ while(!done)
+ {
+ /* print variables */
+ pos = 0;
+ FOR_NB_SCREENS(i)
+ {
+ screens[i].set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
+ screens[i].fillrect(0, 8 + 3 * h, screens[i].width, h + 1);
+ screens[i].set_drawmode(DRMODE_SOLID);
+ }
+
+ for(j = 0; j < varcount; j++)
+ {
+ if (j > 0)
+ {
+ snprintf(buf, sizeof(buf), ":");
+ screens[0].getstringsize(buf, &w, &h);
+ FOR_NB_SCREENS(i)
+ screens[i].putsxy(pos, 8 + 3 * h, buf);
+ pos += w + space_width;
+ }
+
+ snprintf(buf, sizeof(buf), "%d", value[j]);
+
+ FOR_NB_SCREENS(i)
+ screens[i].putsxy(pos, 8 + 3 * h, buf);
+
+ snprintf(buf, sizeof(buf), "%d", variable[j].setting_max);
+ screens[0].getstringsize(buf, &w, &h);
+
+ /* highlight currently selected integer */
+ if (cursor == j)
+ {
+ FOR_NB_SCREENS(i)
+ {
+ screens[i].set_drawmode(DRMODE_COMPLEMENT);
+ screens[i].fillrect(pos, 8 + 3 * h, w + 1, h + 1);
+ screens[i].set_drawmode(DRMODE_SOLID);
+ }
+ }
+
+ pos += w + space_width;
+ }
+
+#ifdef HAVE_LCD_BITMAP
+ FOR_NB_SCREENS(i)
+ screens[i].update();
+#endif
+
+ button = get_action(CONTEXT_SETTINGS, TIMEOUT_BLOCK);
+
+ switch (button)
+ {
+ case ACTION_STD_NEXT:
+ cursor ++;
+
+ if (cursor >= varcount)
+ cursor = varcount - 1;
+
+ if (global_settings.talk_menu)
+ talk_id(names[cursor].voice_id, false);
+ break;
+
+ case ACTION_STD_PREV:
+ /* cancel if pressing left when cursor
+ is already at the far left */
+ if (cursor == 0)
+ {
+ changed = false;
+ gui_syncsplash(HZ/2, str(LANG_CANCEL));
+ done = true;
+ }
+ else
+ {
+ cursor --;
+
+ if (cursor < 0)
+ cursor = 0;
+
+ if (global_settings.talk_menu)
+ talk_id(names[cursor].voice_id, false);
+ }
+ break;
+
+ case ACTION_SETTINGS_INC:
+ case ACTION_SETTINGS_INCREPEAT:
+ value[cursor] += 1;
+
+ if (value[cursor] > variable[cursor].setting_max)
+ value[cursor] = 0;
+
+ if (global_settings.talk_menu)
+ talk_id(value[cursor], false);
+ break;
+
+ case ACTION_SETTINGS_DEC:
+ case ACTION_SETTINGS_DECREPEAT:
+ value[cursor] -= 1;
+
+ if (value[cursor] < 0)
+ value[cursor] = variable[cursor].setting_max;
+
+ if (global_settings.talk_menu)
+ talk_id(value[cursor], false);
+ break;
+
+ case ACTION_STD_OK:
+ changed = true;
+ done = true;
+ break;
+
+ case ACTION_STD_CANCEL:
+ changed = false;
+ gui_syncsplash(HZ/2, str(LANG_CANCEL));
+ done = true;
+
+ default:
+ if (default_event_handler(button) == SYS_USB_CONNECTED)
+ return true;
+ }
+ }
+
+ /* store values if accepted */
+ if(changed)
+ {
+ for(j = 0; j < varcount; j++)
+ *(int*)variable[j].setting = value[j];
+ }
+
+ if(changes_accepted)
+ *changes_accepted = changed;
+ return false;
+}
+
/** extra stuff which is probably misplaced **/
void set_file(char* filename, char* setting, int maxlen)
Index: apps/gui/statusbar.c
===================================================================
--- apps/gui/statusbar.c (revision 14742)
+++ apps/gui/statusbar.c (working copy)
@@ -33,6 +33,7 @@
#include "action.h" /* for keys_locked */
#include "statusbar.h"
#ifdef HAVE_RECORDING
+#include "recording.h"
#include "audio.h"
#include "recording.h"
#endif
@@ -113,7 +114,11 @@
#define STATUSBAR_LOCKR_WIDTH 5
#if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
+#ifdef HAVE_MMC
#define STATUSBAR_DISK_WIDTH 12
+#else
+#define STATUSBAR_DISK_WIDTH 7
+#endif
#define STATUSBAR_DISK_X_POS(statusbar_width) statusbar_width - \
STATUSBAR_DISK_WIDTH
#else
@@ -121,6 +126,15 @@
#endif
#define STATUSBAR_TIME_X_END(statusbar_width) statusbar_width - 1 - \
STATUSBAR_DISK_WIDTH
+#if defined(HAVE_RECORDING)
+#define TIMER_ICON_WIDTH 7
+#if CONFIG_RTC
+#define CLOCK_WIDTH 35
+#else
+#define CLOCK_WIDTH 0
+#endif
+#endif
+
struct gui_syncstatusbar statusbars;
/* Prototypes */
@@ -140,9 +154,11 @@
#endif
#ifdef HAVE_RECORDING
static void gui_statusbar_icon_recording_info(struct screen * display);
+static void gui_statusbar_timer(struct screen * display, int dy, int hr, int mn, int sc, bool recscreen);
+static void gui_statusbar_timer_rep(struct screen * display);
#endif
#if CONFIG_RTC
-static void gui_statusbar_time(struct screen * display, struct tm *time);
+static void gui_statusbar_time(struct screen * display, struct tm *time, bool timer_display);
#endif
#endif
@@ -245,7 +261,22 @@
#if CONFIG_RTC
bar->time = get_time();
#endif /* CONFIG_RTC */
+#ifdef HAVE_RECORDING
+ struct timer* timer = get_timerstat();
+ bar->info.timer_day = timer->days;
+ bar->info.timer_hour = timer->hrs;
+ bar->info.timer_min = timer->mins;
+ /* avoid an update every second unless less than one
+ minute remains on the timer */
+ if (!bar->info.timer_day && !bar->info.timer_hour && !bar->info.timer_min)
+ bar->info.timer_sec = timer->secs;
+ else
+ bar->info.timer_sec = 0;
+ bar->info.timer_display = timer->timer_display;
+ bar->info.timer_repeat = timer->repeater;
+#endif
+
/* only redraw if forced to, or info has changed */
if (force_redraw || bar->redraw_volume ||
#if CONFIG_RTC
@@ -319,8 +350,16 @@
if (bar->info.keylockremote)
gui_statusbar_icon_lock_remote(display);
#endif
+#ifdef HAVE_RECORDING
+ if (bar->info.timer_display)
+ gui_statusbar_timer(display, bar->info.timer_day, bar->info.timer_hour,
+ bar->info.timer_min, bar->info.timer_sec, recscreen_on);
+ else if ((bar->info.timer_repeat) && (recscreen_on))
+ gui_statusbar_timer_rep(display);
+#endif
#if CONFIG_RTC
- gui_statusbar_time(display, bar->time);
+ gui_statusbar_time(display, bar->time,
+ bar->info.timer_display);
bar->last_tm_min = bar->time->tm_min;
#endif /* CONFIG_RTC */
#if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
@@ -581,10 +620,11 @@
/*
* Print time to status bar
*/
-static void gui_statusbar_time(struct screen * display, struct tm *time)
+
+static void gui_statusbar_time(struct screen * display, struct tm *time, bool timer_display)
{
unsigned char buffer[6];
- unsigned int width, height;
+ int width, height;
int hour, minute;
if ( valid_time(time) ) {
hour = time->tm_hour;
@@ -603,15 +643,73 @@
display->setfont(FONT_SYSFIXED);
display->getstringsize(buffer, &width, &height);
if (height <= STATUSBAR_HEIGHT) {
+#ifdef HAVE_RECORDING
+ if (timer_display)
+ display->set_drawmode(DRMODE_INVERSEVID);
+#else
+ (void)timer_display;
+#endif
display->putsxy(STATUSBAR_TIME_X_END(display->width) - width,
STATUSBAR_Y_POS, buffer);
}
+ display->set_drawmode(DRMODE_SOLID);
display->setfont(FONT_UI);
}
#endif
#ifdef HAVE_RECORDING
+static void gui_statusbar_timer(struct screen * display, int dy, int hr, int mn,
+ int sc, bool recscreen)
+{
+ unsigned char buffer[8];
+ int width, height;
+
+ /* vary the display depending on the remaining time to save space */
+ if (dy)
+ snprintf(buffer, sizeof(buffer), " %dd%02dh", hr > 58 ? dy + 1 : dy,
+ hr > 58 ? 0 : hr + 1);
+ else if (!hr && !mn)
+ snprintf(buffer, sizeof(buffer), "%02ds", sc);
+ else
+ snprintf(buffer, sizeof(buffer), "%02dh%02dm", mn > 58 ? hr + 1: hr,
+ mn > 58 ? 0 : mn + 1);
+
+ display->setfont(FONT_SYSFIXED);
+ display->getstringsize(buffer, &width, &height);
+
+ if (height <= STATUSBAR_HEIGHT)
+ {
+ if(((display->width) >= (STATUSBAR_LOCKR_X_POS + STATUSBAR_LOCKR_WIDTH +
+ STATUSBAR_DISK_WIDTH + width + CLOCK_WIDTH + 1))
+ && !recscreen)
+ display->putsxy(STATUSBAR_TIME_X_END(display->width) - width -
+ CLOCK_WIDTH, STATUSBAR_Y_POS, buffer);
+ /* display only an icon for small screens or when in recording screen*/
+ else if ((display->width) >= (STATUSBAR_LOCKR_X_POS +
+ STATUSBAR_LOCKR_WIDTH +
+ STATUSBAR_DISK_WIDTH +
+ TIMER_ICON_WIDTH + CLOCK_WIDTH + 1))
+ display->mono_bitmap(bitmap_icons_7x7[Icon_Timer],
+ STATUSBAR_TIME_X_END(display->width) -
+ TIMER_ICON_WIDTH - CLOCK_WIDTH,
+ STATUSBAR_Y_POS,
+ TIMER_ICON_WIDTH, STATUSBAR_HEIGHT);
+ }
+
+ display->setfont(FONT_UI);
+
+}
+
+static void gui_statusbar_timer_rep(struct screen * display)
+{
+ display->mono_bitmap(bitmap_icons_7x7[Icon_Timer_rep],
+ STATUSBAR_TIME_X_END(display->width) -
+ TIMER_ICON_WIDTH - CLOCK_WIDTH,
+ STATUSBAR_Y_POS,
+ TIMER_ICON_WIDTH, STATUSBAR_HEIGHT);
+}
+
#if CONFIG_CODEC == SWCODEC
/**
* Write a number to the display using bitmaps and return new position
Index: apps/gui/statusbar.h
===================================================================
--- apps/gui/statusbar.h (revision 14742)
+++ apps/gui/statusbar.h (working copy)
@@ -33,6 +33,15 @@
int volume;
int playmode;
int repeat;
+#ifdef HAVE_RECORDING
+ int timer_day;
+ int timer_hour;
+ int timer_min;
+ int timer_sec;
+ int timer_repeat;
+#endif
+ int timer_display;
+
#if CONFIG_CHARGING
bool inserted;
#endif
Index: apps/settings.h
===================================================================
--- apps/settings.h (revision 14742)
+++ apps/settings.h (working copy)
@@ -259,6 +259,12 @@
unsigned const char* string;
long voice_id;
};
+
+struct opt_settings {
+ int* setting;
+ int setting_max;
+};
+
const struct settings_list* find_setting(void* variable, int *id);
bool cfg_int_to_string(int setting_id, int val, char* buf, int buf_len);
void talk_setting(void *global_settings_variable);
@@ -276,6 +282,9 @@
int* variable,
void (*function)(int), int step, int min, int max,
void (*formatter)(char*, size_t, int, const char*) );
+bool set_multi_int(const char* string, const struct opt_items * names,
+ struct opt_settings * variable, int varcount,
+ bool * changes_accepted);
/* use this one if you need to create a lang from the value (i.e with TALK_ID()) */
bool set_int_ex(const unsigned char* string, const char* unit, int voice_unit,
int* variable,
@@ -370,7 +379,6 @@
13= 1GB, 14 = 1.5GB 15 = 1.75MB*/
int rec_split_type; /* split/stop */
int rec_split_method; /* time/filesize */
-
int rec_prerecord_time; /* In seconds, 0-30, 0 means OFF */
char rec_directory[MAX_FILENAME+1];
int cliplight; /* 0 = off
@@ -470,6 +478,15 @@
#endif
bool car_adapter_mode; /* 0=off 1=on */
+#ifdef HAVE_RECORDING
+#if defined(HAVE_LCD_BITMAP) && (LCD_WIDTH > 111)
+ int rec_histogram_mode; /* small lin/log /w balance, big lin/log */
+ int rec_histogram_interval; /* interval: 0.5s, 1s, 2s, 4s */
+ bool hist_def;
+#endif
+ int peak_size;
+#endif
+
/* show status bar */
bool statusbar; /* 0=hide, 1=show */
Index: apps/menus/recording_menu.c
===================================================================
--- apps/menus/recording_menu.c (revision 14742)
+++ apps/menus/recording_menu.c (working copy)
@@ -43,6 +43,7 @@
#include "sound.h"
#ifdef HAVE_RECORDING
#include "audio.h"
+#include "recording.h"
#if CONFIG_TUNER
#include "radio.h"
#endif
@@ -306,12 +307,78 @@
MENUITEM_SETTING(rec_editable, &global_settings.rec_editable, NULL);
#endif
+/* Displays a menu for changing the countdown timer settings */
+static int countdown_timer_func(void)
+{
+ bool retval;
+ bool changed = false;
+ struct timer* timer = get_timerstat();
+
+ static const struct opt_items names[] = {
+ { STR(LANG_TIMER_DAYS) },
+ { STR(LANG_TIMER_HRS) },
+ { STR(LANG_TIMER_MINS) }
+ };
+
+ struct opt_settings settings[] = {
+ { &timer->days, 6 },
+ { &timer->hrs, 23 },
+ { &timer->mins, 59 }
+ };
+
+ retval = set_multi_int(str(LANG_TIMER_SET), names, settings, 3, &changed);
+
+ if (changed)
+ {
+ timer->countdown = false;
+ timer->secs = 0;
+ timer->timer_display = false;
+ }
+
+ return retval;
+}
+
+static int countdown_timer_repeat_func(void)
+{
+ struct timer* timer = get_timerstat();
+ bool retval;
+
+ static const struct opt_items names[] = {
+ { STR(LANG_TIMER_DAYS) },
+ { STR(LANG_TIMER_HRS) },
+ { STR(LANG_TIMER_MINS) }
+ };
+
+ struct opt_settings settings[] = {
+ { &timer->days_rpt, 6 },
+ { &timer->hrs_rpt, 23 },
+ { &timer->mins_rpt, 59 }
+ };
+ retval = set_multi_int(str(LANG_TIMER_REPEAT), names, settings, 3, NULL);
+
+ /* automatically select settings necessary for repeated recording */
+ if (timer->days_rpt || timer->hrs_rpt || timer->mins_rpt)
+ {
+ global_settings.rec_split_type = 1; /* Stop */
+ global_settings.rec_split_method = 0; /* Time */
+ global_settings.rec_trigger_mode = 0; /* The repeat timer isn't
+ compatible with the trigger */
+ }
+
+ return retval;
+}
+
+MENUITEM_FUNCTION(countdown_timer, 0, ID2P(LANG_TIMER_SET),
+ countdown_timer_func, NULL, NULL, Icon_Menu_setting);
+MENUITEM_FUNCTION(countdown_timer_repeat, 0, ID2P(LANG_TIMER_REPEAT),
+ countdown_timer_repeat_func, NULL, NULL, Icon_Menu_setting);
MENUITEM_SETTING(rec_split_type, &global_settings.rec_split_type, NULL);
MENUITEM_SETTING(rec_split_method, &global_settings.rec_split_method, NULL);
MENUITEM_SETTING(rec_timesplit, &global_settings.rec_timesplit, NULL);
MENUITEM_SETTING(rec_sizesplit, &global_settings.rec_sizesplit, NULL);
-MAKE_MENU(filesplitoptionsmenu, ID2P(LANG_RECORD_TIMESPLIT), NULL, Icon_NOICON,
- &rec_split_method, &rec_split_type, &rec_timesplit, &rec_sizesplit);
+MAKE_MENU(timermenu, ID2P(LANG_RECORD_TIMER), NULL, Icon_NOICON,
+ &countdown_timer, &countdown_timer_repeat, &rec_split_method,
+ &rec_split_type, &rec_timesplit, &rec_sizesplit);
MENUITEM_SETTING(rec_prerecord_time, &global_settings.rec_prerecord_time, NULL);
@@ -365,6 +432,9 @@
agc_preset_func, NULL, NULL, Icon_Menu_setting);
MENUITEM_FUNCTION(agc_cliptime, 0, ID2P(LANG_RECORD_AGC_CLIPTIME),
agc_cliptime_func, NULL, NULL, Icon_Menu_setting);
+MAKE_MENU(agc_menu, ID2P(LANG_RECORD_AGC_PRESET), NULL, Icon_NOICON,
+ &agc_preset, &agc_cliptime);
+
#endif /* HAVE_AGC */
/** Rec trigger **/
@@ -481,7 +551,9 @@
int w, h, i;
int stat_height = global_settings.statusbar ? STATUSBAR_HEIGHT : 0;
int pm_y[NB_SCREENS];
+ int pm_h[NB_SCREENS];
+
int trig_xpos[NB_SCREENS];
int trig_ypos[NB_SCREENS];
int trig_width[NB_SCREENS];
@@ -492,6 +564,7 @@
trig_xpos[i] = 0;
trig_ypos[i] = screens[i].height - stat_height - TRIG_HEIGHT;
pm_y[i] = screens[i].height - stat_height;
+ pm_h[i] = 8;
trig_width[i] = screens[i].width;
}
@@ -630,7 +703,7 @@
}
peak_meter_draw_trig(trig_xpos, trig_ypos, trig_width, NB_SCREENS);
- button = peak_meter_draw_get_btn(0, pm_y, 8, NB_SCREENS);
+ button = peak_meter_draw_get_btn(0, pm_y, pm_h, NB_SCREENS);
FOR_NB_SCREENS(i)
screens[i].update();
@@ -797,6 +870,43 @@
MENUITEM_FUNCTION(rectrigger_item, 0, ID2P(LANG_RECORD_TRIGGER),
(int(*)(void))rectrigger, NULL, NULL, Icon_Menu_setting);
+#if LCD_HEIGHT > 111
+static int history_int_func(void)
+{
+ static const struct opt_items names[] = {
+ { "0.5s", TALK_ID(500, UNIT_MS) },
+ { "1s", TALK_ID(1, UNIT_SEC) },
+ { "2s", TALK_ID(2, UNIT_SEC) },
+ { "4s", TALK_ID(4, UNIT_SEC) }
+ };
+ return set_option(str(LANG_RECORDING_HISTOGRAM_INTERVAL),
+ &global_settings.rec_histogram_interval,
+ INT, names, 4, NULL );
+}
+MENUITEM_FUNCTION(history_interval, 0, ID2P(LANG_RECORDING_HISTOGRAM_INTERVAL),
+ history_int_func, NULL, NULL, Icon_Menu_setting);
+MENUITEM_SETTING(hist_def, &global_settings.hist_def, NULL);
+MAKE_MENU(hist_menu, ID2P(LANG_RECORD_HIST_OPTIONS), NULL, Icon_NOICON,
+ &history_interval, &hist_def);
+#endif
+static int peak_size_func(void)
+{
+ static const struct opt_items names[] = {
+ { "1x", TALK_ID(1, UNIT_INT) },
+ { "2x", TALK_ID(2, UNIT_INT) },
+ { "3x", TALK_ID(3, UNIT_INT) },
+ { "4x", TALK_ID(4, UNIT_INT) },
+ { "5x", TALK_ID(5, UNIT_INT) },
+ { "6x", TALK_ID(6, UNIT_INT) },
+ { "7x", TALK_ID(7, UNIT_INT) },
+ { "8x", TALK_ID(8, UNIT_INT) }
+ };
+ return set_option(str(LANG_RECORD_PEAKMETER_SIZE),
+ &global_settings.peak_size,
+ INT, names, 8, NULL );
+}
+MENUITEM_FUNCTION(peak_size, 0, ID2P(LANG_RECORD_PEAKMETER_SIZE),
+ peak_size_func, NULL, NULL, Icon_Menu_setting);
@@ -831,7 +941,7 @@
#if CONFIG_CODEC == MAS3587F
&rec_editable,
#endif
- &filesplitoptionsmenu,
+ &timermenu,
&rec_prerecord_time,
&clear_rec_directory_item,
#ifdef HAVE_BACKLIGHT
@@ -839,8 +949,12 @@
#endif
&rectrigger_item,
#ifdef HAVE_AGC
- &agc_preset, &agc_cliptime,
+ &agc_menu,
#endif
+#if LCD_HEIGHT > 111
+ &hist_menu,
+#endif
+ &peak_size,
&browse_recconfigs, &save_recpresets_item
);
Index: apps/settings_list.c
===================================================================
--- apps/settings_list.c (revision 14742)
+++ apps/settings_list.c (working copy)
@@ -884,6 +884,17 @@
{F_T_INT|F_RECSETTING,&global_settings.rec_trigger_mode,
LANG_RECORD_TRIGGER,INT(0),
"trigger mode","off,once,repeat",UNUSED},
+
+#if defined(HAVE_LCD_BITMAP) && (LCD_WIDTH > 111)
+ {F_T_INT,&global_settings.rec_histogram_mode,-1,INT(1),
+ "histogram mode",NULL,UNUSED},
+ {F_T_INT,&global_settings.rec_histogram_interval,LANG_RECORDING_HISTOGRAM_INTERVAL,INT(0),
+ "histogram interval","0.5s,1s,2s,4s",UNUSED},
+ OFFON_SETTING(0, hist_def, LANG_RECORD_HIST_DRAW, true, "default histogram status", NULL),
+#endif
+ {F_T_INT,&global_settings.peak_size,LANG_RECORD_PEAKMETER_SIZE,INT(0),
+ "peakmeter size", "1x,2x,3x,4x,5x,6x,7x,8x",UNUSED},
+
#endif /* HAVE_RECORDING */
#ifdef HAVE_SPDIF_POWER
Index: apps/keymaps/keymap-x5.c
===================================================================
--- apps/keymaps/keymap-x5.c (revision 14742)
+++ apps/keymaps/keymap-x5.c (working copy)
@@ -217,6 +217,9 @@
{ ACTION_SETTINGS_DEC, BUTTON_DOWN, BUTTON_NONE },
{ ACTION_SETTINGS_DECREPEAT, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_STD_PREV, BUTTON_LEFT, BUTTON_NONE },
+ { ACTION_STD_PREVREPEAT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_STD_NEXT, BUTTON_RIGHT, BUTTON_NONE },
+ { ACTION_STD_NEXTREPEAT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_STD_CANCEL, BUTTON_REC, BUTTON_NONE },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
Index: apps/keymaps/keymap-h1x0_h3x0.c
===================================================================
--- apps/keymaps/keymap-h1x0_h3x0.c (revision 14742)
+++ apps/keymaps/keymap-h1x0_h3x0.c (working copy)
@@ -239,6 +239,7 @@
{ ACTION_SETTINGS_INC, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_SETTINGS_DEC, BUTTON_LEFT, BUTTON_NONE },
{ ACTION_SETTINGS_DEC, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_REC_HIST_TOGGLE, BUTTON_MODE|BUTTON_REPEAT, BUTTON_MODE },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
}; /* button_context_recscreen */
@@ -439,6 +440,10 @@
{ ACTION_SETTINGS_INCREPEAT, BUTTON_RC_REW|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_SETTINGS_DEC, BUTTON_RC_FF, BUTTON_NONE },
{ ACTION_SETTINGS_DECREPEAT, BUTTON_RC_FF|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_STD_PREV, BUTTON_RC_SOURCE, BUTTON_NONE },
+ { ACTION_STD_PREVREPEAT, BUTTON_RC_SOURCE|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_STD_NEXT, BUTTON_RC_BITRATE, BUTTON_NONE },
+ { ACTION_STD_NEXTREPEAT, BUTTON_RC_BITRATE|BUTTON_REPEAT, BUTTON_NONE },
/* { ACTION_NONE, BUTTON_RC_ON, BUTTON_NONE },
{ ACTION_NONE, BUTTON_RC_STOP, BUTTON_NONE },
{ ACTION_NONE, BUTTON_RC_MENU|BUTTON_REL, BUTTON_NONE },
@@ -451,8 +456,13 @@
{ ACTION_SETTINGS_INCREPEAT, BUTTON_RC_VOL_UP|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_SETTINGS_DEC, BUTTON_RC_VOL_DOWN, BUTTON_NONE },
{ ACTION_SETTINGS_DECREPEAT, BUTTON_RC_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE },
- { ACTION_NONE, BUTTON_RC_REW, BUTTON_NONE },
- { ACTION_NONE, BUTTON_RC_FF, BUTTON_NONE },
+ // { ACTION_NONE, BUTTON_RC_REW, BUTTON_NONE },
+ // { ACTION_NONE, BUTTON_RC_FF, BUTTON_NONE },
+ { ACTION_STD_PREV, BUTTON_RC_REW, BUTTON_NONE },
+ { ACTION_STD_PREVREPEAT, BUTTON_RC_REW|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_STD_NEXT, BUTTON_RC_FF, BUTTON_NONE },
+ { ACTION_STD_NEXTREPEAT, BUTTON_RC_FF|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_SETTINGS_RESET, BUTTON_RC_ON, BUTTON_NONE },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
}; /* button_context_settings */
@@ -603,6 +613,7 @@
{ ACTION_SETTINGS_INC, BUTTON_RC_BITRATE|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_SETTINGS_DEC, BUTTON_RC_SOURCE, BUTTON_NONE },
{ ACTION_SETTINGS_DEC, BUTTON_RC_SOURCE|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_REC_HIST_TOGGLE, BUTTON_RC_MODE|BUTTON_REPEAT, BUTTON_RC_MODE },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
}; /* button_context_recscreen_h100remote */
@@ -615,6 +626,7 @@
{ ACTION_SETTINGS_INC, BUTTON_RC_FF|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_SETTINGS_DEC, BUTTON_RC_REW, BUTTON_NONE },
{ ACTION_SETTINGS_DEC, BUTTON_RC_REW|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_REC_HIST_TOGGLE, BUTTON_RC_MODE|BUTTON_REPEAT, BUTTON_RC_MODE },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
}; /* button_context_recscreen_h300lcdremote */
Index: apps/keymaps/keymap-ondio.c
===================================================================
--- apps/keymaps/keymap-ondio.c (revision 14742)
+++ apps/keymaps/keymap-ondio.c (working copy)
@@ -73,9 +73,10 @@
{ ACTION_SETTINGS_INCREPEAT, BUTTON_UP|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_SETTINGS_DEC, BUTTON_DOWN, BUTTON_NONE },
{ ACTION_SETTINGS_DECREPEAT, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_NONE },
- { ACTION_STD_OK, BUTTON_RIGHT, BUTTON_NONE },
- { ACTION_STD_OK, BUTTON_LEFT, BUTTON_NONE },
- { ACTION_STD_CANCEL, BUTTON_MENU, BUTTON_NONE },
+ { ACTION_STD_NEXT, BUTTON_RIGHT, BUTTON_NONE },
+ { ACTION_NONE, BUTTON_RIGHT|BUTTON_REL, BUTTON_RIGHT },
+ { ACTION_STD_PREV, BUTTON_LEFT, BUTTON_NONE },
+ { ACTION_STD_OK, BUTTON_MENU, BUTTON_NONE },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
};