A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita
audio
rust
zig
deno
mpris
rockbox
mpd
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2009 by Jens Arnold
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20//#define TEST_GREYLIB /* Uncomment for testing greylib instead of core gfx */
21
22#include "plugin.h"
23#ifdef TEST_GREYLIB /* otherwise, mylcd defaults to core gfx */
24#include "lib/grey.h"
25#endif
26#include "lib/helper.h"
27#include "lib/mylcd.h"
28
29#ifdef TEST_GREYLIB
30GREY_INFO_STRUCT
31static unsigned char *gbuf;
32static size_t gbuf_size = 0;
33#endif
34
35#define DURATION (HZ) /* longer duration gives more precise results */
36#define RND_SEED 0x43A678C3 /* arbirary */
37
38
39
40static uint16_t rand_table[0x400];
41static int log_fd;
42
43
44static int log_init(void)
45{
46 char logfilename[MAX_PATH];
47 int fd;
48
49 rb->create_numbered_filename(logfilename, HOME_DIR, "test_gfx_log_", ".txt",
50 2 IF_CNFN_NUM_(, NULL));
51 fd = rb->open(logfilename, O_RDWR|O_CREAT|O_TRUNC, 0666);
52 return fd;
53}
54
55static void init_rand_table(void)
56{
57 int i;
58
59 rb->srand(RND_SEED); /* make it reproducable */
60 for (i = 0; i < 0x400; i++)
61 rand_table[i] = rb->rand();
62}
63
64static void time_drawpixel(void)
65{
66 long time_start; /* start tickcount */
67 long time_end; /* end tickcount */
68 int count1, count2, count3, count4;
69
70 /* Test 1: DRMODE_SOLID */
71 mylcd_set_drawmode(DRMODE_SOLID);
72 count1 = 0;
73 rb->sleep(0); /* sync to tick */
74 time_start = *rb->current_tick;
75 while((time_end = *rb->current_tick) - time_start < DURATION)
76 {
77 unsigned rnd = rand_table[count1++ & 0x3ff];
78 mylcd_drawpixel((rnd >> 8) & 0x3f, rnd & 0x3f);
79 }
80
81 /* Test 2: DRMODE_FG */
82 mylcd_set_drawmode(DRMODE_FG);
83 count2 = 0;
84 rb->sleep(0); /* sync to tick */
85 time_start = *rb->current_tick;
86 while((time_end = *rb->current_tick) - time_start < DURATION)
87 {
88 unsigned rnd = rand_table[count2++ & 0x3ff];
89 mylcd_drawpixel((rnd >> 8) & 0x3f, rnd & 0x3f);
90 }
91 /* Test 3: DRMODE_BG */
92 mylcd_set_drawmode(DRMODE_BG);
93 count3 = 0;
94 rb->sleep(0); /* sync to tick */
95 time_start = *rb->current_tick;
96 while((time_end = *rb->current_tick) - time_start < DURATION)
97 {
98 unsigned rnd = rand_table[count3++ & 0x3ff];
99 mylcd_drawpixel((rnd >> 8) & 0x3f, rnd & 0x3f);
100 }
101 /* Test 4: DRMODE_COMPLEMENT */
102 mylcd_set_drawmode(DRMODE_COMPLEMENT);
103 count4 = 0;
104 rb->sleep(0); /* sync to tick */
105 time_start = *rb->current_tick;
106 while((time_end = *rb->current_tick) - time_start < DURATION)
107 {
108 unsigned rnd = rand_table[count4++ & 0x3ff];
109 mylcd_drawpixel((rnd >> 8) & 0x3f, rnd & 0x3f);
110 }
111
112 rb->fdprintf(log_fd, "lcd_drawpixel (pixels/s): %d/%d/%d/%d\n",
113 count1, count2, count3, count4);
114}
115
116static void time_drawline(void)
117{
118 long time_start; /* start tickcount */
119 long time_end; /* end tickcount */
120 int count1, count2, count3, count4;
121
122 /* Test 1: DRMODE_SOLID */
123 mylcd_set_drawmode(DRMODE_SOLID);
124 count1 = 0;
125 rb->sleep(0); /* sync to tick */
126 time_start = *rb->current_tick;
127 while((time_end = *rb->current_tick) - time_start < DURATION)
128 {
129 unsigned rnd1 = rand_table[count1++ & 0x3ff];
130 unsigned rnd2 = rand_table[count1++ & 0x3ff];
131 mylcd_drawline((rnd1 >> 8) & 0x3f, rnd1 & 0x3f,
132 (rnd2 >> 8) & 0x3f, rnd2 & 0x3f);
133 }
134
135 /* Test 2: DRMODE_FG */
136 mylcd_set_drawmode(DRMODE_FG);
137 count2 = 0;
138 rb->sleep(0); /* sync to tick */
139 time_start = *rb->current_tick;
140 while((time_end = *rb->current_tick) - time_start < DURATION)
141 {
142 unsigned rnd1 = rand_table[count2++ & 0x3ff];
143 unsigned rnd2 = rand_table[count2++ & 0x3ff];
144 mylcd_drawline((rnd1 >> 8) & 0x3f, rnd1 & 0x3f,
145 (rnd2 >> 8) & 0x3f, rnd2 & 0x3f);
146 }
147 /* Test 3: DRMODE_BG */
148 mylcd_set_drawmode(DRMODE_BG);
149 count3 = 0;
150 rb->sleep(0); /* sync to tick */
151 time_start = *rb->current_tick;
152 while((time_end = *rb->current_tick) - time_start < DURATION)
153 {
154 unsigned rnd1 = rand_table[count3++ & 0x3ff];
155 unsigned rnd2 = rand_table[count3++ & 0x3ff];
156 mylcd_drawline((rnd1 >> 8) & 0x3f, rnd1 & 0x3f,
157 (rnd2 >> 8) & 0x3f, rnd2 & 0x3f);
158 }
159 /* Test 4: DRMODE_COMPLEMENT */
160 mylcd_set_drawmode(DRMODE_COMPLEMENT);
161 count4 = 0;
162 rb->sleep(0); /* sync to tick */
163 time_start = *rb->current_tick;
164 while((time_end = *rb->current_tick) - time_start < DURATION)
165 {
166 unsigned rnd1 = rand_table[count4++ & 0x3ff];
167 unsigned rnd2 = rand_table[count4++ & 0x3ff];
168 mylcd_drawline((rnd1 >> 8) & 0x3f, rnd1 & 0x3f,
169 (rnd2 >> 8) & 0x3f, rnd2 & 0x3f);
170 }
171
172 rb->fdprintf(log_fd, "lcd_drawline (lines/s): %d/%d/%d/%d\n",
173 count1, count2, count3, count4);
174}
175
176static void time_hline(void)
177{
178 long time_start; /* start tickcount */
179 long time_end; /* end tickcount */
180 int count1, count2, count3, count4;
181
182 /* Test 1: DRMODE_SOLID */
183 mylcd_set_drawmode(DRMODE_SOLID);
184 count1 = 0;
185 rb->sleep(0); /* sync to tick */
186 time_start = *rb->current_tick;
187 while((time_end = *rb->current_tick) - time_start < DURATION)
188 {
189 unsigned rnd1 = rand_table[count1++ & 0x3ff];
190 unsigned rnd2 = rand_table[count1++ & 0x3ff];
191 mylcd_hline((rnd1 >> 8) & 0x3f, rnd1 & 0x3f, rnd2 & 0x3f);
192 }
193
194 /* Test 2: DRMODE_FG */
195 mylcd_set_drawmode(DRMODE_FG);
196 count2 = 0;
197 rb->sleep(0); /* sync to tick */
198 time_start = *rb->current_tick;
199 while((time_end = *rb->current_tick) - time_start < DURATION)
200 {
201 unsigned rnd1 = rand_table[count2++ & 0x3ff];
202 unsigned rnd2 = rand_table[count2++ & 0x3ff];
203 mylcd_hline((rnd1 >> 8) & 0x3f, rnd1 & 0x3f, rnd2 & 0x3f);
204 }
205 /* Test 3: DRMODE_BG */
206 mylcd_set_drawmode(DRMODE_BG);
207 count3 = 0;
208 rb->sleep(0); /* sync to tick */
209 time_start = *rb->current_tick;
210 while((time_end = *rb->current_tick) - time_start < DURATION)
211 {
212 unsigned rnd1 = rand_table[count3++ & 0x3ff];
213 unsigned rnd2 = rand_table[count3++ & 0x3ff];
214 mylcd_hline((rnd1 >> 8) & 0x3f, rnd1 & 0x3f, rnd2 & 0x3f);
215 }
216 /* Test 4: DRMODE_COMPLEMENT */
217 mylcd_set_drawmode(DRMODE_COMPLEMENT);
218 count4 = 0;
219 rb->sleep(0); /* sync to tick */
220 time_start = *rb->current_tick;
221 while((time_end = *rb->current_tick) - time_start < DURATION)
222 {
223 unsigned rnd1 = rand_table[count4++ & 0x3ff];
224 unsigned rnd2 = rand_table[count4++ & 0x3ff];
225 mylcd_hline((rnd1 >> 8) & 0x3f, rnd1 & 0x3f, rnd2 & 0x3f);
226 }
227
228 rb->fdprintf(log_fd, "lcd_hline (lines/s): %d/%d/%d/%d\n",
229 count1, count2, count3, count4);
230}
231
232static void time_vline(void)
233{
234 long time_start; /* start tickcount */
235 long time_end; /* end tickcount */
236 int count1, count2, count3, count4;
237
238 /* Test 1: DRMODE_SOLID */
239 mylcd_set_drawmode(DRMODE_SOLID);
240 count1 = 0;
241 rb->sleep(0); /* sync to tick */
242 time_start = *rb->current_tick;
243 while((time_end = *rb->current_tick) - time_start < DURATION)
244 {
245 unsigned rnd1 = rand_table[count1++ & 0x3ff];
246 unsigned rnd2 = rand_table[count1++ & 0x3ff];
247 mylcd_vline((rnd1 >> 8) & 0x3f, rnd1 & 0x3f, rnd2 & 0x3f);
248 }
249
250 /* Test 2: DRMODE_FG */
251 mylcd_set_drawmode(DRMODE_FG);
252 count2 = 0;
253 rb->sleep(0); /* sync to tick */
254 time_start = *rb->current_tick;
255 while((time_end = *rb->current_tick) - time_start < DURATION)
256 {
257 unsigned rnd1 = rand_table[count2++ & 0x3ff];
258 unsigned rnd2 = rand_table[count2++ & 0x3ff];
259 mylcd_vline((rnd1 >> 8) & 0x3f, rnd1 & 0x3f, rnd2 & 0x3f);
260 }
261 /* Test 3: DRMODE_BG */
262 mylcd_set_drawmode(DRMODE_BG);
263 count3 = 0;
264 rb->sleep(0); /* sync to tick */
265 time_start = *rb->current_tick;
266 while((time_end = *rb->current_tick) - time_start < DURATION)
267 {
268 unsigned rnd1 = rand_table[count3++ & 0x3ff];
269 unsigned rnd2 = rand_table[count3++ & 0x3ff];
270 mylcd_vline((rnd1 >> 8) & 0x3f, rnd1 & 0x3f, rnd2 & 0x3f);
271 }
272 /* Test 4: DRMODE_COMPLEMENT */
273 mylcd_set_drawmode(DRMODE_COMPLEMENT);
274 count4 = 0;
275 rb->sleep(0); /* sync to tick */
276 time_start = *rb->current_tick;
277 while((time_end = *rb->current_tick) - time_start < DURATION)
278 {
279 unsigned rnd1 = rand_table[count4++ & 0x3ff];
280 unsigned rnd2 = rand_table[count4++ & 0x3ff];
281 mylcd_vline((rnd1 >> 8) & 0x3f, rnd1 & 0x3f, rnd2 & 0x3f);
282 }
283
284 rb->fdprintf(log_fd, "lcd_vline (lines/s): %d/%d/%d/%d\n",
285 count1, count2, count3, count4);
286}
287
288static void time_fillrect(void)
289{
290 long time_start; /* start tickcount */
291 long time_end; /* end tickcount */
292 int count1, count2, count3, count4;
293
294 /* Test 1: DRMODE_SOLID */
295 mylcd_set_drawmode(DRMODE_SOLID);
296 count1 = 0;
297 rb->sleep(0); /* sync to tick */
298 time_start = *rb->current_tick;
299 while((time_end = *rb->current_tick) - time_start < DURATION)
300 {
301 unsigned rnd1 = rand_table[count1++ & 0x3ff];
302 unsigned rnd2 = rand_table[count1++ & 0x3ff];
303 mylcd_fillrect((rnd1 >> 8) & 0x3f, rnd1 & 0x3f,
304 (rnd2 >> 8) & 0x3f, rnd2 & 0x3f);
305 }
306
307 /* Test 2: DRMODE_FG */
308 mylcd_set_drawmode(DRMODE_FG);
309 count2 = 0;
310 rb->sleep(0); /* sync to tick */
311 time_start = *rb->current_tick;
312 while((time_end = *rb->current_tick) - time_start < DURATION)
313 {
314 unsigned rnd1 = rand_table[count2++ & 0x3ff];
315 unsigned rnd2 = rand_table[count2++ & 0x3ff];
316 mylcd_fillrect((rnd1 >> 8) & 0x3f, rnd1 & 0x3f,
317 (rnd2 >> 8) & 0x3f, rnd2 & 0x3f);
318 }
319 /* Test 3: DRMODE_BG */
320 mylcd_set_drawmode(DRMODE_BG);
321 count3 = 0;
322 rb->sleep(0); /* sync to tick */
323 time_start = *rb->current_tick;
324 while((time_end = *rb->current_tick) - time_start < DURATION)
325 {
326 unsigned rnd1 = rand_table[count3++ & 0x3ff];
327 unsigned rnd2 = rand_table[count3++ & 0x3ff];
328 mylcd_fillrect((rnd1 >> 8) & 0x3f, rnd1 & 0x3f,
329 (rnd2 >> 8) & 0x3f, rnd2 & 0x3f);
330 }
331 /* Test 4: DRMODE_COMPLEMENT */
332 mylcd_set_drawmode(DRMODE_COMPLEMENT);
333 count4 = 0;
334 rb->sleep(0); /* sync to tick */
335 time_start = *rb->current_tick;
336 while((time_end = *rb->current_tick) - time_start < DURATION)
337 {
338 unsigned rnd1 = rand_table[count4++ & 0x3ff];
339 unsigned rnd2 = rand_table[count4++ & 0x3ff];
340 mylcd_fillrect((rnd1 >> 8) & 0x3f, rnd1 & 0x3f,
341 (rnd2 >> 8) & 0x3f, rnd2 & 0x3f);
342 }
343
344 rb->fdprintf(log_fd, "lcd_fillrect (rects/s): %d/%d/%d/%d\n",
345 count1, count2, count3, count4);
346}
347
348static void time_text(void) /* tests mono_bitmap performance */
349{
350 long time_start; /* start tickcount */
351 long time_end; /* end tickcount */
352 int count1, count2, count3, count4;
353
354 rb->lcd_setfont(FONT_SYSFIXED);
355
356 /* Test 1: DRMODE_SOLID */
357 mylcd_set_drawmode(DRMODE_SOLID);
358 count1 = 0;
359 rb->sleep(0); /* sync to tick */
360 time_start = *rb->current_tick;
361 while((time_end = *rb->current_tick) - time_start < DURATION)
362 {
363 unsigned rnd = rand_table[count1++ & 0x3ff];
364 mylcd_putsxy((rnd >> 8) & 0x3f, rnd & 0x3f, "Rockbox!");
365 }
366
367 /* Test 2: DRMODE_FG */
368 mylcd_set_drawmode(DRMODE_FG);
369 count2 = 0;
370 rb->sleep(0); /* sync to tick */
371 time_start = *rb->current_tick;
372 while((time_end = *rb->current_tick) - time_start < DURATION)
373 {
374 unsigned rnd = rand_table[count2++ & 0x3ff];
375 mylcd_putsxy((rnd >> 8) & 0x3f, rnd & 0x3f, "Rockbox!");
376 }
377 /* Test 3: DRMODE_BG */
378 mylcd_set_drawmode(DRMODE_BG);
379 count3 = 0;
380 rb->sleep(0); /* sync to tick */
381 time_start = *rb->current_tick;
382 while((time_end = *rb->current_tick) - time_start < DURATION)
383 {
384 unsigned rnd = rand_table[count3++ & 0x3ff];
385 mylcd_putsxy((rnd >> 8) & 0x3f, rnd & 0x3f, "Rockbox!");
386 }
387 /* Test 4: DRMODE_COMPLEMENT */
388 mylcd_set_drawmode(DRMODE_COMPLEMENT);
389 count4 = 0;
390 rb->sleep(0); /* sync to tick */
391 time_start = *rb->current_tick;
392 while((time_end = *rb->current_tick) - time_start < DURATION)
393 {
394 unsigned rnd = rand_table[count4++ & 0x3ff];
395 mylcd_putsxy((rnd >> 8) & 0x3f, rnd & 0x3f, "Rockbox!");
396 }
397
398 rb->fdprintf(log_fd, "lcd_putsxy (strings/s): %d/%d/%d/%d\n",
399 count1, count2, count3, count4);
400}
401
402static void time_put_line(void) /* tests put_line performance */
403{
404 long time_start, time_end;
405 int count1, count2, count3, count4;
406 struct screen *display = rb->screens[SCREEN_MAIN];
407 const char fmt[] = "$iRockbox!";
408
409 rb->lcd_setfont(FONT_SYSFIXED);
410 count1 = count2 = count3 = count4 = 0;
411
412 struct line_desc desc = LINE_DESC_DEFINIT;
413 rb->sleep(0); /* sync to tick */
414 time_start = *rb->current_tick;
415 while((time_end = *rb->current_tick) - time_start < DURATION)
416 {
417 unsigned rnd = rand_table[count1++ & 0x3ff];
418 display->put_line((rnd >> 8) & 0x3f, rnd & 0x3f, &desc, fmt, Icon_Audio);
419 }
420
421 desc.style = STYLE_INVERT;
422 rb->sleep(0); /* sync to tick */
423 time_start = *rb->current_tick;
424 while((time_end = *rb->current_tick) - time_start < DURATION)
425 {
426 unsigned rnd = rand_table[count2++ & 0x3ff];
427 display->put_line((rnd >> 8) & 0x3f, rnd & 0x3f, &desc, fmt, Icon_Audio);
428 }
429
430 desc.style = STYLE_COLORBAR;
431 rb->sleep(0); /* sync to tick */
432 time_start = *rb->current_tick;
433 while((time_end = *rb->current_tick) - time_start < DURATION)
434 {
435 unsigned rnd = rand_table[count3++ & 0x3ff];
436 display->put_line((rnd >> 8) & 0x3f, rnd & 0x3f, &desc, fmt, Icon_Audio);
437 }
438
439 desc.style = STYLE_GRADIENT;
440 rb->sleep(0); /* sync to tick */
441 time_start = *rb->current_tick;
442 while((time_end = *rb->current_tick) - time_start < DURATION)
443 {
444 unsigned rnd = rand_table[count4++ & 0x3ff];
445 display->put_line((rnd >> 8) & 0x3f, rnd & 0x3f, &desc, fmt, Icon_Audio);
446 }
447
448 rb->fdprintf(log_fd, "\nput_line (lines (icon+text)/s): \n"
449 " default: %d\n"
450 " inverted: %d\n"
451 " colorbar: %d\n"
452 " gradient: %d\n",
453 count1, count2, count3, count4);
454}
455
456/* plugin entry point */
457enum plugin_status plugin_start(const void* parameter)
458{
459#ifdef HAVE_ADJUSTABLE_CPU_FREQ
460 int cpu_freq;
461#endif
462
463 /* standard stuff */
464 (void)parameter;
465
466 log_fd = log_init();
467 if (log_fd < 0)
468 {
469 rb->splash(HZ, "Could not create logfile");
470 return PLUGIN_ERROR;
471 }
472 rb->fdprintf(log_fd, "%s",
473#ifdef TEST_GREYLIB
474 "Greylib performance test.\n"
475#else
476 "LCD driver performance test.\n"
477#endif
478 "----------------------------\n\n"
479 "Results are printed in the following drawmode order:\n"
480 "solid/foreground/background/complement\n\n");
481
482#ifdef TEST_GREYLIB
483 /* get the remainder of the plugin buffer */
484 gbuf = (unsigned char *) rb->plugin_get_buffer(&gbuf_size);
485
486 /* initialize the greyscale buffer.*/
487 if (!grey_init(gbuf, gbuf_size, GREY_BUFFERED|GREY_ON_COP,
488 LCD_WIDTH, LCD_HEIGHT, NULL))
489 {
490 rb->close(log_fd);
491 rb->splash(HZ, "Couldn't init greyscale library");
492 return PLUGIN_ERROR;
493 }
494#elif LCD_DEPTH > 1
495 rb->lcd_set_backdrop(NULL);
496 rb->lcd_clear_display();
497#endif
498
499 backlight_ignore_timeout();
500
501 rb->splashf(0, "LCD driver performance test, please wait %d sec",
502 7*4*DURATION/HZ);
503 init_rand_table();
504
505#ifdef HAVE_ADJUSTABLE_CPU_FREQ
506 cpu_freq = *rb->cpu_frequency; /* remember CPU frequency */
507#endif
508
509 time_drawpixel();
510 time_drawline();
511 time_hline();
512 time_vline();
513 time_fillrect();
514 time_text();
515 time_put_line();
516
517#ifdef HAVE_ADJUSTABLE_CPU_FREQ
518 if (*rb->cpu_frequency != cpu_freq)
519 rb->fdprintf(log_fd, "\nCPU: %s\n", "clock changed!");
520 else
521 rb->fdprintf(log_fd, "\nCPU: %d MHz\n",
522 (cpu_freq + 500000) / 1000000);
523#endif
524 rb->close(log_fd);
525
526 backlight_use_settings();
527
528#ifdef TEST_GREYLIB
529 grey_release();
530#endif
531
532 return PLUGIN_OK;
533}