mirror of https://github.com/zeldaret/mm.git
246 lines
9.1 KiB
C
246 lines
9.1 KiB
C
#ifndef AUDIO_SEQPLAYER_H
|
|
#define AUDIO_SEQPLAYER_H
|
|
|
|
#include "effects.h"
|
|
#include "list.h"
|
|
#include "playback.h"
|
|
#include "PR/ultratypes.h"
|
|
#include "PR/abi.h"
|
|
#include "unk.h"
|
|
|
|
struct Sample;
|
|
struct Instrument;
|
|
struct TunedSample;
|
|
|
|
#define SEQ_NUM_CHANNELS 16
|
|
|
|
#define NO_LAYER ((SequenceLayer*)(-1))
|
|
|
|
#define TATUMS_PER_BEAT 48
|
|
|
|
#define IS_SEQUENCE_CHANNEL_VALID(ptr) ((uintptr_t)(ptr) != (uintptr_t)&gAudioCtx.sequenceChannelNone)
|
|
#define SEQ_IO_VAL_NONE -1
|
|
|
|
#define MUTE_FLAGS_STOP_SAMPLES (1 << 3) // prevent further noteSubEus from playing
|
|
#define MUTE_FLAGS_STOP_LAYER (1 << 4) // stop something in seqLayer scripts
|
|
#define MUTE_FLAGS_SOFTEN (1 << 5) // lower volume, by default to half
|
|
#define MUTE_FLAGS_STOP_NOTES (1 << 6) // prevent further notes from playing
|
|
#define MUTE_FLAGS_STOP_SCRIPT (1 << 7) // stop processing sequence/channel scripts
|
|
|
|
typedef struct SeqScriptState {
|
|
/* 0x00 */ u8* pc; // program counter
|
|
/* 0x04 */ u8* stack[4];
|
|
/* 0x14 */ u8 remLoopIters[4]; // remaining loop iterations
|
|
/* 0x18 */ u8 depth;
|
|
/* 0x19 */ s8 value;
|
|
} SeqScriptState; // size = 0x1C
|
|
|
|
typedef enum SeqPlayerState {
|
|
/* 0 */ SEQPLAYER_STATE_0,
|
|
/* 1 */ SEQPLAYER_STATE_FADE_IN,
|
|
/* 2 */ SEQPLAYER_STATE_FADE_OUT
|
|
} SeqPlayerState;
|
|
|
|
// Also known as a Group, according to debug strings.
|
|
typedef struct SequencePlayer {
|
|
/* 0x000 */ u8 enabled : 1;
|
|
/* 0x000 */ u8 finished : 1;
|
|
/* 0x000 */ u8 muted : 1;
|
|
/* 0x000 */ u8 seqDmaInProgress : 1;
|
|
/* 0x000 */ u8 fontDmaInProgress : 1;
|
|
/* 0x000 */ u8 recalculateVolume : 1;
|
|
/* 0x000 */ u8 stopScript : 1;
|
|
/* 0x000 */ u8 applyBend : 1;
|
|
/* 0x001 */ u8 state;
|
|
/* 0x002 */ u8 noteAllocPolicy;
|
|
/* 0x003 */ u8 muteFlags;
|
|
/* 0x004 */ u8 seqId;
|
|
/* 0x005 */ u8 defaultFont;
|
|
/* 0x006 */ u8 unk_06[1];
|
|
/* 0x007 */ s8 playerIndex;
|
|
/* 0x008 */ u16 tempo; // tatums per minute
|
|
/* 0x00A */ u16 tempoAcc;
|
|
/* 0x00C */ s16 tempoChange;
|
|
/* 0x00E */ s16 transposition;
|
|
/* 0x010 */ u16 delay;
|
|
/* 0x012 */ u16 fadeTimer;
|
|
/* 0x014 */ u16 storedFadeTimer;
|
|
/* 0x016 */ u16 unk_16;
|
|
/* 0x018 */ u8* seqData;
|
|
/* 0x01C */ f32 fadeVolume;
|
|
/* 0x020 */ f32 fadeVelocity;
|
|
/* 0x024 */ f32 volume;
|
|
/* 0x028 */ f32 muteVolumeScale;
|
|
/* 0x02C */ f32 fadeVolumeScale;
|
|
/* 0x030 */ f32 appliedFadeVolume;
|
|
/* 0x034 */ f32 bend;
|
|
/* 0x038 */ struct SequenceChannel* channels[16];
|
|
/* 0x078 */ SeqScriptState scriptState;
|
|
/* 0x094 */ u8* shortNoteVelocityTable;
|
|
/* 0x098 */ u8* shortNoteGateTimeTable;
|
|
/* 0x09C */ NotePool notePool;
|
|
/* 0x0DC */ s32 skipTicks;
|
|
/* 0x0E0 */ u32 scriptCounter;
|
|
/* 0x0E4 */ UNK_TYPE1 unk_E4[0x74]; // unused struct members for sequence/sound font dma management, according to sm64 decomp
|
|
/* 0x158 */ s8 seqScriptIO[8];
|
|
} SequencePlayer; // size = 0x160
|
|
|
|
// Also known as a SubTrack, according to sm64 debug strings.
|
|
typedef struct SequenceChannel {
|
|
/* 0x00 */ u8 enabled : 1;
|
|
/* 0x00 */ u8 finished : 1;
|
|
/* 0x00 */ u8 stopScript : 1;
|
|
/* 0x00 */ u8 muted : 1; // sets SequenceLayer.muted
|
|
/* 0x00 */ u8 hasInstrument : 1;
|
|
/* 0x00 */ u8 stereoHeadsetEffects : 1;
|
|
/* 0x00 */ u8 largeNotes : 1; // notes specify duration and velocity
|
|
/* 0x00 */ u8 unused : 1;
|
|
union {
|
|
struct {
|
|
/* 0x01 */ u8 freqScale : 1;
|
|
/* 0x01 */ u8 volume : 1;
|
|
/* 0x01 */ u8 pan : 1;
|
|
} s;
|
|
/* 0x01 */ u8 asByte;
|
|
} changes;
|
|
/* 0x02 */ u8 noteAllocPolicy;
|
|
/* 0x03 */ u8 muteFlags;
|
|
/* 0x04 */ u8 targetReverbVol; // or dry/wet mix
|
|
/* 0x05 */ u8 notePriority; // 0-3
|
|
/* 0x06 */ u8 someOtherPriority;
|
|
/* 0x07 */ u8 fontId;
|
|
/* 0x08 */ u8 reverbIndex;
|
|
/* 0x09 */ u8 bookOffset;
|
|
/* 0x0A */ u8 newPan;
|
|
/* 0x0B */ u8 panChannelWeight; // proportion of pan that comes from the channel (0..128)
|
|
/* 0x0C */ u8 gain; // Increases volume by a multiplicative scaling factor. Represented as a UQ4.4 number
|
|
/* 0x0D */ u8 velocityRandomVariance;
|
|
/* 0x0E */ u8 gateTimeRandomVariance;
|
|
/* 0x0F */ u8 combFilterSize;
|
|
/* 0x10 */ u8 surroundEffectIndex;
|
|
/* 0x11 */ u8 channelIndex;
|
|
/* 0x12 */ VibratoSubStruct vibrato;
|
|
/* 0x20 */ u16 delay;
|
|
/* 0x22 */ u16 combFilterGain;
|
|
/* 0x24 */ u16 unk_22; // Used for indexing data
|
|
/* 0x26 */ s16 instOrWave; // either 0 (none), instrument index + 1, or
|
|
// 0x80..0x83 for sawtooth/triangle/sine/square waves.
|
|
/* 0x28 */ s16 transposition;
|
|
/* 0x2C */ f32 volumeScale;
|
|
/* 0x30 */ f32 volume;
|
|
/* 0x34 */ s32 pan;
|
|
/* 0x38 */ f32 appliedVolume;
|
|
/* 0x3C */ f32 freqScale;
|
|
/* 0x40 */ u8 (*dynTable)[][2];
|
|
/* 0x44 */ Note* noteUnused;
|
|
/* 0x48 */ struct SequenceLayer* layerUnused;
|
|
/* 0x4C */ struct Instrument* instrument;
|
|
/* 0x50 */ SequencePlayer* seqPlayer;
|
|
/* 0x54 */ struct SequenceLayer* layers[4];
|
|
/* 0x64 */ SeqScriptState scriptState;
|
|
/* 0x80 */ AdsrSettings adsr;
|
|
/* 0x88 */ NotePool notePool;
|
|
/* 0xC8 */ s8 seqScriptIO[8]; // bridge between sound script and audio lib, "io ports"
|
|
/* 0xD0 */ u8* sfxState; // SfxChannelState
|
|
/* 0xD4 */ s16* filter;
|
|
/* 0xD8 */ StereoData stereoData;
|
|
/* 0xDC */ s32 startSamplePos;
|
|
/* 0xE0 */ s32 unk_E0;
|
|
} SequenceChannel; // size = 0xE4
|
|
|
|
// Might also be known as a Track, according to sm64 debug strings (?).
|
|
typedef struct SequenceLayer {
|
|
/* 0x00 */ u8 enabled : 1;
|
|
/* 0x00 */ u8 finished : 1;
|
|
/* 0x00 */ u8 muted : 1;
|
|
/* 0x00 */ u8 continuousNotes : 1; // keep the same note for consecutive notes with the same sound
|
|
/* 0x00 */ u8 bit3 : 1; // "loaded"?
|
|
/* 0x00 */ u8 ignoreDrumPan : 1;
|
|
/* 0x00 */ u8 bit1 : 1; // "has initialized continuous notes"?
|
|
/* 0x00 */ u8 notePropertiesNeedInit : 1;
|
|
/* 0x01 */ StereoData stereoData;
|
|
/* 0x02 */ u8 instOrWave;
|
|
/* 0x03 */ u8 gateTime;
|
|
/* 0x04 */ u8 semitone;
|
|
/* 0x05 */ u8 portamentoTargetNote;
|
|
/* 0x06 */ u8 pan; // 0..128
|
|
/* 0x07 */ u8 notePan;
|
|
/* 0x08 */ u8 surroundEffectIndex;
|
|
/* 0x09 */ u8 targetReverbVol;
|
|
union {
|
|
struct {
|
|
/* 0x0A */ u16 bit_0 : 1;
|
|
/* 0x0A */ u16 bit_1 : 1;
|
|
/* 0x0A */ u16 bit_2 : 1;
|
|
/* 0x0A */ u16 useVibrato : 1;
|
|
/* 0x0A */ u16 bit_4 : 1;
|
|
/* 0x0A */ u16 bit_5 : 1;
|
|
/* 0x0A */ u16 bit_6 : 1;
|
|
/* 0x0A */ u16 bit_7 : 1;
|
|
/* 0x0A */ u16 bit_8 : 1;
|
|
/* 0x0A */ u16 bit_9 : 1;
|
|
/* 0x0A */ u16 bit_A : 1;
|
|
/* 0x0A */ u16 bit_B : 1;
|
|
/* 0x0A */ u16 bit_C : 1;
|
|
/* 0x0A */ u16 bit_D : 1;
|
|
/* 0x0A */ u16 bit_E : 1;
|
|
/* 0x0A */ u16 bit_F : 1;
|
|
} s;
|
|
/* 0x0A */ u16 asByte;
|
|
} unk_0A;
|
|
/* 0x0C */ VibratoSubStruct vibrato;
|
|
/* 0x1A */ s16 delay;
|
|
/* 0x1C */ s16 gateDelay;
|
|
/* 0x1E */ s16 delay2;
|
|
/* 0x20 */ u16 portamentoTime;
|
|
/* 0x22 */ s16 transposition; // #semitones added to play commands
|
|
// (seq instruction encoding only allows referring to the limited range
|
|
// 0..0x3F; this makes 0x40..0x7F accessible as well)
|
|
/* 0x24 */ s16 shortNoteDefaultDelay;
|
|
/* 0x26 */ s16 lastDelay;
|
|
/* 0x28 */ AdsrSettings adsr;
|
|
/* 0x30 */ Portamento portamento;
|
|
/* 0x3C */ Note* note;
|
|
/* 0x40 */ f32 freqScale;
|
|
/* 0x44 */ f32 bend;
|
|
/* 0x48 */ f32 velocitySquare2;
|
|
/* 0x4C */ f32 velocitySquare; // not sure which one of those corresponds to the sm64 original
|
|
/* 0x50 */ f32 noteVelocity;
|
|
/* 0x54 */ f32 noteFreqScale;
|
|
/* 0x58 */ struct Instrument* instrument;
|
|
/* 0x5C */ struct TunedSample* tunedSample;
|
|
/* 0x60 */ SequenceChannel* channel;
|
|
/* 0x64 */ SeqScriptState scriptState;
|
|
/* 0x80 */ AudioListItem listItem;
|
|
} SequenceLayer; // size = 0x90
|
|
|
|
void AudioScript_SequenceChannelDisable(SequenceChannel* channel);
|
|
void AudioScript_SequencePlayerDisableAsFinished(SequencePlayer* seqPlayer);
|
|
void AudioScript_SequencePlayerDisable(SequencePlayer* seqPlayer);
|
|
void AudioScript_ProcessSequences(s32 arg0);
|
|
void AudioScript_SkipForwardSequence(SequencePlayer* seqPlayer);
|
|
void AudioScript_ResetSequencePlayer(SequencePlayer* seqPlayer);
|
|
void AudioScript_InitSequencePlayerChannels(s32 seqPlayerIndex);
|
|
void AudioScript_InitSequencePlayers(void);
|
|
|
|
typedef enum AudioCustomFunctions {
|
|
/* 0x00 */ AUDIO_CUSTOM_FUNCTION_SEQ_0,
|
|
/* 0x01 */ AUDIO_CUSTOM_FUNCTION_SEQ_1,
|
|
/* 0x02 */ AUDIO_CUSTOM_FUNCTION_SEQ_2,
|
|
/* 0x03 */ AUDIO_CUSTOM_FUNCTION_SEQ_3,
|
|
/* 0xFE */ AUDIO_CUSTOM_FUNCTION_SYNTH = 0xFE,
|
|
/* 0xFF */ AUDIO_CUSTOM_FUNCTION_REVERB
|
|
} AudioCustomFunctions;
|
|
|
|
typedef void (*AudioCustomUpdateFunction)(void);
|
|
typedef u32 (*AudioCustomSeqFunction)(s8 value, SequenceChannel* channel);
|
|
typedef void* (*AudioCustomReverbFunction)(struct Sample*, s32, s8, s32);
|
|
typedef Acmd* (*AudioCustomSynthFunction)(Acmd*, s32, s32);
|
|
|
|
extern AudioCustomUpdateFunction gAudioCustomUpdateFunction;
|
|
extern AudioCustomSeqFunction gAudioCustomSeqFunction;
|
|
extern AudioCustomReverbFunction gAudioCustomReverbFunction;
|
|
extern AudioCustomSynthFunction gAudioCustomSynthFunction;
|
|
|
|
#endif
|