mirror of https://github.com/zeldaret/tmc.git
398 lines
10 KiB
C
398 lines
10 KiB
C
#ifndef GUARD_M4A_INTERNAL_H
|
|
#define GUARD_M4A_INTERNAL_H
|
|
|
|
#include "gba/gba.h"
|
|
|
|
// ASCII encoding of 'Smsh' in reverse
|
|
// This is presumably short for SMASH, the developer of MKS4AGB.
|
|
#define ID_NUMBER 0x68736D53
|
|
|
|
#define C_V 0x40 // center value for PAN, BEND, and TUNE
|
|
|
|
#define SOUND_MODE_REVERB_VAL 0x0000007F
|
|
#define SOUND_MODE_REVERB_SET 0x00000080
|
|
#define SOUND_MODE_MAXCHN 0x00000F00
|
|
#define SOUND_MODE_MAXCHN_SHIFT 8
|
|
#define SOUND_MODE_MASVOL 0x0000F000
|
|
#define SOUND_MODE_MASVOL_SHIFT 12
|
|
#define SOUND_MODE_FREQ_05734 0x00010000
|
|
#define SOUND_MODE_FREQ_07884 0x00020000
|
|
#define SOUND_MODE_FREQ_10512 0x00030000
|
|
#define SOUND_MODE_FREQ_13379 0x00040000
|
|
#define SOUND_MODE_FREQ_15768 0x00050000
|
|
#define SOUND_MODE_FREQ_18157 0x00060000
|
|
#define SOUND_MODE_FREQ_21024 0x00070000
|
|
#define SOUND_MODE_FREQ_26758 0x00080000
|
|
#define SOUND_MODE_FREQ_31536 0x00090000
|
|
#define SOUND_MODE_FREQ_36314 0x000A0000
|
|
#define SOUND_MODE_FREQ_40137 0x000B0000
|
|
#define SOUND_MODE_FREQ_42048 0x000C0000
|
|
#define SOUND_MODE_FREQ 0x000F0000
|
|
#define SOUND_MODE_FREQ_SHIFT 16
|
|
#define SOUND_MODE_DA_BIT_9 0x00800000
|
|
#define SOUND_MODE_DA_BIT_8 0x00900000
|
|
#define SOUND_MODE_DA_BIT_7 0x00A00000
|
|
#define SOUND_MODE_DA_BIT_6 0x00B00000
|
|
#define SOUND_MODE_DA_BIT 0x00B00000
|
|
#define SOUND_MODE_DA_BIT_SHIFT 20
|
|
|
|
struct WaveData {
|
|
u16 type;
|
|
u16 status;
|
|
u32 freq;
|
|
u32 loopStart;
|
|
u32 size; // number of samples
|
|
s8 data[1]; // samples
|
|
};
|
|
|
|
#define TONEDATA_TYPE_CGB 0x07
|
|
#define TONEDATA_TYPE_FIX 0x08
|
|
#define TONEDATA_TYPE_SPL 0x40 // key split
|
|
#define TONEDATA_TYPE_RHY 0x80 // rhythm
|
|
|
|
#define TONEDATA_P_S_PAN 0xc0
|
|
#define TONEDATA_P_S_PAM TONEDATA_P_S_PAN
|
|
|
|
struct ToneData {
|
|
u8 type;
|
|
u8 key;
|
|
u8 length; // sound length (compatible sound)
|
|
u8 pan_sweep; // pan or sweep (compatible sound ch. 1)
|
|
struct WaveData* wav;
|
|
u8 attack;
|
|
u8 decay;
|
|
u8 sustain;
|
|
u8 release;
|
|
};
|
|
|
|
struct CgbChannel {
|
|
u8 sf;
|
|
u8 ty;
|
|
u8 rightVolume;
|
|
u8 leftVolume;
|
|
u8 at;
|
|
u8 de;
|
|
u8 su;
|
|
u8 re;
|
|
u8 ky;
|
|
u8 ev;
|
|
u8 eg;
|
|
u8 ec;
|
|
u8 echoVolume;
|
|
u8 echoLength;
|
|
u8 d1;
|
|
u8 d2;
|
|
u8 gt;
|
|
u8 mk;
|
|
u8 ve;
|
|
u8 pr;
|
|
u8 rp;
|
|
u8 d3[3];
|
|
u8 d5;
|
|
u8 sg;
|
|
u8 n4;
|
|
u8 pan;
|
|
u8 panMask;
|
|
u8 mo;
|
|
u8 le;
|
|
u8 sw;
|
|
u32 fr;
|
|
u32* wp;
|
|
u32 cp;
|
|
u32 tp;
|
|
u32 pp;
|
|
u32 np;
|
|
u8 d4[8];
|
|
};
|
|
|
|
struct MusicPlayerTrack;
|
|
|
|
struct SoundChannel {
|
|
u8 status;
|
|
u8 type;
|
|
u8 rightVolume;
|
|
u8 leftVolume;
|
|
u8 attack;
|
|
u8 decay;
|
|
u8 sustain;
|
|
u8 release;
|
|
u8 ky;
|
|
u8 ev;
|
|
u8 er;
|
|
u8 el;
|
|
u8 echoVolume;
|
|
u8 echoLength;
|
|
u8 d1;
|
|
u8 d2;
|
|
u8 gt;
|
|
u8 mk;
|
|
u8 ve;
|
|
u8 pr;
|
|
u8 rp;
|
|
u8 d3[3];
|
|
u32 ct;
|
|
u32 fw;
|
|
u32 freq;
|
|
struct WaveData* wav;
|
|
u32 cp;
|
|
struct MusicPlayerTrack* track;
|
|
u32 pp;
|
|
u32 np;
|
|
u32 d4;
|
|
u16 xpi;
|
|
u16 xpc;
|
|
};
|
|
|
|
#define MAX_DIRECTSOUND_CHANNELS 12
|
|
|
|
#define PCM_DMA_BUF_SIZE 1584 // size of Direct Sound buffer
|
|
|
|
struct SoundInfo {
|
|
// This field is normally equal to ID_NUMBER but it is set to other
|
|
// values during sensitive operations for locking purposes.
|
|
// This field should be volatile but isn't. This could potentially cause
|
|
// race conditions.
|
|
u32 ident;
|
|
|
|
vu8 pcmDmaCounter;
|
|
|
|
// Direct Sound
|
|
u8 reverb;
|
|
u8 maxChans;
|
|
u8 masterVolume;
|
|
u8 freq;
|
|
|
|
u8 mode;
|
|
u8 c15;
|
|
u8 pcmDmaPeriod; // number of V-blanks per PCM DMA
|
|
u8 maxLines;
|
|
u8 gap[3];
|
|
s32 pcmSamplesPerVBlank;
|
|
s32 pcmFreq;
|
|
s32 divFreq;
|
|
struct CgbChannel* cgbChans;
|
|
u32 func;
|
|
u32 intp;
|
|
void (*CgbSound)(void);
|
|
void (*CgbOscOff)(u8);
|
|
u32 (*MidiKeyToCgbFreq)(u8, u8, u8);
|
|
u32 MPlayJumpTable;
|
|
void* plynote;
|
|
void (*ExtVolPit)(void);
|
|
u8 gap2[16];
|
|
struct SoundChannel chans[MAX_DIRECTSOUND_CHANNELS];
|
|
s8 pcmBuffer[PCM_DMA_BUF_SIZE * 2];
|
|
};
|
|
|
|
struct SongHeader {
|
|
u8 trackCount;
|
|
u8 blockCount;
|
|
u8 priority;
|
|
u8 reverb;
|
|
struct ToneData* tone;
|
|
u8* part[1];
|
|
};
|
|
|
|
#define MPT_FLG_VOLSET 0x01
|
|
#define MPT_FLG_VOLCHG 0x03
|
|
#define MPT_FLG_PITSET 0x04
|
|
#define MPT_FLG_PITCHG 0x0C
|
|
#define MPT_FLG_START 0x40
|
|
#define MPT_FLG_EXIST 0x80
|
|
|
|
struct MusicPlayerTrack {
|
|
u8 flags;
|
|
u8 wait;
|
|
u8 patternLevel;
|
|
u8 repN;
|
|
u8 gateTime;
|
|
u8 key;
|
|
u8 velocity;
|
|
u8 runningStatus;
|
|
u8 keyM;
|
|
u8 pitM;
|
|
s8 keyShift;
|
|
s8 keyShiftX;
|
|
s8 tune;
|
|
u8 pitX;
|
|
s8 bend;
|
|
u8 bendRange;
|
|
u8 volMR;
|
|
u8 volML;
|
|
u8 vol;
|
|
u8 volX;
|
|
s8 pan;
|
|
s8 panX;
|
|
s8 modM;
|
|
u8 mod;
|
|
u8 modT;
|
|
u8 lfoSpeed;
|
|
u8 lfoSpeedC;
|
|
u8 lfoDelay;
|
|
u8 lfoDelayC;
|
|
u8 priority;
|
|
u8 echoVolume;
|
|
u8 echoLength;
|
|
struct SoundChannel* chan;
|
|
struct ToneData tone;
|
|
u8 gap[10];
|
|
u16 unk_3A;
|
|
u32 unk_3C;
|
|
u8* cmdPtr;
|
|
u8* patternStack[3];
|
|
};
|
|
|
|
#define MUSICPLAYER_STATUS_TRACK 0x0000ffff
|
|
#define MUSICPLAYER_STATUS_PAUSE 0x80000000
|
|
|
|
#define MAX_MUSICPLAYER_TRACKS 16
|
|
|
|
#define TEMPORARY_FADE 0x0001
|
|
#define FADE_IN 0x0002
|
|
#define FADE_VOL_MAX 64
|
|
#define FADE_VOL_SHIFT 2
|
|
|
|
struct MusicPlayerInfo {
|
|
struct SongHeader* songHeader;
|
|
u32 status;
|
|
u8 trackCount;
|
|
u8 priority;
|
|
u8 cmd;
|
|
u8 unk_B;
|
|
u32 clock;
|
|
u8 gap[8];
|
|
u8* memAccArea;
|
|
u16 tempoD;
|
|
u16 tempoU;
|
|
u16 tempoI;
|
|
u16 tempoC;
|
|
u16 fadeOI;
|
|
u16 fadeOC;
|
|
u16 fadeOV;
|
|
struct MusicPlayerTrack* tracks;
|
|
struct ToneData* tone;
|
|
u32 ident;
|
|
u32 func;
|
|
u32 intp;
|
|
};
|
|
|
|
struct MusicPlayer {
|
|
struct MusicPlayerInfo* info;
|
|
struct MusicPlayerTrack* track;
|
|
u8 unk_8;
|
|
u16 unk_A;
|
|
};
|
|
|
|
struct Song {
|
|
struct SongHeader* header;
|
|
u16 ms;
|
|
u16 me;
|
|
};
|
|
|
|
extern const struct MusicPlayer gMPlayTable[];
|
|
extern const struct Song gSongTable[];
|
|
|
|
extern u8 gMPlayMemAccArea[];
|
|
|
|
#define MAX_POKEMON_CRIES 2
|
|
|
|
extern char SoundMainRAM[];
|
|
|
|
extern void* gMPlayJumpTable[];
|
|
|
|
typedef void (*XcmdFunc)(struct MusicPlayerInfo*, struct MusicPlayerTrack*);
|
|
extern const XcmdFunc gXcmdTable[];
|
|
|
|
extern struct CgbChannel gCgbChans[];
|
|
extern const u8 gCgb3Vol[];
|
|
|
|
extern const u8 gScaleTable[];
|
|
extern const u32 gFreqTable[];
|
|
extern const u16 gPcmSamplesPerVBlankTable[];
|
|
|
|
extern const u8 gCgbScaleTable[];
|
|
extern const s16 gCgbFreqTable[];
|
|
extern const u8 gNoiseTable[];
|
|
|
|
extern char gNumMusicPlayers[];
|
|
extern char gMaxLines[];
|
|
|
|
#define NUM_MUSIC_PLAYERS ((u16)gNumMusicPlayers)
|
|
#define MAX_LINES ((u32)gMaxLines)
|
|
|
|
u32 umul3232H32(u32 multiplier, u32 multiplicand);
|
|
void SoundMain(void);
|
|
void SoundMainBTM(void);
|
|
void TrackStop(struct MusicPlayerInfo* mplayInfo, struct MusicPlayerTrack* track);
|
|
void MPlayMain(void);
|
|
void RealClearChain(void* x);
|
|
|
|
void MPlayContinue(struct MusicPlayerInfo* mplayInfo);
|
|
void MPlayStart(struct MusicPlayerInfo* mplayInfo, struct SongHeader* songHeader);
|
|
void MPlayStop(struct MusicPlayerInfo* mplayInfo);
|
|
void FadeOutBody(struct MusicPlayerInfo* mplayInfo);
|
|
void TrkVolPitSet(struct MusicPlayerInfo* mplayInfo, struct MusicPlayerTrack* track);
|
|
void MPlayFadeOut(struct MusicPlayerInfo* mplayInfo, u16 speed);
|
|
void ClearChain(void* x);
|
|
void Clear64byte(void* addr);
|
|
void SoundInit(struct SoundInfo* soundInfo);
|
|
void MPlayExtender(struct CgbChannel* cgbChans);
|
|
void m4aSoundMode(u32 mode);
|
|
void MPlayOpen(struct MusicPlayerInfo* mplayInfo, struct MusicPlayerTrack* track, u8 a3);
|
|
void CgbSound(void);
|
|
void CgbOscOff(u8);
|
|
u32 MidiKeyToCgbFreq(u8, u8, u8);
|
|
void nullsub_141(void);
|
|
void MPlayJumpTableCopy(void** mplayJumpTable);
|
|
void SampleFreqSet(u32 freq);
|
|
void m4aSoundVSyncOn(void);
|
|
void m4aSoundVSyncOff(void);
|
|
|
|
void m4aMPlayTempoControl(struct MusicPlayerInfo* mplayInfo, u16 tempo);
|
|
void m4aMPlayVolumeControl(struct MusicPlayerInfo* mplayInfo, u16 trackBits, u16 volume);
|
|
void m4aMPlayPitchControl(struct MusicPlayerInfo* mplayInfo, u16 trackBits, s16 pitch);
|
|
void m4aMPlayPanpotControl(struct MusicPlayerInfo* mplayInfo, u16 trackBits, s8 pan);
|
|
void ClearModM(struct MusicPlayerTrack* track);
|
|
void m4aMPlayModDepthSet(struct MusicPlayerInfo* mplayInfo, u16 trackBits, u8 modDepth);
|
|
void m4aMPlayLFOSpeedSet(struct MusicPlayerInfo* mplayInfo, u16 trackBits, u8 lfoSpeed);
|
|
|
|
// sound command handler functions
|
|
void ply_fine(struct MusicPlayerInfo*, struct MusicPlayerTrack*);
|
|
void ply_goto(struct MusicPlayerInfo*, struct MusicPlayerTrack*);
|
|
void ply_patt(struct MusicPlayerInfo*, struct MusicPlayerTrack*);
|
|
void ply_pend(struct MusicPlayerInfo*, struct MusicPlayerTrack*);
|
|
void ply_rept(struct MusicPlayerInfo*, struct MusicPlayerTrack*);
|
|
void ply_memacc(struct MusicPlayerInfo*, struct MusicPlayerTrack*);
|
|
void ply_prio(struct MusicPlayerInfo*, struct MusicPlayerTrack*);
|
|
void ply_tempo(struct MusicPlayerInfo*, struct MusicPlayerTrack*);
|
|
void ply_keysh(struct MusicPlayerInfo*, struct MusicPlayerTrack*);
|
|
void ply_voice(struct MusicPlayerInfo*, struct MusicPlayerTrack*);
|
|
void ply_vol(struct MusicPlayerInfo*, struct MusicPlayerTrack*);
|
|
void ply_pan(struct MusicPlayerInfo*, struct MusicPlayerTrack*);
|
|
void ply_bend(struct MusicPlayerInfo*, struct MusicPlayerTrack*);
|
|
void ply_bendr(struct MusicPlayerInfo*, struct MusicPlayerTrack*);
|
|
void ply_lfos(struct MusicPlayerInfo*, struct MusicPlayerTrack*);
|
|
void ply_lfodl(struct MusicPlayerInfo*, struct MusicPlayerTrack*);
|
|
void ply_mod(struct MusicPlayerInfo*, struct MusicPlayerTrack*);
|
|
void ply_modt(struct MusicPlayerInfo*, struct MusicPlayerTrack*);
|
|
void ply_tune(struct MusicPlayerInfo*, struct MusicPlayerTrack*);
|
|
void ply_port(struct MusicPlayerInfo*, struct MusicPlayerTrack*);
|
|
void ply_xcmd(struct MusicPlayerInfo*, struct MusicPlayerTrack*);
|
|
void ply_endtie(struct MusicPlayerInfo*, struct MusicPlayerTrack*);
|
|
void ply_note(struct MusicPlayerInfo*, struct MusicPlayerTrack*);
|
|
|
|
// extended sound command handler functions
|
|
void ply_xxx(struct MusicPlayerInfo*, struct MusicPlayerTrack*);
|
|
void ply_xwave(struct MusicPlayerInfo*, struct MusicPlayerTrack*);
|
|
void ply_xtype(struct MusicPlayerInfo*, struct MusicPlayerTrack*);
|
|
void ply_xatta(struct MusicPlayerInfo*, struct MusicPlayerTrack*);
|
|
void ply_xdeca(struct MusicPlayerInfo*, struct MusicPlayerTrack*);
|
|
void ply_xsust(struct MusicPlayerInfo*, struct MusicPlayerTrack*);
|
|
void ply_xrele(struct MusicPlayerInfo*, struct MusicPlayerTrack*);
|
|
void ply_xiecv(struct MusicPlayerInfo*, struct MusicPlayerTrack*);
|
|
void ply_xiecl(struct MusicPlayerInfo*, struct MusicPlayerTrack*);
|
|
void ply_xleng(struct MusicPlayerInfo*, struct MusicPlayerTrack*);
|
|
void ply_xswee(struct MusicPlayerInfo*, struct MusicPlayerTrack*);
|
|
|
|
#endif // GUARD_M4A_INTERNAL_H
|