/* * player.c * * Created on: Nov 25, 2025 * Author: sowgro */ #include "endian_converters.h" #include #include "endian_converters.h" #include "hw8.h" #include "activity4.h" #include "song_info.h" #define NOTE_OFF_EVENT (0) #define NOTE_ON_EVENT (1) #define KEY_PRESSURE (2) typedef struct { uint8_t ev_type; uint32_t abs_time; uint8_t key_number; uint8_t value; } note_event_t; 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 song_info_t song_info; p_song = get_song_info(p_song, &song_info); note_event_t trackEvents[header.ntrcks][1024]; for(int i = 0; i < header.ntrcks; i++){ p_song = parse_track(p_song, trackEvents[i]); } } uint8_t parse_track(uint8_t *p_song, note_event_t *events) { 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++; events[curEvent++] = note; } events[curEvent] = 0; // null terminate array return p_song; }