AAF
AAF stores sound effect, wave, instrument, and music data.
Contents
AAF Header
The file's headers is composed to several int32's packed in a common format.
The first int32 will always read the ID of a section. When you read 0, you stop reading.
Header Entry Structure
id | Structure | Description |
---|---|---|
|
(none) | Tells to stop reading this section |
|
(int32 offset, int32 size, int32 type) | Pointer to the BST (Binary Sound Table) |
|
(int32 offset, int32 size, int32 flags) until offset = 0 then continue | IBNK Pointer Table |
|
(int32 offset, int32 size, int32 flags) until offset = 0 then continue | WSYS Pointer Table |
|
(int32 offset, int32 size, int32 type) | Pointer to BSC (Binary Sequence Collection) |
|
(int32 offset, int32 size, int32 type) | Pointer to the BSM (Binary Stream Map) |
Sample Parsing Code
while (true) { var ChunkID = aafRead.ReadUInt32(); switch (ChunkID) { case 0: return; case 1: case 5: case 4: case 6: case 7: { offset = aafRead.ReadUInt32(); size = aafRead.ReadUInt32(); type = aafRead.ReadUInt32(); break; } case 2: // INST { while (true) { var offset = aafRead.ReadUInt32(); if (offset == 0) break; // 0 means we reached the end. var size = aafRead.ReadUInt32(); var type = aafRead.ReadUInt32(); } } break; case 3: // WSYS { while (true) { var offset = aafRead.ReadUInt32(); if (offset == 0) break; // 0 means we reached the end. var size = aafRead.ReadUInt32(); var type = aafRead.ReadUInt32(); } break; } } }
IBNK
IBNK Stands for "Instrument Bank". It holds the parameters required to play one of the sounds out of the WSYS as a melodic instrument. They can also contain sound effects. All pointers are relative to the 0th byte of the IBNK
Header
Offset | Type | Name | Description |
---|---|---|---|
|
int32 | 0x49424e4b 'IBNK' | Magic |
|
int32 | Size | Size of the IBNK |
|
int32 | ID | Global IBNK ID |
|
int32 | Flags | Flags |
|
byte[0x14] | Padding | Padding |
|
int32 | 0x42414E4B 'BANK' | Magic |
|
int32*[0xF0] | Instrument Pointers | Pointers to instrument objects (0 = empty slot) |
INST
Offset | Type | Name | Description |
---|---|---|---|
|
int32 | 0x494E5354 'INST' | Magic |
|
int32 | 0 | Zero (Padding) |
|
float | frequencyMultiplier | Frequency Multiplier |
|
float | gainMultiplier | gainMultiplier |
|
int32* | Osc1* | Pointer to first JOscillator (0 = null) |
|
int32* | Osc2* | Pointer to second JOscillator(0 = null) |
|
int32* | Eff1* | Pointer to first Effect (0 = null) |
|
int32* | Eff2* | Pointer to second Effect (0 = null) |
|
int32* | Sen1* | Pointer to first sensor (0 = null) |
|
int32* | Sen2* | Pointer to second swnsor (0 = null) |
|
int32 | keyRegionCount | Count of key regions |
|
InstrumentKeyRegion*[keyRegionCount] | Key Regions | int32 pointers to key regions |
InstrumentKeyRegion
Container for an instruments keys. Usually there's only one. The "root key" item defines the key this specific key object is assigned to. By default, it starts at 0. The next definition fills all the keys in betwen, meaning if the next root key was 127, the keys at 0-127 would be assigned to that region.
A single key has two parts to it. The note, and the velocity. The note is specified by the key region, and the velocity regions are defined by attaching them to key regions.
Velocity regions, being the final part of the sound, handle the finetuning, and wave selection.
Offset | Type | Name | Description |
---|---|---|---|
|
byte | bKey | base Key |
|
byte[3] | padding | padding |
|
int32 | velocityRegionCount | Count of velocity regions |
|
InstrumentVeloRegion*[velocityRegionCount] | velregptr | Int32 pointers to each velocity region. |
InstrumentVeloRegion
The velocity region of a KeyRegion. The "root velocity" operates identically to the Key Region.
Offset | Type | Name | Description |
---|---|---|---|
|
byte | bKey | root velocity |
|
byte[3] | padding | padding |
|
short | wsysID | WSYS that the sound for this instrument is in. |
|
short | waveID | WaveID in the WSYS that the sound for this instrument is in. |
|
float | gainMultFT | Finetune float for gain / volume |
|
float | freqMultFT | Finetune float for pitch / frequency |
PER2
A type of INST that doesn't have a pitch or gain on the main instrument, or as many features (like oscillators)
Offset | Type | Name | Description |
---|---|---|---|
|
int32 | 0x50455232 'PER2' | Magic |
|
byte[0x84] | 0 | Unused |
|
PercussionKey*[100] | 100 percussion entries | Int32 pointers to percussion keys |
PercussionKey
Key type for PER2's instrument data (Not regioned)
Offset | Type | Name | Description |
---|---|---|---|
|
float | pitch | Finetune Pitch |
|
float | volume | Finetune Gain |
|
byte[8] | unused | unused |
|
int32 | velocityRegionCount | Count of velocity regions |
|
InstrumentVeloRegion*[velocityRegionCount] | velregptr | Int32 Pointers to each velocity region. |
JOscillator
JAITOscillator is an internal name. It stands for JAudioInterface:TOscillator.
They have no header data, and no other identifying data. , they are pointed to directly by INST objects.
The width and vertex operators are used mainly for effects like vibrato.
Offset | Type | Name | Description |
---|---|---|---|
|
byte | JOscillatorMode | Mode / Target |
|
byte[3] | padding | padding |
|
float | rate | rate |
|
int32* | attackEnvOffset | Int32 pointer to attack JEnvelope |
|
int32* | releaseEnvOffset | Int32 pointer to release JEnvelope |
|
float | width | Width of the oscillator |
|
float | vertex | Vertex of the oscillator |
JOscillatorMode
Different modes that the JOscillator can target.
mode | Name | Desc |
---|---|---|
|
Volume | Changes volume of instrument |
|
Pitch | Changes pitch of instrument |
|
Pan | Changes pan of instrument |
|
FX | Changes filter |
|
Dolby | (Unused) for digital sound output / dolby surround |
JEnvelope
JEnvelopes are only referenced by a JOscillator.
Similar to their parent, they have no identifying header data. In addition, they have no static length. They are ended by an end marker (Which in practice, will require a double scan)
A JEnvelope is composed of vectors with modes with a structure as follows:
Offset | Type | Name | Description |
---|---|---|---|
|
short | JEnvelopeMode | Mode selection for this vector |
|
short | time | Time that this takes place (In ticks) |
|
short | value | Value of this vector at this time |
|
int32 | velocityRegionCount | Count of velocity regions |
JEnvelopeMode
mode | Name | Desc |
---|---|---|
|
Linear | Linear approach to the next vector value |
|
Square | Square curve approach to the next vector value |
|
Square | Square Root (n^0.5) curve approach to the next vector value |
|
SampleCell | Unknown, (Unused?) |
|
Loop | Command vector, defines a loop point |
|
Hold | Pauses the envelope, usually used after it completes |
|
Stop | Stops both the instrument and the envelope |
WSYS
Internally, Wave System.
This section contains all of the information required for decoding the AW File as well as other information for melodic tuning, root key, and other various parts of JAudio.
Offset | Type | Name | Description |
---|---|---|---|
|
int32 | 0x57535953 'WSYS' | Magic |
|
int32 | size | WSYS Size |
|
int32 | wsysID | WSYS ID (This is how insts select the wsys) |
|
int32 | flags | Flags |
|
int32 | [[AAF#WINF | WINF Pointer]] |
|
int32 | [[AAF#WINF | WBCT Pointer]] |
WINF
WINF is a pointer container. They point to the Wave Groups.
The ID's for every wave group are controlled by the | SCNE object. They line up, WaveGroup[1] uses WaveScenes[1]
Offset | Type | Name | Description |
---|---|---|---|
|
int32 | 0x57494E46 'INF' | Magic |
|
int32 | waveGroupCount | Count of wavegroups |
|
WaveGroup*[] (int32) | waveGroupPointers | Pointers to the individual wavegroups. |