-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAudiokinetics RIFF.bt
183 lines (165 loc) · 4.57 KB
/
Audiokinetics RIFF.bt
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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
//------------------------------------------------
//--- 010 Editor v11.0.1 Binary Template
//
// File:
// Authors:
// Version:
// Purpose:
// Category:
// File Mask:
// ID Bytes:
// History:
//------------------------------------------------
typedef enum<ushort>{
WWPCM = 1,
IMA = 2,
IMANew = 0x0069,
XWMA1 = 0x0161,
XWMA2 = 0x0162,
XMA2 = 0x0165,
FXMA2 = 0x0166,
AAC = 0xAAC0,
DSP = 0xFFF0,
HEVAG = 0xFFFB,
ATRAC9 = 0xFFFC,
PCM = 0xFFFE,
VORBIS = 0xFFFF,
OPUSNX = 0x3039,
OPUS = 0x3040,
OPUSWW = 0x3041,
PTADPCM = 0x8311
}WWFormat;
typedef enum<uint>{
AK_ChannelConfigType_Anonymous,
AK_ChannelConfigType_Standard,
AK_ChannelConfigType_Ambisonic,
AK_ChannelConfigType_Objects,
AK_ChannelConfigType_UseDeviceMain,
AK_ChannelConfigType_UseDevicePassthrough
}AkChannelConfigType;
typedef struct{
uint uNumChannels : 8;
AkChannelConfigType eConfigType : 4;
uint uChannelMask : 20;
}ChannelLayout;
typedef struct{
uint dwLoopStartPacketOffset;
uint dwLoopEndPacketOffset;//some form of ending information, changes with fileSize
ushort uLoopBeginExtra;
ushort uLoopEndExtra;
}LoopInfo;
typedef struct{
uint dwTotalPCMFrames;
LoopInfo loopInfo;//despite what it is called, this is not true loop information generally
uint dwSeekTableSize;//within data block
uint dwVorbisDataOffset;//within data block
ushort uMaxPacketSize;//not including header
ushort uLastGranuleExtra;//should be small
uint dwDecodeAllocSize;
uint dwDecodeX64AllocSize;
uint uCommonHash;//potentially referred to by vgmstream as uHashCodebook
ubyte uBlockSizes[2];//only the last two are used by vgmstream, first 4 may be something else entirely
}AK_Header;
typedef struct{
WWFormat Format;
short channels;
int sampleRate;
int averageBps;
short blockAlign;
short bitsPerSample;
short extraSize;
if(extraSize == 0x30){
short unknChannelInfo;//some form of channel layout, becomes 0x10 when 6 channels are present, but 0x00 with only 2
ChannelLayout channelLayout;
AK_Header wemHeader;
}
else{
byte extraData[extraSize];
};
}FMT;
typedef struct{
float unkn1;
float unkn2;//only confirmed one out of the four
float unkn3;
float unkn4;
}AKD;
typedef struct(int length){
byte junk[length];//a pure filler struct for alignment
}JUNK;
typedef struct{
uint CueId;
int PlayPosition;
char chunkId[4];
uint chunkStart;
uint blockStart;
uint sampleStart;
}CuePoint;
typedef struct{
int NumCuePoints;
CuePoint cues[NumCuePoints];
}CUE;
typedef struct{
char labl[4];
int length;
uint CuePointId;
local int stringLength = length-4;
if(stringLength%2 != 0){
stringLength++;
};
char Label[stringLength];
}LABL;
typedef struct(int length){
local int EndOff = FTell()+length;
char adtl[4];//typeId, always adtl
while(FTell() < EndOff){
LABL labl<optimize=false>;
};
}LIST;
typedef struct{
char fmt[4];
int length;
switch(fmt){
case "fmt ": //may need to read as uint
FMT FormatHeader;
break;
case "akd ":
AKD AudioKinecticsData;//the AK is almost definitely Audiokinetics, dunno what the d stands for
break;
case "JUNK":
JUNK JunkAlignment(length)<optimize=false>;
break;
case "cue ":
CUE CuePointList;
break;
case "LIST":
LIST AssociatedDataList(length)<optimize=false>;
break;
//not putting data in this, as data itself is just raw bytes
default:
byte chunkData[length];
break;
};
}WavChunk;
typedef struct(int RIFFSize){
local uint startOffset = FTell();
while(FTell() < startOffset+RIFFSize){
//Printf("%i %i\n",FTell(), startOffset+RIFFSize+8);
WavChunk chunk<optimize=false>;
};
}WAVE;
typedef struct{
/* RIFF is a chunk-based recursive format that utilizes many different smaller types of formats
WWise uses an edited version of the WAVE variation of RIFF, which in itself contains several chunks*/
char RIFF[4];
int RIFFSize;
char RIFFFormat[4];
if(RIFFFormat == "WAVE"){
WAVE WavHeader(RIFFSize-4);
};
}RIFF;
if(ReadUInt(0x00) == 1179011410||ReadUInt(0x00) == 1481001298){//RIFF/RIFX
if (ReadUInt(0x00) == 1481001298){
BigEndian();
};
RIFF riff;//protection allowing it to be used in BNK and PCK templates
};