diff options
| author | sowgro <tpoke.ferrari@gmail.com> | 2025-12-14 00:21:02 -0500 |
|---|---|---|
| committer | sowgro <tpoke.ferrari@gmail.com> | 2025-12-14 00:21:02 -0500 |
| commit | e68a05b29de507a56b8747557707e8d6cdd68542 (patch) | |
| tree | 1f7c457159af75ae198258a2301a55531d7baff5 /project/Core/Src/Project/parser.c | |
| parent | 519f868c445a86b988772307ea1f1e2fc95fe54a (diff) | |
| download | 340-repo-Sowgro-e68a05b29de507a56b8747557707e8d6cdd68542.tar.gz 340-repo-Sowgro-e68a05b29de507a56b8747557707e8d6cdd68542.tar.bz2 340-repo-Sowgro-e68a05b29de507a56b8747557707e8d6cdd68542.zip | |
Refactor
Diffstat (limited to '')
| -rw-r--r-- | project/Core/Src/Project/parser.c | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/project/Core/Src/Project/parser.c b/project/Core/Src/Project/parser.c new file mode 100644 index 0000000..c34b3ba --- /dev/null +++ b/project/Core/Src/Project/parser.c @@ -0,0 +1,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; +} |
