summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/gui/gwps-common.c8
-rw-r--r--apps/gui/icon.c8
-rw-r--r--apps/lang/english.lang4
-rw-r--r--apps/recorder/peakmeter.c163
-rw-r--r--apps/recorder/peakmeter.h23
-rw-r--r--apps/recorder/radio.c12
-rw-r--r--apps/recorder/recording.c173
-rw-r--r--apps/sound_menu.c2
8 files changed, 256 insertions, 137 deletions
diff --git a/apps/gui/gwps-common.c b/apps/gui/gwps-common.c
index b250674d47..37306fb0e3 100644
--- a/apps/gui/gwps-common.c
+++ b/apps/gui/gwps-common.c
@@ -1750,7 +1750,7 @@ bool gui_wps_refresh(struct gui_wps *gwps, int ffwd_offset,
1750#endif 1750#endif
1751 update_line = true; 1751 update_line = true;
1752 } 1752 }
1753 if (flags & refresh_mode & WPS_REFRESH_PEAK_METER && display->height >= LCD_HEIGHT) { 1753 if (flags & refresh_mode & WPS_REFRESH_PEAK_METER) {
1754 /* peak meter */ 1754 /* peak meter */
1755 int peak_meter_y; 1755 int peak_meter_y;
1756 1756
@@ -1761,12 +1761,12 @@ bool gui_wps_refresh(struct gui_wps *gwps, int ffwd_offset,
1761 line so that it is only displayed if no status bar is 1761 line so that it is only displayed if no status bar is
1762 visible. If so we neither want do draw nor enable the 1762 visible. If so we neither want do draw nor enable the
1763 peak meter. */ 1763 peak meter. */
1764 if (peak_meter_y + h <= LCD_HEIGHT) { 1764 if (peak_meter_y + h <= display->height) {
1765 /* found a line with a peak meter -> remember that we must 1765 /* found a line with a peak meter -> remember that we must
1766 enable it later */ 1766 enable it later */
1767 enable_pm = true; 1767 enable_pm = true;
1768 peak_meter_draw(0, peak_meter_y, LCD_WIDTH, 1768 peak_meter_screen(gwps->display, 0, peak_meter_y,
1769 MIN(h, LCD_HEIGHT - peak_meter_y)); 1769 MIN(h, display->height - peak_meter_y));
1770 } 1770 }
1771 } 1771 }
1772#else 1772#else
diff --git a/apps/gui/icon.c b/apps/gui/icon.c
index 0cdee11b8e..ef6f61f94e 100644
--- a/apps/gui/icon.c
+++ b/apps/gui/icon.c
@@ -26,12 +26,14 @@
26void screen_put_iconxy(struct screen * display, int x, int y, ICON icon) 26void screen_put_iconxy(struct screen * display, int x, int y, ICON icon)
27{ 27{
28#ifdef HAVE_LCD_BITMAP 28#ifdef HAVE_LCD_BITMAP
29 int width, height;
29 int xpos, ypos; 30 int xpos, ypos;
31 display->getstringsize((unsigned char *)"M", &width, &height);
30 xpos = x*CURSOR_WIDTH; 32 xpos = x*CURSOR_WIDTH;
31 ypos = y*display->char_height + display->getymargin(); 33 ypos = y*height + display->getymargin();
32 34
33 if ( display->char_height > CURSOR_HEIGHT )/* center the cursor */ 35 if ( height > CURSOR_HEIGHT )/* center the cursor */
34 ypos += (display->char_height - CURSOR_HEIGHT) / 2; 36 ypos += (height - CURSOR_HEIGHT) / 2;
35 if(icon==0)/* Don't display invalid icons */ 37 if(icon==0)/* Don't display invalid icons */
36 screen_clear_area(display, xpos, ypos, CURSOR_WIDTH, CURSOR_HEIGHT); 38 screen_clear_area(display, xpos, ypos, CURSOR_WIDTH, CURSOR_HEIGHT);
37 else 39 else
diff --git a/apps/lang/english.lang b/apps/lang/english.lang
index 65e45cff5c..868b20646e 100644
--- a/apps/lang/english.lang
+++ b/apps/lang/english.lang
@@ -939,13 +939,13 @@ new:
939 939
940id: LANG_RECORDING_LEFT 940id: LANG_RECORDING_LEFT
941desc: in the recording screen 941desc: in the recording screen
942eng: "Gain Left" 942eng: "Gain L"
943voice: "" 943voice: ""
944new: 944new:
945 945
946id: LANG_RECORDING_RIGHT 946id: LANG_RECORDING_RIGHT
947desc: in the recording screen 947desc: in the recording screen
948eng: "Gain Right" 948eng: "Gain R"
949voice: "" 949voice: ""
950new: 950new:
951 951
diff --git a/apps/recorder/peakmeter.c b/apps/recorder/peakmeter.c
index 8bcc0688a6..ec80622367 100644
--- a/apps/recorder/peakmeter.c
+++ b/apps/recorder/peakmeter.c
@@ -33,6 +33,7 @@
33#include "lang.h" 33#include "lang.h"
34#include "peakmeter.h" 34#include "peakmeter.h"
35#include "audio.h" 35#include "audio.h"
36#include "screen_access.h"
36#ifdef CONFIG_BACKLIGHT 37#ifdef CONFIG_BACKLIGHT
37#include "backlight.h" 38#include "backlight.h"
38#endif 39#endif
@@ -48,6 +49,8 @@ static bool pm_playback = true; /* selects between playback and recording peaks
48 49
49#endif 50#endif
50 51
52struct meter_scales scales[NB_SCREENS];
53
51#if !defined(SIMULATOR) && CONFIG_CODEC != SWCODEC 54#if !defined(SIMULATOR) && CONFIG_CODEC != SWCODEC
52/* Data source */ 55/* Data source */
53static int pm_src_left = MAS_REG_DQPEAK_L; 56static int pm_src_left = MAS_REG_DQPEAK_L;
@@ -60,12 +63,6 @@ static int pm_cur_right;
60static int pm_max_left; /* maximum values between peak meter draws */ 63static int pm_max_left; /* maximum values between peak meter draws */
61static int pm_max_right; 64static int pm_max_right;
62 65
63/* Peak hold */
64static int pm_peak_left; /* buffered peak values */
65static int pm_peak_right;
66static long pm_peak_timeout_l; /* peak hold timeouts */
67static long pm_peak_timeout_r;
68
69/* Clip hold */ 66/* Clip hold */
70static bool pm_clip_left = false; /* when true a clip has occurred */ 67static bool pm_clip_left = false; /* when true a clip has occurred */
71static bool pm_clip_right = false; 68static bool pm_clip_right = false;
@@ -82,6 +79,7 @@ unsigned short peak_meter_range_min; /* minimum of range in samples */
82unsigned short peak_meter_range_max; /* maximum of range in samples */ 79unsigned short peak_meter_range_max; /* maximum of range in samples */
83static unsigned short pm_range; /* range width in samples */ 80static unsigned short pm_range; /* range width in samples */
84static bool pm_use_dbfs = true; /* true if peakmeter displays dBfs */ 81static bool pm_use_dbfs = true; /* true if peakmeter displays dBfs */
82bool level_check; /* true if peeked at peakmeter before drawing */
85static unsigned short pm_db_min = 0; /* minimum of range in 1/100 dB */ 83static unsigned short pm_db_min = 0; /* minimum of range in 1/100 dB */
86static unsigned short pm_db_max = 9000; /* maximum of range in 1/100 dB */ 84static unsigned short pm_db_max = 9000; /* maximum of range in 1/100 dB */
87static unsigned short pm_db_range = 9000; /* range width in 1/100 dB */ 85static unsigned short pm_db_range = 9000; /* range width in 1/100 dB */
@@ -140,7 +138,6 @@ static const long clip_time_out[] = {
140 138
141/* precalculated peak values that represent magical 139/* precalculated peak values that represent magical
142 dBfs values. Used to draw the scale */ 140 dBfs values. Used to draw the scale */
143#define DB_SCALE_SRC_VALUES_SIZE 12
144static const int db_scale_src_values[DB_SCALE_SRC_VALUES_SIZE] = { 141static const int db_scale_src_values[DB_SCALE_SRC_VALUES_SIZE] = {
145 32752, /* 0 db */ 142 32752, /* 0 db */
146 22784, /* - 3 db */ 143 22784, /* - 3 db */
@@ -158,15 +155,6 @@ static const int db_scale_src_values[DB_SCALE_SRC_VALUES_SIZE] = {
158 155
159static int db_scale_count = DB_SCALE_SRC_VALUES_SIZE; 156static int db_scale_count = DB_SCALE_SRC_VALUES_SIZE;
160 157
161/* if db_scale_valid is false the content of
162 db_scale_lcd_coord needs recalculation */
163static bool db_scale_valid = false;
164
165/* contains the lcd x coordinates of the magical
166 scale values in db_scale_src_values */
167static int db_scale_lcd_coord[sizeof db_scale_src_values / sizeof (int)];
168
169
170/** 158/**
171 * Calculates dB Value for the peak meter, uses peak value as input 159 * Calculates dB Value for the peak meter, uses peak value as input
172 * @param int sample - The input value 160 * @param int sample - The input value
@@ -368,7 +356,9 @@ void peak_meter_set_min(int newmin)
368 356
369 pm_db_min = calc_db(peak_meter_range_min); 357 pm_db_min = calc_db(peak_meter_range_min);
370 pm_db_range = pm_db_max - pm_db_min; 358 pm_db_range = pm_db_max - pm_db_min;
371 db_scale_valid = false; 359 int i;
360 FOR_NB_SCREENS(i)
361 scales[i].db_scale_valid = false;
372} 362}
373 363
374/** 364/**
@@ -410,7 +400,9 @@ void peak_meter_set_max(int newmax)
410 400
411 pm_db_max = calc_db(peak_meter_range_max); 401 pm_db_max = calc_db(peak_meter_range_max);
412 pm_db_range = pm_db_max - pm_db_min; 402 pm_db_range = pm_db_max - pm_db_min;
413 db_scale_valid = false; 403 int i;
404 FOR_NB_SCREENS(i)
405 scales[i].db_scale_valid = false;
414} 406}
415 407
416/** 408/**
@@ -449,8 +441,10 @@ bool peak_meter_get_use_dbfs(void)
449 */ 441 */
450void peak_meter_set_use_dbfs(bool use) 442void peak_meter_set_use_dbfs(bool use)
451{ 443{
444 int i;
452 pm_use_dbfs = use; 445 pm_use_dbfs = use;
453 db_scale_valid = false; 446 FOR_NB_SCREENS(i)
447 scales[i].db_scale_valid = false;
454} 448}
455 449
456/** 450/**
@@ -713,7 +707,8 @@ void peak_meter_peek(void)
713 break; 707 break;
714 } 708 }
715#endif 709#endif
716 710 /* check levels next time peakmeter drawn */
711 level_check = true;
717#ifdef PM_DEBUG 712#ifdef PM_DEBUG
718 peek_calls++; 713 peek_calls++;
719#endif 714#endif
@@ -816,23 +811,27 @@ unsigned short peak_meter_scale_value(unsigned short val, int meterwidth)
816 } 811 }
817 return retval; 812 return retval;
818} 813}
819 814void peak_meter_screen(struct screen *display, int x, int y, int height)
820 815{
816 peak_meter_draw(display, &scales[display->screen_type], x, y,
817 display->width, height);
818}
821/** 819/**
822 * Draws a peak meter in the specified size at the specified position. 820 * Draws a peak meter in the specified size at the specified position.
823 * @param int x - The x coordinate. 821 * @param int x - The x coordinate.
824 * Make sure that 0 <= x and x + width < LCD_WIDTH 822 * Make sure that 0 <= x and x + width < display->width
825 * @param int y - The y coordinate. 823 * @param int y - The y coordinate.
826 * Make sure that 0 <= y and y + height < LCD_HEIGHT 824 * Make sure that 0 <= y and y + height < display->height
827 * @param int width - The width of the peak meter. Note that for display 825 * @param int width - The width of the peak meter. Note that for display
828 * of clips a 3 pixel wide area is used -> 826 * of clips a 3 pixel wide area is used ->
829 * width > 3 827 * width > 3
830 * @param int height - The height of the peak meter. height > 3 828 * @param int height - The height of the peak meter. height > 3
831 */ 829 */
832void peak_meter_draw(int x, int y, int width, int height) 830void peak_meter_draw(struct screen *display, struct meter_scales *scales,
831 int x, int y, int width, int height)
833{ 832{
833 static int left_level = 0, right_level = 0;
834 int left = 0, right = 0; 834 int left = 0, right = 0;
835 static int last_left = 0, last_right = 0;
836 int meterwidth = width - 3; 835 int meterwidth = width - 3;
837 int i; 836 int i;
838 837
@@ -844,17 +843,21 @@ void peak_meter_draw(int x, int y, int width, int height)
844 /* if disabled only draw the peak meter */ 843 /* if disabled only draw the peak meter */
845 if (peak_meter_enabled) { 844 if (peak_meter_enabled) {
846 845
847 /* read the volume info from MAS */
848 left = peak_meter_read_l();
849 right = peak_meter_read_r();
850 846
851 /* scale the samples dBfs */ 847 if (level_check){
852 left = peak_meter_scale_value(left, meterwidth); 848 /* only read the volume info from MAS if peek since last read*/
853 right = peak_meter_scale_value(right, meterwidth); 849 left_level = peak_meter_read_l();
854 850 right_level = peak_meter_read_r();
855 /* if the scale has changed -> recalculate the scale 851 level_check = false;
852 }
853
854 /* scale the samples dBfs */
855 left = peak_meter_scale_value(left_level, meterwidth);
856 right = peak_meter_scale_value(right_level, meterwidth);
857
858 /*if the scale has changed -> recalculate the scale
856 (The scale becomes invalid when the range changed.) */ 859 (The scale becomes invalid when the range changed.) */
857 if (!db_scale_valid){ 860 if (!scales->db_scale_valid){
858 861
859 if (pm_use_dbfs) { 862 if (pm_use_dbfs) {
860 db_scale_count = DB_SCALE_SRC_VALUES_SIZE; 863 db_scale_count = DB_SCALE_SRC_VALUES_SIZE;
@@ -862,7 +865,7 @@ void peak_meter_draw(int x, int y, int width, int height)
862 /* find the real x-coords for predefined interesting 865 /* find the real x-coords for predefined interesting
863 dBfs values. These only are recalculated when the 866 dBfs values. These only are recalculated when the
864 scaling of the meter changed. */ 867 scaling of the meter changed. */
865 db_scale_lcd_coord[i] = 868 scales->db_scale_lcd_coord[i] =
866 peak_meter_scale_value( 869 peak_meter_scale_value(
867 db_scale_src_values[i], 870 db_scale_src_values[i],
868 meterwidth - 1); 871 meterwidth - 1);
@@ -873,7 +876,7 @@ void peak_meter_draw(int x, int y, int width, int height)
873 else { 876 else {
874 db_scale_count = 10; 877 db_scale_count = 10;
875 for (i = 0; i < db_scale_count; i++) { 878 for (i = 0; i < db_scale_count; i++) {
876 db_scale_lcd_coord[i] = 879 scales->db_scale_lcd_coord[i] =
877 (i * (MAX_PEAK / 10) - peak_meter_range_min) * 880 (i * (MAX_PEAK / 10) - peak_meter_range_min) *
878 meterwidth / pm_range; 881 meterwidth / pm_range;
879 } 882 }
@@ -881,20 +884,20 @@ void peak_meter_draw(int x, int y, int width, int height)
881 884
882 /* mark scale valid to avoid recalculating dBfs values 885 /* mark scale valid to avoid recalculating dBfs values
883 of the scale. */ 886 of the scale. */
884 db_scale_valid = true; 887 scales->db_scale_valid = true;
885 } 888 }
886 889
887 /* apply release */ 890 /* apply release */
888 left = MAX(left , last_left - pm_peak_release); 891 left = MAX(left , scales->last_left - pm_peak_release);
889 right = MAX(right, last_right - pm_peak_release); 892 right = MAX(right, scales->last_right - pm_peak_release);
890 893
891 /* reset max values after timeout */ 894 /* reset max values after timeout */
892 if (TIME_AFTER(current_tick, pm_peak_timeout_l)){ 895 if (TIME_AFTER(current_tick, scales->pm_peak_timeout_l)){
893 pm_peak_left = 0; 896 scales->pm_peak_left = 0;
894 } 897 }
895 898
896 if (TIME_AFTER(current_tick, pm_peak_timeout_r)){ 899 if (TIME_AFTER(current_tick, scales->pm_peak_timeout_r)){
897 pm_peak_right = 0; 900 scales->pm_peak_right = 0;
898 } 901 }
899 902
900 if (!pm_clip_eternal) { 903 if (!pm_clip_eternal) {
@@ -910,51 +913,51 @@ void peak_meter_draw(int x, int y, int width, int height)
910 } 913 }
911 914
912 /* check for new max values */ 915 /* check for new max values */
913 if (left > pm_peak_left) { 916 if (left > scales->pm_peak_left) {
914 pm_peak_left = left - 1; 917 scales->pm_peak_left = left - 1;
915 pm_peak_timeout_l = 918 scales->pm_peak_timeout_l =
916 current_tick + peak_time_out[pm_peak_hold]; 919 current_tick + peak_time_out[pm_peak_hold];
917 } 920 }
918 921
919 if (right > pm_peak_right) { 922 if (right > scales->pm_peak_right) {
920 pm_peak_right = right - 1; 923 scales->pm_peak_right = right - 1;
921 pm_peak_timeout_r = 924 scales->pm_peak_timeout_r =
922 current_tick + peak_time_out[pm_peak_hold]; 925 current_tick + peak_time_out[pm_peak_hold];
923 } 926 }
924 } 927 }
925 928
926 /* draw the peak meter */ 929 /* draw the peak meter */
927 lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); 930 display->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
928 lcd_fillrect(x, y, width, height); 931 display->fillrect(x, y, width, height);
929 lcd_set_drawmode(DRMODE_SOLID); 932 display->set_drawmode(DRMODE_SOLID);
930 933
931 /* draw left */ 934 /* draw left */
932 lcd_fillrect (x, y, left, height / 2 - 2 ); 935 display->fillrect (x, y, left, height / 2 - 2 );
933 if (pm_peak_left > 0) { 936 if (scales->pm_peak_left > 0) {
934 lcd_vline(x + pm_peak_left, y, y + height / 2 - 2 ); 937 display->vline(x + scales->pm_peak_left, y, y + height / 2 - 2 );
935 } 938 }
936 if (pm_clip_left) { 939 if (pm_clip_left) {
937 lcd_fillrect(x + meterwidth, y, 3, height / 2 - 1); 940 display->fillrect(x + meterwidth, y, 3, height / 2 - 1);
938 } 941 }
939 942
940 /* draw right */ 943 /* draw right */
941 lcd_fillrect(x, y + height / 2 + 1, right, height / 2 - 2); 944 display->fillrect(x, y + height / 2 + 1, right, height / 2 - 2);
942 if (pm_peak_right > 0) { 945 if (scales->pm_peak_right > 0) {
943 lcd_vline( x + pm_peak_right, y + height / 2, y + height - 2); 946 display->vline( x + scales->pm_peak_right, y + height / 2, y + height - 2);
944 } 947 }
945 if (pm_clip_right) { 948 if (pm_clip_right) {
946 lcd_fillrect(x + meterwidth, y + height / 2, 3, height / 2 - 1); 949 display->fillrect(x + meterwidth, y + height / 2, 3, height / 2 - 1);
947 } 950 }
948 951
949 /* draw scale end */ 952 /* draw scale end */
950 lcd_vline(x + meterwidth, y, y + height - 2); 953 display->vline(x + meterwidth, y, y + height - 2);
951 954
952 lcd_set_drawmode(DRMODE_COMPLEMENT); 955 display->set_drawmode(DRMODE_COMPLEMENT);
953 /* draw dots for scale marks */ 956 /* draw dots for scale marks */
954 for (i = 0; i < db_scale_count; i++) { 957 for (i = 0; i < db_scale_count; i++) {
955 /* The x-coordinates of interesting scale mark points 958 /* The x-coordinates of interesting scale mark points
956 have been calculated before */ 959 have been calculated before */
957 lcd_drawpixel(db_scale_lcd_coord[i], y + height / 2 - 1); 960 display->drawpixel(scales->db_scale_lcd_coord[i], y + height / 2 - 1);
958 } 961 }
959 962
960#ifdef HAVE_RECORDING 963#ifdef HAVE_RECORDING
@@ -988,25 +991,25 @@ void peak_meter_draw(int x, int y, int width, int height)
988 if (trig_status != TRIG_OFF) { 991 if (trig_status != TRIG_OFF) {
989 int start_trigx, stop_trigx, ycenter; 992 int start_trigx, stop_trigx, ycenter;
990 993
991 lcd_set_drawmode(DRMODE_SOLID); 994 display->set_drawmode(DRMODE_SOLID);
992 ycenter = y + height / 2; 995 ycenter = y + height / 2;
993 /* display threshold value */ 996 /* display threshold value */
994 start_trigx = x+peak_meter_scale_value(trig_strt_threshold,meterwidth); 997 start_trigx = x+peak_meter_scale_value(trig_strt_threshold,meterwidth);
995 lcd_vline(start_trigx, ycenter - 2, ycenter); 998 display->vline(start_trigx, ycenter - 2, ycenter);
996 start_trigx ++; 999 start_trigx ++;
997 if (start_trigx < LCD_WIDTH) lcd_drawpixel(start_trigx, ycenter - 1); 1000 if (start_trigx < display->width ) display->drawpixel(start_trigx, ycenter - 1);
998 1001
999 stop_trigx = x + peak_meter_scale_value(trig_stp_threshold,meterwidth); 1002 stop_trigx = x + peak_meter_scale_value(trig_stp_threshold,meterwidth);
1000 lcd_vline(stop_trigx, ycenter - 2, ycenter); 1003 display->vline(stop_trigx, ycenter - 2, ycenter);
1001 if (stop_trigx > 0) lcd_drawpixel(stop_trigx - 1, ycenter - 1); 1004 if (stop_trigx > 0) display->drawpixel(stop_trigx - 1, ycenter - 1);
1002 } 1005 }
1003#endif /*HAVE_RECORDING*/ 1006#endif /*HAVE_RECORDING*/
1004 1007
1005#ifdef PM_DEBUG 1008#ifdef PM_DEBUG
1006 /* display a bar to show how many calls to peak_meter_peek 1009 /* display a bar to show how many calls to peak_meter_peek
1007 have ocurred since the last display */ 1010 have ocurred since the last display */
1008 lcd_set_drawmode(DRMODE_COMPLEMENT); 1011 display->set_drawmode(DRMODE_COMPLEMENT);
1009 lcd_fillrect(x, y, tmp, 3); 1012 display->fillrect(x, y, tmp, 3);
1010 1013
1011 if (tmp < PEEKS_PER_DRAW_SIZE) { 1014 if (tmp < PEEKS_PER_DRAW_SIZE) {
1012 peeks_per_redraw[tmp]++; 1015 peeks_per_redraw[tmp]++;
@@ -1019,14 +1022,14 @@ void peak_meter_draw(int x, int y, int width, int height)
1019 1022
1020 /* display a bar to show how many ticks have passed since 1023 /* display a bar to show how many ticks have passed since
1021 the last redraw */ 1024 the last redraw */
1022 lcd_fillrect(x, y + height / 2, current_tick - pm_tick, 2); 1025 display->fillrect(x, y + height / 2, current_tick - pm_tick, 2);
1023 pm_tick = current_tick; 1026 pm_tick = current_tick;
1024#endif 1027#endif
1025 1028
1026 last_left = left; 1029 scales->last_left = left;
1027 last_right = right; 1030 scales->last_right = right;
1028 1031
1029 lcd_set_drawmode(DRMODE_SOLID); 1032 display->set_drawmode(DRMODE_SOLID);
1030} 1033}
1031 1034
1032#ifdef HAVE_RECORDING 1035#ifdef HAVE_RECORDING
@@ -1171,11 +1174,12 @@ void peak_meter_draw_trig(int xpos, int ypos)
1171} 1174}
1172#endif 1175#endif
1173 1176
1174int peak_meter_draw_get_btn(int x, int y, int width, int height) 1177int peak_meter_draw_get_btn(int x, int y, int height)
1175{ 1178{
1176 int button = BUTTON_NONE; 1179 int button = BUTTON_NONE;
1177 long next_refresh = current_tick; 1180 long next_refresh = current_tick;
1178 long next_big_refresh = current_tick + HZ / 10; 1181 long next_big_refresh = current_tick + HZ / 10;
1182 int i;
1179#ifndef SIMULATOR 1183#ifndef SIMULATOR
1180 bool highperf = !ata_disk_is_active(); 1184 bool highperf = !ata_disk_is_active();
1181#else 1185#else
@@ -1196,8 +1200,11 @@ int peak_meter_draw_get_btn(int x, int y, int width, int height)
1196 sleep(0); /* Sleep until end of current tick. */ 1200 sleep(0); /* Sleep until end of current tick. */
1197 } 1201 }
1198 if (TIME_AFTER(current_tick, next_refresh)) { 1202 if (TIME_AFTER(current_tick, next_refresh)) {
1199 peak_meter_draw(x, y, width, height); 1203 FOR_NB_SCREENS(i)
1200 lcd_update_rect(x, y, width, height); 1204 {
1205 peak_meter_screen(&screens[i], x, y, height);
1206 screens[i].update_rect(x, y, screens[i].width, height);
1207 }
1201 next_refresh += HZ / PEAK_METER_FPS; 1208 next_refresh += HZ / PEAK_METER_FPS;
1202 dopeek = true; 1209 dopeek = true;
1203 } 1210 }
diff --git a/apps/recorder/peakmeter.h b/apps/recorder/peakmeter.h
index 5513dfacf1..759b4547ca 100644
--- a/apps/recorder/peakmeter.h
+++ b/apps/recorder/peakmeter.h
@@ -29,8 +29,7 @@ extern bool peak_meter_histogram(void);
29extern bool peak_meter_enabled; 29extern bool peak_meter_enabled;
30 30
31extern void peak_meter_playback(bool playback); 31extern void peak_meter_playback(bool playback);
32extern void peak_meter_draw(int x, int y, int width, int height); 32extern int peak_meter_draw_get_btn(int x, int y, int height);
33extern int peak_meter_draw_get_btn(int x, int y, int width, int height);
34extern void peak_meter_set_clip_hold(int time); 33extern void peak_meter_set_clip_hold(int time);
35extern void peak_meter_peek(void); 34extern void peak_meter_peek(void);
36extern void peak_meter_init_range( bool dbfs, int range_min, int range_max); 35extern void peak_meter_init_range( bool dbfs, int range_min, int range_max);
@@ -80,4 +79,24 @@ extern void peak_meter_draw_trig(int x, int y);
80extern unsigned short peak_meter_range_min; 79extern unsigned short peak_meter_range_min;
81extern unsigned short peak_meter_range_max; 80extern unsigned short peak_meter_range_max;
82 81
82#define DB_SCALE_SRC_VALUES_SIZE 12
83struct meter_scales{
84 /* buffered peak values */
85 int pm_peak_left;
86 int pm_peak_right;
87 /* if db_scale_valid is false the content of
88 db_scale_lcd_coord needs recalculation */
89 bool db_scale_valid;
90 /* contains the lcd x coordinates of the magical
91 scale values in db_scale_src_values */
92 int db_scale_lcd_coord[DB_SCALE_SRC_VALUES_SIZE];
93 int last_left;
94 int last_right;
95 /* peak hold timeouts */
96 long pm_peak_timeout_l;
97 long pm_peak_timeout_r;
98};
99extern void peak_meter_draw(struct screen *display, struct meter_scales *meter_scales,
100 int x, int y, int width, int height);
101extern void peak_meter_screen(struct screen *display, int x, int y, int height);
83#endif /* __PEAKMETER_H__ */ 102#endif /* __PEAKMETER_H__ */
diff --git a/apps/recorder/radio.c b/apps/recorder/radio.c
index 5258b5b2a1..7cdfd51e6d 100644
--- a/apps/recorder/radio.c
+++ b/apps/recorder/radio.c
@@ -768,11 +768,17 @@ bool radio_screen(void)
768 /* Only display the peak meter when not recording */ 768 /* Only display the peak meter when not recording */
769 if(!audio_status()) 769 if(!audio_status())
770 { 770 {
771 /* just main screen for the time being */ 771
772#if CONFIG_CODEC != SWCODEC 772#if CONFIG_CODEC != SWCODEC
773 peak_meter_draw(0, STATUSBAR_HEIGHT + fh*(top_of_screen + 4), LCD_WIDTH, fh); 773 FOR_NB_SCREENS(i)
774 {
775 peak_meter_screen(&screens[i],0,
776 STATUSBAR_HEIGHT + fh*(top_of_screen + 4), fh);
777 screens[i].update_rect(0, STATUSBAR_HEIGHT + fh*(top_of_screen + 4),
778 screens[i].width, fh);
779 }
774#endif 780#endif
775 screens[SCREEN_MAIN].update_rect(0, STATUSBAR_HEIGHT + fh*(top_of_screen + 4), screens[SCREEN_MAIN].width, fh); 781
776 } 782 }
777 783
778 if(TIME_AFTER(current_tick, timeout)) 784 if(TIME_AFTER(current_tick, timeout))
diff --git a/apps/recorder/recording.c b/apps/recorder/recording.c
index 92275a580e..84fef9f3a1 100644
--- a/apps/recorder/recording.c
+++ b/apps/recorder/recording.c
@@ -43,6 +43,7 @@
43#include "lang.h" 43#include "lang.h"
44#include "font.h" 44#include "font.h"
45#include "icons.h" 45#include "icons.h"
46#include "icon.h"
46#include "screens.h" 47#include "screens.h"
47#include "peakmeter.h" 48#include "peakmeter.h"
48#include "statusbar.h" 49#include "statusbar.h"
@@ -60,6 +61,7 @@
60#include "sound.h" 61#include "sound.h"
61#include "ata.h" 62#include "ata.h"
62#include "splash.h" 63#include "splash.h"
64#include "screen_access.h"
63#ifdef HAVE_RECORDING 65#ifdef HAVE_RECORDING
64 66
65 67
@@ -104,6 +106,17 @@
104#define REC_DEC BUTTON_LEFT 106#define REC_DEC BUTTON_LEFT
105#endif 107#endif
106 108
109#if (CONFIG_REMOTE_KEYPAD == H100_REMOTE) || (CONFIG_KEYPAD == IRIVER_H300_PAD)
110#define REC_RC_SHUTDOWN (BUTTON_RC_STOP | BUTTON_REPEAT)
111#define REC_RC_STOPEXIT BUTTON_RC_STOP
112#define REC_RC_RECPAUSE BUTTON_RC_ON
113#define REC_RC_INC BUTTON_RC_BITRATE
114#define REC_RC_DEC BUTTON_RC_SOURCE
115#define REC_RC_NEXT BUTTON_RC_FF
116#define REC_RC_PREV BUTTON_RC_REW
117#define REC_RC_SETTINGS BUTTON_RC_MODE
118#endif
119
107bool f2_rec_screen(void); 120bool f2_rec_screen(void);
108bool f3_rec_screen(void); 121bool f3_rec_screen(void);
109 122
@@ -508,6 +521,7 @@ bool recording_screen(void)
508 bool led_state = false; 521 bool led_state = false;
509 int led_countdown = 2; 522 int led_countdown = 2;
510#endif 523#endif
524 int i;
511 525
512#ifdef HAVE_UDA1380 526#ifdef HAVE_UDA1380
513/*calculate no. of digital steps to each analogue step. Assuming 527/*calculate no. of digital steps to each analogue step. Assuming
@@ -565,10 +579,13 @@ bool recording_screen(void)
565 579
566 settings_apply_trigger(); 580 settings_apply_trigger();
567 581
568 lcd_setfont(FONT_SYSFIXED); 582 FOR_NB_SCREENS(i)
569 lcd_getstringsize("M", &w, &h); 583 {
570 lcd_setmargins(global_settings.invert_cursor ? 0 : w, 8); 584 screens[i].setfont(FONT_SYSFIXED);
571 585 screens[i].getstringsize("M", &w, &h);
586 screens[i].setmargins(global_settings.invert_cursor ? 0 : w, 8);
587 }
588
572 if(rec_create_directory() > 0) 589 if(rec_create_directory() > 0)
573 have_recorded = true; 590 have_recorded = true;
574 591
@@ -628,7 +645,7 @@ bool recording_screen(void)
628#endif /* CONFIG_LED */ 645#endif /* CONFIG_LED */
629 646
630 /* Wait for a button a while (HZ/10) drawing the peak meter */ 647 /* Wait for a button a while (HZ/10) drawing the peak meter */
631 button = peak_meter_draw_get_btn(0, 8 + h*2, LCD_WIDTH, h); 648 button = peak_meter_draw_get_btn(0, 8 + h*2, h*2);
632 649
633 if (last_audio_stat != audio_stat) 650 if (last_audio_stat != audio_stat)
634 { 651 {
@@ -643,6 +660,12 @@ bool recording_screen(void)
643 { 660 {
644 case REC_STOPEXIT: 661 case REC_STOPEXIT:
645 case REC_SHUTDOWN: 662 case REC_SHUTDOWN:
663#ifdef REC_RC_STOPEXIT
664 case REC_RC_STOPEXIT:
665#endif
666#ifdef REC_RC_SHUTDOWN
667 case REC_RC_SHUTDOWN:
668#endif
646 /* turn off the trigger */ 669 /* turn off the trigger */
647 peak_meter_trigger(false); 670 peak_meter_trigger(false);
648 peak_meter_set_trigger_listener(NULL); 671 peak_meter_set_trigger_listener(NULL);
@@ -663,6 +686,9 @@ bool recording_screen(void)
663 break; 686 break;
664 687
665 case REC_RECPAUSE: 688 case REC_RECPAUSE:
689#ifdef REC_RC_RECPAUSE
690 case REC_RC_RECPAUSE:
691#endif
666#ifdef REC_RECPAUSE_PRE 692#ifdef REC_RECPAUSE_PRE
667 if (lastbutton != REC_RECPAUSE_PRE) 693 if (lastbutton != REC_RECPAUSE_PRE)
668 break; 694 break;
@@ -715,6 +741,9 @@ bool recording_screen(void)
715 741
716#ifdef REC_PREV 742#ifdef REC_PREV
717 case REC_PREV: 743 case REC_PREV:
744#ifdef REC_RC_PREV
745 case REC_RC_PREV:
746#endif
718 cursor--; 747 cursor--;
719 adjust_cursor(); 748 adjust_cursor();
720 update_countdown = 1; /* Update immediately */ 749 update_countdown = 1; /* Update immediately */
@@ -723,6 +752,9 @@ bool recording_screen(void)
723 752
724#ifdef REC_NEXT 753#ifdef REC_NEXT
725 case REC_NEXT: 754 case REC_NEXT:
755#ifdef REC_RC_NEXT
756 case REC_RC_NEXT:
757#endif
726 cursor++; 758 cursor++;
727 adjust_cursor(); 759 adjust_cursor();
728 update_countdown = 1; /* Update immediately */ 760 update_countdown = 1; /* Update immediately */
@@ -731,6 +763,10 @@ bool recording_screen(void)
731 763
732 case REC_INC: 764 case REC_INC:
733 case REC_INC | BUTTON_REPEAT: 765 case REC_INC | BUTTON_REPEAT:
766#ifdef REC_RC_INC
767 case REC_RC_INC:
768 case REC_RC_INC | BUTTON_REPEAT:
769#endif
734 switch(cursor) 770 switch(cursor)
735 { 771 {
736 case 0: 772 case 0:
@@ -788,6 +824,10 @@ bool recording_screen(void)
788 824
789 case REC_DEC: 825 case REC_DEC:
790 case REC_DEC | BUTTON_REPEAT: 826 case REC_DEC | BUTTON_REPEAT:
827#ifdef REC_RC_INC
828 case REC_RC_DEC:
829 case REC_RC_DEC | BUTTON_REPEAT:
830#endif
791 switch(cursor) 831 switch(cursor)
792 { 832 {
793 case 0: 833 case 0:
@@ -848,6 +888,9 @@ bool recording_screen(void)
848 888
849#ifdef REC_SETTINGS 889#ifdef REC_SETTINGS
850 case REC_SETTINGS: 890 case REC_SETTINGS:
891#ifdef REC_RC_SETTINGS
892 case REC_RC_SETTINGS:
893#endif
851 if(audio_stat != AUDIO_STATUS_RECORD) 894 if(audio_stat != AUDIO_STATUS_RECORD)
852 { 895 {
853#if CONFIG_LED == LED_REAL 896#if CONFIG_LED == LED_REAL
@@ -874,8 +917,11 @@ bool recording_screen(void)
874 set_gain(); 917 set_gain();
875 update_countdown = 1; /* Update immediately */ 918 update_countdown = 1; /* Update immediately */
876 919
877 lcd_setfont(FONT_SYSFIXED); 920 FOR_NB_SCREENS(i)
878 lcd_setmargins(global_settings.invert_cursor ? 0 : w, 8); 921 {
922 screens[i].setfont(FONT_SYSFIXED);
923 screens[i].setmargins(global_settings.invert_cursor ? 0 : w, 8);
924 }
879 } 925 }
880 break; 926 break;
881#endif 927#endif
@@ -943,7 +989,8 @@ bool recording_screen(void)
943 if (button != BUTTON_NONE) 989 if (button != BUTTON_NONE)
944 lastbutton = button; 990 lastbutton = button;
945 991
946 lcd_setfont(FONT_SYSFIXED); 992 FOR_NB_SCREENS(i)
993 screens[i].setfont(FONT_SYSFIXED);
947 994
948 seconds = audio_recorded_time() / HZ; 995 seconds = audio_recorded_time() / HZ;
949 996
@@ -957,14 +1004,16 @@ bool recording_screen(void)
957 update_countdown = 5; 1004 update_countdown = 5;
958 last_seconds = seconds; 1005 last_seconds = seconds;
959 1006
960 lcd_clear_display(); 1007 FOR_NB_SCREENS(i)
1008 screens[i].clear_display();
961 1009
962 hours = seconds / 3600; 1010 hours = seconds / 3600;
963 minutes = (seconds - (hours * 3600)) / 60; 1011 minutes = (seconds - (hours * 3600)) / 60;
964 snprintf(buf, 32, "%s %02d:%02d:%02d", 1012 snprintf(buf, 32, "%s %02d:%02d:%02d",
965 str(LANG_RECORDING_TIME), 1013 str(LANG_RECORDING_TIME),
966 hours, minutes, seconds%60); 1014 hours, minutes, seconds%60);
967 lcd_puts(0, 0, buf); 1015 FOR_NB_SCREENS(i)
1016 screens[i].puts(0, 0, buf);
968 1017
969 dseconds = rec_timesplit_seconds(); 1018 dseconds = rec_timesplit_seconds();
970 num_recorded_bytes = audio_num_recorded_bytes(); 1019 num_recorded_bytes = audio_num_recorded_bytes();
@@ -997,7 +1046,8 @@ bool recording_screen(void)
997 str(LANG_RECORDING_SIZE), buf2); 1046 str(LANG_RECORDING_SIZE), buf2);
998 } 1047 }
999 } 1048 }
1000 lcd_puts(0, 1, buf); 1049 FOR_NB_SCREENS(i)
1050 screens[i].puts(0, 1, buf);
1001 1051
1002 /* We will do file splitting regardless, either at the end of 1052 /* We will do file splitting regardless, either at the end of
1003 a split interval, or when the filesize approaches the 2GB 1053 a split interval, or when the filesize approaches the 2GB
@@ -1017,10 +1067,15 @@ bool recording_screen(void)
1017 buf2, sizeof(buf2))); 1067 buf2, sizeof(buf2)));
1018 1068
1019 if (global_settings.invert_cursor && (pos++ == cursor)) 1069 if (global_settings.invert_cursor && (pos++ == cursor))
1020 lcd_puts_style(0, 3, buf, STYLE_INVERT); 1070 {
1071 FOR_NB_SCREENS(i)
1072 screens[i].puts_style_offset(0, 4, buf, STYLE_INVERT,0);
1073 }
1021 else 1074 else
1022 lcd_puts(0, 3, buf); 1075 {
1023 1076 FOR_NB_SCREENS(i)
1077 screens[i].puts(0, 4, buf);
1078 }
1024 1079
1025 if(global_settings.rec_source == SOURCE_MIC) 1080 if(global_settings.rec_source == SOURCE_MIC)
1026 { 1081 {
@@ -1059,9 +1114,15 @@ bool recording_screen(void)
1059 buf2, sizeof(buf2))); 1114 buf2, sizeof(buf2)));
1060#endif 1115#endif
1061 if(global_settings.invert_cursor && ((1==cursor)||(2==cursor))) 1116 if(global_settings.invert_cursor && ((1==cursor)||(2==cursor)))
1062 lcd_puts_style(0, 4, buf, STYLE_INVERT); 1117 {
1118 FOR_NB_SCREENS(i)
1119 screens[i].puts_style_offset(0, 5, buf, STYLE_INVERT,0);
1120 }
1063 else 1121 else
1064 lcd_puts(0, 4, buf); 1122 {
1123 FOR_NB_SCREENS(i)
1124 screens[i].puts(0, 5, buf);
1125 }
1065 } 1126 }
1066 else if(global_settings.rec_source == SOURCE_LINE) 1127 else if(global_settings.rec_source == SOURCE_LINE)
1067 { 1128 {
@@ -1104,9 +1165,16 @@ bool recording_screen(void)
1104 buf2, sizeof(buf2))); 1165 buf2, sizeof(buf2)));
1105#endif /* HAVE_UDA1380 */ 1166#endif /* HAVE_UDA1380 */
1106 if(global_settings.invert_cursor && ((1==cursor)||(2==cursor))) 1167 if(global_settings.invert_cursor && ((1==cursor)||(2==cursor)))
1107 lcd_puts_style(0, 4, buf, STYLE_INVERT); 1168 {
1169 FOR_NB_SCREENS(i)
1170 screens[i].puts_style_offset(0, 5, buf, STYLE_INVERT,0);
1171 }
1108 else 1172 else
1109 lcd_puts(0, 4, buf); 1173 {
1174 FOR_NB_SCREENS(i)
1175 screens[i].puts(0, 5, buf);
1176 }
1177
1110#ifdef HAVE_UDA1380 1178#ifdef HAVE_UDA1380
1111 snprintf(buf, 32, "%s:%s (%s)", 1179 snprintf(buf, 32, "%s:%s (%s)",
1112 str(LANG_RECORDING_RIGHT), 1180 str(LANG_RECORDING_RIGHT),
@@ -1134,39 +1202,59 @@ bool recording_screen(void)
1134 buf2, sizeof(buf2))); 1202 buf2, sizeof(buf2)));
1135#endif /* HAVE_UDA1380 */ 1203#endif /* HAVE_UDA1380 */
1136 if(global_settings.invert_cursor && ((1==cursor)||(3==cursor))) 1204 if(global_settings.invert_cursor && ((1==cursor)||(3==cursor)))
1137 lcd_puts_style(0, 5, buf, STYLE_INVERT); 1205 {
1206 FOR_NB_SCREENS(i)
1207 screens[i].puts_style_offset(0, 6, buf, STYLE_INVERT,0);
1208 }
1138 else 1209 else
1139 lcd_puts(0, 5, buf); 1210 {
1140 } 1211 FOR_NB_SCREENS(i)
1141 switch(cursor) 1212 screens[i].puts(0, 6, buf);
1142 { 1213 }
1143 case 1:
1144 put_cursorxy(0, 4, true);
1145
1146 if(global_settings.rec_source != SOURCE_MIC)
1147 put_cursorxy(0, 5, true);
1148
1149 break;
1150 case 2:
1151 put_cursorxy(0, 4, true);
1152 break;
1153 case 3:
1154 put_cursorxy(0, 5, true);
1155 break;
1156 default:
1157 put_cursorxy(0, 0, true);
1158 } 1214 }
1159 1215
1216 if(!global_settings.invert_cursor){
1217 switch(cursor)
1218 {
1219 case 1:
1220 FOR_NB_SCREENS(i)
1221 screen_put_cursorxy(&screens[i], 0, 5, true);
1222
1223 if(global_settings.rec_source != SOURCE_MIC)
1224 {
1225 FOR_NB_SCREENS(i)
1226 screen_put_cursorxy(&screens[i], 0, 6, true);
1227 }
1228 break;
1229 case 2:
1230 FOR_NB_SCREENS(i)
1231 screen_put_cursorxy(&screens[i], 0, 5, true);
1232 break;
1233 case 3:
1234 FOR_NB_SCREENS(i)
1235 screen_put_cursorxy(&screens[i], 0, 6, true);
1236 break;
1237 default:
1238 FOR_NB_SCREENS(i)
1239 screen_put_cursorxy(&screens[i], 0, 4, true);
1240 }
1241 }
1242
1160 snprintf(buf, 32, "%s %s", 1243 snprintf(buf, 32, "%s %s",
1161 freq_str[global_settings.rec_frequency], 1244 freq_str[global_settings.rec_frequency],
1162 global_settings.rec_channels? 1245 global_settings.rec_channels?
1163 str(LANG_CHANNEL_MONO):str(LANG_CHANNEL_STEREO)); 1246 str(LANG_CHANNEL_MONO):str(LANG_CHANNEL_STEREO));
1164 lcd_puts(0, 7, buf); 1247
1248 /* Main screen only for this info */
1249 lcd_puts(0, 8, buf);
1165 1250
1166 gui_syncstatusbar_draw(&statusbars, true); 1251 gui_syncstatusbar_draw(&statusbars, true);
1167 peak_meter_draw(0, 8 + h*2, LCD_WIDTH, h);
1168 1252
1169 lcd_update(); 1253 FOR_NB_SCREENS(i)
1254 {
1255 peak_meter_screen(&screens[i], 0, 8 + h*2, h*2);
1256 screens[i].update();
1257 }
1170 1258
1171 /* draw the trigger status */ 1259 /* draw the trigger status */
1172 if (peak_meter_trigger_status() != TRIG_OFF) 1260 if (peak_meter_trigger_status() != TRIG_OFF)
@@ -1227,9 +1315,6 @@ bool recording_screen(void)
1227 ata_set_led_enabled(true); 1315 ata_set_led_enabled(true);
1228#endif 1316#endif
1229 return been_in_usb_mode; 1317 return been_in_usb_mode;
1230/*
1231#endif
1232*/
1233} 1318}
1234 1319
1235#ifdef REC_F2 1320#ifdef REC_F2
diff --git a/apps/sound_menu.c b/apps/sound_menu.c
index 1c61c6630a..5944c46100 100644
--- a/apps/sound_menu.c
+++ b/apps/sound_menu.c
@@ -666,7 +666,7 @@ bool rectrigger(void)
666 666
667 peak_meter_draw_trig(0, LCD_HEIGHT - 8 - TRIG_HEIGHT); 667 peak_meter_draw_trig(0, LCD_HEIGHT - 8 - TRIG_HEIGHT);
668 668
669 button = peak_meter_draw_get_btn(0, LCD_HEIGHT - 8, LCD_WIDTH, 8); 669 button = peak_meter_draw_get_btn(0, LCD_HEIGHT - 8, 8);
670 670
671 lcd_update(); 671 lcd_update();
672 672