MusyX: Initial PC Port rework

Former-commit-id: 6f498225ac05f1d4ad7721d8f4c36aedd23fc52d
This commit is contained in:
Phillip Stephens 2023-11-29 22:50:02 -08:00
parent 622219bb94
commit add17c11c7
41 changed files with 691 additions and 2836 deletions

View File

@ -4248,7 +4248,7 @@ musyx/runtime/s_data.c:
.bss start:0x8055EC60 end:0x8055F260
.sbss start:0x805A9AD8 end:0x805A9AE0
musyx/runtime/hw_dspctrl.c:
musyx/runtime/dolphin/hw_dspctrl.c:
.text start:0x803AACFC end:0x803AE110
.rodata start:0x803D8A68 end:0x803D8AC0
.data start:0x803F3FA8 end:0x803F3FC0
@ -4284,23 +4284,23 @@ musyx/runtime/snd_service.c:
.data start:0x803F4278 end:0x803F4A80
.sdata start:0x805A8BD0 end:0x805A8BD8
musyx/runtime/hardware.c:
musyx/runtime/dolphin/hardware.c:
.text start:0x803B2F4C end:0x803B3F70
.rodata start:0x803D8BD0 end:0x803D8CD0
.sdata start:0x805A8BD8 end:0x805A8BE8
.sbss start:0x805A9B40 end:0x805A9B50
.sdata2 start:0x805AF398 end:0x805AF3B0
musyx/runtime/dsp_import.c:
musyx/runtime/dolphin/dsp_import.c:
.data start:0x803F4A80 end:0x803F6460
.sdata start:0x805A8BE8 end:0x805A8BF0
musyx/runtime/hw_aramdma.c:
musyx/runtime/dolphin/hw_aramdma.c:
.text start:0x803B3F70 end:0x803B4C3C
.bss start:0x80566F90 end:0x805678A0
.sbss start:0x805A9B50 end:0x805A9B70
musyx/runtime/hw_dolphin.c:
musyx/runtime/dolphin/hw_dolphin.c:
.text start:0x803B4C3C end:0x803B5134
.bss start:0x805678A0 end:0x80569900
.sbss start:0x805A9B70 end:0x805A9B98

View File

@ -202,6 +202,7 @@ cflags_musyx = [
"-Cpp_exceptions off",
"-str reuse,pool,readonly",
"-fp_contract off",
"-DMUSY_TARGET=MUSY_TARGET_DOLPHIN"
]
cflags_musyx_debug = [
@ -216,6 +217,7 @@ cflags_musyx_debug = [
"-D_DEBUG=1",
"-enum int",
"-Cpp_exceptions off",
"-DMUSY_TARGET=MUSY_TARGET_DOLPHIN"
]
# REL flags
@ -1199,10 +1201,10 @@ config.libs = [
Object(Matching, "musyx/runtime/snd_math.c"),
Object(NonMatching, "musyx/runtime/snd_midictrl.c"),
Object(Matching, "musyx/runtime/snd_service.c"),
Object(Matching, "musyx/runtime/hardware.c"),
Object(Matching, "musyx/runtime/hw_aramdma.c"),
Object(Matching, "musyx/runtime/dsp_import.c"),
Object(Matching, "musyx/runtime/hw_dolphin.c"),
Object(Matching, "musyx/runtime/dolphin/hardware.c"),
Object(Matching, "musyx/runtime/dolphin/hw_aramdma.c"),
Object(Matching, "musyx/runtime/dolphin/dsp_import.c"),
Object(Matching, "musyx/runtime/dolphin/hw_dolphin.c"),
Object(Matching, "musyx/runtime/hw_memory.c"),
Object(Matching, "musyx/runtime/hw_lib_dummy.c"),
Object(Matching, "musyx/runtime/CheapReverb/creverb_fx.c"),
@ -1211,7 +1213,7 @@ config.libs = [
Object(Matching, "musyx/runtime/StdReverb/reverb.c"),
Object(Matching, "musyx/runtime/Delay/delay_fx.c"),
Object(Matching, "musyx/runtime/Chorus/chorus_fx.c"),
Object(Matching, "musyx/runtime/profile.c"),
Object(Matching, "musyx/runtime/dolphin/profile.c"),
],
),
{

View File

@ -1,22 +1,42 @@
#ifndef _MUSYX_ASSERT
#define _MUSYX_ASSERT
#ifndef _ASSERT
#define _ASSERT
#include "musyx/version.h"
#include "musyx/platform.h"
#if MUSY_TARGET == MUSY_TARGET_DOLPHIN
extern void OSPanic(const char* file, int line, const char* msg, ...);
extern void OSReport(const char* msg, ...);
#ifndef MUSY_PANIC
#define MUSY_PANIC OSPanic
#endif
#ifndef MUSY_REPORT
#define MUSY_REPORT OSReport
#endif
#elif MUSY_TARGET == MUSY_TARGET_PC
#include <assert.h>
#ifndef MUSY_PANIC
#define MUSY_PANIC assert
#endif
#ifndef MUSY_REPORT
#define MUSY_REPORT printf
#endif
#endif
// TODO: Cleanup
static inline unsigned __SOME_ASSERT_DERP1() { return 0; }
static inline unsigned __SOME_ASSERT_DERP2() { return __SOME_ASSERT_DERP1(); }
static inline void __SOME_ASSERT_DERP() { __SOME_ASSERT_DERP2() != 0; }
#ifndef ASSERT
#ifndef MUSY_ASSERT
#ifdef _DEBUG
#define MUSY_ASSERT(cond) \
do { \
if (!(cond)) { \
OSPanic(__FILE__, __LINE__, "Failed assertion " #cond); \
MUSY_PANIC(__FILE__, __LINE__, "Failed assertion " #cond); \
} \
__SOME_ASSERT_DERP(); \
} while (0)
@ -33,7 +53,7 @@ static inline void __SOME_ASSERT_DERP() { __SOME_ASSERT_DERP2() != 0; }
s32 tmp = 1; \
s32 tmp2; \
if (!(cond)) { \
OSPanic(__FILE__, __LINE__, msg); \
MUSY_PANIC(__FILE__, __LINE__, msg); \
tmp2 = 0; \
if (tmp2 == 0) { \
tmp = 0; \
@ -44,7 +64,7 @@ static inline void __SOME_ASSERT_DERP() { __SOME_ASSERT_DERP2() != 0; }
#define MUSY_ASSERT_MSG(cond, msg) \
do { \
if (!(cond)) { \
OSPanic(__FILE__, __LINE__, msg); \
MUSY_PANIC(__FILE__, __LINE__, msg); \
} \
} while (0)
#endif
@ -55,7 +75,7 @@ static inline void __SOME_ASSERT_DERP() { __SOME_ASSERT_DERP2() != 0; }
#ifndef MUSY_DEBUG
#ifdef _DEBUG
#define MUSY_DEBUG OSReport
#define MUSY_DEBUG MUSY_REPORT
#else
#define MUSY_DEBUG
#endif
@ -63,10 +83,10 @@ static inline void __SOME_ASSERT_DERP() { __SOME_ASSERT_DERP2() != 0; }
#ifndef MUSY_FATAL
#ifdef _DEBUG
#define MUSY_FATAL(msg) OSPanic(__FILE__, __LINE__, msg)
#define MUSY_FATAL(msg) MUSY_PANIC(__FILE__, __LINE__, msg)
#else
#define MUSY_FATAL
#endif
#endif
#endif // _MUSYX_ASSERT
#endif // _ASSERT

View File

@ -1,14 +1,14 @@
#ifndef _MUSYX_DSP_IMPORT
#define _MUSYX_DSP_IMPORT
#include "types.h"
#include "musyx/musyx.h"
#ifdef __cplusplus
extern "C" {
#endif
extern char dspSlave[];
extern ushort dspSlaveLength;
extern u16 dspSlaveLength;
#ifdef __cplusplus
}

View File

@ -1,15 +1,30 @@
#ifndef _MUSYX_HARDWARE
#define _MUSYX_HARDWARE
#include "musyx/musyx_priv.h"
#include "musyx/musyx.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef void* (*ARAMUploadCallback)(u32, u32);
typedef u32 (*SND_MESSAGE_CALLBACK)(u32, u32);
extern SND_MESSAGE_CALLBACK salMessageCallback;
extern SND_HOOKS salHooks;
extern u32 dspHRTFOn;
extern u16* dspCmdList;
extern u16 dspCmdFirstSize;
extern u8 dspScale2IndexTab[1024];
u32 hwFrq2Pitch(u32 frq);
void hwOff(s32 vid);
bool hwIsStudioActive(u8 studio);
void* hwGetStreamPlayBuffer(u8 hwStreamHandle);
s32 hwInit(u32* frq, u16 numVoices, u16 numStudios, u32 flags); /* extern */
void hwExit();
void hwInitSamplePlayback(u32 v, u16 smpID, void* newsmp, u32 set_defadsr, u32 prio,
u32 callbackUserValue, u32 setSRC, u8 itdMode);
void hwSetVolume(u32 v, u8 table, float vol, u32 pan, u32 span, float auxa, float auxb);
@ -31,15 +46,50 @@ u16 hwGetSampleID(u32 voice);
u8 hwGetSampleType(u32 voice);
void hwChangeStudioMix(u8 studio, u32 isMaster);
void hwSetStreamLoopPS(u32 voice, u8 ps);
void hwFlushStream(void* base, u32 offset, u32 bytes, unsigned char hwStreamHandle, void (*callback)(u32),
u32 user);
void hwFlushStream(void* base, u32 offset, u32 bytes, unsigned char hwStreamHandle,
void (*callback)(u32), u32 user);
void hwSetSaveSampleCallback(ARAMUploadCallback callback, unsigned long chunckSize);
void hwSyncSampleMem();
void hwSetAUXProcessingCallbacks(u8 studio, SND_AUX_CALLBACK auxA, void* userA,
SND_AUX_CALLBACK auxB, void* userB);
void hwSetMesgCallback(SND_MESSAGE_CALLBACK callback);
#if MUSY_VERSION >= MUSY_VERSION_CHECK(2, 0, 3)
void hwSetFilter(u32 v, unsigned char mode, unsigned short coefA, unsigned short coefB);
void hwLowPassFrqToCoef(u32 frq, unsigned short* _a0, unsigned short* _b1);
#endif
void hwSetSRCType(u32 v, u8 salSRCType);
void hwSetITDMode(u32 v, u8 mode);
void hwSetPolyPhaseFilter(u32 v, u8 salCoefSel);
bool hwAddInput(u8 studio, SND_STUDIO_INPUT* in_desc);
bool hwRemoveInput(u8 studio, SND_STUDIO_INPUT* in_desc);
void hwChangeStudio(u32 v, u8 studio);
void hwDisableHRTF();
void hwStart(u32 v, u8 studio);
void hwKeyOff(u32 v);
void hwFrameDone();
void hwActivateStudio(u8 studio, u32 isMaster, SND_STUDIO_TYPE type);
void hwDeactivateStudio(u8);
void hwSetPriority(u32 v, u32 prio);
u32 hwIsActive(u32);
u32 hwGlobalActivity();
void hwSetAUXProcessingCallbacks(u8 studio, SND_AUX_CALLBACK auxA, void* userA,
SND_AUX_CALLBACK auxB, void* userB);
u8 hwInitStream(u32 len);
u8 hwGetTimeOffset();
u32 hwGetVirtualSampleID(u32 v);
void hwIRQEnterCritical();
void hwIRQLeaveCritical();
extern u32 aramSize;
extern u8* aramBase;
unsigned long aramGetStreamBufferAddress(unsigned char id, unsigned long* len);
u32 aramGetStreamBufferAddress(u8 id, u32* len);
void aramUploadData(void* mram, u32 aram, u32 len, u32 highPrio, void (*callback)(u32), u32 user);
void aramFreeStreamBuffer(u8 id);
void* aramStoreData(void* src, u32 len);
void aramRemoveData(void* aram, u32 len);
u8 aramAllocateStreamBuffer(u32 len);
#ifdef __cplusplus
}
#endif

View File

@ -2,6 +2,7 @@
#define _MUSYX_MUSYX
#include "musyx/version.h"
#include "musyx/platform.h"
#include <math.h>

File diff suppressed because it is too large Load Diff

View File

@ -1,11 +1,20 @@
#ifndef _MUSYX_SEQ
#define _MUSYX_SEQ
#include "musyx/musyx_priv.h"
#include "musyx/musyx.h"
#include "musyx/voice.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct PAGE {
// total size: 0x6
u16 macro; // offset 0x0, size 0x2
u8 prio; // offset 0x2, size 0x1
u8 maxVoices; // offset 0x3, size 0x1
u8 index; // offset 0x4, size 0x1
u8 reserved; // offset 0x5, size 0x1
} PAGE;
typedef struct ARR {
// total size: 0x58
@ -173,10 +182,35 @@ typedef struct SEQ_PATTERN {
u32 noteData; // offset 0xC, size 0x4
} SEQ_PATTERN;
typedef struct CHANNEL_DEFAULTS {
// total size: 0x1
u8 pbRange; // offset 0x0, size 0x1
} CHANNEL_DEFAULTS;
typedef struct MIDI_CHANNEL_SETUP {
// total size: 0x5
u8 program; // offset 0x0, size 0x1
u8 volume; // offset 0x1, size 0x1
u8 panning; // offset 0x2, size 0x1
u8 reverb; // offset 0x3, size 0x1
u8 chorus; // offset 0x4, size 0x1
} MIDI_CHANNEL_SETUP;
typedef struct MIDISETUP {
// total size: 0x54
u16 songId; // offset 0x0, size 0x2
u16 reserved; // offset 0x2, size 0x2
MIDI_CHANNEL_SETUP channel[16]; // offset 0x4, size 0x50
} MIDISETUP;
extern u8 synthTrackVolume[64];
extern SEQ_INSTANCE seqInstance[8];
extern u16 seqMIDIPriority[8][16];
void seqInit(); /* extern */
u32 seqStartPlay(PAGE* norm, PAGE* drum, MIDISETUP* midiSetup, u32* song, SND_PLAYPARA* para,
u8 studio, u16 sgid);
u32 seqGetPrivateId(u32 seqId);
void seqSpeed(u32 seqId, u16 speed);
void seqVolume(u8 volume, u16 time, u32 seqId, u8 mode);
void sndSeqStop(s32 unk);
@ -189,7 +223,52 @@ void seqStop(u32 seqId);
u16 seqGetMIDIPriority(u8 set, u8 channel);
void seqCrossFade(SND_CROSSFADE* ci, u32* new_seqId, bool8 irq_call);
u32 seqPlaySong(u16 sgid, u16 sid, void* arrfile, SND_PLAYPARA* para, u8 irq_call, u8 studio);
void seqPause(SND_SEQID seqId);
void seqContinue(SND_SEQID seqId);
void seqMute(SND_SEQID seqId, u32 mask1, u32 mask2);
void seqKillInstancesByGroupID(SND_GROUPID sgid);
void seqKillAllInstances();
u8 inpTranslateExCtrl(u8 ctrl);
void inpSetGlobalMIDIDirtyFlag(u8 chan, u8 midiSet, s32 flag);
void inpAddCtrl(CTRL_DEST* dest, u8 ctrl, s32 scale, u8 comb, u32 isVar);
void inpSetMidiCtrl(u8 ctrl, u8 channel, u8 set, u8 value);
void inpSetMidiCtrl14(u8 ctrl, u8 channel, u8 set, u16 value);
void inpSetExCtrl(SYNTH_VOICE* svoice, u8 ctrl, s16 v);
CHANNEL_DEFAULTS* inpGetChannelDefaults(u8 midi, u8 midiSet);
#if MUSY_VERSION >= MUSY_VERSION_CHECK(2, 0, 3)
unsigned short inpGetFilterSwitch(struct SYNTH_VOICE* svoice);
unsigned short inpGetFilterParameter(struct SYNTH_VOICE* svoice);
void inpSetLPFDefaultRange(u32 lowFrq, u32 highFrq);
#endif
extern CTRL_DEST inpAuxA[8][4];
extern CTRL_DEST inpAuxB[8][4];
void inpSetMidiLastNote(u8 midi, u8 midiSet, u8 key);
u8 inpGetMidiLastNote(u8 midi, u8 midiSet);
u16 inpGetExCtrl(SYNTH_VOICE* svoice, u8 ctrl);
u16 inpGetMidiCtrl(u8 ctrl, u8 channel, u8 set);
void inpSetMidiLastNote(u8 midi, u8 midiSet, u8 key);
u16 inpGetModulation(SYNTH_VOICE* svoice);
void inpResetMidiCtrl(u8 ch, u8 set, u32 coldReset);
void inpResetChannelDefaults(u8 midi, u8 midiSet);
u16 inpGetPitchBend(SYNTH_VOICE* svoice);
u16 inpGetDoppler(SYNTH_VOICE* svoice);
u16 inpGetTremolo(SYNTH_VOICE* svoice);
u16 inpGetPanning(SYNTH_VOICE* svoice);
u16 inpGetSurPanning(SYNTH_VOICE* svoice);
u16 inpGetVolume(SYNTH_VOICE* svoice);
u16 inpGetReverb(SYNTH_VOICE* svoice);
u16 inpGetPreAuxA(SYNTH_VOICE* svoice);
u16 inpGetPostAuxA(SYNTH_VOICE* svoice);
u16 inpGetPreAuxB(SYNTH_VOICE* svoice);
u16 inpGetPostAuxB(SYNTH_VOICE* svoice);
u16 inpGetPedal(SYNTH_VOICE* svoice);
u16 inpGetAuxA(u8 studio, u8 index, u8 midi, u8 midiSet);
u16 inpGetAuxB(u8 studio, u8 index, u8 midi, u8 midiSet);
void inpInit(SYNTH_VOICE* svoice);
void inpFXCopyCtrl(u8 ctrl, SYNTH_VOICE* dvoice, SYNTH_VOICE* svoice);
s16 varGet(SYNTH_VOICE* svoice, u32 ctrl, u8 index);
#ifdef __cplusplus
}
#endif

View File

@ -1,11 +1,278 @@
#ifndef _MUSYX_SYNTH
#define _MUSYX_SYNTH
#include "musyx/musyx.h"
#include "musyx/adsr.h"
#include "musyx/musyx_priv.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
MAC_STATE_RUNNABLE = 0,
MAC_STATE_YIELDED,
MAC_STATE_STOPPED,
} MAC_STATE;
typedef struct MSTEP {
u32 para[2];
} MSTEP;
typedef struct CALLSTACK {
MSTEP* addr;
MSTEP* curAddr;
} CALLSTACK;
typedef struct SYNTH_VOICELIST {
// total size: 0x4
u8 prev; // offset 0x0, size 0x1
u8 next; // offset 0x1, size 0x1
u16 user; // offset 0x2, size 0x2
} SYNTH_VOICELIST;
extern SYNTH_VOICELIST voicePrioSortVoices[64];
extern u8 voicePrioSortVoicesRoot[256];
extern SYNTH_VOICELIST voicePrioSortVoices[64];
typedef struct SYNTH_ROOTLIST {
// total size: 0x4
u16 next; // offset 0x0, size 0x2
u16 prev; // offset 0x2, size 0x2
} SYNTH_ROOTLIST;
extern SYNTH_ROOTLIST voicePrioSortRootList[256];
typedef struct synthInfo {
u32 mixFrq;
u32 numSamples;
SND_PLAYBACKINFO pbInfo;
u8 voiceNum;
u8 maxMusic;
u8 maxSFX;
u8 studioNum;
} SynthInfo;
extern SynthInfo synthInfo;
typedef struct VID_LIST {
struct VID_LIST* next;
struct VID_LIST* prev;
u32 vid;
u32 root;
} VID_LIST;
typedef struct SYNTH_QUEUE {
// total size: 0xC
struct SYNTH_QUEUE* next; // offset 0x0, size 0x4
struct SYNTH_QUEUE* prev; // offset 0x4, size 0x4
u8 voice; // offset 0x8, size 0x1
u8 jobTabIndex; // offset 0x9, size 0x1
} SYNTH_QUEUE;
typedef enum {
SYNTH_JOBTYPE_LOW = 0,
SYNTH_JOBTYPE_ZERO = 1,
SYNTH_JOBTYPE_EVENT = 2,
} SYNTH_JOBTYPE;
typedef struct {
// total size: 0xC
SYNTH_QUEUE* lowPrecision; // offset 0x0, size 0x4
SYNTH_QUEUE* event; // offset 0x4, size 0x4
SYNTH_QUEUE* zeroOffset; // offset 0x8, size 0x4
} SYNTH_JOBTAB;
typedef struct SYNTH_LFO {
u32 time;
u32 period;
s16 value;
s16 lastValue;
} SYNTH_LFO;
typedef struct SYNTHMasterFader {
// total size: 0x30
f32 volume; // offset 0x0, size 0x4
f32 target; // offset 0x4, size 0x4
f32 start; // offset 0x8, size 0x4
f32 time; // offset 0xC, size 0x4
f32 deltaTime; // offset 0x10, size 0x4
f32 pauseVol; // offset 0x14, size 0x4
f32 pauseTarget; // offset 0x18, size 0x4
f32 pauseStart; // offset 0x1C, size 0x4
f32 pauseTime; // offset 0x20, size 0x4
f32 pauseDeltaTime; // offset 0x24, size 0x4
u32 seqId; // offset 0x28, size 0x4
u8 seqMode; // offset 0x2C, size 0x1
u8 type; // offset 0x2D, size 0x1
} SYNTHMasterFader;
typedef struct CTRL_SOURCE {
u8 midiCtrl;
u8 combine;
s32 scale;
} CTRL_SOURCE;
typedef struct CTRL_DEST {
CTRL_SOURCE source[4];
u16 oldValue;
u8 numSource;
} CTRL_DEST;
#pragma push
#pragma pack(4)
typedef struct SYNTH_VOICE {
// total size: 0x404
SYNTH_QUEUE lowPrecisionJob; // offset 0x0, size 0xC
SYNTH_QUEUE zeroOffsetJob; // offset 0xC, size 0xC
SYNTH_QUEUE eventJob; // offset 0x18, size 0xC
u64 lastLowCallTime; // offset 0x24, size 0x8
u64 lastZeroCallTime; // offset 0x2C, size 0x8
MSTEP* addr; // offset 0x34, size 0x4
MSTEP* curAddr; // offset 0x38, size 0x4
struct SYNTH_VOICE* nextMacActive; // offset 0x3C, size 0x4
struct SYNTH_VOICE* prevMacActive; // offset 0x40, size 0x4
struct SYNTH_VOICE* nextTimeQueueMacro; // offset 0x44, size 0x4
struct SYNTH_VOICE* prevTimeQueueMacro; // offset 0x48, size 0x4
MAC_STATE macState; // offset 0x4C, size 0x4
MSTEP* trapEventAddr[3]; // offset 0x50, size 0xC
MSTEP* trapEventCurAddr[3]; // offset 0x5C, size 0xC
u8 trapEventAny; // offset 0x68, size 0x1
CALLSTACK callStack[4]; // offset 0x6C, size 0x20
u8 callStackEntryNum; // offset 0x8C, size 0x1
u8 callStackIndex; // offset 0x8D, size 0x1
u64 macStartTime; // offset 0x90, size 0x8
u64 wait; // offset 0x98, size 0x8
u64 waitTime; // offset 0xA0, size 0x8
u8 timeUsedByInput; // offset 0xA8, size 0x1
u16 loop; // offset 0xAA, size 0x2
s32 local_vars[16]; // offset 0xAC, size 0x40
u32 child; // offset 0xEC, size 0x4
u32 parent; // offset 0xF0, size 0x4
u32 id; // offset 0xF4, size 0x4
VID_LIST* vidList; // offset 0xF8, size 0x4
VID_LIST* vidMasterList; // offset 0xFC, size 0x4
#if MUSY_VERSION >= MUSY_VERSION_CHECK(1, 5, 0) && MUSY_VERSION <= MUSY_VERSION_CHECK(2, 0, 0)
u16 allocId; // offset 0x100, size 0x2
#else
u32 allocId;
#endif
u16 macroId; // offset 0x102, size 0x2
u8 keyGroup; // offset 0x104, size 0x1
u32 lastVID; // offset 0x108, size 0x4
u8 prio; // offset 0x10C, size 0x1
u16 ageSpeed; // offset 0x10E, size 0x2
u32 age; // offset 0x110, size 0x4
u64 cFlags; // offset 0x114, size 0x8
u8 block; // offset 0x11C, size 0x1
u8 fxFlag; // offset 0x11D, size 0x1
u8 vGroup; // offset 0x11E, size 0x1
u8 studio; // offset 0x11F, size 0x1
u8 track; // offset 0x120, size 0x1
u8 midi; // offset 0x121, size 0x1
u8 midiSet; // offset 0x122, size 0x1
u8 section; // offset 0x123, size 0x1
#if MUSY_VERSION <= MUSY_VERSION_CHECK(1, 5, 0)
void* sAddr;
#endif
u32 sInfo; // offset 0x124, size 0x4
u32 playFrq; // offset 0x128, size 0x4
#if MUSY_VERSION >= MUSY_VERSION_CHECK(2, 0, 3)
u16 sampleId;
#endif
u16 curNote; // offset 0x12C, size 0x2
s8 curDetune; // offset 0x12E, size 0x1
u8 orgNote; // offset 0x12F, size 0x1
u8 lastNote; // offset 0x130, size 0x1
u8 portType; // offset 0x131, size 0x1
u16 portLastCtrlState; // offset 0x132, size 0x2
u32 portDuration; // offset 0x134, size 0x4
u32 portCurPitch; // offset 0x138, size 0x4
u32 portTime; // offset 0x13C, size 0x4
u8 vibKeyRange; // offset 0x140, size 0x1
u8 vibCentRange; // offset 0x141, size 0x1
u32 vibPeriod; // offset 0x144, size 0x4
u32 vibCurTime; // offset 0x148, size 0x4
s32 vibCurOffset; // offset 0x14C, size 0x4
s16 vibModAddScale; // offset 0x150, size 0x2
u32 volume; // offset 0x154, size 0x4
u32 orgVolume; // offset 0x158, size 0x4
float lastVolFaderScale; // offset 0x15C, size 0x4
u32 lastPan; // offset 0x160, size 0x4
u32 lastSPan; // offset 0x164, size 0x4
float treCurScale; // offset 0x168, size 0x4
u16 treScale; // offset 0x16C, size 0x2
u16 treModAddScale; // offset 0x16E, size 0x2
u32 panning[2]; // offset 0x170, size 0x8
s32 panDelta[2]; // offset 0x178, size 0x8
u32 panTarget[2]; // offset 0x180, size 0x8
u32 panTime[2]; // offset 0x188, size 0x8
u8 revVolScale; // offset 0x190, size 0x1
u8 revVolOffset; // offset 0x191, size 0x1
u8 volTable; // offset 0x192, size 0x1
u8 itdMode; // offset 0x193, size 0x1
s32 envDelta; // offset 0x194, size 0x4
u32 envTarget; // offset 0x198, size 0x4
u32 envCurrent; // offset 0x19C, size 0x4
u32 sweepOff[2]; // offset 0x1A0, size 0x8
s32 sweepAdd[2]; // offset 0x1A8, size 0x8
s32 sweepCnt[2]; // offset 0x1B0, size 0x8
u8 sweepNum[2]; // offset 0x1B8, size 0x2
SYNTH_LFO lfo[2]; // offset 0x1BC, size 0x18
u8 lfoUsedByInput[2]; // offset 0x1D4, size 0x2
u8 pbLowerKeyRange; // offset 0x1D6, size 0x1
u8 pbUpperKeyRange; // offset 0x1D7, size 0x1
u16 pbLast; // offset 0x1D8, size 0x2
#if MUSY_VERSION >= MUSY_VERSION_CHECK(2, 0, 3)
u32 lpfLowerFrqBoundary;
u32 lpfUpperFrqBoundary;
#endif
ADSR_VARS pitchADSR; // offset 0x1DC, size 0x28
s16 pitchADSRRange; // offset 0x204, size 0x2
u16 curPitch; // offset 0x206, size 0x2
struct setup {
// total size: 0x9
u8 vol; // offset 0x0, size 0x1
u8 pan; // offset 0x1, size 0x1
u8 midi; // offset 0x2, size 0x1
u8 midiSet; // offset 0x3, size 0x1
u8 section; // offset 0x4, size 0x1
u8 track; // offset 0x5, size 0x1
u8 vGroup; // offset 0x6, size 0x1
u8 studio; // offset 0x7, size 0x1
u8 itdMode; // offset 0x8, size 0x1
} setup; // offset 0x208, size 0x9
u32 midiDirtyFlags; // offset 0x214, size 0x4
CTRL_DEST inpVolume; // offset 0x218, size 0x24
CTRL_DEST inpPanning; // offset 0x23C, size 0x24
CTRL_DEST inpSurroundPanning; // offset 0x260, size 0x24
CTRL_DEST inpPitchBend; // offset 0x284, size 0x24
CTRL_DEST inpDoppler; // offset 0x2A8, size 0x24
CTRL_DEST inpModulation; // offset 0x2CC, size 0x24
CTRL_DEST inpPedal; // offset 0x2F0, size 0x24
CTRL_DEST inpPortamento; // offset 0x314, size 0x24
CTRL_DEST inpPreAuxA; // offset 0x338, size 0x24
CTRL_DEST inpReverb; // offset 0x35C, size 0x24
CTRL_DEST inpPreAuxB; // offset 0x380, size 0x24
CTRL_DEST inpPostAuxB; // offset 0x3A4, size 0x24
CTRL_DEST inpTremolo; // offset 0x3C8, size 0x24
#if MUSY_VERSION >= MUSY_VERSION_CHECK(2, 0, 3)
CTRL_DEST inpFilterSwitch; // offset 0x3F8, size 0x24
CTRL_DEST inpFilterParameter; // offset 0x41C, size 0x24
#endif
u8 mesgNum; // offset 0x3EC, size 0x1
u8 mesgRead; // offset 0x3ED, size 0x1
u8 mesgWrite; // offset 0x3EE, size 0x1
s32 mesgQueue[4]; // offset 0x3F0, size 0x10
u16 curOutputVolume; // offset 0x400, size 0x2
} SYNTH_VOICE;
typedef struct synthITDInfo {
// total size: 0x2
u8 music; // offset 0x0, size 0x1
u8 sfx; // offset 0x1, size 0x1
} synthITDInfo;
#pragma pop
typedef void (*SYNTH_MESSAGE_CALLBACK)(u32, s32);
extern SND_AUX_CALLBACK synthAuxACallback[8];
extern u8 synthAuxAMIDI[8];
extern u8 synthAuxAMIDISet[8];
@ -17,8 +284,25 @@ extern void* synthAuxBUser[8];
extern synthITDInfo synthITDDefault[8];
extern u32 synthFlags;
extern SYNTH_VOICE* synthVoice;
extern u8 sndActive;
extern u8 synthIdleWaitActive;
extern SynthInfo synthInfo;
extern s32 synthGlobalVariable[16];
extern u64 synthRealTime;
extern SYNTH_MESSAGE_CALLBACK synthMessageCallback;
u32 vidGetInternalId(SND_VOICEID id);
u32 synthGetTicksPerSecond(SYNTH_VOICE* svoice);
void synthKillVoicesByMacroReferences(u16* ref);
void synthExit();
void synthInit(u32 mixFrq, u32 numVoices);
void synthSetBpm(u32 pbm, u8 set, u8 section);
void synthFXCloneMidiSetup(SYNTH_VOICE* dest, SYNTH_VOICE* src);
void synthSetMusicVolumeType(u8 vGroup, u8 type);
void synthInitAllocationAids();
void synthInitPortamento(SYNTH_VOICE* svoice);
void synthStartSynthJobHandling(SYNTH_VOICE* svoice);
void synthForceLowPrecisionUpdate(SYNTH_VOICE* svoice);
void synthKeyStateUpdate(SYNTH_VOICE* svoice);
bool synthFXSetCtrl(SND_VOICEID vid, u8 ctrl, u8 value);
bool synthFXSetCtrl14(SND_VOICEID vid, u8 ctrl, u16 value);
@ -32,27 +316,16 @@ u32 synthStartSound(u16 id, u8 prio, u8 max,
u8 key, u8 vol, u8 panning, u8 midi, u8 midiSet, u8 section, u16 step,
u16 trackid, u8 vGroup, s16 prioOffset, u8 studio, u32 itd);
bool synthIsFadeOutActive(u8 vGroup);
/* TODO: Move this where it belongs */
void hwSetAUXProcessingCallbacks(u8 studio, SND_AUX_CALLBACK auxA, void* userA,
SND_AUX_CALLBACK auxB, void* userB);
u32 voiceBlock(u8 prio);
MSTEP* dataGetMacro(u16 mid);
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 synthActivateStudio(u8 studio, u32 isMaster, SND_STUDIO_TYPE type);
void synthDeactivateStudio(u8 studio);
u8 synthFXGetMaxVoices(u16 fid);
void synthPauseVolume(u8 volume, u16 time, u8 vGroup);
bool dataRemoveFX(u16 gid);
void voiceUnblock(u32 voice);
void voiceRemovePriority(SYNTH_VOICE* svoice);
void synthKillAllVoices(bool8 musiconly);
void synthKeyStateUpdate(SYNTH_VOICE* svoice);
u32 synthAddStudioInput(u8 studio, SND_STUDIO_INPUT* in_desc);
u32 synthRemoveStudioInput(u8 studio, SND_STUDIO_INPUT* in_desc);
u32 synthGetTicksPerSecond(SYNTH_VOICE* svoice);
#ifdef __cplusplus
}
#endif

View File

@ -1,7 +1,7 @@
#ifndef _MUSYX_SYNTH_DBTAB
#define _MUSYX_SYNTH_DBTAB
#include "types.h"
#include "musyx/musyx.h"
#ifdef __cplusplus
extern "C" {

View File

@ -1,6 +1,12 @@
#ifndef _MUSYX_VERSION
#define _MUSYX_VERSION
#define MUSY_TARGET_PC 0
#define MUSY_TARGET_DOLPHIN 1
#ifndef MUSY_TARGET
#define MUSY_TARGET MUSY_TARGET_PC
#endif
#ifndef MUSY_VERSION_CHECK
#define MUSY_VERSION_CHECK(major, minor, patch) ((major << 16) | (minor << 8) | (patch))

View File

@ -9,9 +9,11 @@
---------------------------------------
*/
#include "musyx/musyx_priv.h"
#include "musyx/musyx.h"
#include "musyx/sal.h"
#include <float.h>
#include <math.h>
#include <string.h>
static void DLsetdelay(_SND_REVSTD_DELAYLINE* dl, s32 lag) {
dl->outPoint = dl->inPoint - (lag * sizeof(f32));
@ -121,6 +123,7 @@ bool ReverbSTDModify(_SND_REVSTD_WORK* rv, float coloration, float time, float m
return ReverbSTDCreate(rv, coloration, time, mix, damping, predelay);
}
#ifdef __MWERKS__
static const float value0_3 = 0.3f;
static const float value0_6 = 0.6f;
static const double i2fMagic = 4.503601774854144E15;
@ -411,6 +414,11 @@ lbl_803B599C:
blr
#endif
}
#else
static void HandleReverb(long* sptr, struct _SND_REVSTD_WORK* rv) {
// TODO: Reimplement this in C
}
#endif
void ReverbSTDCallback(s32* left, s32* right, s32* surround, _SND_REVSTD_WORK* rv) {
HandleReverb(left, rv);

View File

@ -10,11 +10,14 @@
---------------------------------------
*/
#include "musyx/musyx_priv.h"
#include "musyx/musyx.h"
#include "musyx/assert.h"
// TODO: Cleanup and move externs to header
extern bool ReverbSTDCreate(_SND_REVSTD_WORK* rv, f32 coloration, f32 time, f32 mix, f32 damping,
f32 preDelay);
extern void ReverbHIFree(_SND_REVSTD_WORK* rev);
extern void ReverbSTDFree(_SND_REVSTD_WORK* rev);
extern void ReverbSTDCallback(s32* left, s32* right, s32* surround, _SND_REVSTD_WORK* rv);
extern unsigned long ReverbSTDModify(_SND_REVSTD_WORK* rv, float coloration, float time, float mix,
float damping, float predelay);

View File

@ -1,4 +1,6 @@
#include "musyx/musyx_priv.h"
#include "musyx/musyx.h"
#include "musyx/sal.h"
#include "musyx/assert.h"
static float rsmpTab12khz[512] = {
@ -109,6 +111,8 @@ static float rsmpTab12khz[512] = {
const double i2fMagic = 4.503601774854144E15;
#ifdef __MWERKS__
// clang-format off
static asm void do_src1(_SND_CHORUS_SRCINFO* src) {
nofralloc
@ -285,9 +289,15 @@ lbl_803B6E10:
addi r1, r1, 0x40
blr
}
/* clang-format on */
#else
static void do_src1(_SND_CHORUS_SRCINFO* src) {
// TODO: Reimplement in C
}
#endif
#ifdef __MWERKS__
/* clang-format off */
static asm void do_src2(register _SND_CHORUS_SRCINFO* src) {
#define posLoV r4
#define posHiV r5
@ -519,6 +529,11 @@ lbl_803B6FF4:
#undef destPtr
#undef smpBasePtr
}
#else
static void do_src2(register _SND_CHORUS_SRCINFO* src) {
// TODO: Reimplement in C
}
#endif
void sndAuxCallbackChorus(u8 reason, SND_AUX_INFO* info, void* user) {
SND_AUX_CHORUS* c;

View File

@ -9,20 +9,23 @@
---------------------------------------
*/
#include "musyx/musyx_priv.h"
#include "musyx/musyx.h"
#include "musyx/assert.h"
#include "musyx/sal.h"
void sndAuxCallbackDelay(u8 reason, SND_AUX_INFO* info, void* user) {
long l; // r30
long r; // r29
long s; // r28
long* lBuf; // r27
long* rBuf; // r26
long* sBuf; // r25
unsigned long i; // r24
struct SND_AUX_DELAY* c; // r31
long* left; // r23
long* right; // r22
long* sur; // r21
long l; // r30
long r; // r29
long s; // r28
long* lBuf; // r27
long* rBuf; // r26
long* sBuf; // r25
unsigned long i; // r24
SND_AUX_DELAY* c; // r31
long* left; // r23
long* right; // r22
long* sur; // r21
switch (reason) {
case SND_AUX_REASON_BUFFERUPDATE:

View File

@ -1,6 +1,9 @@
#include "math.h"
#include "musyx/musyx_priv.h"
#include <math.h>
#include <string.h>
#include "musyx/musyx.h"
#include "musyx/sal.h"
static void DLsetdelay(_SND_REVHI_DELAYLINE* delayline, s32 len) {
delayline->outPoint = delayline->inPoint - (len * sizeof(f32));
@ -113,6 +116,7 @@ bool ReverbHIModify(struct _SND_REVHI_WORK* rv, float coloration, float time, fl
return ReverbHICreate(rv, coloration, time, mix, damping, preDelay, crosstalk);
}
#ifdef __MWERKS__
static const float value0_3 = 0.3f;
static const float value0_6 = 0.6f;
static const double i2fMagic = 4.503601774854144E15;
@ -223,7 +227,15 @@ L_00000710:
addi r1, r1, 0x30
blr
}
#else
/* clang-format on */
static void DoCrossTalk(s32* a, s32* b, f32 start, f32 end) {
// TODO: Reimplement in C
}
#endif
#ifdef __MWERKS__
/* clang-format off */
static asm void HandleReverb(s32*, SND_AUX_REVERBHI* rev, s32) {
nofralloc
stwu r1, -0xc0(r1)
@ -580,6 +592,11 @@ L_00000C6C:
blr
}
/* clang-format on */
#else
static void HandleReverb(s32*, SND_AUX_REVERBHI* rev, s32) {
// TODO: Reimplement in C
}
#endif
void ReverbHICallback(s32* left, s32* right, s32* surround, SND_AUX_REVERBHI* rev) {
u8 i;

View File

@ -10,7 +10,9 @@
---------------------------------------
*/
#include "musyx/musyx_priv.h"
#include "musyx/musyx.h"
#include "musyx/assert.h"
extern bool ReverbHICreate(_SND_REVHI_WORK* rev, f32 coloration, f32 time, f32 mix, f32 damping,
f32 preDelay, f32 crosstalk);

View File

@ -1,428 +0,0 @@
#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,
};
ushort dspSlaveLength = sizeof(dspSlave);
#ifdef __cplusplus
}
#endif

View File

@ -1,501 +0,0 @@
#include "musyx/musyx_priv.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

@ -1,338 +0,0 @@
#include "musyx/musyx_priv.h"
#include <dolphin/ar.h>
#include <dolphin/arq.h>
#include <dolphin/os.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

@ -1,172 +0,0 @@
#include "musyx/musyx_priv.h"
#include "dolphin/dsp.h"
#include "musyx/dsp_import.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

@ -1,4 +1,4 @@
#include "musyx/musyx_priv.h"
#include "musyx/hardware.h"
void* salMalloc(u32 len) { return salHooks.malloc(len); }

View File

@ -1,4 +1,4 @@
#include "musyx/musyx_priv.h"
#include "musyx/sal.h"
#include "musyx/synth_dbtab.h"
#include <math.h>

View File

@ -1,94 +0,0 @@
#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);
}

View File

@ -1,6 +1,10 @@
#include "musyx/musyx_priv.h"
#include "musyx/assert.h"
#include "musyx/hardware.h"
#include "musyx/seq.h"
#include "musyx/synth.h"
#include "musyx/synthdata.h"
#include "musyx/s3d.h"
static GSTACK gs[128];
static s16 sp;
@ -182,7 +186,6 @@ void sndSetSampleDataUploadCallback(void* (*callback)(unsigned long, unsigned lo
u32 sndPushGroup(void* prj_data, u16 gid, void* samples, void* sdir, void* pool) {
GROUP_DATA* g; // r31
#line 0x18d
MUSY_ASSERT_MSG(prj_data != NULL, "Project data pointer is NULL");
MUSY_ASSERT_MSG(sdir != NULL, "Sample directory pointer is NULL");

View File

@ -1,6 +1,11 @@
#include "musyx/seq.h"
#include "musyx/assert.h"
#include "musyx/sal.h"
#include "musyx/synth.h"
#include <stdint.h>
static NOTE seqNote[256];
SEQ_INSTANCE seqInstance[8];
u16 seqMIDIPriority[8][16];
@ -10,9 +15,9 @@ static bool8 curFadeOutState = 0;
static u32 curSeqId = 0;
static NOTE* noteFree = NULL;
static SEQ_INSTANCE* cseq = NULL;
struct SEQ_INSTANCE* seqFreeRoot = NULL;
struct SEQ_INSTANCE* seqPausedRoot = NULL;
struct SEQ_INSTANCE* seqActiveRoot = NULL;
SEQ_INSTANCE* seqFreeRoot = NULL;
SEQ_INSTANCE* seqPausedRoot = NULL;
SEQ_INSTANCE* seqActiveRoot = NULL;
static void ClearNotes() {
NOTE* ln = NULL; // r30

View File

@ -18,6 +18,7 @@
#include "musyx/hardware.h"
#include "musyx/seq.h"
#include "musyx/assert.h"
/*

View File

@ -1,5 +1,7 @@
#include "musyx/musyx.h"
#include "musyx/musyx_priv.h"
#include "musyx/hardware.h"
#include "musyx/sal.h"
#include "musyx/synth.h"
static u8 s3dCallCnt;
@ -444,7 +446,8 @@ static u16 clip3FFF(u32 v) {
return v;
}
static void SetFXParameters(SND_EMITTER* const em, f32 vol, f32 xPan, f32 yPan, f32 zPan, f32 doppler) {
static void SetFXParameters(SND_EMITTER* const em, f32 vol, f32 xPan, f32 yPan, f32 zPan,
f32 doppler) {
SND_VOICEID vid; // r30
u8 i; // r28
SND_PARAMETER* pPtr; // r31

View File

@ -17,7 +17,14 @@
*/
#include "musyx/musyx_priv.h"
#include "musyx/assert.h"
#include "musyx/s3d.h"
#include "musyx/seq.h"
#include "musyx/stream.h"
#include "musyx/synth.h"
#include "musyx/hardware.h"
#include "musyx/synthdata.h"
// #define _DEBUG
/*
@ -34,7 +41,8 @@ static s32 DoInit(u32 mixFrq, u32 aramSize, u32 numVoices, u32 flags)
{
bool ret;
MUSY_DEBUG("\nMusyX software initialization...\nBuild Date: %s %s\n\n", "Dec 17 2003", "20:32:41");
MUSY_DEBUG("\nMusyX software initialization...\nBuild Date: %s %s\n\n", "Dec 17 2003",
"20:32:41");
ret = FALSE;
#if MUSY_VERSION >= MUSY_VERSION_CHECK(2, 0, 3)

View File

@ -1,5 +1,5 @@
#include "math.h"
#include "musyx/musyx_priv.h"
#include <math.h>
#include "musyx/musyx.h"
void salApplyMatrix(const SND_FMATRIX* mat, const SND_FVECTOR* in, SND_FVECTOR* out) {
out->x = mat->m[0][0] * in->x + mat->m[0][1] * in->y + mat->m[0][2] * in->z + mat->t[0];

View File

@ -17,7 +17,10 @@
*/
#include "musyx/musyx_priv.h"
#include "musyx/assert.h"
#include "musyx/seq.h"
#include "musyx/synth.h"
#include <string.h>
#define SYNTH_FX_MIDISET 0xFF
@ -36,7 +39,7 @@ static CHANNEL_DEFAULTS inpChannelDefaults[8][16];
static CHANNEL_DEFAULTS inpFXChannelDefaults[64];
inline bool GetGlobalFlagSet(u8 chan, u8 midiSet, s32 flag) {
static inline bool GetGlobalFlagSet(u8 chan, u8 midiSet, s32 flag) {
return (flag & inpGlobalMIDIDirtyFlags[midiSet][chan]) != 0;
}

View File

@ -1,4 +1,7 @@
#include "musyx/musyx_priv.h"
#include "musyx/musyx.h"
#include "musyx/snd.h"
#include "musyx/synth.h"
#ifdef __cplusplus
extern "C" {

View File

@ -19,7 +19,14 @@
---------------------------------------
*/
#include "musyx/assert.h"
#include "musyx/hardware.h"
#include "musyx/macros.h"
#include "musyx/s3d.h"
#include "musyx/seq.h"
#include "musyx/stream.h"
#include "musyx/synth.h"
#include <stdarg.h>
/*
@ -597,7 +604,7 @@ void synthDeactivateStudio(u8 studio) {
*/
sndDeactivateStudio(u8 studio) {
void sndDeactivateStudio(u8 studio) {
MUSY_ASSERT_MSG(sndActive != NULL, "Sound system is not initialized.");
MUSY_ASSERT_MSG(studio < synthInfo.studioNum, "Illegal studio index.");
if (studio != 0) {
@ -616,7 +623,7 @@ sndDeactivateStudio(u8 studio) {
*/
synthChangeStudioMasterMix(u8 studio, u32 isMaster) {
void synthChangeStudioMasterMix(u8 studio, u32 isMaster) {
MUSY_ASSERT_MSG(sndActive != NULL, "Sound system is not initialized.");
hwChangeStudioMix(studio, isMaster);
}
@ -680,7 +687,7 @@ u32 sndRemoveStudioInput(u8 studio, SND_STUDIO_INPUT* in_desc) {
}
u8 sndDbgGetActiveVoices() {
u8 n; // r31
u8 n; // r31
hwDisableIrq();
n = voiceFxRunning + voiceMusicRunning;
hwEnableIrq();

View File

@ -1,6 +1,14 @@
#include "musyx/musyx_priv.h"
#include "musyx/musyx.h"
#include "musyx/assert.h"
#include "musyx/hardware.h"
#include "musyx/stream.h"
#include "musyx/synth.h"
#ifndef _DEBUG
#include "musyx/synthdata.h"
#include "musyx/voice.h"
#include "musyx/snd.h"
#if !defined(_DEBUG) && MUSY_TARGET == MUSY_TARGET_DOLPHIN
#include "dolphin/os.h"
#endif
@ -28,13 +36,13 @@ void SetHWMix(const STREAM_INFO* si) {
void streamHandle() {
STREAM_INFO* si; // r31
u32 cpos; // r30
u32 len; // r29
u32 i; // r25
SAMPLE_INFO newsmp; // r1+0x8
u32 cpos; // r30
u32 len; // r29
u32 i; // r25
SAMPLE_INFO newsmp; // r1+0x8
float f; // r63
SND_VOICEID v;
// TODO: Match this
if (streamCallCnt != 0) {
@ -55,7 +63,10 @@ void streamHandle() {
#if MUSY_VERSION <= MUSY_VERSION_CHECK(1, 5, 3)
si->adpcmInfo.initialPS = si->adpcmInfo.loopPS = *(u8*)si->buffer;
#if MUSY_TARGET == MUSY_TARGET_DOLPHIN
DCInvalidateRange(si->buffer, 1);
#endif
#endif
switch (si->type) {
@ -100,8 +111,7 @@ void streamHandle() {
if (si->last < off) {
switch (si->type) {
case 0: {
len = si->updateFunction(si->buffer + si->last, off - si->last, NULL, 0,
si->user);
len = si->updateFunction(si->buffer + si->last, off - si->last, NULL, 0, si->user);
if (len != 0 && si->state == 2) {
off = (si->last + len) % si->size;
if (!(si->flags & 0x20000)) {
@ -119,18 +129,17 @@ void streamHandle() {
} break;
case 1: {
cpos = (si->last / 14) * 8;
if ((len = si->updateFunction((void*)((u32)si->buffer + cpos), off - si->last , NULL, 0,
if ((len = si->updateFunction((void*)((u32)si->buffer + cpos), off - si->last, NULL, 0,
si->user)) != 0 &&
si->state == 2) {
off = (si->last + len) % si->size;
if (!(si->flags & 0x20000)) {
if (off != 0) {
hwFlushStream(si->buffer, cpos, ((off + 13) / 14) * 8 - cpos,
si->hwStreamHandle, NULL, 0);
hwFlushStream(si->buffer, cpos, ((off + 13) / 14) * 8 - cpos, si->hwStreamHandle,
NULL, 0);
} else {
hwFlushStream(si->buffer, cpos, (si->bytes) - cpos,
si->hwStreamHandle, NULL, 0);
hwFlushStream(si->buffer, cpos, (si->bytes) - cpos, si->hwStreamHandle, NULL, 0);
}
}
si->last = off;
@ -140,7 +149,7 @@ void streamHandle() {
} else if (off == 0) {
switch (si->type) {
case 0:
if ((len = si->updateFunction(si->buffer + si->last , si->size - si->last, NULL, 0,
if ((len = si->updateFunction(si->buffer + si->last, si->size - si->last, NULL, 0,
si->user)) &&
si->state == 2) {
off = (si->last + len) % si->size;
@ -157,15 +166,14 @@ void streamHandle() {
}
break;
case 1:
cpos = ((si->last / 14) * 8) ;
if ((len = si->updateFunction( (void*)((u32)si->buffer + cpos) , si->size - si->last, NULL, 0,
si->user)) &&
cpos = ((si->last / 14) * 8);
if ((len = si->updateFunction((void*)((u32)si->buffer + cpos), si->size - si->last,
NULL, 0, si->user)) &&
si->state == 2) {
off = (si->last + len) % si->size;
if (!(si->flags & 0x20000)) {
if (off == 0) {
hwFlushStream(si->buffer, cpos , si->bytes - cpos, si->hwStreamHandle,
NULL, 0);
hwFlushStream(si->buffer, cpos, si->bytes - cpos, si->hwStreamHandle, NULL, 0);
} else {
hwFlushStream(si->buffer, cpos, ((off + 13) / 14) * 8 - cpos, si->hwStreamHandle,
NULL, 0);
@ -179,14 +187,14 @@ void streamHandle() {
} else {
switch (si->type) {
case 0:
if ((len = si->updateFunction(si->buffer + si->last, si->size - si->last, si->buffer, off,
si->user)) &&
if ((len = si->updateFunction(si->buffer + si->last, si->size - si->last, si->buffer,
off, si->user)) &&
si->state == 2) {
off = (si->last + len) % si->size;
if (!(si->flags & 0x20000)) {
if (len > si->size - si->last) {
hwFlushStream(si->buffer, si->last * 2, (si->bytes - si->last * 2) ,
hwFlushStream(si->buffer, si->last * 2, (si->bytes - si->last * 2),
si->hwStreamHandle, NULL, 0);
hwFlushStream(si->buffer, 0, off * 2, si->hwStreamHandle, NULL, 0);
@ -198,41 +206,44 @@ void streamHandle() {
NULL, 0);
}
}
si->last = off;
si->last = off;
}
break;
case 1: {
cpos = (si->last / 14) * 8;
if ((len = si->updateFunction((void*)((u32)si->buffer + cpos) , si->size - si->last, si->buffer, off,
si->user)) &&
if ((len = si->updateFunction((void*)((u32)si->buffer + cpos), si->size - si->last,
si->buffer, off, si->user)) &&
si->state == 2) {
off = (si->last + len) % si->size;
if (!(si->flags & 0x20000)) {
if (len > si->size - si->last) {
hwFlushStream(si->buffer, cpos, si->bytes - cpos,
si->hwStreamHandle, NULL, 0);
hwFlushStream(si->buffer, cpos, si->bytes - cpos, si->hwStreamHandle, NULL, 0);
hwFlushStream(si->buffer, 0, (off / 14) << 3, si->hwStreamHandle, NULL, 0);
} else if (off == 0) {
hwFlushStream(si->buffer, cpos, si->bytes - cpos, si->hwStreamHandle, NULL, 0);
} else {
hwFlushStream(si->buffer, cpos, ((off + 13) / 14) * 8 - cpos, si->hwStreamHandle, NULL,
0);
hwFlushStream(si->buffer, cpos, ((off + 13) / 14) * 8 - cpos, si->hwStreamHandle,
NULL, 0);
}
}
si->last = off;
}
} break;
}
}
if (si->state == 2 && !(si->flags & 0x20000) && si->type == 1) {
#if MUSY_TARGET == MUSY_TARGET_DOLPHIN
hwSetStreamLoopPS(si->voice,
(si->lastPSFromBuffer = *(u32*)OSCachedToUncached(si->buffer) >> 24));
#elif MUSY_TARGET == MUSY_TARGET_PC
hwSetStreamLoopPS(si->voice, (si->lastPSFromBuffer = *(u32*)si->buffer >> 24));
#endif
}
}
}break;
} break;
}
}
}
@ -323,7 +334,13 @@ void sndStreamARAMUpdate(u32 stid, u32 off1, u32 len1, u32 off2, u32 len2) {
#if MUSY_VERSION >= MUSY_VERSION_CHECK(1, 5, 4)
if (streamInfo[i].type == 1) {
#if MUSY_TARGET == MUSY_TARGET_DOLPHIN
streamInfo[i].lastPSFromBuffer = (*(u32*)OSCachedToUncached(streamInfo[i].buffer)) >> 24;
#elif MUSY_TARGET == MUSY_TARGET_PC
streamInfo[i].lastPSFromBuffer = (*(u32*)streamInfo[i].buffer) >> 24;
#endif
if (streamInfo[i].voice != -1) {
hwSetStreamLoopPS(streamInfo[i].voice, streamInfo[i].lastPSFromBuffer);
}

View File

@ -1,7 +1,14 @@
#include "musyx/synth.h"
#include "musyx/assert.h"
#include "musyx/hardware.h"
#include "musyx/musyx_priv.h"
#include "musyx/macros.h"
#include "musyx/sal.h"
#include "musyx/seq.h"
#include "musyx/snd.h"
#include "musyx/synthdata.h"
#include <string.h>
static u32 synthTicksPerSecond[9][16];
static SYNTH_JOBTAB synthJobTable[32];
@ -687,13 +694,13 @@ static void ZeroOffsetHandler(u32 i) {
if (volUpdate || (sv->midiDirtyFlags & 0xf01) != 0) {
preVol = voiceVol;
postVol = voiceVol * vol * (f32)inpGetVolume(sv) * (1.f/16383.f) /* 1/16384? */;
postVol = voiceVol * vol * (f32)inpGetVolume(sv) * (1.f / 16383.f) /* 1/16384? */;
auxa = ((f32)sv->revVolOffset * (1.f / 127.f)) +
((preVol * (f32)inpGetPreAuxA(sv) * (1.f/16383.f) /* 1/16384? */) +
((preVol * (f32)inpGetPreAuxA(sv) * (1.f / 16383.f) /* 1/16384? */) +
((f32)sv->revVolScale *
(postVol * (f32)inpGetReverb(sv) * (1.f/16383.f) /* 1/16384? */) * (1.f / 127.f)));
auxb = (preVol * (f32)inpGetPreAuxB(sv) * (1.f/16383.f) /* 1/16384? */) +
(postVol * (f32)inpGetPostAuxB(sv) * (1.f/16383.f) /* 1/16384? */);
(postVol * (f32)inpGetReverb(sv) * (1.f / 16383.f) /* 1/16384? */) * (1.f / 127.f)));
auxb = (preVol * (f32)inpGetPreAuxB(sv) * (1.f / 16383.f) /* 1/16384? */) +
(postVol * (f32)inpGetPostAuxB(sv) * (1.f / 16383.f) /* 1/16384? */);
sv->curOutputVolume = (u16)(postVol * 32767.f);
hwSetVolume(i, sv->volTable, postVol, sv->lastPan, sv->lastSPan, auxa, auxb);
}
@ -701,7 +708,8 @@ static void ZeroOffsetHandler(u32 i) {
if (sv->midiDirtyFlags & 0x6000) {
if (inpGetFilterSwitch(sv) > 0x1FFF) {
para = inpGetFilterParameter(sv);
frq = sv->lpfLowerFrqBoundary + (u32)((1.f - ((1.f/16383.f) * para)) * (sv->lpfUpperFrqBoundary - sv->lpfLowerFrqBoundary));
frq = sv->lpfLowerFrqBoundary + (u32)((1.f - ((1.f / 16383.f) * para)) *
(sv->lpfUpperFrqBoundary - sv->lpfLowerFrqBoundary));
hwLowPassFrqToCoef(frq, &a0, &b0);
hwSetFilter(i, 1, a0, b0);
} else {

View File

@ -1,6 +1,5 @@
#include "musyx/musyx_priv.h"
#include "musyx/synth.h"
extern SynthInfo synthInfo;
static float toneup_tab[128] = {
1.0f, 1.0594635f, 1.1224623f, 1.1892071f, 1.2599211f, 1.3348398f, 1.4142141f,

View File

@ -1,5 +1,5 @@
#include "musyx/musyx_priv.h"
#include "musyx/adsr.h"
#include "musyx/synth_dbtab.h"
#include <float.h>
@ -75,7 +75,7 @@ u32 salChangeADSRState(ADSR_VARS* adsr) {
adsr->state = 2;
adsr->currentVolume = 0x7fff0000;
adsr->currentIndex = 0xc10000;
adsr->currentDelta = -(((0xc1 - (uint)(adsr->data).dls.sLevel) * 0x10000) / adsr->cnt);
adsr->currentDelta = -(((0xc1 - (u32)(adsr->data).dls.sLevel) * 0x10000) / adsr->cnt);
goto done;
}
}

View File

@ -1,7 +1,12 @@
#include "musyx/musyx.h"
#include "musyx/musyx_priv.h"
#include "musyx/assert.h"
#include "musyx/hardware.h"
#include "musyx/macros.h"
#include "musyx/snd.h"
#include "musyx/voice.h"
static VS vs;
VS vs;
void vsInit() {
u32 i;
@ -220,7 +225,6 @@ unsigned long sndVirtualSampleAllocateBuffers(unsigned char numInstances,
unsigned long numSamples) {
long i; // r31
unsigned long len; // r28
#line 437
MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized.");
MUSY_ASSERT_MSG(numInstances <= 64, "Parameter exceeded maximum number of instances allowable");
@ -253,7 +257,6 @@ unsigned long sndVirtualSampleAllocateBuffers(unsigned char numInstances,
s32 sndVirtualSampleFreeBuffers() {
u8 i; // r31
#line 481
MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized.");
for (i = 0; i < vs.numBuffers; ++i) {
@ -265,7 +268,6 @@ s32 sndVirtualSampleFreeBuffers() {
void sndVirtualSampleSetCallback(unsigned long (*callback)(unsigned char,
struct SND_VIRTUALSAMPLE_INFO*)) {
#line 0x1ed
MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized.");
vs.callback = callback;
}
@ -281,7 +283,6 @@ void vsARAMDMACallback(unsigned long user) {
void sndVirtualSampleARAMUpdate(unsigned short instID, void* base, unsigned long off1,
unsigned long len1, unsigned long off2, unsigned long len2) {
u8 i;
#line 0x203
MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized.");
hwDisableIrq();
@ -309,7 +310,11 @@ void sndVirtualSampleARAMUpdate(unsigned short instID, void* base, unsigned long
}
if (vs.streamBuffer[i].smpType == 5) {
#if MUSY_TARGET == MUSY_TARGET_DOLPHIN
hwSetStreamLoopPS(vs.streamBuffer[i].voice, *(u32*)(OSCachedToUncached(base)) >> 24);
#elif MUSY_TARGET == MUSY_TARGET_PC
hwSetStreamLoopPS(vs.streamBuffer[i].voice, *(u32*)(base) >> 24);
#endif
}
break;
}

View File

@ -1,6 +1,7 @@
#include "musyx/assert.h"
#include "musyx/hardware.h"
#include "musyx/musyx_priv.h"
#include "musyx/synthdata.h"
#include "musyx/snd.h"
static SDIR_TAB dataSmpSDirs[128];
static u16 dataSmpSDirNum;
@ -49,7 +50,6 @@ bool dataInsertKeymap(u16 cid, void* keymapdata) {
hwEnableIrq();
return 0;
}
#line 0x8d
MUSY_ASSERT_MSG(keymapdata != NULL, "Keymap data pointer is NULL");
dataKeymapTab[i].id = cid;
@ -119,7 +119,6 @@ bool dataInsertLayer(u16 cid, void* layerdata, u16 size) {
hwEnableIrq();
return 0;
}
#line 0xe2
MUSY_ASSERT_MSG(layerdata != NULL, "Layer data pointer is NULL");
dataLayerTab[i].id = cid;
@ -188,7 +187,6 @@ bool dataInsertCurve(u16 cid, void* curvedata) {
hwEnableIrq();
return 0;
}
#line 0x13a
MUSY_ASSERT_MSG(curvedata != NULL, "Curve data pointer is NULL");
dataCurveTab[i].id = cid;
@ -344,7 +342,7 @@ bool dataAddSampleReference(u16 sid) {
}
}
done:
#line 542
MUSY_ASSERT_MSG(sdir != NULL,
"Sample ID to be inserted could not be found in any sample directory.\n");
@ -451,7 +449,6 @@ bool dataInsertMacro(u16 mid, void* macroaddr) {
}
if (dataMacTotal < 2048) {
#line 0x2c7
MUSY_ASSERT_MSG(macroaddr, "Macro data pointer is NULL");
for (i = 0; i < 512; ++i) {
if (dataMacMainTab[i].subTabIndex > base) {

View File

@ -1,6 +1,11 @@
#include "musyx/musyx_priv.h"
#include "musyx/assert.h"
#include "musyx/hardware.h"
#include "musyx/macros.h"
#include "musyx/seq.h"
#include "musyx/snd.h"
#include "musyx/synth.h"
#include "musyx/synthdata.h"
#include <string.h>
static u8 DebugMacroSteps;
@ -997,7 +1002,7 @@ void varSet(SYNTH_VOICE* svoice, u32 ctrl, u8 index, s16 v) { varSet32(svoice, c
static void mcmdVarCalculation(SYNTH_VOICE* svoice, MSTEP* cstep, u8 op) {
s16 s1; // r28
s16 s2; // r31
s32 t; // r30
s32 t; // r30
s1 = varGet(svoice, (u8)(cstep->para[0] >> 24), cstep->para[1]);
if (op == 4) {

View File

@ -1,5 +1,11 @@
#include "musyx/musyx_priv.h"
#include "musyx/musyx.h"
#include "musyx/assert.h"
#include "musyx/hardware.h"
#include "musyx/voice.h"
#include "musyx/stream.h"
#include "musyx/macros.h"
void voiceResetLastStarted(SYNTH_VOICE* svoice);