1 #include "musicbox.h"
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <vfsdev/pwm_dev.h>
5 
6 MENU_COVER_TYP musicbox_cover = {MENU_COVER_FUNC, NULL, NULL,
7                                  musicbox_cover_draw, 0};
8 MENU_TASK_TYP  musicbox_tasks = {musicbox_init, musicbox_uninit};
9 MENU_TYP       musicbox       = {"musicbox", &musicbox_cover, &musicbox_tasks,
10                      musicbox_key_handel, NULL};
11 
12 static aos_task_t musicbox_task_handle;
13 
14 #define NOTE_SPACE_RATIO 1.3
15 
16 music_t *music_list[] = {
17     &Imperial_March,
18     &liang_zhi_lao_hu,
19 };
20 
21 player_t musicbox_player = {music_list, 2, 0, 0, 0, 0};
22 
musicbox_cover_draw(int * draw_index)23 void musicbox_cover_draw(int *draw_index)
24 {
25     int floating_y[] = {-5, -4, -3, -2, -1, 0, 1,  2,  3,  4,
26                         5,  4,  3,  2,  1,  0, -1, -2, -3, -4};
27     OLED_Clear();
28 
29     OLED_Icon_Draw(48, 16 + floating_y[*draw_index], &icon_note_32_32, 0);
30 
31     OLED_Icon_Draw(2, 24, &icon_skip_left, 0);
32     OLED_Icon_Draw(122, 24, &icon_skip_right, 0);
33 
34     (*draw_index)++;
35     if ((*draw_index) >= 20) {
36         (*draw_index) = 0;
37     }
38 
39     OLED_Refresh_GRAM();
40     aos_msleep(100);
41     return 0;
42 }
43 
musicbox_init(void)44 int musicbox_init(void)
45 {
46     OLED_Clear();
47     OLED_Refresh_GRAM();
48 
49     musicbox_player.isPlaying      = 0;
50     musicbox_player.cur_music_note = 0;
51     set_music_time();
52 
53     aos_task_new_ext(&musicbox_task_handle, "musicbox_task", musicbox_task, NULL, 1024 * 4, AOS_DEFAULT_APP_PRI);
54     LOGI(EDU_TAG, "aos_task_new musicbox_task\n");
55     return 0;
56 }
57 
musicbox_uninit(void)58 int musicbox_uninit(void)
59 {
60     noTone(0);
61     aos_task_delete(&musicbox_task_handle);
62     LOGI(EDU_TAG, "aos_task_delete musicbox_task\n");
63     return 0;
64 }
65 
set_music_time()66 void set_music_time()
67 {
68     for (int i = 0; i < musicbox_player.music_list_len; i++) {
69         for (int n = 0; n < musicbox_player.music_list[i]->noteLength; n++) {
70             int noteDuration =
71                 1000 / musicbox_player.music_list[i]->noteDurations[n];
72             noteDuration =
73                 (noteDuration < 0) ? (-noteDuration * 1.5) : noteDuration;
74             musicbox_player.music_list[i]->musicTime +=
75                 (noteDuration + (int)(noteDuration * NOTE_SPACE_RATIO));
76         }
77     }
78 }
79 
next_song()80 void next_song()
81 {
82     musicbox_player.cur_music_index =
83         ((musicbox_player.cur_music_index ==
84           musicbox_player.music_list_len - 1) ?
85              (0) :
86              (musicbox_player.cur_music_index + 1));
87     LOGI(EDU_TAG, "cur_music_index %d\n", musicbox_player.cur_music_index);
88     musicbox_player.cur_music_note = 0;
89     musicbox_player.cur_music_time = 0;
90     musicbox_player.isPlaying      = 1;
91 }
92 
previous_song()93 void previous_song()
94 {
95     musicbox_player.cur_music_index =
96         ((musicbox_player.cur_music_index == 0) ?
97              (musicbox_player.music_list_len - 1) :
98              (musicbox_player.cur_music_index - 1));
99     LOGI(EDU_TAG, "cur_music_index %d\n", musicbox_player.cur_music_index);
100     musicbox_player.cur_music_note = 0;
101     musicbox_player.cur_music_time = 0;
102     musicbox_player.isPlaying      = 1;
103 }
104 
pause_resume()105 void pause_resume() { musicbox_player.isPlaying = !musicbox_player.isPlaying; }
106 
musicbox_key_handel(key_code_t key_code)107 void musicbox_key_handel(key_code_t key_code)
108 {
109     switch (key_code) {
110         case 0b0001:
111             // pre
112             previous_song();
113             aos_msleep(1000);
114             break;
115         case 0b0100:
116             // next
117             next_song();
118             aos_msleep(1000);
119             break;
120         case 0b1000:
121             // pause/resume
122             pause_resume();
123             break;
124         default:
125             break;
126     }
127 }
128 
tone(uint16_t port,uint16_t frequency,uint16_t duration)129 void tone(uint16_t port, uint16_t frequency, uint16_t duration)
130 {
131     int ret = -1;
132     int fd = 0;
133     char name[16] = {0};
134     float duty_cycle = 0.8;
135 
136     snprintf(name, sizeof(name), "/dev/pwm%d", port);
137     fd = open(name, 0);
138     if (fd >= 0) {
139         if (frequency > 0) {
140             ret = ioctl(fd, IOC_PWM_FREQ, (unsigned long)frequency);
141             ret = ioctl(fd, IOC_PWM_DUTY_CYCLE, (unsigned long)&duty_cycle);
142             ret = ioctl(fd, IOC_PWM_ON, (unsigned long)0);
143         }
144         if (duration != 0) {
145             aos_msleep(duration);
146         }
147         if (frequency > 0 && duration > 0) {
148             ret = ioctl(fd, IOC_PWM_OFF, (unsigned long)0);
149             close(fd);
150         }
151     }
152 }
153 
noTone(uint16_t port)154 void noTone(uint16_t port)
155 {
156     int ret = -1;
157     int fd = 0;
158     char name[16] = {0};
159     float duty_cycle = 0.8;
160     int freq = 1;
161     unsigned int period_s;
162 
163     snprintf(name, sizeof(name), "/dev/pwm%d", port);
164     fd = open(name, 0);
165     if (fd >= 0) {
166         ret = ioctl(fd, IOC_PWM_FREQ, (unsigned long)freq);
167         ret = ioctl(fd, IOC_PWM_DUTY_CYCLE, (unsigned long)&duty_cycle);
168         ret = ioctl(fd, IOC_PWM_ON, (unsigned long)0);
169         ret = ioctl(fd, IOC_PWM_OFF, (unsigned long)0);
170         close(fd);
171     }
172 }
173 
musicbox_task()174 void musicbox_task()
175 {
176     while (1) {
177         OLED_Clear();
178         music_t *cur_music =
179             musicbox_player.music_list[musicbox_player.cur_music_index];
180 
181         char show_song_name[14] = {0};
182         sprintf(show_song_name, "%-13.13s", cur_music->name);
183         OLED_Show_String(14, 4, show_song_name, 16, 1);
184 
185         if (musicbox_player.isPlaying) {
186             if (musicbox_player.cur_music_note < cur_music->noteLength) {
187                 int noteDuration =
188                     1000 /
189                     cur_music->noteDurations[musicbox_player.cur_music_note];
190                 noteDuration =
191                     (noteDuration < 0) ? (-noteDuration * 1.5) : noteDuration;
192                 LOGI(EDU_TAG, "note[%d] = %d\t delay %d ms\n",
193                        musicbox_player.cur_music_note,
194                        cur_music->noteDurations[musicbox_player.cur_music_note],
195                        noteDuration);
196                 int note = cur_music->notes[musicbox_player.cur_music_note];
197                 tone(0, note, noteDuration);
198                 aos_msleep((int)(noteDuration * NOTE_SPACE_RATIO));
199                 musicbox_player.cur_music_time +=
200                     (noteDuration + (int)(noteDuration * NOTE_SPACE_RATIO));
201                 musicbox_player.cur_music_note++;
202             } else {
203                 noTone(0);
204                 aos_msleep(1000);
205                 next_song();
206             }
207             OLED_Icon_Draw(54, 36, &icon_pause_24_24, 1);
208         } else {
209             OLED_Icon_Draw(54, 36, &icon_resume_24_24, 1);
210             aos_msleep(500);
211         }
212 
213         OLED_DrawLine(14, 26, 14, 29, 1);
214         OLED_DrawLine(117, 26, 117, 29, 1);
215         OLED_DrawLine(16, 27,
216                       (int)(16 + 99.0 * (musicbox_player.cur_music_time * 1.0 /
217                                          cur_music->musicTime)),
218                       27, 1);
219         OLED_DrawLine(16, 28,
220                       16 + 99.0 * (musicbox_player.cur_music_time * 1.0 /
221                                    cur_music->musicTime),
222                       28, 1);
223         OLED_Icon_Draw(94, 36, &icon_next_song_24_24, 1);
224         OLED_Icon_Draw(14, 36, &icon_previous_song_24_24, 1);
225         OLED_Refresh_GRAM();
226     }
227 }
228