blob: c34b3bab68b39c9c08ab3e6cf327e0d870b53dde (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
/*
* player.c
*
* Created on: Nov 25, 2025
* Author: sowgro
*/
#include <parser.h>
#include "endian_converters.h"
#include <stdint.h>
#include "endian_converters.h"
#include "hw8.h"
#include "activity4.h"
#include "systick.h"
#include "tone.h"
static track_t tracks[4];
static int nTracks;
static int startTime;
static song_info_t song_info;
void parser_play_notes() {
int count = systick_get_count();
int curAbsTime = count - startTime;
for (int i = 0; i < nTracks; i++) {
note_event_t curEvent = tracks[i].events[tracks[i].curEventIndex];
if (curEvent.abs_time >= curAbsTime) {
switch (curEvent.ev_type) {
case NOTE_OFF_EVENT:
remove_tone(curEvent.key_number); break;
case NOTE_ON_EVENT:
add_tone(curEvent.key_number, curEvent.value); break;
}
}
tracks[i].curEventIndex++;
}
play_tones();
}
void parse_song(uint8_t *p_song) {
header_t header;
header = get_header(p_song);
p_song += sizeof(header_t) - 2; // move pointer past header
parse_song_info(p_song, &song_info);
nTracks = header.ntrcks;
for(int i = 0; i < nTracks; i++){
p_song = parse_track(p_song, &tracks[i]);
}
}
uint8_t *parse_track(uint8_t *p_song, track_t *track) {
printf("Parsing track \r\n");
p_song += 4; // skip MTrk
uint32_t MTrk_len = convert_to_uint32(p_song);
p_song += 4;
int curEvent = 0;
uint32_t prev_abs_time = 0;
for (uint8_t *p_end = p_song + MTrk_len; p_song != p_end; p_song++) {
note_event_t note;
parseDelay_result_t delay_result = parseDelay(p_song);
uint32_t abs_time = prev_abs_time + delay_result.value;
note.abs_time = abs_time;
prev_abs_time = abs_time;
p_song += delay_result.bytes_used;
if (*p_song >> 4 == 0b1000) {
note.ev_type = NOTE_OFF_EVENT;
} else if (*p_song >> 4 == 0b1001) {
note.ev_type = NOTE_ON_EVENT;
} else if (*p_song >> 4 == 0b1010) {
note.ev_type = KEY_PRESSURE;
} else {
continue;
}
// size_t channelNumber = *p_song && 0b00001111;
p_song++;
note.key_number = *p_song;
p_song++;
note.value = *p_song;
p_song++;
track->events[curEvent++] = note;
}
track->nEvents = curEvent;
track->curEventIndex = 0;
printf("parsing track done\r\n");
return p_song;
}
uint8_t *parse_song_info(uint8_t *p_song, song_info_t *ret) {
ret->copyright = 0;
ret->tempo = 0;
ret->title = 0;
p_song += 4; // move past MTrk label
uint32_t MTrk_len = convert_to_uint32(p_song); // read in size of MTrk
p_song += sizeof(MTrk_len);
for (uint8_t *p_end = p_song + MTrk_len; p_song != p_end; p_song++) {
// FF 02 - copyright
if (convert_to_uint16(p_song) == 0xFF02) {
p_song += sizeof(uint16_t);
uint8_t ev_len = *(uint8_t *) p_song;
p_song += sizeof(ev_len);
ret->copyright = (char *) p_song;
ret->copyright[ev_len] = 0;
}
// FF 03 - title
if (convert_to_uint16(p_song) == 0xFF03) {
p_song += sizeof(uint16_t);
uint8_t ev_len = *(uint8_t *) p_song;
p_song += sizeof(ev_len);
ret->title = (char *) p_song;
ret->title[ev_len] = 0;
}
// FF 51 - tempo
if (convert_to_uint16(p_song) == 0xFF51) {
p_song += sizeof(uint16_t);
p_song += sizeof(uint8_t); // skip length, always 03
ret->tempo = convert_to_uint24(p_song);
}
}
return p_song;
}
song_info_t parser_get_song_info() {
return song_info;
}
|