diff options
author | Linus Nielsen Feltzing <linus@haxx.se> | 2004-08-21 23:22:05 +0000 |
---|---|---|
committer | Linus Nielsen Feltzing <linus@haxx.se> | 2004-08-21 23:22:05 +0000 |
commit | 792bd17a089c290a201a811fd64f5a6f5f21ff2f (patch) | |
tree | 442b268874d500104ec6e615dee57a85de942698 | |
parent | 1e9de584f604f7d9da4e2e1ee7ce25c909ec1969 (diff) | |
download | rockbox-792bd17a089c290a201a811fd64f5a6f5f21ff2f.tar.gz rockbox-792bd17a089c290a201a811fd64f5a6f5f21ff2f.zip |
Patch #1002379 by Lee Pilgrim, New VU meter
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@5004 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | apps/plugins/vu_meter.c | 729 |
1 files changed, 321 insertions, 408 deletions
diff --git a/apps/plugins/vu_meter.c b/apps/plugins/vu_meter.c index a9d74da794..c400a4e189 100644 --- a/apps/plugins/vu_meter.c +++ b/apps/plugins/vu_meter.c | |||
@@ -15,508 +15,421 @@ | |||
15 | * KIND, either express or implied. | 15 | * KIND, either express or implied. |
16 | * | 16 | * |
17 | **************************************************************************/ | 17 | **************************************************************************/ |
18 | |||
19 | /****************************************************** | ||
20 | * Quick note: throughout this code you'll see | ||
21 | * comments like this one, inside of a box. They are | ||
22 | * used to indicate new functions, not because I | ||
23 | * think you're blind. Only here to help. | ||
24 | ******************************************************/ | ||
25 | |||
26 | #include "plugin.h" | 18 | #include "plugin.h" |
27 | 19 | ||
28 | #ifdef HAVE_LCD_BITMAP | 20 | #ifdef HAVE_LCD_BITMAP |
29 | 21 | ||
30 | static struct plugin_api* rb; | 22 | const struct plugin_api* rb; |
31 | |||
32 | /* This table is used to define x positions on a logarithmic (dBfs) scale. | ||
33 | There are 112 of them, one for each pixel. | ||
34 | The formula I used to figure these out was log(x)*32.09, | ||
35 | where x was the original x position. */ | ||
36 | static unsigned char db_scale[] = {0,0,10,15,19,22,25,27,29,31,32,33,35,36,37,38,39,39,40,41,42,42, | ||
37 | 43,44,44,45,45,46,46,47,47,48,48,49,49,50,50,50,51,51,51,52,52, | ||
38 | 52,53,53,53,54,54,54,55,55,55,55,56,56,56,56,56,66, 71,75,78,81, | ||
39 | 83,85,87,88,89,91,92,93,94,95,95,96,97,98,98,99,100,100,101,101, | ||
40 | 102,102,103,103,104,104,105,105,106,106,106,107,107,107,108,108, | ||
41 | 108,109,109,109,110,110,110,111,111,111,111,112,112,112}; | ||
42 | |||
43 | /* Define's y positions, and makes it look like an arch, like a real needle would. */ | ||
44 | static unsigned char y_values[] = {32,31,30,29,28,27,26,25,24,24,23,22,22,21,21,20,19,19,18,18,18,18,18,17,17,17,17,17, | ||
45 | 17,17,17,17,17,18,18,18,18,18,19,19,20,21,21,22,22,23,24,24,25,26,27,28,29,30,31,32, | ||
46 | 32,31,30,29,28,27,26,25,24,24,23,22,22,21,21,20,19,19,18,18,18,18,18,17,17,17,17,17, | ||
47 | 17,17,17,17,17,18,18,18,18,18,19,19,20,21,21,22,22,23,24,24,25,26,27,28,29,30,31,32}; | ||
48 | |||
49 | /*************************************************** | ||
50 | * LCD Bitmaps/Icons | ||
51 | ***************************************************/ | ||
52 | |||
53 | /* Linear mode bitmap icon. */ | ||
54 | unsigned char mode_linear[] = {0xDF,0x10,0xD0,0x00,0xDF,0x00,0xDF,0x02,0xC4,0x08,0xDF, | ||
55 | 0x00,0xDF,0x15,0xD1,0x00,0xDE,0x05,0xDE,0x00,0xDF,0x05, | ||
56 | 0xDA}; | ||
57 | |||
58 | /* Logarithmic (dBfs) mode bitmap icon. */ | ||
59 | unsigned char mode_dbfs[] = {0xC8,0x14,0x14,0x1F,0x00,0xDF,0x15,0x15,0x0A,0xC0,0x1E, | ||
60 | 0x05,0x05,0xC0,0x16,0x15,0xD5,0x09,0xC0,0x00,0xF0,0x00, | ||
61 | 0xFE}; | ||
62 | 23 | ||
63 | /* Channel indicator - no level [4x8] */ | 24 | /* Defines x positions on a logarithmic (dBfs) scale. */ |
64 | static unsigned char sound_speaker[] = {0x18,0x24,0x42,0xFF}; | 25 | const unsigned char analog_db_scale[] = |
26 | {0,0,10,15,19,22,25,27,29,31,32,33,35,36,37,38,39,39,40,41,42,42,43,44,44,45,45,46, | ||
27 | 46,47,47,48,48,49,49,50,50,50,51,51,51,52,52,52,53,53,53,54,54,54,55,55,55,55,56,56}; | ||
65 | 28 | ||
66 | /* Channel indicator - low level [2x8] */ | 29 | const unsigned char digital_db_scale[] = |
67 | static unsigned char sound_low_level[] = {0x24,0x18}; | 30 | {0,2,3,5,5,6,6,6,7,7,7,7,8,8,8,8,8,9,9,9,9,9,9,9,9,10,10, |
31 | 10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11}; | ||
68 | 32 | ||
69 | /* Channel indicator - medium level [2x8] */ | 33 | /* Define's y positions, to make the needle arch, like a real needle would. */ |
70 | static unsigned char sound_med_level[] = {0x42,0x3C}; | 34 | const unsigned char y_values[] = |
35 | {34,34,33,33,32,32,31,31,30,30,29,29,28,28,28,27,27,27,26,26,26,26,25,25,25,25,25,25, | ||
36 | 25,25,25,25,25,25,26,26,26,26,27,27,27,28,28,28,29,29,30,30,31,31,32,32,33,33,34,34}; | ||
71 | 37 | ||
72 | /* Channel indicator - high level [2x8] */ | 38 | const unsigned char led[] = {0x0e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x0e}; |
73 | static unsigned char sound_high_level[] = {0x81,0x7E}; | ||
74 | 39 | ||
75 | /* Channel indicator - maxed out [3x8] */ | 40 | const unsigned char needle_cover[] = |
76 | static unsigned char sound_max_level[] = {0x0E,0xDF,0x0E}; | 41 | {0x18, 0x1c, 0x1c, 0x1e, 0x1e, 0x1f, 0x1f, 0x1f, 0x1e, 0x1e, 0x1c, 0x1c, 0x18}; |
77 | 42 | ||
78 | /* Volume level icon [4x7] */ | 43 | const unsigned char sound_speaker[] = {0x18,0x24,0x42,0xFF}; |
79 | static unsigned char volume_indicator[] = {0x1C,0x1C,0x22,0x7F}; | 44 | const unsigned char sound_low_level[] = {0x24,0x18}; |
45 | const unsigned char sound_med_level[] = {0x42,0x3C}; | ||
46 | const unsigned char sound_high_level[] = {0x81,0x7E}; | ||
47 | const unsigned char sound_max_level[] = {0x0E,0xDF,0x0E}; | ||
80 | 48 | ||
81 | /* RIGHT ARROW icon (from icons.c) [7x8] */ | 49 | #define ANALOG 1 /* The two meter types */ |
82 | static unsigned char right_arrow[] = {0x7F,0x3E,0x1C,0x7F,0x3E,0x1C,0x08}; | 50 | #define DIGITAL 2 |
83 | 51 | ||
84 | /* LEFT ARROW icon (from icons.c) [7x8] */ | ||
85 | static unsigned char left_arrow[] = {0x08,0x1C,0x3E,0x7F,0x1C,0x3E,0x7F}; | ||
86 | |||
87 | /************************* | ||
88 | * DEFINES | ||
89 | *************************/ | ||
90 | #define MAX_PEAK 0x7FFF | ||
91 | #define NEEDLE_BOTTOM_Y 54 | ||
92 | |||
93 | /****************************** | ||
94 | * LEFT NEEDLE ints | ||
95 | ******************************/ | ||
96 | #define LEFT_NEEDLE_BOTTOM_X 28 | ||
97 | int left_needle_top_y; | 52 | int left_needle_top_y; |
98 | int left_needle_top_x; | 53 | int left_needle_top_x; |
99 | int old_left_needle_top_x = 0; | 54 | int last_left_needle_top_x; |
100 | int left_needle_top_x_no_log; | ||
101 | |||
102 | /******************************* | ||
103 | * RIGHT NEEDLE ints | ||
104 | *******************************/ | ||
105 | #define RIGHT_NEEDLE_BOTTOM_X 84 | ||
106 | int right_needle_top_y; | 55 | int right_needle_top_y; |
107 | int right_needle_top_x; | 56 | int right_needle_top_x; |
108 | int old_right_needle_top_x = 56; | 57 | int last_right_needle_top_x = 56; |
109 | int right_needle_top_x_no_log; | ||
110 | |||
111 | /********************* | ||
112 | * LEFT MINIMETER ints | ||
113 | *********************/ | ||
114 | int mini_left_low; | ||
115 | int mini_left_med; | ||
116 | int mini_left_high; | ||
117 | int mini_left_clip; | ||
118 | |||
119 | /********************** | ||
120 | * RIGHT MINIMETER ints | ||
121 | **********************/ | ||
122 | int mini_right_low; | ||
123 | int mini_right_med; | ||
124 | int mini_right_high; | ||
125 | int mini_right_clip; | ||
126 | |||
127 | /************************ | ||
128 | * GENERAL ints | ||
129 | ************************/ | ||
130 | char curr_vol[3]; /* CURRENT VOLUME */ | ||
131 | int vol; /* CURENNT VOLUME int */ | ||
132 | int on = 1; /* MINIMETER OPTIONS int */ | ||
133 | int needle_cover_mode = 1; /* NEEDLE COVER int (defaults to "rounded") */ | ||
134 | int arch = 1; /* ARCH int (defaults to "solid") */ | ||
135 | int decay = 3; /* DECAY int (defaults to "medium") */ | ||
136 | |||
137 | /************************* | ||
138 | * GENERAL bools | ||
139 | *************************/ | ||
140 | bool quit = false; | ||
141 | bool use_log_scale = true; | ||
142 | bool use_minimeters = true; | ||
143 | |||
144 | /******************************************** | ||
145 | * Change the volume - derived from VIDEO.C | ||
146 | ********************************************/ | ||
147 | void ChangeVolume(int delta) | ||
148 | { | ||
149 | vol = rb->global_settings->volume + delta; | ||
150 | 58 | ||
151 | if (vol > 100) vol = 100; | 59 | int num_left_leds; |
152 | else if (vol < 0) vol = 0; | 60 | int num_right_leds; |
153 | if (vol != rb->global_settings->volume) | 61 | int last_num_left_leds; |
154 | { | 62 | int last_num_right_leds; |
155 | rb->mpeg_sound_set(SOUND_VOLUME, vol); | ||
156 | rb->global_settings->volume = vol; | ||
157 | rb->snprintf(curr_vol, sizeof(curr_vol), "%d", vol); | ||
158 | } | ||
159 | } | ||
160 | 63 | ||
161 | /***************************************************** | 64 | int i; |
162 | * Draw the status bar | ||
163 | *****************************************************/ | ||
164 | void draw_status_bar(void) | ||
165 | { | ||
166 | rb->lcd_setfont(FONT_SYSFIXED); | ||
167 | 65 | ||
168 | rb->lcd_drawline(0, 10, 112, 10); | 66 | #define MAX_PEAK 0x7FFF |
169 | rb->lcd_putsxy(1, 1, "VU Meter"); | ||
170 | rb->lcd_drawline(52, 1, 52, 8); | ||
171 | rb->lcd_bitmap(volume_indicator, 60, 1, 4, 7, true); | ||
172 | rb->lcd_putsxy(65, 1, curr_vol); | ||
173 | rb->lcd_drawline(85, 1, 85, 8); | ||
174 | |||
175 | if(use_log_scale) | ||
176 | rb->lcd_bitmap(mode_dbfs, 88, 1, 23, 8, true); | ||
177 | else | ||
178 | rb->lcd_bitmap(mode_linear, 88, 1, 23, 8, true); | ||
179 | |||
180 | /* The last line under the needle covers. */ | ||
181 | rb->lcd_drawline(0, 54, 111, 54); | ||
182 | 67 | ||
183 | rb->lcd_update_rect(0, 0, 112, 10); | 68 | struct saved_settings { |
69 | int meter_type; | ||
70 | bool analog_use_db_scale; | ||
71 | bool digital_use_db_scale; | ||
72 | bool analog_minimeters; | ||
73 | bool digital_minimeters; | ||
74 | int analog_decay; | ||
75 | int digital_decay; | ||
76 | } settings; | ||
77 | |||
78 | void reset_settings(void) { | ||
79 | settings.meter_type=ANALOG; | ||
80 | settings.analog_use_db_scale=true; | ||
81 | settings.digital_use_db_scale=true; | ||
82 | settings.analog_minimeters=true; | ||
83 | settings.digital_minimeters=false; | ||
84 | settings.analog_decay=3; | ||
85 | settings.digital_decay=0; | ||
184 | } | 86 | } |
185 | 87 | ||
186 | /****************************** | 88 | void load_settings(void) { |
187 | * DRAW left MiniMeters | 89 | int fp = rb->open("/.rockbox/rocks/.vu_meter", O_RDONLY); |
188 | ******************************/ | 90 | if(fp>=0) { |
91 | rb->read(fp, &settings, sizeof(struct saved_settings)); | ||
92 | rb->close(fp); | ||
93 | } | ||
94 | else { | ||
95 | reset_settings(); | ||
96 | rb->splash(HZ, true, "Press ON for help"); | ||
97 | } | ||
98 | } | ||
189 | 99 | ||
190 | void draw_left_minimeters(void) | 100 | void save_settings(void) { |
191 | { | 101 | int fp = rb->creat("/.rockbox/rocks/.vu_meter", O_WRONLY); |
192 | rb->lcd_bitmap(sound_speaker, 22, 56, 4, 8, true); | 102 | if(fp >= 0) { |
193 | 103 | rb->write (fp, &settings, sizeof(struct saved_settings)); | |
194 | if(5<left_needle_top_x_no_log) | 104 | rb->close(fp); |
195 | rb->lcd_bitmap(sound_low_level, 27, 56, 2, 8, false); | 105 | } |
196 | if(12<left_needle_top_x_no_log) | ||
197 | rb->lcd_bitmap(sound_med_level, 30, 56, 2, 8, false); | ||
198 | if(24<left_needle_top_x_no_log) | ||
199 | rb->lcd_bitmap(sound_high_level, 33, 56, 2, 8, false); | ||
200 | if(40<left_needle_top_x_no_log) | ||
201 | rb->lcd_bitmap(sound_max_level, 36, 56, 3, 8, false); | ||
202 | } | 106 | } |
203 | 107 | ||
204 | /******************************* | 108 | void change_volume(int delta) { |
205 | * DRAW right MiniMeters | 109 | char curr_vol[4]; |
206 | *******************************/ | 110 | int vol = rb->global_settings->volume + delta; |
207 | void draw_right_minimeters(void) | 111 | |
208 | { | 112 | if (vol>100) vol = 100; |
209 | rb->lcd_bitmap(sound_speaker, 79, 56, 4, 8, true); | 113 | else if (vol < 0) vol = 0; |
210 | 114 | if (vol != rb->global_settings->volume) { | |
211 | if(5<(right_needle_top_x_no_log-56)) | 115 | rb->mpeg_sound_set(SOUND_VOLUME, vol); |
212 | rb->lcd_bitmap(sound_low_level, 84, 56, 2, 8, false); | 116 | rb->global_settings->volume = vol; |
213 | if(12<(right_needle_top_x_no_log-56)) | 117 | rb->snprintf(curr_vol, sizeof(curr_vol), "%d", vol); |
214 | rb->lcd_bitmap(sound_med_level, 87, 56, 2, 8, false); | 118 | rb->lcd_putsxy(0,0, curr_vol); |
215 | if(24<(right_needle_top_x_no_log-56)) | 119 | rb->lcd_update(); |
216 | rb->lcd_bitmap(sound_high_level, 90, 56, 2, 8, false); | 120 | rb->sleep(HZ/12); |
217 | if(40<(right_needle_top_x_no_log-56)) | 121 | } |
218 | rb->lcd_bitmap(sound_max_level, 93, 56, 3, 8, false); | ||
219 | } | 122 | } |
220 | 123 | ||
221 | /*************************************** | 124 | void change_settings(void) |
222 | * GENERAL SETTINGS - F1 | ||
223 | ***************************************/ | ||
224 | void general_settings(void) | ||
225 | { | 125 | { |
226 | char buf[15]; | 126 | int selected_setting=0; |
227 | int w, h; | 127 | bool quit=false; |
228 | |||
229 | while(!quit) | 128 | while(!quit) |
230 | { | 129 | { |
231 | rb->lcd_clear_display(); | 130 | rb->lcd_clear_display(); |
232 | 131 | ||
233 | /* Left hand side (needle covers) */ | 132 | rb->lcd_putsxy(33, 0, "Settings"); |
234 | rb->lcd_putsxy(0, 15, "Needle"); | 133 | |
235 | rb->lcd_putsxy(0, 23, "Covers:"); | 134 | rb->lcd_putsxy(0, 8, "Meter type:"); |
236 | if(needle_cover_mode == 1) | 135 | if(settings.meter_type==ANALOG) |
237 | rb->lcd_putsxy(0, 32, "Rounded"); | 136 | rb->lcd_putsxy(67, 8, "Analog"); |
238 | else | 137 | else |
239 | rb->lcd_putsxy(0, 32, "Pyramid"); | 138 | rb->lcd_putsxy(67, 8, "Digital"); |
240 | rb->lcd_bitmap(left_arrow, 43, 23, 7, 8, true); | 139 | |
241 | 140 | if(settings.meter_type==ANALOG) { | |
242 | /* Right hand side (visible arch) */ | 141 | rb->lcd_putsxy(0, 16, "Scale:"); |
243 | rb->snprintf(buf, sizeof(buf), "Visible"); | 142 | if(settings.analog_use_db_scale) |
244 | rb->lcd_getstringsize(buf, &w, &h); | 143 | rb->lcd_putsxy(36, 16, "dBfs"); |
245 | rb->lcd_putsxy(LCD_WIDTH-w, 15, buf); | 144 | else |
246 | rb->snprintf(buf, sizeof(buf), "Arch:"); | 145 | rb->lcd_putsxy(36, 16, "Linear"); |
247 | rb->lcd_getstringsize(buf, &w, &h); | 146 | |
248 | rb->lcd_putsxy(LCD_WIDTH-w, 23, buf); | 147 | rb->lcd_putsxy(0, 24, "Minimeters:"); |
249 | rb->lcd_bitmap(right_arrow, 62, 23, 7, 8, true); | 148 | if(settings.analog_minimeters) |
250 | if(arch == 1) | 149 | rb->lcd_putsxy(65, 24, "On"); |
251 | { | 150 | else |
252 | rb->snprintf(buf, sizeof(buf), "Solid"); | 151 | rb->lcd_putsxy(65, 24, "Off"); |
253 | rb->lcd_getstringsize(buf, &w, &h); | 152 | |
254 | rb->lcd_putsxy(LCD_WIDTH-w, 32, buf); | 153 | rb->lcd_putsxy(0, 32, "Decay Speed:"); |
154 | switch(settings.analog_decay) { | ||
155 | case 0: rb->lcd_putsxy(10, 40, "No Decay"); break; | ||
156 | case 1: rb->lcd_putsxy(10, 40, "Very Fast"); break; | ||
157 | case 2: rb->lcd_putsxy(10, 40, "Fast"); break; | ||
158 | case 3: rb->lcd_putsxy(10, 40, "Medium"); break; | ||
159 | case 4: rb->lcd_putsxy(10, 40, "Medium-Slow"); break; | ||
160 | case 5: rb->lcd_putsxy(10, 40, "Slow"); break; | ||
161 | case 6: rb->lcd_putsxy(10, 40, "Very Slow"); break; | ||
162 | } | ||
255 | } | 163 | } |
256 | else if(arch == 2) | 164 | else { |
257 | { | 165 | rb->lcd_putsxy(0, 16, "Scale:"); |
258 | rb->snprintf(buf, sizeof(buf), "Dotted"); | 166 | if(settings.digital_use_db_scale) |
259 | rb->lcd_getstringsize(buf, &w, &h); | 167 | rb->lcd_putsxy(36, 16, "dBfs"); |
260 | rb->lcd_putsxy(LCD_WIDTH-w, 32, buf); | 168 | else |
169 | rb->lcd_putsxy(36, 16, "Linear"); | ||
170 | |||
171 | rb->lcd_putsxy(0, 24, "Minimeters:"); | ||
172 | if(settings.digital_minimeters) | ||
173 | rb->lcd_putsxy(65, 24, "On"); | ||
174 | else | ||
175 | rb->lcd_putsxy(65, 24, "Off"); | ||
176 | |||
177 | rb->lcd_putsxy(0, 32, "Decay Speed:"); | ||
178 | switch(settings.digital_decay) { | ||
179 | case 0: rb->lcd_putsxy(10, 40, "No Decay"); break; | ||
180 | case 1: rb->lcd_putsxy(10, 40, "Very Fast"); break; | ||
181 | case 2: rb->lcd_putsxy(10, 40, "Fast"); break; | ||
182 | case 3: rb->lcd_putsxy(10, 40, "Medium"); break; | ||
183 | case 4: rb->lcd_putsxy(10, 40, "Medium-Slow"); break; | ||
184 | case 5: rb->lcd_putsxy(10, 40, "Slow"); break; | ||
185 | case 6: rb->lcd_putsxy(10, 40, "Very Slow"); break; | ||
186 | } | ||
261 | } | 187 | } |
262 | else | ||
263 | { | ||
264 | rb->snprintf(buf, sizeof(buf), "Off"); | ||
265 | rb->lcd_getstringsize(buf, &w, &h); | ||
266 | rb->lcd_putsxy(LCD_WIDTH-w, 32, buf); | ||
267 | } | ||
268 | 188 | ||
189 | rb->lcd_invertrect(0, selected_setting*8+8,111,8); | ||
269 | rb->lcd_update(); | 190 | rb->lcd_update(); |
270 | 191 | ||
271 | switch(rb->button_get_w_tmo(HZ/4)) | 192 | switch(rb->button_get_w_tmo(1)) |
272 | { | 193 | { |
273 | case BUTTON_F1: | 194 | case BUTTON_F1: |
274 | case BUTTON_OFF: | 195 | case BUTTON_OFF: |
275 | quit = true; | 196 | quit = true; |
276 | break; | 197 | break; |
277 | 198 | ||
199 | case BUTTON_LEFT: | ||
200 | if(selected_setting==0) | ||
201 | settings.meter_type == DIGITAL ? settings.meter_type = ANALOG : settings.meter_type++; | ||
202 | if(settings.meter_type==ANALOG) { | ||
203 | if(selected_setting==1) | ||
204 | settings.analog_use_db_scale = !settings.analog_use_db_scale; | ||
205 | if(selected_setting==2) | ||
206 | settings.analog_minimeters = !settings.analog_minimeters; | ||
207 | if(selected_setting==3) | ||
208 | settings.analog_decay == 0 ? settings.analog_decay = 6 : settings.analog_decay--; | ||
209 | } | ||
210 | else { | ||
211 | if(selected_setting==1) | ||
212 | settings.digital_use_db_scale = !settings.digital_use_db_scale; | ||
213 | if(selected_setting==2) | ||
214 | settings.digital_minimeters = !settings.digital_minimeters; | ||
215 | if(selected_setting==3) | ||
216 | settings.digital_decay == 0 ? settings.digital_decay = 6 : settings.digital_decay--; | ||
217 | } | ||
218 | break; | ||
219 | |||
278 | case BUTTON_RIGHT: | 220 | case BUTTON_RIGHT: |
279 | arch==3 ? arch=1 : arch++; | 221 | if(selected_setting==0) |
222 | settings.meter_type == DIGITAL ? settings.meter_type = ANALOG : settings.meter_type++; | ||
223 | if(settings.meter_type==ANALOG) { | ||
224 | if(selected_setting==1) | ||
225 | settings.analog_use_db_scale = !settings.analog_use_db_scale; | ||
226 | if(selected_setting==2) | ||
227 | settings.analog_minimeters = !settings.analog_minimeters; | ||
228 | if(selected_setting==3) | ||
229 | settings.analog_decay == 6 ? settings.analog_decay = 0 : settings.analog_decay++; | ||
230 | } | ||
231 | else { | ||
232 | if(selected_setting==1) | ||
233 | settings.digital_use_db_scale = !settings.digital_use_db_scale; | ||
234 | if(selected_setting==2) | ||
235 | settings.digital_minimeters = !settings.digital_minimeters; | ||
236 | if(selected_setting==3) | ||
237 | settings.digital_decay == 6 ? settings.digital_decay = 0 : settings.digital_decay++; | ||
238 | } | ||
280 | break; | 239 | break; |
281 | 240 | ||
282 | case BUTTON_LEFT: | 241 | case BUTTON_DOWN: |
283 | needle_cover_mode==2 ? needle_cover_mode=1 : needle_cover_mode++; | 242 | selected_setting == 3 ? selected_setting=0 : selected_setting++; |
284 | break; | 243 | break; |
244 | |||
245 | case BUTTON_UP: | ||
246 | selected_setting == 0 ? selected_setting=3 : selected_setting--; | ||
285 | } | 247 | } |
286 | } | 248 | } |
287 | } | 249 | } |
288 | 250 | ||
289 | /***************************** | 251 | void draw_analog_minimeters(void) { |
290 | * User Decay settings | 252 | rb->lcd_bitmap(sound_speaker, 0, 12, 4, 8, true); |
291 | *****************************/ | 253 | if(5<left_needle_top_x) |
292 | void user_decay_settings(void) | 254 | rb->lcd_bitmap(sound_low_level, 5, 12, 2, 8, false); |
293 | { | 255 | if(12<left_needle_top_x) |
294 | while(!quit) | 256 | rb->lcd_bitmap(sound_med_level, 7, 12, 2, 8, false); |
295 | { | 257 | if(24<left_needle_top_x) |
296 | rb->lcd_clear_display(); | 258 | rb->lcd_bitmap(sound_high_level, 9, 12, 2, 8, false); |
297 | 259 | if(40<left_needle_top_x) | |
298 | rb->lcd_putsxy(2, 0, "User Decay Options"); | 260 | rb->lcd_bitmap(sound_max_level, 12, 12, 3, 8, false); |
299 | rb->lcd_putsxy(5, 15, "Release Speed:"); | 261 | |
300 | 262 | rb->lcd_bitmap(sound_speaker, 54, 12, 4, 8, true); | |
301 | switch(decay) | 263 | if(5<(right_needle_top_x-56)) |
302 | { | 264 | rb->lcd_bitmap(sound_low_level, 59, 12, 2, 8, false); |
303 | case 0: rb->lcd_putsxy(5, 23, "No Decay"); break; | 265 | if(12<(right_needle_top_x-56)) |
304 | case 1: rb->lcd_putsxy(5, 23, "Very Fast"); break; | 266 | rb->lcd_bitmap(sound_med_level, 61, 12, 2, 8, false); |
305 | case 2: rb->lcd_putsxy(5, 23, "Fast"); break; | 267 | if(24<(right_needle_top_x-56)) |
306 | case 3: rb->lcd_putsxy(5, 23, "Medium"); break; | 268 | rb->lcd_bitmap(sound_high_level, 63, 12, 2, 8, false); |
307 | case 4: rb->lcd_putsxy(5, 23, "Medium-Slow"); break; | 269 | if(40<(right_needle_top_x-56)) |
308 | case 5: rb->lcd_putsxy(5, 23, "Slow"); break; | 270 | rb->lcd_bitmap(sound_max_level, 66, 12, 3, 8, false); |
309 | case 6: rb->lcd_putsxy(5, 23, "Very Slow"); break; | ||
310 | default: break; | ||
311 | } | ||
312 | |||
313 | rb->lcd_putsxy(2, 48, "UP/DOWN: Change"); | ||
314 | rb->lcd_putsxy(2, 56, "OFF/F2: Back to VU"); | ||
315 | |||
316 | rb->lcd_update(); | ||
317 | |||
318 | switch(rb->button_get_w_tmo(HZ/4)) | ||
319 | { | ||
320 | case BUTTON_F2: | ||
321 | case BUTTON_OFF: | ||
322 | quit = true; | ||
323 | break; | ||
324 | |||
325 | case BUTTON_DOWN: | ||
326 | decay == 6 ? decay = 0 : decay++; | ||
327 | break; | ||
328 | |||
329 | case BUTTON_UP: | ||
330 | decay == 0 ? decay = 6 : decay--; | ||
331 | break; | ||
332 | } | ||
333 | } | ||
334 | } | 271 | } |
335 | 272 | ||
336 | /*********************************************************************** | 273 | void draw_digital_minimeters(void) { |
337 | * PLUGIN STARTS HERE | 274 | rb->lcd_bitmap(sound_speaker, 34, 24, 4, 8, true); |
338 | ***********************************************************************/ | 275 | if(1<num_left_leds) |
339 | enum plugin_status plugin_start(struct plugin_api* api, void* parameter) | 276 | rb->lcd_bitmap(sound_low_level, 39, 24, 2, 8, false); |
340 | { | 277 | if(2<num_left_leds) |
341 | TEST_PLUGIN_API(api); | 278 | rb->lcd_bitmap(sound_med_level, 41, 24, 2, 8, false); |
342 | (void) parameter; | 279 | if(5<num_left_leds) |
343 | rb = api; | 280 | rb->lcd_bitmap(sound_high_level, 43, 24, 2, 8, false); |
281 | if(8<num_left_leds) | ||
282 | rb->lcd_bitmap(sound_max_level, 46, 24, 3, 8, false); | ||
283 | |||
284 | rb->lcd_bitmap(sound_speaker, 34, 40, 4, 8, true); | ||
285 | if(1<(num_right_leds)) | ||
286 | rb->lcd_bitmap(sound_low_level, 39, 40, 2, 8, false); | ||
287 | if(2<(num_right_leds)) | ||
288 | rb->lcd_bitmap(sound_med_level, 41, 40, 2, 8, false); | ||
289 | if(5<(num_right_leds)) | ||
290 | rb->lcd_bitmap(sound_high_level, 43, 40, 2, 8, false); | ||
291 | if(8<(num_right_leds)) | ||
292 | rb->lcd_bitmap(sound_max_level, 46, 40, 3, 8, false); | ||
293 | } | ||
344 | 294 | ||
345 | /* Calculate the volume right away */ | 295 | void analog_meter(void) { |
346 | vol = rb->global_settings->volume; | 296 | if(settings.analog_use_db_scale) { |
347 | rb->snprintf(curr_vol, sizeof(curr_vol), "%d", vol); | 297 | left_needle_top_x = analog_db_scale[rb->mas_codec_readreg(0xC)*56/MAX_PEAK]; |
298 | right_needle_top_x = analog_db_scale[rb->mas_codec_readreg(0xD)*56/MAX_PEAK]+56; | ||
299 | } | ||
348 | 300 | ||
349 | rb->splash(HZ*2, true, "Press [ON] for help"); | 301 | else { |
350 | while (!PLUGIN_OK) | 302 | left_needle_top_x = rb->mas_codec_readreg(0xC) * 56 / MAX_PEAK; |
351 | { | 303 | right_needle_top_x = (rb->mas_codec_readreg(0xD) * 56 / MAX_PEAK)+56; |
352 | quit = false; | 304 | } |
353 | 305 | ||
354 | #ifdef SIMULATOR | 306 | /* Makes a decay on the needle */ |
355 | left_needle_top_x_no_log = rb->rand()%56; | 307 | left_needle_top_x = (left_needle_top_x+last_left_needle_top_x*settings.analog_decay)/(settings.analog_decay+1); |
356 | right_needle_top_x_no_log = (rb->rand()%56)+56; | 308 | right_needle_top_x = (right_needle_top_x+last_right_needle_top_x*settings.analog_decay)/(settings.analog_decay+1); |
357 | #else | ||
358 | left_needle_top_x_no_log = | ||
359 | (rb->mas_codec_readreg(0xC) * 56 / MAX_PEAK); | ||
360 | 309 | ||
361 | right_needle_top_x_no_log = | 310 | last_left_needle_top_x = left_needle_top_x; |
362 | (rb->mas_codec_readreg(0xD) * 56 / MAX_PEAK) + 56; | 311 | last_right_needle_top_x = right_needle_top_x; |
363 | #endif | ||
364 | 312 | ||
365 | rb->lcd_clear_display(); | 313 | left_needle_top_y = y_values[left_needle_top_x]; |
314 | right_needle_top_y = y_values[right_needle_top_x-56]; | ||
366 | 315 | ||
367 | if (use_log_scale) | 316 | /* Needles */ |
368 | { | 317 | rb->lcd_drawline(28, 63, left_needle_top_x, left_needle_top_y); |
369 | left_needle_top_x = db_scale[left_needle_top_x_no_log]; | 318 | rb->lcd_drawline(84, 63, right_needle_top_x, right_needle_top_y); |
370 | right_needle_top_x = db_scale[right_needle_top_x_no_log]; | ||
371 | } | ||
372 | 319 | ||
373 | else | 320 | if(settings.analog_minimeters) |
374 | { | 321 | draw_analog_minimeters(); |
375 | left_needle_top_x = left_needle_top_x_no_log; | ||
376 | right_needle_top_x = right_needle_top_x_no_log; | ||
377 | } | ||
378 | 322 | ||
379 | /* Makes a decay on the needle (Custom Decay is at F2) */ | 323 | /* Needle covers */ |
380 | left_needle_top_x = (left_needle_top_x+old_left_needle_top_x*decay)/(decay+1); | 324 | rb->lcd_bitmap(needle_cover, 22, 59, 13, 5, false); |
381 | right_needle_top_x = (right_needle_top_x+old_right_needle_top_x*decay)/(decay+1); | 325 | rb->lcd_bitmap(needle_cover, 78, 59, 13, 5, false); |
382 | 326 | ||
383 | old_left_needle_top_x = left_needle_top_x; | 327 | /* Show Left/Right */ |
384 | old_right_needle_top_x = right_needle_top_x; | 328 | rb->lcd_putsxy(16, 12, "Left"); |
329 | rb->lcd_putsxy(70, 12, "Right"); | ||
385 | 330 | ||
386 | left_needle_top_y = y_values[left_needle_top_x]; | 331 | /* Line above/below the Left/Right text */ |
387 | right_needle_top_y = y_values[right_needle_top_x]; | 332 | rb->lcd_drawline(0,9,111,9); |
333 | rb->lcd_drawline(0,21,111,21); | ||
388 | 334 | ||
389 | /* Draws the needles */ | 335 | for(i=0; i<56; i++) { |
390 | rb->lcd_drawline(LEFT_NEEDLE_BOTTOM_X, NEEDLE_BOTTOM_Y, | 336 | rb->lcd_drawpixel(i, (y_values[i])-2); |
391 | left_needle_top_x, left_needle_top_y); | 337 | rb->lcd_drawpixel(i+56, (y_values[i])-2); |
338 | } | ||
339 | } | ||
392 | 340 | ||
393 | rb->lcd_drawline(RIGHT_NEEDLE_BOTTOM_X, NEEDLE_BOTTOM_Y, | 341 | void digital_meter(void) { |
394 | right_needle_top_x, right_needle_top_y); | 342 | if(settings.digital_use_db_scale) { |
343 | num_left_leds = digital_db_scale[rb->mas_codec_readreg(0xC) * 44 / MAX_PEAK]; | ||
344 | num_right_leds = digital_db_scale[rb->mas_codec_readreg(0xD) * 44 / MAX_PEAK]; | ||
345 | } | ||
346 | else { | ||
347 | num_left_leds = rb->mas_codec_readreg(0xC) * 11 / MAX_PEAK; | ||
348 | num_right_leds = rb->mas_codec_readreg(0xD) * 11 / MAX_PEAK; | ||
349 | } | ||
395 | 350 | ||
396 | /* We've got four needle cover modes... */ | 351 | num_left_leds = (num_left_leds+last_num_left_leds*settings.digital_decay)/(settings.digital_decay+1); |
397 | if(needle_cover_mode == 1) /* Rounded needle cover. */ | 352 | num_right_leds = (num_right_leds+last_num_right_leds*settings.digital_decay)/(settings.digital_decay+1); |
398 | { | 353 | |
399 | /* Left needle cover, top to bottom */ | 354 | last_num_left_leds = num_left_leds; |
400 | rb->lcd_drawline(27, 49, 29, 49); | 355 | last_num_right_leds = num_right_leds; |
401 | rb->lcd_drawline(25, 50, 31, 50); | ||
402 | rb->lcd_drawline(23, 51, 33, 51); | ||
403 | rb->lcd_drawline(22, 52, 34, 52); | ||
404 | rb->lcd_drawline(22, 53, 34, 53); | ||
405 | |||
406 | /* Right needle cover, top to bottom */ | ||
407 | rb->lcd_drawline(83, 49, 85, 49); | ||
408 | rb->lcd_drawline(81, 50, 87, 50); | ||
409 | rb->lcd_drawline(79, 51, 89, 51); | ||
410 | rb->lcd_drawline(78, 52, 90, 52); | ||
411 | rb->lcd_drawline(78, 53, 90, 53); | ||
412 | } | ||
413 | 356 | ||
414 | else /* Pyramid needle cover. */ | 357 | /* LEDS */ |
415 | { | 358 | for(i=0; i<num_left_leds; i++) |
416 | /* Left needle cover, top to bottom */ | 359 | rb->lcd_bitmap(led, i*9+2+i, 14, 9, 5, false); |
417 | rb->lcd_drawpixel(28, 49); | ||
418 | rb->lcd_drawline(27, 50, 29, 50); | ||
419 | rb->lcd_drawline(26, 51, 30, 51); | ||
420 | rb->lcd_drawline(25, 52, 31, 52); | ||
421 | rb->lcd_drawline(24, 53, 32, 53); | ||
422 | |||
423 | /* Right needle cover, top to bottom */ | ||
424 | rb->lcd_drawpixel(84, 49); | ||
425 | rb->lcd_drawline(83, 50, 85, 50); | ||
426 | rb->lcd_drawline(82, 51, 86, 51); | ||
427 | rb->lcd_drawline(81, 52, 87, 52); | ||
428 | rb->lcd_drawline(80, 53, 88, 53); | ||
429 | } | ||
430 | 360 | ||
431 | if(arch == 1) /* Solid */ | 361 | for(i=0; i<num_right_leds; i++) |
432 | { | 362 | rb->lcd_bitmap(led, i*9+2+i, 52, 9, 5, false); |
433 | int i; | ||
434 | for(i=0; i<=112; i++) | ||
435 | rb->lcd_drawpixel(i, (y_values[i])-2 ); | ||
436 | } | ||
437 | else if(arch == 2) /* Dotted */ | ||
438 | { | ||
439 | int i; | ||
440 | for(i=0; i<=112; i+=2) | ||
441 | rb->lcd_drawpixel(i, y_values[i]); | ||
442 | } | ||
443 | 363 | ||
444 | if(use_minimeters) | 364 | if(settings.digital_minimeters) |
445 | { | 365 | draw_digital_minimeters(); |
446 | draw_left_minimeters(); | 366 | |
447 | draw_right_minimeters(); | 367 | /* Lines above/below where the LEDS are */ |
448 | } | 368 | rb->lcd_drawline(0,12,111,12); |
369 | rb->lcd_drawline(0,20,111,20); | ||
370 | |||
371 | rb->lcd_drawline(0,50,111,50); | ||
372 | rb->lcd_drawline(0,58,111,58); | ||
373 | |||
374 | /* Show Left/Right */ | ||
375 | rb->lcd_putsxy(2, 24, "Left"); | ||
376 | rb->lcd_putsxy(2, 40, "Right"); | ||
377 | |||
378 | /* Line in the middle */ | ||
379 | rb->lcd_drawline(0,35,111,35); | ||
380 | } | ||
381 | |||
382 | enum plugin_status plugin_start(struct plugin_api* api, void* parameter) { | ||
383 | TEST_PLUGIN_API(api); | ||
384 | (void) parameter; | ||
385 | rb = api; | ||
449 | 386 | ||
450 | draw_status_bar(); | 387 | load_settings(); |
388 | rb->lcd_setfont(FONT_SYSFIXED); | ||
389 | |||
390 | while (1) | ||
391 | { | ||
392 | rb->lcd_clear_display(); | ||
451 | 393 | ||
394 | rb->lcd_putsxy(33, 0, "VU Meter"); | ||
395 | |||
396 | if(settings.meter_type==ANALOG) | ||
397 | analog_meter(); | ||
398 | else | ||
399 | digital_meter(); | ||
400 | |||
452 | rb->lcd_update(); | 401 | rb->lcd_update(); |
453 | 402 | ||
454 | /* Using a faster timeout like "1" makes the | 403 | switch (rb->button_get_w_tmo(1)) |
455 | * minimeters flicker, HZ/35 looks good. */ | ||
456 | switch (rb->button_get_w_tmo(HZ/35)) | ||
457 | { | 404 | { |
458 | /* EXIT */ | ||
459 | case BUTTON_OFF: | 405 | case BUTTON_OFF: |
406 | save_settings(); | ||
460 | return PLUGIN_OK; | 407 | return PLUGIN_OK; |
461 | break; | 408 | break; |
462 | 409 | ||
463 | /* INFO */ | ||
464 | case BUTTON_ON: | 410 | case BUTTON_ON: |
465 | rb->lcd_clear_display(); | 411 | rb->lcd_clear_display(); |
466 | while(!quit) | 412 | rb->lcd_puts(0, 0, "OFF: Exit"); |
467 | { | 413 | rb->lcd_puts(0, 1, "F1: Settings"); |
468 | rb->lcd_puts(0, 0, "OFF: Exit Plugin"); | 414 | rb->lcd_puts(0, 2, "UP/DOWN: Volume"); |
469 | rb->lcd_puts(0, 1, "PLAY: Change Scale"); | 415 | rb->lcd_update(); |
470 | rb->lcd_puts(0, 2, "F1: Settings"); | 416 | rb->sleep(HZ*3); |
471 | rb->lcd_puts(0, 3, "F2: Custom Decay"); | ||
472 | rb->lcd_puts(0, 4, "F3: Mini-Meters"); | ||
473 | rb->lcd_puts(0, 5, "UP/DOWN: Volume"); | ||
474 | rb->lcd_puts(0, 7, "ON to exit..."); | ||
475 | |||
476 | rb->lcd_update(); | ||
477 | |||
478 | switch(rb->button_get_w_tmo(HZ/4)) | ||
479 | { | ||
480 | case BUTTON_ON: | ||
481 | quit = true; | ||
482 | break; | ||
483 | } | ||
484 | } | ||
485 | break; | 417 | break; |
486 | 418 | ||
487 | /* SCALE switch */ | ||
488 | case BUTTON_PLAY: | ||
489 | use_log_scale = !use_log_scale; | ||
490 | break; | ||
491 | |||
492 | /* GENERAL SETTINGS screen */ | ||
493 | case BUTTON_F1: | 419 | case BUTTON_F1: |
494 | general_settings(); | 420 | change_settings(); |
495 | break; | ||
496 | |||
497 | /* DECAY SETTINGS screen */ | ||
498 | case BUTTON_F2: | ||
499 | user_decay_settings(); | ||
500 | break; | ||
501 | |||
502 | /* MINIMETER SETTINGS screen */ | ||
503 | case BUTTON_F3: | ||
504 | use_minimeters = !use_minimeters; | ||
505 | break; | 421 | break; |
506 | 422 | ||
507 | /* VOLUME UP */ | ||
508 | case BUTTON_UP: | 423 | case BUTTON_UP: |
509 | case BUTTON_UP | BUTTON_REPEAT: | 424 | case BUTTON_UP | BUTTON_REPEAT: |
510 | ChangeVolume(1); | 425 | change_volume(1); |
511 | break; | 426 | break; |
512 | 427 | ||
513 | /* VOLUME DOWN */ | ||
514 | case BUTTON_DOWN: | 428 | case BUTTON_DOWN: |
515 | case BUTTON_DOWN | BUTTON_REPEAT: | 429 | case BUTTON_DOWN | BUTTON_REPEAT: |
516 | ChangeVolume(-1); | 430 | change_volume(-1); |
517 | break; | 431 | break; |
518 | 432 | ||
519 | /* USB CONNECTED */ | ||
520 | case SYS_USB_CONNECTED: | 433 | case SYS_USB_CONNECTED: |
521 | rb->usb_screen(); | 434 | rb->usb_screen(); |
522 | return PLUGIN_USB_CONNECTED; | 435 | return PLUGIN_USB_CONNECTED; |