internal.h (28206B)
1 #ifndef AUDIO_INTERNAL_H 2 #define AUDIO_INTERNAL_H 3 4 #include <ultra64.h> 5 6 #include "types.h" 7 8 #if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) 9 #define SEQUENCE_PLAYERS 4 10 #define SEQUENCE_CHANNELS 48 11 #define SEQUENCE_LAYERS 64 12 #else 13 #define SEQUENCE_PLAYERS 3 14 #define SEQUENCE_CHANNELS 32 15 #ifdef VERSION_JP 16 #define SEQUENCE_LAYERS 48 17 #else 18 #define SEQUENCE_LAYERS 52 19 #endif 20 #endif 21 22 #define LAYERS_MAX 4 23 #define CHANNELS_MAX 16 24 25 #define NO_LAYER ((struct SequenceChannelLayer *)(-1)) 26 27 #define MUTE_BEHAVIOR_STOP_SCRIPT 0x80 // stop processing sequence/channel scripts 28 #define MUTE_BEHAVIOR_STOP_NOTES 0x40 // prevent further notes from playing 29 #define MUTE_BEHAVIOR_SOFTEN 0x20 // lower volume, by default to half 30 31 #define SEQUENCE_PLAYER_STATE_0 0 32 #define SEQUENCE_PLAYER_STATE_FADE_OUT 1 33 #define SEQUENCE_PLAYER_STATE_2 2 34 #define SEQUENCE_PLAYER_STATE_3 3 35 #define SEQUENCE_PLAYER_STATE_4 4 36 37 #define NOTE_PRIORITY_DISABLED 0 38 #define NOTE_PRIORITY_STOPPING 1 39 #define NOTE_PRIORITY_MIN 2 40 #define NOTE_PRIORITY_DEFAULT 3 41 42 #define TATUMS_PER_BEAT 48 43 44 // abi.h contains more details about the ADPCM and S8 codecs, "skip" skips codec processing 45 #define CODEC_ADPCM 0 46 #define CODEC_S8 1 47 #define CODEC_SKIP 2 48 49 #ifdef VERSION_JP 50 #define TEMPO_SCALE 1 51 #else 52 #define TEMPO_SCALE TATUMS_PER_BEAT 53 #endif 54 55 // TODO: US_FLOAT should probably be renamed to JP_DOUBLE since eu seems to use floats too 56 #ifdef VERSION_JP 57 #define US_FLOAT(x) x 58 #else 59 #define US_FLOAT(x) x ## f 60 #endif 61 62 // Convert u8 or u16 to f32. On JP, this uses a u32->f32 conversion, 63 // resulting in more bloated codegen, while on US it goes through s32. 64 // Since u8 and u16 fit losslessly in both, behavior is the same. 65 #ifdef VERSION_JP 66 #define FLOAT_CAST(x) (f32) (x) 67 #else 68 #define FLOAT_CAST(x) (f32) (s32) (x) 69 #endif 70 71 // No-op printf macro which leaves string literals in rodata in IDO. IDO 72 // doesn't support variadic macros, so instead we let the parameter list 73 // expand to a no-op comma expression. Another possibility is that it might 74 // have expanded to something with "if (0)". See also goddard/gd_main.h. 75 // On US/JP, -sopt optimizes away these except for external.c. 76 #ifdef __sgi 77 #define stubbed_printf 78 #else 79 #define stubbed_printf(...) 80 #endif 81 82 #ifdef VERSION_EU 83 #define eu_stubbed_printf_0(msg) stubbed_printf(msg) 84 #define eu_stubbed_printf_1(msg, a) stubbed_printf(msg, a) 85 #define eu_stubbed_printf_2(msg, a, b) stubbed_printf(msg, a, b) 86 #define eu_stubbed_printf_3(msg, a, b, c) stubbed_printf(msg, a, b, c) 87 #else 88 #define eu_stubbed_printf_0(msg) 89 #define eu_stubbed_printf_1(msg, a) 90 #define eu_stubbed_printf_2(msg, a, b) 91 #define eu_stubbed_printf_3(msg, a, b, c) 92 #endif 93 94 struct NotePool; 95 96 struct AudioListItem { 97 // A node in a circularly linked list. Each node is either a head or an item: 98 // - Items can be either detached (prev = NULL), or attached to a list. 99 // 'value' points to something of interest. 100 // - List heads are always attached; if a list is empty, its head points 101 // to itself. 'count' contains the size of the list. 102 // If the list holds notes, 'pool' points back to the pool where it lives. 103 // Otherwise, that member is NULL. 104 struct AudioListItem *prev; 105 struct AudioListItem *next; 106 union { 107 void *value; // either Note* or SequenceChannelLayer* 108 s32 count; 109 } u; 110 struct NotePool *pool; 111 }; // size = 0x10 112 113 struct NotePool { 114 struct AudioListItem disabled; 115 struct AudioListItem decaying; 116 struct AudioListItem releasing; 117 struct AudioListItem active; 118 }; 119 120 struct VibratoState { 121 /*0x00, 0x00*/ struct SequenceChannel *seqChannel; 122 /*0x04, 0x04*/ u32 time; 123 #if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) 124 /* , 0x08*/ s16 *curve; 125 /* , 0x0C*/ f32 extent; 126 /* , 0x10*/ f32 rate; 127 /* , 0x14*/ u8 active; 128 #else 129 /*0x08, */ s8 *curve; 130 /*0x0C, */ u8 active; 131 /*0x0E, */ u16 rate; 132 /*0x10, */ u16 extent; 133 #endif 134 /*0x12, 0x16*/ u16 rateChangeTimer; 135 /*0x14, 0x18*/ u16 extentChangeTimer; 136 /*0x16, 0x1A*/ u16 delay; 137 }; // size = 0x18, 0x1C on EU 138 139 // Pitch sliding by up to one octave in the positive direction. Negative 140 // direction is "supported" by setting extent to be negative. The code 141 // extrapolates exponentially in the wrong direction in that case, but that 142 // doesn't prevent seqplayer from doing it, AFAICT. 143 struct Portamento { 144 u8 mode; // bit 0x80 denotes something; the rest are an index 0-5 145 f32 cur; 146 f32 speed; 147 f32 extent; 148 }; // size = 0x10 149 150 struct AdsrEnvelope { 151 s16 delay; 152 s16 arg; 153 }; // size = 0x4 154 155 struct AdpcmLoop { 156 u32 start; 157 u32 end; 158 u32 count; 159 u32 pad; 160 s16 state[16]; // only exists if count != 0. 8-byte aligned 161 }; 162 163 struct AdpcmBook { 164 s32 order; 165 s32 npredictors; 166 s16 book[1]; // size 8 * order * npredictors. 8-byte aligned 167 }; 168 169 struct AudioBankSample { 170 #if defined(VERSION_SH) || defined(VERSION_CN) 171 /* 0x00 */ u32 codec : 4; 172 /* 0x00 */ u32 medium : 2; 173 /* 0x00 */ u32 bit1 : 1; 174 /* 0x00 */ u32 isPatched : 1; 175 /* 0x01 */ u32 size : 24; 176 #else 177 u8 unused; 178 u8 loaded; 179 #endif 180 u8 *sampleAddr; 181 struct AdpcmLoop *loop; 182 struct AdpcmBook *book; 183 #if !defined(VERSION_SH) && !defined(VERSION_CN) 184 u32 sampleSize; // never read. either 0 or 1 mod 9, depending on padding 185 #endif 186 }; 187 188 struct AudioBankSound { 189 struct AudioBankSample *sample; 190 f32 tuning; // frequency scale factor 191 }; // size = 0x8 192 193 struct Instrument { 194 /*0x00*/ u8 loaded; 195 /*0x01*/ u8 normalRangeLo; 196 /*0x02*/ u8 normalRangeHi; 197 /*0x03*/ u8 releaseRate; 198 /*0x04*/ struct AdsrEnvelope *envelope; 199 /*0x08*/ struct AudioBankSound lowNotesSound; 200 /*0x10*/ struct AudioBankSound normalNotesSound; 201 /*0x18*/ struct AudioBankSound highNotesSound; 202 }; // size = 0x20 203 204 struct Drum { 205 u8 releaseRate; 206 u8 pan; 207 u8 loaded; 208 struct AudioBankSound sound; 209 struct AdsrEnvelope *envelope; 210 }; 211 212 struct AudioBank { 213 struct Drum **drums; 214 struct Instrument *instruments[1]; 215 }; // dynamic size 216 217 struct CtlEntry { 218 #if !defined(VERSION_SH) && !defined(VERSION_CN) 219 u8 unused; 220 #endif 221 u8 numInstruments; 222 u8 numDrums; 223 #if defined(VERSION_SH) || defined(VERSION_CN) 224 u8 bankId1; 225 u8 bankId2; 226 #endif 227 struct Instrument **instruments; 228 struct Drum **drums; 229 }; // size = 0xC 230 231 struct M64ScriptState { 232 u8 *pc; 233 u8 *stack[4]; 234 u8 remLoopIters[4]; 235 u8 depth; 236 }; // size = 0x1C 237 238 // Also known as a Group, according to debug strings. 239 struct SequencePlayer { 240 /*US/JP, EU, SH */ 241 #if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) 242 /*0x000, 0x000, 0x000*/ u8 enabled : 1; 243 #else 244 /*0x000, 0x000*/ volatile u8 enabled : 1; 245 #endif 246 /*0x000, 0x000*/ u8 finished : 1; // never read 247 /*0x000, 0x000*/ u8 muted : 1; 248 /*0x000, 0x000*/ u8 seqDmaInProgress : 1; 249 /*0x000, 0x000*/ u8 bankDmaInProgress : 1; 250 #if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) 251 /* 0x000*/ u8 recalculateVolume : 1; 252 #endif 253 #if defined(VERSION_SH) || defined(VERSION_CN) 254 /* 0x000*/ u8 unkSh: 1; 255 #endif 256 #if defined(VERSION_JP) || defined(VERSION_US) 257 /*0x001 */ s8 seqVariation; 258 #endif 259 /*0x002, 0x001, 0x001*/ u8 state; 260 /*0x003, 0x002*/ u8 noteAllocPolicy; 261 /*0x004, 0x003*/ u8 muteBehavior; 262 /*0x005, 0x004*/ u8 seqId; 263 /*0x006, 0x005*/ u8 defaultBank[1]; // must be an array to get a comparison 264 // to match; other u8's might also be part of that array 265 /*0x007, 0x006*/ u8 loadingBankId; 266 #if defined(VERSION_JP) || defined(VERSION_US) 267 /*0x008, ?????*/ u8 loadingBankNumInstruments; 268 /*0x009, ?????*/ u8 loadingBankNumDrums; 269 #endif 270 #if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) 271 /* , 0x007, 0x007*/ s8 seqVariationEu[1]; 272 #endif 273 /*0x00A, 0x008*/ u16 tempo; // beats per minute in JP, tatums per minute in US/EU 274 /*0x00C, 0x00A*/ u16 tempoAcc; 275 #if defined(VERSION_JP) || defined(VERSION_US) 276 /*0x00E, 0x010*/ u16 fadeRemainingFrames; 277 #endif 278 #if defined(VERSION_SH) || defined(VERSION_CN) 279 /* 0x00C*/ s16 tempoAdd; 280 #endif 281 /*0x010, 0x00C, 0x00E*/ s16 transposition; 282 /*0x012, 0x00E, 0x010*/ u16 delay; 283 #if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) 284 /*0x00E, 0x010, 0x012*/ u16 fadeRemainingFrames; 285 /* , 0x012, 0x014*/ u16 fadeTimerUnkEu; 286 #endif 287 /*0x014, 0x014*/ u8 *seqData; // buffer of some sort 288 /*0x018, 0x018, 0x1C*/ f32 fadeVolume; // set to 1.0f 289 /*0x01C, 0x01C*/ f32 fadeVelocity; // set to 0.0f 290 /*0x020, 0x020, 0x024*/ f32 volume; // set to 0.0f 291 /*0x024, 0x024*/ f32 muteVolumeScale; // set to 0.5f 292 #if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) 293 /* , 0x028, 0x02C*/ f32 fadeVolumeScale; 294 /* , 0x02C*/ f32 appliedFadeVolume; 295 #else 296 /* */ u8 pad2[4]; 297 #endif 298 /*0x02C, 0x030, 0x034*/ struct SequenceChannel *channels[CHANNELS_MAX]; 299 /*0x06C, 0x070*/ struct M64ScriptState scriptState; 300 /*0x088, 0x08C*/ u8 *shortNoteVelocityTable; 301 /*0x08C, 0x090*/ u8 *shortNoteDurationTable; 302 /*0x090, 0x094*/ struct NotePool notePool; 303 /*0x0D0, 0x0D4*/ OSMesgQueue seqDmaMesgQueue; 304 /*0x0E8, 0x0EC*/ OSMesg seqDmaMesg; 305 /*0x0EC, 0x0F0*/ OSIoMesg seqDmaIoMesg; 306 /*0x100, 0x108*/ OSMesgQueue bankDmaMesgQueue; 307 /*0x118, 0x120*/ OSMesg bankDmaMesg; 308 /*0x11C, 0x124*/ OSIoMesg bankDmaIoMesg; 309 /*0x130, 0x13C*/ u8 *bankDmaCurrMemAddr; 310 #if defined(VERSION_JP) || defined(VERSION_US) 311 /*0x134, ?????*/ struct AudioBank *loadingBank; 312 #endif 313 /*0x138, 0x140*/ uintptr_t bankDmaCurrDevAddr; 314 /*0x13C, 0x144*/ ssize_t bankDmaRemaining; 315 }; // size = 0x140, 0x148 on EU, 0x14C on SH 316 317 struct AdsrSettings { 318 u8 releaseRate; 319 #if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) 320 u8 sustain; 321 #else 322 u16 sustain; // sustain level, 2^16 = max 323 #endif 324 struct AdsrEnvelope *envelope; 325 }; // size = 0x8 326 327 struct AdsrState { 328 /*0x00, 0x00*/ u8 action; 329 /*0x01, 0x01*/ u8 state; 330 #if defined(VERSION_JP) || defined(VERSION_US) 331 /*0x02, */ s16 initial; // always 0 332 /*0x04, */ s16 target; 333 /*0x06, */ s16 current; 334 #endif 335 /*0x08, 0x02*/ s16 envIndex; 336 /*0x0A, 0x04*/ s16 delay; 337 #if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) 338 /* , 0x08*/ f32 sustain; 339 /* , 0x0C*/ f32 velocity; 340 /* , 0x10*/ f32 fadeOutVel; 341 /* , 0x14*/ f32 current; 342 /* , 0x18*/ f32 target; 343 s32 pad1C; 344 #else 345 /*0x0C, */ s16 sustain; 346 /*0x0E, */ s16 fadeOutVel; 347 /*0x10, */ s32 velocity; 348 /*0x14, */ s32 currentHiRes; 349 /*0x18, */ s16 *volOut; 350 #endif 351 /*0x1C, 0x20*/ struct AdsrEnvelope *envelope; 352 }; // size = 0x20, 0x24 in EU 353 354 struct ReverbBitsData { 355 /* 0x00 */ u8 bit0 : 1; 356 /* 0x00 */ u8 bit1 : 1; 357 /* 0x00 */ u8 bit2 : 1; 358 /* 0x00 */ u8 usesHeadsetPanEffects : 1; 359 /* 0x00 */ u8 stereoHeadsetEffects : 2; 360 /* 0x00 */ u8 strongRight : 1; 361 /* 0x00 */ u8 strongLeft : 1; 362 }; 363 364 union ReverbBits { 365 /* 0x00 */ struct ReverbBitsData s; 366 /* 0x00 */ u8 asByte; 367 }; 368 struct ReverbInfo { 369 u8 reverbVol; 370 u8 synthesisVolume; // UQ4.4, although 0 <= x < 1 is rounded up to 1 371 u8 pan; 372 union ReverbBits reverbBits; 373 f32 freqScale; 374 f32 velocity; 375 s32 unused; 376 s16 *filter; 377 }; 378 379 struct NoteAttributes { 380 u8 reverbVol; 381 #if defined(VERSION_SH) || defined(VERSION_CN) 382 u8 synthesisVolume; // UQ4.4, although 0 <= x < 1 is rounded up to 1 383 #endif 384 #if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) 385 u8 pan; 386 #endif 387 #if defined(VERSION_SH) || defined(VERSION_CN) 388 union ReverbBits reverbBits; 389 #endif 390 f32 freqScale; 391 f32 velocity; 392 #if defined(VERSION_JP) || defined(VERSION_US) 393 f32 pan; 394 #endif 395 #if defined(VERSION_SH) || defined(VERSION_CN) 396 s16 *filter; 397 #endif 398 }; // size = 0x10 399 400 // Also known as a SubTrack, according to debug strings. 401 // Confusingly, a SubTrack is a container of Tracks. 402 struct SequenceChannel { 403 /* U/J, EU, SH */ 404 /*0x00, 0x00*/ u8 enabled : 1; 405 /*0x00, 0x00*/ u8 finished : 1; 406 /*0x00, 0x00*/ u8 stopScript : 1; 407 /*0x00, 0x00*/ u8 stopSomething2 : 1; // sets SequenceChannelLayer.stopSomething 408 /*0x00, 0x00*/ u8 hasInstrument : 1; 409 /*0x00, 0x00*/ u8 stereoHeadsetEffects : 1; 410 /*0x00, ????*/ u8 largeNotes : 1; // notes specify duration and velocity 411 /*0x00, ????*/ u8 unused : 1; // never read, set to 0 412 #if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) 413 /* , 0x01*/ union { 414 struct { 415 u8 freqScale : 1; 416 u8 volume : 1; 417 u8 pan : 1; 418 } as_bitfields; 419 u8 as_u8; 420 } changes; 421 #endif 422 /*0x01, 0x02*/ u8 noteAllocPolicy; 423 /*0x02, 0x03, 0x03*/ u8 muteBehavior; 424 /*0x03, 0x04, 0x04*/ u8 reverbVol; // until EU: Q1.7, after EU: UQ0.8 425 /*0x04, ????*/ u8 notePriority; // 0-3 426 #if defined(VERSION_SH) || defined(VERSION_CN) 427 u8 unkSH06; // some priority 428 #endif 429 /*0x05, 0x06*/ u8 bankId; 430 #if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) 431 /* , 0x07*/ u8 reverbIndex; 432 /* , 0x08, 0x09*/ u8 bookOffset; 433 /* , 0x09*/ u8 newPan; 434 /* , 0x0A*/ u8 panChannelWeight; // proportion of pan that comes from the channel (0..128) 435 #else 436 /*0x06, */ u8 updatesPerFrameUnused; 437 #endif 438 #if defined(VERSION_SH) || defined(VERSION_CN) 439 /* 0x0C*/ u8 synthesisVolume; // UQ4.4, although 0 <= x < 1 is rounded up to 1 440 #endif 441 /*0x08, 0x0C, 0x0E*/ u16 vibratoRateStart; // initially 0x800 442 /*0x0A, 0x0E, 0x10*/ u16 vibratoExtentStart; 443 /*0x0C, 0x10, 0x12*/ u16 vibratoRateTarget; // initially 0x800 444 /*0x0E, 0x12, 0x14*/ u16 vibratoExtentTarget; 445 /*0x10, 0x14, 0x16*/ u16 vibratoRateChangeDelay; 446 /*0x12, 0x16, 0x18*/ u16 vibratoExtentChangeDelay; 447 /*0x14, 0x18, 0x1A*/ u16 vibratoDelay; 448 /*0x16, 0x1A, 0x1C*/ u16 delay; 449 /*0x18, 0x1C, 0x1E*/ s16 instOrWave; // either 0 (none), instrument index + 1, or 450 // 0x80..0x83 for sawtooth/triangle/sine/square waves. 451 /*0x1A, 0x1E, 0x20*/ s16 transposition; 452 /*0x1C, 0x20, 0x24*/ f32 volumeScale; 453 /*0x20, 0x24, 0x28*/ f32 volume; 454 #if defined(VERSION_JP) || defined(VERSION_US) 455 /*0x24, */ f32 pan; 456 /*0x28, */ f32 panChannelWeight; // proportion of pan that comes from the channel (0..1) 457 #else 458 /* , 0x28*/ s32 pan; 459 /* , 0x2C*/ f32 appliedVolume; 460 #endif 461 /*0x2C, 0x30*/ f32 freqScale; 462 /*0x30, 0x34*/ u8 (*dynTable)[][2]; 463 /*0x34, ????*/ struct Note *noteUnused; // never read 464 /*0x38, ????*/ struct SequenceChannelLayer *layerUnused; // never read 465 /*0x3C, 0x40*/ struct Instrument *instrument; 466 /*0x40, 0x44*/ struct SequencePlayer *seqPlayer; 467 /*0x44, 0x48*/ struct SequenceChannelLayer *layers[LAYERS_MAX]; 468 #if !defined(VERSION_SH) && !defined(VERSION_CN) 469 /*0x54, 0x58 */ s8 soundScriptIO[8]; // bridge between sound script and audio lib. For player 2, 470 // [0] contains enabled, [4] contains sound ID, [5] contains reverb adjustment 471 #endif 472 /*0x5C, 0x60*/ struct M64ScriptState scriptState; 473 /*0x78, 0x7C*/ struct AdsrSettings adsr; 474 /*0x80, 0x84*/ struct NotePool notePool; 475 #if defined(VERSION_SH) || defined(VERSION_CN) 476 /* 0xC0*/ s8 soundScriptIO[8]; // bridge between sound script and audio lib. For player 2, 477 // [0] contains enabled, [4] contains sound ID, [5] contains reverb adjustment 478 /* 0xC8*/ u16 unkC8; 479 /* 0xCC*/ s16 *filter; 480 #endif 481 }; // size = 0xC0, 0xC4 in EU, 0xD0 in SH 482 483 // Also known as a Track, according to debug strings. 484 struct SequenceChannelLayer { 485 /* U/J, EU, SH */ 486 /*0x00, 0x00*/ u8 enabled : 1; 487 /*0x00, 0x00*/ u8 finished : 1; 488 /*0x00, 0x00*/ u8 stopSomething : 1; // ? 489 /*0x00, 0x00*/ u8 continuousNotes : 1; // keep the same note for consecutive notes with the same sound 490 #if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) 491 /* , 0x00*/ u8 unusedEu0b8 : 1; 492 /* , 0x00*/ u8 notePropertiesNeedInit : 1; 493 /* , 0x00*/ u8 ignoreDrumPan : 1; 494 #if defined(VERSION_SH) || defined(VERSION_CN) 495 /* , , 0x01 */ union ReverbBits reverbBits; 496 #endif 497 /* , 0x01, 0x02*/ u8 instOrWave; 498 #endif 499 /*0x01, 0x02, 0x03*/ u8 status; // 0x03 in SH 500 /*0x02, 0x03*/ u8 noteDuration; // set to 0x80 501 /*0x03, 0x04*/ u8 portamentoTargetNote; 502 #if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) 503 /* , 0x05*/ u8 pan; // 0..128 504 /* , 0x06, 0x07*/ u8 notePan; 505 #endif 506 /*0x04, 0x08*/ struct Portamento portamento; 507 /*0x14, 0x18*/ struct AdsrSettings adsr; 508 /*0x1C, 0x20*/ u16 portamentoTime; 509 /*0x1E, 0x22*/ s16 transposition; // #semitones added to play commands 510 // (m64 instruction encoding only allows referring to the limited range 511 // 0..0x3f; this makes 0x40..0x7f accessible as well) 512 /*0x20, 0x24, 0x24*/ f32 freqScale; 513 #if defined(VERSION_SH) || defined(VERSION_CN) 514 /* 0x28*/ f32 freqScaleMultiplier; 515 #endif 516 /*0x24, 0x28, 0x2C*/ f32 velocitySquare; 517 #if defined(VERSION_JP) || defined(VERSION_US) 518 /*0x28, */ f32 pan; // 0..1 519 #endif 520 /*0x2C, 0x2C, 0x30*/ f32 noteVelocity; 521 #if defined(VERSION_JP) || defined(VERSION_US) 522 /*0x30*/ f32 notePan; 523 #endif 524 /*0x34, 0x30, 0x34*/ f32 noteFreqScale; 525 /*0x38, 0x34*/ s16 shortNoteDefaultPlayPercentage; 526 /*0x3A, 0x36*/ s16 playPercentage; // it's not really a percentage... 527 /*0x3C, 0x38*/ s16 delay; 528 /*0x3E, 0x3A*/ s16 duration; 529 /*0x40, 0x3C*/ s16 delayUnused; // set to 'delay', never read 530 /*0x44, 0x40, 0x44*/ struct Note *note; 531 /*0x48, 0x44*/ struct Instrument *instrument; 532 /*0x4C, 0x48*/ struct AudioBankSound *sound; 533 /*0x50, 0x4C, 0x50*/ struct SequenceChannel *seqChannel; 534 /*0x54, 0x50*/ struct M64ScriptState scriptState; 535 /*0x70, 0x6C*/ struct AudioListItem listItem; 536 #if defined(VERSION_EU) 537 u8 pad2[4]; 538 #endif 539 }; // size = 0x80 540 541 #if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) 542 struct NoteSynthesisState { 543 /*0x00*/ u8 restart; 544 /*0x01*/ u8 sampleDmaIndex; 545 /*0x02*/ u8 prevHeadsetPanRight; 546 /*0x03*/ u8 prevHeadsetPanLeft; 547 #if defined(VERSION_SH) || defined(VERSION_CN) 548 /* 0x04*/ u8 reverbVol; 549 /* 0x05*/ u8 unk5; 550 #endif 551 /*0x04, 0x06*/ u16 samplePosFrac; 552 /*0x08*/ s32 samplePosInt; 553 /*0x0C*/ struct NoteSynthesisBuffers *synthesisBuffers; 554 /*0x10*/ s16 curVolLeft; // UQ0.16 (EU Q1.15) 555 /*0x12*/ s16 curVolRight; // UQ0.16 (EU Q1.15) 556 }; 557 struct NotePlaybackState { 558 /* U/J, EU, SH */ 559 /*0x04, 0x00, 0x00*/ u8 priority; 560 /* 0x01, 0x01*/ u8 waveId; 561 /* 0x02, 0x02*/ u8 sampleCountIndex; 562 #if defined(VERSION_SH) || defined(VERSION_CN) 563 /* 0x03*/ u8 bankId; 564 /* 0x04*/ u8 unkSH34; 565 #endif 566 /*0x08, 0x04, 0x06*/ s16 adsrVolScale; 567 /*0x18, 0x08, 0x08*/ f32 portamentoFreqScale; 568 /*0x1C, 0x0C, 0x0C*/ f32 vibratoFreqScale; 569 /*0x28, 0x10, */ struct SequenceChannelLayer *prevParentLayer; 570 /*0x2C, 0x14, 0x14*/ struct SequenceChannelLayer *parentLayer; 571 /*0x30, 0x18, 0x18*/ struct SequenceChannelLayer *wantedParentLayer; 572 /* , 0x1C, 0x1C*/ struct NoteAttributes attributes; 573 /*0x54, 0x28, 0x2C*/ struct AdsrState adsr; 574 /*0x74, 0x4C, */ struct Portamento portamento; 575 /*0x84, 0x5C, */ struct VibratoState vibratoState; 576 }; 577 struct NoteSubEu { 578 /*0x00*/ volatile u8 enabled : 1; 579 /*0x00*/ u8 needsInit : 1; 580 /*0x00*/ u8 finished : 1; 581 /*0x00*/ u8 envMixerNeedsInit : 1; 582 /*0x00*/ u8 stereoStrongRight : 1; 583 /*0x00*/ u8 stereoStrongLeft : 1; 584 /*0x00*/ u8 stereoHeadsetEffects : 1; 585 /*0x00*/ u8 usesHeadsetPanEffects : 1; 586 /*0x01*/ u8 reverbIndex : 3; 587 /*0x01*/ u8 bookOffset : 3; 588 /*0x01*/ u8 isSyntheticWave : 1; 589 /*0x01*/ u8 hasTwoAdpcmParts : 1; 590 #ifdef VERSION_EU 591 /*0x02*/ u8 bankId; 592 #else 593 /*0x02*/ u8 synthesisVolume; // UQ4.4, although 0 <= x < 1 is rounded up to 1 594 #endif 595 /*0x03*/ u8 headsetPanRight; 596 /*0x04*/ u8 headsetPanLeft; 597 /*0x05*/ u8 reverbVol; // UQ0.7 (EU Q1.7) 598 /*0x06*/ u16 targetVolLeft; // UQ0.12 (EU UQ0.10) 599 /*0x08*/ u16 targetVolRight; // UQ0.12 (EU UQ0.10) 600 /*0x0A*/ u16 resamplingRateFixedPoint; // stored as signed but loaded as u16 601 /*0x0C*/ union { 602 s16 *samples; 603 struct AudioBankSound *audioBankSound; 604 } sound; 605 #if defined(VERSION_SH) || defined(VERSION_CN) 606 /*0x10*/ s16 *filter; 607 #endif 608 }; 609 struct Note { 610 /* U/J, EU, SH */ 611 /*0xA4, 0x00, 0x00*/ struct AudioListItem listItem; 612 /* 0x10, 0x10*/ struct NoteSynthesisState synthesisState; 613 // The next members are actually part of a struct (NotePlaybackState), but 614 // that results in messy US/EU ifdefs. Instead we cast to a struct pointer 615 // when needed... This breaks alignment on non-N64 platforms, which we hack 616 // around by skipping the padding in that case. 617 // TODO: use macros or something instead. 618 #ifdef TARGET_N64 619 u8 pad0[12]; 620 #endif 621 622 /*0x04, 0x30, 0x30*/ u8 priority; 623 /* 0x31, 0x31*/ u8 waveId; 624 /* 0x32, 0x32*/ u8 sampleCountIndex; 625 #if defined(VERSION_SH) || defined(VERSION_CN) 626 /* 0x33*/ u8 bankId; 627 /* 0x34*/ u8 unkSH34; 628 #endif 629 /*0x08, 0x34, 0x36*/ s16 adsrVolScale; 630 /*0x18, 0x38, */ f32 portamentoFreqScale; 631 /*0x1C, 0x3C, */ f32 vibratoFreqScale; 632 /*0x28, 0x40, */ struct SequenceChannelLayer *prevParentLayer; 633 /*0x2C, 0x44, 0x44*/ struct SequenceChannelLayer *parentLayer; 634 /*0x30, 0x48, 0x48*/ struct SequenceChannelLayer *wantedParentLayer; 635 /* , 0x4C, 0x4C*/ struct NoteAttributes attributes; 636 /*0x54, 0x58, 0x5C*/ struct AdsrState adsr; 637 /*0x74, 0x7C*/ struct Portamento portamento; 638 /*0x84, 0x8C*/ struct VibratoState vibratoState; 639 u8 pad3[8]; 640 /* , 0xB0, 0xB4*/ struct NoteSubEu noteSubEu; 641 }; // size = 0xC0, known to be 0xC8 on SH 642 #else 643 // volatile Note, needed in synthesis_process_notes 644 struct vNote { 645 /* U/J, EU */ 646 /*0x00*/ volatile u8 enabled : 1; 647 long long int force_structure_alignment; 648 }; // size = 0xC0 649 struct Note { 650 /* U/J, EU */ 651 /*0x00*/ u8 enabled : 1; 652 /*0x00*/ u8 needsInit : 1; 653 /*0x00*/ u8 restart : 1; 654 /*0x00*/ u8 finished : 1; 655 /*0x00*/ u8 envMixerNeedsInit : 1; 656 /*0x00*/ u8 stereoStrongRight : 1; 657 /*0x00*/ u8 stereoStrongLeft : 1; 658 /*0x00*/ u8 stereoHeadsetEffects : 1; 659 /*0x01*/ u8 usesHeadsetPanEffects; 660 /*0x02*/ u8 unk2; 661 /*0x03*/ u8 sampleDmaIndex; 662 /*0x04, 0x30*/ u8 priority; 663 /*0x05*/ u8 sampleCount; // 0, 8, 16, 32 or 64 664 /*0x06*/ u8 instOrWave; 665 /*0x07*/ u8 bankId; // in NoteSubEu on EU 666 /*0x08*/ s16 adsrVolScale; 667 /* */ u8 pad1[2]; 668 /*0x0C, 0xB3*/ u16 headsetPanRight; 669 /*0x0E, 0xB4*/ u16 headsetPanLeft; 670 /*0x10*/ u16 prevHeadsetPanRight; 671 /*0x12*/ u16 prevHeadsetPanLeft; 672 /*0x14*/ s32 samplePosInt; 673 /*0x18, 0x38*/ f32 portamentoFreqScale; 674 /*0x1C, 0x3C*/ f32 vibratoFreqScale; 675 /*0x20*/ u16 samplePosFrac; 676 /*0x24*/ struct AudioBankSound *sound; 677 /*0x28, 0x40*/ struct SequenceChannelLayer *prevParentLayer; 678 /*0x2C, 0x44*/ struct SequenceChannelLayer *parentLayer; 679 /*0x30, 0x48*/ struct SequenceChannelLayer *wantedParentLayer; 680 /*0x34*/ struct NoteSynthesisBuffers *synthesisBuffers; 681 /*0x38*/ f32 frequency; 682 /*0x3C*/ u16 targetVolLeft; // Q1.15, but will always be non-negative 683 /*0x3E*/ u16 targetVolRight; // Q1.15, but will always be non-negative 684 /*0x40*/ u8 reverbVol; // Q1.7 685 /*0x41*/ u8 unused1; // never read, set to 0x3f 686 /*0x44*/ struct NoteAttributes attributes; 687 /*0x54, 0x58*/ struct AdsrState adsr; 688 /*0x74, 0x7C*/ struct Portamento portamento; 689 /*0x84, 0x8C*/ struct VibratoState vibratoState; 690 /*0x9C*/ s16 curVolLeft; // Q1.15, but will always be non-negative 691 /*0x9E*/ s16 curVolRight; // Q1.15, but will always be non-negative 692 /*0xA0*/ s16 reverbVolShifted; // Q1.15 693 /*0xA2*/ s16 unused2; // never read, set to 0 694 /*0xA4, 0x00*/ struct AudioListItem listItem; 695 /* */ u8 pad2[0xc]; 696 }; // size = 0xC0 697 #endif 698 699 struct NoteSynthesisBuffers { 700 s16 adpcmdecState[0x10]; 701 s16 finalResampleState[0x10]; 702 #if defined(VERSION_SH) || defined(VERSION_CN) 703 s16 unk[0x10]; 704 s16 filterBuffer[0x20]; 705 s16 panSamplesBuffer[0x20]; 706 #else 707 s16 mixEnvelopeState[0x28]; 708 s16 panResampleState[0x10]; 709 s16 panSamplesBuffer[0x20]; 710 s16 dummyResampleState[0x10]; 711 #if defined(VERSION_JP) || defined(VERSION_US) 712 s16 samples[0x40]; 713 #endif 714 #endif 715 }; 716 717 #ifdef VERSION_EU 718 struct ReverbSettingsEU { 719 u8 downsampleRate; 720 u8 windowSize; // To be multiplied by 64 721 u16 gain; 722 }; 723 #else 724 struct ReverbSettingsEU { 725 u8 downsampleRate; // always 1 726 u8 windowSize; // To be multiplied by 16 727 u16 gain; 728 u16 unk4; // always zero 729 u16 unk6; // always zero 730 s8 unk8; // always -1 731 u16 unkA; // always 0x3000 732 s16 unkC; // always zero 733 s16 unkE; // always zero 734 }; 735 #endif 736 737 struct AudioSessionSettingsEU { 738 /* 0x00 */ u32 frequency; 739 /* 0x04 */ u8 unk1; // always 1 740 /* 0x05 */ u8 maxSimultaneousNotes; 741 /* 0x06 */ u8 numReverbs; // always 1 742 /* 0x07 */ u8 unk2; // always 0 743 /* 0x08 */ struct ReverbSettingsEU *reverbSettings; 744 /* 0x0C */ u16 volume; 745 /* 0x0E */ u16 unk3; // always 0 746 /* 0x10 */ u32 persistentSeqMem; 747 /* 0x14 */ u32 persistentBankMem; 748 #if defined(VERSION_SH) || defined(VERSION_CN) 749 /* 0x18 */ u32 unk18; // always 0 750 #endif 751 /* 0x18, 0x1C */ u32 temporarySeqMem; 752 /* 0x1C, 0x20 */ u32 temporaryBankMem; 753 #if defined(VERSION_SH) || defined(VERSION_CN) 754 /* 0x24 */ u32 unk24; // always 0 755 /* 0x28 */ u32 unkMem28; // always 0 756 /* 0x2C */ u32 unkMem2C; // always 0 757 #endif 758 }; // 0x30 on shindou 759 760 struct AudioSessionSettings { 761 /*0x00*/ u32 frequency; 762 /*0x04*/ u8 maxSimultaneousNotes; 763 /*0x05*/ u8 reverbDownsampleRate; // always 1 764 /*0x06*/ u16 reverbWindowSize; 765 /*0x08*/ u16 reverbGain; 766 /*0x0A*/ u16 volume; 767 /*0x0C*/ u32 persistentSeqMem; 768 /*0x10*/ u32 persistentBankMem; 769 /*0x14*/ u32 temporarySeqMem; 770 /*0x18*/ u32 temporaryBankMem; 771 }; // size = 0x1C 772 773 struct AudioBufferParametersEU { 774 /*0x00*/ s16 presetUnk4; // audio frames per vsync? 775 /*0x02*/ u16 frequency; 776 /*0x04*/ u16 aiFrequency; // ?16 777 /*0x06*/ s16 samplesPerFrameTarget; 778 /*0x08*/ s16 maxAiBufferLength; 779 /*0x0A*/ s16 minAiBufferLength; 780 /*0x0C*/ s16 updatesPerFrame; 781 /*0x0E*/ s16 samplesPerUpdate; 782 /*0x10*/ s16 samplesPerUpdateMax; 783 /*0x12*/ s16 samplesPerUpdateMin; 784 /*0x14*/ f32 resampleRate; // contains 32000.0f / frequency 785 /*0x18*/ f32 updatesPerFrameInv; // 1.0f / updatesPerFrame 786 /*0x1C*/ f32 unkUpdatesPerFrameScaled; // 3.0f / (1280.0f * updatesPerFrame) 787 }; 788 789 struct EuAudioCmd { 790 union { 791 #if IS_BIG_ENDIAN 792 struct { 793 u8 op; 794 u8 arg1; 795 u8 arg2; 796 u8 arg3; 797 } s; 798 #else 799 struct { 800 u8 arg3; 801 u8 arg2; 802 u8 arg1; 803 u8 op; 804 } s; 805 #endif 806 s32 first; 807 } u; 808 union { 809 s32 as_s32; 810 u32 as_u32; 811 f32 as_f32; 812 #if IS_BIG_ENDIAN 813 u8 as_u8; 814 s8 as_s8; 815 #else 816 struct { 817 u8 pad0[3]; 818 u8 as_u8; 819 }; 820 struct { 821 u8 pad1[3]; 822 s8 as_s8; 823 }; 824 #endif 825 } u2; 826 }; 827 828 #if defined(VERSION_SH) || defined(VERSION_CN) 829 struct PendingDmaSample { 830 u8 medium; 831 u8 bankId; 832 u8 idx; 833 uintptr_t devAddr; 834 void *vAddr; 835 u8 *resultSampleAddr; 836 s32 state; 837 s32 remaining; 838 s8 *io; 839 /*0x1C*/ struct AudioBankSample sample; 840 /*0x2C*/ OSMesgQueue queue; 841 /*0x44*/ OSMesg mesgs[1]; 842 /*0x48*/ OSIoMesg ioMesg; 843 }; 844 845 struct UnkStruct80343D00 { 846 u32 someIndex; // array into one of the two slots below 847 struct PendingDmaSample arr[2]; 848 }; 849 850 // in external.c 851 extern s32 D_SH_80343CF0; 852 extern struct UnkStruct80343D00 D_SH_80343D00; 853 #endif 854 855 #endif // AUDIO_INTERNAL_H