yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
spc_parser.h
Go to the documentation of this file.
1#ifndef YAZE_ZELDA3_MUSIC_SPC_PARSER_H
2#define YAZE_ZELDA3_MUSIC_SPC_PARSER_H
3
4#include <cstdint>
5#include <vector>
6
7#include "absl/status/statusor.h"
8#include "rom/rom.h"
11
12namespace yaze {
13namespace zelda3 {
14namespace music {
15
16// ROM offsets for sound bank block headers (from usdasm disassembly)
17// Each bank has a block header: [size:2][aram_addr:2][data:size]
18//
19// Banks 0, 1, 3 are contiguous starting at $19:8000 (PC 0xC8000)
20// Bank 2 (dungeon) is separate at $1B:8000 (PC 0xD8000)
21//
22// Song table blocks (loading to ARAM $D000):
23// - Overworld: $1A:9EF5 (PC 0xD1EF5)
24// - Dungeon: $1B:8000 (PC 0xD8000)
25// - Credits: $1A:D380 (PC 0xD5380)
26constexpr uint32_t kSoundBankOffsets[] = {
27 0xC8000, // Bank 0 (common) - start of contiguous region
28 0xD1EF5, // Bank 1 (overworld) - song table block
29 0xD8000, // Bank 2 (dungeon) - separate region
30 0xD5380 // Bank 3 (credits) - song table block
31};
32
44class SpcParser {
45 public:
49 struct ParseContext {
50 Rom* rom = nullptr;
51 uint8_t current_bank = 0;
52 uint32_t bank_offset = 0;
53
54 // Parsing state
55 std::vector<uint16_t> visited_addresses; // Prevent infinite loops
56 int max_parse_depth = 100;
58 };
59
60 // =========================================================================
61 // Song Parsing
62 // =========================================================================
63
71 static absl::StatusOr<MusicSong> ParseSong(Rom& rom, uint16_t address,
72 uint8_t bank);
73
82 static absl::StatusOr<std::vector<uint16_t>> ReadSongPointerTable(
83 Rom& rom, uint16_t table_address, uint8_t bank, int max_entries = 40);
84
93 static absl::StatusOr<MusicTrack> ParseTrack(Rom& rom, uint16_t address,
94 uint8_t bank,
95 int max_ticks = 50000);
96
97 // =========================================================================
98 // Address Resolution
99 // =========================================================================
100
108 static uint32_t SpcAddressToRomOffset(Rom& rom, uint16_t spc_address,
109 uint8_t bank);
110
119 static const uint8_t* GetSpcData(Rom& rom, uint16_t spc_address, uint8_t bank,
120 int* out_length = nullptr);
121
122 // =========================================================================
123 // Command Utilities
124 // =========================================================================
125
131 static int GetCommandParamCount(uint8_t opcode) {
132 if (opcode < 0xE0)
133 return 0;
134 return kCommandParamCount[opcode - 0xE0];
135 }
136
140 static bool IsNotePitch(uint8_t byte) {
141 return byte >= kNoteMinPitch && byte <= kNoteRest;
142 }
143
147 static bool IsDuration(uint8_t byte) { return byte < 0x80; }
148
152 static bool IsCommand(uint8_t byte) { return byte >= 0xE0; }
153
154 private:
155 // Internal parsing with context
156 static absl::StatusOr<MusicTrack> ParseTrackInternal(ParseContext& ctx,
157 uint16_t address,
158 int max_ticks);
159
160 // Parse subroutine call
161 static absl::StatusOr<int> ParseSubroutine(ParseContext& ctx,
162 uint16_t address, int repeat_count,
163 int remaining_ticks);
164};
165
171class BrrCodec {
172 public:
179 static std::vector<int16_t> Decode(const std::vector<uint8_t>& brr_data,
180 int* loop_start = nullptr);
181
188 static std::vector<uint8_t> Encode(const std::vector<int16_t>& pcm_data,
189 int loop_start = -1);
190
191 private:
192 // Filter coefficients for BRR decoding
193 static constexpr int kFilter1[4] = {0, 15, 61, 115};
194 static constexpr int kFilter2[4] = {0, 4, 5, 6};
195 static constexpr int kFilter3[4] = {0, 0, 15, 13};
196};
197
198} // namespace music
199} // namespace zelda3
200} // namespace yaze
201
202#endif // YAZE_ZELDA3_MUSIC_SPC_PARSER_H
The Rom class is used to load, save, and modify Rom data. This is a generic SNES ROM container and do...
Definition rom.h:24
BRR sample encoder/decoder.
Definition spc_parser.h:171
static constexpr int kFilter2[4]
Definition spc_parser.h:194
static std::vector< int16_t > Decode(const std::vector< uint8_t > &brr_data, int *loop_start=nullptr)
Decode BRR data to PCM samples.
static std::vector< uint8_t > Encode(const std::vector< int16_t > &pcm_data, int loop_start=-1)
Encode PCM samples to BRR format.
static constexpr int kFilter3[4]
Definition spc_parser.h:195
static constexpr int kFilter1[4]
Definition spc_parser.h:193
Parser for N-SPC music data from ROM.
Definition spc_parser.h:44
static bool IsDuration(uint8_t byte)
Check if a byte is a duration value (< 128).
Definition spc_parser.h:147
static bool IsCommand(uint8_t byte)
Check if a byte is a command opcode.
Definition spc_parser.h:152
static absl::StatusOr< MusicSong > ParseSong(Rom &rom, uint16_t address, uint8_t bank)
Parse a complete song from ROM.
Definition spc_parser.cc:16
static bool IsNotePitch(uint8_t byte)
Check if a byte is a note pitch.
Definition spc_parser.h:140
static absl::StatusOr< std::vector< uint16_t > > ReadSongPointerTable(Rom &rom, uint16_t table_address, uint8_t bank, int max_entries=40)
Read the song pointer table for a given SPC bank.
static const uint8_t * GetSpcData(Rom &rom, uint16_t spc_address, uint8_t bank, int *out_length=nullptr)
Get a pointer to ROM data at an SPC address.
static absl::StatusOr< MusicTrack > ParseTrackInternal(ParseContext &ctx, uint16_t address, int max_ticks)
static absl::StatusOr< int > ParseSubroutine(ParseContext &ctx, uint16_t address, int repeat_count, int remaining_ticks)
static absl::StatusOr< MusicTrack > ParseTrack(Rom &rom, uint16_t address, uint8_t bank, int max_ticks=50000)
Parse a single track from ROM.
static int GetCommandParamCount(uint8_t opcode)
Get the parameter count for an N-SPC command.
Definition spc_parser.h:131
static uint32_t SpcAddressToRomOffset(Rom &rom, uint16_t spc_address, uint8_t bank)
Convert an SPC address to a ROM offset.
constexpr uint8_t kNoteRest
Definition song_data.h:58
constexpr uint8_t kNoteMinPitch
Definition song_data.h:55
constexpr int kCommandParamCount[32]
Definition song_data.h:19
constexpr uint32_t kSoundBankOffsets[]
Definition spc_parser.h:26
Context for parsing operations.
Definition spc_parser.h:49
std::vector< uint16_t > visited_addresses
Definition spc_parser.h:55