Anonymous

Changes

From Final Fantasy Inside

FF7/PSX/Sound/AKAO sequence

382 bytes added, 22:24, 31 October 2020
no edit summary
== Introduction ==
AKAO frames are sequence is the most complicated frames in part of the FF7 sound system. ("AKAO" is frame magicthe signature string, probably which implies that the sound format has developed by Minoru Akao, Square Enix sound programmer :) Minoru Akao.)
Frame AKAO sequence is similar to MIDI sequence - it's custom tracker format for playing sequence sound, well tuned specially for PSX.
This frames are The sequence data can be found in all FF7 game modules: Field, Battle, Worldmap and in minigames.
All files with exension *.SND are AKAO.
* '''MOVIE/OVER2.SND''' - same game over sequence, don't know, why to duplicate data
Other AKAO frames sequences are hard-wired in other files.
== AKAO frame structure File Structure ==
=== Header (size: 16 bytes) ===
struct AkaoHeaderAkaoSeqHeader
{
static const uint8_t magic[4]; // "AKAO" C-string aka frame *MAGIC* uint16_t id; // frame song ID, used for playing sequence uint16_t length; // frame data length - sizeof(header)
uint16_t reverb_type; // reverb type (range from 0 to 9)
struct AkaoTimeStamp timestamp; // creation time }; struct AkaoTimeStamp { uint8_t year_bcd; // year (in binary coded decimal) uint8_t month_bcd; // month (in binary coded decimal, between 0x01 - 0x12) uint8_t day_bcd; // day (in binary coded decimal, between 0x01 - 0x31) uint8_t hours_bcd; // hours (in binary coded decimal, between 0x00 - 0x23) uint8_t minutes_bcd; // minutes (in binary coded decimal, between 0x00 - 0x59) uint8_t seconds_bcd; // seconds (in binary coded decimal, between 0x00 - 0x59) } timestamp;
};
=== Channel info Info (size: 4 bytes + 2 bytes * <channels count>) ===
struct AkaoChannelInfo
{
uint32_t mask; // represents bitmask of used channels in this framesong uint32_t uint16_t start_offsets[num_channels]; // offsets to channel opcode data
};
int num_channels = 0;
while (int bit = 0; bit < 24; bit++) if ((info.mask & 0xFFFFFF) & (1 << bit)) != 0; bit++) num_channels++; First there is 32-bit number (offset 0x10), which represents bitmask of used channels in this song. After this bitmask, there is <channels count> offsets to channel opcode data counting from current offset. Each offsets is a relative offset based on the address *next to* the offset itself. (This is a general rule for early versions of AKAO to interpret relative offsets.)
First === Channel Commands [AKAO Opcodes] ===For every channels in an AKAO sequence, there is 32-bit a set of commands to perform. This is similar to Field opcodes. Here I will call this sound commands "opcodes". Every opcode has its own number of arguments (offset 0x10from no-arguments, to 3 arguments), which represents bitmask of used channels in this frame.
After this frame, there is <channels count> offsets to channel opcode data counting from current offset. Each offsets is a relative offset based on the address *next to* the offset itself. (This is a general rule for early versions of AKAO to interpret relative offsets.)=== Drum Instrument Map Table ===
When a song uses a drum kit with [[FF7/PSX/Sound/Opcodes/0xeced|opcode 0xEC]], a drum instrument map table will be placed at the end of the sequence. The table determines the instrument, channel volume and pan for each keys.
=== Channel Commands [AKAO Opcodes] ===Most complicated partThe table consists of a repetition of 5-byte items.
For every channel in AKAO frame there is set of commands struct AkaoDrumKeyAttr { uint8_t instrument; // corresponding to perform. This is similar opcode 0xA1 uint8_t key; // note number when playing the drum note uint16_t volume; // corresponding to Field opcodes. Here I'll call this sound commands "opcodes". Every opcode has it's own number 0xA8 (lower 8bit is a fractional part of arguments (from no-arguments, the volume) uint8_t pan; // corresponding to 3 arguments).opcode 0xAA }
== Example (homeHome-created Created AKAO frameSequence): ==
=== Header ===
'''41 4b 41 4f''' - AKAO string
'''34 12''' - frame song ID: 0x1234
'''16 00''' - frame data length 0x16 in hex or 22 in decimal
'''04 00''' - reverb type: 4 (large studio)
'''96 12 18 22 46 28''' - unknown datacreated at 1996-12-18 22:46:28
=== Channel info Info ===
'''01 00 00 00''' - this indicates, that used only one channel
=== Channel commands Commands ===
'''e8 a8 66''' - sets tempo, parameter 0x66a8
== Sound Opcode list List ==
{| class="wikitable"
|0x9A-0x9F
|Unimplemented
|n/a1|n/a
|Should not be used.
|-
|Load Instrument
|2
|instrument: byte(0-127)
|
|-
|-
|[[FF7/PSX/Sound/Opcodes/0xb4b5|0xB4]]
|Vibrato (Channel Pitch LFO (Vibrato)
|4
|delay: byte, rate: byte, type: byte (0-15)
|When <code>rate</code> is 0, it will be translated to 256 ticks.
The interpretation of the first parameter may change to depth depending on 0xF3.
|-
|[[FF7/PSX/Sound/Opcodes/0xb4b5|0xB5]]
|Channel Pitch LFO Vibrato Depth
|2
|depth: byte
|-
|[[FF7/PSX/Sound/Opcodes/0xb4b5|0xB6]]
|Turn Off Channel Pitch LFOVibrato
|1
|
|-
|[[FF7/PSX/Sound/Opcodes/0xb8b9|0xB8]]
|Tremolo (Channel Volume LFO (Tremolo)
|4
|delay: byte, rate: byte, type: byte (0-15)
|When <code>rate</code> is 0, it will be translated to 256 ticks.
The interpretation of the first parameter may change to depth depending on 0xF3.
|-
|[[FF7/PSX/Sound/Opcodes/0xb8b9|0xB9]]
|Channel Volume LFO Tremolo Depth
|2
|depth: byte
|-
|[[FF7/PSX/Sound/Opcodes/0xb8b9|0xBA]]
|Turn Off Channel Volume LFOTremolo
|1
|
|-
|[[FF7/PSX/Sound/Opcodes/0xdd|0xDD]]
|Channel Pitch LFO Vibrato Depth Slide
|3
|length: byte, depth: byte
|-
|[[FF7/PSX/Sound/Opcodes/0xde|0xDE]]
|Channel Volume LFO Tremolo Depth Slide
|3
|length: byte, depth: byte
|3
|drum_map_offset: signed int16
|The <code>drum_map_offset</code> is a relative offset pointing to the drum instrument map table that maps , which determines the instrument and articulation for each keys.
|-
|[[FF7/PSX/Sound/Opcodes/0xeced|0xED]]
|-
|[[FF7/PSX/Sound/Opcodes/0xf3|0xF3]]
|Use No Delay for Channel Pitch/Volume LFOUnknown
|1
|
|Specific to FF7. This instruction changes the interpretation of the 0xB4 and 0xB8 parameters. There is no actual use in music.
|-
|[[FF7/PSX/Sound/Opcodes/0xf4f5|0xF4]]
|-
|[[FF7/PSX/Sound/Opcodes/0xf4f5|0xF6]]
|Overlay Volume Balance of Overlay Voice
|2
|balance: byte (0-127)
|-
|[[FF7/PSX/Sound/Opcodes/0xf4f5|0xF7]]
|Overlay Volume Balance Slide of Overlay Voice
|3
|length: byte, balance: byte (0-127)
|[[FF7/PSX/Sound/Opcodes/0xfe|0xFE]]
|Measure Number
|23|measure: byteshort
|
|-
17
edits