Difference between revisions of "FF7/PSX/Sound/AKAO sequence"
Line 107: | Line 107: | ||
! Length | ! Length | ||
! Operands | ! Operands | ||
+ | ! Note | ||
|- | |- | ||
|[[FF7/PSX/Sound/Opcodes/0xa0|0xA0]] | |[[FF7/PSX/Sound/Opcodes/0xa0|0xA0]] | ||
|Finish Channel | |Finish Channel | ||
|1 | |1 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 117: | Line 119: | ||
|2 | |2 | ||
|u8 instrument | |u8 instrument | ||
+ | | | ||
|- | |- | ||
|[[FF7/PSX/Sound/Opcodes/0xa2|0xA2]] | |[[FF7/PSX/Sound/Opcodes/0xa2|0xA2]] | ||
Line 122: | Line 125: | ||
|2 | |2 | ||
|u8 delta_time | |u8 delta_time | ||
+ | | | ||
|- | |- | ||
|[[FF7/PSX/Sound/Opcodes/0xa8aa|0xA3]] | |[[FF7/PSX/Sound/Opcodes/0xa8aa|0xA3]] | ||
Line 127: | Line 131: | ||
|2 | |2 | ||
|u8 volume | |u8 volume | ||
+ | | | ||
|- | |- | ||
|[[FF7/PSX/Sound/Opcodes/0xa4|0xA4]] | |[[FF7/PSX/Sound/Opcodes/0xa4|0xA4]] | ||
Line 132: | Line 137: | ||
|3 | |3 | ||
|u8 length, s8 semitones | |u8 length, s8 semitones | ||
+ | | | ||
|- | |- | ||
|[[FF7/PSX/Sound/Opcodes/0xa5|0xA5]] | |[[FF7/PSX/Sound/Opcodes/0xa5|0xA5]] | ||
Line 137: | Line 143: | ||
|2 | |2 | ||
|u8 octave | |u8 octave | ||
+ | | | ||
|- | |- | ||
|[[FF7/PSX/Sound/Opcodes/0xa6|0xA6]] | |[[FF7/PSX/Sound/Opcodes/0xa6|0xA6]] | ||
|Increase Octave | |Increase Octave | ||
|1 | |1 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 146: | Line 154: | ||
|Decrease Octave | |Decrease Octave | ||
|1 | |1 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 152: | Line 161: | ||
|2 | |2 | ||
|u8 volume | |u8 volume | ||
+ | | | ||
|- | |- | ||
|[[FF7/PSX/Sound/Opcodes/0xa9|0xA9]] | |[[FF7/PSX/Sound/Opcodes/0xa9|0xA9]] | ||
− | | | + | |Channel Volume Slide |
|3 | |3 | ||
+ | |u8 length, u8 volume | ||
| | | | ||
|- | |- | ||
Line 162: | Line 173: | ||
|2 | |2 | ||
|u8 pan | |u8 pan | ||
+ | |64 is the center | ||
|- | |- | ||
|[[FF7/PSX/Sound/Opcodes/0xab|0xAB]] | |[[FF7/PSX/Sound/Opcodes/0xab|0xAB]] | ||
− | | | + | |Channel Pan Slide |
|3 | |3 | ||
+ | |u8 length, u8 pan | ||
| | | | ||
|- | |- | ||
|[[FF7/PSX/Sound/Opcodes/0xac|0xAC]] | |[[FF7/PSX/Sound/Opcodes/0xac|0xAC]] | ||
− | | | + | |Noise Clock Frequency |
|2 | |2 | ||
+ | |u8 clock | ||
| | | | ||
|- | |- | ||
|[[FF7/PSX/Sound/Opcodes/0xad|0xAD]] | |[[FF7/PSX/Sound/Opcodes/0xad|0xAD]] | ||
− | | | + | |ADSR: Attack Rate |
|2 | |2 | ||
+ | |u8 attack_rate | ||
| | | | ||
|- | |- | ||
|[[FF7/PSX/Sound/Opcodes/0xae|0xAE]] | |[[FF7/PSX/Sound/Opcodes/0xae|0xAE]] | ||
− | | | + | |ADSR: Decay Rate |
|2 | |2 | ||
+ | |u8 decay_rate | ||
| | | | ||
|- | |- | ||
|[[FF7/PSX/Sound/Opcodes/0xaf|0xAF]] | |[[FF7/PSX/Sound/Opcodes/0xaf|0xAF]] | ||
− | | | + | |ADSR: Sustain Level |
|2 | |2 | ||
+ | |u8 sustain_level | ||
| | | | ||
|- | |- | ||
|[[FF7/PSX/Sound/Opcodes/0xb0|0xB0]] | |[[FF7/PSX/Sound/Opcodes/0xb0|0xB0]] | ||
− | | | + | |ADSR: Decay Rate & Sustain Level |
|3 | |3 | ||
+ | |u8 decay_rate, u8 sustain_level | ||
| | | | ||
|- | |- | ||
|[[FF7/PSX/Sound/Opcodes/0xb1|0xB1]] | |[[FF7/PSX/Sound/Opcodes/0xb1|0xB1]] | ||
− | | | + | |ADSR: Sustain Rate |
|2 | |2 | ||
+ | |u8 sustain_rate | ||
| | | | ||
|- | |- | ||
|[[FF7/PSX/Sound/Opcodes/0xb2|0xB2]] | |[[FF7/PSX/Sound/Opcodes/0xb2|0xB2]] | ||
− | | | + | |ADSR: Release Rate |
|2 | |2 | ||
+ | |u8 release_rate | ||
| | | | ||
|- | |- | ||
|[[FF7/PSX/Sound/Opcodes/0xb3|0xB3]] | |[[FF7/PSX/Sound/Opcodes/0xb3|0xB3]] | ||
+ | |Reset ADSR | ||
+ | |1 | ||
| | | | ||
− | |||
| | | | ||
|- | |- | ||
Line 211: | Line 232: | ||
| | | | ||
|4 | |4 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 216: | Line 238: | ||
| | | | ||
|2 | |2 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 221: | Line 244: | ||
| | | | ||
|1 | |1 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 226: | Line 250: | ||
| | | | ||
|2 | |2 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 231: | Line 256: | ||
| | | | ||
|4 | |4 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 236: | Line 262: | ||
| | | | ||
|2 | |2 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 241: | Line 268: | ||
| | | | ||
|1 | |1 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 246: | Line 274: | ||
| | | | ||
|2 | |2 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 251: | Line 280: | ||
| | | | ||
|3 | |3 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 256: | Line 286: | ||
| | | | ||
|2 | |2 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 261: | Line 292: | ||
| | | | ||
|1 | |1 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 266: | Line 298: | ||
| | | | ||
|2 | |2 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 271: | Line 304: | ||
| | | | ||
|2 | |2 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 276: | Line 310: | ||
| | | | ||
|2 | |2 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 281: | Line 316: | ||
|Turn On Reverb | |Turn On Reverb | ||
|1 | |1 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 286: | Line 322: | ||
| | | | ||
|1 | |1 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 291: | Line 328: | ||
| | | | ||
|1 | |1 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 296: | Line 334: | ||
| | | | ||
|1 | |1 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 301: | Line 340: | ||
| | | | ||
|1 | |1 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 306: | Line 346: | ||
| | | | ||
|1 | |1 | ||
+ | | | ||
| | | | ||
|- | |- | ||
|[[FF7/PSX/Sound/Opcodes/0xc8|0xC8]] | |[[FF7/PSX/Sound/Opcodes/0xc8|0xC8]] | ||
|Loop Point | |Loop Point | ||
+ | | | ||
|1 | |1 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 316: | Line 359: | ||
| | | | ||
|2 | |2 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 321: | Line 365: | ||
|Return to Loop Point | |Return to Loop Point | ||
|1 | |1 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 326: | Line 371: | ||
| | | | ||
|1 | |1 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 331: | Line 377: | ||
| | | | ||
|1 | |1 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 336: | Line 383: | ||
| | | | ||
|1 | |1 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 341: | Line 389: | ||
| | | | ||
|1 | |1 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 346: | Line 395: | ||
| | | | ||
|1 | |1 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 351: | Line 401: | ||
| | | | ||
|1 | |1 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 356: | Line 407: | ||
| | | | ||
|1 | |1 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 361: | Line 413: | ||
| | | | ||
|1 | |1 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 366: | Line 419: | ||
| | | | ||
|1 | |1 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 371: | Line 425: | ||
| | | | ||
|1 | |1 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 376: | Line 431: | ||
| | | | ||
|1 | |1 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 381: | Line 437: | ||
| | | | ||
|1 | |1 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 386: | Line 443: | ||
| | | | ||
|1 | |1 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 391: | Line 449: | ||
| | | | ||
|2 | |2 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 396: | Line 455: | ||
| | | | ||
|2 | |2 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 401: | Line 461: | ||
| | | | ||
|2 | |2 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 406: | Line 467: | ||
| | | | ||
|1 | |1 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 411: | Line 473: | ||
| | | | ||
|2 | |2 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 416: | Line 479: | ||
| | | | ||
|3 | |3 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 421: | Line 485: | ||
| | | | ||
|3 | |3 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 426: | Line 491: | ||
| | | | ||
|3 | |3 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 432: | Line 498: | ||
|3 | |3 | ||
|u16 tempo | |u16 tempo | ||
+ | | | ||
|- | |- | ||
|[[FF7/PSX/Sound/Opcodes/0xe9|0xE9]] | |[[FF7/PSX/Sound/Opcodes/0xe9|0xE9]] | ||
| | | | ||
|4 | |4 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 442: | Line 510: | ||
|3 | |3 | ||
|u16 depth | |u16 depth | ||
+ | | | ||
|- | |- | ||
|[[FF7/PSX/Sound/Opcodes/0xeb|0xEB]] | |[[FF7/PSX/Sound/Opcodes/0xeb|0xEB]] | ||
| | | | ||
|4 | |4 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 451: | Line 521: | ||
| | | | ||
|3 | |3 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 456: | Line 527: | ||
| | | | ||
|1 | |1 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 461: | Line 533: | ||
| | | | ||
|3 | |3 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 466: | Line 539: | ||
| | | | ||
|3 | |3 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 471: | Line 545: | ||
| | | | ||
|4 | |4 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 476: | Line 551: | ||
| | | | ||
|4 | |4 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 481: | Line 557: | ||
| | | | ||
|2 | |2 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 486: | Line 563: | ||
| | | | ||
|1 | |1 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 491: | Line 569: | ||
| | | | ||
|3 | |3 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 496: | Line 575: | ||
| | | | ||
|1 | |1 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 501: | Line 581: | ||
| | | | ||
|2 | |2 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 506: | Line 587: | ||
| | | | ||
|3 | |3 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 511: | Line 593: | ||
| | | | ||
|2 | |2 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 516: | Line 599: | ||
| | | | ||
|1 | |1 | ||
+ | | | ||
| | | | ||
|- | |- | ||
|[[FF7/PSX/Sound/Opcodes/0xfa|0xFA]] | |[[FF7/PSX/Sound/Opcodes/0xfa|0xFA]] | ||
+ | | | ||
| | | | ||
| | | | ||
Line 524: | Line 609: | ||
|- | |- | ||
|[[FF7/PSX/Sound/Opcodes/0xfb|0xFB]] | |[[FF7/PSX/Sound/Opcodes/0xfb|0xFB]] | ||
+ | | | ||
| | | | ||
| | | | ||
Line 531: | Line 617: | ||
| | | | ||
|3 | |3 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 536: | Line 623: | ||
| | | | ||
|3 | |3 | ||
+ | | | ||
| | | | ||
|- | |- | ||
Line 541: | Line 629: | ||
| | | | ||
|2 | |2 | ||
+ | | | ||
| | | | ||
|- | |- | ||
|[[FF7/PSX/Sound/Opcodes/0xff|0xFF]] | |[[FF7/PSX/Sound/Opcodes/0xff|0xFF]] | ||
+ | | | ||
| | | | ||
| | | | ||
| | | | ||
|} | |} |
Revision as of 05:44, 31 May 2020
Contents
Introduction
AKAO frames are most complicated frames in FF7 sound system. ("AKAO" is frame magic, probably developed by Minoru Akao, Square Enix sound programmer :) )
Frame is similar to MIDI sequence - it's custom tracker format for playing sequence sound, well tuned specially for PSX.
This frames are in all FF7 game modules: Field, Battle, Worldmap and in minigames.
All files with exension *.SND are AKAO.
- MINI/ASERI2.SND - Battle Arena theme
- MINI/SENSUI.SND - used in Submarine minigame
- ENEMY6/OVER2.SND - game over sequence
- ENEMY6/FAN2.SND - battle win "fanfare" sequence
- MOVIE/OVER2.SND - same game over sequence, don't know, why to duplicate data
Other AKAO frames are hard-wired in other files.
AKAO frame structure
Header (size: 16 bytes)
struct AkaoHeader { static const uint8_t magic[4]; // "AKAO" C-string aka frame *MAGIC* uint16_t id; // frame ID, used for playing sequence uint16_t length; // frame length - sizeof(header) uint16_t reverb_type; // reverb type (range from 0 to 9) 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 (size: 4 bytes + 2 bytes * <channels count>)
struct AkaoChannelInfo { uint32_t mask; // represents bitmask of used channels in this frame uint32_t start_offsets[num_channels]; // offsets to channel opcode data };
int num_channels = 0; while (int bit = 0; ((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 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.)
Channel Commands [AKAO Opcodes]
Most complicated part.
For every channel in AKAO frame there is set of commands to perform. This is similar to Field opcodes. Here I'll call this sound commands "opcodes". Every opcode has it's own number of arguments (from no-arguments, to 3 arguments).
Example (home-created AKAO frame):
Header
41 4b 41 4f - AKAO string
34 12 - frame ID: 0x1234
16 00 - frame length 0x16 in hex or 22 in decimal
04 00 - reverb type: 4 (large studio)
96 12 18 22 46 28 - unknown data
Channel info
01 00 00 00 - this indicates, that used only one channel
00 00 - offset to first channel opcodes: in our example 0x00 means that next to this offset is opcodes for first channel
Channel commands
e8 a8 66 - sets tempo, parameter 0x66a8
ea 00 50 - sets reverb depth
a8 55 - load sample 0x55 from INSTR.ALL to channel
aa 40 - sets channel volume
c2 - turns on reverb effect
a1 0c - sets volume pan
c8 - sets loop point
66 - 0x66 % 11 = 3 (3 means to take 3rd number from play length table), 0x66 / 11 = 9 (9 means to take pitch[9] from loaded instrument record index)
ca - returns to saved loop point with opcode c8
This example plays Chocobo "Whoo-Hoo" (instrument number 0x55) repeatedly.
Sound Opcode list
Opcode | Summary | Length | Operands | Note | |
---|---|---|---|---|---|
0xA0 | Finish Channel | 1 | |||
0xA1 | Load Instrument | 2 | u8 instrument | ||
0xA2 | Overwrite Next Delta-Time Length | 2 | u8 delta_time | ||
0xA3 | Channel Master Volume | 2 | u8 volume | ||
0xA4 | Pitch Bend Slide | 3 | u8 length, s8 semitones | ||
0xA5 | Set Octave | 2 | u8 octave | ||
0xA6 | Increase Octave | 1 | |||
0xA7 | Decrease Octave | 1 | |||
0xA8 | Channel Volume | 2 | u8 volume | ||
0xA9 | Channel Volume Slide | 3 | u8 length, u8 volume | ||
0xAA | Channel Pan | 2 | u8 pan | 64 is the center | |
0xAB | Channel Pan Slide | 3 | u8 length, u8 pan | ||
0xAC | Noise Clock Frequency | 2 | u8 clock | ||
0xAD | ADSR: Attack Rate | 2 | u8 attack_rate | ||
0xAE | ADSR: Decay Rate | 2 | u8 decay_rate | ||
0xAF | ADSR: Sustain Level | 2 | u8 sustain_level | ||
0xB0 | ADSR: Decay Rate & Sustain Level | 3 | u8 decay_rate, u8 sustain_level | ||
0xB1 | ADSR: Sustain Rate | 2 | u8 sustain_rate | ||
0xB2 | ADSR: Release Rate | 2 | u8 release_rate | ||
0xB3 | Reset ADSR | 1 | |||
0xB4 | 4 | ||||
0xB5 | 2 | ||||
0xB6 | 1 | ||||
0xB7 | 2 | ||||
0xB8 | 4 | ||||
0xB9 | 2 | ||||
0xBA | 1 | ||||
0xBB | 2 | ||||
0xBC | 3 | ||||
0xBD | 2 | ||||
0xBE | 1 | ||||
0xBF | 2 | ||||
0xC0 | 2 | ||||
0xC1 | 2 | ||||
0xC2 | Turn On Reverb | 1 | |||
0xC3 | 1 | ||||
0xC4 | 1 | ||||
0xC5 | 1 | ||||
0xC6 | 1 | ||||
0xC7 | 1 | ||||
0xC8 | Loop Point | 1 | |||
0xC9 | 2 | ||||
0xCA | Return to Loop Point | 1 | |||
0xCB | 1 | ||||
0xCC | 1 | ||||
0xCD | 1 | ||||
0xCE | 1 | ||||
0xCF | 1 | ||||
0xD0 | 1 | ||||
0xD1 | 1 | ||||
0xD2 | 1 | ||||
0xD3 | 1 | ||||
0xD4 | 1 | ||||
0xD5 | 1 | ||||
0xD6 | 1 | ||||
0xD7 | 1 | ||||
0xD8 | 2 | ||||
0xD9 | 2 | ||||
0xDA | 2 | ||||
0xDB | 1 | ||||
0xDC | 2 | ||||
0xDD | 3 | ||||
0xDE | 3 | ||||
0xDF | 3 | ||||
0xE8 | Tempo | 3 | u16 tempo | ||
0xE9 | 4 | ||||
0xEA | Reverb Depth | 3 | u16 depth | ||
0xEB | 4 | ||||
0xEC | 3 | ||||
0xED | 1 | ||||
0xEE | 3 | ||||
0xEF | 3 | ||||
0xF0 | 4 | ||||
0xF1 | 4 | ||||
0xF2 | 2 | ||||
0xF3 | 1 | ||||
0xF4 | 3 | ||||
0xF5 | 1 | ||||
0xF6 | 2 | ||||
0xF7 | 3 | ||||
0xF8 | 2 | ||||
0xF9 | 1 | ||||
0xFA | |||||
0xFB | |||||
0xFC | 3 | ||||
0xFD | 3 | ||||
0xFE | 2 | ||||
0xFF |