1 /**
2  * @file lv_demo_music_main.c
3  *
4  */
5 
6 /*********************
7  *      INCLUDES
8  *********************/
9 #include "lv_demo_music_main.h"
10 #if LV_USE_DEMO_MUSIC
11 
12 #include "lv_demo_music_list.h"
13 #include "assets/spectrum_1.h"
14 #include "assets/spectrum_2.h"
15 #include "assets/spectrum_3.h"
16 #include "../../lvgl_private.h"
17 
18 /*********************
19  *      DEFINES
20  *********************/
21 #define ACTIVE_TRACK_CNT    3
22 #define INTRO_TIME          2000
23 #define BAR_COLOR1          lv_color_hex(0xe9dbfc)
24 #define BAR_COLOR2          lv_color_hex(0x6f8af6)
25 #define BAR_COLOR3          lv_color_hex(0xffffff)
26 #if LV_DEMO_MUSIC_LARGE
27     #define BAR_COLOR1_STOP     160
28     #define BAR_COLOR2_STOP     200
29     #define BAR_REST_RADIUS     165
30 #else
31     #define BAR_COLOR1_STOP     80
32     #define BAR_COLOR2_STOP     100
33     #define BAR_REST_RADIUS     82
34 #endif
35 #define BAR_COLOR3_STOP     (LV_MAX(LV_HOR_RES, LV_VER_RES) / 3)
36 #define BAR_CNT             20
37 #define DEG_STEP            (180/BAR_CNT)
38 #define BAND_CNT            4
39 #define BAR_PER_BAND_CNT    (BAR_CNT / BAND_CNT)
40 
41 /**********************
42  *      TYPEDEFS
43  **********************/
44 
45 /**********************
46  *  STATIC PROTOTYPES
47  **********************/
48 static lv_obj_t * create_cont(lv_obj_t * parent);
49 static void create_wave_images(lv_obj_t * parent);
50 static lv_obj_t * create_title_box(lv_obj_t * parent);
51 static lv_obj_t * create_icon_box(lv_obj_t * parent);
52 static lv_obj_t * create_spectrum_obj(lv_obj_t * parent);
53 static lv_obj_t * create_ctrl_box(lv_obj_t * parent);
54 static lv_obj_t * create_handle(lv_obj_t * parent);
55 
56 static void spectrum_anim_cb(void * a, int32_t v);
57 static void start_anim_cb(void * var, int32_t v);
58 static void del_counter_timer_cb(lv_event_t * e);
59 static void spectrum_draw_event_cb(lv_event_t * e);
60 static lv_obj_t * album_image_create(lv_obj_t * parent);
61 static void album_gesture_event_cb(lv_event_t * e);
62 static void play_event_click_cb(lv_event_t * e);
63 static void prev_click_event_cb(lv_event_t * e);
64 static void next_click_event_cb(lv_event_t * e);
65 static void timer_cb(lv_timer_t * t);
66 static void track_load(uint32_t id);
67 static void stop_start_anim(lv_timer_t * t);
68 static void spectrum_end_cb(lv_anim_t * a);
69 static void album_fade_anim_cb(void * var, int32_t v);
70 static int32_t get_cos(int32_t deg, int32_t a);
71 static int32_t get_sin(int32_t deg, int32_t a);
72 
73 /**********************
74  *  STATIC VARIABLES
75  **********************/
76 static lv_obj_t * main_cont;
77 static lv_obj_t * spectrum_obj;
78 static lv_obj_t * title_label;
79 static lv_obj_t * artist_label;
80 static lv_obj_t * genre_label;
81 static lv_obj_t * time_obj;
82 static lv_obj_t * album_image_obj;
83 static lv_obj_t * slider_obj;
84 static uint32_t spectrum_i = 0;
85 static uint32_t spectrum_i_pause = 0;
86 static uint32_t bar_ofs = 0;
87 static uint32_t bar_rot = 0;
88 static uint32_t time_act;
89 static lv_timer_t  * stop_start_anim_timer;
90 static lv_timer_t  * sec_counter_timer;
91 static const lv_font_t * font_small;
92 static const lv_font_t * font_large;
93 static uint32_t track_id;
94 static bool playing;
95 static bool start_anim;
96 static int32_t start_anim_values[40];
97 static lv_obj_t * play_obj;
98 static const uint16_t (* spectrum)[4];
99 static uint32_t spectrum_len;
100 static const uint16_t rnd_array[30] = {994, 285, 553, 11, 792, 707, 966, 641, 852, 827, 44, 352, 146, 581, 490, 80, 729, 58, 695, 940, 724, 561, 124, 653, 27, 292, 557, 506, 382, 199};
101 
102 /**********************
103  *      MACROS
104  **********************/
105 
106 /**********************
107  *   GLOBAL FUNCTIONS
108  **********************/
109 
110 /*
111  * Callback adapter function to convert parameter types to avoid compile-time
112  * warning.
113  */
_image_set_scale_anim_cb(void * obj,int32_t scale)114 static void _image_set_scale_anim_cb(void * obj, int32_t scale)
115 {
116     lv_image_set_scale((lv_obj_t *)obj, (uint16_t)scale);
117 }
118 
119 /*
120  * Callback adapter function to convert parameter types to avoid compile-time
121  * warning.
122  */
_obj_set_x_anim_cb(void * obj,int32_t x)123 static void _obj_set_x_anim_cb(void * obj, int32_t x)
124 {
125     lv_obj_set_x((lv_obj_t *)obj, (int32_t)x);
126 }
127 
lv_demo_music_main_create(lv_obj_t * parent)128 lv_obj_t * lv_demo_music_main_create(lv_obj_t * parent)
129 {
130     font_small = LV_FONT_DEFAULT;
131     font_large = LV_FONT_DEFAULT;
132 
133 #if LV_DEMO_MUSIC_LARGE
134 #if LV_FONT_MONTSERRAT_22
135     font_small = &lv_font_montserrat_22;
136 #else
137     LV_LOG_WARN("LV_FONT_MONTSERRAT_22 is not enabled for the music demo. Using LV_FONT_DEFAULT instead.");
138 #endif
139 #if LV_FONT_MONTSERRAT_32
140     font_large = &lv_font_montserrat_32;
141 #else
142     LV_LOG_WARN("LV_FONT_MONTSERRAT_32 is not enabled for the music demo. Using LV_FONT_DEFAULT instead.");
143 #endif
144 #else
145 #if LV_FONT_MONTSERRAT_12
146     font_small = &lv_font_montserrat_12;
147 #else
148     LV_LOG_WARN("LV_FONT_MONTSERRAT_12 is not enabled for the music demo. Using LV_FONT_DEFAULT instead.");
149 #endif
150 #if LV_FONT_MONTSERRAT_16
151     font_large = &lv_font_montserrat_16;
152 #else
153     LV_LOG_WARN("LV_FONT_MONTSERRAT_16 is not enabled for the music demo. Using LV_FONT_DEFAULT instead.");
154 #endif
155 #endif
156 
157     /*Create the content of the music player*/
158     lv_obj_t * cont = create_cont(parent);
159 
160     create_wave_images(cont);
161     lv_obj_t * title_box = create_title_box(cont);
162     lv_obj_t * icon_box = create_icon_box(cont);
163     lv_obj_t * ctrl_box = create_ctrl_box(cont);
164     spectrum_obj = create_spectrum_obj(cont);
165     lv_obj_t * handle_box = create_handle(cont);
166 
167 #if LV_DEMO_MUSIC_ROUND
168     lv_obj_set_style_pad_hor(cont, LV_HOR_RES / 6, 0);
169 #endif
170 
171     /*Arrange the content into a grid*/
172 #if LV_DEMO_MUSIC_SQUARE || LV_DEMO_MUSIC_ROUND
173     static const int32_t grid_cols[] = {LV_GRID_FR(1), LV_GRID_TEMPLATE_LAST};
174     static int32_t grid_rows[] = {LV_DEMO_MUSIC_HANDLE_SIZE,     /*Spacing*/
175                                   0,   /*Spectrum obj, set later*/
176                                   LV_GRID_CONTENT, /*Title box*/
177                                   LV_GRID_FR(3),   /*Spacer*/
178                                   LV_GRID_CONTENT, /*Icon box*/
179                                   LV_GRID_FR(3),   /*Spacer*/
180                                   LV_GRID_CONTENT, /*Control box*/
181                                   LV_GRID_FR(3),   /*Spacer*/
182                                   LV_GRID_CONTENT, /*Handle box*/
183                                   LV_DEMO_MUSIC_HANDLE_SIZE,     /*Spacing*/
184                                   LV_GRID_TEMPLATE_LAST
185                                  };
186 
187     grid_rows[1] = LV_VER_RES;
188 
189     lv_obj_set_grid_dsc_array(cont, grid_cols, grid_rows);
190     lv_obj_set_style_grid_row_align(cont, LV_GRID_ALIGN_SPACE_BETWEEN, 0);
191     lv_obj_set_grid_cell(spectrum_obj, LV_GRID_ALIGN_STRETCH, 0, 1, LV_GRID_ALIGN_CENTER, 1, 1);
192     lv_obj_set_grid_cell(title_box, LV_GRID_ALIGN_STRETCH, 0, 1, LV_GRID_ALIGN_CENTER, 2, 1);
193     lv_obj_set_grid_cell(icon_box, LV_GRID_ALIGN_STRETCH, 0, 1, LV_GRID_ALIGN_CENTER, 4, 1);
194     lv_obj_set_grid_cell(ctrl_box, LV_GRID_ALIGN_STRETCH, 0, 1, LV_GRID_ALIGN_CENTER, 6, 1);
195     lv_obj_set_grid_cell(handle_box, LV_GRID_ALIGN_STRETCH, 0, 1, LV_GRID_ALIGN_CENTER, 8, 1);
196 #elif LV_DEMO_MUSIC_LANDSCAPE == 0
197     static const int32_t grid_cols[] = {LV_GRID_FR(1), LV_GRID_TEMPLATE_LAST};
198     static const int32_t grid_rows[] = {LV_DEMO_MUSIC_HANDLE_SIZE,     /*Spacing*/
199                                         LV_GRID_FR(1),   /*Spacer*/
200                                         LV_GRID_CONTENT, /*Title box*/
201                                         LV_GRID_FR(3),   /*Spacer*/
202                                         LV_GRID_CONTENT, /*Icon box*/
203                                         LV_GRID_FR(3),   /*Spacer*/
204 # if LV_DEMO_MUSIC_LARGE == 0
205                                         250,    /*Spectrum obj*/
206 # else
207                                         480,   /*Spectrum obj*/
208 # endif
209                                         LV_GRID_FR(3),   /*Spacer*/
210                                         LV_GRID_CONTENT, /*Control box*/
211                                         LV_GRID_FR(3),   /*Spacer*/
212                                         LV_GRID_CONTENT, /*Handle box*/
213                                         LV_GRID_FR(1),   /*Spacer*/
214                                         LV_DEMO_MUSIC_HANDLE_SIZE,     /*Spacing*/
215                                         LV_GRID_TEMPLATE_LAST
216                                        };
217 
218     lv_obj_set_grid_dsc_array(cont, grid_cols, grid_rows);
219     lv_obj_set_style_grid_row_align(cont, LV_GRID_ALIGN_SPACE_BETWEEN, 0);
220     lv_obj_set_grid_cell(title_box, LV_GRID_ALIGN_STRETCH, 0, 1, LV_GRID_ALIGN_CENTER, 2, 1);
221     lv_obj_set_grid_cell(icon_box, LV_GRID_ALIGN_STRETCH, 0, 1, LV_GRID_ALIGN_CENTER, 4, 1);
222     lv_obj_set_grid_cell(spectrum_obj, LV_GRID_ALIGN_STRETCH, 0, 1, LV_GRID_ALIGN_CENTER, 6, 1);
223     lv_obj_set_grid_cell(ctrl_box, LV_GRID_ALIGN_STRETCH, 0, 1, LV_GRID_ALIGN_CENTER, 8, 1);
224     lv_obj_set_grid_cell(handle_box, LV_GRID_ALIGN_STRETCH, 0, 1, LV_GRID_ALIGN_CENTER, 10, 1);
225 #else
226     /*Arrange the content into a grid*/
227     static const int32_t grid_cols[] = {LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_TEMPLATE_LAST};
228     static const int32_t grid_rows[] = {LV_DEMO_MUSIC_HANDLE_SIZE,     /*Spacing*/
229                                         LV_GRID_FR(1),   /*Spacer*/
230                                         LV_GRID_CONTENT, /*Title box*/
231                                         LV_GRID_FR(1),   /*Spacer*/
232                                         LV_GRID_CONTENT, /*Icon box*/
233                                         LV_GRID_FR(3),   /*Spacer*/
234                                         LV_GRID_CONTENT, /*Control box*/
235                                         LV_GRID_FR(1),   /*Spacer*/
236                                         LV_GRID_CONTENT, /*Handle box*/
237                                         LV_GRID_FR(1),   /*Spacer*/
238                                         LV_DEMO_MUSIC_HANDLE_SIZE,     /*Spacing*/
239                                         LV_GRID_TEMPLATE_LAST
240                                        };
241 
242     lv_obj_set_grid_dsc_array(cont, grid_cols, grid_rows);
243     lv_obj_set_style_grid_row_align(cont, LV_GRID_ALIGN_SPACE_BETWEEN, 0);
244     lv_obj_set_grid_cell(title_box, LV_GRID_ALIGN_STRETCH, 0, 1, LV_GRID_ALIGN_CENTER, 2, 1);
245     lv_obj_set_grid_cell(icon_box, LV_GRID_ALIGN_STRETCH, 0, 1, LV_GRID_ALIGN_CENTER, 4, 1);
246     lv_obj_set_grid_cell(ctrl_box, LV_GRID_ALIGN_STRETCH, 0, 1, LV_GRID_ALIGN_CENTER, 6, 1);
247     lv_obj_set_grid_cell(handle_box, LV_GRID_ALIGN_STRETCH, 0, 2, LV_GRID_ALIGN_CENTER, 8, 1);
248     lv_obj_set_grid_cell(spectrum_obj, LV_GRID_ALIGN_STRETCH, 1, 1, LV_GRID_ALIGN_CENTER, 1, 9);
249 #endif
250 
251     sec_counter_timer = lv_timer_create(timer_cb, 1000, NULL);
252     lv_timer_pause(sec_counter_timer);
253 
254     /*Animate in the content after the intro time*/
255     lv_anim_t a;
256 
257     start_anim = true;
258 
259     stop_start_anim_timer = lv_timer_create(stop_start_anim, INTRO_TIME + 3000, NULL);
260     lv_timer_set_repeat_count(stop_start_anim_timer, 1);
261 
262     lv_anim_init(&a);
263 
264     uint32_t i;
265     lv_anim_set_exec_cb(&a, start_anim_cb);
266     lv_anim_set_values(&a, LV_MAX(LV_HOR_RES, LV_VER_RES) / 2, 0);
267     lv_anim_set_path_cb(&a, lv_anim_path_bounce);
268     for(i = 0; i < BAR_CNT; i++) {
269         lv_anim_set_delay(&a, INTRO_TIME - 200 + (rnd_array[i] % 200));
270         lv_anim_set_duration(&a, 2500 + (rnd_array[i] % 500));
271         lv_anim_set_var(&a, &start_anim_values[i]);
272         lv_anim_start(&a);
273     }
274 
275     lv_obj_fade_in(title_box, 1000, INTRO_TIME + 1000);
276     lv_obj_fade_in(icon_box, 1000, INTRO_TIME + 1000);
277     lv_obj_fade_in(ctrl_box, 1000, INTRO_TIME + 1000);
278     lv_obj_fade_in(handle_box, 1000, INTRO_TIME + 1000);
279     lv_obj_fade_in(album_image_obj, 800, INTRO_TIME + 1000);
280     lv_obj_fade_in(spectrum_obj, 0, INTRO_TIME);
281 
282     lv_anim_set_path_cb(&a, lv_anim_path_ease_out);
283     lv_anim_set_var(&a, album_image_obj);
284     lv_anim_set_duration(&a, 1000);
285     lv_anim_set_delay(&a, INTRO_TIME + 1000);
286     lv_anim_set_values(&a, 1, LV_SCALE_NONE);
287     lv_anim_set_exec_cb(&a, _image_set_scale_anim_cb);
288     lv_anim_set_completed_cb(&a, NULL);
289     lv_anim_start(&a);
290 
291     /* Create an intro from a logo + label */
292     LV_IMAGE_DECLARE(img_lv_demo_music_logo);
293     lv_obj_t * logo = lv_image_create(lv_screen_active());
294     lv_image_set_src(logo, &img_lv_demo_music_logo);
295     lv_obj_move_foreground(logo);
296     lv_obj_align_to(logo, spectrum_obj, LV_ALIGN_CENTER, 0, 0);
297 
298 #if LV_DEMO_MUSIC_SQUARE == 0 && LV_DEMO_MUSIC_ROUND == 0
299     lv_obj_t * title = lv_label_create(lv_screen_active());
300     lv_label_set_text(title, "LVGL Demo\nMusic player");
301     lv_obj_set_style_text_align(title, LV_TEXT_ALIGN_CENTER, 0);
302     lv_obj_set_style_text_font(title, font_large, 0);
303     lv_obj_set_style_text_line_space(title, 8, 0);
304     lv_obj_fade_out(title, 500, INTRO_TIME);
305     lv_obj_align_to(title, logo, LV_ALIGN_OUT_LEFT_MID, -20, 0);
306 #endif
307 
308 
309     lv_anim_set_path_cb(&a, lv_anim_path_ease_in);
310     lv_anim_set_var(&a, logo);
311     lv_anim_set_duration(&a, 400);
312     lv_anim_set_delay(&a, INTRO_TIME + 800);
313     lv_anim_set_values(&a, LV_SCALE_NONE, 10);
314     lv_anim_set_completed_cb(&a, lv_obj_delete_anim_completed_cb);
315     lv_anim_start(&a);
316 
317     lv_obj_update_layout(main_cont);
318 
319     return main_cont;
320 }
321 
lv_demo_music_album_next(bool next)322 void lv_demo_music_album_next(bool next)
323 {
324     uint32_t id = track_id;
325     if(next) {
326         id++;
327         if(id >= ACTIVE_TRACK_CNT) id = 0;
328     }
329     else {
330         if(id == 0) {
331             id = ACTIVE_TRACK_CNT - 1;
332         }
333         else {
334             id--;
335         }
336     }
337 
338     if(playing) {
339         lv_demo_music_play(id);
340     }
341     else {
342         track_load(id);
343     }
344 }
345 
lv_demo_music_play(uint32_t id)346 void lv_demo_music_play(uint32_t id)
347 {
348     track_load(id);
349 
350     lv_demo_music_resume();
351 }
352 
lv_demo_music_resume(void)353 void lv_demo_music_resume(void)
354 {
355     playing = true;
356     spectrum_i = spectrum_i_pause;
357     lv_anim_t a;
358     lv_anim_init(&a);
359     lv_anim_set_values(&a, spectrum_i, spectrum_len - 1);
360     lv_anim_set_exec_cb(&a, spectrum_anim_cb);
361     lv_anim_set_var(&a, spectrum_obj);
362     lv_anim_set_duration(&a, ((spectrum_len - spectrum_i) * 1000) / 30);
363     lv_anim_set_reverse_duration(&a, 0);
364     lv_anim_set_completed_cb(&a, spectrum_end_cb);
365     lv_anim_start(&a);
366 
367     if(sec_counter_timer) lv_timer_resume(sec_counter_timer);
368     lv_slider_set_range(slider_obj, 0, lv_demo_music_get_track_length(track_id));
369 
370     lv_obj_add_state(play_obj, LV_STATE_CHECKED);
371 
372 }
373 
lv_demo_music_pause(void)374 void lv_demo_music_pause(void)
375 {
376     playing = false;
377     spectrum_i_pause = spectrum_i;
378     spectrum_i = 0;
379     lv_anim_delete(spectrum_obj, spectrum_anim_cb);
380     lv_obj_invalidate(spectrum_obj);
381     lv_image_set_scale(album_image_obj, LV_SCALE_NONE);
382     if(sec_counter_timer) lv_timer_pause(sec_counter_timer);
383     lv_obj_remove_state(play_obj, LV_STATE_CHECKED);
384 }
385 
386 /**********************
387  *   STATIC FUNCTIONS
388  **********************/
389 
create_cont(lv_obj_t * parent)390 static lv_obj_t * create_cont(lv_obj_t * parent)
391 {
392     /*A transparent container in which the player section will be scrolled*/
393     main_cont = lv_obj_create(parent);
394     lv_obj_remove_flag(main_cont, LV_OBJ_FLAG_CLICKABLE);
395     lv_obj_remove_flag(main_cont, LV_OBJ_FLAG_SCROLL_ELASTIC);
396     lv_obj_remove_style_all(main_cont);                            /*Make it transparent*/
397     lv_obj_set_size(main_cont, lv_pct(100), lv_pct(100));
398     lv_obj_set_scroll_snap_y(main_cont, LV_SCROLL_SNAP_CENTER);    /*Snap the children to the center*/
399 
400     /*Create a container for the player*/
401     lv_obj_t * player = lv_obj_create(main_cont);
402     lv_obj_set_y(player, - LV_DEMO_MUSIC_HANDLE_SIZE);
403 #if LV_DEMO_MUSIC_SQUARE || LV_DEMO_MUSIC_ROUND
404     lv_obj_set_size(player, LV_HOR_RES, 2 * LV_VER_RES + LV_DEMO_MUSIC_HANDLE_SIZE * 2);
405 #else
406     lv_obj_set_size(player, LV_HOR_RES, LV_VER_RES + LV_DEMO_MUSIC_HANDLE_SIZE * 2);
407 #endif
408     lv_obj_remove_flag(player, LV_OBJ_FLAG_SNAPPABLE);
409 
410     lv_obj_set_style_bg_color(player, lv_color_hex(0xffffff), 0);
411     lv_obj_set_style_border_width(player, 0, 0);
412     lv_obj_set_style_pad_all(player, 0, 0);
413     lv_obj_set_scroll_dir(player, LV_DIR_VER);
414 
415     /* Transparent placeholders below the player container
416      * It is used only to snap it to center.*/
417     lv_obj_t * placeholder1 = lv_obj_create(main_cont);
418     lv_obj_remove_style_all(placeholder1);
419     lv_obj_remove_flag(placeholder1, LV_OBJ_FLAG_CLICKABLE);
420 
421     lv_obj_t * placeholder2 = lv_obj_create(main_cont);
422     lv_obj_remove_style_all(placeholder2);
423     lv_obj_remove_flag(placeholder2, LV_OBJ_FLAG_CLICKABLE);
424 
425 #if LV_DEMO_MUSIC_SQUARE || LV_DEMO_MUSIC_ROUND
426     lv_obj_t * placeholder3 = lv_obj_create(main_cont);
427     lv_obj_remove_style_all(placeholder3);
428     lv_obj_remove_flag(placeholder3, LV_OBJ_FLAG_CLICKABLE);
429 
430     lv_obj_set_size(placeholder1, lv_pct(100), LV_VER_RES);
431     lv_obj_set_y(placeholder1, 0);
432 
433     lv_obj_set_size(placeholder2, lv_pct(100), LV_VER_RES);
434     lv_obj_set_y(placeholder2, LV_VER_RES);
435 
436     lv_obj_set_size(placeholder3, lv_pct(100),  LV_VER_RES - 2 * LV_DEMO_MUSIC_HANDLE_SIZE);
437     lv_obj_set_y(placeholder3, 2 * LV_VER_RES + LV_DEMO_MUSIC_HANDLE_SIZE);
438 #else
439     lv_obj_set_size(placeholder1, lv_pct(100), LV_VER_RES);
440     lv_obj_set_y(placeholder1, 0);
441 
442     lv_obj_set_size(placeholder2, lv_pct(100),  LV_VER_RES - 2 * LV_DEMO_MUSIC_HANDLE_SIZE);
443     lv_obj_set_y(placeholder2, LV_VER_RES + LV_DEMO_MUSIC_HANDLE_SIZE);
444 #endif
445 
446     lv_obj_update_layout(main_cont);
447 
448     return player;
449 }
450 
create_wave_images(lv_obj_t * parent)451 static void create_wave_images(lv_obj_t * parent)
452 {
453     LV_IMAGE_DECLARE(img_lv_demo_music_wave_top);
454     LV_IMAGE_DECLARE(img_lv_demo_music_wave_bottom);
455     lv_obj_t * wave_top = lv_image_create(parent);
456     lv_image_set_src(wave_top, &img_lv_demo_music_wave_top);
457     lv_image_set_inner_align(wave_top, LV_IMAGE_ALIGN_TILE);
458     lv_obj_set_width(wave_top, LV_HOR_RES);
459     lv_obj_align(wave_top, LV_ALIGN_TOP_MID, 0, 0);
460     lv_obj_add_flag(wave_top, LV_OBJ_FLAG_IGNORE_LAYOUT);
461 
462     lv_obj_t * wave_bottom = lv_image_create(parent);
463     lv_image_set_src(wave_bottom, &img_lv_demo_music_wave_bottom);
464     lv_image_set_inner_align(wave_bottom, LV_IMAGE_ALIGN_TILE);
465     lv_obj_set_width(wave_bottom, LV_HOR_RES);
466     lv_obj_align(wave_bottom, LV_ALIGN_BOTTOM_MID, 0, 0);
467     lv_obj_add_flag(wave_bottom, LV_OBJ_FLAG_IGNORE_LAYOUT);
468 
469     LV_IMAGE_DECLARE(img_lv_demo_music_corner_left);
470     LV_IMAGE_DECLARE(img_lv_demo_music_corner_right);
471     lv_obj_t * wave_corner = lv_image_create(parent);
472     lv_image_set_src(wave_corner, &img_lv_demo_music_corner_left);
473 #if LV_DEMO_MUSIC_ROUND == 0
474     lv_obj_align(wave_corner, LV_ALIGN_BOTTOM_LEFT, 0, 0);
475 #else
476     lv_obj_align(wave_corner, LV_ALIGN_BOTTOM_LEFT, -LV_HOR_RES / 6, 0);
477 #endif
478     lv_obj_add_flag(wave_corner, LV_OBJ_FLAG_IGNORE_LAYOUT);
479 
480     wave_corner = lv_image_create(parent);
481     lv_image_set_src(wave_corner, &img_lv_demo_music_corner_right);
482 #if LV_DEMO_MUSIC_ROUND == 0
483     lv_obj_align(wave_corner, LV_ALIGN_BOTTOM_RIGHT, 0, 0);
484 #else
485     lv_obj_align(wave_corner, LV_ALIGN_BOTTOM_RIGHT, LV_HOR_RES / 6, 0);
486 #endif
487     lv_obj_add_flag(wave_corner, LV_OBJ_FLAG_IGNORE_LAYOUT);
488 }
489 
create_title_box(lv_obj_t * parent)490 static lv_obj_t * create_title_box(lv_obj_t * parent)
491 {
492 
493     /*Create the titles*/
494     lv_obj_t * cont = lv_obj_create(parent);
495     lv_obj_remove_style_all(cont);
496     lv_obj_set_height(cont, LV_SIZE_CONTENT);
497     lv_obj_set_flex_flow(cont, LV_FLEX_FLOW_COLUMN);
498     lv_obj_set_flex_align(cont, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
499 
500     title_label = lv_label_create(cont);
501     lv_obj_set_style_text_font(title_label, font_large, 0);
502     lv_obj_set_style_text_color(title_label, lv_color_hex(0x504d6d), 0);
503     lv_label_set_text(title_label, lv_demo_music_get_title(track_id));
504     lv_obj_set_height(title_label, lv_font_get_line_height(font_large) * 3 / 2);
505 
506     artist_label = lv_label_create(cont);
507     lv_obj_set_style_text_font(artist_label, font_small, 0);
508     lv_obj_set_style_text_color(artist_label, lv_color_hex(0x504d6d), 0);
509     lv_label_set_text(artist_label, lv_demo_music_get_artist(track_id));
510 
511     genre_label = lv_label_create(cont);
512     lv_obj_set_style_text_font(genre_label, font_small, 0);
513     lv_obj_set_style_text_color(genre_label, lv_color_hex(0x8a86b8), 0);
514     lv_label_set_text(genre_label, lv_demo_music_get_genre(track_id));
515 
516     return cont;
517 }
518 
create_icon_box(lv_obj_t * parent)519 static lv_obj_t * create_icon_box(lv_obj_t * parent)
520 {
521 
522     lv_obj_t * cont = lv_obj_create(parent);
523     lv_obj_remove_style_all(cont);
524     lv_obj_set_height(cont, LV_SIZE_CONTENT);
525     lv_obj_set_flex_flow(cont, LV_FLEX_FLOW_ROW);
526     lv_obj_set_flex_align(cont, LV_FLEX_ALIGN_SPACE_EVENLY, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
527 
528     lv_obj_t * icon;
529     LV_IMAGE_DECLARE(img_lv_demo_music_icon_1);
530     LV_IMAGE_DECLARE(img_lv_demo_music_icon_2);
531     LV_IMAGE_DECLARE(img_lv_demo_music_icon_3);
532     LV_IMAGE_DECLARE(img_lv_demo_music_icon_4);
533     icon = lv_image_create(cont);
534     lv_image_set_src(icon, &img_lv_demo_music_icon_1);
535     icon = lv_image_create(cont);
536     lv_image_set_src(icon, &img_lv_demo_music_icon_2);
537     icon = lv_image_create(cont);
538     lv_image_set_src(icon, &img_lv_demo_music_icon_3);
539     icon = lv_image_create(cont);
540     lv_image_set_src(icon, &img_lv_demo_music_icon_4);
541 
542     return cont;
543 }
544 
create_spectrum_obj(lv_obj_t * parent)545 static lv_obj_t * create_spectrum_obj(lv_obj_t * parent)
546 {
547     /*Create the spectrum visualizer*/
548     lv_obj_t * obj = lv_obj_create(parent);
549     lv_obj_remove_style_all(obj);
550 #if LV_DEMO_MUSIC_LARGE
551     lv_obj_set_height(obj, 500);
552 #else
553     lv_obj_set_height(obj, 250);
554 #endif
555     lv_obj_remove_flag(obj, LV_OBJ_FLAG_CLICKABLE | LV_OBJ_FLAG_SCROLLABLE);
556     lv_obj_add_event_cb(obj, spectrum_draw_event_cb, LV_EVENT_ALL, NULL);
557     lv_obj_refresh_ext_draw_size(obj);
558     album_image_obj = album_image_create(obj);
559     return obj;
560 }
561 
create_ctrl_box(lv_obj_t * parent)562 static lv_obj_t * create_ctrl_box(lv_obj_t * parent)
563 {
564     /*Create the control box*/
565     lv_obj_t * cont = lv_obj_create(parent);
566     lv_obj_remove_style_all(cont);
567     lv_obj_set_height(cont, LV_SIZE_CONTENT);
568     lv_obj_remove_flag(cont, LV_OBJ_FLAG_SCROLL_ON_FOCUS);
569 #if LV_DEMO_MUSIC_LARGE
570     lv_obj_set_style_pad_bottom(cont, 17, 0);
571 #else
572     lv_obj_set_style_pad_bottom(cont, 8, 0);
573 #endif
574     static const int32_t grid_col[] = {LV_GRID_FR(2), LV_GRID_FR(3), LV_GRID_FR(5), LV_GRID_FR(5), LV_GRID_FR(5), LV_GRID_FR(3), LV_GRID_FR(2), LV_GRID_TEMPLATE_LAST};
575     static const int32_t grid_row[] = {LV_GRID_CONTENT, LV_GRID_CONTENT, LV_GRID_TEMPLATE_LAST};
576     lv_obj_set_grid_dsc_array(cont, grid_col, grid_row);
577 
578     LV_IMAGE_DECLARE(img_lv_demo_music_btn_loop);
579     LV_IMAGE_DECLARE(img_lv_demo_music_btn_rnd);
580     LV_IMAGE_DECLARE(img_lv_demo_music_btn_next);
581     LV_IMAGE_DECLARE(img_lv_demo_music_btn_prev);
582     LV_IMAGE_DECLARE(img_lv_demo_music_btn_play);
583     LV_IMAGE_DECLARE(img_lv_demo_music_btn_pause);
584 
585     lv_obj_t * icon;
586     icon = lv_image_create(cont);
587     lv_image_set_src(icon, &img_lv_demo_music_btn_rnd);
588     lv_obj_set_grid_cell(icon, LV_GRID_ALIGN_START, 1, 1, LV_GRID_ALIGN_CENTER, 0, 1);
589 
590     icon = lv_image_create(cont);
591     lv_image_set_src(icon, &img_lv_demo_music_btn_loop);
592     lv_obj_set_grid_cell(icon, LV_GRID_ALIGN_END, 5, 1, LV_GRID_ALIGN_CENTER, 0, 1);
593 
594     icon = lv_image_create(cont);
595     lv_image_set_src(icon, &img_lv_demo_music_btn_prev);
596     lv_obj_set_grid_cell(icon, LV_GRID_ALIGN_CENTER, 2, 1, LV_GRID_ALIGN_CENTER, 0, 1);
597     lv_obj_add_event_cb(icon, prev_click_event_cb, LV_EVENT_CLICKED, NULL);
598     lv_obj_add_flag(icon, LV_OBJ_FLAG_CLICKABLE);
599 
600     play_obj = lv_imagebutton_create(cont);
601     lv_imagebutton_set_src(play_obj, LV_IMAGEBUTTON_STATE_RELEASED, NULL, &img_lv_demo_music_btn_play, NULL);
602     lv_imagebutton_set_src(play_obj, LV_IMAGEBUTTON_STATE_CHECKED_RELEASED, NULL, &img_lv_demo_music_btn_pause, NULL);
603     lv_obj_add_flag(play_obj, LV_OBJ_FLAG_CHECKABLE);
604     lv_obj_set_grid_cell(play_obj, LV_GRID_ALIGN_CENTER, 3, 1, LV_GRID_ALIGN_CENTER, 0, 1);
605 
606     lv_obj_add_event_cb(play_obj, play_event_click_cb, LV_EVENT_CLICKED, NULL);
607     lv_obj_add_flag(play_obj, LV_OBJ_FLAG_CLICKABLE);
608     lv_obj_set_width(play_obj, img_lv_demo_music_btn_play.header.w);
609 
610     icon = lv_image_create(cont);
611     lv_image_set_src(icon, &img_lv_demo_music_btn_next);
612     lv_obj_set_grid_cell(icon, LV_GRID_ALIGN_CENTER, 4, 1, LV_GRID_ALIGN_CENTER, 0, 1);
613     lv_obj_add_event_cb(icon, next_click_event_cb, LV_EVENT_CLICKED, NULL);
614     lv_obj_add_flag(icon, LV_OBJ_FLAG_CLICKABLE);
615 
616     LV_IMAGE_DECLARE(img_lv_demo_music_slider_knob);
617     slider_obj = lv_slider_create(cont);
618     lv_obj_set_style_anim_duration(slider_obj, 100, 0);
619     lv_obj_add_flag(slider_obj, LV_OBJ_FLAG_CLICKABLE); /*No input from the slider*/
620     lv_obj_remove_flag(slider_obj, LV_OBJ_FLAG_SCROLL_ON_FOCUS);
621 
622 #if LV_DEMO_MUSIC_LARGE == 0
623     lv_obj_set_height(slider_obj, 3);
624 #else
625     lv_obj_set_height(slider_obj, 6);
626 #endif
627     lv_obj_set_grid_cell(slider_obj, LV_GRID_ALIGN_STRETCH, 1, 4, LV_GRID_ALIGN_CENTER, 1, 1);
628 
629     lv_obj_set_style_bg_image_src(slider_obj, &img_lv_demo_music_slider_knob, LV_PART_KNOB);
630     lv_obj_set_style_bg_opa(slider_obj, LV_OPA_TRANSP, LV_PART_KNOB);
631     lv_obj_set_style_pad_all(slider_obj, 20, LV_PART_KNOB);
632     lv_obj_set_style_bg_grad_dir(slider_obj, LV_GRAD_DIR_HOR, LV_PART_INDICATOR);
633     lv_obj_set_style_bg_color(slider_obj, lv_color_hex(0x569af8), LV_PART_INDICATOR);
634     lv_obj_set_style_bg_grad_color(slider_obj, lv_color_hex(0xa666f1), LV_PART_INDICATOR);
635     lv_obj_set_style_outline_width(slider_obj, 0, 0);
636     lv_obj_add_event_cb(slider_obj, del_counter_timer_cb, LV_EVENT_DELETE, NULL);
637 
638     time_obj = lv_label_create(cont);
639     lv_obj_set_style_text_font(time_obj, font_small, 0);
640     lv_obj_set_style_text_color(time_obj, lv_color_hex(0x8a86b8), 0);
641     lv_label_set_text(time_obj, "0:00");
642     lv_obj_set_grid_cell(time_obj, LV_GRID_ALIGN_END, 5, 1, LV_GRID_ALIGN_CENTER, 1, 1);
643     lv_obj_add_event_cb(time_obj, del_counter_timer_cb, LV_EVENT_DELETE, NULL);
644 
645     return cont;
646 }
647 
create_handle(lv_obj_t * parent)648 static lv_obj_t * create_handle(lv_obj_t * parent)
649 {
650     lv_obj_t * cont = lv_obj_create(parent);
651     lv_obj_remove_style_all(cont);
652 
653     lv_obj_set_size(cont, lv_pct(100), LV_SIZE_CONTENT);
654     lv_obj_set_flex_flow(cont, LV_FLEX_FLOW_COLUMN);
655     lv_obj_set_flex_align(cont, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
656     lv_obj_set_style_pad_row(cont, 8, 0);
657 
658     /*A handle to scroll to the track list*/
659     lv_obj_t * handle_label = lv_label_create(cont);
660     lv_label_set_text(handle_label, "ALL TRACKS");
661     lv_obj_set_style_text_font(handle_label, font_small, 0);
662     lv_obj_set_style_text_color(handle_label, lv_color_hex(0x8a86b8), 0);
663 
664     lv_obj_t * handle_rect = lv_obj_create(cont);
665 #if LV_DEMO_MUSIC_LARGE
666     lv_obj_set_size(handle_rect, 40, 3);
667 #else
668     lv_obj_set_size(handle_rect, 20, 2);
669 #endif
670 
671     lv_obj_set_style_bg_color(handle_rect, lv_color_hex(0x8a86b8), 0);
672     lv_obj_set_style_border_width(handle_rect, 0, 0);
673 
674     return cont;
675 }
676 
track_load(uint32_t id)677 static void track_load(uint32_t id)
678 {
679     spectrum_i = 0;
680     time_act = 0;
681     spectrum_i_pause = 0;
682     lv_slider_set_value(slider_obj, 0, LV_ANIM_OFF);
683     lv_label_set_text(time_obj, "0:00");
684 
685     if(id == track_id) return;
686     bool next = false;
687     if((track_id + 1) % ACTIVE_TRACK_CNT == id) next = true;
688 
689     lv_demo_music_list_button_check(track_id, false);
690 
691     track_id = id;
692 
693     lv_demo_music_list_button_check(id, true);
694 
695     lv_label_set_text(title_label, lv_demo_music_get_title(track_id));
696     lv_label_set_text(artist_label, lv_demo_music_get_artist(track_id));
697     lv_label_set_text(genre_label, lv_demo_music_get_genre(track_id));
698 
699     lv_anim_t a;
700     lv_anim_init(&a);
701     lv_anim_set_var(&a, album_image_obj);
702     lv_anim_set_values(&a, lv_obj_get_style_image_opa(album_image_obj, 0), LV_OPA_TRANSP);
703     lv_anim_set_exec_cb(&a, album_fade_anim_cb);
704     lv_anim_set_duration(&a, 500);
705     lv_anim_start(&a);
706 
707     lv_anim_init(&a);
708     lv_anim_set_var(&a, album_image_obj);
709     lv_anim_set_duration(&a, 500);
710     lv_anim_set_path_cb(&a, lv_anim_path_ease_out);
711 #if LV_DEMO_MUSIC_LANDSCAPE
712     if(next) {
713         lv_anim_set_values(&a, 0, - LV_HOR_RES / 7);
714     }
715     else {
716         lv_anim_set_values(&a, 0, LV_HOR_RES / 7);
717     }
718 #else
719     if(next) {
720         lv_anim_set_values(&a, 0, - LV_HOR_RES / 2);
721     }
722     else {
723         lv_anim_set_values(&a, 0, LV_HOR_RES / 2);
724     }
725 #endif
726     lv_anim_set_exec_cb(&a, _obj_set_x_anim_cb);
727     lv_anim_set_completed_cb(&a, lv_obj_delete_anim_completed_cb);
728     lv_anim_start(&a);
729 
730     lv_anim_set_path_cb(&a, lv_anim_path_linear);
731     lv_anim_set_var(&a, album_image_obj);
732     lv_anim_set_duration(&a, 500);
733     lv_anim_set_values(&a, LV_SCALE_NONE, LV_SCALE_NONE / 2);
734     lv_anim_set_exec_cb(&a, _image_set_scale_anim_cb);
735     lv_anim_set_completed_cb(&a, NULL);
736     lv_anim_start(&a);
737 
738     album_image_obj = album_image_create(spectrum_obj);
739 
740     lv_anim_set_path_cb(&a, lv_anim_path_overshoot);
741     lv_anim_set_var(&a, album_image_obj);
742     lv_anim_set_duration(&a, 500);
743     lv_anim_set_delay(&a, 100);
744     lv_anim_set_values(&a, LV_SCALE_NONE / 4, LV_SCALE_NONE);
745     lv_anim_set_exec_cb(&a, _image_set_scale_anim_cb);
746     lv_anim_set_completed_cb(&a, NULL);
747     lv_anim_start(&a);
748 
749     lv_anim_init(&a);
750     lv_anim_set_var(&a, album_image_obj);
751     lv_anim_set_values(&a, 0, LV_OPA_COVER);
752     lv_anim_set_exec_cb(&a, album_fade_anim_cb);
753     lv_anim_set_duration(&a, 500);
754     lv_anim_set_delay(&a, 100);
755     lv_anim_start(&a);
756 }
757 
get_cos(int32_t deg,int32_t a)758 int32_t get_cos(int32_t deg, int32_t a)
759 {
760     int32_t r = (lv_trigo_cos(deg) * a);
761 
762     r += LV_TRIGO_SIN_MAX / 2;
763     return r >> LV_TRIGO_SHIFT;
764 }
765 
get_sin(int32_t deg,int32_t a)766 int32_t get_sin(int32_t deg, int32_t a)
767 {
768     int32_t r = lv_trigo_sin(deg) * a;
769 
770     return (r + LV_TRIGO_SIN_MAX / 2) >> LV_TRIGO_SHIFT;
771 
772 }
773 
del_counter_timer_cb(lv_event_t * e)774 static void del_counter_timer_cb(lv_event_t * e)
775 {
776     lv_event_code_t code = lv_event_get_code(e);
777     if(code == LV_EVENT_DELETE && sec_counter_timer) {
778         lv_timer_delete(sec_counter_timer);
779         sec_counter_timer = NULL;
780     }
781 }
782 
spectrum_draw_event_cb(lv_event_t * e)783 static void spectrum_draw_event_cb(lv_event_t * e)
784 {
785     lv_event_code_t code = lv_event_get_code(e);
786 
787     if(code == LV_EVENT_REFR_EXT_DRAW_SIZE) {
788 #if LV_DEMO_MUSIC_LANDSCAPE
789         lv_event_set_ext_draw_size(e, LV_HOR_RES);
790 #else
791         lv_event_set_ext_draw_size(e, LV_VER_RES);
792 #endif
793     }
794     else if(code == LV_EVENT_COVER_CHECK) {
795         lv_event_set_cover_res(e, LV_COVER_RES_NOT_COVER);
796     }
797     else if(code == LV_EVENT_DRAW_MAIN_BEGIN) {
798         lv_obj_t * obj = lv_event_get_target(e);
799         lv_layer_t * layer = lv_event_get_layer(e);
800 
801         lv_opa_t opa = lv_obj_get_style_opa_recursive(obj, LV_PART_MAIN);
802         if(opa < LV_OPA_MIN) return;
803 
804         lv_point_t center;
805         lv_area_t obj_coords;
806         lv_obj_get_coords(obj, &obj_coords);
807         center.x = obj_coords.x1 + lv_obj_get_width(obj) / 2;
808         center.y = obj_coords.y1 + lv_obj_get_height(obj) / 2;
809 
810         lv_draw_triangle_dsc_t draw_dsc;
811         lv_draw_triangle_dsc_init(&draw_dsc);
812         draw_dsc.bg_opa = LV_OPA_COVER;
813 
814         uint16_t r[64];
815         uint32_t i;
816 
817         for(i = 0; i < BAR_CNT; i++) {
818             r[i] = BAR_REST_RADIUS;
819         }
820 
821         uint32_t s;
822         for(s = 0; s < 4; s++) {
823             uint32_t f;
824             uint32_t band_w = 0;    /*Real number of bars in this band.*/
825             switch(s) {
826                 case 0:
827                     band_w = 20;
828                     break;
829                 case 1:
830                     band_w = 8;
831                     break;
832                 case 2:
833                     band_w = 4;
834                     break;
835                 case 3:
836                     band_w = 2;
837                     break;
838             }
839 
840             /* Add "side bars" with cosine characteristic.*/
841             for(f = 0; f < band_w; f++) {
842                 uint32_t ampl_main = spectrum[spectrum_i][s];
843                 int32_t ampl_mod = get_cos(f * 360 / band_w + 180, 180) + 180;
844                 int32_t t = BAR_PER_BAND_CNT * s - band_w / 2 + f;
845                 if(t < 0) t = BAR_CNT + t;
846                 if(t >= BAR_CNT) t = t - BAR_CNT;
847                 r[t] += (ampl_main * ampl_mod) >> 9;
848             }
849         }
850 
851         const int32_t amax = 20;
852         int32_t animv = spectrum_i - 0;
853         if(animv > amax) animv = amax;
854         for(i = 0; i < BAR_CNT; i++) {
855             uint32_t deg_space = 1;
856             uint32_t deg = i * DEG_STEP + 90;
857             uint32_t j = (i + bar_rot + rnd_array[bar_ofs % 10]) % BAR_CNT;
858             uint32_t k = (i + bar_rot + rnd_array[(bar_ofs + 1) % 10]) % BAR_CNT;
859 
860             uint32_t v;
861             if(start_anim) {
862                 v = BAR_REST_RADIUS + start_anim_values[i];
863             }
864             else {
865                 v = (r[k] * animv + r[j] * (amax - animv)) / amax;
866             }
867 
868             if(v < BAR_COLOR1_STOP) draw_dsc.bg_color = BAR_COLOR1;
869             else if(v > (uint32_t)BAR_COLOR3_STOP) draw_dsc.bg_color = BAR_COLOR3;
870             else if(v > BAR_COLOR2_STOP) draw_dsc.bg_color = lv_color_mix(BAR_COLOR3, BAR_COLOR2,
871                                                                               ((v - BAR_COLOR2_STOP) * 255) / (BAR_COLOR3_STOP - BAR_COLOR2_STOP));
872             else draw_dsc.bg_color = lv_color_mix(BAR_COLOR2, BAR_COLOR1,
873                                                       ((v - BAR_COLOR1_STOP) * 255) / (BAR_COLOR2_STOP - BAR_COLOR1_STOP));
874 
875             uint32_t di = deg + deg_space;
876 
877             int32_t x1_out = get_cos(di, v);
878             draw_dsc.p[0].x = center.x + x1_out;
879             draw_dsc.p[0].y = center.y + get_sin(di, v);
880 
881             di += DEG_STEP - deg_space * 2;
882 
883             int32_t x2_out = get_cos(di, v);
884             draw_dsc.p[1].x = center.x + x2_out;
885             draw_dsc.p[1].y = center.y + get_sin(di, v);
886 
887             int32_t x2_in = get_cos(di, 0);
888             draw_dsc.p[2].x = center.x + x2_in;
889             draw_dsc.p[2].y = center.y + get_sin(di, 0);
890             lv_draw_triangle(layer, &draw_dsc);
891 
892             draw_dsc.p[0].x = center.x - x1_out;
893             draw_dsc.p[1].x = center.x - x2_out;
894             draw_dsc.p[2].x = center.x - x2_in;
895             lv_draw_triangle(layer, &draw_dsc);
896         }
897     }
898     else if(code == LV_EVENT_DELETE) {
899         lv_anim_delete(NULL, start_anim_cb);
900         lv_anim_delete(NULL, spectrum_anim_cb);
901         if(start_anim && stop_start_anim_timer) lv_timer_delete(stop_start_anim_timer);
902     }
903 }
904 
spectrum_anim_cb(void * a,int32_t v)905 static void spectrum_anim_cb(void * a, int32_t v)
906 {
907     lv_obj_t * obj = a;
908     if(start_anim) {
909         lv_obj_invalidate(obj);
910         return;
911     }
912 
913     spectrum_i = v;
914     lv_obj_invalidate(obj);
915 
916     static uint32_t bass_cnt = 0;
917     static int32_t last_bass = -1000;
918     static int32_t dir = 1;
919     if(spectrum[spectrum_i][0] > 12) {
920         if(spectrum_i - last_bass > 5) {
921             bass_cnt++;
922             last_bass = spectrum_i;
923             if(bass_cnt >= 2) {
924                 bass_cnt = 0;
925                 bar_ofs++;
926             }
927         }
928     }
929     if(spectrum[spectrum_i][0] < 4) bar_rot += dir;
930 
931     lv_image_set_scale(album_image_obj, LV_SCALE_NONE + spectrum[spectrum_i][0]);
932 }
933 
start_anim_cb(void * var,int32_t v)934 static void start_anim_cb(void * var, int32_t v)
935 {
936     int32_t * av = var;
937     *av = v;
938     lv_obj_invalidate(spectrum_obj);
939 }
940 
album_image_create(lv_obj_t * parent)941 static lv_obj_t * album_image_create(lv_obj_t * parent)
942 {
943     LV_IMAGE_DECLARE(img_lv_demo_music_cover_1);
944     LV_IMAGE_DECLARE(img_lv_demo_music_cover_2);
945     LV_IMAGE_DECLARE(img_lv_demo_music_cover_3);
946 
947     lv_obj_t * img;
948     img = lv_image_create(parent);
949 
950     switch(track_id) {
951         case 2:
952             lv_image_set_src(img, &img_lv_demo_music_cover_3);
953             spectrum = spectrum_3;
954             spectrum_len = sizeof(spectrum_3) / sizeof(spectrum_3[0]);
955             break;
956         case 1:
957             lv_image_set_src(img, &img_lv_demo_music_cover_2);
958             spectrum = spectrum_2;
959             spectrum_len = sizeof(spectrum_2) / sizeof(spectrum_2[0]);
960             break;
961         case 0:
962             lv_image_set_src(img, &img_lv_demo_music_cover_1);
963             spectrum = spectrum_1;
964             spectrum_len = sizeof(spectrum_1) / sizeof(spectrum_1[0]);
965             break;
966     }
967     lv_image_set_antialias(img, false);
968     lv_obj_align(img, LV_ALIGN_CENTER, 0, 0);
969     lv_obj_add_event_cb(img, album_gesture_event_cb, LV_EVENT_GESTURE, NULL);
970     lv_obj_remove_flag(img, LV_OBJ_FLAG_GESTURE_BUBBLE);
971     lv_obj_add_flag(img, LV_OBJ_FLAG_CLICKABLE);
972 
973     return img;
974 
975 }
976 
album_gesture_event_cb(lv_event_t * e)977 static void album_gesture_event_cb(lv_event_t * e)
978 {
979     LV_UNUSED(e);
980     lv_dir_t dir = lv_indev_get_gesture_dir(lv_indev_active());
981     if(dir == LV_DIR_LEFT) lv_demo_music_album_next(true);
982     if(dir == LV_DIR_RIGHT) lv_demo_music_album_next(false);
983 }
984 
play_event_click_cb(lv_event_t * e)985 static void play_event_click_cb(lv_event_t * e)
986 {
987     lv_obj_t * obj = lv_event_get_target(e);
988     if(lv_obj_has_state(obj, LV_STATE_CHECKED)) {
989         lv_demo_music_resume();
990     }
991     else {
992         lv_demo_music_pause();
993     }
994 }
995 
prev_click_event_cb(lv_event_t * e)996 static void prev_click_event_cb(lv_event_t * e)
997 {
998     LV_UNUSED(e);
999     lv_demo_music_album_next(false);
1000 }
1001 
next_click_event_cb(lv_event_t * e)1002 static void next_click_event_cb(lv_event_t * e)
1003 {
1004     lv_event_code_t code = lv_event_get_code(e);
1005     if(code == LV_EVENT_CLICKED) {
1006         lv_demo_music_album_next(true);
1007     }
1008 }
1009 
timer_cb(lv_timer_t * t)1010 static void timer_cb(lv_timer_t * t)
1011 {
1012     LV_UNUSED(t);
1013     time_act++;
1014     lv_label_set_text_fmt(time_obj, "%"LV_PRIu32":%02"LV_PRIu32, time_act / 60, time_act % 60);
1015     lv_slider_set_value(slider_obj, time_act, LV_ANIM_ON);
1016 }
1017 
spectrum_end_cb(lv_anim_t * a)1018 static void spectrum_end_cb(lv_anim_t * a)
1019 {
1020     LV_UNUSED(a);
1021     lv_demo_music_album_next(true);
1022 }
1023 
stop_start_anim(lv_timer_t * t)1024 static void stop_start_anim(lv_timer_t * t)
1025 {
1026     LV_UNUSED(t);
1027     start_anim = false;
1028     lv_obj_refresh_ext_draw_size(spectrum_obj);
1029 }
1030 
album_fade_anim_cb(void * var,int32_t v)1031 static void album_fade_anim_cb(void * var, int32_t v)
1032 {
1033     lv_obj_set_style_image_opa(var, v, 0);
1034 }
1035 #endif /*LV_USE_DEMO_MUSIC*/
1036