MusyX: add missing files

Former-commit-id: cb7c8e496e17429d4378927ae391fd8591de1c5f
This commit is contained in:
Phillip Stephens 2023-11-29 22:51:46 -08:00
parent add17c11c7
commit 88d1cd404e
15 changed files with 2439 additions and 0 deletions

64
include/musyx/adsr.h Normal file
View File

@ -0,0 +1,64 @@
#ifndef ADSR_H
#define ADSR_H
#include "musyx/musyx.h"
typedef struct ADSR_INFO {
// total size: 0x14
union ai_data {
struct {
// total size: 0x14
s32 atime; // offset 0x0, size 0x4
s32 dtime; // offset 0x4, size 0x4
u16 slevel; // offset 0x8, size 0x2
u16 rtime; // offset 0xA, size 0x2
s32 ascale; // offset 0xC, size 0x4
s32 dscale; // offset 0x10, size 0x4
} dls;
struct {
// total size: 0x8
u16 atime; // offset 0x0, size 0x2
u16 dtime; // offset 0x2, size 0x2
u16 slevel; // offset 0x4, size 0x2
u16 rtime; // offset 0x6, size 0x2
} linear;
} data; // offset 0x0, size 0x14
} ADSR_INFO;
typedef struct ADSR_VARS {
u8 mode;
u8 state;
u32 cnt;
s32 currentVolume;
s32 currentIndex;
s32 currentDelta;
union data {
struct _dls {
u32 aTime;
u32 dTime;
u16 sLevel;
u32 rTime;
u16 cutOff;
u8 aMode;
} dls;
struct _linear {
u32 aTime;
u32 dTime;
u16 sLevel;
u32 rTime;
} linear;
} data;
} ADSR_VARS;
#ifdef __cplusplus
extern "C" {
#endif
u32 adsrHandleLowPrecision(ADSR_VARS* adsr, u16* adsr_start, u16* adsr_delta);
bool adsrRelease(ADSR_VARS* adsr);
#ifdef __cplusplus
}
#endif
#endif // ADSR_H

114
include/musyx/dspvoice.h Normal file
View File

@ -0,0 +1,114 @@
#ifndef DSPVOICE_H
#define DSPVOICE_H
#include "musyx/musyx.h"
#include "musyx/voice.h"
#include "musyx/synthdata.h"
typedef struct DSPvoice {
_PB* pb;
void* patchData;
void* itdBuffer;
struct DSPvoice* next;
struct DSPvoice* prev;
struct DSPvoice* nextAlien;
u32 mesgCallBackUserValue;
u32 prio;
u32 currentAddr;
u32 changed[5];
u32 pitch[5];
u16 volL;
u16 volR;
u16 volS;
u16 volLa;
u16 volRa;
u16 volSa;
u16 volLb;
u16 volRb;
u16 volSb;
u16 lastVolL;
u16 lastVolR;
u16 lastVolS;
u16 lastVolLa;
u16 lastVolRa;
u16 lastVolSa;
u16 lastVolLb;
u16 lastVolRb;
u16 lastVolSb;
u16 smp_id;
SAMPLE_INFO smp_info;
VSampleInfo vSampleInfo;
u8 streamLoopPS;
ADSR_VARS adsr;
u16 srcTypeSelect;
u16 srcCoefSelect;
u16 itdShiftL;
u16 itdShiftR;
u8 singleOffset;
struct {
u32 posHi;
u32 posLo;
u32 pitch;
} playInfo;
struct {
u8 pitch;
u8 vol;
u8 volA;
u8 volB;
} lastUpdate;
u32 virtualSampleID;
u8 state;
u8 postBreak;
u8 startupBreak;
u8 studio;
u32 flags;
} DSPvoice;
typedef struct DSPhostDPop {
// total size: 0x24
s32 l; // offset 0x0, size 0x4
s32 r; // offset 0x4, size 0x4
s32 s; // offset 0x8, size 0x4
s32 lA; // offset 0xC, size 0x4
s32 rA; // offset 0x10, size 0x4
s32 sA; // offset 0x14, size 0x4
s32 lB; // offset 0x18, size 0x4
s32 rB; // offset 0x1C, size 0x4
s32 sB; // offset 0x20, size 0x4
} DSPhostDPop;
typedef struct DSPinput {
// total size: 0xC
u8 studio; // offset 0x0, size 0x1
u16 vol; // offset 0x2, size 0x2
u16 volA; // offset 0x4, size 0x2
u16 volB; // offset 0x6, size 0x2
SND_STUDIO_INPUT* desc; // offset 0x8, size 0x4
} DSPinput;
typedef struct DSPstudioinfo {
// total size: 0xBC
_SPB* spb; // offset 0x0, size 0x4
DSPhostDPop hostDPopSum; // offset 0x4, size 0x24
s32* main[2]; // offset 0x28, size 0x8
s32* auxA[3]; // offset 0x30, size 0xC
s32* auxB[3]; // offset 0x3C, size 0xC
DSPvoice* voiceRoot; // offset 0x48, size 0x4
DSPvoice* alienVoiceRoot; // offset 0x4C, size 0x4
u8 state; // offset 0x50, size 0x1
u8 isMaster; // offset 0x51, size 0x1
u8 numInputs; // offset 0x52, size 0x1
SND_STUDIO_TYPE type; // offset 0x54, size 0x4
DSPinput in[7]; // offset 0x58, size 0x54
SND_AUX_CALLBACK auxAHandler; // offset 0xAC, size 0x4
SND_AUX_CALLBACK auxBHandler; // offset 0xB0, size 0x4
void* auxAUser; // offset 0xB4, size 0x4
void* auxBUser; // offset 0xB8, size 0x4
} DSPstudioinfo;
extern DSPstudioinfo dspStudio[8];
extern DSPvoice* dspVoice;
#endif

26
include/musyx/macros.h Normal file
View File

@ -0,0 +1,26 @@
#ifndef _MUSYX_MACROS
#define _MUSYX_MACROS
#include "musyx/musyx.h"
#include "musyx/synth.h"
#ifdef __cplusplus
extern "C" {
#endif
void macInit();
bool macPostMessage(SND_VOICEID vid, s32 mesg);
u32 macStart(u16 macid, u8 priority, u8 maxVoices, u16 allocId, u8 key, u8 vol, u8 panning, u8 midi,
u8 midiSet, u8 section, u16 step, u16 trackid, u8 new_vid, u8 vGroup, u8 studio,
u32 itd);
void macHandle(u32 deltaTime);
void macMakeInactive(SYNTH_VOICE* svoice, MAC_STATE);
void macSetPedalState(SYNTH_VOICE* svoice, u32 state);
void macSetExternalKeyoff(SYNTH_VOICE* svoice);
void macSampleEndNotify(SYNTH_VOICE* sv);
#ifdef __cplusplus
}
#endif
#endif

22
include/musyx/platform.h Normal file
View File

@ -0,0 +1,22 @@
#ifndef _MUSYX_PLATFORM
#define _MUSYX_PLATFORM
#define MUSY_TARGET_PC 0
#define MUSY_TARGET_DOLPHIN 1
#ifndef MUSY_TARGET
#define MUSY_TARGET MUSY_TARGET_PC
#endif
#ifndef ATTRIBUTE_ALIGN
#if defined(__MWERKS__) || defined(__GNUC__)
#define ATTRIBUTE_ALIGN(num) __attribute__((aligned(num)))
#elif defined(_MSC_VER)
#define ATTRIBUTE_ALIGN(num)
#else
#error unknown compiler
#endif
#endif
#endif

21
include/musyx/s3d.h Normal file
View File

@ -0,0 +1,21 @@
#ifndef _MUSYX_S3D
#define _MUSYX_S3D
#include "musyx/musyx.h"
#include "musyx/synthdata.h"
#ifdef __cplusplus
extern "C" {
#endif
void s3dKillAllEmitter();
void s3dInit(u32); /* extern */
void s3dKillEmitterByFXID(FX_TAB* fxTab, u32 num);
void s3dExit();
#ifdef __cplusplus
}
#endif
#endif

81
include/musyx/sal.h Normal file
View File

@ -0,0 +1,81 @@
#ifndef SAL_H
#define SAL_H
#include "musyx/dspvoice.h"
#include "musyx/musyx.h"
typedef void (*SND_SOME_CALLBACK)();
#define CLAMP(value, min, max) ((value) > (max) ? (max) : (value) < (min) ? (min) : (value))
// TODO matching hack
#define CLAMP_INV(value, min, max) ((value) < (min) ? (min) : (value) > (max) ? (max) : (value))
#ifdef __cplusplus
extern "C" {
#endif
typedef struct SAL_VOLINFO {
// total size: 0x24
f32 volL; // offset 0x0, size 0x4
f32 volR; // offset 0x4, size 0x4
f32 volS; // offset 0x8, size 0x4
f32 volAuxAL; // offset 0xC, size 0x4
f32 volAuxAR; // offset 0x10, size 0x4
f32 volAuxAS; // offset 0x14, size 0x4
f32 volAuxBL; // offset 0x18, size 0x4
f32 volAuxBR; // offset 0x1C, size 0x4
f32 volAuxBS; // offset 0x20, size 0x4
} SAL_VOLINFO;
typedef struct SAL_PANINFO {
// total size: 0x30
u32 pan_i; // offset 0x0, size 0x4
u32 pan_im; // offset 0x4, size 0x4
u32 span_i; // offset 0x8, size 0x4
u32 span_im; // offset 0xC, size 0x4
u32 rpan_i; // offset 0x10, size 0x4
u32 rpan_im; // offset 0x14, size 0x4
f32 pan_f; // offset 0x18, size 0x4
f32 pan_fm; // offset 0x1C, size 0x4
f32 span_f; // offset 0x20, size 0x4
f32 span_fm; // offset 0x24, size 0x4
f32 rpan_f; // offset 0x28, size 0x4
f32 rpan_fm; // offset 0x2C, size 0x4
} SAL_PANINFO;
u32 salInitAi(SND_SOME_CALLBACK, u32, u32*);
u32 salInitDsp(u32);
u32 salInitDspCtrl(u8 numVoices, u8 numStudios, u32 defaultStudioDPL2);
u32 salStartAi();
void salInitHRTFBuffer();
void salActivateVoice(DSPvoice* dsp_vptr, u8 studio);
void salDeactivateVoice(DSPvoice* dsp_vptr);
void salActivateStudio(u8 studio, u32 isMaster, SND_STUDIO_TYPE type);
void salDeactivateStudio(u8 studio);
void salActivateVoice(DSPvoice* dsp_vptr, u8 studio);
void salCalcVolume(u8 voltab_index, SAL_VOLINFO* vi, f32 vol, u32 pan, u32 span, f32 auxa, f32 auxb,
u32 itd, u32 dpl2);
void salReconnectVoice(DSPvoice* dsp_vptr, u8 studio);
void* salMalloc(u32 len);
void salFree(void* addr);
#define SAL_MAX_STUDIONUM 8
extern u8 salMaxStudioNum;
extern u8 salNumVoices;
void salApplyMatrix(const SND_FMATRIX* a, const SND_FVECTOR* b, SND_FVECTOR* out);
f32 salNormalizeVector(SND_FVECTOR* vec);
void salCrossProduct(SND_FVECTOR* out, const SND_FVECTOR* a, const SND_FVECTOR* b);
#define SAL_CROSS_PRODUCT(out, a, b) \
do { \
out.x = (a.y * b.z) - (a.z * b.y); \
out.y = (a.z * b.x) - (a.x * b.z); \
out.z = (a.x * b.y) - (a.y * b.x); \
} while (0)
void salInvertMatrix(SND_FMATRIX* out, const SND_FMATRIX* in);
#ifdef __cplusplus
}
#endif
#endif

30
include/musyx/snd.h Normal file
View File

@ -0,0 +1,30 @@
#ifndef SND_H
#define SND_H
#include "musyx/musyx.h"
#include "musyx/voice.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef s32 (*SND_COMPARE)(void*, void*);
u16 sndRand(void);
s16 sndSin(u16 angle);
void* sndBSearch(void* key, void* base, s32 num, s32 len, SND_COMPARE cmp);
void sndConvertMs(u32* time);
void sndConvertTicks(u32* out, SYNTH_VOICE* svoice);
u32 sndConvert2Ms(u32 time);
u32 sndStreamAllocLength(u32 num, u32 flags);
void sndStreamFree(u32 stid);
u32 sndStreamActivate(u32 stid);
void sndStreamDeactivate(u32 stid);
u32 sndGetPitch(u8 key, u32 sInfo);
s32 sndPitchUpOne(u16 note);
#ifdef __cplusplus
}
#endif
#endif

76
include/musyx/stream.h Normal file
View File

@ -0,0 +1,76 @@
#ifndef _MUSYX_STREAM
#define _MUSYX_STREAM
#include "musyx/musyx.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef s32 (*SND_STREAM_UPDATE_CALLBACK)(void* buffer1, u32 len1, void* buffer2, u32 len2,
u32 user);
typedef struct SNDADPCMinfo {
// total size: 0x28
u16 numCoef; // offset 0x0, size 0x2
u8 initialPS; // offset 0x2, size 0x1
u8 loopPS; // offset 0x3, size 0x1
s16 loopY0; // offset 0x4, size 0x2
s16 loopY1; // offset 0x6, size 0x2
s16 coefTab[8][2]; // offset 0x8, size 0x20
} SNDADPCMinfo;
typedef struct STREAM_INFO {
#if MUSY_VERSION >= MUSY_VERSION_CHECK(1, 5, 4)
u32 nextStreamHandle;
#endif
u32 stid;
u32 flags;
u8 state;
u8 type;
/* These were moved to near the start of the structure in later versions */
#if MUSY_VERSION >= MUSY_VERSION_CHECK(1, 5, 4)
u8 hwStreamHandle;
u8 lastPSFromBuffer;
#endif
SND_STREAM_UPDATE_CALLBACK updateFunction;
s16* buffer;
u32 size;
u32 bytes;
u32 last;
SNDADPCMinfo adpcmInfo;
volatile SND_VOICEID voice;
u32 user;
u32 frq;
u8 prio;
u8 vol;
u8 pan;
u8 span;
u8 auxa;
u8 auxb;
#if MUSY_VERSION >= MUSY_VERSION_CHECK(1, 5, 4)
u8 orgPan;
u8 orgSPan;
#endif
u8 studio;
/* These were moved to near the start of the structure in later versions */
#if MUSY_VERSION <= MUSY_VERSION_CHECK(1, 5, 3)
u8 hwStreamHandle;
u32 nextStreamHandle;
#endif
} STREAM_INFO;
#if MUSY_VERSION >= MUSY_VERSION_CHECK(1, 5, 4)
void streamOutputModeChanged();
#endif
void streamInit(); /* extern */
void streamKill(SND_VOICEID voice);
void streamCorrectLoops();
#ifdef __cplusplus
}
#endif
#endif

211
include/musyx/synthdata.h Normal file
View File

@ -0,0 +1,211 @@
#ifndef SYNTHDATA_H
#define SYNTHDATA_H
#include "musyx/macros.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct SAMPLE_INFO {
// total size: 0x20
u32 info; // offset 0x0, size 0x4
void* addr; // offset 0x4, size 0x4
void* extraData; // offset 0x8, size 0x4
u32 offset; // offset 0xC, size 0x4
u32 length; // offset 0x10, size 0x4
u32 loop; // offset 0x14, size 0x4
u32 loopLength; // offset 0x18, size 0x4
u8 compType; // offset 0x1C, size 0x1
} SAMPLE_INFO;
typedef struct GROUP_DATA {
// total size: 0x28
u32 nextOff; // offset 0x0, size 0x4
u16 id; // offset 0x4, size 0x2
u16 type; // offset 0x6, size 0x2
u32 macroOff; // offset 0x8, size 0x4
u32 sampleOff; // offset 0xC, size 0x4
u32 curveOff; // offset 0x10, size 0x4
u32 keymapOff; // offset 0x14, size 0x4
u32 layerOff; // offset 0x18, size 0x4
union {
struct fx {
// total size: 0x4
u32 tableOff; // offset 0x0, size 0x4
} fx;
struct song {
// total size: 0xC
u32 normpageOff; // offset 0x0, size 0x4
u32 drumpageOff; // offset 0x4, size 0x4
u32 midiSetupOff; // offset 0x8, size 0x4
} song;
} data; // offset 0x1C, size 0xC
} GROUP_DATA;
typedef struct SAMPLE_HEADER {
// total size: 0x10
u32 info; // offset 0x0, size 0x4
u32 length; // offset 0x4, size 0x4
u32 loopOffset; // offset 0x8, size 0x4
u32 loopLength; // offset 0xC, size 0x4
} SAMPLE_HEADER;
typedef struct SDIR_DATA {
// total size: 0x20
u16 id; // offset 0x0, size 0x2
u16 ref_cnt; // offset 0x2, size 0x2
u32 offset; // offset 0x4, size 0x4
void* addr; // offset 0x8, size 0x4
SAMPLE_HEADER header; // offset 0xC, size 0x10
u32 extraData; // offset 0x1C, size 0x4
} SDIR_DATA;
typedef struct SDIR_TAB {
// total size: 0xC
SDIR_DATA* data; // offset 0x0, size 0x4
void* base; // offset 0x4, size 0x4
u16 numSmp; // offset 0x8, size 0x2
u16 res; // offset 0xA, size 0x2
} SDIR_TAB;
typedef struct DATA_TAB {
// total size: 0x8
void* data; // offset 0x0, size 0x4
u16 id; // offset 0x4, size 0x2
u16 refCount; // offset 0x6, size 0x2
} DATA_TAB;
typedef struct LAYER_TAB {
// total size: 0xC
void* data; // offset 0x0, size 0x4
u16 id; // offset 0x4, size 0x2
u16 num; // offset 0x6, size 0x2
u16 refCount; // offset 0x8, size 0x2
u16 reserved; // offset 0xA, size 0x2
} LAYER_TAB;
typedef struct MAC_MAINTAB {
// total size: 0x4
u16 num; // offset 0x0, size 0x2
u16 subTabIndex; // offset 0x2, size 0x2
} MAC_MAINTAB;
typedef struct MAC_SUBTAB {
// total size: 0x8
void* data; // offset 0x0, size 0x4
u16 id; // offset 0x4, size 0x2
u16 refCount; // offset 0x6, size 0x2
} MAC_SUBTAB;
typedef struct GSTACK {
// total size: 0xC
GROUP_DATA* gAddr; // offset 0x0, size 0x4
SDIR_DATA* sdirAddr; // offset 0x4, size 0x4
void* prjAddr; // offset 0x8, size 0x4
} GSTACK;
typedef struct LAYER {
// total size: 0xC
u16 id; // offset 0x0, size 0x2
u8 keyLow; // offset 0x2, size 0x1
u8 keyHigh; // offset 0x3, size 0x1
s8 transpose; // offset 0x4, size 0x1
u8 volume; // offset 0x5, size 0x1
s16 prioOffset; // offset 0x6, size 0x2
u8 panning; // offset 0x8, size 0x1
u8 reserved[3]; // offset 0x9, size 0x3
} LAYER;
typedef struct KEYMAP {
// total size: 0x8
u16 id; // offset 0x0, size 0x2
s8 transpose; // offset 0x2, size 0x1
u8 panning; // offset 0x3, size 0x1
s16 prioOffset; // offset 0x4, size 0x2
u8 reserved[2]; // offset 0x6, size 0x2
} KEYMAP;
typedef struct MEM_DATA {
// total size: 0x408
u32 nextOff; // offset 0x0, size 0x4
u16 id; // offset 0x4, size 0x2
u16 reserved; // offset 0x6, size 0x2
union {
struct {
// total size: 0x10
u32 num; // offset 0x0, size 0x4
LAYER entry[1]; // offset 0x4, size 0xC
} layer;
KEYMAP map[128];
u8 tab[1];
MSTEP cmd[1][2];
} data; // offset 0x8, size 0x400
} MEM_DATA;
typedef struct POOL_DATA {
// total size: 0x10
u32 macroOff; // offset 0x0, size 0x4
u32 curveOff; // offset 0x4, size 0x4
u32 keymapOff; // offset 0x8, size 0x4
u32 layerOff; // offset 0xC, size 0x4
} POOL_DATA;
typedef struct FX_TAB {
// total size: 0xA
u16 id; // offset 0x0, size 0x2
u16 macro; // offset 0x2, size 0x2
u8 maxVoices; // offset 0x4, size 0x1
u8 priority; // offset 0x5, size 0x1
u8 volume; // offset 0x6, size 0x1
u8 panning; // offset 0x7, size 0x1
u8 key; // offset 0x8, size 0x1
u8 vGroup; // offset 0x9, size 0x1
} FX_TAB;
typedef struct FX_DATA {
// total size: 0xE
u16 num; // offset 0x0, size 0x2
u16 reserverd; // offset 0x2, size 0x2
FX_TAB fx[1]; // offset 0x4, size 0xA
} FX_DATA;
typedef struct FX_GROUP {
// total size: 0x8
u16 gid; // offset 0x0, size 0x2
u16 fxNum; // offset 0x2, size 0x2
FX_TAB* fxTab; // offset 0x4, size 0x4
} FX_GROUP;
void dataInit(u32, u32); /* extern */
void dataExit();
#if MUSY_VERSION >= MUSY_VERSION_CHECK(2, 0, 3)
void dataInitStack(unsigned long aramBase, unsigned long aramSize);
#else
void dataInitStack(); /* extern */
#endif
u32 dataInsertSDir(SDIR_DATA* sdir, void* smp_data);
u32 dataRemoveSDir(SDIR_DATA* sdir);
u32 dataInsertMacro(u16 mid, void* macroaddr);
u32 dataRemoveMacro(u16 mid);
u32 dataInsertCurve(u16 cid, void* curvedata);
u32 dataRemoveCurve(u16 sid);
s32 dataGetSample(u16 sid, SAMPLE_INFO* newsmp);
void* dataGetCurve(u16 cid);
u32 dataAddSampleReference(u16 sid);
u32 dataRemoveSampleReference(u16 sid);
u32 dataInsertKeymap(u16 cid, void* keymapdata);
u32 dataRemoveKeymap(u16 sid);
u32 dataInsertLayer(u16 cid, void* layerdata, u16 size);
u32 dataRemoveLayer(u16 sid);
u32 dataInsertFX(u16 gid, FX_TAB* fx, u16 fxNum);
bool dataRemoveFX(u16 gid);
FX_TAB* dataGetFX(u16 fid);
void* dataGetLayer(u16 cid, u16* n);
void* dataGetKeymap(u16 cid);
MSTEP* dataGetMacro(u16 mid);
#ifdef __cplusplus
}
#endif
#endif // SYNTHDATA_H

258
include/musyx/voice.h Normal file
View File

@ -0,0 +1,258 @@
#ifndef _MUSYX_VOICE_H_
#define _MUSYX_VOICE_H_
#include "musyx/synth.h"
#include "musyx/version.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct _PBMIX {
// total size: 0x24
u16 vL; // offset 0x0, size 0x2
u16 vDeltaL; // offset 0x2, size 0x2
u16 vR; // offset 0x4, size 0x2
u16 vDeltaR; // offset 0x6, size 0x2
u16 vAuxAL; // offset 0x8, size 0x2
u16 vDeltaAuxAL; // offset 0xA, size 0x2
u16 vAuxAR; // offset 0xC, size 0x2
u16 vDeltaAuxAR; // offset 0xE, size 0x2
u16 vAuxBL; // offset 0x10, size 0x2
u16 vDeltaAuxBL; // offset 0x12, size 0x2
u16 vAuxBR; // offset 0x14, size 0x2
u16 vDeltaAuxBR; // offset 0x16, size 0x2
u16 vAuxBS; // offset 0x18, size 0x2
u16 vDeltaAuxBS; // offset 0x1A, size 0x2
u16 vS; // offset 0x1C, size 0x2
u16 vDeltaS; // offset 0x1E, size 0x2
u16 vAuxAS; // offset 0x20, size 0x2
u16 vDeltaAuxAS; // offset 0x22, size 0x2
} _PBMIX;
typedef struct _PBITD {
// total size: 0xE
u16 flag; // offset 0x0, size 0x2
u16 bufferHi; // offset 0x2, size 0x2
u16 bufferLo; // offset 0x4, size 0x2
u16 shiftL; // offset 0x6, size 0x2
u16 shiftR; // offset 0x8, size 0x2
u16 targetShiftL; // offset 0xA, size 0x2
u16 targetShiftR; // offset 0xC, size 0x2
} _PBITD;
typedef struct _PBUPDATE {
// total size: 0xE
u16 updNum[5]; // offset 0x0, size 0xA
u16 dataHi; // offset 0xA, size 0x2
u16 dataLo; // offset 0xC, size 0x2
} _PBUPDATE;
typedef struct _PBDPOP {
// total size: 0x12
u16 aL; // offset 0x0, size 0x2
u16 aAuxAL; // offset 0x2, size 0x2
u16 aAuxBL; // offset 0x4, size 0x2
u16 aR; // offset 0x6, size 0x2
u16 aAuxAR; // offset 0x8, size 0x2
u16 aAuxBR; // offset 0xA, size 0x2
u16 aS; // offset 0xC, size 0x2
u16 aAuxAS; // offset 0xE, size 0x2
u16 aAuxBS; // offset 0x10, size 0x2
} _PBDPOP;
typedef struct _PBVE {
// total size: 0x4
u16 currentVolume; // offset 0x0, size 0x2
u16 currentDelta; // offset 0x2, size 0x2
} _PBVE;
typedef struct _PBFIR {
// total size: 0x6
u16 numCoefs; // offset 0x0, size 0x2
u16 coefsHi; // offset 0x2, size 0x2
u16 coefsLo; // offset 0x4, size 0x2
} _PBFIR;
typedef struct _PBADDR {
// total size: 0x10
u16 loopFlag; // offset 0x0, size 0x2
u16 format; // offset 0x2, size 0x2
u16 loopAddressHi; // offset 0x4, size 0x2
u16 loopAddressLo; // offset 0x6, size 0x2
u16 endAddressHi; // offset 0x8, size 0x2
u16 endAddressLo; // offset 0xA, size 0x2
u16 currentAddressHi; // offset 0xC, size 0x2
u16 currentAddressLo; // offset 0xE, size 0x2
} _PBADDR;
typedef struct _PBADPCM {
// total size: 0x28
u16 a[8][2]; // offset 0x0, size 0x20
u16 gain; // offset 0x20, size 0x2
u16 pred_scale; // offset 0x22, size 0x2
u16 yn1; // offset 0x24, size 0x2
u16 yn2; // offset 0x26, size 0x2
} _PBADPCM;
typedef struct _PBSRC {
// total size: 0xE
u16 ratioHi; // offset 0x0, size 0x2
u16 ratioLo; // offset 0x2, size 0x2
u16 currentAddressFrac; // offset 0x4, size 0x2
u16 last_samples[4]; // offset 0x6, size 0x8
} _PBSRC;
typedef struct _PBADPCMLOOP {
// total size: 0x6
u16 loop_pred_scale; // offset 0x0, size 0x2
u16 loop_yn1; // offset 0x2, size 0x2
u16 loop_yn2; // offset 0x4, size 0x2
} _PBADPCMLOOP;
typedef struct _PB {
// total size: 0xBC
u16 nextHi; // offset 0x0, size 0x2
u16 nextLo; // offset 0x2, size 0x2
u16 currHi; // offset 0x4, size 0x2
u16 currLo; // offset 0x6, size 0x2
u16 srcSelect; // offset 0x8, size 0x2
u16 coefSelect; // offset 0xA, size 0x2
u16 mixerCtrl; // offset 0xC, size 0x2
u16 state; // offset 0xE, size 0x2
u16 loopType; // offset 0x10, size 0x2
_PBMIX mix; // offset 0x12, size 0x24
_PBITD itd; // offset 0x36, size 0xE
_PBUPDATE update; // offset 0x44, size 0xE
_PBDPOP dpop; // offset 0x52, size 0x12
_PBVE ve; // offset 0x64, size 0x4
_PBFIR fir; // offset 0x68, size 0x6
_PBADDR addr; // offset 0x6E, size 0x10
_PBADPCM adpcm; // offset 0x7E, size 0x28
_PBSRC src; // offset 0xA6, size 0xE
_PBADPCMLOOP adpcmLoop; // offset 0xB4, size 0x6
u16 streamLoopCnt; // offset 0xBA, size 0x2
} _PB;
typedef struct VSampleInfo {
// total size: 0xC
void* loopBufferAddr; // offset 0x0, size 0x4
u32 loopBufferLength; // offset 0x4, size 0x4
u8 inLoopBuffer; // offset 0x8, size 0x1
} VSampleInfo;
typedef struct SND_VIRTUALSAMPLE_INFO {
// total size: 0x14
u16 smpID; // offset 0x0, size 0x2
u16 instID; // offset 0x2, size 0x2
union vsData {
struct vsUpdate {
// total size: 0x10
u32 off1; // offset 0x0, size 0x4
u32 len1; // offset 0x4, size 0x4
u32 off2; // offset 0x8, size 0x4
u32 len2; // offset 0xC, size 0x4
} update;
} data;
} SND_VIRTUALSAMPLE_INFO;
typedef struct VS_BUFFER {
// total size: 0x24
u8 state; // offset 0x0, size 0x1
u8 hwId; // offset 0x1, size 0x1
u8 smpType; // offset 0x2, size 0x1
u8 voice; // offset 0x3, size 0x1
u32 last; // offset 0x4, size 0x4
u32 finalGoodSamples; // offset 0x8, size 0x4
u32 finalLast; // offset 0xC, size 0x4
SND_VIRTUALSAMPLE_INFO info; // offset 0x10, size 0x14
} VS_BUFFER;
typedef struct _VS {
// total size: 0x950
u8 numBuffers; // offset 0x0, size 0x1
u32 bufferLength; // offset 0x4, size 0x4
VS_BUFFER streamBuffer[64]; // offset 0x8, size 0x900
u8 voices[64]; // offset 0x908, size 0x40
u16 nextInstID; // offset 0x948, size 0x2
u32 (*callback)(u8,
SND_VIRTUALSAMPLE_INFO*); // offset 0x94C, size 0x4
} VS;
extern VS vs;
typedef struct _SPB {
// total size: 0x36
u16 dpopLHi; // offset 0x0, size 0x2
u16 dpopLLo; // offset 0x2, size 0x2
u16 dpopLDelta; // offset 0x4, size 0x2
u16 dpopRHi; // offset 0x6, size 0x2
u16 dpopRLo; // offset 0x8, size 0x2
u16 dpopRDelta; // offset 0xA, size 0x2
u16 dpopSHi; // offset 0xC, size 0x2
u16 dpopSLo; // offset 0xE, size 0x2
u16 dpopSDelta; // offset 0x10, size 0x2
u16 dpopALHi; // offset 0x12, size 0x2
u16 dpopALLo; // offset 0x14, size 0x2
u16 dpopALDelta; // offset 0x16, size 0x2
u16 dpopARHi; // offset 0x18, size 0x2
u16 dpopARLo; // offset 0x1A, size 0x2
u16 dpopARDelta; // offset 0x1C, size 0x2
u16 dpopASHi; // offset 0x1E, size 0x2
u16 dpopASLo; // offset 0x20, size 0x2
u16 dpopASDelta; // offset 0x22, size 0x2
u16 dpopBLHi; // offset 0x24, size 0x2
u16 dpopBLLo; // offset 0x26, size 0x2
u16 dpopBLDelta; // offset 0x28, size 0x2
u16 dpopBRHi; // offset 0x2A, size 0x2
u16 dpopBRLo; // offset 0x2C, size 0x2
u16 dpopBRDelta; // offset 0x2E, size 0x2
u16 dpopBSHi; // offset 0x30, size 0x2
u16 dpopBSLo; // offset 0x32, size 0x2
u16 dpopBSDelta; // offset 0x34, size 0x2
} _SPB;
extern u16 voicePrioSortRootListRoot;
extern u8 voiceMusicRunning;
extern u8 voiceFxRunning;
extern u8 voiceListInsert;
extern u8 voiceListRoot;
void vsInit(); /* extern */
u32 vsSampleStartNotify(u8 voice);
void vsSampleEndNotify(u32 pubID);
void voiceSetPriority(SYNTH_VOICE* svoice, u8 prio);
u32 voiceIsLastStarted(SYNTH_VOICE* svoice);
void voiceSetLastStarted(SYNTH_VOICE* svoice);
void voiceResetLastStarted(SYNTH_VOICE* svoice);
void voiceInitLastStarted();
s32 voiceKillSound(u32 voiceid);
void voiceKill(u32 vi);
void voiceSetPriority(SYNTH_VOICE* svoice, u8 prio);
u32 voiceIsLastStarted(SYNTH_VOICE* svoice);
void voiceSetLastStarted(SYNTH_VOICE* svoice);
void voiceResetLastStarted(SYNTH_VOICE* svoice);
void voiceInitLastStarted();
s32 voiceKillSound(u32 voiceid);
void voiceKill(u32 vi);
u32 voiceBlock(u8 prio);
u32 voiceAllocate(u8 priority, u8 maxVoices, u16 allocId, u8 fxFlag);
#if MUSY_VERSION >= MUSY_VERSION_CHECK(2, 0, 3)
int voiceAllocatePeek(u8 priority, u8 maxVoices, u32 allocId, u8 fxFlag, u32* currentAllocId);
#endif
void voiceFree(SYNTH_VOICE* svoice);
void voiceUnblock(u32 voice);
void voiceRemovePriority(SYNTH_VOICE* svoice);
void vidInit();
u32 vidGetInternalId(SND_VOICEID id);
void vidRemoveVoiceReferences(SYNTH_VOICE* svoice);
u32 vidMakeNew(SYNTH_VOICE* svoice, u32 isMaster);
u32 vidMakeRoot(SYNTH_VOICE* svoice);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,428 @@
#include "musyx/dsp_import.h"
#ifdef __cplusplus
extern "C" {
#endif
char dspSlave[0x19E0] ATTRIBUTE_ALIGN(32) = {
0x00, 0x00, 0x00, 0x00, 0x02, 0x9F, 0x0C, 0x10, 0x02, 0x9F, 0x0C, 0x1F, 0x02, 0x9F, 0x0C, 0x3B,
0x02, 0x9F, 0x0C, 0x4A, 0x02, 0x9F, 0x0C, 0x50, 0x02, 0x9F, 0x0C, 0x82, 0x02, 0x9F, 0x0C, 0x88,
0x13, 0x02, 0x13, 0x03, 0x12, 0x04, 0x13, 0x05, 0x13, 0x06, 0x8E, 0x00, 0x8C, 0x00, 0x8B, 0x00,
0x00, 0x92, 0x00, 0xFF, 0x81, 0x00, 0x89, 0x00, 0x00, 0x9E, 0x0E, 0x80, 0x00, 0xFE, 0x0E, 0x1B,
0x81, 0x00, 0x00, 0xFE, 0x0E, 0x31, 0x16, 0xFC, 0xDC, 0xD1, 0x16, 0xFD, 0x00, 0x00, 0x16, 0xFB,
0x00, 0x01, 0x26, 0xFC, 0x02, 0xA0, 0x80, 0x00, 0x02, 0x9C, 0x00, 0x29, 0x02, 0x9F, 0x00, 0x45,
0x13, 0x02, 0x13, 0x03, 0x12, 0x04, 0x13, 0x05, 0x13, 0x06, 0x8E, 0x00, 0x8C, 0x00, 0x8B, 0x00,
0x00, 0x92, 0x00, 0xFF, 0x16, 0xFC, 0xDC, 0xD1, 0x16, 0xFD, 0x00, 0x01, 0x16, 0xFB, 0x00, 0x01,
0x26, 0xFC, 0x02, 0xA0, 0x80, 0x00, 0x02, 0x9C, 0x00, 0x40, 0x8E, 0x00, 0x81, 0x00, 0x89, 0x00,
0x00, 0x9F, 0xBA, 0xBE, 0x26, 0xFE, 0x02, 0xC0, 0x80, 0x00, 0x02, 0x9C, 0x00, 0x4A, 0x82, 0x00,
0x02, 0x94, 0x00, 0x4A, 0x23, 0xFF, 0x81, 0x00, 0x26, 0xFE, 0x02, 0xC0, 0x80, 0x00, 0x02, 0x9C,
0x00, 0x54, 0x27, 0xFF, 0x02, 0x40, 0x7F, 0xFF, 0x2E, 0xCE, 0x2F, 0xCF, 0x16, 0xCD, 0x0C, 0x00,
0x81, 0x00, 0x2E, 0xC9, 0x1F, 0xFB, 0x2F, 0xCB, 0x02, 0xBF, 0x05, 0x5C, 0x00, 0x80, 0x0C, 0x00,
0x8E, 0x00, 0x81, 0x00, 0x89, 0x70, 0xB1, 0x00, 0x02, 0x91, 0x00, 0x7E, 0x0A, 0x12, 0xC1, 0x00,
0x02, 0x92, 0x00, 0x7E, 0x00, 0x9F, 0x0A, 0xFF, 0x4C, 0x00, 0x1C, 0x7E, 0x02, 0x13, 0x1C, 0x7E,
0x17, 0x6F, 0x16, 0xFC, 0xFB, 0xAD, 0x16, 0xFD, 0x80, 0x80, 0x00, 0x21, 0x16, 0xFC, 0xBA, 0xAD,
0x2E, 0xFD, 0x00, 0x21, 0x81, 0x00, 0x89, 0x70, 0x8E, 0x78, 0x2E, 0xCE, 0x2F, 0xCF, 0x00, 0x9E,
0x0E, 0x44, 0x2E, 0xCD, 0x0E, 0x00, 0x2E, 0xC9, 0x00, 0x9E, 0x00, 0x40, 0x2E, 0xCB, 0x00, 0x81,
0x0E, 0x44, 0x00, 0x82, 0x00, 0x00, 0x00, 0x9B, 0x00, 0x9F, 0x00, 0x9A, 0x01, 0x40, 0x81, 0x00,
0x89, 0x00, 0x8F, 0x00, 0x02, 0xBF, 0x05, 0x5C, 0x19, 0x3E, 0x19, 0x3C, 0xB1, 0x00, 0x19, 0x3F,
0x02, 0x94, 0x00, 0xA6, 0x00, 0x5A, 0x1B, 0x5E, 0x02, 0x9F, 0x00, 0xAE, 0x99, 0x00, 0x1B, 0x5E,
0x1B, 0x5C, 0x00, 0x7B, 0x00, 0xAD, 0x4C, 0x00, 0x1B, 0x5E, 0x1B, 0x5C, 0x19, 0x3E, 0x19, 0x3C,
0xB1, 0x00, 0x19, 0x3F, 0x02, 0x94, 0x00, 0xB8, 0x00, 0x5A, 0x1B, 0x5E, 0x02, 0x9F, 0x00, 0xC0,
0x99, 0x00, 0x1B, 0x5E, 0x1B, 0x5C, 0x00, 0x7B, 0x00, 0xBF, 0x4C, 0x00, 0x1B, 0x5E, 0x1B, 0x5C,
0x19, 0x3E, 0x19, 0x3C, 0xB1, 0x00, 0x19, 0x3F, 0x02, 0x94, 0x00, 0xCA, 0x00, 0x5A, 0x1B, 0x5E,
0x02, 0x9F, 0x00, 0xD2, 0x99, 0x00, 0x1B, 0x5E, 0x1B, 0x5C, 0x00, 0x7B, 0x00, 0xD1, 0x4C, 0x00,
0x1B, 0x5E, 0x1B, 0x5C, 0x00, 0x82, 0x04, 0x00, 0x19, 0x3E, 0x19, 0x3C, 0xB1, 0x79, 0x02, 0x94,
0x00, 0xDD, 0x00, 0x5A, 0x1B, 0x5E, 0x02, 0x9F, 0x00, 0xE5, 0x99, 0x00, 0x1B, 0x5E, 0x1B, 0x5C,
0x00, 0x7B, 0x00, 0xE4, 0x4C, 0x00, 0x1B, 0x5E, 0x1B, 0x5C, 0x19, 0x3E, 0x19, 0x3C, 0xB1, 0x79,
0x02, 0x94, 0x00, 0xEE, 0x00, 0x5A, 0x1B, 0x5E, 0x02, 0x9F, 0x00, 0xF6, 0x99, 0x00, 0x1B, 0x5E,
0x1B, 0x5C, 0x00, 0x7B, 0x00, 0xF5, 0x4C, 0x00, 0x1B, 0x5E, 0x1B, 0x5C, 0x19, 0x3E, 0x19, 0x3C,
0xB1, 0x79, 0x02, 0x94, 0x00, 0xFF, 0x00, 0x5A, 0x1B, 0x5E, 0x02, 0x9F, 0x01, 0x07, 0x99, 0x00,
0x1B, 0x5E, 0x1B, 0x5C, 0x00, 0x7B, 0x01, 0x06, 0x4C, 0x00, 0x1B, 0x5E, 0x1B, 0x5C, 0x00, 0x82,
0x07, 0xC0, 0x19, 0x3E, 0x19, 0x3C, 0xB1, 0x79, 0x02, 0x94, 0x01, 0x12, 0x00, 0x5A, 0x1B, 0x5E,
0x02, 0x9F, 0x01, 0x1A, 0x99, 0x00, 0x1B, 0x5E, 0x1B, 0x5C, 0x00, 0x7B, 0x01, 0x19, 0x4C, 0x00,
0x1B, 0x5E, 0x1B, 0x5C, 0x19, 0x3E, 0x19, 0x3C, 0xB1, 0x79, 0x02, 0x94, 0x01, 0x23, 0x00, 0x5A,
0x1B, 0x5E, 0x02, 0x9F, 0x01, 0x2B, 0x99, 0x00, 0x1B, 0x5E, 0x1B, 0x5C, 0x00, 0x7B, 0x01, 0x2A,
0x4C, 0x00, 0x1B, 0x5E, 0x1B, 0x5C, 0x19, 0x3E, 0x19, 0x3C, 0xB1, 0x79, 0x02, 0x94, 0x01, 0x34,
0x00, 0x5A, 0x1B, 0x5E, 0x02, 0x9F, 0x01, 0x3C, 0x99, 0x00, 0x1B, 0x5E, 0x1B, 0x5C, 0x00, 0x7B,
0x01, 0x3B, 0x4C, 0x00, 0x1B, 0x5E, 0x1B, 0x5C, 0x02, 0x9F, 0x00, 0x68, 0x00, 0x85, 0xFF, 0xFF,
0x81, 0x50, 0x89, 0x40, 0x8E, 0x48, 0x00, 0xFA, 0x0E, 0x17, 0x00, 0xF8, 0x0E, 0x18, 0x00, 0x81,
0x00, 0x00, 0x02, 0xBF, 0x04, 0xF1, 0x00, 0xDA, 0x0E, 0x17, 0x00, 0xD8, 0x0E, 0x18, 0x89, 0x48,
0x00, 0x81, 0x04, 0x00, 0x02, 0xBF, 0x04, 0xF1, 0x00, 0xDA, 0x0E, 0x17, 0x00, 0xD8, 0x0E, 0x18,
0x89, 0x48, 0x00, 0x81, 0x07, 0xC0, 0x02, 0xBF, 0x04, 0xF1, 0x02, 0x9F, 0x00, 0x68, 0x00, 0x86,
0x07, 0xC0, 0x02, 0xBF, 0x04, 0x84, 0x02, 0x9F, 0x00, 0x68, 0x81, 0x00, 0x8E, 0x00, 0x19, 0x1E,
0x19, 0x1C, 0x2E, 0xCE, 0x2C, 0xCF, 0x16, 0xCD, 0x00, 0x00, 0x16, 0xC9, 0x00, 0x01, 0x16, 0xCB,
0x07, 0x80, 0x02, 0xBF, 0x05, 0x5C, 0x02, 0x9F, 0x00, 0x68, 0x81, 0x00, 0x89, 0x70, 0x8E, 0x60,
0x2E, 0xCE, 0x2C, 0xCF, 0x16, 0xCD, 0x0E, 0x44, 0x16, 0xC9, 0x00, 0x00, 0x89, 0x00, 0x0D, 0x20,
0x2D, 0xCB, 0x4C, 0x00, 0x1C, 0x80, 0x00, 0x80, 0x02, 0x80, 0x00, 0x81, 0x00, 0x00, 0x00, 0x82,
0x01, 0x40, 0x00, 0x83, 0x0E, 0x44, 0x0A, 0x00, 0x27, 0xC9, 0x03, 0xA0, 0x00, 0x04, 0x02, 0x9C,
0x01, 0x8C, 0x2E, 0xCE, 0x2C, 0xCF, 0x16, 0xCD, 0x0E, 0x54, 0x16, 0xC9, 0x00, 0x00, 0x16, 0xCB,
0x02, 0x60, 0x00, 0x9F, 0x00, 0xA0, 0x8F, 0x00, 0x00, 0x7F, 0x01, 0xA5, 0x19, 0x7E, 0x1B, 0x1A,
0x19, 0x7C, 0x1B, 0x1A, 0x1B, 0x5E, 0x7C, 0x22, 0x1B, 0x3E, 0x1B, 0x3C, 0x1C, 0x04, 0x02, 0x9F,
0x00, 0x68, 0x8E, 0x70, 0x89, 0x60, 0x19, 0x1F, 0x2E, 0xCE, 0x2C, 0xCF, 0x16, 0xCD, 0x0C, 0x00,
0x16, 0xC9, 0x00, 0x00, 0x05, 0x03, 0x03, 0x40, 0xFF, 0xF0, 0x2F, 0xCB, 0x02, 0xBF, 0x05, 0x5C,
0x00, 0x80, 0x0C, 0x00, 0x02, 0x9F, 0x00, 0x68, 0x81, 0x00, 0x89, 0x70, 0x8E, 0x78, 0x2E, 0xCE,
0x2F, 0xCF, 0x16, 0xCD, 0x0B, 0x80, 0x16, 0xC9, 0x00, 0x00, 0x16, 0xCB, 0x00, 0xC0, 0x00, 0x82,
0x0E, 0x08, 0x00, 0x9F, 0x00, 0x00, 0x1B, 0x5F, 0x00, 0x9F, 0x01, 0x40, 0x1B, 0x5F, 0x00, 0x9F,
0x02, 0x80, 0x1B, 0x5F, 0x00, 0x9F, 0x04, 0x00, 0x1B, 0x5F, 0x00, 0x9F, 0x05, 0x40, 0x1B, 0x5F,
0x00, 0x9F, 0x06, 0x80, 0x1B, 0x5F, 0x00, 0x9F, 0x07, 0xC0, 0x1B, 0x5F, 0x00, 0x9F, 0x09, 0x00,
0x1B, 0x5F, 0x00, 0x9F, 0x0A, 0x40, 0x1B, 0x5F, 0x02, 0xBF, 0x05, 0x5C, 0x00, 0xDE, 0x0B, 0xA7,
0x00, 0xDF, 0x0B, 0xA8, 0x2E, 0xCE, 0x2F, 0xCF, 0x16, 0xCD, 0x03, 0xC0, 0x16, 0xC9, 0x00, 0x00,
0x16, 0xCB, 0x00, 0x80, 0x81, 0x00, 0x89, 0x00, 0x00, 0xDE, 0x0B, 0x84, 0x00, 0x9F, 0x0B, 0x31,
0x4C, 0x00, 0x1C, 0x7E, 0x02, 0x13, 0x00, 0xFE, 0x0E, 0x15, 0x00, 0xDE, 0x0B, 0x85, 0x00, 0x9F,
0x0B, 0x34, 0x4C, 0x00, 0x1C, 0x7E, 0x02, 0x13, 0x00, 0xFE, 0x0E, 0x16, 0x00, 0xDE, 0x0B, 0x86,
0x00, 0x9F, 0x0B, 0x11, 0x4C, 0x00, 0x1C, 0x7E, 0x02, 0x13, 0x00, 0xFE, 0x0E, 0x14, 0x81, 0x00,
0x00, 0xDE, 0x0B, 0x9B, 0xB1, 0x00, 0x02, 0x95, 0x02, 0x3A, 0x89, 0x00, 0x00, 0xDF, 0x0B, 0x9E,
0x03, 0x00, 0x0C, 0xC0, 0x00, 0xFF, 0x0E, 0x40, 0x00, 0xDF, 0x0B, 0x9F, 0x03, 0x00, 0x0C, 0xC0,
0x00, 0xFF, 0x0E, 0x41, 0x00, 0x9F, 0x0C, 0xE0, 0x00, 0xFF, 0x0E, 0x42, 0x00, 0xFF, 0x0E, 0x43,
0x02, 0xBF, 0x05, 0x5C, 0x00, 0xDE, 0x0B, 0x9C, 0x2E, 0xCE, 0x00, 0xDE, 0x0B, 0x9D, 0x2E, 0xCF,
0x16, 0xCD, 0x0C, 0xC0, 0x16, 0xC9, 0x00, 0x00, 0x16, 0xCB, 0x00, 0x40, 0x02, 0xBF, 0x05, 0x5C,
0x02, 0x9F, 0x00, 0x68, 0x00, 0x9F, 0x0C, 0xE0, 0x00, 0xFF, 0x0E, 0x42, 0x00, 0xFF, 0x0E, 0x40,
0x00, 0xFF, 0x0E, 0x41, 0x00, 0xFF, 0x0E, 0x43, 0x02, 0xBF, 0x05, 0x5C, 0x02, 0x9F, 0x00, 0x68,
0x8E, 0x00, 0x00, 0xE0, 0x0E, 0x07, 0x00, 0x80, 0x0B, 0xA2, 0x00, 0x81, 0x03, 0xC0, 0x0E, 0x05,
0x00, 0xFE, 0x0E, 0x04, 0x89, 0x00, 0x81, 0x50, 0x00, 0x9F, 0x0B, 0x80, 0x00, 0x7A, 0x02, 0x5B,
0x19, 0x3E, 0x4C, 0x49, 0x1C, 0x5E, 0x1A, 0x59, 0x00, 0x83, 0x0E, 0x05, 0x1B, 0x61, 0x1B, 0x60,
0x00, 0xDE, 0x0B, 0x87, 0x06, 0x01, 0x02, 0x95, 0x02, 0x67, 0x02, 0x9F, 0x03, 0x32, 0x00, 0xDE,
0x0E, 0x42, 0x00, 0xFE, 0x0E, 0x1C, 0x00, 0xC3, 0x0E, 0x15, 0x17, 0x7F, 0x8E, 0x00, 0x8A, 0x00,
0x81, 0x00, 0x89, 0x00, 0x00, 0xDE, 0x0B, 0xB3, 0x00, 0xDF, 0x0B, 0xB2, 0x1F, 0x1F, 0x4D, 0x00,
0x14, 0x81, 0x8D, 0x1E, 0x1F, 0xD8, 0x00, 0x98, 0x80, 0x00, 0x00, 0x80, 0x0E, 0x44, 0xA8, 0x30,
0xAC, 0x38, 0xAD, 0x30, 0xAC, 0x38, 0xAD, 0x30, 0xAC, 0x38, 0xAD, 0x30, 0xAC, 0x38, 0xAD, 0x30,
0xAC, 0x38, 0xAD, 0x30, 0xAC, 0x38, 0xAD, 0x30, 0xAC, 0x38, 0xAD, 0x30, 0xAC, 0x38, 0xAD, 0x30,
0xAC, 0x38, 0xAD, 0x30, 0xAC, 0x38, 0xAD, 0x30, 0xAC, 0x38, 0xAD, 0x30, 0xAC, 0x38, 0xAD, 0x30,
0xAC, 0x38, 0xAD, 0x30, 0xAC, 0x38, 0xAD, 0x30, 0xAC, 0x38, 0xAD, 0x30, 0xAC, 0x38, 0x00, 0xFE,
0x0B, 0xB2, 0x8F, 0x00, 0x00, 0x80, 0x0E, 0x44, 0x00, 0xC1, 0x0E, 0x43, 0x1C, 0x61, 0x19, 0x3A,
0x19, 0x18, 0x90, 0x59, 0x19, 0x19, 0x9E, 0x51, 0x80, 0x80, 0x97, 0x59, 0x80, 0x91, 0x9E, 0x51,
0x80, 0x80, 0x97, 0x59, 0x80, 0x91, 0x9E, 0x51, 0x80, 0x80, 0x97, 0x59, 0x80, 0x91, 0x9E, 0x51,
0x80, 0x80, 0x97, 0x59, 0x80, 0x91, 0x9E, 0x51, 0x80, 0x80, 0x97, 0x59, 0x80, 0x91, 0x9E, 0x51,
0x80, 0x80, 0x97, 0x59, 0x80, 0x91, 0x9E, 0x51, 0x80, 0x80, 0x97, 0x59, 0x80, 0x91, 0x9E, 0x51,
0x80, 0x80, 0x97, 0x59, 0x80, 0x91, 0x9E, 0x51, 0x80, 0x80, 0x97, 0x59, 0x80, 0x91, 0x9E, 0x51,
0x80, 0x80, 0x97, 0x59, 0x80, 0x91, 0x9E, 0x51, 0x80, 0x80, 0x97, 0x59, 0x80, 0x91, 0x9E, 0x51,
0x80, 0x80, 0x97, 0x59, 0x80, 0x91, 0x9E, 0x51, 0x80, 0x80, 0x97, 0x59, 0x80, 0x91, 0x9E, 0x51,
0x80, 0x80, 0x97, 0x59, 0x80, 0x91, 0x9E, 0x51, 0x80, 0x80, 0x97, 0x59, 0x80, 0x91, 0x9E, 0x00,
0x6F, 0x33, 0x1B, 0x7F, 0x00, 0xC3, 0x0E, 0x14, 0x8F, 0x00, 0x8D, 0x00, 0x8A, 0x00, 0x17, 0x7F,
0x81, 0x00, 0x00, 0xDE, 0x0B, 0x9B, 0xB1, 0x00, 0x02, 0x95, 0x03, 0x2A, 0x00, 0xDE, 0x0E, 0x42,
0x00, 0xFE, 0x0E, 0x43, 0x81, 0x00, 0x89, 0x00, 0x00, 0xDE, 0x0B, 0x9E, 0x00, 0xDF, 0x0B, 0xA0,
0x82, 0x00, 0x02, 0x93, 0x03, 0x06, 0x78, 0x00, 0x02, 0x9F, 0x03, 0x09, 0x02, 0x95, 0x03, 0x09,
0x74, 0x00, 0x00, 0xFE, 0x0B, 0x9E, 0x00, 0xDF, 0x0E, 0x43, 0x05, 0xE0, 0x4C, 0x00, 0x00, 0xFE,
0x0E, 0x40, 0x81, 0x00, 0x89, 0x00, 0x00, 0xDE, 0x0B, 0x9F, 0x00, 0xDF, 0x0B, 0xA1, 0x82, 0x00,
0x02, 0x93, 0x03, 0x1D, 0x78, 0x00, 0x02, 0x9F, 0x03, 0x20, 0x02, 0x95, 0x03, 0x20, 0x74, 0x00,
0x00, 0xFE, 0x0B, 0x9F, 0x00, 0xDF, 0x0E, 0x43, 0x05, 0xE0, 0x4C, 0x00, 0x00, 0xFE, 0x0E, 0x41,
0x02, 0x9F, 0x03, 0x32, 0x00, 0xDE, 0x0E, 0x42, 0x00, 0xFE, 0x0E, 0x40, 0x00, 0xFE, 0x0E, 0x41,
0x00, 0xFE, 0x0E, 0x43, 0x81, 0x00, 0x8E, 0x00, 0x84, 0x00, 0x89, 0x00, 0x1E, 0xFE, 0x0E, 0x40,
0x1E, 0xBE, 0x00, 0x83, 0x0E, 0x08, 0x1C, 0x03, 0x1F, 0xF5, 0x19, 0x1A, 0xF8, 0x58, 0xFB, 0xA0,
0xF8, 0xB1, 0xFB, 0xA0, 0xF8, 0xB1, 0xFB, 0xA0, 0xF8, 0xB1, 0xFB, 0xA0, 0xF8, 0x3B, 0x1B, 0x7E,
0x00, 0x83, 0x0E, 0x04, 0x81, 0x00, 0x89, 0x73, 0x19, 0x61, 0x19, 0x60, 0x78, 0x00, 0x00, 0xFE,
0x0E, 0x04, 0x02, 0x94, 0x02, 0x53, 0x8E, 0x00, 0x81, 0x00, 0x00, 0xDE, 0x0B, 0x9B, 0xB1, 0x00,
0x02, 0x95, 0x03, 0x6A, 0x00, 0xDE, 0x0B, 0x9C, 0x00, 0xDC, 0x0B, 0x9D, 0x2E, 0xCE, 0x2C, 0xCF,
0x81, 0x00, 0x00, 0xDE, 0x0E, 0x1C, 0x2E, 0xCD, 0x16, 0xC9, 0x00, 0x01, 0x16, 0xCB, 0x00, 0x40,
0x02, 0xBF, 0x05, 0x5C, 0x81, 0x00, 0x89, 0x00, 0x00, 0xDE, 0x0B, 0x82, 0x00, 0xDF, 0x0B, 0x83,
0x2E, 0xCE, 0x2F, 0xCF, 0x16, 0xCD, 0x0B, 0x80, 0x16, 0xC9, 0x00, 0x01, 0x16, 0xCB, 0x00, 0xC0,
0x02, 0xBF, 0x05, 0x5C, 0x81, 0x00, 0x00, 0xDE, 0x0B, 0x80, 0x00, 0xDC, 0x0B, 0x81, 0xB1, 0x00,
0x02, 0x94, 0x03, 0x86, 0x00, 0xC0, 0x0E, 0x07, 0x02, 0x9F, 0x00, 0x68, 0x2E, 0xCE, 0x2C, 0xCF,
0x16, 0xCD, 0x0B, 0x80, 0x16, 0xC9, 0x00, 0x00, 0x16, 0xCB, 0x00, 0xC0, 0x00, 0x82, 0x0E, 0x08,
0x00, 0x9F, 0x00, 0x00, 0x1B, 0x5F, 0x00, 0x9F, 0x01, 0x40, 0x1B, 0x5F, 0x00, 0x9F, 0x02, 0x80,
0x1B, 0x5F, 0x00, 0x9F, 0x04, 0x00, 0x1B, 0x5F, 0x00, 0x9F, 0x05, 0x40, 0x1B, 0x5F, 0x00, 0x9F,
0x06, 0x80, 0x1B, 0x5F, 0x00, 0x9F, 0x07, 0xC0, 0x1B, 0x5F, 0x00, 0x9F, 0x09, 0x00, 0x1B, 0x5F,
0x00, 0x9F, 0x0A, 0x40, 0x1B, 0x5F, 0x02, 0xBF, 0x05, 0x5C, 0x00, 0xDE, 0x0B, 0xA7, 0x00, 0xDF,
0x0B, 0xA8, 0x2E, 0xCE, 0x2F, 0xCF, 0x16, 0xCD, 0x03, 0xC0, 0x16, 0xC9, 0x00, 0x00, 0x16, 0xCB,
0x00, 0x80, 0x81, 0x00, 0x89, 0x00, 0x00, 0xDE, 0x0B, 0x84, 0x00, 0x9F, 0x0B, 0x31, 0x4C, 0x00,
0x1C, 0x7E, 0x02, 0x13, 0x00, 0xFE, 0x0E, 0x15, 0x00, 0xDE, 0x0B, 0x85, 0x00, 0x9F, 0x0B, 0x34,
0x4C, 0x00, 0x1C, 0x7E, 0x02, 0x13, 0x00, 0xFE, 0x0E, 0x16, 0x00, 0xDE, 0x0B, 0x86, 0x00, 0x9F,
0x0B, 0x11, 0x4C, 0x00, 0x1C, 0x7E, 0x02, 0x13, 0x00, 0xFE, 0x0E, 0x14, 0x81, 0x00, 0x00, 0xDE,
0x0B, 0x9B, 0xB1, 0x00, 0x02, 0x95, 0x04, 0x03, 0x89, 0x00, 0x00, 0xDF, 0x0B, 0x9E, 0x03, 0x00,
0x0C, 0xC0, 0x00, 0xFF, 0x0E, 0x40, 0x00, 0xDF, 0x0B, 0x9F, 0x03, 0x00, 0x0C, 0xC0, 0x00, 0xFF,
0x0E, 0x41, 0x00, 0x9F, 0x0C, 0xE0, 0x00, 0xFF, 0x0E, 0x42, 0x00, 0xFF, 0x0E, 0x43, 0x02, 0xBF,
0x05, 0x5C, 0x00, 0xDE, 0x0B, 0x9C, 0x2E, 0xCE, 0x00, 0xDE, 0x0B, 0x9D, 0x2E, 0xCF, 0x16, 0xCD,
0x0C, 0xC0, 0x16, 0xC9, 0x00, 0x00, 0x16, 0xCB, 0x00, 0x40, 0x02, 0xBF, 0x05, 0x5C, 0x00, 0xC0,
0x0E, 0x07, 0x02, 0x9F, 0x02, 0x48, 0x00, 0x9F, 0x0C, 0xE0, 0x00, 0xFF, 0x0E, 0x42, 0x00, 0xFF,
0x0E, 0x40, 0x00, 0xFF, 0x0E, 0x41, 0x00, 0xFF, 0x0E, 0x43, 0x02, 0xBF, 0x05, 0x5C, 0x00, 0xC0,
0x0E, 0x07, 0x02, 0x9F, 0x02, 0x48, 0x8E, 0x00, 0x00, 0x86, 0x04, 0x00, 0x81, 0x00, 0x89, 0x70,
0x19, 0x1C, 0x2E, 0xCE, 0x2C, 0xCF, 0x1F, 0xC6, 0x2E, 0xCD, 0x16, 0xC9, 0x00, 0x01, 0x16, 0xCB,
0x07, 0x80, 0x02, 0xBF, 0x05, 0x5C, 0x02, 0xBF, 0x04, 0x84, 0x02, 0x9F, 0x00, 0x68, 0x8E, 0x00,
0x00, 0x86, 0x07, 0xC0, 0x81, 0x00, 0x89, 0x70, 0x19, 0x1C, 0x2E, 0xCE, 0x2C, 0xCF, 0x1F, 0xC6,
0x2E, 0xCD, 0x16, 0xC9, 0x00, 0x01, 0x16, 0xCB, 0x07, 0x80, 0x02, 0xBF, 0x05, 0x5C, 0x02, 0xBF,
0x04, 0x84, 0x02, 0x9F, 0x00, 0x68, 0x8C, 0x00, 0x8A, 0x00, 0x81, 0x00, 0x89, 0x70, 0x19, 0x1F,
0x2E, 0xCE, 0x2F, 0xCF, 0x16, 0xCD, 0x02, 0x80, 0x16, 0xC9, 0x00, 0x01, 0x16, 0xCB, 0x02, 0x80,
0x8F, 0x50, 0x81, 0x40, 0x00, 0x81, 0x04, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x82, 0x01, 0x40,
0x00, 0x99, 0x00, 0x80, 0x02, 0xBF, 0x05, 0x5C, 0x11, 0x05, 0x04, 0x6C, 0x1F, 0x61, 0x11, 0x20,
0x04, 0x5E, 0x89, 0x72, 0x19, 0x5C, 0xF0, 0x7B, 0x19, 0x7D, 0xF1, 0x31, 0x81, 0x39, 0x89, 0x00,
0x68, 0x00, 0x2E, 0xCE, 0x2C, 0xCF, 0x1F, 0xFB, 0x2F, 0xCD, 0x0F, 0x01, 0x2F, 0xC9, 0x1F, 0xF9,
0x2F, 0xCB, 0x72, 0x00, 0x1F, 0x5E, 0x1F, 0x1C, 0x81, 0x00, 0x26, 0xC9, 0x02, 0xA0, 0x00, 0x04,
0x02, 0x9C, 0x04, 0x6D, 0x02, 0x9F, 0x00, 0x68, 0x02, 0x9F, 0x00, 0x68, 0x02, 0x9F, 0x00, 0x68,
0x02, 0x9F, 0x00, 0x68, 0x16, 0xFC, 0xDC, 0xD1, 0x16, 0xFD, 0x00, 0x02, 0x16, 0xFB, 0x00, 0x01,
0x02, 0x9F, 0x0C, 0x91, 0x02, 0x9F, 0x00, 0x45, 0x8E, 0x00, 0x19, 0x1F, 0x19, 0x1D, 0x1F, 0x5F,
0x1F, 0x1D, 0x2F, 0xCE, 0x2D, 0xCF, 0x89, 0x00, 0x1F, 0xA6, 0x2D, 0xCD, 0x0E, 0x00, 0x2E, 0xC9,
0x81, 0x00, 0x00, 0x9C, 0x00, 0xC0, 0x2C, 0xCB, 0x1C, 0xA0, 0x00, 0x81, 0x0E, 0x44, 0x48, 0x00,
0x1B, 0x3E, 0x1B, 0x3C, 0x0B, 0x00, 0x00, 0x99, 0x00, 0x60, 0x4B, 0x00, 0x1B, 0x3D, 0x00, 0x81,
0x0E, 0x44, 0x1C, 0x06, 0x00, 0x83, 0x00, 0x00, 0x1C, 0x43, 0x27, 0xC9, 0x03, 0xA0, 0x00, 0x04,
0x02, 0x9C, 0x04, 0xA5, 0x11, 0x09, 0x04, 0xDA, 0x8E, 0x00, 0x19, 0x3A, 0x19, 0x38, 0x69, 0x00,
0x2F, 0xCE, 0x2D, 0xCF, 0x89, 0x00, 0x19, 0x3D, 0x2D, 0xCD, 0x16, 0xC9, 0x00, 0x00, 0x81, 0x00,
0x00, 0x9C, 0x00, 0xC0, 0x2C, 0xCB, 0x00, 0x81, 0x0E, 0x44, 0x48, 0x00, 0x1B, 0x3E, 0x1B, 0x3C,
0x0B, 0x00, 0x09, 0x60, 0x4B, 0x00, 0x1B, 0x3D, 0x00, 0x81, 0x0E, 0x44, 0x8F, 0x00, 0x80, 0xF0,
0x80, 0xC0, 0x6A, 0x00, 0x48, 0x00, 0x11, 0x17, 0x04, 0xD4, 0x80, 0xF0, 0x80, 0xC0, 0x6B, 0x32,
0x49, 0x22, 0x80, 0xF0, 0x80, 0xC0, 0x6A, 0x3A, 0x48, 0x2A, 0x80, 0xF0, 0x80, 0xC0, 0x6B, 0x32,
0x49, 0x22, 0x1B, 0x5F, 0x1B, 0x5D, 0x80, 0xF0, 0x80, 0xC0, 0x6A, 0x00, 0x48, 0x00, 0x11, 0x17,
0x04, 0xE8, 0x80, 0xF0, 0x80, 0xC0, 0x6B, 0x32, 0x49, 0x22, 0x80, 0xF0, 0x80, 0xC0, 0x6A, 0x3A,
0x48, 0x2A, 0x80, 0xF0, 0x80, 0xC0, 0x6B, 0x32, 0x49, 0x22, 0x1B, 0x5F, 0x1B, 0x5D, 0x1C, 0x05,
0x02, 0xDF, 0x8E, 0x00, 0x00, 0x9B, 0x0E, 0x44, 0x00, 0x9D, 0x00, 0xC0, 0x02, 0xBF, 0x05, 0x41,
0x49, 0x00, 0x00, 0xFF, 0x0E, 0x1D, 0x00, 0xFD, 0x0E, 0x1E, 0x89, 0x00, 0x02, 0xBF, 0x05, 0x5C,
0x11, 0x04, 0x05, 0x2C, 0x00, 0xDA, 0x0E, 0x1D, 0x00, 0xD8, 0x0E, 0x1E, 0x00, 0x9B, 0x0E, 0xA4,
0x00, 0x9D, 0x00, 0xC0, 0x02, 0xBF, 0x05, 0x41, 0x49, 0x00, 0x00, 0xFF, 0x0E, 0x1D, 0x00, 0xFD,
0x0E, 0x1E, 0x00, 0x83, 0x0E, 0x44, 0x02, 0xBF, 0x05, 0x4C, 0x89, 0x00, 0x00, 0xDA, 0x0E, 0x1D,
0x00, 0xD8, 0x0E, 0x1E, 0x00, 0x9B, 0x0E, 0x44, 0x00, 0x9D, 0x00, 0xC0, 0x02, 0xBF, 0x05, 0x41,
0x49, 0x00, 0x00, 0xFF, 0x0E, 0x1D, 0x00, 0xFD, 0x0E, 0x1E, 0x00, 0x83, 0x0E, 0xA4, 0x02, 0xBF,
0x05, 0x4C, 0x00, 0x00, 0x00, 0x00, 0x8E, 0x00, 0x89, 0x00, 0x00, 0xDA, 0x0E, 0x1D, 0x00, 0xD8,
0x0E, 0x1E, 0x00, 0x9B, 0x0E, 0xA4, 0x00, 0x9D, 0x00, 0xC0, 0x02, 0xBF, 0x05, 0x41, 0x49, 0x00,
0x00, 0x83, 0x0E, 0x44, 0x02, 0xBF, 0x05, 0x4C, 0x00, 0x83, 0x0E, 0xA4, 0x02, 0xBF, 0x05, 0x4C,
0x02, 0xDF, 0x8E, 0x00, 0x00, 0xFA, 0xFF, 0xCE, 0x00, 0xF8, 0xFF, 0xCF, 0x00, 0xFB, 0xFF, 0xCD,
0x16, 0xC9, 0x00, 0x00, 0x2D, 0xCB, 0x02, 0xDF, 0x8F, 0x00, 0x8D, 0x00, 0x8A, 0x00, 0x19, 0x7A,
0x19, 0x78, 0xA0, 0x00, 0xB6, 0x00, 0x11, 0x30, 0x05, 0x5A, 0x91, 0x79, 0x4E, 0x6D, 0x19, 0x7A,
0x4D, 0x43, 0xA0, 0x39, 0xB6, 0x29, 0x02, 0xDF, 0x26, 0xC9, 0x02, 0xA0, 0x00, 0x04, 0x02, 0x9C,
0x05, 0x5C, 0x02, 0xDF, 0x26, 0xFE, 0x02, 0xC0, 0x80, 0x00, 0x02, 0x9C, 0x05, 0x62, 0x02, 0xDF,
0x26, 0xFC, 0x02, 0xA0, 0x80, 0x00, 0x02, 0x9C, 0x05, 0x68, 0x02, 0xDF, 0x26, 0xFC, 0x02, 0xA0,
0x80, 0x00, 0x02, 0x9C, 0x05, 0x6E, 0x02, 0xDF, 0x81, 0x00, 0x89, 0x70, 0x8E, 0x60, 0x2E, 0xCE,
0x2C, 0xCF, 0x16, 0xCD, 0x0E, 0x44, 0x16, 0xC9, 0x00, 0x00, 0x89, 0x00, 0x0D, 0x20, 0x2D, 0xCB,
0x4C, 0x00, 0x1C, 0x80, 0x00, 0x80, 0x02, 0x80, 0x00, 0x81, 0x00, 0x00, 0x00, 0x82, 0x01, 0x40,
0x00, 0x83, 0x0E, 0x44, 0x0A, 0x00, 0x27, 0xC9, 0x03, 0xA0, 0x00, 0x04, 0x02, 0x9C, 0x05, 0x8B,
0x2E, 0xCE, 0x2C, 0xCF, 0x16, 0xCD, 0x0E, 0x54, 0x16, 0xC9, 0x00, 0x00, 0x16, 0xCB, 0x02, 0x60,
0x00, 0x9F, 0x00, 0xA0, 0x8F, 0x00, 0x00, 0x7F, 0x05, 0xA4, 0x19, 0x7E, 0x1B, 0x1A, 0x19, 0x7C,
0x1B, 0x1A, 0x1B, 0x5E, 0x1B, 0x5C, 0x1B, 0x3E, 0x1B, 0x3C, 0x1C, 0x04, 0x02, 0x9F, 0x00, 0x68,
0x00, 0x82, 0x0B, 0xB8, 0x19, 0x5E, 0x2E, 0xD1, 0x19, 0x5E, 0x2E, 0xD4, 0x19, 0x5E, 0x2E, 0xD5,
0x19, 0x5E, 0x2E, 0xD6, 0x19, 0x5E, 0x2E, 0xD7, 0x19, 0x5E, 0x2E, 0xD8, 0x19, 0x5E, 0x2E, 0xD9,
0x19, 0x5E, 0x2E, 0xA0, 0x19, 0x5E, 0x2E, 0xA1, 0x19, 0x5E, 0x2E, 0xA2, 0x19, 0x5E, 0x2E, 0xA3,
0x19, 0x5E, 0x2E, 0xA4, 0x19, 0x5E, 0x2E, 0xA5, 0x19, 0x5E, 0x2E, 0xA6, 0x19, 0x5E, 0x2E, 0xA7,
0x19, 0x5E, 0x2E, 0xA8, 0x19, 0x5E, 0x2E, 0xA9, 0x19, 0x5E, 0x2E, 0xAA, 0x19, 0x5E, 0x2E, 0xAB,
0x19, 0x5E, 0x2E, 0xAC, 0x19, 0x5E, 0x2E, 0xAD, 0x19, 0x5E, 0x2E, 0xAE, 0x19, 0x5E, 0x2E, 0xAF,
0x19, 0x5E, 0x2E, 0xDE, 0x19, 0x5E, 0x2E, 0xDA, 0x19, 0x5E, 0x2E, 0xDB, 0x19, 0x5E, 0x2E, 0xDC,
0x8C, 0x00, 0x8A, 0x00, 0x8E, 0x00, 0x00, 0xD8, 0x0E, 0x16, 0x19, 0x5B, 0x19, 0x59, 0x81, 0x00,
0x19, 0x5C, 0x00, 0x80, 0x0E, 0x44, 0x19, 0x5F, 0x1B, 0x1F, 0x19, 0x5F, 0x1B, 0x1F, 0x19, 0x5F,
0x1B, 0x1F, 0x18, 0x5F, 0x1B, 0x1F, 0x6B, 0x00, 0x15, 0x05, 0x4D, 0x00, 0x15, 0x7E, 0x1C, 0x9F,
0x1C, 0xBD, 0x05, 0xE0, 0x99, 0x00, 0x7D, 0x00, 0x1C, 0xDD, 0x89, 0x00, 0x1F, 0xA5, 0x15, 0x02,
0x1C, 0xBF, 0x00, 0x9A, 0x01, 0xFC, 0x00, 0x9E, 0x0E, 0x44, 0x00, 0x81, 0xFF, 0xDD, 0x00, 0x83,
0x0D, 0x80, 0x00, 0x64, 0x06, 0x1A, 0x18, 0x27, 0x1B, 0x07, 0x4A, 0x00, 0x1F, 0xFC, 0x18, 0x27,
0x1B, 0x07, 0x15, 0x79, 0x35, 0x00, 0x18, 0x27, 0x1B, 0x07, 0x41, 0x00, 0x1B, 0x7E, 0x18, 0x27,
0x1B, 0x07, 0x1B, 0x7F, 0x00, 0x00, 0x00, 0x65, 0x06, 0x20, 0x18, 0x27, 0x1B, 0x07, 0x00, 0x00,
0x00, 0x00, 0x00, 0x07, 0x18, 0x7F, 0x00, 0x66, 0x06, 0x29, 0x4A, 0x3B, 0x1F, 0xFC, 0x15, 0x79,
0x35, 0x33, 0x41, 0x00, 0x1B, 0x7F, 0x00, 0x04, 0x18, 0x9F, 0x1A, 0xDF, 0x18, 0x9F, 0x1A, 0xDF,
0x18, 0x9F, 0x1A, 0xDF, 0x18, 0x9F, 0x1A, 0xDF, 0x1A, 0xDC, 0x00, 0x82, 0x0B, 0xD2, 0x27, 0xDC,
0x1A, 0xDF, 0x27, 0xDB, 0x1A, 0xDF, 0x27, 0xDA, 0x1A, 0xDF, 0x00, 0x82, 0x0B, 0xBE, 0x27, 0xD9,
0x1A, 0xDF, 0x27, 0xD8, 0x1A, 0xDF, 0x8F, 0x00, 0x00, 0xC1, 0x0E, 0x42, 0x00, 0x82, 0x0D, 0x80,
0x19, 0x40, 0x19, 0x43, 0x80, 0xF0, 0xB8, 0xC0, 0x11, 0x1F, 0x06, 0x54, 0xA6, 0xF0, 0xBC, 0xF0,
0x19, 0x40, 0x19, 0x43, 0xBC, 0xF0, 0x4E, 0xC0, 0xB8, 0x31, 0xA6, 0xF0, 0xBC, 0xF0, 0xBC, 0x00,
0x4E, 0x00, 0x1B, 0x3E, 0x00, 0xE1, 0x0E, 0x42, 0x02, 0xDF, 0x00, 0x82, 0x0B, 0xB8, 0x19, 0x5E,
0x2E, 0xD1, 0x19, 0x5E, 0x2E, 0xD4, 0x19, 0x5E, 0x2E, 0xD5, 0x19, 0x5E, 0x2E, 0xD6, 0x19, 0x5E,
0x2E, 0xD7, 0x19, 0x5E, 0x2E, 0xD8, 0x19, 0x5E, 0x2E, 0xD9, 0x19, 0x5E, 0x2E, 0xA0, 0x19, 0x5E,
0x2E, 0xA1, 0x19, 0x5E, 0x2E, 0xA2, 0x19, 0x5E, 0x2E, 0xA3, 0x19, 0x5E, 0x2E, 0xA4, 0x19, 0x5E,
0x2E, 0xA5, 0x19, 0x5E, 0x2E, 0xA6, 0x19, 0x5E, 0x2E, 0xA7, 0x19, 0x5E, 0x2E, 0xA8, 0x19, 0x5E,
0x2E, 0xA9, 0x19, 0x5E, 0x2E, 0xAA, 0x19, 0x5E, 0x2E, 0xAB, 0x19, 0x5E, 0x2E, 0xAC, 0x19, 0x5E,
0x2E, 0xAD, 0x19, 0x5E, 0x2E, 0xAE, 0x19, 0x5E, 0x2E, 0xAF, 0x19, 0x5E, 0x2E, 0xDE, 0x19, 0x5E,
0x2E, 0xDA, 0x19, 0x5E, 0x2E, 0xDB, 0x19, 0x5E, 0x2E, 0xDC, 0x8C, 0x00, 0x8A, 0x00, 0x8E, 0x00,
0x19, 0x5B, 0x19, 0x59, 0x81, 0x00, 0x19, 0x5C, 0x00, 0x80, 0x0E, 0x44, 0x19, 0x5F, 0x19, 0x5F,
0x19, 0x5F, 0x1B, 0x1F, 0x18, 0x5F, 0x1B, 0x1F, 0x6B, 0x00, 0x15, 0x05, 0x4D, 0x00, 0x15, 0x7E,
0x1C, 0x9F, 0x1C, 0xBD, 0x05, 0xE0, 0x99, 0x00, 0x7D, 0x00, 0x1C, 0xDD, 0x89, 0x00, 0x1F, 0xA5,
0x15, 0x02, 0x1C, 0xBF, 0x00, 0x9A, 0x01, 0xFC, 0x00, 0x9E, 0x0E, 0x45, 0x00, 0x81, 0xFF, 0xDD,
0x00, 0x83, 0x0D, 0x80, 0x00, 0x64, 0x06, 0xCB, 0x18, 0x27, 0x1B, 0x07, 0x4A, 0x00, 0x1B, 0x7E,
0x18, 0x27, 0x1B, 0x07, 0x1B, 0x7C, 0x00, 0x00, 0x18, 0x27, 0x1B, 0x07, 0x00, 0x00, 0x00, 0x00,
0x18, 0x27, 0x1B, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x06, 0xD1, 0x18, 0x27, 0x1B, 0x07,
0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x06, 0xD6, 0x4A, 0x00, 0x1B, 0x7E, 0x1B, 0x7C, 0x00, 0x04,
0x18, 0x9F, 0x1A, 0xDF, 0x18, 0x9F, 0x1A, 0xDF, 0x18, 0x9F, 0x1A, 0xDF, 0x18, 0x9F, 0x1A, 0xDF,
0x1A, 0xDC, 0x00, 0x82, 0x0B, 0xD2, 0x27, 0xDC, 0x1A, 0xDF, 0x27, 0xDB, 0x1A, 0xDF, 0x27, 0xDA,
0x1A, 0xDF, 0x00, 0x82, 0x0B, 0xBE, 0x27, 0xD9, 0x1A, 0xDF, 0x27, 0xD8, 0x1A, 0xDF, 0x8D, 0x00,
0x8B, 0x00, 0x8F, 0x00, 0x00, 0xC1, 0x0E, 0x42, 0x00, 0x82, 0x0D, 0x80, 0x81, 0x00, 0x11, 0x20,
0x07, 0x03, 0x89, 0x00, 0x19, 0x40, 0x18, 0x9E, 0x18, 0x1B, 0x19, 0x9A, 0x54, 0x00, 0x1F, 0x5E,
0x19, 0x59, 0xB0, 0x00, 0xFB, 0x00, 0x81, 0x39, 0x00, 0xE1, 0x0E, 0x42, 0x02, 0xDF, 0x00, 0x82,
0x0B, 0xB8, 0x19, 0x5E, 0x2E, 0xD1, 0x19, 0x5E, 0x2E, 0xD4, 0x19, 0x5E, 0x2E, 0xD5, 0x19, 0x5E,
0x2E, 0xD6, 0x19, 0x5E, 0x2E, 0xD7, 0x19, 0x5E, 0x2E, 0xD8, 0x19, 0x5E, 0x2E, 0xD9, 0x19, 0x5E,
0x2E, 0xA0, 0x19, 0x5E, 0x2E, 0xA1, 0x19, 0x5E, 0x2E, 0xA2, 0x19, 0x5E, 0x2E, 0xA3, 0x19, 0x5E,
0x2E, 0xA4, 0x19, 0x5E, 0x2E, 0xA5, 0x19, 0x5E, 0x2E, 0xA6, 0x19, 0x5E, 0x2E, 0xA7, 0x19, 0x5E,
0x2E, 0xA8, 0x19, 0x5E, 0x2E, 0xA9, 0x19, 0x5E, 0x2E, 0xAA, 0x19, 0x5E, 0x2E, 0xAB, 0x19, 0x5E,
0x2E, 0xAC, 0x19, 0x5E, 0x2E, 0xAD, 0x19, 0x5E, 0x2E, 0xAE, 0x19, 0x5E, 0x2E, 0xAF, 0x19, 0x5E,
0x2E, 0xDE, 0x19, 0x5E, 0x2E, 0xDA, 0x19, 0x5E, 0x2E, 0xDB, 0x19, 0x5E, 0x2E, 0xDC, 0x00, 0xC0,
0x0E, 0x42, 0x00, 0x81, 0xFF, 0xDD, 0x11, 0x20, 0x07, 0x48, 0x18, 0x24, 0x1B, 0x04, 0x00, 0x00,
0x00, 0x00, 0x00, 0xE0, 0x0E, 0x42, 0x00, 0x82, 0x0B, 0xD9, 0x00, 0x04, 0x18, 0x9F, 0x1A, 0xDF,
0x18, 0x9F, 0x1A, 0xDF, 0x18, 0x9F, 0x1A, 0xDF, 0x18, 0x9F, 0x1A, 0xDF, 0x89, 0x00, 0x1A, 0xDC,
0x27, 0xDC, 0x00, 0xFF, 0x0B, 0xD2, 0x27, 0xDB, 0x00, 0xFF, 0x0B, 0xD1, 0x27, 0xDA, 0x00, 0xFF,
0x0B, 0xD0, 0x27, 0xD9, 0x00, 0xFF, 0x0B, 0xBE, 0x27, 0xD8, 0x00, 0xFF, 0x0B, 0xBD, 0x02, 0xDF,
0x00, 0xC0, 0x0E, 0x40, 0x00, 0x81, 0x0B, 0x89, 0x00, 0xC2, 0x0E, 0x08, 0x1C, 0x62, 0x00, 0xC4,
0x0E, 0x41, 0x00, 0xC5, 0x0E, 0x09, 0x02, 0xBF, 0x80, 0xE7, 0x00, 0xF8, 0x0B, 0xA9, 0x00, 0xFB,
0x0B, 0xAC, 0x02, 0xDF, 0x00, 0xC0, 0x0E, 0x40, 0x00, 0x81, 0x0B, 0x89, 0x00, 0xC2, 0x0E, 0x08,
0x1C, 0x62, 0x00, 0xC4, 0x0E, 0x41, 0x00, 0xC5, 0x0E, 0x09, 0x02, 0xBF, 0x80, 0xE7, 0x00, 0xF8,
0x0B, 0xA9, 0x00, 0xFB, 0x0B, 0xAC, 0x00, 0xC0, 0x0E, 0x40, 0x00, 0x81, 0x0B, 0x8D, 0x00, 0xC2,
0x0E, 0x0B, 0x1C, 0x62, 0x00, 0xC4, 0x0E, 0x41, 0x00, 0xC5, 0x0E, 0x0C, 0x02, 0xBF, 0x80, 0xE7,
0x00, 0xF8, 0x0B, 0xAA, 0x00, 0xFB, 0x0B, 0xAD, 0x02, 0xDF, 0x00, 0xC0, 0x0E, 0x40, 0x00, 0x81,
0x0B, 0x89, 0x00, 0xC2, 0x0E, 0x08, 0x1C, 0x62, 0x00, 0xC4, 0x0E, 0x41, 0x00, 0xC5, 0x0E, 0x09,
0x02, 0xBF, 0x80, 0xE7, 0x00, 0xF8, 0x0B, 0xA9, 0x00, 0xFB, 0x0B, 0xAC, 0x00, 0xC0, 0x0E, 0x40,
0x00, 0x81, 0x0B, 0x91, 0x00, 0xC2, 0x0E, 0x0E, 0x1C, 0x62, 0x00, 0xC4, 0x0E, 0x41, 0x00, 0xC5,
0x0E, 0x0F, 0x02, 0xBF, 0x80, 0xE7, 0x00, 0xF8, 0x0B, 0xAB, 0x00, 0xFB, 0x0B, 0xAE, 0x02, 0xDF,
0x00, 0xC0, 0x0E, 0x40, 0x00, 0x81, 0x0B, 0x89, 0x00, 0xC2, 0x0E, 0x08, 0x1C, 0x62, 0x00, 0xC4,
0x0E, 0x41, 0x00, 0xC5, 0x0E, 0x09, 0x02, 0xBF, 0x80, 0xE7, 0x00, 0xF8, 0x0B, 0xA9, 0x00, 0xFB,
0x0B, 0xAC, 0x00, 0xC0, 0x0E, 0x40, 0x00, 0x81, 0x0B, 0x8D, 0x00, 0xC2, 0x0E, 0x0B, 0x1C, 0x62,
0x00, 0xC4, 0x0E, 0x41, 0x00, 0xC5, 0x0E, 0x0C, 0x02, 0xBF, 0x80, 0xE7, 0x00, 0xF8, 0x0B, 0xAA,
0x00, 0xFB, 0x0B, 0xAD, 0x00, 0xC0, 0x0E, 0x40, 0x00, 0x81, 0x0B, 0x91, 0x00, 0xC2, 0x0E, 0x0E,
0x1C, 0x62, 0x00, 0xC4, 0x0E, 0x41, 0x00, 0xC5, 0x0E, 0x0F, 0x02, 0xBF, 0x80, 0xE7, 0x00, 0xF8,
0x0B, 0xAB, 0x00, 0xFB, 0x0B, 0xAE, 0x02, 0xDF, 0x00, 0xC0, 0x0E, 0x40, 0x00, 0x81, 0x0B, 0x89,
0x00, 0xC2, 0x0E, 0x08, 0x1C, 0x62, 0x00, 0xC4, 0x0E, 0x41, 0x00, 0xC5, 0x0E, 0x09, 0x02, 0xBF,
0x80, 0xE7, 0x00, 0xF8, 0x0B, 0xA9, 0x00, 0xFB, 0x0B, 0xAC, 0x00, 0xC0, 0x0E, 0x43, 0x00, 0x81,
0x0B, 0x97, 0x00, 0xC2, 0x0E, 0x0A, 0x1C, 0x62, 0x02, 0xBF, 0x81, 0xF9, 0x00, 0xF8, 0x0B, 0xAF,
0x02, 0xDF, 0x00, 0xC0, 0x0E, 0x40, 0x00, 0x81, 0x0B, 0x89, 0x00, 0xC2, 0x0E, 0x08, 0x1C, 0x62,
0x00, 0xC4, 0x0E, 0x41, 0x00, 0xC5, 0x0E, 0x09, 0x02, 0xBF, 0x80, 0xE7, 0x00, 0xF8, 0x0B, 0xA9,
0x00, 0xFB, 0x0B, 0xAC, 0x00, 0xC0, 0x0E, 0x40, 0x00, 0x81, 0x0B, 0x8D, 0x00, 0xC2, 0x0E, 0x0B,
0x1C, 0x62, 0x00, 0xC4, 0x0E, 0x41, 0x00, 0xC5, 0x0E, 0x0C, 0x02, 0xBF, 0x80, 0xE7, 0x00, 0xF8,
0x0B, 0xAA, 0x00, 0xFB, 0x0B, 0xAD, 0x00, 0xC0, 0x0E, 0x43, 0x00, 0x81, 0x0B, 0x97, 0x00, 0xC2,
0x0E, 0x0A, 0x1C, 0x62, 0x1C, 0x80, 0x00, 0xC5, 0x0E, 0x0D, 0x02, 0xBF, 0x80, 0xE7, 0x00, 0xF8,
0x0B, 0xAF, 0x00, 0xFB, 0x0B, 0xB0, 0x02, 0xDF, 0x00, 0xC0, 0x0E, 0x40, 0x00, 0x81, 0x0B, 0x89,
0x00, 0xC2, 0x0E, 0x08, 0x1C, 0x62, 0x00, 0xC4, 0x0E, 0x41, 0x00, 0xC5, 0x0E, 0x09, 0x02, 0xBF,
0x80, 0xE7, 0x00, 0xF8, 0x0B, 0xA9, 0x00, 0xFB, 0x0B, 0xAC, 0x00, 0xC0, 0x0E, 0x40, 0x00, 0x81,
0x0B, 0x91, 0x00, 0xC2, 0x0E, 0x0E, 0x1C, 0x62, 0x00, 0xC4, 0x0E, 0x41, 0x00, 0xC5, 0x0E, 0x0F,
0x02, 0xBF, 0x80, 0xE7, 0x00, 0xF8, 0x0B, 0xAB, 0x00, 0xFB, 0x0B, 0xAE, 0x00, 0xC0, 0x0E, 0x43,
0x00, 0x81, 0x0B, 0x95, 0x00, 0xC2, 0x0E, 0x10, 0x1C, 0x62, 0x1C, 0x80, 0x00, 0xC5, 0x0E, 0x0A,
0x02, 0xBF, 0x80, 0xE7, 0x00, 0xF8, 0x0B, 0xB1, 0x00, 0xFB, 0x0B, 0xAF, 0x02, 0xDF, 0x00, 0xC0,
0x0E, 0x40, 0x00, 0x81, 0x0B, 0x89, 0x00, 0xC2, 0x0E, 0x08, 0x1C, 0x62, 0x00, 0xC4, 0x0E, 0x41,
0x00, 0xC5, 0x0E, 0x09, 0x02, 0xBF, 0x80, 0xE7, 0x00, 0xF8, 0x0B, 0xA9, 0x00, 0xFB, 0x0B, 0xAC,
0x00, 0xC0, 0x0E, 0x40, 0x00, 0x81, 0x0B, 0x8D, 0x00, 0xC2, 0x0E, 0x0B, 0x1C, 0x62, 0x00, 0xC4,
0x0E, 0x41, 0x00, 0xC5, 0x0E, 0x0C, 0x02, 0xBF, 0x80, 0xE7, 0x00, 0xF8, 0x0B, 0xAA, 0x00, 0xFB,
0x0B, 0xAD, 0x00, 0xC0, 0x0E, 0x40, 0x00, 0x81, 0x0B, 0x91, 0x00, 0xC2, 0x0E, 0x0E, 0x1C, 0x62,
0x00, 0xC4, 0x0E, 0x41, 0x00, 0xC5, 0x0E, 0x0F, 0x02, 0xBF, 0x80, 0xE7, 0x00, 0xF8, 0x0B, 0xAB,
0x00, 0xFB, 0x0B, 0xAE, 0x00, 0xC0, 0x0E, 0x43, 0x00, 0x81, 0x0B, 0x97, 0x00, 0xC2, 0x0E, 0x0A,
0x1C, 0x62, 0x1C, 0x80, 0x00, 0xC5, 0x0E, 0x0D, 0x02, 0xBF, 0x80, 0xE7, 0x00, 0xF8, 0x0B, 0xAF,
0x00, 0xFB, 0x0B, 0xB0, 0x00, 0xC0, 0x0E, 0x43, 0x00, 0x81, 0x0B, 0x95, 0x00, 0xC2, 0x0E, 0x10,
0x1C, 0x62, 0x02, 0xBF, 0x81, 0xF9, 0x00, 0xF8, 0x0B, 0xB1, 0x02, 0xDF, 0x00, 0xC0, 0x0E, 0x40,
0x00, 0x81, 0x0B, 0x89, 0x00, 0xC2, 0x0E, 0x08, 0x00, 0x83, 0x0E, 0x44, 0x00, 0xC4, 0x0E, 0x41,
0x00, 0xC5, 0x0E, 0x09, 0x02, 0xBF, 0x82, 0x82, 0x00, 0xF8, 0x0B, 0xA9, 0x00, 0xFB, 0x0B, 0xAC,
0x02, 0xDF, 0x00, 0xC0, 0x0E, 0x40, 0x00, 0x81, 0x0B, 0x89, 0x00, 0xC2, 0x0E, 0x08, 0x00, 0x83,
0x0E, 0x44, 0x00, 0xC4, 0x0E, 0x41, 0x00, 0xC5, 0x0E, 0x09, 0x02, 0xBF, 0x82, 0x82, 0x00, 0xF8,
0x0B, 0xA9, 0x00, 0xFB, 0x0B, 0xAC, 0x00, 0xC0, 0x0E, 0x40, 0x00, 0x81, 0x0B, 0x8D, 0x00, 0xC2,
0x0E, 0x0B, 0x00, 0x83, 0x0E, 0x44, 0x00, 0xC4, 0x0E, 0x41, 0x00, 0xC5, 0x0E, 0x0C, 0x02, 0xBF,
0x82, 0x82, 0x00, 0xF8, 0x0B, 0xAA, 0x00, 0xFB, 0x0B, 0xAD, 0x02, 0xDF, 0x00, 0xC0, 0x0E, 0x40,
0x00, 0x81, 0x0B, 0x89, 0x00, 0xC2, 0x0E, 0x08, 0x00, 0x83, 0x0E, 0x44, 0x00, 0xC4, 0x0E, 0x41,
0x00, 0xC5, 0x0E, 0x09, 0x02, 0xBF, 0x82, 0x82, 0x00, 0xF8, 0x0B, 0xA9, 0x00, 0xFB, 0x0B, 0xAC,
0x00, 0xC0, 0x0E, 0x40, 0x00, 0x81, 0x0B, 0x91, 0x00, 0xC2, 0x0E, 0x0E, 0x00, 0x83, 0x0E, 0x44,
0x00, 0xC4, 0x0E, 0x41, 0x00, 0xC5, 0x0E, 0x0F, 0x02, 0xBF, 0x82, 0x82, 0x00, 0xF8, 0x0B, 0xAB,
0x00, 0xFB, 0x0B, 0xAE, 0x02, 0xDF, 0x00, 0xC0, 0x0E, 0x40, 0x00, 0x81, 0x0B, 0x89, 0x00, 0xC2,
0x0E, 0x08, 0x00, 0x83, 0x0E, 0x44, 0x00, 0xC4, 0x0E, 0x41, 0x00, 0xC5, 0x0E, 0x09, 0x02, 0xBF,
0x82, 0x82, 0x00, 0xF8, 0x0B, 0xA9, 0x00, 0xFB, 0x0B, 0xAC, 0x00, 0xC0, 0x0E, 0x40, 0x00, 0x81,
0x0B, 0x8D, 0x00, 0xC2, 0x0E, 0x0B, 0x00, 0x83, 0x0E, 0x44, 0x00, 0xC4, 0x0E, 0x41, 0x00, 0xC5,
0x0E, 0x0C, 0x02, 0xBF, 0x82, 0x82, 0x00, 0xF8, 0x0B, 0xAA, 0x00, 0xFB, 0x0B, 0xAD, 0x00, 0xC0,
0x0E, 0x40, 0x00, 0x81, 0x0B, 0x91, 0x00, 0xC2, 0x0E, 0x0E, 0x00, 0x83, 0x0E, 0x44, 0x00, 0xC4,
0x0E, 0x41, 0x00, 0xC5, 0x0E, 0x0F, 0x02, 0xBF, 0x82, 0x82, 0x00, 0xF8, 0x0B, 0xAB, 0x00, 0xFB,
0x0B, 0xAE, 0x02, 0xDF, 0x00, 0xC0, 0x0E, 0x40, 0x00, 0x81, 0x0B, 0x89, 0x00, 0xC2, 0x0E, 0x08,
0x00, 0x83, 0x0E, 0x44, 0x00, 0xC4, 0x0E, 0x41, 0x00, 0xC5, 0x0E, 0x09, 0x02, 0xBF, 0x82, 0x82,
0x00, 0xF8, 0x0B, 0xA9, 0x00, 0xFB, 0x0B, 0xAC, 0x00, 0xC0, 0x0E, 0x43, 0x00, 0x81, 0x0B, 0x97,
0x00, 0xC2, 0x0E, 0x0A, 0x00, 0x83, 0x0E, 0x44, 0x02, 0xBF, 0x84, 0x5D, 0x00, 0xF8, 0x0B, 0xAF,
0x02, 0xDF, 0x00, 0xC0, 0x0E, 0x40, 0x00, 0x81, 0x0B, 0x89, 0x00, 0xC2, 0x0E, 0x08, 0x00, 0x83,
0x0E, 0x44, 0x00, 0xC4, 0x0E, 0x41, 0x00, 0xC5, 0x0E, 0x09, 0x02, 0xBF, 0x82, 0x82, 0x00, 0xF8,
0x0B, 0xA9, 0x00, 0xFB, 0x0B, 0xAC, 0x00, 0xC0, 0x0E, 0x40, 0x00, 0x81, 0x0B, 0x8D, 0x00, 0xC2,
0x0E, 0x0B, 0x00, 0x83, 0x0E, 0x44, 0x00, 0xC4, 0x0E, 0x41, 0x00, 0xC5, 0x0E, 0x0C, 0x02, 0xBF,
0x82, 0x82, 0x00, 0xF8, 0x0B, 0xAA, 0x00, 0xFB, 0x0B, 0xAD, 0x00, 0xC0, 0x0E, 0x43, 0x00, 0x81,
0x0B, 0x97, 0x00, 0xC2, 0x0E, 0x0A, 0x00, 0x83, 0x0E, 0x44, 0x1C, 0x80, 0x00, 0xC5, 0x0E, 0x0D,
0x02, 0xBF, 0x82, 0x82, 0x00, 0xF8, 0x0B, 0xAF, 0x00, 0xFB, 0x0B, 0xB0, 0x02, 0xDF, 0x00, 0xC0,
0x0E, 0x40, 0x00, 0x81, 0x0B, 0x89, 0x00, 0xC2, 0x0E, 0x08, 0x00, 0x83, 0x0E, 0x44, 0x00, 0xC4,
0x0E, 0x41, 0x00, 0xC5, 0x0E, 0x09, 0x02, 0xBF, 0x82, 0x82, 0x00, 0xF8, 0x0B, 0xA9, 0x00, 0xFB,
0x0B, 0xAC, 0x00, 0xC0, 0x0E, 0x40, 0x00, 0x81, 0x0B, 0x91, 0x00, 0xC2, 0x0E, 0x0E, 0x00, 0x83,
0x0E, 0x44, 0x00, 0xC4, 0x0E, 0x41, 0x00, 0xC5, 0x0E, 0x0F, 0x02, 0xBF, 0x82, 0x82, 0x00, 0xF8,
0x0B, 0xAB, 0x00, 0xFB, 0x0B, 0xAE, 0x00, 0xC0, 0x0E, 0x43, 0x00, 0x81, 0x0B, 0x95, 0x00, 0xC2,
0x0E, 0x10, 0x00, 0x83, 0x0E, 0x44, 0x1C, 0x80, 0x00, 0xC5, 0x0E, 0x0A, 0x02, 0xBF, 0x82, 0x82,
0x00, 0xF8, 0x0B, 0xB1, 0x00, 0xFB, 0x0B, 0xAF, 0x02, 0xDF, 0x00, 0xC0, 0x0E, 0x40, 0x00, 0x81,
0x0B, 0x89, 0x00, 0xC2, 0x0E, 0x08, 0x00, 0x83, 0x0E, 0x44, 0x00, 0xC4, 0x0E, 0x41, 0x00, 0xC5,
0x0E, 0x09, 0x02, 0xBF, 0x82, 0x82, 0x00, 0xF8, 0x0B, 0xA9, 0x00, 0xFB, 0x0B, 0xAC, 0x00, 0xC0,
0x0E, 0x40, 0x00, 0x81, 0x0B, 0x8D, 0x00, 0xC2, 0x0E, 0x0B, 0x00, 0x83, 0x0E, 0x44, 0x00, 0xC0,
0x0E, 0x41, 0x00, 0xC5, 0x0E, 0x0C, 0x02, 0xBF, 0x82, 0x82, 0x00, 0xF8, 0x0B, 0xAA, 0x00, 0xFB,
0x0B, 0xAD, 0x00, 0xC0, 0x0E, 0x40, 0x00, 0x81, 0x0B, 0x91, 0x00, 0xC2, 0x0E, 0x0E, 0x00, 0x83,
0x0E, 0x44, 0x00, 0xC4, 0x0E, 0x41, 0x00, 0xC5, 0x0E, 0x0F, 0x02, 0xBF, 0x82, 0x82, 0x00, 0xF8,
0x0B, 0xAB, 0x00, 0xFB, 0x0B, 0xAE, 0x00, 0xC0, 0x0E, 0x43, 0x00, 0x81, 0x0B, 0x97, 0x00, 0xC2,
0x0E, 0x0A, 0x00, 0x83, 0x0E, 0x44, 0x1C, 0x80, 0x00, 0xC5, 0x0E, 0x0D, 0x02, 0xBF, 0x82, 0x82,
0x00, 0xF8, 0x0B, 0xAF, 0x00, 0xFB, 0x0B, 0xB0, 0x00, 0xC0, 0x0E, 0x43, 0x00, 0x81, 0x0B, 0x95,
0x00, 0xC2, 0x0E, 0x10, 0x00, 0x83, 0x0E, 0x44, 0x02, 0xBF, 0x84, 0x5D, 0x00, 0xF8, 0x0B, 0xB1,
0x02, 0xDF, 0x00, 0xC0, 0x0E, 0x40, 0x00, 0x81, 0x0B, 0x89, 0x00, 0xC2, 0x0E, 0x08, 0x1C, 0x62,
0x00, 0xC4, 0x0E, 0x41, 0x00, 0xC5, 0x0E, 0x09, 0x02, 0xBF, 0x80, 0xE7, 0x00, 0xF8, 0x0B, 0xA9,
0x00, 0xFB, 0x0B, 0xAC, 0x00, 0xC0, 0x0E, 0x43, 0x00, 0x81, 0x0B, 0x91, 0x00, 0xC2, 0x0E, 0x0E,
0x1C, 0x62, 0x1C, 0x80, 0x00, 0xC5, 0x0E, 0x0F, 0x02, 0xBF, 0x80, 0xE7, 0x00, 0xF8, 0x0B, 0xAB,
0x00, 0xFB, 0x0B, 0xAE, 0x02, 0xDF, 0x00, 0xC0, 0x0E, 0x40, 0x00, 0x81, 0x0B, 0x89, 0x00, 0xC2,
0x0E, 0x08, 0x1C, 0x62, 0x00, 0xC4, 0x0E, 0x41, 0x00, 0xC5, 0x0E, 0x09, 0x02, 0xBF, 0x80, 0xE7,
0x00, 0xF8, 0x0B, 0xA9, 0x00, 0xFB, 0x0B, 0xAC, 0x00, 0xC0, 0x0E, 0x43, 0x00, 0x81, 0x0B, 0x91,
0x00, 0xC2, 0x0E, 0x0E, 0x1C, 0x62, 0x1C, 0x80, 0x00, 0xC5, 0x0E, 0x0F, 0x02, 0xBF, 0x80, 0xE7,
0x00, 0xF8, 0x0B, 0xAB, 0x00, 0xFB, 0x0B, 0xAE, 0x00, 0xC0, 0x0E, 0x40, 0x00, 0x81, 0x0B, 0x8D,
0x00, 0xC2, 0x0E, 0x0B, 0x1C, 0x62, 0x00, 0xC4, 0x0E, 0x41, 0x00, 0xC5, 0x0E, 0x0C, 0x02, 0xBF,
0x80, 0xE7, 0x00, 0xF8, 0x0B, 0xAA, 0x00, 0xFB, 0x0B, 0xAD, 0x00, 0xC0, 0x0E, 0x43, 0x00, 0x81,
0x0B, 0x99, 0x00, 0xC2, 0x0E, 0x0D, 0x1C, 0x62, 0x02, 0xBF, 0x81, 0xF9, 0x00, 0xF8, 0x0B, 0xB0,
0x02, 0xDF, 0x00, 0xC0, 0x0E, 0x40, 0x00, 0x81, 0x0B, 0x89, 0x00, 0xC2, 0x0E, 0x08, 0x00, 0x83,
0x0E, 0x44, 0x00, 0xC4, 0x0E, 0x41, 0x00, 0xC5, 0x0E, 0x09, 0x02, 0xBF, 0x82, 0x82, 0x00, 0xF8,
0x0B, 0xA9, 0x00, 0xFB, 0x0B, 0xAC, 0x00, 0xC0, 0x0E, 0x43, 0x00, 0x81, 0x0B, 0x91, 0x00, 0xC2,
0x0E, 0x0E, 0x00, 0x83, 0x0E, 0x44, 0x1C, 0x80, 0x00, 0xC5, 0x0E, 0x0F, 0x02, 0xBF, 0x82, 0x82,
0x00, 0xF8, 0x0B, 0xAB, 0x00, 0xFB, 0x0B, 0xAE, 0x02, 0xDF, 0x00, 0xC0, 0x0E, 0x40, 0x00, 0x81,
0x0B, 0x89, 0x00, 0xC2, 0x0E, 0x08, 0x00, 0x83, 0x0E, 0x44, 0x00, 0xC4, 0x0E, 0x41, 0x00, 0xC5,
0x0E, 0x09, 0x02, 0xBF, 0x82, 0x82, 0x00, 0xF8, 0x0B, 0xA9, 0x00, 0xFB, 0x0B, 0xAC, 0x00, 0xC0,
0x0E, 0x43, 0x00, 0x81, 0x0B, 0x91, 0x00, 0xC2, 0x0E, 0x0E, 0x00, 0x83, 0x0E, 0x44, 0x1C, 0x80,
0x00, 0xC5, 0x0E, 0x0F, 0x02, 0xBF, 0x82, 0x82, 0x00, 0xF8, 0x0B, 0xAB, 0x00, 0xFB, 0x0B, 0xAE,
0x00, 0xC0, 0x0E, 0x40, 0x00, 0x81, 0x0B, 0x8D, 0x00, 0xC2, 0x0E, 0x0B, 0x00, 0x83, 0x0E, 0x44,
0x00, 0xC4, 0x0E, 0x41, 0x00, 0xC5, 0x0E, 0x0C, 0x02, 0xBF, 0x82, 0x82, 0x00, 0xF8, 0x0B, 0xAA,
0x00, 0xFB, 0x0B, 0xAD, 0x00, 0xC0, 0x0E, 0x43, 0x00, 0x81, 0x0B, 0x99, 0x00, 0xC2, 0x0E, 0x0D,
0x00, 0x83, 0x0E, 0x44, 0x02, 0xBF, 0x84, 0x5D, 0x00, 0xF8, 0x0B, 0xB0, 0x02, 0xDF, 0x00, 0x82,
0x01, 0x3E, 0x01, 0xBC, 0x02, 0x48, 0x04, 0x13, 0x04, 0x27, 0x01, 0x65, 0x05, 0x74, 0x0B, 0x37,
0x01, 0x5F, 0x04, 0x78, 0x04, 0x74, 0x04, 0x76, 0x01, 0xA9, 0x04, 0x3B, 0x04, 0x7A, 0x0B, 0xB1,
0x01, 0x75, 0x07, 0x68, 0x07, 0x7A, 0x07, 0x9D, 0x07, 0xC0, 0x07, 0xF4, 0x08, 0x11, 0x08, 0x44,
0x08, 0x77, 0x08, 0xC6, 0x08, 0xD9, 0x08, 0xFE, 0x09, 0x23, 0x09, 0x5A, 0x09, 0x79, 0x09, 0xAF,
0x09, 0xE5, 0x0A, 0x39, 0x0A, 0x5B, 0x07, 0x68, 0x07, 0x68, 0x07, 0x68, 0x07, 0x68, 0x07, 0x68,
0x07, 0x68, 0x0A, 0x99, 0x0A, 0xBD, 0x07, 0x68, 0x07, 0x68, 0x07, 0x68, 0x07, 0x68, 0x07, 0x68,
0x07, 0x68, 0x05, 0xA8, 0x06, 0x5D, 0x07, 0x07, 0x10, 0x00, 0x12, 0x00, 0x14, 0x00, 0x8E, 0x00,
0x81, 0x00, 0x89, 0x70, 0x19, 0x1C, 0x2E, 0xCE, 0x2C, 0xCF, 0x16, 0xCD, 0x0E, 0x80, 0x16, 0xC9,
0x00, 0x00, 0x16, 0xCB, 0x01, 0x00, 0x1F, 0x7E, 0x1F, 0x3C, 0x81, 0x00, 0x26, 0xC9, 0x02, 0xA0,
0x00, 0x04, 0x02, 0x9C, 0x0B, 0x46, 0x19, 0x1E, 0x19, 0x1C, 0x2E, 0xCE, 0x2C, 0xCF, 0x16, 0xCD,
0x02, 0x80, 0x16, 0xC9, 0x00, 0x00, 0x16, 0xCB, 0x02, 0x80, 0x1C, 0x80, 0x00, 0x80, 0x02, 0x80,
0x00, 0xC1, 0x0E, 0x1B, 0x00, 0x85, 0x00, 0x00, 0x00, 0x89, 0x00, 0x7F, 0x00, 0x82, 0x0F, 0x00,
0x00, 0x83, 0x16, 0xB4, 0x1C, 0xE3, 0x81, 0x00, 0x26, 0xC9, 0x02, 0xA0, 0x00, 0x04, 0x02, 0x9C,
0x0B, 0x64, 0x8F, 0x00, 0x8A, 0x78, 0x8C, 0x68, 0xF1, 0x00, 0x1A, 0x3F, 0x84, 0xE3, 0x10, 0x7E,
0xF2, 0xE3, 0xF2, 0xE7, 0xF2, 0x78, 0x6E, 0x68, 0xF1, 0x32, 0x1A, 0x3F, 0x11, 0x9E, 0x0B, 0x80,
0x1C, 0x67, 0x84, 0xE3, 0x10, 0x7E, 0xF2, 0xE3, 0xF2, 0xE7, 0xF2, 0x78, 0x6E, 0x68, 0xF1, 0x32,
0x1A, 0x3F, 0x1C, 0x67, 0x84, 0xE3, 0x10, 0x7E, 0xF2, 0xE3, 0xF2, 0xE7, 0xF2, 0x00, 0x6E, 0x00,
0x1B, 0x5E, 0x00, 0xE1, 0x0E, 0x1B, 0x00, 0x80, 0x02, 0x80, 0x00, 0x83, 0x0F, 0x00, 0x00, 0x81,
0x00, 0x00, 0x00, 0x82, 0x01, 0x40, 0x00, 0x89, 0xFF, 0xFF, 0x89, 0x00, 0x81, 0x00, 0x8F, 0x00,
0x11, 0xA0, 0x0B, 0xA0, 0x19, 0x7F, 0x99, 0x30, 0x1B, 0x1E, 0x1B, 0x3F, 0x7D, 0x29, 0x1B, 0x5F,
0x1B, 0x5D, 0x8E, 0x00, 0x1F, 0xDB, 0x1F, 0x99, 0x2E, 0xCE, 0x2C, 0xCF, 0x16, 0xCD, 0x0E, 0x80,
0x16, 0xC9, 0x00, 0x01, 0x16, 0xCB, 0x01, 0x00, 0x02, 0xBF, 0x05, 0x5C, 0x1C, 0x04, 0x02, 0x9F,
0x00, 0x68, 0x8E, 0x00, 0x81, 0x00, 0x89, 0x70, 0x19, 0x1C, 0x2E, 0xCE, 0x2C, 0xCF, 0x16, 0xCD,
0x07, 0xC0, 0x16, 0xC9, 0x00, 0x01, 0x16, 0xCB, 0x05, 0x00, 0x02, 0xBF, 0x05, 0x5C, 0x81, 0x00,
0x89, 0x70, 0x19, 0x1C, 0x2E, 0xCE, 0x2C, 0xCF, 0x16, 0xCD, 0x07, 0xC0, 0x16, 0xC9, 0x00, 0x00,
0x89, 0x00, 0x0D, 0x20, 0x2D, 0xCB, 0x4C, 0x00, 0x1C, 0x80, 0x00, 0x80, 0x07, 0xC0, 0x00, 0x83,
0x00, 0x00, 0x1C, 0x43, 0x0A, 0x00, 0x27, 0xC9, 0x03, 0xA0, 0x00, 0x04, 0x02, 0x9C, 0x0B, 0xD3,
0x2E, 0xCE, 0x2C, 0xCF, 0x16, 0xCD, 0x07, 0xD0, 0x16, 0xC9, 0x00, 0x00, 0x16, 0xCB, 0x04, 0xE0,
0x8F, 0x00, 0x80, 0xF0, 0x80, 0xC0, 0x6A, 0x00, 0x48, 0x00, 0x11, 0x4F, 0x0B, 0xEE, 0x80, 0xF0,
0x80, 0xC0, 0x6B, 0x32, 0x49, 0x22, 0x80, 0xF0, 0x80, 0xC0, 0x6A, 0x3A, 0x48, 0x2A, 0x80, 0xF0,
0x80, 0xC0, 0x6B, 0x32, 0x49, 0x22, 0x1B, 0x5F, 0x1B, 0x5D, 0x80, 0xF0, 0x80, 0xC0, 0x68, 0x00,
0x7C, 0x00, 0x4A, 0x00, 0x11, 0x4F, 0x0C, 0x05, 0x80, 0xF0, 0x80, 0xC0, 0x69, 0x32, 0x7D, 0x00,
0x4B, 0x22, 0x80, 0xF0, 0x80, 0xC0, 0x68, 0x3A, 0x7C, 0x00, 0x4A, 0x2A, 0x80, 0xF0, 0x80, 0xC0,
0x69, 0x32, 0x7D, 0x00, 0x4B, 0x22, 0x1B, 0x5F, 0x1B, 0x5D, 0x1C, 0x04, 0x02, 0x9F, 0x00, 0x68,
0x8E, 0x00, 0x16, 0xFC, 0xEC, 0xC0, 0x1F, 0xCC, 0x1D, 0x9E, 0x2E, 0xFD, 0x26, 0xFC, 0x02, 0xA0,
0x80, 0x00, 0x02, 0x9C, 0x0C, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0x8E, 0x00,
0x00, 0xF0, 0x0E, 0x17, 0x00, 0xFE, 0x0E, 0x18, 0x00, 0xFC, 0x0E, 0x19, 0x1F, 0xCC, 0x1D, 0x9E,
0x16, 0xFC, 0xFE, 0xED, 0x2E, 0xFD, 0x26, 0xFC, 0x02, 0xA0, 0x80, 0x00, 0x02, 0x9C, 0x0C, 0x2B,
0x00, 0xD0, 0x0E, 0x17, 0x00, 0xDE, 0x0E, 0x18, 0x00, 0xDC, 0x0E, 0x19, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0x8E, 0x00, 0x1D, 0xBC, 0x1D, 0xBE, 0x81, 0x00, 0x00, 0xDE,
0x0B, 0xB7, 0x06, 0x01, 0x02, 0x95, 0x0C, 0x47, 0x0E, 0x00, 0x00, 0xFE, 0x0B, 0x87, 0x1F, 0xCD,
0x1F, 0x8D, 0x02, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF,
0x8E, 0x00, 0x1D, 0xBC, 0x1D, 0xBE, 0x81, 0x00, 0x00, 0xDE, 0x0B, 0xB7, 0x06, 0x01, 0x02, 0x95,
0x0C, 0x5F, 0x0E, 0x00, 0x00, 0xFE, 0x0B, 0x87, 0x1F, 0xCD, 0x1F, 0x8D, 0x02, 0xFF, 0x81, 0x00,
0x00, 0xDE, 0x0B, 0x88, 0x06, 0x01, 0x02, 0x95, 0x0C, 0x71, 0x00, 0xDE, 0x0B, 0xDA, 0x2E, 0xDA,
0x00, 0xDE, 0x0B, 0xDB, 0x2E, 0xDB, 0x00, 0xDE, 0x0B, 0xDC, 0x2E, 0xDC, 0x1F, 0xCD, 0x1F, 0x8D,
0x02, 0xFF, 0x00, 0xDE, 0x0B, 0xDA, 0x2E, 0xDA, 0x26, 0xDB, 0x2E, 0xDB, 0x26, 0xDC, 0x2E, 0xDC,
0x81, 0x00, 0x00, 0xDC, 0x0B, 0xDD, 0x76, 0x00, 0x00, 0xFC, 0x0B, 0xDD, 0x81, 0x00, 0x1F, 0xCD,
0x1F, 0x8D, 0x02, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0x0C, 0x9F, 0x0C, 0xA2, 0x0C, 0xDA,
0x0C, 0xDD, 0x8E, 0x00, 0x81, 0x00, 0x89, 0x00, 0x02, 0xBF, 0x0C, 0xE0, 0x27, 0xFF, 0x00, 0x9E,
0x0C, 0x8D, 0x4C, 0x00, 0x1C, 0x7E, 0x03, 0x13, 0x1C, 0x7F, 0x17, 0x6F, 0x00, 0x21, 0x02, 0x9F,
0x00, 0x30, 0x00, 0x21, 0x81, 0x00, 0x89, 0x00, 0x02, 0xBF, 0x0C, 0xE0, 0x24, 0xFF, 0x02, 0xBF,
0x0C, 0xE6, 0x25, 0xFF, 0x02, 0xBF, 0x0C, 0xE6, 0x27, 0xFF, 0x2E, 0xCE, 0x2C, 0xCF, 0x16, 0xC9,
0x00, 0x01, 0x2F, 0xCD, 0x2D, 0xCB, 0x81, 0x00, 0x89, 0x00, 0x02, 0xBF, 0x0C, 0xE0, 0x24, 0xFF,
0x1C, 0x9E, 0x1C, 0xBC, 0x02, 0xBF, 0x0C, 0xE6, 0x25, 0xFF, 0x02, 0xBF, 0x0C, 0xE6, 0x27, 0xFF,
0x1C, 0xDF, 0x1C, 0xFD, 0x81, 0x00, 0x02, 0xBF, 0x0C, 0xE0, 0x26, 0xFF, 0x1C, 0x1E, 0x89, 0x00,
0x02, 0xBF, 0x0C, 0xE6, 0x20, 0xFF, 0x1F, 0x5F, 0x02, 0xBF, 0x0C, 0xE0, 0x21, 0xFF, 0x02, 0xBF,
0x0C, 0xE0, 0x23, 0xFF, 0x26, 0xC9, 0x02, 0xA0, 0x00, 0x04, 0x02, 0x9C, 0x0C, 0xD2, 0x02, 0x9F,
0x80, 0xB5, 0x00, 0x21, 0x02, 0x9F, 0x80, 0x00, 0x00, 0x21, 0x02, 0x9F, 0x00, 0x45, 0x00, 0x21,
0x26, 0xFE, 0x02, 0xC0, 0x80, 0x00, 0x02, 0x9C, 0x0C, 0xE0, 0x02, 0xDF, 0x27, 0xFE, 0x03, 0xC0,
0x80, 0x00, 0x02, 0x9C, 0x0C, 0xE6, 0x02, 0xDF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
u16 dspSlaveLength = sizeof(dspSlave);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,504 @@
#include "musyx/assert.h"
#include "musyx/hardware.h"
#include "musyx/stream.h"
#include "musyx/synth.h"
#include "musyx/sal.h"
extern void DCStoreRange(void* addr, u32 nBytes);
static volatile const u16 itdOffTab[128] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4,
5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 15, 15, 15, 16,
16, 17, 17, 17, 18, 18, 19, 19, 19, 20, 20, 20, 21, 21, 22, 22, 22, 23, 23, 23, 24, 24, 24, 25, 25, 25, 26, 26, 26, 27, 27, 27,
28, 28, 28, 28, 29, 29, 29, 29, 29, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
};
//SND_PROFILE_INFO prof;
u8 salFrame;
u8 salAuxFrame;
u8 salNumVoices;
u8 salMaxStudioNum;
SND_HOOKS salHooks;
u8 salTimeOffset;
void hwSetTimeOffset(u8 offset);
static void snd_handle_irq() {
u8 r; // r31
u8 i; // r30
u8 v; // r29
if (sndActive == 0) {
return;
}
streamCorrectLoops();
hwIRQEnterCritical();
// sndProfStartPCM(&prof.dspCtrl);
salCtrlDsp(salAiGetDest());
// sndProfStopPMC(&prof.dspCtrl);
hwIRQLeaveCritical();
hwIRQEnterCritical();
// sndProfStartPCM(&prof.auxProcessing);
salHandleAuxProcessing();
// sndProfStopPMC(&prof.auxProcessing);
hwIRQLeaveCritical();
hwIRQEnterCritical();
salFrame ^= 1;
salAuxFrame = (salAuxFrame + 1) % 3;
for (v = 0; v < salNumVoices; ++v) {
for (i = 0; i < 5; ++i) {
dspVoice[v].changed[i] = 0;
}
}
// sndProfStartPMC(&prof.sequencer);
// sndProfPausePMC(&prof.sequencer);
// sndProfStartPMC(&prof.synthesizer);
// sndProfPausePMC(&prof.synthesizer);
hwIRQLeaveCritical();
for (r = 0; r < 5; ++r) {
hwIRQEnterCritical();
hwSetTimeOffset(r);
// sndProfStartPMC(&prof.sequencer);
seqHandle(256);
// sndProfPausePMC(&prof.sequencer);
// sndProfStartPMC(&prof.synthesizer);
synthHandle(256);
// sndProfPausePMC(&prof.synthesizer);
hwIRQLeaveCritical();
}
// sndProfStopPMC(&prof.sequencer);
// sndProfStopPMC(&prof.synthesizer);
hwIRQEnterCritical();
hwSetTimeOffset(0);
// sndProfStartPMC(&prof.emitters);
s3dHandle();
// sndProfStopPMC(&prof.emitters);
hwIRQLeaveCritical();
hwIRQEnterCritical();
// sndProfStartPMC(&prof.streaming);
streamHandle();
// sndProfStopPMC(&prof.streaming);
hwIRQLeaveCritical();
hwIRQEnterCritical();
vsSampleUpdates();
hwIRQLeaveCritical();
// sndProfUpdateMisc(&prof);
// if (sndProfUserCallback) {
// sndProfUserCallback(&prof);
// }
}
s32 hwInit(u32* frq, u16 numVoices, u16 numStudios, u32 flags) {
MUSY_DEBUG("Entering hwInit()\n\n");
hwInitIrq();
salFrame = 0;
salAuxFrame = 0;
salMessageCallback = NULL;
if (salInitAi(snd_handle_irq, flags, frq) != 0) {
MUSY_DEBUG("salInitAi() is done.\n\n");
if (salInitDspCtrl(numVoices, numStudios, (flags & 1) != 0) != 0) {
MUSY_DEBUG("salInitDspCtrl() is done.\n\n");
if (salInitDsp(flags)) {
MUSY_DEBUG("salInitDsp() is done.\n\n");
hwEnableIrq();
MUSY_DEBUG("Starting AI DMA...\n\n");
salStartAi();
MUSY_DEBUG("hwInit() done.\n\n");
return 0;
}
MUSY_DEBUG("Could not initialize DSP.\n");
} else {
MUSY_DEBUG("Could not initialize DSP control logic.\n");
}
} else {
MUSY_DEBUG("Could not initialize AI.\n");
}
return -1;
}
void hwExit() {
hwDisableIrq();
salExitDsp();
salExitDspCtrl();
salExitAi();
hwEnableIrq();
hwExitIrq();
}
void hwSetTimeOffset(u8 offset) { salTimeOffset = offset; }
u8 hwGetTimeOffset() { return salTimeOffset; }
u32 hwIsActive(u32 v) { return dspVoice[v].state != 0; }
u32 hwGlobalActivity() { return 0; }
void hwSetMesgCallback(SND_MESSAGE_CALLBACK callback) { salMessageCallback = callback; }
void hwSetPriority(u32 v, u32 prio) { dspVoice[v].prio = prio; }
void hwInitSamplePlayback(u32 v, u16 smpID, void* newsmp, u32 set_defadsr, u32 prio, u32 callbackUserValue, u32 setSRC, u8 itdMode) {
unsigned char i; // r30
unsigned long bf; // r29
bf = 0;
for (i = 0; i <= salTimeOffset; ++i) {
bf |= dspVoice[v].changed[i] & 0x20;
dspVoice[v].changed[i] = 0;
}
dspVoice[v].changed[0] = bf;
dspVoice[v].prio = prio;
dspVoice[v].mesgCallBackUserValue = callbackUserValue;
dspVoice[v].flags = 0;
dspVoice[v].smp_id = smpID;
dspVoice[v].smp_info = *(SAMPLE_INFO*)newsmp;
if (set_defadsr != 0) {
dspVoice[v].adsr.mode = 0;
dspVoice[v].adsr.data.dls.aTime = 0;
dspVoice[v].adsr.data.dls.dTime = 0;
dspVoice[v].adsr.data.dls.sLevel = 0x7FFF;
dspVoice[v].adsr.data.dls.rTime = 0;
}
dspVoice[v].lastUpdate.pitch = 0xff;
dspVoice[v].lastUpdate.vol = 0xff;
dspVoice[v].lastUpdate.volA = 0xff;
dspVoice[v].lastUpdate.volB = 0xff;
if (setSRC != 0) {
hwSetSRCType(v, 0);
hwSetPolyPhaseFilter(v, 1);
}
hwSetITDMode(v, itdMode);
}
void hwBreak(s32 vid) {
if (dspVoice[vid].state == 1 && salTimeOffset == 0) {
dspVoice[vid].startupBreak = 1;
}
dspVoice[vid].changed[salTimeOffset] |= 0x20;
}
void hwSetADSR(u32 v, void* _adsr, u8 mode) {
u32 sl; // r29
ADSR_INFO* adsr = (ADSR_INFO*)_adsr; // r30
switch (mode) {
case 0: {
dspVoice[v].adsr.mode = 0;
dspVoice[v].adsr.data.linear.aTime = adsr->data.linear.atime;
dspVoice[v].adsr.data.linear.dTime = adsr->data.linear.dtime;
sl = adsr->data.linear.slevel << 3;
if (sl > 0x7fff) {
sl = 0x7fff;
}
dspVoice[v].adsr.data.linear.sLevel = sl;
dspVoice[v].adsr.data.linear.rTime = adsr->data.linear.rtime;
break;
}
case 1:
case 2:
dspVoice[v].adsr.mode = 1;
dspVoice[v].adsr.data.dls.aMode = 0;
if (mode == 1) {
dspVoice[v].adsr.data.dls.aTime = adsrConvertTimeCents(adsr->data.dls.atime) & 0xFFFF;
dspVoice[v].adsr.data.dls.dTime = adsrConvertTimeCents(adsr->data.dls.dtime) & 0xFFFF;
sl = adsr->data.dls.slevel >> 2;
if (sl > 0x3ff) {
sl = 0x3ff;
}
dspVoice[v].adsr.data.dls.sLevel = 193 - dspScale2IndexTab[sl];
} else {
dspVoice[v].adsr.data.dls.aTime = adsr->data.dls.atime & 0xFFFF;
dspVoice[v].adsr.data.dls.dTime = adsr->data.dls.dtime & 0xFFFF;
dspVoice[v].adsr.data.dls.sLevel = adsr->data.dls.slevel;
}
dspVoice[v].adsr.data.dls.rTime = adsr->data.dls.rtime;
}
dspVoice[v].changed[0] |= 0x10;
}
void hwSetVirtualSampleLoopBuffer(u32 voice, void* addr, u32 len) {
dspVoice[voice].vSampleInfo.loopBufferAddr = addr;
dspVoice[voice].vSampleInfo.loopBufferLength = len;
}
u32 hwGetVirtualSampleState(u32 voice) { return dspVoice[voice].vSampleInfo.inLoopBuffer; }
u8 hwGetSampleType(u32 voice) { return dspVoice[voice].smp_info.compType; }
u16 hwGetSampleID(u32 voice) { return dspVoice[voice].smp_id; }
void hwSetStreamLoopPS(u32 voice, u8 ps) { dspVoice[voice].streamLoopPS = ps; }
void hwStart(u32 v, u8 studio) {
dspVoice[v].singleOffset = salTimeOffset;
salActivateVoice(&dspVoice[v], studio);
}
void hwKeyOff(u32 v) { dspVoice[v].changed[salTimeOffset] |= 0x40; }
void hwSetPitch(unsigned long v, unsigned short speed) {
struct DSPvoice* dsp_vptr = &dspVoice[v];
if (speed >= 0x4000) {
speed = 0x3fff;
}
if (dsp_vptr->lastUpdate.pitch != 0xff && dsp_vptr->pitch[dsp_vptr->lastUpdate.pitch] == speed * 16) {
return;
}
dsp_vptr->pitch[salTimeOffset] = speed * 16;
dsp_vptr->changed[salTimeOffset] |= 8;
dsp_vptr->lastUpdate.pitch = salTimeOffset;
}
void hwSetSRCType(u32 v, u8 salSRCType) {
static u16 dspSRCType[3] = {0, 1, 2};
struct DSPvoice* dsp_vptr = &dspVoice[v];
dsp_vptr->srcTypeSelect = dspSRCType[salSRCType];
dsp_vptr->changed[0] |= 0x100;
}
void hwSetPolyPhaseFilter(unsigned long v, unsigned char salCoefSel) {
static u16 dspCoefSel[3] = {0, 1, 2};
struct DSPvoice* dsp_vptr = &dspVoice[v];
dsp_vptr->srcCoefSelect = dspCoefSel[salCoefSel];
dsp_vptr->changed[0] |= 0x80;
}
static void SetupITD(DSPvoice* dsp_vptr, u8 pan) {
dsp_vptr->itdShiftL = itdOffTab[pan];
dsp_vptr->itdShiftR = 32 - itdOffTab[pan];
dsp_vptr->changed[0] |= 0x200;
}
void hwSetITDMode(u32 v, u8 mode) {
if (!mode) {
dspVoice[v].flags |= 0x80000000;
dspVoice[v].itdShiftL = 16;
dspVoice[v].itdShiftR = 16;
return;
}
dspVoice[v].flags &= ~0x80000000;
}
#define hwGetITDMode(dsp_vptr) (dsp_vptr->flags & 0x80000000)
void hwSetVolume(unsigned long v, unsigned char table, float vol, unsigned long pan, unsigned long span, float auxa, float auxb) {
SAL_VOLINFO vi; // r1+0x24
unsigned short il; // r30
unsigned short ir; // r29
unsigned short is; // r28
DSPvoice* dsp_vptr = &dspVoice[v]; // r31
if (vol >= 1.f) {
vol = 1.f;
}
if (auxa >= 1.f) {
auxa = 1.f;
}
if (auxb >= 1.f) {
auxb = 1.f;
}
salCalcVolume(table, &vi, vol, pan, span, auxa, auxb, (dsp_vptr->flags & 0x80000000) != 0,
dspStudio[dsp_vptr->studio].type == SND_STUDIO_TYPE_RESERVED0);
il = 32767.f * vi.volL;
ir = 32767.f * vi.volR;
is = 32767.f * vi.volS;
if (dsp_vptr->lastUpdate.vol == 0xff || dsp_vptr->volL != il || dsp_vptr->volR != ir || dsp_vptr->volS != is) {
dsp_vptr->volL = il;
dsp_vptr->volR = ir;
dsp_vptr->volS = is;
dsp_vptr->changed[0] |= 1;
dsp_vptr->lastUpdate.vol = 0;
}
il = 32767.f * vi.volAuxAL;
ir = 32767.f * vi.volAuxAR;
is = 32767.f * vi.volAuxAS;
if (dsp_vptr->lastUpdate.volA == 0xff || dsp_vptr->volLa != il || dsp_vptr->volRa != ir || dsp_vptr->volSa != is) {
dsp_vptr->volLa = il;
dsp_vptr->volRa = ir;
dsp_vptr->volSa = is;
dsp_vptr->changed[0] |= 2;
dsp_vptr->lastUpdate.volA = 0;
}
il = 32767.f * vi.volAuxBL;
ir = 32767.f * vi.volAuxBR;
is = 32767.f * vi.volAuxBS;
if (dsp_vptr->lastUpdate.volB == 0xff || dsp_vptr->volLb != il || dsp_vptr->volRb != ir || dsp_vptr->volSb != is) {
dsp_vptr->volLb = il;
dsp_vptr->volRb = ir;
dsp_vptr->volSb = is;
dsp_vptr->changed[0] |= 4;
dsp_vptr->lastUpdate.volB = 0;
}
if (hwGetITDMode(dsp_vptr)) {
SetupITD(dsp_vptr, (pan >> 16));
}
}
void hwOff(s32 vid) { salDeactivateVoice(&dspVoice[vid]); }
void hwSetAUXProcessingCallbacks(u8 studio, SND_AUX_CALLBACK auxA, void* userA, SND_AUX_CALLBACK auxB, void* userB) {
dspStudio[studio].auxAHandler = auxA;
dspStudio[studio].auxAUser = userA;
dspStudio[studio].auxBHandler = auxB;
dspStudio[studio].auxBUser = userB;
}
void hwActivateStudio(unsigned char studio, unsigned long isMaster, SND_STUDIO_TYPE type) { salActivateStudio(studio, isMaster, type); }
void hwDeactivateStudio(u8 studio) { salDeactivateStudio(studio); }
void hwChangeStudioMix(u8 studio, u32 isMaster) { dspStudio[studio].isMaster = isMaster; }
bool hwIsStudioActive(u8 studio) { return dspStudio[studio].state == 1; }
bool hwAddInput(u8 studio, SND_STUDIO_INPUT* in_desc) { return salAddStudioInput(&dspStudio[studio], in_desc); }
bool hwRemoveInput(u8 studio, SND_STUDIO_INPUT* in_desc) { return salRemoveStudioInput(&dspStudio[studio], in_desc); }
void hwChangeStudio(u32 v, u8 studio) { salReconnectVoice(&dspVoice[v], studio); }
u32 hwGetPos(u32 v) {
unsigned long pos; // r31
unsigned long off; // r30
if (dspVoice[v].state != 2) {
return 0;
}
switch (dspVoice[v].smp_info.compType) {
case 0:
case 1:
case 4:
case 5:
pos = ((dspVoice[v].currentAddr - (u32)dspVoice[v].smp_info.addr * 2) / 16) * 14;
off = dspVoice[v].currentAddr & 0xf;
if (off >= 2) {
pos += off - 2;
}
break;
case 3:
pos = dspVoice[v].currentAddr - (u32)dspVoice[v].smp_info.addr;
break;
case 2:
pos = dspVoice[v].currentAddr - ((u32)dspVoice[v].smp_info.addr / 2);
break;
}
return pos;
}
void hwFlushStream(void* base, unsigned long offset, unsigned long bytes, unsigned char hwStreamHandle, void (*callback)(unsigned long),
unsigned long user) {
u32 aram; // r28
u32 mram; // r29
u32 len;
aram = aramGetStreamBufferAddress(hwStreamHandle, &len);
bytes += (offset & 31);
offset &= ~31;
bytes = (bytes + 31) & ~31;
mram = (u32)base + offset;
DCStoreRange((void*)mram, bytes);
aramUploadData((void*)mram, aram + offset, bytes, 1, callback, user);
}
void hwPrepareStreamBuffer() {}
u8 hwInitStream(u32 len) { return aramAllocateStreamBuffer(len); }
void hwExitStream(u8 id) { aramFreeStreamBuffer(id); }
void* hwGetStreamPlayBuffer(u8 hwStreamHandle) { return (void*)aramGetStreamBufferAddress(hwStreamHandle, NULL); }
void* hwTransAddr(void* samples) { return samples; }
u32 hwFrq2Pitch(u32 frq) { return (frq * 4096.f) / synthInfo.mixFrq; }
void hwInitSampleMem(u32 baseAddr, u32 length) {
#line 940
MUSY_ASSERT(baseAddr==0x00000000);
aramInit(length);
}
void hwExitSampleMem() { aramExit(); }
static u32 convert_length(u32 len, u8 type) {
switch (type) {
case 0:
case 1:
case 4:
case 5:
return (((u32)((len + 0xD) / 0xe))) * 8;
case 2:
return len * 2;
}
return len;
}
void hwSaveSample(void* header, void* data) {
u32 len = ((u32*)*((u32*)header))[1] & 0xFFFFFF;
u8 type = ((u32*)*((u32*)header))[1] >> 0x18;
len = convert_length(len, type);
*((u32*)data) = (u32)aramStoreData((void*)*((u32*)data), len);
}
void hwSetSaveSampleCallback(ARAMUploadCallback callback, unsigned long chunckSize) { aramSetUploadCallback(callback, chunckSize); }
void hwRemoveSample(void* header, void* data) {
#if MUSY_VERSION <= MUSY_VERSION_CHECK(1, 5, 3)
u32 len = (((u32*)header))[1] & 0xFFFFFF;
u8 type = (((u32*)header))[1] >> 0x18;
len = convert_length(len, type);
#else
u8 type = (((u32*)header))[1] >> 0x18;
u32 len = convert_length((((u32*)header))[1] & 0xFFFFFF, type);
#endif
aramRemoveData(data, len);
}
void hwSyncSampleMem() { aramSyncTransferQueue(); }
void hwFrameDone() {}
void sndSetHooks(SND_HOOKS* hooks) { salHooks = *hooks; }
void hwEnableHRTF() {
if (dspHRTFOn != FALSE) {
return;
}
dspHRTFOn = TRUE;
salInitHRTFBuffer();
}
void hwDisableHRTF() { dspHRTFOn = FALSE; }
u32 hwGetVirtualSampleID(u32 v) {
if (dspVoice[v].state == 0) {
return 0xFFFFFFFF;
}
return dspVoice[v].virtualSampleID;
}
bool hwVoiceInStartup(u32 v) { return dspVoice[v].state == 1; }

View File

@ -0,0 +1,339 @@
#include <dolphin/ar.h>
#include <dolphin/arq.h>
#include <dolphin/os.h>
#include "musyx/assert.h"
typedef struct ARAMTransferJob {
// total size: 0x28
ARQRequest arq; // offset 0x0, size 0x20
void (*callback)(unsigned long); // offset 0x20, size 0x4
unsigned long user; // offset 0x24, size 0x4
} ARAMTransferJob;
typedef struct ARAMTransferQueue {
// total size: 0x284
ARAMTransferJob queue[16]; // offset 0x0, size 0x280
vu8 write; // offset 0x280, size 0x1
vu8 valid; // offset 0x281, size 0x1
} ARAMTransferQueue;
typedef struct STREAM_BUFFER {
// total size: 0x10
struct STREAM_BUFFER* next; // offset 0x0, size 0x4
unsigned long aram; // offset 0x4, size 0x4
unsigned long length; // offset 0x8, size 0x4
unsigned long allocLength; // offset 0xC, size 0x4
} STREAM_BUFFER;
static unsigned long aramTop; // size: 0x4
static unsigned long aramWrite; // size: 0x4
static unsigned long aramStream; // size: 0x4
static void* (*aramUploadCallback)(unsigned long, unsigned long); // size: 0x4
static unsigned long aramUploadChunkSize; // size: 0x4
static ARAMTransferQueue aramQueueLo;
static ARAMTransferQueue aramQueueHi;
static STREAM_BUFFER aramStreamBuffers[64];
static STREAM_BUFFER* aramUsedStreamBuffers;
static STREAM_BUFFER* aramFreeStreamBuffers;
static STREAM_BUFFER* aramIdleStreamBuffers;
static void InitStreamBuffers();
static void aramQueueInit() {
aramQueueLo.write = aramQueueLo.valid = 0;
aramQueueHi.write = aramQueueHi.valid = 0;
}
static void aramQueueCallback(unsigned long ptr) {
u32 i; // r31
ARQRequest* arq; // r29
ARAMTransferQueue* aramQueue; // r30
arq = (ARQRequest*)ptr;
if (arq->priority == 1) {
aramQueue = &aramQueueHi;
} else {
aramQueue = &aramQueueLo;
}
for (i = 0; i < 16; ++i) {
if (arq == &aramQueue->queue[i].arq && aramQueue->queue[i].callback) {
aramQueue->queue[i].callback(aramQueue->queue[i].user);
}
}
--aramQueue->valid;
}
void aramUploadData(void* mram, unsigned long aram, unsigned long len, unsigned long highPrio,
void (*callback)(unsigned long), unsigned long user) {
ARAMTransferQueue* aramQueue; // r31
int old; // r30
aramQueue = highPrio != 0 ? &aramQueueHi : &aramQueueLo;
for (;;) {
old = OSDisableInterrupts();
if (aramQueue->valid < 16) {
aramQueue->queue[aramQueue->write].arq.owner = 42;
aramQueue->queue[aramQueue->write].arq.type = 0;
aramQueue->queue[aramQueue->write].arq.priority = highPrio != 0 ? 1 : 0;
aramQueue->queue[aramQueue->write].arq.source = (u32)mram;
aramQueue->queue[aramQueue->write].arq.dest = aram;
aramQueue->queue[aramQueue->write].arq.length = len;
aramQueue->queue[aramQueue->write].arq.callback = aramQueueCallback;
aramQueue->queue[aramQueue->write].callback = callback;
aramQueue->queue[aramQueue->write].user = user;
ARQPostRequest(&aramQueue->queue[aramQueue->write].arq,
aramQueue->queue[aramQueue->write].arq.owner,
aramQueue->queue[aramQueue->write].arq.type,
aramQueue->queue[aramQueue->write].arq.priority,
aramQueue->queue[aramQueue->write].arq.source,
aramQueue->queue[aramQueue->write].arq.dest,
aramQueue->queue[aramQueue->write].arq.length,
aramQueue->queue[aramQueue->write].arq.callback);
++aramQueue->valid;
aramQueue->write = (aramQueue->write + 1) % 16;
OSRestoreInterrupts(old);
return;
}
OSRestoreInterrupts(old);
}
}
void aramSyncTransferQueue() {
while (aramQueueLo.valid != 0) {
}
}
void aramInit(unsigned long length) {
signed short* tmpMem; // r30
unsigned long i; // r29
unsigned long aramBase; // r28
#line 173
MUSY_ASSERT_MSG(length > sizeof(s16) * 640, "ARAM size is too small");
aramBase = ARGetBaseAddress();
tmpMem = (s16*)salMalloc(sizeof(s16) * 640);
#line 182
MUSY_ASSERT_MSG(tmpMem != NULL, "Could not allocate temporary storage");
for (i = 0; i < 640; ++i) {
tmpMem[i] = 0;
}
DCFlushRange(tmpMem, sizeof(s16) * 640);
aramQueueInit();
aramUploadData(tmpMem, aramBase, sizeof(s16) * 640, 0, NULL, 0);
aramSyncTransferQueue();
salFree(tmpMem);
aramTop = aramBase + length;
if (aramTop > ARGetSize()) {
aramTop = ARGetSize();
}
aramWrite = aramBase + sizeof(s16) * 640;
aramUploadCallback = NULL;
InitStreamBuffers();
MUSY_DEBUG("MusyX ARAM handler initialized\n");
}
void aramExit() {}
unsigned long aramGetZeroBuffer() { return ARGetBaseAddress(); }
void aramSetUploadCallback(void* (*callback)(unsigned long, unsigned long),
unsigned long chunckSize) {
unsigned long acs; // r30
if (callback != NULL) {
chunckSize = (chunckSize + 31) & ~31;
acs = ARQGetChunkSize();
aramUploadChunkSize = chunckSize < acs ? acs : chunckSize;
}
aramUploadCallback = callback;
}
void* aramStoreData(void* src, unsigned long len) {
unsigned long addr; // r26
void* buffer; // r27
unsigned long blkSize; // r30
len = (len + 31) & ~31;
#line 266
MUSY_ASSERT_MSG(aramWrite + len <= aramStream, "Data will not fit in remaining ARAM space");
addr = aramWrite;
if (aramUploadCallback == NULL) {
#line 276
MUSY_ASSERT_MSG(!((u32)src & 31), "MRAM address is not aligned properly");
DCFlushRange(src, len);
aramUploadData(src, aramWrite, len, 0, NULL, 0);
aramWrite += len;
return (void*)addr;
}
while (len != 0) {
blkSize = len >= aramUploadChunkSize ? aramUploadChunkSize : len;
buffer = (void*)aramUploadCallback((u32)src, blkSize);
#line 297
MUSY_ASSERT_MSG(!((u32)buffer & 31), "MRAM address is not aligned properly");
DCFlushRange(buffer, blkSize);
aramUploadData(buffer, aramWrite, blkSize, 0, NULL, 0);
len -= blkSize;
aramWrite += blkSize;
src = (void*)((u32)src + blkSize);
}
return (void*)addr;
}
void aramRemoveData(void* aram, unsigned long len) {
len = (len + 31) & ~31;
aramWrite -= len;
#line 328
MUSY_ASSERT_MSG((u32)aram == aramWrite,
"Current ARAM address does not match originally allocated one");
}
static void InitStreamBuffers() {
unsigned long i; // r31
aramUsedStreamBuffers = NULL;
aramFreeStreamBuffers = NULL;
aramIdleStreamBuffers = aramStreamBuffers;
for (i = 1; i < 64; ++i) {
aramStreamBuffers[i - 1].next = &aramStreamBuffers[i];
}
aramStreamBuffers[i - 1].next = NULL;
aramStream = aramTop;
}
unsigned char aramAllocateStreamBuffer(unsigned long len) {
STREAM_BUFFER* sb; // r30
STREAM_BUFFER* oSb; // r31
STREAM_BUFFER* lastSb; // r28
u32 minLen; // r27
len = (len + 31) & ~31;
lastSb = oSb = NULL;
minLen = -1;
for (sb = aramFreeStreamBuffers; sb != NULL; sb = sb->next) {
if (sb->allocLength == len) {
oSb = sb;
break;
}
if (sb->allocLength > len && minLen > sb->allocLength) {
oSb = sb;
minLen = sb->allocLength;
}
lastSb = sb;
}
if (oSb == NULL) {
if (aramIdleStreamBuffers != NULL && aramStream - len >= aramWrite) {
oSb = aramIdleStreamBuffers;
aramIdleStreamBuffers = oSb->next;
oSb->allocLength = len;
oSb->length = len;
aramStream -= len;
oSb->aram = aramStream;
oSb->next = aramUsedStreamBuffers;
aramUsedStreamBuffers = oSb;
}
} else {
if (lastSb != NULL) {
lastSb->next = oSb->next;
} else {
aramFreeStreamBuffers = oSb->next;
}
oSb->length = len;
oSb->next = aramUsedStreamBuffers;
aramUsedStreamBuffers = oSb;
}
if (oSb == NULL) {
MUSY_DEBUG("No stream buffer slots available or ARAM.\n\n");
return 0xFF;
}
return (oSb - aramStreamBuffers);
}
unsigned long aramGetStreamBufferAddress(unsigned char id, unsigned long* len) {
#line 467
MUSY_ASSERT_MSG(id != 0xFF, "Stream buffer ID is invalid");
if (len != NULL) {
*len = aramStreamBuffers[id].length;
}
return aramStreamBuffers[id].aram;
}
void aramFreeStreamBuffer(unsigned char id) {
struct STREAM_BUFFER* fSb; // r30
struct STREAM_BUFFER* sb; // r31
struct STREAM_BUFFER* lastSb; // r29
struct STREAM_BUFFER* nextSb; // r27
unsigned long minAddr; // r28
MUSY_ASSERT_MSG(id != 0xFF, "Stream buffer ID is invalid");
fSb = &aramStreamBuffers[id];
lastSb = NULL;
sb = aramUsedStreamBuffers;
while (sb != NULL) {
if (sb == fSb) {
if (lastSb != NULL) {
lastSb->next = fSb->next;
} else {
aramUsedStreamBuffers = fSb->next;
}
break;
} else {
lastSb = sb;
sb = sb->next;
}
}
if (fSb->aram == aramStream) {
fSb->next = aramIdleStreamBuffers;
aramIdleStreamBuffers = fSb;
minAddr = -1;
sb = aramUsedStreamBuffers;
while (sb != NULL) {
if (sb->aram <= minAddr) {
minAddr = sb->aram;
}
sb = sb->next;
}
lastSb = NULL;
sb = aramFreeStreamBuffers;
while (sb != NULL) {
nextSb = sb->next;
if (sb->aram < minAddr) {
if (lastSb != NULL) {
lastSb->next = sb->next;
} else {
aramFreeStreamBuffers = sb->next;
}
sb->next = aramIdleStreamBuffers;
aramIdleStreamBuffers = sb;
}
sb = nextSb;
}
aramStream = minAddr != -1 ? minAddr : aramTop;
return;
}
fSb->next = aramFreeStreamBuffers;
aramFreeStreamBuffers = fSb;
}

View File

@ -0,0 +1,171 @@
#include "dolphin/dsp.h"
#include "musyx/assert.h"
#include "musyx/dsp_import.h"
#include "musyx/hardware.h"
#include "musyx/sal.h"
static DSPTaskInfo dsp_task ATTRIBUTE_ALIGN(8);
static u16 dram_image[4096] ATTRIBUTE_ALIGN(32);
static volatile u32 oldState = 0;
static volatile u16 hwIrqLevel = 0;
static volatile u32 salDspInitIsDone = 0;
static volatile OSTick salLastTick = 0;
static volatile u32 salLogicActive = 0;
static volatile u32 salLogicIsWaiting = 0;
static volatile u32 salDspIsDone = 0;
void* salAIBufferBase = NULL;
static u8 salAIBufferIndex = 0;
static SND_SOME_CALLBACK userCallback = NULL;
#define DMA_BUFFER_LEN 0x280
u32 salGetStartDelay();
static void callUserCallback() {
if (salLogicActive) {
return;
}
salLogicActive = 1;
OSEnableInterrupts();
userCallback();
OSDisableInterrupts();
salLogicActive = 0;
}
void salCallback() {
salAIBufferIndex = (salAIBufferIndex + 1) % 4;
AIInitDMA(OSCachedToPhysical(salAIBufferBase) + (salAIBufferIndex * DMA_BUFFER_LEN),
DMA_BUFFER_LEN);
salLastTick = OSGetTick();
if (salDspIsDone) {
callUserCallback();
} else {
salLogicIsWaiting = 1;
}
}
void dspInitCallback() {
salDspIsDone = TRUE;
salDspInitIsDone = TRUE;
}
void dspResumeCallback() {
salDspIsDone = TRUE;
if (salLogicIsWaiting) {
salLogicIsWaiting = FALSE;
callUserCallback();
}
}
u32 salInitAi(SND_SOME_CALLBACK callback, u32 unk, u32* outFreq) {
if ((salAIBufferBase = salMalloc(DMA_BUFFER_LEN * 4)) != NULL) {
memset(salAIBufferBase, 0, DMA_BUFFER_LEN * 4);
DCFlushRange(salAIBufferBase, DMA_BUFFER_LEN * 4);
salAIBufferIndex = TRUE;
salLogicIsWaiting = FALSE;
salDspIsDone = TRUE;
salLogicActive = FALSE;
userCallback = callback;
AIRegisterDMACallback(salCallback);
AIInitDMA(OSCachedToPhysical(salAIBufferBase) + (salAIBufferIndex * 0x280), 0x280);
synthInfo.numSamples = 0x20;
*outFreq = 32000;
MUSY_DEBUG("MusyX AI interface initialized.\n");
return TRUE;
}
return FALSE;
}
u32 salStartAi() { AIStartDMA(); }
u32 salExitAi() {
AIRegisterDMACallback(NULL);
AIStopDMA();
salFree(salAIBufferBase);
return TRUE;
}
void* salAiGetDest() {
u8 index; // r31
index = (salAIBufferIndex + 2) % 4;
return (void*)((u8*)salAIBufferBase + index * DMA_BUFFER_LEN);
}
u32 salInitDsp() {
u8 _[8];
dsp_task.iram_mmem_addr = (u16*)dspSlave;
dsp_task.iram_length = dspSlaveLength;
dsp_task.iram_addr = 0;
dsp_task.dram_mmem_addr = (u16*)dram_image;
dsp_task.dram_length = 0x2000;
dsp_task.dram_addr = 0;
dsp_task.dsp_init_vector = 0x10;
dsp_task.dsp_resume_vector = 0x30;
dsp_task.init_cb = dspInitCallback;
dsp_task.res_cb = dspResumeCallback;
dsp_task.done_cb = NULL;
dsp_task.req_cb = NULL;
dsp_task.priority = 0;
DSPInit();
DSPAddTask(&dsp_task);
salDspInitIsDone = FALSE;
hwEnableIrq();
while (!salDspInitIsDone)
;
hwDisableIrq();
return TRUE;
}
u32 salExitDsp() {
DSPHalt();
while (DSPGetDMAStatus())
;
DSPReset();
return TRUE;
}
void salStartDsp(u16* cmdList) {
salDspIsDone = FALSE;
PPCSync();
/* clang-format off */
MUSY_ASSERT(((u32)cmdList&0x1F) == 0);
/* clang-format on */
DSPSendMailToDSP(dspCmdFirstSize | 0xbabe0000);
while (DSPCheckMailToDSP())
;
DSPSendMailToDSP((u32)cmdList);
while (DSPCheckMailToDSP())
;
}
void salCtrlDsp(u32 unk) {
salBuildCommandList(unk, salGetStartDelay());
salStartDsp(dspCmdList);
}
u32 salGetStartDelay() { return OSTicksToMicroseconds(OSGetTick() - salLastTick); }
void hwInitIrq() {
oldState = OSDisableInterrupts();
hwIrqLevel = 1;
}
void hwExitIrq() {}
void hwEnableIrq() {
if (--hwIrqLevel == 0) {
OSRestoreInterrupts(oldState);
}
}
void hwDisableIrq() {
if ((hwIrqLevel++) == 0) {
oldState = OSDisableInterrupts();
}
}
void hwIRQEnterCritical() { OSDisableInterrupts(); }
void hwIRQLeaveCritical() { OSEnableInterrupts(); }

View File

@ -0,0 +1,94 @@
#include "dolphin/PPCArch.h"
#include "musyx/musyx_priv.h"
SND_PROF_USERCALLBACK sndProfUserCallback = NULL;
void sndProfSetCallback(SND_PROF_USERCALLBACK callback) { sndProfUserCallback = callback; }
void sndProfUpdateMisc(SND_PROFILE_INFO* info) {
info->numMusicVoices = voiceMusicRunning;
info->numSFXVoices = voiceFxRunning;
}
void sndProfResetPMC(SND_PROFILE_DATA* info) {
PPCMtpmc1(0);
PPCMtpmc2(0);
PPCMtpmc3(0);
PPCMtpmc4(0);
info->sumLoadStores = info->loadStores = 0;
info->sumMissCycles = info->missCycles = 0;
info->sumCycles = info->cycles = 0;
info->sumInstructions = info->instructions = 0;
info->peekLoadStores = 0;
info->peekMissCycles = 0;
info->peekCycles = 0;
info->peekInstructions = 0;
info->cnt = 0;
info->paused = 1;
}
void sndProfStartPMC(SND_PROFILE_DATA* info) {
PPCMtmmcr0(0);
PPCMtmmcr1(0);
info->paused = 0;
info->_loadStores = PPCMfpmc2();
info->_missCycles = PPCMfpmc3();
info->_cycles = PPCMfpmc4();
info->_instructions = PPCMfpmc1();
PPCMtmmcr1(0x78400000);
PPCMtmmcr0(0xc08b);
}
void sndProfPausePMC(SND_PROFILE_DATA* info) {
PPCMtmmcr0(0);
PPCMtmmcr1(0);
info->loadStores += PPCMfpmc2() - info->_loadStores;
info->missCycles += PPCMfpmc3() - info->_missCycles;
info->cycles += PPCMfpmc4() - info->_cycles;
info->instructions += PPCMfpmc1() - info->_instructions;
info->paused = 1;
PPCMtmmcr1(0x78400000);
PPCMtmmcr0(0xc08b);
}
void sndProfStopPMC(SND_PROFILE_DATA* info) {
PPCMtmmcr0(0);
PPCMtmmcr1(0);
if (info->paused == 0) {
info->loadStores = info->loadStores + (PPCMfpmc2() - info->_loadStores);
info->missCycles = info->missCycles + (PPCMfpmc3() - info->_missCycles);
info->cycles = info->cycles + (PPCMfpmc4() - info->_cycles);
info->instructions = info->instructions + (PPCMfpmc1() - info->_instructions);
info->paused = 1;
}
info->cnt = info->cnt + 1;
info->sumLoadStores += info->loadStores;
info->sumMissCycles += info->missCycles;
info->sumCycles += info->cycles;
info->sumInstructions += info->instructions;
info->avgLoadStores = info->sumLoadStores / info->cnt;
info->avgMissCycles = info->sumMissCycles / info->cnt;
info->avgCycles = info->sumCycles / info->cnt;
info->avgInstructions = info->sumInstructions / info->cnt;
info->lastLoadStores = info->loadStores;
info->lastMissCycles = info->missCycles;
info->lastCycles = info->cycles;
info->lastInstructions = info->instructions;
if (info->loadStores > info->peekLoadStores) {
info->peekLoadStores = info->loadStores;
}
if (info->missCycles > info->peekMissCycles) {
info->peekMissCycles = info->missCycles;
}
if (info->cycles > info->peekCycles) {
info->peekCycles = info->cycles;
}
if (info->instructions > info->peekInstructions) {
info->peekInstructions = info->instructions;
}
info->loadStores = 0;
info->missCycles = 0;
info->cycles = 0;
info->instructions = 0;
PPCMtmmcr1(0x78400000);
PPCMtmmcr0(0xc08b);
}