summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/plugins/vu_meter.c729
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
30static struct plugin_api* rb; 22const 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. */
36static 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. */
44static 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. */
54unsigned 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. */
59unsigned 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. */
64static unsigned char sound_speaker[] = {0x18,0x24,0x42,0xFF}; 25const 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,
2746,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] */ 29const unsigned char digital_db_scale[] =
67static 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,
3110,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. */
70static unsigned char sound_med_level[] = {0x42,0x3C}; 34const 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,
3625,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] */ 38const unsigned char led[] = {0x0e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x0e};
73static unsigned char sound_high_level[] = {0x81,0x7E};
74 39
75/* Channel indicator - maxed out [3x8] */ 40const unsigned char needle_cover[] =
76static 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] */ 43const unsigned char sound_speaker[] = {0x18,0x24,0x42,0xFF};
79static unsigned char volume_indicator[] = {0x1C,0x1C,0x22,0x7F}; 44const unsigned char sound_low_level[] = {0x24,0x18};
45const unsigned char sound_med_level[] = {0x42,0x3C};
46const unsigned char sound_high_level[] = {0x81,0x7E};
47const 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 */
82static 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] */
85static 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
97int left_needle_top_y; 52int left_needle_top_y;
98int left_needle_top_x; 53int left_needle_top_x;
99int old_left_needle_top_x = 0; 54int last_left_needle_top_x;
100int left_needle_top_x_no_log;
101
102/*******************************
103 * RIGHT NEEDLE ints
104 *******************************/
105#define RIGHT_NEEDLE_BOTTOM_X 84
106int right_needle_top_y; 55int right_needle_top_y;
107int right_needle_top_x; 56int right_needle_top_x;
108int old_right_needle_top_x = 56; 57int last_right_needle_top_x = 56;
109int right_needle_top_x_no_log;
110
111/*********************
112 * LEFT MINIMETER ints
113 *********************/
114int mini_left_low;
115int mini_left_med;
116int mini_left_high;
117int mini_left_clip;
118
119/**********************
120 * RIGHT MINIMETER ints
121 **********************/
122int mini_right_low;
123int mini_right_med;
124int mini_right_high;
125int mini_right_clip;
126
127/************************
128 * GENERAL ints
129 ************************/
130char curr_vol[3]; /* CURRENT VOLUME */
131int vol; /* CURENNT VOLUME int */
132int on = 1; /* MINIMETER OPTIONS int */
133int needle_cover_mode = 1; /* NEEDLE COVER int (defaults to "rounded") */
134int arch = 1; /* ARCH int (defaults to "solid") */
135int decay = 3; /* DECAY int (defaults to "medium") */
136
137/*************************
138 * GENERAL bools
139 *************************/
140bool quit = false;
141bool use_log_scale = true;
142bool use_minimeters = true;
143
144/********************************************
145 * Change the volume - derived from VIDEO.C
146 ********************************************/
147void ChangeVolume(int delta)
148{
149 vol = rb->global_settings->volume + delta;
150 58
151 if (vol > 100) vol = 100; 59int num_left_leds;
152 else if (vol < 0) vol = 0; 60int num_right_leds;
153 if (vol != rb->global_settings->volume) 61int last_num_left_leds;
154 { 62int 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/***************************************************** 64int i;
162 * Draw the status bar
163 *****************************************************/
164void 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); 68struct 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
78void 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/****************************** 88void 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
190void draw_left_minimeters(void) 100void 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/******************************* 108void change_volume(int delta) {
205 * DRAW right MiniMeters 109 char curr_vol[4];
206 *******************************/ 110 int vol = rb->global_settings->volume + delta;
207void 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/*************************************** 124void change_settings(void)
222 * GENERAL SETTINGS - F1
223 ***************************************/
224void 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/***************************** 251void 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)
292void 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/*********************************************************************** 273void 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)
339enum 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 */ 295void 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, 341void 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
382enum 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;