-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathadx.h
159 lines (131 loc) · 3.93 KB
/
adx.h
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
#pragma once
// reference: https://en.wikipedia.org/wiki/ADX_(file_format)
#include <cstdint>
#include <winsock.h>
// note: BIG ENDIAN
constexpr auto ADX_SIGNATURE = 0x8000;
constexpr auto ADX_COPYRIGHT_SIGNATURE = "(c)CRI";
enum class ADXEncodingType : uint8_t
{
ADX_FIXED_COEF = 0x02,
ADX_LINEAR_SCALE = 0x03,
ADX_EXP_SCALE = 0x04,
ADX_AHX_10 = 0x10,
ADX_AHX_11 = 0x11,
};
enum class ADXVersion : uint8_t
{
ADX_VERSION_3 = 0x03,
ADX_VERSION_4 = 0x04,
ADX_VERSION_5 = 0x05,
};
constexpr auto ADX_HEADER_SIZE = 0x14; // 20
constexpr auto ADX_V3_HEADER_SIZE = 0x2c; // 44
constexpr auto ADX_V4_HEADER_SIZE = 0x38; // 56
constexpr auto ADX_V3_PART_SIZE = (ADX_V3_HEADER_SIZE - ADX_HEADER_SIZE);
constexpr auto ADX_V4_PART_SIZE = (ADX_V4_HEADER_SIZE - ADX_HEADER_SIZE);
struct ADXheaderCommon
{
uint16_t sig_8000; // 0x8000
uint16_t copyright_offset; // if == 0x14, there's no loop info
ADXEncodingType encoding_type;
uint8_t block_size; // typ. 18
uint8_t sample_bitdepth; // typ. 4
uint8_t channel_count;
uint32_t sample_rate;
uint32_t total_samples;
// 0x10
uint16_t highpass_frequency;
ADXVersion version;
uint8_t flags; // 0x08: encrypted in XOR
void prepare()
{
sig_8000 = ntohs(sig_8000);
copyright_offset = ntohs(copyright_offset);
sample_rate = ntohl(sample_rate);
total_samples = ntohl(total_samples);
highpass_frequency = ntohs(highpass_frequency);
}
};
static_assert(sizeof(ADXheaderCommon) == ADX_HEADER_SIZE, "sizeof ADX common common is not 20 bytes. maybe padding?");
struct ADXheaderV3
{
// 0x14
uint16_t loop_alignment_samples;
uint16_t loop_enabled_1;
uint32_t loop_enabled_2;
uint32_t loop_begin_sample_index;
// 0x20
uint32_t loop_begin_byte_index;
uint32_t loop_end_sample_index;
uint32_t loop_end_byte_index;
inline void prepare()
{
loop_alignment_samples = ntohs(loop_alignment_samples);
loop_enabled_1 = ntohs(loop_enabled_1);
loop_enabled_2 = ntohl(loop_enabled_2);
loop_begin_sample_index = ntohl(loop_begin_sample_index);
loop_begin_byte_index = ntohl(loop_begin_byte_index);
loop_end_sample_index = ntohl(loop_end_sample_index);
loop_end_byte_index = ntohl(loop_end_byte_index);
}
};
static_assert(sizeof(ADXheaderV3) == ADX_V3_PART_SIZE, "sizeof ADX V3 common is not 0x2c bytes. maybe padding?");
struct ADXheaderV4
{
// 0x14
uint8_t reserved[16];
// 0x24
uint32_t loop_enabled;
uint32_t loop_begin_sample_index;
uint32_t loop_begin_byte_index;
// 0x30
uint32_t loop_end_sample_index;
uint32_t loop_end_byte_index;
inline void prepare()
{
loop_enabled = ntohl(loop_enabled);
loop_begin_sample_index = ntohl(loop_begin_sample_index);
loop_begin_byte_index = ntohl(loop_begin_byte_index);
loop_end_sample_index = ntohl(loop_end_sample_index);
loop_end_byte_index = ntohl(loop_end_byte_index);
}
};
static_assert(sizeof(ADXheaderV4) == ADX_V4_PART_SIZE, "sizeof ADX V4 common is not 0x38 bytes. maybe padding?");
struct ADXheader
{
ADXheaderCommon common;
union
{
ADXheaderV3 v3;
ADXheaderV4 v4;
};
inline void prepare()
{
common.prepare();
switch (common.version)
{
case ADXVersion::ADX_VERSION_3:
v3.prepare();
break;
case ADXVersion::ADX_VERSION_4:
case ADXVersion::ADX_VERSION_5:
v4.prepare();
break;
}
}
};
static_assert(sizeof(ADXheader) == ADX_V4_HEADER_SIZE, "sizeof ADXheader is not 0x38 bytes. maybe padding?");
// https://azuco.sakura.ne.jp/column/ag_adx/cri.html
// note: AFS is in LITTLE ENDIAN
constexpr auto AFS_SIGNATURE = "AFS\0";
struct AFSheader
{
char signature[4]; // "AFS\0"
uint32_t num_of_files;
};
struct AFSitem
{
uint32_t offset;
uint32_t length;
};