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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
|
#pragma once
#include <map>
#include <vector>
#include <string>
#include <iostream>
#include <yaml-cpp/yaml.h>
#include "binarytools/BinaryWriter.h"
#include <variant>
#include <optional>
#define NONE 0xFFFF
#define ALIGN(val, al) (size_t) ((val + (al - 1)) & -al)
namespace AIFC {
enum MagicValues {
FORM = 0x464f524d,
AIFC = 0x41494643,
COMM = 0x434f4d4d,
INST = 0x494e5354,
VAPC = 0x56415043,
SSND = 0x53534e44,
AAPL = 0x4150504c,
stoc = 0x73746f63,
};
}
struct Entry {
uint32_t offset;
uint32_t length;
};
struct AudioBankSound {
uint32_t offset;
float tuning;
bool operator==(const AudioBankSound& other) const {
return offset == other.offset && tuning == other.tuning;
}
};
struct Instrument {
bool valid;
std::string name;
uint32_t offset;
uint8_t releaseRate;
uint8_t normalRangeLo;
uint8_t normalRangeHi;
uint32_t envelope;
std::optional<AudioBankSound> soundLo;
std::optional<AudioBankSound> soundMed;
std::optional<AudioBankSound> soundHi;
};
struct AdpcmBook {
int32_t order{};
int32_t npredictors{};
std::vector<int16_t> table;
bool operator==(const AdpcmBook& other) const {
return order == other.order && npredictors == other.npredictors && table == other.table;
}
};
struct Drum {
std::string name;
uint32_t offset;
uint8_t releaseRate;
uint8_t pan;
uint32_t envelope;
AudioBankSound sound;
bool operator==(const Drum& other) const {
return name == other.name && offset == other.offset && releaseRate == other.releaseRate && pan == other.pan && envelope == other.envelope && sound == other.sound;
}
};
struct AdpcmLoop {
uint32_t start{};
uint32_t end{};
int32_t count{};
uint32_t pad{};
std::optional<std::vector<int16_t>> state;
bool operator==(const AdpcmLoop& other) const {
return start == other.start && end == other.end && count == other.count && pad == other.pad && state == other.state;
}
};
struct AudioBankSample {
std::string name;
std::vector<uint8_t> data;
AdpcmBook book;
AdpcmLoop loop;
std::vector<float> tunings;
};
struct SampleBank {
std::string name;
uint32_t offset;
std::vector<uint8_t> data;
std::map<uint32_t, AudioBankSample*> entries;
AudioBankSample* AddSample(uint32_t addr, size_t sampleSize, const AdpcmBook& book, const AdpcmLoop& loop);
};
struct TBLFile {
std::vector<SampleBank*> banks;
std::vector<std::string> tbls;
std::map<std::string, SampleBank*> map;
};
struct CTLHeader {
uint32_t instruments;
uint32_t numDrums;
uint32_t shared;
};
struct AdsrEnvelope {
int16_t delay;
int16_t arg;
};
struct Envelope {
std::string name;
std::vector<AdsrEnvelope> entries;
};
struct Bank {
std::string name;
SampleBank* sampleBank;
std::vector<Instrument> insts;
std::vector<Drum> drums;
std::vector<std::variant<Instrument, std::vector<Drum>>> allInsts;
std::vector<uint32_t> instOffsets;
std::map<uint32_t, Envelope> envelopes;
std::map<uint32_t, AudioBankSample*> samples;
void print() const;
};
class AudioManager {
public:
static AudioManager* Instance;
void initialize(std::vector<uint8_t>& buffer, YAML::Node& data);
void create_aifc(int32_t index, LUS::BinaryWriter& writer);
AudioBankSample get_aifc(int32_t index);
std::map<uint32_t, Bank> get_banks();
uint32_t get_index(AudioBankSample* bank);
private:
std::map<uint32_t, Bank> banks;
std::map<AudioBankSample*, uint32_t> sampleMap;
TBLFile loaded_tbl;
static std::vector<Entry> parse_seq_file(std::vector<uint8_t>& buffer, uint32_t offset, bool isCTL);
static CTLHeader parse_ctl_header(std::vector<uint8_t>& data);
static std::optional<AudioBankSound> parse_sound(std::vector<uint8_t> data);
static Drum parse_drum(std::vector<uint8_t>& data, uint32_t addr);
static Instrument parse_inst(std::vector<uint8_t>& data, uint32_t addr);
static AdpcmLoop parse_loop(uint32_t addr, std::vector<uint8_t>& bankData);
static AdpcmBook parse_book(uint32_t addr, std::vector<uint8_t>& bankData);
static AudioBankSample* parse_sample(std::vector<uint8_t>& data, std::vector<uint8_t>& bankData, SampleBank* sampleBank);
static std::vector<AdsrEnvelope> parse_envelope(uint32_t addr, std::vector<uint8_t>& dataBank);
static Bank parse_ctl(CTLHeader header, std::vector<uint8_t> data, SampleBank* bank, uint32_t index);
static TBLFile parse_tbl(std::vector<uint8_t>& data, std::vector<Entry>& entries);
static void write_aifc(AudioBankSample* entry, LUS::BinaryWriter& writer);
};
|