Convert MusyX to a submodule

This commit is contained in:
Phillip Stephens 2023-12-18 18:42:55 -08:00
parent 081a2fe39f
commit 465620fe57
57 changed files with 50 additions and 18298 deletions

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "extern/musyx"]
path = extern/musyx
url = git@github.com:AxioDL/musyx.git

View File

@ -157,6 +157,7 @@ cflags_base = [
"-str reuse",
"-nosyspath",
"-i include",
"-i extern/musyx/include",
"-i libc",
f"-i build/{config.version}/include",
"-DPRIME1",
@ -187,7 +188,7 @@ cflags_retro = [
"-gccinc",
"-inline deferred,noauto",
"-common on",
"-DMUSY_TARGET=MUSY_TARGET_DOLPHIN"
"-DMUSY_TARGET=MUSY_TARGET_DOLPHIN",
]
cflags_musyx = [
@ -195,6 +196,7 @@ cflags_musyx = [
"-nodefaults",
"-nosyspath",
"-i include",
"-i extern/musyx/include",
"-i libc",
"-inline auto",
"-O4,p",
@ -203,7 +205,7 @@ cflags_musyx = [
"-Cpp_exceptions off",
"-str reuse,pool,readonly",
"-fp_contract off",
"-DMUSY_TARGET=MUSY_TARGET_DOLPHIN"
"-DMUSY_TARGET=MUSY_TARGET_DOLPHIN",
]
cflags_musyx_debug = [
@ -212,13 +214,14 @@ cflags_musyx_debug = [
"-nodefaults",
"-nosyspath",
"-i include",
"-i extern/musyx/include",
"-i libc",
"-g",
"-sym on",
"-D_DEBUG=1",
"-enum int",
"-Cpp_exceptions off",
"-DMUSY_TARGET=MUSY_TARGET_DOLPHIN"
"-DMUSY_TARGET=MUSY_TARGET_DOLPHIN",
]
# REL flags
@ -1176,45 +1179,47 @@ config.libs = [
],
},
MusyX(
#debug=True,
#mw_version="GC/1.2.5",
#major=1,
#minor=5,
#patch=3,
# debug=True,
# mw_version="GC/1.2.5",
# major=1,
# minor=5,
# patch=3,
objects=[
Object(Matching, "musyx/runtime/seq.c"),
Object(Matching, "musyx/runtime/synth.c"),
Object(Matching, "musyx/runtime/seq_api.c"),
Object(Matching, "musyx/runtime/snd_synthapi.c"),
Object(NonMatching, "musyx/runtime/stream.c"),
Object(Matching, "musyx/runtime/synthdata.c"),
Object(NonMatching, "musyx/runtime/synthmacros.c"),
Object(Matching, "musyx/runtime/synthvoice.c"),
Object(Matching, "musyx/runtime/synth_ac.c"),
Object(Matching, "musyx/runtime/synth_adsr.c"),
Object(Matching, "musyx/runtime/synth_vsamples.c"),
Object(Matching, "musyx/runtime/synth_dbtab.c"),
Object(Matching, "musyx/runtime/s_data.c"),
Object(NonMatching, "musyx/runtime/hw_dspctrl.c"),
Object(Matching, "musyx/runtime/hw_volconv.c"),
Object(Matching, "musyx/runtime/snd3d.c"),
Object(Matching, "musyx/runtime/snd_init.c"),
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/hw_memory.c"),
Object(Matching, "musyx/runtime/hw_lib_dummy.c"),
Object(Matching, "musyx/runtime/CheapReverb/creverb_fx.c"),
Object(Matching, "musyx/runtime/CheapReverb/creverb.c"),
Object(Matching, "musyx/runtime/StdReverb/reverb_fx.c"),
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/dolphin/profile.c"),
Object(
Matching, "musyx/runtime/seq.c", source="extern/musyx/runtime/seq.c"
),
Object(Matching, "musyx/runtime/synth.c", source="extern/musyx/synth.c"),
Object(Matching, "musyx/runtime/seq_api.c", source="extern/musyx/seq_api.c"),
Object(Matching, "musyx/runtime/snd_synthapi.c", source="extern/musyx/snd_synthapi.c"),
Object(NonMatching, "musyx/runtime/stream.c", source="extern/musyx/stream.c"),
Object(Matching, "musyx/runtime/synthdata.c", source="extern/musyx/synthdata.c"),
Object(NonMatching, "musyx/runtime/synthmacros.c", source="extern/musyx/synthmacros.c"),
Object(Matching, "musyx/runtime/synthvoice.c", source="extern/musyx/synthvoice.c"),
Object(Matching, "musyx/runtime/synth_ac.c", source="extern/musyx/synth_ac.c"),
Object(Matching, "musyx/runtime/synth_adsr.c", source="extern/musyx/synth_adsr.c"),
Object(Matching, "musyx/runtime/synth_vsamples.c", source="extern/musyx/synth_vsamples.c"),
Object(Matching, "musyx/runtime/synth_dbtab.c", source="extern/musyx/synth_dbtab.c"),
Object(Matching, "musyx/runtime/s_data.c", source="extern/musyx/s_data.c"),
Object(NonMatching, "musyx/runtime/hw_dspctrl.c", source="extern/musyx/hw_dspctrl.c"),
Object(Matching, "musyx/runtime/hw_volconv.c", source="extern/musyx/hw_volconv.c"),
Object(Matching, "musyx/runtime/snd3d.c", source="extern/musyx/snd3d.c"),
Object(Matching, "musyx/runtime/snd_init.c", source="extern/musyx/snd_init.c"),
Object(Matching, "musyx/runtime/snd_math.c", source="extern/musyx/snd_math.c"),
Object(NonMatching, "musyx/runtime/snd_midictrl.c", source="extern/musyx/snd_midictrl.c"),
Object(Matching, "musyx/runtime/snd_service.c", source="extern/musyx/snd_service.c"),
Object(Matching, "musyx/runtime/hardware.c", source="extern/musyx/hardware.c"),
Object(Matching, "musyx/runtime/hw_aramdma.c", source="extern/musyx/hw_aramdma.c"),
Object(Matching, "musyx/runtime/dsp_import.c", source="extern/musyx/dsp_import.c"),
Object(Matching, "musyx/runtime/hw_dolphin.c", source="extern/musyx/hw_dolphin.c"),
Object(Matching, "musyx/runtime/hw_memory.c", source="extern/musyx/hw_memory.c"),
Object(Matching, "musyx/runtime/hw_lib_dummy.c", source="extern/musyx/hw_lib_dummy.c"),
Object(Matching, "musyx/runtime/CheapReverb/creverb_fx.c", source="extern/musyx/creverb_fx.c"),
Object(Matching, "musyx/runtime/CheapReverb/creverb.c", source="extern/musyx/creverb.c"),
Object(Matching, "musyx/runtime/StdReverb/reverb_fx.c", source="extern/musyx/reverb_fx.c"),
Object(Matching, "musyx/runtime/StdReverb/reverb.c", source="extern/musyx/reverb.c"),
Object(Matching, "musyx/runtime/Delay/delay_fx.c", source="extern/musyx/delay_fx.c"),
Object(Matching, "musyx/runtime/Chorus/chorus_fx.c", source="extern/musyx/chorus_fx.c"),
Object(Matching, "musyx/runtime/profile.c", source="extern/musyx/profile.c"),
],
),
{

1
extern/musyx vendored Submodule

@ -0,0 +1 @@
Subproject commit 6f76370d3614c260b43cbd6cc875ac9de885359d

View File

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

View File

@ -1,105 +0,0 @@
#ifndef _ASSERT
#define _ASSERT
#include "musyx/platform.h"
#include "musyx/version.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>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
static inline void panic(const char* file, int line, const char* msg, ...) {
va_list list;
va_start(list);
vprintf(msg, list);
va_end(list);
printf(" in \"%s\" on line %d.\n", file, line);
abort();
}
#ifndef MUSY_PANIC
#define MUSY_PANIC panic
#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 MUSY_ASSERT
#ifdef _DEBUG
#define MUSY_ASSERT(cond) \
do { \
if (!(cond)) { \
MUSY_PANIC(__FILE__, __LINE__, "Failed assertion " #cond); \
} \
__SOME_ASSERT_DERP(); \
} while (0)
#else
#define MUSY_ASSERT(cond)
#endif
#endif
#ifndef MUSY_ASSERT_MSG
#ifdef _DEBUG
#if MUSY_VERSION >= MUSY_VERSION_CHECK(2, 0, 0)
#define MUSY_ASSERT_MSG(cond, msg) \
do { \
s32 tmp = 1; \
s32 tmp2; \
if (!(cond)) { \
MUSY_PANIC(__FILE__, __LINE__, msg); \
tmp2 = 0; \
if (tmp2 == 0) { \
tmp = 0; \
} \
} \
} while (0)
#else
#define MUSY_ASSERT_MSG(cond, msg) \
do { \
if (!(cond)) { \
MUSY_PANIC(__FILE__, __LINE__, msg); \
} \
} while (0)
#endif
#else
#define MUSY_ASSERT_MSG(cond, msg)
#endif
#endif
#ifndef MUSY_DEBUG
#ifdef _DEBUG
#define MUSY_DEBUG MUSY_REPORT
#else
#define MUSY_DEBUG
#endif
#endif
#ifndef MUSY_FATAL
#ifdef _DEBUG
#define MUSY_FATAL(msg) MUSY_PANIC(__FILE__, __LINE__, msg)
#else
#define MUSY_FATAL
#endif
#endif
#endif // _ASSERT

View File

@ -1,21 +0,0 @@
#ifndef _MUSYX_DSP_IMPORT
#define _MUSYX_DSP_IMPORT
#include "musyx/platform.h"
#if MUSY_TARGET == MUSY_TARGET_DOLPHIN
#include "musyx/musyx.h"
#ifdef __cplusplus
extern "C" {
#endif
extern char dspSlave[];
extern u16 dspSlaveLength;
#ifdef __cplusplus
}
#endif
#endif
#endif // _MUSYX_DSP_IMPORT

View File

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

View File

@ -1,103 +0,0 @@
#ifndef _MUSYX_HARDWARE
#define _MUSYX_HARDWARE
#include "musyx/musyx.h"
#include <stddef.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 s16* 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);
void hwSetPitch(u32 v, u16 speed);
void hwInitIrq();
void hwExitIrq();
void hwEnableIrq();
void hwDisableIrq();
void* hwTransAddr(void* samples);
void hwExitStream(u8 id);
void hwSaveSample(void* header, void* data);
void hwRemoveSample(void* header, void* data);
u32 hwGetVirtualSampleState(u32 voice);
bool hwVoiceInStartup(u32 v);
void hwBreak(s32 vid);
u32 hwGetPos(u32 v);
void hwInitSampleMem(u32 baseAddr, u32 length);
void hwExitSampleMem();
void hwSetVirtualSampleLoopBuffer(u32 voice, void* addr, u32 len);
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, u8 hwStreamHandle, void (*callback)(size_t),
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, bool 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;
void aramInit(u32 length);
void aramExit();
size_t aramGetStreamBufferAddress(u8 id, size_t* len);
void aramUploadData(void* mram, u32 aram, u32 len, u32 highPrio, void (*callback)(size_t), u32 user);
void aramFreeStreamBuffer(u8 id);
void* aramStoreData(void* src, u32 len);
void aramRemoveData(void* aram, u32 len);
u8 aramAllocateStreamBuffer(u32 len);
unsigned long aramGetZeroBuffer();
void aramSetUploadCallback(ARAMUploadCallback callback, u32 chunckSize);
void aramSyncTransferQueue();
#ifdef __cplusplus
}
#endif
#endif // _MUSYX_HARDWARE

View File

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

View File

@ -1,833 +0,0 @@
#ifndef _MUSYX_MUSYX
#define _MUSYX_MUSYX
#include "musyx/platform.h"
#include "musyx/version.h"
#include <math.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
#if MUSY_TARGET == MUSY_TARGET_DOLPHIN
typedef signed char s8;
typedef unsigned char u8;
typedef signed short s16;
typedef unsigned short u16;
typedef signed long s32;
typedef unsigned long u32;
typedef unsigned long long u64;
typedef float f32;
typedef double f64;
#elif MUSY_TARGET == MUSY_TARGET_PC
typedef signed char s8;
typedef unsigned char u8;
typedef signed short s16;
typedef unsigned short u16;
typedef signed int s32;
typedef unsigned int u32;
typedef unsigned long long u64;
typedef float f32;
typedef double f64;
#endif
#ifndef NULL
#define NULL 0
#endif
#ifndef bool8
typedef unsigned char bool8;
#endif
#ifndef __cplusplus
#if __STDC_VERSION__ <= 199901L
typedef unsigned long bool;
#endif
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
#endif
#define SND_STUDIO_MAXNUM 8
#define SND_STUDIO_DEFAULT 0
#define SND_STUDIO_NONE 0xFF
#define SYNTH_MAX_VOICES 64
typedef u32 SND_SEQID;
typedef u32 SND_VOICEID;
typedef u32 SND_STREAMID;
typedef u16 SND_GROUPID;
typedef u16 SND_SONGID;
typedef u16 SND_FXID;
typedef enum {
SND_OUTPUTMODE_MONO = 0,
SND_OUTPUTMODE_STEREO,
SND_OUTPUTMODE_SURROUND
} SND_OUTPUTMODE;
typedef struct SND_PLAYBACKINFO {
u32 frq;
u8 stereo;
u8 bits;
s8 deviceName[256];
s8 versionText[256];
} SND_PLAYBACKINFO;
typedef struct SND_SEQVOLDEF {
u8 track;
u8 volGroup;
} SND_SEQVOLDEF;
#define SND_PLAYPARA_DEFAULT 0x00000000
#define SND_PLAYPARA_TRACKMUTE 0x00000001
#define SND_PLAYPARA_SPEED 0x00000002
#define SND_PLAYPARA_VOLUME 0x00000004
#define SND_PLAYPARA_SEQVOLDEF 0x00000008
#define SND_PLAYPARA_PAUSE 0x00000010
typedef struct SND_PLAYPARA {
u32 flags; // Enable features by using these flags
u32 trackMute[2]; // Initial mute settings
u16 speed; // Initial speed factor (0x100 = 1:1)
struct { // Start volume information
u16 time;
u8 target;
} volume;
u8 numSeqVolDef; // Number of non-standart volume group tracks
SND_SEQVOLDEF* seqVolDef; // List of tracks and the volume groups to be assigned to them
u8 numFaded; // Number of entries to the fade list
u8* faded; // Array of u8s containing the volume group IDs that should be affected by the initial
// volume setting (default will always be affected)
} SND_PLAYPARA;
#define SND_CROSSFADE_STOP 0 // Stop old song after fadedown
#define SND_CROSSFADE_PAUSE 1 // Pause old song after fadedown
#define SND_CROSSFADE_CONTINUE 2 // Continue previously paused song as new one
#define SND_CROSSFADE_START 0 // Start new song (no continue)
#define SND_CROSSFADE_SYNC 4 // Crossfade should start syncronized by sync-controller (104)
#define SND_CROSSFADE_PAUSENEW 8 // Pause new song before even starting it
#define SND_CROSSFADE_TRACKMUTE 16 // Use trackmute informtion
#define SND_CROSSFADE_SPEED 32 // Use speed informtion
#define SND_CROSSFADE_MUTE 64 // Old song continues playing & gets muted after fade down
#define SND_CROSSFADE_MUTENEW 128 // Mute new song after starting it
#define SND_CROSSFADE_DEFAULT 0
typedef struct SND_CROSSFADE {
SND_SEQID seqId1;
u16 time1;
SND_SEQID seqId2;
u16 time2;
void* arr2;
SND_GROUPID gid2;
SND_SONGID sid2;
u8 vol2;
u8 studio2;
u32 trackMute2[2]; // Mute bits (see sndMute())
u16 speed2; // Initial speed (of new song)
u8 flags;
} SND_CROSSFADE;
#define SND_ID_ERROR 0xFFFFFFFF // ID is invalid
#define SND_USERMUSIC_VOLGROUPS 0xFA
#define SND_USERFX_VOLGROUPS 0xFB
#define SND_USERALL_VOLGROUPS 0xFC
#define SND_MUSIC_VOLGROUPS 0xFD
#define SND_FX_VOLGROUPS 0xFE
#define SND_ALL_VOLGROUPS 0xFF
#define SND_MAX_USER_VOLGROUP 20
bool sndPushGroup(void* prj_data, SND_GROUPID gid, void* samples, void* sampdir, void* pool);
bool sndPopGroup(void);
void sndSetSampleDataUploadCallback(void* (*callback)(u32 offset, u32 bytes), u32 chunkSize);
typedef struct SND_HOOKS {
void* (*malloc)(size_t addr);
void (*free)(void* addr);
} SND_HOOKS;
void sndSetHooks(SND_HOOKS* hooks);
// Misc flags to influence the way the sound system works internally
// (support may vary from platform to platform)
#define SND_FLAGS_DEFAULT 0x00000000
#define SND_FLAGS_DEFAULT_STUDIO_DPL2 0x00000001 // Use DPL2 encoding for default studio
#define SND_FLAGS_EMITTERGROUPSUSEMAXVOICES \
0x00000002 // define this to enable usage of max. voices from FX table for emitter group start
// management
// Platform dependend flags : PC
#define SND_FLAGS_PC_USE_TIMER \
0x00000000 // Use timer driven update system (less performance hit, larger latency)
#define SND_FLAGS_PC_USE_THREAD \
0x00010000 // Use thread driven update system (larger performance hit, shorter latency)
#define SND_FLAGS_PC_USE_PRIMARY 0x00020000 // Use a primary sound buffer for mixing (Win95/98 only)
#define SND_FLAGS_PC_LATENCY0 0x00000000 // Latency values (see documentation)
#define SND_FLAGS_PC_LATENCY1 0x10000000
#define SND_FLAGS_PC_LATENCY2 0x20000000
#define SND_FLAGS_PC_LATENCY3 0x30000000
#define SND_FLAGS_PC_LATENCY4 0x40000000
#define SND_FLAGS_PC_LATENCY5 0x50000000
#define SND_FLAGS_PC_LATENCY6 0x60000000
#define SND_FLAGS_PC_LATENCY7 0x70000000
s32 sndInit(u8 voices, u8 music, u8 sfx, u8 studios, u32 flags, u32 aramSize);
void sndQuit(void);
bool sndIsInstalled(void);
bool sndIsIdle(void);
SND_PLAYBACKINFO* sndGetPlayBackInfo(void);
void sndSetMaxVoices(u8 music, u8 sfx);
void sndVolume(u8 volume, u16 time, u8 volGroup);
void sndMasterVolume(u8 volume, u16 time, u8 music, u8 fx);
void sndOutputMode(SND_OUTPUTMODE mode);
void sndSilence(void);
#define SND_PAUSEVOL_NORMAL 127
void sndPauseVolume(u8 mute_vol, u16 time, u8 volGroup);
#define SND_MIDICTRL_MODULATION 0x01
#define SND_MIDICTRL_VOLUME 0x07
#define SND_MIDICTRL_PANNING 0x0A
#define SND_MIDICTRL_PEDAL 0x40
#define SND_MIDICTRL_PORTAMENTO 0x41
#define SND_MIDICTRL_REVERB 0x5B
#define SND_MIDICTRL_CHORUS 0x5D
#define SND_MIDICTRL_PITCHBEND 0x80
#define SND_MIDICTRL_SPANNING 0x83
#define SND_MIDICTRL_DOPPLER 0x84
#define SND_SEQVOL_CONTINUE 0
#define SND_SEQVOL_STOP 1
#define SND_SEQVOL_PAUSE 2
#define SND_SEQVOL_MUTE 3
#define SND_SEQVOL_MODEMASK 0xF
#define SND_ID_ERROR 0xFFFFFFFF // ID is invalid
#define SND_MAX_SEQINSTANCES 8
#define SND_SEQ_ERROR_ID 0xFFFFFFFF
#define SND_SEQ_CROSSFADE_ID 0x80000000
#define SND_PAUSEVOL_NORMAL 127
#define SND_SEQVOL_CONTINUE 0
#define SND_SEQVOL_STOP 1
#define SND_SEQVOL_PAUSE 2
#define SND_SEQVOL_MUTE 3
#define sndSeqPlay(sgid, sid, arrfile, para) \
sndSeqPlayEx(sgid, sid, arrfile, para, SND_STUDIO_DEFAULT)
SND_SEQID sndSeqPlayEx(SND_GROUPID sgid, SND_SONGID sid, void* arrfile, SND_PLAYPARA* para,
u8 studio);
void sndSeqStop(SND_SEQID seqId);
void sndSeqPause(SND_SEQID seqId);
void sndSeqContinue(SND_SEQID seqId);
void sndSeqMute(SND_SEQID seqId, u32 mask1, u32 mask2);
void sndSeqSpeed(SND_SEQID seqId, u16 speed);
bool sndSeqLoop(SND_SEQID seqId, bool on);
bool sndSeqLoopEx(SND_SEQID seqId, u8 track, bool on);
u16 sndSeqGetLoopCnt(SND_SEQID seqId);
u16 sndSeqGetLoopCntEx(SND_SEQID seqId, u8 track);
bool sndSeqGetValid(SND_SEQID seqId);
u8 sndSeqGetMidiCtrl(SND_SEQID seqId, u8 channel, u8 ctrl);
u16 sndSeqGetMidiCtrl14(SND_SEQID seqId, u8 channel, u8 ctrl);
bool sndSeqSetMidiCtrl(SND_SEQID seqId, u8 channel, u8 ctrl, u8 value);
bool sndSeqSetMidiCtrl14(SND_SEQID seqId, u8 channel, u8 ctrl, u16 value);
void sndSeqVolume(u8 volume, u16 time, SND_SEQID seqId, u8 mode);
u8 sndSeqGetVolGroup(SND_SEQID seqId);
bool sndSeqAssignVolGroup2Track(SND_SEQID seqId, u8 track, u8 vGroup);
void sndSeqCrossFade(SND_CROSSFADE* ci, SND_SEQID* new_seqId);
bool sndSeqCrossFadeDone(SND_SEQID* new_seqId);
typedef struct SND_PARAMETER {
u8 ctrl;
union _paraData {
u8 value7;
u16 value14;
} paraData;
} SND_PARAMETER;
typedef struct SND_PARAMETER_INFO {
u8 numPara; // How many MIDI controller values (ID,value - value may be 8-bit or 16-bit!)
SND_PARAMETER* paraArray; // Parameter data...
} SND_PARAMETER_INFO;
#define SND_FX_DEFVOL 0xFF
#define SND_FX_DEFPAN 0xFF
#define sndFXStart(fid, vol, pan) sndFXStartEx(fid, vol, pan, SND_STUDIO_DEFAULT)
SND_VOICEID sndFXStartEx(SND_FXID fid, u8 vol, u8 pan, u8 studio);
SND_VOICEID sndFXStartPara(SND_FXID fid, u8 vol, u8 pan, u8 studio, u8 numPara, ...);
SND_VOICEID sndFXStartParaInfo(SND_FXID fid, u8 vol, u8 pan, u8 studio,
SND_PARAMETER_INFO* paraInfo);
SND_VOICEID sndFXCheck(SND_VOICEID vid);
bool sndFXKeyOff(SND_VOICEID vid);
bool sndFXCtrl(SND_VOICEID vid, u8 ctrl, u8 value);
bool sndFXCtrl14(SND_VOICEID vid, u8 ctrl, u16 value);
#define SND_MIDICTRL_MODULATION 0x01
#define SND_MIDICTRL_VOLUME 0x07
#define SND_MIDICTRL_PANNING 0x0A
#define SND_MIDICTRL_PEDAL 0x40
#define SND_MIDICTRL_PORTAMENTO 0x41
#define SND_MIDICTRL_REVERB 0x5B
#define SND_MIDICTRL_CHORUS 0x5D
#define SND_MIDICTRL_PITCHBEND 0x80
#define SND_MIDICTRL_SPANNING 0x83
#define SND_MIDICTRL_DOPPLER 0x84
#define sndFXPitchBend(vid, pb) sndFXCtrl14(vid, SND_MIDICTRL_PITCHBEND, pb)
#define sndFXModulation(vid, modu) sndFXCtrl14(vid, SND_MIDICTRL_MODULATION, modu)
#define sndFXDoppler(vid, doppler) sndFXCtrl14(vid, SND_MIDICTRL_DOPPLER, doppler)
#define sndFXReverb(vid, reverb) sndFXCtrl(vid, SND_MIDICTRL_REVERB, reverb)
#define sndFXChorus(vid, chorus) sndFXCtrl(vid, SND_MIDICTRL_CHORUS, chorus)
#define sndFXPedal(vid, pedal) sndFXCtrl(vid, SND_MIDICTRL_PEDAL, pedal)
#define sndFXVolume(vid, vol) sndFXCtrl(vid, SND_MIDICTRL_VOLUME, vol)
#define sndFXPanning(vid, pan) sndFXCtrl(vid, SND_MIDICTRL_PANNING, pan)
#define sndFXSurroundPanning(vid, span) sndFXCtrl(vid, SND_MIDICTRL_SPANNING, span)
bool sndFXAssignVolGroup2FXId(SND_FXID fid, u8 vGroup);
// --------------------------------------------------------
s32 sndReadFlag(u8 num);
s32 sndWriteFlag(u8 num, s32 value);
bool sndSendMessage(SND_VOICEID vid, s32 mesg);
void sndSetReceiveMessageCallback(void (*callback)(SND_VOICEID vid, s32 mesg));
// --------------------------------------------------------
// Flags
#define SND_STREAM_DEFAULT 0x00000000 // Default stream buffer (PCM16)
#define SND_STREAM_ADPCM 0x00000001 // ADPCM stream buffer
#define SND_STREAM_INACTIVE 0x00010000 // Allocate stream, but do not start it yet
#define SND_STREAM_MANUALARAMUPD 0x00020000 // Application will provide manual ARAM buffer updates
#define SND_STREAM_ADPCM_BLKBYTES 8 // Bytes per ADPCM block
#define SND_STREAM_ADPCM_BLKSIZE 14 // Samples per ADPCM block
// ADPCM info structure
typedef struct SND_ADPCMSTREAM_INFO {
s16 coefTab[8][2]; // Table of coef. pairs
} SND_ADPCMSTREAM_INFO;
#define sndStreamAlloc(prio, buffer, size, frq, vol, pan, span, fxvol, updateFunction, user) \
sndStreamAllocEx(prio, buffer, size, frq, vol, pan, span, fxvol, 0, SND_STUDIO_DEFAULT, \
SND_STREAM_DEFAULT, updateFunction, user, NULL)
SND_STREAMID sndStreamAllocEx(u8 prio, void* buffer, u32 samples, u32 frq, u8 vol, u8 pan, u8 span,
u8 auxa, u8 auxb, u8 studio, u32 flags,
u32 (*updateFunction)(void* buffer1, u32 len1, void* buffer2,
u32 len2, u32 user),
u32 user, SND_ADPCMSTREAM_INFO* adpcmInfo);
SND_STREAMID sndStreamAllocStereo(u8 prio, void* lBuffer, void* rBuffer, u32 samples, u32 frq,
u8 vol, u8 pan, u8 span, u8 auxa, u8 auxb, u8 studio, u32 flags,
u32 (*updateFunction)(void* buffer1, u32 len1, void* buffer2,
u32 len2, u32 user),
u32 lUser, u32 rUser, SND_ADPCMSTREAM_INFO* adpcmInfoL,
SND_ADPCMSTREAM_INFO* adpcmInfoR);
u32 sndStreamAllocLength(u32 num, u32 flags);
void sndStreamFree(SND_STREAMID stid);
void sndStreamMixParameter(SND_STREAMID stid, u8 vol, u8 pan, u8 span, u8 fxvol);
void sndStreamMixParameterEx(SND_STREAMID stid, u8 vol, u8 pan, u8 span, u8 auxa, u8 auxb);
void sndStreamADPCMParameter(SND_STREAMID stid, SND_ADPCMSTREAM_INFO* adpcmInfo);
void sndStreamFrq(SND_STREAMID stid, u32 frq);
bool sndStreamActivate(SND_STREAMID stid);
void sndStreamDeactivate(SND_STREAMID stid);
void sndStreamARAMUpdate(SND_STREAMID stid, u32 off1, u32 len1, u32 off2, u32 len2);
u32 sndStreamCallbackFrq(u32 msTime);
// --------------------------------------------------------
#define SND_VIRTUALSAMPLE_DEFAULT 0x00000000
bool sndVirtualSampleAllocateBuffers(u8 numInstances, u32 numSamples, u32 flags);
void sndVirtualSampleFreeBuffers(void);
typedef u16 SND_VSID; // Virtual sample ID
typedef u16 SND_INSTID; // Virtual sample instance ID
typedef struct SND_VIRTUALSAMPLE_INFO {
SND_VSID smpID; // ID of sample to be streamed
SND_INSTID instID; // ID of this instance of the stream
union vsData {
struct vsUpdate { // Buffer update info
u32 off1;
u32 len1;
u32 off2;
u32 len2;
} update;
} data;
} SND_VIRTUALSAMPLE_INFO;
#define SND_VIRTUALSAMPLE_REASON_INIT 0 // Virtual sample just started playback
#define SND_VIRTUALSAMPLE_REASON_UPDATE 1 // Virtual sample is within stream buffer and needs data
#define SND_VIRTUALSAMPLE_REASON_STOP 2 // Virtual sample just has been stopped
#define SND_VIRTUALSAMPLE_REASON_ARAMDMADONE \
3 // Last ARAM update initiated for this virtual sample has finished
void sndVirtualSampleSetCallback(u32 (*callback)(u8 reason, const SND_VIRTUALSAMPLE_INFO* info));
void sndVirtualSampleARAMUpdate(SND_INSTID instID, void* base, u32 off1, u32 len1, u32 off2,
u32 len2);
void sndVirtualSampleEndPlayback(SND_INSTID instID, bool sampleEndedNormally);
#define SND_AUX_BLOCKSIZE 160 // Size of block passed to the AUX FX hanler (in samples)
#define SND_AUX_REASON_BUFFERUPDATE 0
#define SND_AUX_REASON_PARAMETERUPDATE 1
#define SND_MIDI_NONE 0xFF
#define SND_AUX_NUMPARAMETERS 4
typedef struct SND_AUX_INFO {
union SND_AUX_DATA {
struct SND_AUX_BUFFERUPDATE {
s32* left;
s32* right;
s32* surround;
} bufferUpdate;
struct SND_AUX_PARAMETERUPDATE {
u16 para[SND_AUX_NUMPARAMETERS];
} parameterUpdate;
} data;
} SND_AUX_INFO;
void sndSetAuxProcessingCallbacks(u8 studio,
void (*auxA)(u8 reason, SND_AUX_INFO* info, void* user),
void* userA, u8 midiA, SND_SEQID seqIDA,
void (*auxB)(u8 reason, SND_AUX_INFO* info, void* user),
void* userB, u8 midiB, SND_SEQID seqIDB);
#define SND_AUXA_PARAMETERS 0
#define SND_AUXB_PARAMETERS 1
void sndUpdateAuxParameter(u8 studio, u16 para[SND_AUX_NUMPARAMETERS], u8 auxBus);
typedef enum {
SND_STUDIO_TYPE_STD = 0,
SND_STUDIO_TYPE_DPL2,
SND_STUDIO_TYPE_RESERVED1,
SND_STUDIO_TYPE_RESERVED2
} SND_STUDIO_TYPE;
#define sndActivateStudio(studio, isMaster) \
sndActivateStudioEx(studio, isMaster, SND_STUDIO_TYPE_STD)
void sndActivateStudioEx(u8 studio, bool isMaster, SND_STUDIO_TYPE type);
void sndChangeStudioMasterMix(u8 studio, bool isMaster);
void sndDeactivateStudio(u8 studio);
void sndSetITDDefault(u8 studio, bool musicITD, bool sfxITD);
// Standard Quality Reverb AUX FX
typedef struct _SND_REVSTD_DELAYLINE {
s32 inPoint;
s32 outPoint;
s32 length;
f32* inputs;
f32 lastOutput;
} _SND_REVSTD_DELAYLINE;
typedef struct _SND_REVSTD_WORK {
_SND_REVSTD_DELAYLINE AP[6];
_SND_REVSTD_DELAYLINE C[6];
f32 allPassCoeff;
f32 combCoef[6];
f32 lpLastout[3];
f32 level;
f32 damping;
s32 preDelayTime;
f32* preDelayLine[3];
f32* preDelayPtr[3];
} _SND_REVSTD_WORK;
typedef struct SND_AUX_REVERBSTD {
_SND_REVSTD_WORK rv;
bool8 tempDisableFX;
f32 coloration;
f32 mix;
f32 time;
f32 damping;
f32 preDelay;
} SND_AUX_REVERBSTD;
typedef void (*SND_AUX_CALLBACK)(u8 reason, SND_AUX_INFO* info, void* user);
void sndAuxCallbackReverbSTD(u8 reason, SND_AUX_INFO* info, void* user);
bool sndAuxCallbackPrepareReverbSTD(SND_AUX_REVERBSTD* rev);
bool sndAuxCallbackShutdownReverbSTD(SND_AUX_REVERBSTD* rev);
bool sndAuxCallbackUpdateSettingsReverbSTD(SND_AUX_REVERBSTD* rev);
// High Quality Reverb AUX FX
//
typedef struct _SND_REVHI_DELAYLINE {
s32 inPoint;
s32 outPoint;
s32 length;
f32* inputs;
f32 lastOutput;
} _SND_REVHI_DELAYLINE;
typedef struct _SND_REVHI_WORK {
_SND_REVHI_DELAYLINE AP[9];
_SND_REVHI_DELAYLINE C[9];
f32 allPassCoeff;
f32 combCoef[9];
f32 lpLastout[3];
f32 level;
f32 damping;
s32 preDelayTime;
f32 crosstalk;
f32* preDelayLine[3];
f32* preDelayPtr[3];
} _SND_REVHI_WORK;
typedef struct SND_AUX_REVERBHI {
_SND_REVHI_WORK rv;
bool8 tempDisableFX;
f32 coloration;
f32 mix;
f32 time;
f32 damping;
f32 preDelay;
f32 crosstalk;
} SND_AUX_REVERBHI;
void sndAuxCallbackReverbHI(u8 reason, SND_AUX_INFO* info, void* user);
bool sndAuxCallbackPrepareReverbHI(SND_AUX_REVERBHI* rev);
bool sndAuxCallbackShutdownReverbHI(SND_AUX_REVERBHI* rev);
bool sndAuxCallbackUpdateSettingsReverbHI(SND_AUX_REVERBHI* rev);
// Delay AUX FX
//
typedef struct SND_AUX_DELAY {
u32 currentSize[3];
u32 currentPos[3];
u32 currentFeedback[3];
u32 currentOutput[3];
s32* left;
s32* right;
s32* sur;
// - - - - - - - - - - -
u32 delay[3]; // Delay buffer length in ms per channel
u32 feedback[3]; // Feedback volume in % per channel
u32 output[3]; // Output volume in % per channel
} SND_AUX_DELAY;
void sndAuxCallbackDelay(u8 reason, SND_AUX_INFO* info, void* user);
bool sndAuxCallbackPrepareDelay(SND_AUX_DELAY* delay);
bool sndAuxCallbackShutdownDelay(SND_AUX_DELAY* delay);
bool sndAuxCallbackUpdateSettingsDelay(SND_AUX_DELAY* delay);
// Chorus AUX FX
typedef struct _SND_CHORUS_SRCINFO {
s32* dest;
s32* smpBase;
s32* old;
u32 posLo;
u32 posHi;
u32 pitchLo;
u32 pitchHi;
u32 trigger;
u32 target;
} _SND_CHORUS_SRCINFO;
#define _SND_CHORUS_NUM_BLOCKS 3
typedef struct _SND_CHORUS_WORK {
s32* lastLeft[_SND_CHORUS_NUM_BLOCKS];
s32* lastRight[_SND_CHORUS_NUM_BLOCKS];
s32* lastSur[_SND_CHORUS_NUM_BLOCKS];
u8 currentLast;
s32 oldLeft[4];
s32 oldRight[4];
s32 oldSur[4];
u32 currentPosLo;
u32 currentPosHi;
s32 pitchOffset;
u32 pitchOffsetPeriodCount;
u32 pitchOffsetPeriod;
_SND_CHORUS_SRCINFO src;
} _SND_CHORUS_WORK;
typedef struct SND_AUX_CHORUS {
_SND_CHORUS_WORK work;
u32 baseDelay; // Base delay of chorus effect in ms
u32 variation; // Variation of base delay in ms
u32 period; // Period of variational oscilation in ms
} SND_AUX_CHORUS;
void sndAuxCallbackChorus(u8 reason, SND_AUX_INFO* info, void* user);
bool sndAuxCallbackPrepareChorus(SND_AUX_CHORUS* ch);
bool sndAuxCallbackShutdownChorus(SND_AUX_CHORUS* ch);
bool sndAuxCallbackUpdateSettingsChorus(SND_AUX_CHORUS* ch);
// Studio linkage
typedef struct SND_STUDIO_INPUT {
u8 vol;
u8 volA;
u8 volB;
u8 srcStudio;
} SND_STUDIO_INPUT;
bool sndAddStudioInput(u8 studio, SND_STUDIO_INPUT* in_desc);
bool sndRemoveStudioInput(u8 studio, SND_STUDIO_INPUT* in_desc);
// 3D API
typedef struct SND_FVECTOR {
f32 x;
f32 y;
f32 z;
} SND_FVECTOR;
typedef struct SND_FMATRIX {
f32 m[3][3];
f32 t[3];
} SND_FMATRIX;
typedef struct SND_ROOM {
struct SND_ROOM* next;
struct SND_ROOM* prev;
u32 flags;
SND_FVECTOR pos; // World "position" of room
f32 distance; // Average distance to listeners (squared)
u8 studio;
void (*activateReverb)(u8 studio, void* para); // Callbacks to activate/deactivate "reverb" (AuxA)
void (*deActivateReverb)(u8 studio); // (NULL -> none)
void* user; // Pointer to user data (e.g. "reverb" parameters)
u32 curMVol; // Current master mix volume (7.16)
} SND_ROOM;
typedef struct SND_DOOR {
struct SND_DOOR* next;
struct SND_DOOR* prev;
SND_FVECTOR pos; // Position of door
f32 open; // State (0=closed, 1=open)
f32 dampen; // Dampening when closed (0=none, 1=full)
u8 fxVol; // FX mix volume of this door (0-127)
u8 destStudio; // When active: Studio the input is linked to
SND_ROOM* a; // Rooms to be linked
SND_ROOM* b;
u32 flags; // Flags
s16 filterCoef[4]; // Coefs of the 4 tab FIR filter (0x7FFF = 1.0)
SND_STUDIO_INPUT input; // Input info (when active)
} SND_DOOR;
#define SND_DOOR_A2B 0x00000000 // Door leads from A to B
#define SND_DOOR_B2A 0x00000001 // Door leads from B to A
#define SND_DOOR_DEFAULT SND_DOOR_A2B
typedef struct SND_LISTENER {
struct SND_LISTENER* next;
struct SND_LISTENER* prev;
SND_ROOM* room;
u32 flags;
SND_FVECTOR pos;
f32 volPosOff; // (reserved for future use)
SND_FVECTOR dir; // Speed in units/second
SND_FVECTOR heading;
SND_FVECTOR right;
SND_FVECTOR up;
SND_FMATRIX mat;
f32 surroundDisFront;
f32 surroundDisBack;
f32 soundSpeed;
f32 vol;
} SND_LISTENER;
#define SND_LISTENER_DEFAULT 0x00000000 // No special features are activated
#define SND_LISTENER_DOPPLERFX \
0x00000001 // Listener is supposed to be moving fast enough to display Dopller effects
typedef struct SND_EMITTER {
struct SND_EMITTER* next;
struct SND_EMITTER* prev;
SND_ROOM* room;
SND_PARAMETER_INFO* paraInfo;
u32 flags;
SND_FVECTOR pos;
SND_FVECTOR dir; // Speed in units/second
f32 maxDis;
f32 maxVol;
f32 minVol;
f32 volPush; // -1.0f = 1/square -> 0.0 = linear -> 1.0 = square
SND_VOICEID vid;
u32 group; // Group ID (by default FXID | 0x80000000) used to do volume priorities for continous
// emitters
SND_FXID fxid;
u8 studio;
u8 maxVoices; // Max. voices of the assigned FX
u16 VolLevelCnt; // Used during continous emitter allocation process
f32 fade; // Used to fade-in of continous emitters
} SND_EMITTER;
#define SND_EMITTER_DEFAULTKEY 0xFF
#define SND_EMITTER_DEFAULTVOL 0xFF
#define SND_EMITTER_DEFAULT 0x00000000 // No special features are activated
#define SND_EMITTER_CONTINOUS \
0x00000001 // Parameters should be updated over time (they will be set just once if not set)
#define SND_EMITTER_CONTINUOUS \
0x00000001 // Parameters should be updated over time (they will be set just once if not set)
#define SND_EMITTER_RESTARTABLE \
0x00000002 // If the used voice is reallocated, the sound should be restarted as soon as possible
#define SND_EMITTER_PAUSABLE \
0x00000004 // The sound may be stopped if it is no longer audible (and restarted if the above flag
// is set as soon as it's audibel again)
#define SND_EMITTER_DOPPLERFX \
0x00000008 // Emitter is supposed to be moving fast enough to display Doppler effects
#define SND_EMITTER_ITD \
0x00000010 // Enable ITD per default. The macro controlling the voice may still overwrite this
// setting
#define SND_EMITTER_HARDSTART \
0x00000020 // By default continous emitters are quickly faded in at startup to avoid pop sounds at
// restart. This disables this behavior
#define SND_EMITTER_NOSILENTSTART \
0x00000040 // Do not start emitter if the volume would be zero (it will be removed from the active
// list in this case)
//
// Setup / Change logical rooms
//
void sndSetup3DStudios(u8 first, u8 num);
bool sndAddRoom(SND_ROOM* room, SND_FVECTOR* pos, void (*activateReverb)(u8 studio, void* para),
void (*deActivateReverb)(u8 studio));
bool sndRemoveRoom(SND_ROOM* room);
bool sndUpdateRoom(SND_ROOM* room, SND_FVECTOR* pos);
bool sndAddDoor(SND_DOOR* door, SND_ROOM* a, SND_ROOM* b, SND_FVECTOR* pos, f32 dampen, f32 open,
u8 fxVol, s16 filterCoef[4], u32 flags);
bool sndRemoveDoor(SND_DOOR* door);
//
// Functions to add emitters to logical rooms
//
SND_VOICEID sndAddEmitter(SND_EMITTER* em, SND_FVECTOR* pos, SND_FVECTOR* dir, f32 maxDis, f32 comp,
u32 flags, SND_FXID fxid, u8 maxVol, u8 minVol, SND_ROOM* room);
SND_VOICEID sndAddEmitterEx(SND_EMITTER* em_buffer, SND_FVECTOR* pos, SND_FVECTOR* dir, f32 maxDis,
f32 comp, u32 flags, SND_FXID fxid, u16 groupid, u8 maxVol, u8 minVol,
SND_ROOM* room);
SND_VOICEID sndAddEmitterPara(SND_EMITTER* em, SND_FVECTOR* pos, SND_FVECTOR* dir, f32 maxDis,
f32 comp, u32 flags, SND_FXID fxid, u8 maxVol, u8 minVol,
SND_ROOM* room, SND_PARAMETER_INFO* para);
SND_VOICEID sndAddEmitterParaEx(SND_EMITTER* em_buffer, SND_FVECTOR* pos, SND_FVECTOR* dir,
f32 maxDis, f32 comp, u32 flags, SND_FXID fxid, u16 groupid,
u8 maxVol, u8 minVol, SND_ROOM* room, SND_PARAMETER_INFO* para);
//
// Listener related functions
//
bool sndAddListener(SND_LISTENER* li, SND_FVECTOR* pos, SND_FVECTOR* dir, SND_FVECTOR* heading,
SND_FVECTOR* up, f32 front_sur, f32 back_sur, f32 soundSpeed, u32 flags, u8 vol,
SND_ROOM* room);
bool sndAddListenerEx(SND_LISTENER* li, SND_FVECTOR* pos, SND_FVECTOR* dir, SND_FVECTOR* heading,
SND_FVECTOR* up, f32 front_sur, f32 back_sur, f32 soundSpeed,
f32 volPosOffset, u32 flags, u8 vol, SND_ROOM* room);
bool sndUpdateListener(SND_LISTENER* li, SND_FVECTOR* pos, SND_FVECTOR* dir, SND_FVECTOR* heading,
SND_FVECTOR* up, u8 vol, SND_ROOM* room);
bool sndRemoveListener(SND_LISTENER* li);
//
// Functions to add emitters directly to a studio
//
SND_VOICEID sndAddEmitter2Studio(SND_EMITTER* em, SND_FVECTOR* pos, SND_FVECTOR* dir, f32 maxDis,
f32 comp, u32 flags, SND_FXID fxid, u8 maxVol, u8 minVol,
u8 studio);
SND_VOICEID sndAddEmitter2StudioEx(SND_EMITTER* em_buffer, SND_FVECTOR* pos, SND_FVECTOR* dir,
f32 maxDis, f32 comp, u32 flags, SND_FXID fxid, u16 groupid,
u8 maxVol, u8 minVol, u8 studio);
SND_VOICEID sndAddEmitter2StudioPara(SND_EMITTER* em, SND_FVECTOR* pos, SND_FVECTOR* dir,
f32 maxDis, f32 comp, u32 flags, SND_FXID fxid, u8 maxVol,
u8 minVol, u8 studio, SND_PARAMETER_INFO* para);
SND_VOICEID sndAddEmitter2StudioParaEx(SND_EMITTER* em_buffer, SND_FVECTOR* pos, SND_FVECTOR* dir,
f32 maxDis, f32 comp, u32 flags, SND_FXID fxid, u16 groupid,
u8 maxVol, u8 minVol, u8 studio, SND_PARAMETER_INFO* para);
//
// Maintain emitters
//
bool sndUpdateEmitter(SND_EMITTER* em, SND_FVECTOR* pos, SND_FVECTOR* dir, u8 maxVol,
SND_ROOM* room);
bool sndRemoveEmitter(SND_EMITTER* em);
//
// Misc. 3D functions
//
bool sndCheckEmitter(SND_EMITTER* em);
SND_VOICEID sndEmitterVoiceID(SND_EMITTER* em);
typedef struct SND_3DINFO {
u8 vol;
u8 pan;
u8 span;
u16 doppler;
} SND_3DINFO;
void sndGet3DParameters(SND_3DINFO* info, SND_FVECTOR* pos, SND_FVECTOR* dir, f32 maxDis, f32 comp,
u8 maxVol, u8 minVol, SND_ROOM* room);
// ------------------------- Debug Functions -----------------------
u8 sndDbgGetActiveVoices(void);
void* sndConvert32BitSDIRTo64BitSDIR(void* sdir_int);
#ifdef __cplusplus
}
#endif
#endif // _MUSYX_MUSYX

View File

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

View File

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

View File

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

View File

@ -1,271 +0,0 @@
#ifndef _MUSYX_SEQ
#define _MUSYX_SEQ
#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
u32 tTab; // offset 0x0, size 0x4
u32 pTab; // offset 0x4, size 0x4
u32 tmTab; // offset 0x8, size 0x4
u32 mTrack; // offset 0xC, size 0x4
u32 info; // offset 0x10, size 0x4
u32 loopPoint[16]; // offset 0x14, size 0x40
u32 tsTab; // offset 0x54, size 0x4
} ARR;
#define ARR_GET(arr, offset) ((void*)(offset + (uintptr_t)arr))
#define ARR_GET_TYPE(arr, offset, ty) ((ty)ARR_GET(arr, offset))
typedef struct TENTRY {
// total size: 0xC
u32 time; // offset 0x0, size 0x4
u8 prgChange; // offset 0x4, size 0x1
u8 velocity; // offset 0x5, size 0x1
u8 res[2]; // offset 0x6, size 0x2
u16 pattern; // offset 0x8, size 0x2
s8 transpose; // offset 0xA, size 0x1
s8 velocityAdd; // offset 0xB, size 0x1
} TENTRY;
typedef struct TRACK {
// total size: 0x8
struct TENTRY* base; // offset 0x0, size 0x4
struct TENTRY* addr; // offset 0x4, size 0x4
} TRACK;
typedef struct NOTE {
// total size: 0x14
struct NOTE* next; // offset 0x0, size 0x4
struct NOTE* prev; // offset 0x4, size 0x4
u32 id; // offset 0x8, size 0x4
s32 endTime; // offset 0xC, size 0x4
u8 section; // offset 0x10, size 0x1
u8 timeIndex; // offset 0x11, size 0x1
u8 reserved[2]; // offset 0x12, size 0x2
} NOTE;
typedef struct NOTE_DATA {
// total size: 0x6
u16 time; // offset 0x0, size 0x2
u8 key; // offset 0x2, size 0x1
u8 velocity; // offset 0x3, size 0x1
u16 length; // offset 0x4, size 0x2
} NOTE_DATA;
typedef struct PRG_STATE {
// total size: 0x4 (>=2.0: 0x6)
u16 macId; // offset 0x0, size 0x2
u8 priority; // offset 0x2, size 0x1
u8 maxVoices; // offset 0x3, size 0x1
#if MUSY_VERSION >= MUSY_VERSION_CHECK(2, 0, 1)
u8 program; // offset 0x4, size 0x1
#endif
} PRG_STATE;
typedef struct SEQ_STREAM {
// total size: 0xC
u8* nextAddr; // offset 0x0, size 0x4
u16 value; // offset 0x4, size 0x2
s16 nextDelta; // offset 0x6, size 0x2
u32 nextTime; // offset 0x8, size 0x4
} SEQ_STREAM;
typedef struct CPAT {
// total size: 0x2C
u32 lTime; // offset 0x0, size 0x4
u32 baseTime; // offset 0x4, size 0x4
NOTE_DATA* addr; // offset 0x8, size 0x4
TENTRY* patternInfo; // offset 0xC, size 0x4
SEQ_STREAM pitchBend; // offset 0x10, size 0xC
SEQ_STREAM modulation; // offset 0x1C, size 0xC
u8 midi; // offset 0x28, size 0x1
} CPAT;
typedef struct SEQ_EVENT {
// total size: 0x18
struct SEQ_EVENT* next; // offset 0x0, size 0x4
struct SEQ_EVENT* prev; // offset 0x4, size 0x4
u32 time; // offset 0x8, size 0x4
union evInfo {
TENTRY* trackAddr;
struct {
// total size: 0x8
NOTE_DATA* addr; // offset 0x0, size 0x4
CPAT* base; // offset 0x4, size 0x4
} pattern;
} info; // offset 0xC, size 0x8
u8 type; // offset 0x14, size 0x1
u8 trackId; // offset 0x15, size 0x1
} SEQ_EVENT;
typedef struct MTRACK_DATA {
// total size: 0x8
volatile u32 time; // offset 0x0, size 0x4
u32 bpm; // offset 0x4, size 0x4
} MTRACK_DATA;
typedef struct MTRACK {
// total size: 0x8
MTRACK_DATA* base; // offset 0x0, size 0x4
MTRACK_DATA* addr; // offset 0x4, size 0x4
} MTRACK;
typedef struct TICKS {
// total size: 0x8
u32 low; // offset 0x0, size 0x4
s32 high; // offset 0x4, size 0x4
} TICKS;
typedef struct SEQ_SECTION {
// total size: 0x38
MTRACK mTrack; // offset 0x0, size 0x8
u32 bpm; // offset 0x8, size 0x4
TICKS tickDelta[2]; // offset 0xC, size 0x10
SEQ_EVENT* globalEventRoot; // offset 0x1C, size 0x4
TICKS time[2]; // offset 0x20, size 0x10
u8 timeIndex; // offset 0x30, size 0x1
u16 speed; // offset 0x32, size 0x2
u16 loopCnt; // offset 0x34, size 0x2
u8 loopDisable; // offset 0x36, size 0x1
} SEQ_SECTION;
typedef struct SEQ_INSTANCE {
// total size: 0x1868
struct SEQ_INSTANCE* next; // offset 0x0, size 0x4
struct SEQ_INSTANCE* prev; // offset 0x4, size 0x4
u8 state; // offset 0x8, size 0x1
u8 index; // offset 0x9, size 0x1
u16 groupID; // offset 0xA, size 0x2
u32 publicId; // offset 0xC, size 0x4
PAGE* normtab; // offset 0x10, size 0x4
u8 normTrans[128]; // offset 0x14, size 0x80
PAGE* drumtab; // offset 0x94, size 0x4
u8 drumTrans[128]; // offset 0x98, size 0x80
ARR* arrbase; // offset 0x118, size 0x4
u32 trackMute[2]; // offset 0x11C, size 0x8
TRACK track[64]; // offset 0x124, size 0x200
u8 trackVolGroup[64]; // offset 0x324, size 0x40
CPAT pattern[64]; // offset 0x364, size 0xB00
NOTE* noteUsed[2]; // offset 0xE64, size 0x8
NOTE* noteKeyOff; // offset 0xE6C, size 0x4
PRG_STATE prgState[16]; // offset 0xE70, size 0x40
u8 defVGroup; // offset 0xEB0, size 0x1
SND_CROSSFADE syncCrossInfo; // offset 0xEB4, size 0x28
u32* syncSeqIdPtr; // offset 0xEDC, size 0x4
u8 syncActive; // offset 0xEE0, size 0x1
u8 defStudio; // offset 0xEE1, size 0x1
u8 keyOffCheck; // offset 0xEE2, size 0x1
SEQ_EVENT event[64]; // offset 0xEE4, size 0x600
u8* trackSectionTab; // offset 0x14E4, size 0x4
SEQ_SECTION section[16]; // offset 0x14E8, size 0x380
} SEQ_INSTANCE;
typedef struct SEQ_PATTERN {
// total size: 0x10
u32 headerLen; // offset 0x0, size 0x4
u32 pitchBend; // offset 0x4, size 0x4
u32 modulation; // offset 0x8, size 0x4
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 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();
void seqHandle(u32 deltaTime);
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
#endif // _MUSYX_SEQ

View File

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

View File

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

View File

@ -1,334 +0,0 @@
#ifndef _MUSYX_SYNTH
#define _MUSYX_SYNTH
#include "musyx/musyx.h"
#include "musyx/adsr.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];
extern void* synthAuxAUser[8];
extern SND_AUX_CALLBACK synthAuxBCallback[8];
extern u8 synthAuxBMIDI[8];
extern u8 synthAuxBMIDISet[8];
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 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);
void synthHandle(u32 deltaTime);
bool synthFXSetCtrl(SND_VOICEID vid, u8 ctrl, u8 value);
bool synthFXSetCtrl14(SND_VOICEID vid, u8 ctrl, u16 value);
bool synthSendKeyOff(SND_VOICEID vid);
SND_VOICEID synthFXStart(u16 fid, u8 vol, u8 pan, u8 studio, u32 itd);
void synthVolume(u8 volume, u16 time, u8 vGroup, u8 seqMode, u32 seqId);
u32 synthStartSound(u16 id, u8 prio, u8 max,
#if MUSY_VERSION >= MUSY_VERSION_CHECK(2, 0, 1)
u32 sourceID,
#endif
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);
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);
void synthKillAllVoices(bool8 musiconly);
void synthKeyStateUpdate(SYNTH_VOICE* svoice);
bool synthAddStudioInput(u8 studio, SND_STUDIO_INPUT* in_desc);
bool synthRemoveStudioInput(u8 studio, SND_STUDIO_INPUT* in_desc);
u32 synthGetTicksPerSecond(SYNTH_VOICE* svoice);
#ifdef __cplusplus
}
#endif
#endif // _MUSYX_SYNTH

View File

@ -1,18 +0,0 @@
#ifndef _MUSYX_SYNTH_DBTAB
#define _MUSYX_SYNTH_DBTAB
#include "musyx/musyx.h"
#ifdef __cplusplus
extern "C" {
#endif
extern u16 dspAttenuationTab[194];
extern u8 dspScale2IndexTab[1024];
extern float dspDLSVolTab[129];
#ifdef __cplusplus
}
#endif
#endif // _MUSYX_SYNTH_DBTAB

View File

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

View File

@ -1,49 +0,0 @@
#ifndef _MUSYX_TXWIN
#define _MUSYX_TXWIN
#include <dolphin/types.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct STRUCT_WIN {
s32 x1;
s32 y1;
s32 x2;
s32 y2;
char* caption;
u32 flags;
s32 curr_x;
s32 curr_y;
s32 pixel_width;
s32 pixel_height;
s32 char_width;
s32 char_height;
u16 num_lines;
char** buffer;
u16 total_lines;
u16 curr_output_line;
u16 curr_view_line;
void (*refresh)();
struct STRUCT_WIN* next;
struct STRUCT_WIN* prev;
} sWIN;
void winInit(void);
void winRefresh(void);
void winLogPrintf(sWIN* handle, char* fmt, ...);
void winPrintfXY(sWIN* handle, s16 char_x, s16 char_y, char* fmt, ...);
void winClearLogWindow(sWIN* handle);
void winSetFontSize(u16 size);
sWIN* winOpenLogWindow(s32 x1, s32 y1, s32 x2, s32 y2, char* caption, u16 num_lines, u32 flags);
sWIN* winOpenWindow(s32 x1, s32 y1, s32 x2, s32 y2, char* caption, void* func, u32 flags);
// WXOpenWindow();
#ifdef __cpluplus
}
#endif // __cpluplus
#endif // _MUSYX_TXWIN

View File

@ -1,32 +0,0 @@
#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))
#endif
#ifndef MUSY_VERSION_MAJOR
#define MUSY_VERSION_MAJOR 2
#endif
#ifndef MUSY_VERSION_MINOR
#define MUSY_VERSION_MINOR 0
#endif
#ifndef MUSY_VERSION_PATCH
#define MUSY_VERSION_PATCH 0
#endif
#ifndef MUSY_VERSION
#define MUSY_VERSION MUSY_VERSION_CHECK(MUSY_VERSION_MAJOR, MUSY_VERSION_MINOR, MUSY_VERSION_PATCH)
#endif
#endif // _MUSYX_VERSION

View File

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

View File

@ -1,440 +0,0 @@
/* ---------------------------------------
---------------------------------------
*/
#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));
while (dl->outPoint < 0) {
dl->outPoint += dl->length;
}
}
static void DLcreate(_SND_REVSTD_DELAYLINE* dl, s32 len) {
dl->length = (s32)len * sizeof(f32);
dl->inputs = (f32*)salMalloc(len * sizeof(f32));
memset(dl->inputs, 0, len * sizeof(len));
dl->lastOutput = 0.f;
DLsetdelay(dl, len >> 1);
dl->inPoint = 0;
dl->outPoint = 0;
}
static void DLdelete(_SND_REVSTD_DELAYLINE* dl) { salFree(dl->inputs); }
bool ReverbSTDCreate(_SND_REVSTD_WORK* rv, float coloration, float time, float mix, float damping,
float predelay) {
static u32 lens[4] = {1789, 1999, 433, 149};
u8 i; // r31
u8 k; // r29
if ((coloration < 0.f || coloration > 1.f) || (time < .01f || time > 10.f) ||
(mix < 0.f || mix > 1.f) || (damping < 0.f || damping > 1.f) ||
(predelay < 0.f || predelay > 0.1f)) {
return FALSE;
}
memset(rv, 0, sizeof(_SND_REVSTD_WORK));
for (k = 0; k < 3; ++k) {
for (i = 0; i < 2; ++i) {
DLcreate(&rv->C[i + k * 2], lens[i] + 2);
DLsetdelay(&rv->C[i + k * 2], lens[i]);
rv->combCoef[i + k * 2] = powf(10.f, (int)(lens[i] * -3) / (time * 32000.f));
}
for (i = 0; i < 2; ++i) {
DLcreate(&rv->AP[i + k * 2], lens[i + 2] + 2);
DLsetdelay(&rv->AP[i + k * 2], lens[i + 2]);
}
rv->lpLastout[k] = 0.f;
}
rv->allPassCoeff = coloration;
rv->level = mix;
rv->damping = damping;
if (rv->damping < 0.05f) {
rv->damping = 0.05f;
}
rv->damping = 1.f - (rv->damping * 0.8f + 0.05f);
if (predelay != 0.f) {
rv->preDelayTime = (int)(predelay * 32000.f);
for (k = 0; k < 3; ++k) {
rv->preDelayLine[k] = salMalloc(rv->preDelayTime << 2);
memset(rv->preDelayLine[k], 0, rv->preDelayTime << 2);
rv->preDelayPtr[k] = rv->preDelayLine[k];
}
} else {
rv->preDelayTime = 0;
for (k = 0; k < 3; ++k) {
rv->preDelayPtr[k] = NULL;
rv->preDelayLine[k] = NULL;
}
}
return TRUE;
}
bool ReverbSTDModify(_SND_REVSTD_WORK* rv, float coloration, float time, float mix, float damping,
float predelay) {
unsigned char i; // r31
if ((coloration < 0.f || coloration > 1.f) || (time < .01f || time > 10.f) ||
(mix < 0.f || mix > 1.f) || (damping < 0.f || damping > 1.f) ||
(predelay < 0.f || predelay > 0.1f)) {
return FALSE;
}
rv->allPassCoeff = coloration;
rv->level = mix;
rv->damping = damping;
if (rv->damping < 0.05f) {
rv->damping = 0.05;
}
rv->damping = 1.f - (rv->damping * 0.8f + 0.05f);
for (i = 0; i < 6; ++i) {
DLdelete(&rv->AP[i]);
}
for (i = 0; i < 6; ++i) {
DLdelete(&rv->C[i]);
}
if (rv->preDelayTime != 0) {
for (i = 0; i < 3; ++i) {
salFree(rv->preDelayLine[i]);
}
}
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;
static asm void HandleReverb(long* sptr, struct _SND_REVSTD_WORK* rv) {
#if 1
nofralloc
stwu r1, -0x90(r1)
stmw r17, 8(r1)
stfd f14, 0x58(r1)
stfd f15, 0x60(r1)
stfd f16, 0x68(r1)
stfd f17, 0x70(r1)
stfd f18, 0x78(r1)
stfd f19, 0x80(r1)
stfd f20, 0x88(r1)
lis r31, value0_3@ha
lfs f6, value0_3@l(r31)
lis r31, value0_6@ha
lfs f9, value0_6@l(r31)
lis r31, i2fMagic@ha
lfd f5, i2fMagic@l(r31)
lfs f2, 0xf0(r4)
lfs f11, 0x11c(r4)
lfs f8, 0x118(r4)
fmuls f3, f8, f9
fsubs f4, f9, f3
lis r30, 0x4330
stw r30, 0x50(r1)
li r5, 0
lbl_803B56C8:
slwi r31, r5, 3
add r31, r31, r4
lfs f19, 0xf4(r31)
lfs f20, 0xf8(r31)
slwi r31, r5, 2
add r31, r31, r4
lfs f7, 0x10c(r31)
lwz r27, 0x124(r31)
lwz r28, 0x130(r31)
lwz r31, 0x120(r4)
addi r22, r31, -1
slwi r22, r22, 2
add r22, r22, r27
cmpwi cr7, r31, 0
mulli r31, r5, 0x28
addi r29, r4, 0x78
add r29, r29, r31
addi r30, r4, 0
add r30, r30, r31
lwz r21, 0(r29)
lwz r20, 4(r29)
lwz r19, 0x14(r29)
lwz r18, 0x18(r29)
lfs f15, 0x10(r29)
lfs f16, 0x24(r29)
lwz r26, 8(r29)
lwz r25, 0x1c(r29)
lwz r7, 0xc(r29)
lwz r8, 0x20(r29)
lwz r12, 0(r30)
lwz r11, 4(r30)
lwz r10, 0x14(r30)
lwz r9, 0x18(r30)
lfs f17, 0x10(r30)
lfs f18, 0x24(r30)
lwz r24, 8(r30)
lwz r23, 0x1c(r30)
lwz r17, 0xc(r30)
lwz r6, 0x20(r30)
lwz r30, 0(r3)
xoris r30, r30, 0x8000
stw r30, 0x54(r1)
lfd f12, 0x50(r1)
fsubs f12, f12, f5
li r31, 0x9f
mtctr r31
lbl_803B5780:
fmr f13, f12
beq cr7, lbl_803B57A0
lfs f13, 0(r28)
addi r28, r28, 4
cmpw r28, r22
stfs f12, -4(r28)
bne+ lbl_803B57A0
mr r28, r27
lbl_803B57A0:
fmadds f8, f19, f15, f13
lwzu r29, 4(r3)
fmadds f9, f20, f16, f13
stfsx f8, r7, r21
addi r21, r21, 4
stfsx f9, r8, r19
lfsx f14, r7, r20
addi r20, r20, 4
lfsx f16, r8, r18
cmpw r21, r26
cmpw cr1, r20, r26
addi r19, r19, 4
addi r18, r18, 4
fmr f15, f14
cmpw cr5, r19, r25
fadds f14, f14, f16
cmpw cr6, r18, r25
bne+ lbl_803B57EC
li r21, 0
lbl_803B57EC:
xoris r29, r29, 0x8000
fmadds f9, f2, f17, f14
bne+ cr1, lbl_803B57FC
li r20, 0
lbl_803B57FC:
stw r29, 0x54(r1)
bne+ cr5, lbl_803B5808
li r19, 0
lbl_803B5808:
stfsx f9, r17, r12
fnmsubs f14, f2, f9, f17
addi r12, r12, 4
bne+ cr6, lbl_803B581C
li r18, 0
lbl_803B581C:
lfsx f17, r17, r11
cmpw cr5, r12, r24
addi r11, r11, 4
cmpw cr6, r11, r24
bne+ cr5, lbl_803B5834
li r12, 0
lbl_803B5834:
bne+ cr6, lbl_803B583C
li r11, 0
lbl_803B583C:
fmuls f14, f14, f6
lfd f10, 0x50(r1)
fmadds f14, f11, f7, f14
fmadds f9, f2, f18, f14
fmr f7, f14
stfsx f9, r6, r10
fnmsubs f14, f2, f9, f18
fmuls f8, f4, f12
lfsx f18, r6, r9
addi r10, r10, 4
addi r9, r9, 4
fmadds f14, f3, f14, f8
cmpw cr5, r10, r23
cmpw cr6, r9, r23
fctiwz f14, f14
bne+ cr5, lbl_803B5880
li r10, 0
lbl_803B5880:
bne+ cr6, lbl_803B5888
li r9, 0
lbl_803B5888:
li r31, -4
fsubs f12, f10, f5
stfiwx f14, r3, r31
bdnz lbl_803B5780
fmr f13, f12
beq cr7, lbl_803B58B8
lfs f13, 0(r28)
addi r28, r28, 4
cmpw r28, r22
stfs f12, -4(r28)
bne+ lbl_803B58B8
mr r28, r27
lbl_803B58B8:
fmadds f8, f19, f15, f13
fmadds f9, f20, f16, f13
stfsx f8, r7, r21
addi r21, r21, 4
stfsx f9, r8, r19
lfsx f14, r7, r20
addi r20, r20, 4
lfsx f16, r8, r18
cmpw r21, r26
cmpw cr1, r20, r26
addi r19, r19, 4
addi r18, r18, 4
fmr f15, f14
cmpw cr5, r19, r25
fadds f14, f14, f16
cmpw cr6, r18, r25
bne+ lbl_803B5900
li r21, 0
lbl_803B5900:
fmadds f9, f2, f17, f14
bne+ cr1, lbl_803B590C
li r20, 0
lbl_803B590C:
bne+ cr5, lbl_803B5914
li r19, 0
lbl_803B5914:
stfsx f9, r17, r12
fnmsubs f14, f2, f9, f17
addi r12, r12, 4
bne+ cr6, lbl_803B5928
li r18, 0
lbl_803B5928:
lfsx f17, r17, r11
cmpw cr5, r12, r24
addi r11, r11, 4
cmpw cr6, r11, r24
bne+ cr5, lbl_803B5940
li r12, 0
lbl_803B5940:
bne+ cr6, lbl_803B5948
li r11, 0
lbl_803B5948:
fmuls f14, f14, f6
fmadds f14, f11, f7, f14
mulli r31, r5, 0x28
fmadds f9, f2, f18, f14
fmr f7, f14
addi r29, r4, 0x78
add r29, r29, r31
stfsx f9, r6, r10
fnmsubs f14, f2, f9, f18
fmuls f8, f4, f12
lfsx f18, r6, r9
addi r10, r10, 4
addi r9, r9, 4
fmadds f14, f3, f14, f8
cmpw cr5, r10, r23
cmpw cr6, r9, r23
fctiwz f14, f14
bne+ cr5, lbl_803B5994
li r10, 0
lbl_803B5994:
bne+ cr6, lbl_803B599C
li r9, 0
lbl_803B599C:
addi r30, r4, 0
add r30, r30, r31
stfiwx f14, r0, r3
stw r21, 0(r29)
stw r20, 4(r29)
stw r19, 0x14(r29)
stw r18, 0x18(r29)
addi r3, r3, 4
stfs f15, 0x10(r29)
stfs f16, 0x24(r29)
slwi r31, r5, 2
add r31, r31, r4
addi r5, r5, 1
stw r12, 0(r30)
stw r11, 4(r30)
stw r10, 0x14(r30)
stw r9, 0x18(r30)
cmpwi r5, 3
stfs f17, 0x10(r30)
stfs f18, 0x24(r30)
stfs f7, 0x10c(r31)
stw r28, 0x130(r31)
bne lbl_803B56C8
lfd f14, 0x58(r1)
lfd f15, 0x60(r1)
lfd f16, 0x68(r1)
lfd f17, 0x70(r1)
lfd f18, 0x78(r1)
lfd f19, 0x80(r1)
lfd f20, 0x88(r1)
lmw r17, 8(r1)
addi r1, r1, 0x90
blr
#endif
}
#else
static void HandleReverb(s32* 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);
}
void ReverbSTDFree(_SND_REVSTD_WORK* rv) {
u8 i; // r31
for (i = 0; i < 6; ++i) {
DLdelete(&rv->AP[i]);
}
for (i = 0; i < 6; ++i) {
DLdelete(&rv->C[i]);
}
if (rv->preDelayTime != 0) {
for (i = 0; i < 3; ++i) {
salFree(rv->preDelayLine[i]);
}
}
}

View File

@ -1,56 +0,0 @@
/* ---------------------------------------
---------------------------------------
*/
#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 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);
void sndAuxCallbackReverbSTD(u8 reason, SND_AUX_INFO* info, void* user) {
switch (reason) {
case SND_AUX_REASON_BUFFERUPDATE:
if ((u8)((SND_AUX_REVERBSTD*)user)->tempDisableFX == 0) {
ReverbSTDCallback(info->data.bufferUpdate.left, info->data.bufferUpdate.right,
info->data.bufferUpdate.surround, &((SND_AUX_REVERBSTD*)user)->rv);
}
break;
case SND_AUX_REASON_PARAMETERUPDATE:
// UNIMPLEMENTED
break;
default:
MUSY_ASSERT(FALSE);
break;
}
}
bool sndAuxCallbackUpdateSettingsReverbSTD(SND_AUX_REVERBSTD* rev) {
rev->tempDisableFX = TRUE;
ReverbSTDModify(&rev->rv, rev->coloration, rev->time, rev->mix, rev->damping, rev->preDelay);
rev->tempDisableFX = FALSE;
return TRUE;
}
bool sndAuxCallbackPrepareReverbSTD(SND_AUX_REVERBSTD* rev) {
rev->tempDisableFX = 0;
return ReverbSTDCreate(&rev->rv, rev->coloration, rev->time, rev->mix, rev->damping,
rev->preDelay);
}
bool sndAuxCallbackShutdownReverbSTD(SND_AUX_REVERBSTD* rev) {
ReverbSTDFree(&rev->rv);
return TRUE;
}

View File

@ -1,665 +0,0 @@
#include "musyx/musyx.h"
#include "musyx/sal.h"
#include "musyx/assert.h"
static float rsmpTab12khz[512] = {
0.097503662109f, 0.802215576172f, 0.101593017578f, -0.000976562500f, 0.093505859375f,
0.802032470703f, 0.105804443359f, -0.001037597656f, 0.089599609375f, 0.801696777344f,
0.110107421875f, -0.001159667969f, 0.085784912109f, 0.801177978516f, 0.114471435547f,
-0.001281738281f, 0.082031250000f, 0.800476074219f, 0.118927001953f, -0.001403808594f,
0.078369140625f, 0.799621582031f, 0.123474121094f, -0.001525878906f, 0.074798583984f,
0.798614501953f, 0.128143310547f, -0.001647949219f, 0.071350097656f, 0.797424316406f,
0.132873535156f, -0.001770019531f, 0.067962646484f, 0.796051025391f, 0.137695312500f,
-0.001922607422f, 0.064697265625f, 0.794525146484f, 0.142608642578f, -0.002044677734f,
0.061492919922f, 0.792846679688f, 0.147613525391f, -0.002197265625f, 0.058349609375f,
0.790985107422f, 0.152709960938f, -0.002319335938f, 0.055328369141f, 0.788940429688f,
0.157897949219f, -0.002471923828f, 0.052368164062f, 0.786743164062f, 0.163177490234f,
-0.002655029297f, 0.049499511719f, 0.784423828125f, 0.168518066406f, -0.002807617188f,
0.046722412109f, 0.781890869141f, 0.173980712891f, -0.002990722656f, 0.044006347656f,
0.779205322266f, 0.179504394531f, -0.003143310547f, 0.041412353516f, 0.776367187500f,
0.185119628906f, -0.003326416016f, 0.038879394531f, 0.773376464844f, 0.190826416016f,
-0.003509521484f, 0.036407470703f, 0.770233154297f, 0.196594238281f, -0.003692626953f,
0.034027099609f, 0.766937255859f, 0.202484130859f, -0.003875732422f, 0.031738281250f,
0.763488769531f, 0.208435058594f, -0.004058837891f, 0.029510498047f, 0.759857177734f,
0.214447021484f, -0.004272460938f, 0.027374267578f, 0.756103515625f, 0.220550537109f,
-0.004455566406f, 0.025299072266f, 0.752197265625f, 0.226745605469f, -0.004669189453f,
0.023315429688f, 0.748168945312f, 0.233001708984f, -0.004852294922f, 0.021392822266f,
0.743988037109f, 0.239318847656f, -0.005065917969f, 0.019561767578f, 0.739654541016f,
0.245727539062f, -0.005310058594f, 0.017791748047f, 0.735198974609f, 0.252197265625f,
-0.005523681641f, 0.016052246094f, 0.730590820312f, 0.258728027344f, -0.005706787109f,
0.014404296875f, 0.725860595703f, 0.265350341797f, -0.005920410156f, 0.012817382812f,
0.721008300781f, 0.272033691406f, -0.006164550781f, 0.011322021484f, 0.716003417969f,
0.278778076172f, -0.006378173828f, 0.009887695312f, 0.710906982422f, 0.285583496094f,
-0.006561279297f, 0.008514404297f, 0.705657958984f, 0.292449951172f, -0.006774902344f,
0.007202148438f, 0.700317382812f, 0.299346923828f, -0.007019042969f, 0.005920410156f,
0.694854736328f, 0.306335449219f, -0.007232666016f, 0.004699707031f, 0.689270019531f,
0.313385009766f, -0.007415771484f, 0.003570556641f, 0.683563232422f, 0.320465087891f,
-0.007629394531f, 0.002471923828f, 0.677734375000f, 0.327606201172f, -0.007873535156f,
0.001434326172f, 0.671844482422f, 0.334777832031f, -0.008087158203f, 0.000457763672f,
0.665832519531f, 0.341979980469f, -0.008270263672f, -0.000488281250f, 0.659729003906f,
0.349243164062f, -0.008453369141f, -0.001342773438f, 0.653533935547f, 0.356567382812f,
-0.008636474609f, -0.002166748047f, 0.647216796875f, 0.363891601562f, -0.008850097656f,
-0.002960205078f, 0.640838623047f, 0.371276855469f, -0.009033203125f, -0.003692626953f,
0.634338378906f, 0.378692626953f, -0.009216308594f, -0.004364013672f, 0.627777099609f,
0.386138916016f, -0.009338378906f, -0.004974365234f, 0.621154785156f, 0.393615722656f,
-0.009490966797f, -0.005584716797f, 0.614440917969f, 0.401092529297f, -0.009643554688f,
-0.006134033203f, 0.607635498047f, 0.408599853516f, -0.009796142578f, -0.006652832031f,
0.600769042969f, 0.416107177734f, -0.009918212891f, -0.007141113281f, 0.593841552734f,
0.423645019531f, -0.010009765625f, -0.007568359375f, 0.586853027344f, 0.431213378906f,
-0.010131835938f, -0.007965087891f, 0.579772949219f, 0.438751220703f, -0.010223388672f,
-0.008331298828f, 0.572662353516f, 0.446319580078f, -0.010284423828f, -0.008666992188f,
0.565521240234f, 0.453887939453f, -0.010345458984f, -0.008972167969f, 0.558319091797f,
0.461456298828f, -0.010406494141f, -0.009216308594f, 0.551055908203f, 0.469024658203f,
-0.010406494141f, -0.009460449219f, 0.543731689453f, 0.476593017578f, -0.010406494141f,
-0.009674072266f, 0.536407470703f, 0.484130859375f, -0.010375976562f, -0.009857177734f,
0.529022216797f, 0.491668701172f, -0.010375976562f, -0.010009765625f, 0.521606445312f,
0.499176025391f, -0.010314941406f, -0.010131835938f, 0.514160156250f, 0.506683349609f,
-0.010253906250f, -0.010253906250f, 0.506683349609f, 0.514160156250f, -0.010131835938f,
-0.010314941406f, 0.499176025391f, 0.521606445312f, -0.010009765625f, -0.010375976562f,
0.491668701172f, 0.529022216797f, -0.009857177734f, -0.010375976562f, 0.484130859375f,
0.536407470703f, -0.009674072266f, -0.010406494141f, 0.476593017578f, 0.543731689453f,
-0.009460449219f, -0.010406494141f, 0.469024658203f, 0.551055908203f, -0.009216308594f,
-0.010406494141f, 0.461456298828f, 0.558319091797f, -0.008972167969f, -0.010345458984f,
0.453887939453f, 0.565521240234f, -0.008666992188f, -0.010284423828f, 0.446319580078f,
0.572662353516f, -0.008331298828f, -0.010223388672f, 0.438751220703f, 0.579772949219f,
-0.007965087891f, -0.010131835938f, 0.431213378906f, 0.586853027344f, -0.007568359375f,
-0.010009765625f, 0.423645019531f, 0.593841552734f, -0.007141113281f, -0.009918212891f,
0.416107177734f, 0.600769042969f, -0.006652832031f, -0.009796142578f, 0.408599853516f,
0.607635498047f, -0.006134033203f, -0.009643554688f, 0.401092529297f, 0.614440917969f,
-0.005584716797f, -0.009490966797f, 0.393615722656f, 0.621154785156f, -0.004974365234f,
-0.009338378906f, 0.386138916016f, 0.627777099609f, -0.004364013672f, -0.009216308594f,
0.378692626953f, 0.634338378906f, -0.003692626953f, -0.009033203125f, 0.371276855469f,
0.640838623047f, -0.002960205078f, -0.008850097656f, 0.363891601562f, 0.647216796875f,
-0.002166748047f, -0.008636474609f, 0.356567382812f, 0.653533935547f, -0.001342773438f,
-0.008453369141f, 0.349243164062f, 0.659729003906f, -0.000488281250f, -0.008270263672f,
0.341979980469f, 0.665832519531f, 0.000457763672f, -0.008087158203f, 0.334777832031f,
0.671844482422f, 0.001434326172f, -0.007873535156f, 0.327606201172f, 0.677734375000f,
0.002471923828f, -0.007629394531f, 0.320465087891f, 0.683563232422f, 0.003570556641f,
-0.007415771484f, 0.313385009766f, 0.689270019531f, 0.004699707031f, -0.007232666016f,
0.306335449219f, 0.694854736328f, 0.005920410156f, -0.007019042969f, 0.299346923828f,
0.700317382812f, 0.007202148438f, -0.006774902344f, 0.292449951172f, 0.705657958984f,
0.008514404297f, -0.006561279297f, 0.285583496094f, 0.710906982422f, 0.009887695312f,
-0.006378173828f, 0.278778076172f, 0.716003417969f, 0.011322021484f, -0.006164550781f,
0.272033691406f, 0.721008300781f, 0.012817382812f, -0.005920410156f, 0.265350341797f,
0.725860595703f, 0.014404296875f, -0.005706787109f, 0.258728027344f, 0.730590820312f,
0.016052246094f, -0.005523681641f, 0.252197265625f, 0.735198974609f, 0.017791748047f,
-0.005310058594f, 0.245727539062f, 0.739654541016f, 0.019561767578f, -0.005065917969f,
0.239318847656f, 0.743988037109f, 0.021392822266f, -0.004852294922f, 0.233001708984f,
0.748168945312f, 0.023315429688f, -0.004669189453f, 0.226745605469f, 0.752197265625f,
0.025299072266f, -0.004455566406f, 0.220550537109f, 0.756103515625f, 0.027374267578f,
-0.004272460938f, 0.214447021484f, 0.759857177734f, 0.029510498047f, -0.004058837891f,
0.208435058594f, 0.763488769531f, 0.031738281250f, -0.003875732422f, 0.202484130859f,
0.766937255859f, 0.034027099609f, -0.003692626953f, 0.196594238281f, 0.770233154297f,
0.036407470703f, -0.003509521484f, 0.190826416016f, 0.773376464844f, 0.038879394531f,
-0.003326416016f, 0.185119628906f, 0.776367187500f, 0.041412353516f, -0.003143310547f,
0.179504394531f, 0.779205322266f, 0.044006347656f, -0.002990722656f, 0.173980712891f,
0.781890869141f, 0.046722412109f, -0.002807617188f, 0.168518066406f, 0.784423828125f,
0.049499511719f, -0.002655029297f, 0.163177490234f, 0.786743164062f, 0.052368164062f,
-0.002471923828f, 0.157897949219f, 0.788940429688f, 0.055328369141f, -0.002319335938f,
0.152709960938f, 0.790985107422f, 0.058349609375f, -0.002197265625f, 0.147613525391f,
0.792846679688f, 0.061492919922f, -0.002044677734f, 0.142608642578f, 0.794525146484f,
0.064697265625f, -0.001922607422f, 0.137695312500f, 0.796051025391f, 0.067962646484f,
-0.001770019531f, 0.132873535156f, 0.797424316406f, 0.071350097656f, -0.001647949219f,
0.128143310547f, 0.798614501953f, 0.074798583984f, -0.001525878906f, 0.123474121094f,
0.799621582031f, 0.078369140625f, -0.001403808594f, 0.118927001953f, 0.800476074219f,
0.082031250000f, -0.001281738281f, 0.114471435547f, 0.801177978516f, 0.085784912109f,
-0.001159667969f, 0.110107421875f, 0.801696777344f, 0.089599609375f, -0.001037597656f,
0.105804443359f, 0.802032470703f, 0.093505859375f, -0.000976562500f, 0.101593017578f,
0.802215576172f, 0.097503662109f,
};
const double i2fMagic = 4.503601774854144E15;
#ifdef __MWERKS__
// clang-format off
static asm void do_src1(_SND_CHORUS_SRCINFO* src) {
nofralloc
stwu r1, -0x40(sp)
stmw r26, 0x28(sp)
lwz r4, 0xc(r3)
lwz r5, 0x10(r3)
lwz r6, 0x14(r3)
lwz r8, 0x1c(r3)
lwz r7, 0x20(r3)
lwz r31, 4(r3)
lwz r30, 0(r3)
lwz r9, 8(r3)
lis r10, 0x4330
stw r10, 8(sp)
stw r10, 0x10(sp)
stw r10, 0x18(sp)
stw r10, 0x20(sp)
lis r10, i2fMagic@ha
lfd f9, i2fMagic@l(r10)
slwi r10, r5, 2
lwz r11, 0(r9)
lwz r29, 4(r9)
lwz r28, 8(r9)
lwzx r27, r31, r10
xoris r11, r11, 0x8000
xoris r29, r29, 0x8000
stw r11, 0xc(sp)
xoris r28, r28, 0x8000
stw r29, 0x14(sp)
xoris r27, r27, 0x8000
stw r28, 0x1c(sp)
lfd f1, 8(sp)
stw r27, 0x24(sp)
lfd f2, 0x10(sp)
fsubs f1, f1, f9
lfd f3, 0x18(sp)
fsubs f2, f2, f9
lfd f4, 0x20(sp)
fsubs f3, f3, f9
fsubs f4, f4, f9
li r26, -4
lis r12, rsmpTab12khz@ha
addi r12, r12, rsmpTab12khz@l
li r9, 0xa0
mtctr r9
lbl_803B6D5C:
rlwinm r10, r4, 7, 0x15, 0x1b
addc r4, r4, r6
add r10, r10, r12
mcrxr cr0
lfs f5, 0(r10)
beq lbl_803B6DA4
lfs f6, 4(r10)
fmuls f10, f1, f5
lfs f7, 8(r10)
fmadds f10, f2, f6, f10
lfs f8, 0xc(r10)
fmadds f10, f3, f7, f10
addi r30, r30, 4
fmadds f10, f4, f8, f10
fctiwz f10, f10
stfiwx f10, r26, r30
bdnz lbl_803B6D5C
b lbl_803B6E10
lbl_803B6DA4:
addi r5, r5, 1
lfs f6, 4(r10)
fmuls f10, f1, f5
cmpw r5, r8
fmr f1, f2
lfs f7, 8(r10)
fmadds f10, f2, f6, f10
fmr f2, f3
lfs f8, 0xc(r10)
fmadds f10, f3, f7, f10
addi r30, r30, 4
fmr f3, f4
bne+ lbl_803B6DDC
mr r5, r7
lbl_803B6DDC:
fmadds f10, f4, f8, f10
slwi r9, r5, 2
bdz lbl_803B6E08
lwzx r10, r9, r31
fctiwz f10, f10
xoris r10, r10, 0x8000
stw r10, 0xc(sp)
stfiwx f10, r26, r30
lfd f4, 8(sp)
fsubs f4, f4, f9
b lbl_803B6D5C
lbl_803B6E08:
fctiwz f10, f10
stfiwx f10, r26, r30
lbl_803B6E10:
lwz r9, 8(r3)
fctiwz f1, f1
fctiwz f2, f2
fctiwz f3, f3
stfiwx f1, r0, r9
addi r10, r9, 4
stfiwx f2, r0, r10
addi r10, r9, 8
stfiwx f3, r0, r10
stw r4, 0xc(r3)
stw r5, 0x10(r3)
lmw r26, 0x28(sp)
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
#define pitchLoV r6
#define triggerV r8
#define targetV r7
#define oldPtr r9
#define destPtr r30
#define smpBasePtr r31
nofralloc;
/* Save stack state to stack */
stwu r1, -0x40(sp);
stmw r26, 0x28(sp);
lwz posLoV, src->posLo;
lwz posHiV, src->posHi;
lwz pitchLoV, src->pitchLo;
lwz triggerV, src->trigger;
lwz targetV, src->target;
lwz smpBasePtr, src->smpBase;
lwz destPtr, src->dest;
lwz oldPtr, src->old;
/* Store upper portion of int->float conversion constant */
lis r10, 0x4330;
stw r10, 0x08(sp);
stw r10, 0x10(sp);
stw r10, 0x18(sp);
stw r10, 0x20(sp);
lis r10, i2fMagic @ha;
lfd f9, i2fMagic @l(r10);
// posHi * 4
slwi r10, posHiV, 2;
lwz r11, 0(oldPtr);
lwz r29, 4(oldPtr);
lwz r28, 8(oldPtr);
lwzx r27, smpBasePtr, r10;
xoris r11, r11, 0x8000;
xoris r29, r29, 0x8000;
stw r11, 0xc(sp);
xoris r28, r28, 0x8000;
stw r29, 0x14(sp);
xoris r27, r27, 0x8000;
stw r28, 0x1c(sp);
lfd f1, 0x08(sp);
stw r27, 0x24(sp);
lfd f2, 0x10(sp);
fsubs f1, f1, f9;
lfd f3, 0x18(sp);
fsubs f2, f2, f9;
lfd f4, 0x20(sp);
fsubs f3, f3, f9;
fsubs f4, f4, f9;
/* Some offset? */
li r26, -4;
lis r12, rsmpTab12khz @ha;
addi r12, r12, rsmpTab12khz @l;
li r9, 0xa0;
mtctr r9;
lbl_803B6EF4:
rlwinm r10, posLoV, 7, 0x15, 0x1b;
addc posLoV, posLoV, pitchLoV;
add r10, r10, r12;
mcrxr cr0;
addi posHiV, posHiV, 1;
lfs f5, 0(r10);
beq lbl_803B6F70;
lfs f6, 4(r10);
fmuls f10, f1, f5;
cmpw posHiV, triggerV;
fmr f1, f2;
lfs f7, 8(r10);
fmadds f10, f2, f6, f10;
fmr f2, f3;
lfs f8, 0xc(r10);
fmadds f10, f3, f7, f10;
addi destPtr, destPtr, 4;
fmr f3, f4;
bne + lbl_803B6F44;
mr posHiV, targetV;
lbl_803B6F44:
fmadds f10, f4, f8, f10;
slwi r9, posHiV, 2;
bdz lbl_803B6FF4;
lwzx r10, r9, smpBasePtr;
fctiwz f10, f10;
xoris r10, r10, 0x8000;
stw r10, 0xc(sp);
stfiwx f10, r26, destPtr;
lfd f4, 8(sp);
fsubs f4, f4, f9;
b lbl_803B6EF4;
lbl_803B6F70:
cmpw posHiV, triggerV;
lfs f6, 4(r10);
bne + lbl_803B6F80;
mr posHiV, targetV;
lbl_803B6F80:
slwi r11, posHiV, 2;
addi posHiV, posHiV, 1;
lwzx r29, r11, smpBasePtr;
fmuls f10, f1, f5;
cmpw posHiV, triggerV;
xoris r29, r29, 0x8000;
fmr f1, f3;
lfs f7, 8(r10);
stw r29, 0xc(sp);
fmadds f10, f2, f6, f10;
lfs f8, 0xc(r10);
fmadds f10, f3, f7, f10;
lfd f3, 8(sp);
fmr f2, f4;
addi destPtr, destPtr, 4;
fsubs f3, f3, f9;
bne + lbl_803B6FC8;
mr posHiV, targetV;
lbl_803B6FC8:
fmadds f10, f4, f8, f10;
slwi r9, posHiV, 2;
bdz lbl_803B6FF4;
lwzx r10, r9, smpBasePtr;
fctiwz f10, f10;
xoris r10, r10, 0x8000;
stw r10, 0xc(sp);
stfiwx f10, r26, destPtr;
lfd f4, 8(sp);
fsubs f4, f4, f9;
b lbl_803B6EF4;
lbl_803B6FF4:
fctiwz f10, f10;
stfiwx f10, r26, destPtr;
lwz r9, 8(r3);
fctiwz f1, f1;
fctiwz f2, f2;
fctiwz f3, f3;
stfiwx f1, r0, r9;
addi r10, r9, 4;
stfiwx f2, r0, r10;
addi r10, r9, 8;
stfiwx f3, r0, r10;
stw posLoV, src->posLo;
stw posHiV, src->posHi;
/* Pop and restore LR to original values */
lmw r26, 0x28(sp);
addi r1, r1, 0x40;
blr;
#undef posLoV
#undef posHiV
#undef pitchLoV
#undef triggerV
#undef targetV
#undef oldPtr
#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;
s32 *leftD, *rightD, *surD, *leftS, *rightS, *surS;
u32 i;
u8 nextCurrentLast;
switch (reason) {
case SND_AUX_REASON_BUFFERUPDATE:
c = (SND_AUX_CHORUS*)user;
nextCurrentLast = (c->work.currentLast + 1) % 3;
leftD = c->work.lastLeft[nextCurrentLast];
rightD = c->work.lastRight[nextCurrentLast];
surD = c->work.lastSur[nextCurrentLast];
leftS = info->data.bufferUpdate.left;
rightS = info->data.bufferUpdate.right;
surS = info->data.bufferUpdate.surround;
for (i = 0; i < 160; ++i) {
*leftD = *leftS++;
leftD++;
*rightD = *rightS++;
rightD++;
*surD = *surS++;
surD++;
}
c->work.src.pitchHi = (c->work.pitchOffset >> 0x10) + 1;
c->work.src.pitchLo = ((c->work.pitchOffset & 0xFFFF) << 16);
if (--c->work.pitchOffsetPeriodCount == 0) {
c->work.pitchOffsetPeriodCount = c->work.pitchOffsetPeriod;
c->work.pitchOffset = -c->work.pitchOffset;
}
for (i = 0; i < 3; ++i) {
c->work.src.posHi = c->work.currentPosHi;
c->work.src.posLo = c->work.currentPosLo;
switch (i) {
case 0:
c->work.src.smpBase = c->work.lastLeft[0];
c->work.src.dest = info->data.bufferUpdate.left;
c->work.src.old = c->work.oldLeft;
break;
case 1:
c->work.src.smpBase = c->work.lastRight[0];
c->work.src.dest = info->data.bufferUpdate.right;
c->work.src.old = c->work.oldRight;
break;
case 2:
c->work.src.smpBase = c->work.lastSur[0];
c->work.src.dest = info->data.bufferUpdate.surround;
c->work.src.old = c->work.oldSur;
break;
}
switch (c->work.src.pitchHi) {
case 0:
do_src1(&c->work.src);
break;
case 1:
do_src2(&c->work.src);
break;
}
}
c->work.currentPosHi = c->work.src.posHi % 480;
c->work.currentPosLo = c->work.src.posLo;
c->work.currentLast = nextCurrentLast;
break;
case SND_AUX_REASON_PARAMETERUPDATE:
break;
default:
#line 957
MUSY_ASSERT(FALSE);
break;
}
}
bool sndAuxCallbackUpdateSettingsChorus(SND_AUX_CHORUS* ch) {
ch->work.currentPosHi = 0x140 - ((ch->baseDelay - 5) << 5);
ch->work.currentPosLo = 0;
ch->work.currentPosHi = (ch->work.currentPosHi + (ch->work.currentLast - 1) * 0xa0) % 0x1e0;
ch->work.pitchOffsetPeriod = (ch->period / 5) + 1 & ~1;
ch->work.pitchOffsetPeriodCount = (u32)ch->work.pitchOffsetPeriod >> 1;
ch->work.pitchOffset = (ch->variation << 16) / (ch->work.pitchOffsetPeriod * 5);
return TRUE;
}
bool sndAuxCallbackPrepareChorus(SND_AUX_CHORUS* chorus) {
u32 i;
s32* lastLeft;
s32* lastRight;
s32* lastSur;
chorus->work.lastLeft[0] = (s32*)salMalloc(0x1680);
if (chorus->work.lastLeft[0] != NULL) {
chorus->work.lastRight[0] = chorus->work.lastLeft[0] + 0x1e0;
chorus->work.lastSur[0] = chorus->work.lastRight[0] + 0x1e0;
for (i = 1; i < 3; ++i) {
chorus->work.lastLeft[i] = chorus->work.lastLeft[0] + i * 0xa0;
chorus->work.lastRight[i] = chorus->work.lastRight[0] + i * 0xa0;
chorus->work.lastSur[i] = chorus->work.lastSur[0] + i * 0xa0;
}
lastLeft = chorus->work.lastLeft[0];
lastRight = chorus->work.lastRight[0];
lastSur = chorus->work.lastSur[0];
for (i = 0; i < 0x140; i += 1) {
*lastLeft++ = 0;
*lastRight++ = 0;
*lastSur++ = 0;
}
chorus->work.currentLast = 1;
chorus->work.oldLeft[0] = chorus->work.oldLeft[1] = chorus->work.oldLeft[2] = chorus->work.oldLeft[3] = 0;
chorus->work.oldRight[0] = chorus->work.oldRight[1] = chorus->work.oldRight[2] = chorus->work.oldRight[3] = 0;
chorus->work.oldSur[0] = chorus->work.oldSur[1] = chorus->work.oldSur[2] = chorus->work.oldSur[3] = 0;
chorus->work.src.trigger = 480;
chorus->work.src.target = 0;
return sndAuxCallbackUpdateSettingsChorus(chorus);
}
return FALSE;
}
bool sndAuxCallbackShutdownChorus(SND_AUX_CHORUS* ch) {
salFree(ch->work.lastLeft[0]);
return TRUE;
}

View File

@ -1,118 +0,0 @@
/* ---------------------------------------
---------------------------------------
*/
#include "musyx/musyx.h"
#include "musyx/assert.h"
#include "musyx/sal.h"
void sndAuxCallbackDelay(u8 reason, SND_AUX_INFO* info, void* user) {
s32 l; // r30
s32 r; // r29
s32 s; // r28
s32* lBuf; // r27
s32* rBuf; // r26
s32* sBuf; // r25
u32 i; // r24
SND_AUX_DELAY* c; // r31
s32* left; // r23
s32* right; // r22
s32* sur; // r21
switch (reason) {
case SND_AUX_REASON_BUFFERUPDATE:
c = (SND_AUX_DELAY*)user;
left = info->data.bufferUpdate.left;
right = info->data.bufferUpdate.right;
sur = info->data.bufferUpdate.surround;
lBuf = c->left + (c->currentPos[0] * 160);
rBuf = c->right + (c->currentPos[1] * 160);
sBuf = c->sur + (c->currentPos[2] * 160);
for (i = 0; i < 160; ++i) {
l = *lBuf;
r = *rBuf;
s = *sBuf;
*lBuf++ = *left + ((s32)(l * c->currentFeedback[0]) >> 7);
*rBuf++ = *right + ((s32)(r * c->currentFeedback[1]) >> 7);
*sBuf++ = *sur + ((s32)(s * c->currentFeedback[2]) >> 7);
*left++ = (s32)(l * c->currentOutput[0]) >> 7;
*right++ = (s32)(r * c->currentOutput[1]) >> 7;
*sur++ = (s32)(s * c->currentOutput[2]) >> 7;
}
c->currentPos[0] = (c->currentPos[0] + 1) % c->currentSize[0];
c->currentPos[1] = (c->currentPos[1] + 1) % c->currentSize[1];
c->currentPos[2] = (c->currentPos[2] + 1) % c->currentSize[2];
break;
case SND_AUX_REASON_PARAMETERUPDATE:
break;
default:
MUSY_ASSERT(FALSE);
break;
}
}
bool sndAuxCallbackUpdateSettingsDelay(SND_AUX_DELAY* delay) {
u32 i;
s32* left;
s32* right;
s32* sur;
sndAuxCallbackShutdownDelay(delay);
for (i = 0; i < 3; ++i) {
delay->currentSize[i] = ((delay->delay[i] - 5) * 32 + 159) / 160;
delay->currentPos[i] = 0;
delay->currentFeedback[i] = (delay->feedback[i] << 7) / 100;
delay->currentOutput[i] = (delay->output[i] << 7) / 100;
}
delay->left = (s32*)salMalloc(delay->currentSize[0] * 160 * 4);
delay->right = (s32*)salMalloc(delay->currentSize[1] * 160 * 4);
delay->sur = (s32*)salMalloc(delay->currentSize[2] * 160 * 4);
/* clang-format off */
MUSY_ASSERT(delay->left!=NULL);
MUSY_ASSERT(delay->right!=NULL);
MUSY_ASSERT(delay->sur!=NULL);
/* clang-format on */
left = delay->left;
right = delay->right;
sur = delay->sur;
for (i = 0; i < delay->currentSize[0] * 160; ++i) {
*left++ = 0;
}
for (i = 0; i < delay->currentSize[1] * 160; ++i) {
*right++ = 0;
}
for (i = 0; i < delay->currentSize[2] * 160; ++i) {
*sur++ = 0;
}
return TRUE;
}
bool sndAuxCallbackPrepareDelay(SND_AUX_DELAY* delay) {
delay->left = NULL;
return sndAuxCallbackUpdateSettingsDelay(delay);
}
bool sndAuxCallbackShutdownDelay(SND_AUX_DELAY* delay) {
if (delay->left != NULL) {
salFree(delay->left);
salFree(delay->right);
salFree(delay->sur);
}
return TRUE;
}

View File

@ -1,634 +0,0 @@
#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));
while (delayline->outPoint < 0) {
delayline->outPoint += delayline->length;
}
}
static void DLcreate(_SND_REVHI_DELAYLINE* delayline, s32 length) {
delayline->length = (s32)length * sizeof(f32);
delayline->inputs = (f32*)salMalloc(length * sizeof(f32));
memset(delayline->inputs, 0, length * sizeof(length));
delayline->lastOutput = 0.f;
DLsetdelay(delayline, length >> 1);
delayline->inPoint = 0;
delayline->outPoint = 0;
}
static void DLdelete(_SND_REVHI_DELAYLINE* delayline) { salFree(delayline->inputs); }
bool ReverbHICreate(_SND_REVHI_WORK* rev, f32 coloration, f32 time, f32 mix, f32 damping,
f32 preDelay, f32 crosstalk) {
static int lens[] = {1789, 1999, 2333, 433, 149, 47, 73, 67};
unsigned char i; // r31
unsigned char k; // r29
if (coloration < 0.f || coloration > 1.f || time < 0.01f || time > 10.f || mix < 0.f ||
mix > 1.f || crosstalk < 0.f || crosstalk > 1.f || damping < 0.f || damping > 1.f ||
preDelay < 0.f || preDelay > 0.1f) {
return FALSE;
}
memset(rev, 0, sizeof(_SND_REVHI_WORK));
for (k = 0; k < 3; ++k) {
for (i = 0; i < 3; ++i) {
DLcreate(&rev->C[i + k * 3], lens[i] + 2);
DLsetdelay(&rev->C[i + k * 3], lens[i]);
rev->combCoef[i + k * 3] = powf(10.f, (lens[i] * -3) / (32000.f * time));
}
for (i = 0; i < 2; ++i) {
DLcreate(&rev->AP[i + k * 3], lens[i + 3] + 2);
DLsetdelay(&rev->AP[i + k * 3], lens[i + 3]);
}
DLcreate(&rev->AP[k * 3 + 2], lens[k + 5] + 2);
DLsetdelay(&rev->AP[k * 3 + 2], lens[k + 5]);
rev->lpLastout[k] = 0.f;
}
rev->allPassCoeff = coloration;
rev->level = mix;
rev->crosstalk = crosstalk;
rev->damping = damping;
if (rev->damping < 0.05f) {
rev->damping = 0.05f;
}
rev->damping = 1.f - (rev->damping * 0.8f + 0.05f);
if (preDelay != 0.f) {
rev->preDelayTime = preDelay * 32000.f;
for (i = 0; i < 3; ++i) {
rev->preDelayLine[i] = (f32*)salMalloc(rev->preDelayTime * sizeof(f32));
memset(rev->preDelayLine[i], 0, rev->preDelayTime * sizeof(f32));
rev->preDelayPtr[i] = rev->preDelayLine[i];
}
} else {
rev->preDelayTime = 0;
for (i = 0; i < 3; ++i) {
rev->preDelayPtr[i] = NULL;
rev->preDelayLine[i] = NULL;
}
}
return TRUE;
}
bool ReverbHIModify(struct _SND_REVHI_WORK* rv, float coloration, float time, float mix,
float damping, float preDelay, float crosstalk) {
u8 i; // r30
if (coloration < 0.f || coloration > 1.f || time < 0.01f || time > 10.f || mix < 0.f ||
mix > 1.f || crosstalk < 0.f || crosstalk > 1.f || damping < 0.f || damping > 1.f ||
preDelay < 0.f || preDelay > 0.1f) {
return FALSE;
}
rv->allPassCoeff = coloration;
rv->level = mix;
rv->crosstalk = crosstalk;
rv->damping = damping;
if (rv->damping < 0.05f) {
rv->damping = 0.05f;
}
rv->damping = 1.f - (rv->damping * 0.8f + 0.05f);
for (i = 0; i < 9; ++i) {
DLdelete(&rv->AP[i]);
}
for (i = 0; i < 9; ++i) {
DLdelete(&rv->C[i]);
}
if (rv->preDelayTime != 0) {
for (i = 0; i < 3; ++i) {
salFree(rv->preDelayLine[i]);
}
}
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;
/* clang-format off */
/* TODO: Properly rework these to use input arguments and cleanup ASM */
static asm void DoCrossTalk(s32* a, s32* b, f32 start, f32 end) {
nofralloc
stwu r1, -0x30(r1)
stfd f14, 0x28(r1)
lis r5, i2fMagic@ha
lfd f0, i2fMagic@l(r5)
lis r5, 0x4330
stw r5, 0x8(r1)
stw r5, 0x10(r1)
stw r5, 0x18(r1)
stw r5, 0x20(r1)
ps_merge00 f3, f2, f1
ps_merge00 f4, f1, f2
lis r5, value0_6@ha
lfs f5, value0_6@l(r5)
li r5, 0x4f
mtctr r5
li r10, -0x8
li r11, -0x4
ps_muls0 f4, f4, f5
lwz r6, 0x0(r3)
lwz r7, 0x0(r4)
xoris r6, r6, 0x8000
lwz r8, 0x4(r3)
xoris r7, r7, 0x8000
lwz r9, 0x4(r4)
xoris r8, r8, 0x8000
stw r6, 0xc(r1)
xoris r9, r9, 0x8000
stw r7, 0x14(r1)
stw r8, 0x1c(r1)
stw r9, 0x24(r1)
lfd f5, 0x8(r1)
lfd f6, 0x10(r1)
fsubs f5, f5, f0
lfd f7, 0x18(r1)
fsubs f6, f6, f0
lfd f8, 0x20(r1)
fsubs f7, f7, f0
fsubs f8, f8, f0
L_00000710:
ps_merge00 f9, f5, f6
lwzu r6, 0x8(r3)
ps_merge00 f10, f7, f8
lwzu r7, 0x8(r4)
xoris r6, r6, 0x8000
lwz r8, 0x4(r3)
ps_mul f11, f9, f3
xoris r7, r7, 0x8000
ps_mul f12, f9, f4
lwz r9, 0x4(r4)
ps_mul f13, f10, f3
xoris r8, r8, 0x8000
ps_mul f14, f10, f4
stw r6, 0xc(r1)
ps_sum0 f11, f11, f11, f11
xoris r9, r9, 0x8000
ps_sum0 f12, f12, f12, f12
stw r7, 0x14(r1)
ps_sum0 f13, f13, f13, f13
stw r8, 0x1c(r1)
ps_sum0 f14, f14, f14, f14
stw r9, 0x24(r1)
fctiw f11, f11
lfd f5, 0x8(r1)
fctiw f12, f12
lfd f6, 0x10(r1)
fctiw f13, f13
fsubs f5, f5, f0
fctiw f14, f14
lfd f7, 0x18(r1)
stfiwx f11, r10, r3
fsubs f6, f6, f0
stfiwx f12, r10, r4
lfd f8, 0x20(r1)
stfiwx f13, r11, r3
fsubs f7, f7, f0
stfiwx f14, r11, r4
fsubs f8, f8, f0
bdnz L_00000710
ps_merge00 f9, f5, f6
addi r3, r3, 0x8
ps_merge00 f10, f7, f8
addi r4, r4, 0x8
ps_mul f11, f9, f3
ps_mul f12, f9, f4
ps_mul f13, f10, f3
ps_mul f14, f10, f4
ps_sum0 f11, f11, f11, f11
ps_sum0 f12, f12, f12, f12
ps_sum0 f13, f13, f13, f13
ps_sum0 f14, f14, f14, f14
fctiw f11, f11
fctiw f12, f12
fctiw f13, f13
fctiw f14, f14
stfiwx f11, r10, r3
stfiwx f12, r10, r4
stfiwx f13, r11, r3
stfiwx f14, r11, r4
lfd f14, 0x28(r1)
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)
stmw r14, 0x8(r1)
stfd f14, 0x60(r1)
stfd f15, 0x68(r1)
stfd f16, 0x70(r1)
stfd f17, 0x78(r1)
stfd f18, 0x80(r1)
stfd f19, 0x88(r1)
stfd f20, 0x90(r1)
stfd f21, 0x98(r1)
stfd f22, 0xa0(r1)
stfd f23, 0xa8(r1)
stfd f24, 0xb0(r1)
stfd f25, 0xb8(r1)
stw r5, 0x50(r1)
stw r4, 0x54(r1)
lis r31, value0_3@ha
lfs f6, value0_3@l(r31)
lis r31, value0_6@ha
lfs f9, value0_6@l(r31)
lis r31, i2fMagic@ha
lfd f5, i2fMagic@l(r31)
lfs f2, 0x168(r4)
lfs f15, 0x1a0(r4)
lfs f8, 0x19c(r4)
fmuls f3, f8, f9
fsubs f4, f9, f3
slwi r30, r5, 1
add r30, r30, r5
mulli r31, r30, 0x14
addi r29, r4, 0xb4
add r29, r29, r31
addi r27, r4, 0x0
add r27, r27, r31
slwi r31, r30, 2
add r31, r31, r4
lfs f22, 0x16c(r31)
lfs f23, 0x170(r31)
lfs f24, 0x174(r31)
slwi r31, r5, 2
add r31, r31, r4
lfs f25, 0x190(r31)
lwz r31, 0x1a4(r4)
lis r30, 0x4330
stw r30, 0x58(r1)
addi r22, r31, -0x1
slwi r22, r22, 2
slwi r28, r5, 2
add r28, r28, r4
cmpwi cr7, r31, 0x0
lwz r21, 0x0(r29)
lwz r20, 0x4(r29)
lwz r19, 0x14(r29)
lwz r18, 0x18(r29)
lwz r17, 0x28(r29)
lwz r16, 0x2c(r29)
lfs f16, 0x10(r29)
lfs f17, 0x24(r29)
lfs f18, 0x38(r29)
lwz r25, 0x8(r29)
lwz r24, 0x1c(r29)
lwz r23, 0x30(r29)
lwz r4, 0xc(r29)
lwz r5, 0x20(r29)
lwz r6, 0x34(r29)
lwz r12, 0x0(r27)
lwz r11, 0x4(r27)
lwz r10, 0x14(r27)
lwz r9, 0x18(r27)
lwz r8, 0x28(r27)
lwz r7, 0x2c(r27)
lfs f19, 0x10(r27)
lfs f20, 0x24(r27)
lfs f21, 0x38(r27)
lwz r15, 0x8(r27)
lwz r14, 0x1c(r27)
lwz r30, 0x0(r3)
xoris r30, r30, 0x8000
stw r30, 0x5c(r1)
lfd f12, 0x58(r1)
fsubs f12, f12, f5
li r31, 0x9f
mtctr r31
L_00000954:
fmr f13, f12
beq cr7, L_00000984
lwz r30, 0x1ac(r28)
lwz r29, 0x1b8(r28)
add r31, r22, r30
addi r29, r29, 0x4
lfs f13, -0x4(r29)
cmpw r29, r31
stfs f12, -0x4(r29)
bne+ L_00000980
mr r29, r30
L_00000980:
stw r29, 0x1b8(r30)
L_00000984:
fmadds f8, f22, f16, f13
lwzu r29, 0x4(r3)
fmadds f9, f23, f17, f13
stfsx f8, r4, r21
addi r21, r21, 0x4
stfsx f9, r5, r19
lfsx f14, r4, r20
addi r20, r20, 0x4
lfsx f17, r5, r18
cmpw r21, r25
cmpw cr1, r20, r25
addi r19, r19, 0x4
addi r18, r18, 0x4
fmr f16, f14
cmpw cr5, r19, r24
fadds f14, f14, f17
cmpw cr6, r18, r24
bne+ L_000009D0
li r21, 0x0
L_000009D0:
fmadds f8, f24, f18, f13
bne+ cr1, L_000009DC
li r20, 0x0
L_000009DC:
stfsx f8, r6, r17
addi r17, r17, 0x4
bne+ cr5, L_000009EC
li r19, 0x0
L_000009EC:
lfsx f18, r6, r16
addi r16, r16, 0x4
cmpw r17, r23
bne+ cr6, L_00000A00
li r18, 0x0
L_00000A00:
fadds f14, f14, f18
cmpw cr1, r16, r23
lwz r26, 0xc(r27)
fmadds f9, f2, f19, f14
bne+ L_00000A18
li r17, 0x0
L_00000A18:
bne+ cr1, L_00000A20
li r16, 0x0
L_00000A20:
xoris r29, r29, 0x8000
stfsx f9, r26, r12
fnmsubs f14, f2, f9, f19
addi r12, r12, 0x4
lfsx f19, r26, r11
cmpw cr5, r12, r15
addi r11, r11, 0x4
lwz r26, 0x20(r27)
cmpw cr6, r11, r15
fmadds f8, f2, f20, f14
bne+ cr5, L_00000A50
li r12, 0x0
L_00000A50:
stw r29, 0x5c(r1)
stfsx f8, r26, r10
fnmsubs f14, f2, f8, f20
addi r10, r10, 0x4
bne+ cr6, L_00000A68
li r11, 0x0
L_00000A68:
lfsx f20, r26, r9
cmpw r10, r14
fmuls f14, f14, f6
addi r9, r9, 0x4
cmpw cr1, r9, r14
lfd f10, 0x58(r1)
fmadds f14, f15, f25, f14
bne+ L_00000A8C
li r10, 0x0
L_00000A8C:
lwz r26, 0x34(r27)
fmadds f9, f2, f21, f14
fmr f25, f14
bne+ cr1, L_00000AA0
li r9, 0x0
L_00000AA0:
stfsx f9, r26, r8
fnmsubs f14, f2, f9, f21
lwz r31, 0x30(r27)
fmuls f8, f4, f12
lfsx f21, r26, r7
addi r8, r8, 0x4
addi r7, r7, 0x4
fmadds f14, f3, f14, f8
cmpw cr5, r8, r31
cmpw cr6, r7, r31
fctiwz f14, f14
bne+ cr5, L_00000AD4
li r8, 0x0
L_00000AD4:
bne+ cr6, L_00000ADC
li r7, 0x0
L_00000ADC:
li r31, -0x4
fsubs f12, f10, f5
stfiwx f14, r3, r31
bdnz L_00000954
fmr f13, f12
beq cr7, L_00000B1C
lwz r30, 0x1ac(r28)
lwz r29, 0x1b8(r28)
add r31, r22, r30
addi r29, r29, 0x4
lfs f13, -0x4(r29)
cmpw r29, r31
stfs f12, -0x4(r29)
bne+ L_00000B18
mr r29, r30
L_00000B18:
stw r29, 0x1b8(r30)
L_00000B1C:
fmadds f8, f22, f16, f13
fmadds f9, f23, f17, f13
stfsx f8, r4, r21
addi r21, r21, 0x4
stfsx f9, r5, r19
lfsx f14, r4, r20
addi r20, r20, 0x4
lfsx f17, r5, r18
cmpw r21, r25
cmpw cr1, r20, r25
addi r19, r19, 0x4
addi r18, r18, 0x4
fmr f16, f14
cmpw cr5, r19, r24
fadds f14, f14, f17
cmpw cr6, r18, r24
bne+ L_00000B64
li r21, 0x0
L_00000B64:
fmadds f8, f24, f18, f13
bne+ cr1, L_00000B70
li r20, 0x0
L_00000B70:
stfsx f8, r6, r17
addi r17, r17, 0x4
bne+ cr5, L_00000B80
li r19, 0x0
L_00000B80:
lfsx f18, r6, r16
addi r16, r16, 0x4
cmpw r17, r23
bne+ cr6, L_00000B94
li r18, 0x0
L_00000B94:
fadds f14, f14, f18
cmpw cr1, r16, r23
lwz r26, 0xc(r27)
fmadds f9, f2, f19, f14
bne+ L_00000BAC
li r17, 0x0
L_00000BAC:
bne+ cr1, L_00000BB4
li r16, 0x0
L_00000BB4:
stfsx f9, r26, r12
fnmsubs f14, f2, f9, f19
addi r12, r12, 0x4
lfsx f19, r26, r11
cmpw cr5, r12, r15
addi r11, r11, 0x4
lwz r26, 0x20(r27)
cmpw cr6, r11, r15
fmadds f8, f2, f20, f14
bne+ cr5, L_00000BE0
li r12, 0x0
L_00000BE0:
stfsx f8, r26, r10
fnmsubs f14, f2, f8, f20
addi r10, r10, 0x4
bne+ cr6, L_00000BF4
li r11, 0x0
L_00000BF4:
lfsx f20, r26, r9
cmpw r10, r14
fmuls f14, f14, f6
addi r9, r9, 0x4
cmpw cr1, r9, r14
fmadds f14, f15, f25, f14
bne+ L_00000C14
li r10, 0x0
L_00000C14:
lwz r26, 0x34(r27)
lwz r5, 0x50(r1)
lwz r4, 0x54(r1)
fmadds f9, f2, f21, f14
fmr f25, f14
bne+ cr1, L_00000C30
li r9, 0x0
L_00000C30:
stfsx f9, r26, r8
fnmsubs f14, f2, f9, f21
lwz r29, 0x30(r27)
fmuls f8, f4, f12
lfsx f21, r26, r7
addi r8, r8, 0x4
addi r7, r7, 0x4
fmadds f14, f3, f14, f8
cmpw cr5, r8, r29
cmpw cr6, r7, r29
fctiwz f14, f14
bne+ cr5, L_00000C64
li r8, 0x0
L_00000C64:
bne+ cr6, L_00000C6C
li r7, 0x0
L_00000C6C:
slwi r30, r5, 1
add r30, r30, r5
mulli r31, r30, 0x14
stfiwx f14, r0, r3
addi r29, r4, 0xb4
add r29, r29, r31
stw r21, 0x0(r29)
stw r20, 0x4(r29)
stw r19, 0x14(r29)
stw r18, 0x18(r29)
stw r17, 0x28(r29)
stw r16, 0x2c(r29)
stfs f16, 0x10(r29)
stfs f17, 0x24(r29)
stfs f18, 0x38(r29)
stw r12, 0x0(r27)
stw r11, 0x4(r27)
stw r10, 0x14(r27)
stw r9, 0x18(r27)
stw r8, 0x28(r27)
stw r7, 0x2c(r27)
stfs f19, 0x10(r27)
stfs f20, 0x24(r27)
stfs f21, 0x38(r27)
slwi r31, r5, 2
add r31, r31, r4
stfs f25, 0x190(r31)
lfd f14, 0x60(r1)
lfd f15, 0x68(r1)
lfd f16, 0x70(r1)
lfd f17, 0x78(r1)
lfd f18, 0x80(r1)
lfd f19, 0x88(r1)
lfd f20, 0x90(r1)
lfd f21, 0x98(r1)
lfd f22, 0xa0(r1)
lfd f23, 0xa8(r1)
lfd f24, 0xb0(r1)
lfd f25, 0xb8(r1)
lmw r14, 0x8(r1)
addi r1, r1, 0xc0
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;
for (i = 0; i < 3; ++i) {
switch (i) {
case 0:
if (rev->rv.crosstalk != 0.f) {
DoCrossTalk(left, right, rev->rv.crosstalk * 0.5f, 1.f - (rev->rv.crosstalk * 0.5f));
}
HandleReverb(left, rev, 0);
break;
case 1:
HandleReverb(right, rev, 1);
break;
case 2:
HandleReverb(surround, rev, 2);
break;
}
}
}
void ReverbHIFree(_SND_REVHI_WORK* rv) {
u8 i;
for (i = 0; i < 9; ++i) {
DLdelete(&rv->AP[i]);
}
for (i = 0; i < 9; ++i) {
DLdelete(&rv->C[i]);
}
if (rv->preDelayTime != 0) {
for (i = 0; i < 3; ++i) {
salFree(rv->preDelayLine[i]);
}
}
}

View File

@ -1,58 +0,0 @@
/* ---------------------------------------
---------------------------------------
*/
#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);
extern void ReverbHIFree(_SND_REVHI_WORK* rev);
extern void ReverbHIModify(_SND_REVHI_WORK* rev, f32 coloration, f32 time, f32 mix, f32 damping,
f32 preDelay, f32 crosstalk);
extern void ReverbHICallback(s32* left, s32* right, s32* surround, SND_AUX_REVERBHI* rev);
void sndAuxCallbackReverbHI(u8 reason, SND_AUX_INFO* info, void* user) {
switch (reason) {
case SND_AUX_REASON_BUFFERUPDATE:
if (((SND_AUX_REVERBHI*)user)->tempDisableFX == 0) {
ReverbHICallback(info->data.bufferUpdate.left, info->data.bufferUpdate.right,
info->data.bufferUpdate.surround, (SND_AUX_REVERBHI*)user);
}
break;
case SND_AUX_REASON_PARAMETERUPDATE:
break;
default:
MUSY_ASSERT(FALSE);
break;
}
}
bool sndAuxCallbackUpdateSettingsReverbHI(SND_AUX_REVERBHI* rev) {
rev->tempDisableFX = TRUE;
ReverbHIModify(&rev->rv, rev->coloration, rev->time, rev->mix, rev->damping, rev->preDelay,
rev->crosstalk);
rev->tempDisableFX = FALSE;
return TRUE;
}
bool sndAuxCallbackPrepareReverbHI(SND_AUX_REVERBHI* rev) {
rev->tempDisableFX = FALSE;
return ReverbHICreate(&rev->rv, rev->coloration, rev->time, rev->mix, rev->damping, rev->preDelay,
rev->crosstalk);
}
bool sndAuxCallbackShutdownReverbHI(SND_AUX_REVERBHI* rev) {
ReverbHIFree(&rev->rv);
return TRUE;
}

View File

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

View File

@ -1,526 +0,0 @@
#include "musyx/hardware.h"
#include "musyx/assert.h"
#include "musyx/s3d.h"
#include "musyx/sal.h"
#include "musyx/seq.h"
#include "musyx/stream.h"
#include "musyx/synth.h"
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(u32 v, u16 speed) {
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(u32 v, u8 salCoefSel) {
static u16 dspCoefSel[3] = {0, 1, 2};
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(u32 v, u8 table, float vol, u32 pan, u32 span, float auxa, float auxb) {
SAL_VOLINFO vi; // r1+0x24
u16 il; // r30
u16 ir; // r29
u16 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_DPL2);
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(u8 studio, bool 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, u32 offset, u32 bytes, u8 hwStreamHandle, void (*callback)(size_t),
u32 user) {
size_t aram; // r28
size_t mram; // r29
size_t len;
aram = aramGetStreamBufferAddress(hwStreamHandle, &len);
bytes += (offset & 31);
offset &= ~31;
bytes = (bytes + 31) & ~31;
mram = (u32)base + offset;
#if MUSY_TARGET == MUSY_TARGET_DOLPHIN
DCStoreRange((void*)mram, bytes);
#endif
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) {
#if MUSY_TARGET == MUSY_TARGET_DOLPHIN
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);
#endif
}
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,422 +0,0 @@
#include "musyx/assert.h"
#include "musyx/musyx.h"
#include "musyx/platform.h"
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;
#if MUSY_TARGET == MUSY_TARGET_DOLPHIN
#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)(u32); // 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;
static u32 aramTop; // size: 0x4
static u32 aramWrite; // size: 0x4
static u32 aramStream; // size: 0x4
static void* (*aramUploadCallback)(u32, u32); // size: 0x4
static u32 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;
}
#elif MUSY_TARGET == MUSY_TARGET_PC
// 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() {}
static void aramQueueCallback(unsigned long ptr) {}
void aramUploadData(void* mram, unsigned long aram, unsigned long len, unsigned long highPrio,
void (*callback)(unsigned long), unsigned long user) {}
void aramSyncTransferQueue() {}
void aramInit(unsigned long length) {}
void aramExit() {}
unsigned long aramGetZeroBuffer() { return 0; }
void aramSetUploadCallback(void* (*callback)(unsigned long, unsigned long),
unsigned long chunckSize) {}
void* aramStoreData(void* src, unsigned long len) {}
void aramRemoveData(void* aram, unsigned long len) {}
static void InitStreamBuffers() {}
unsigned char aramAllocateStreamBuffer(u32 len) { return 0; }
size_t aramGetStreamBufferAddress(u8 id, size_t* len) {
MUSY_ASSERT_MSG(id != 0xFF, "Stream buffer ID is invalid");
}
void aramFreeStreamBuffer(unsigned char id) {
STREAM_BUFFER* fSb; // r30
STREAM_BUFFER* sb; // r31
STREAM_BUFFER* lastSb; // r29
STREAM_BUFFER* nextSb; // r27
unsigned long minAddr; // r28
MUSY_ASSERT_MSG(id != 0xFF, "Stream buffer ID is invalid");
}
#endif

View File

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

View File

@ -1,527 +0,0 @@
/*
*/
#include "musyx/assert.h"
#include "musyx/dspvoice.h"
#include "musyx/hardware.h"
#include "musyx/sal.h"
#include <string.h>
#ifdef _DEBUG
static u32 dbgActiveVoicesMax = 0;
#endif
extern u8 salAuxFrame;
DSPstudioinfo dspStudio[8];
static u32 dspARAMZeroBuffer = 0;
u16* dspCmdLastLoad = NULL;
u16* dspCmdLastBase = NULL;
s16* dspCmdList = NULL;
u16 dspCmdLastSize = 0;
u16* dspCmdCurBase = NULL;
u16* dspCmdMaxPtr = NULL;
u16* dspCmdPtr = NULL;
u16 dspCmdFirstSize = 0;
u32 dspHRTFOn = FALSE;
s16* dspHrtfHistoryBuffer = NULL;
s32* dspSurround = NULL;
s16* dspITDBuffer = NULL;
DSPvoice* dspVoice = NULL;
SND_MESSAGE_CALLBACK salMessageCallback = NULL;
bool salInitDspCtrl(u8 numVoices, u8 numStudios, u32 defaultStudioDPL2) {
u32 i; // r31
u32 j; // r27
size_t itdPtr; // r28
salNumVoices = numVoices;
salMaxStudioNum = numStudios;
MUSY_ASSERT(salMaxStudioNum <= SAL_MAX_STUDIONUM);
dspARAMZeroBuffer = aramGetZeroBuffer();
if ((dspCmdList = salMalloc(1024 * sizeof(u16))) != NULL) {
MUSY_DEBUG("Allocated dspCmdList.\n\n");
if ((dspSurround = salMalloc(160 * sizeof(s32))) != NULL) {
MUSY_DEBUG("Allocated surround buffer.\n\n");
memset(dspSurround, 0, 160 * sizeof(s32));
#if MUSY_TARGET == MUSY_TARGET_DOLPHIN
DCFlushRange(dspSurround, 160 * sizeof(long));
#endif
if ((dspVoice = salMalloc(salNumVoices * sizeof(DSPvoice))) != NULL) {
MUSY_DEBUG("Allocated HW voice array.\n\n");
if ((dspITDBuffer = salMalloc(salNumVoices * 64)) != NULL) {
MUSY_DEBUG("Allocated ITD buffers for voice array.\n\n");
#if MUSY_TARGET == MUSY_TARGET_DOLPHIN
DCInvalidateRange(dspITDBuffer, salNumVoices * 64);
#endif
itdPtr = (u32)dspITDBuffer;
for (i = 0; i < salNumVoices; ++i) {
MUSY_DEBUG("Initializing voice %d...\n", i);
dspVoice[i].state = 0;
dspVoice[i].postBreak = 0;
dspVoice[i].startupBreak = 0;
dspVoice[i].lastUpdate.pitch = 0xff;
dspVoice[i].lastUpdate.vol = 0xff;
dspVoice[i].lastUpdate.volA = 0xff;
dspVoice[i].lastUpdate.volB = 0xff;
dspVoice[i].pb = salMalloc(sizeof(_PB));
memset(dspVoice[i].pb, 0, sizeof(_PB));
dspVoice[i].patchData = salMalloc(0x80);
dspVoice[i].pb->currHi = ((u32)dspVoice[i].pb >> 16);
dspVoice[i].pb->currLo = (u16)dspVoice[i].pb;
dspVoice[i].pb->update.dataHi = ((u32)dspVoice[i].patchData >> 16);
dspVoice[i].pb->update.dataLo = ((u16)dspVoice[i].patchData);
dspVoice[i].pb->itd.bufferHi = ((u32)itdPtr >> 16);
dspVoice[i].pb->itd.bufferLo = ((u16)itdPtr);
dspVoice[i].itdBuffer = (void*)itdPtr;
itdPtr += 0x40;
dspVoice[i].virtualSampleID = 0xFFFFFFFF;
#if MUSY_TARGET == MUSY_TARGET_DOLPHIN
DCStoreRangeNoSync(dspVoice[i].pb, sizeof(_PB));
#endif
for (j = 0; j < 5; ++j) {
dspVoice[i].changed[j] = 0;
}
}
MUSY_DEBUG("All voices initialized.\n\n");
for (i = 0; i < salMaxStudioNum; ++i) {
MUSY_DEBUG("Initializing studio %d...\n", i);
dspStudio[i].state = 0;
if ((dspStudio[i].spb = (_SPB*)salMalloc(sizeof(_SPB))) == NULL) {
return FALSE;
}
if ((dspStudio[i].main[0] = (void*)salMalloc(0x3c00)) == NULL) {
return FALSE;
}
memset(dspStudio[i].main[0], 0, 0x3c00);
#if MUSY_TARGET == MUSY_TARGET_DOLPHIN
DCFlushRangeNoSync(dspStudio[i].main[0], 0x3c00);
#endif
dspStudio[i].main[1] = dspStudio[i].main[0] + 0x1e0;
dspStudio[i].auxA[0] = dspStudio[i].main[1] + 0x1e0;
dspStudio[i].auxA[1] = dspStudio[i].auxA[0] + 0x1e0;
dspStudio[i].auxA[2] = dspStudio[i].auxA[1] + 0x1e0;
dspStudio[i].auxB[0] = dspStudio[i].auxA[2] + 0x1e0;
dspStudio[i].auxB[1] = dspStudio[i].auxB[0] + 0x1e0;
dspStudio[i].auxB[2] = dspStudio[i].auxB[1] + 0x1e0;
memset(dspStudio[i].spb, 0, sizeof(_SPB));
dspStudio[i].hostDPopSum.l = dspStudio[i].hostDPopSum.r = dspStudio[i].hostDPopSum.s =
0;
dspStudio[i].hostDPopSum.lA = dspStudio[i].hostDPopSum.rA =
dspStudio[i].hostDPopSum.sA = 0;
dspStudio[i].hostDPopSum.lB = dspStudio[i].hostDPopSum.rB =
dspStudio[i].hostDPopSum.sB = 0;
#if MUSY_TARGET == MUSY_TARGET_DOLPHIN
DCFlushRangeNoSync(dspStudio[i].spb, sizeof(_SPB));
#endif
}
MUSY_DEBUG("All studios are initialized.\n\n");
salActivateStudio(
0, 1, defaultStudioDPL2 != FALSE ? SND_STUDIO_TYPE_DPL2 : SND_STUDIO_TYPE_STD);
MUSY_DEBUG("Default studio is active.\n\n");
if ((dspHrtfHistoryBuffer = salMalloc(0x100)) == NULL) {
return FALSE;
}
salInitHRTFBuffer();
return TRUE;
}
}
}
}
return FALSE;
}
void salInitHRTFBuffer() {
memset(dspHrtfHistoryBuffer, 0, 0x100);
#if MUSY_TARGET == MUSY_TARGET_DOLPHIN
DCFlushRangeNoSync(dspHrtfHistoryBuffer, 0x100);
#endif
}
bool salExitDspCtrl() {
u8 i; // r31
salFree(dspHrtfHistoryBuffer);
for (i = 0; i < salNumVoices; ++i) {
salFree(dspVoice[i].pb);
salFree(dspVoice[i].patchData);
}
for (i = 0; i < salMaxStudioNum; ++i) {
salFree(dspStudio[i].spb);
salFree(dspStudio[i].main[0]);
}
salFree(dspITDBuffer);
salFree(dspVoice);
salFree(dspSurround);
salFree(dspCmdList);
return TRUE;
}
void salActivateStudio(u8 studio, u32 isMaster, SND_STUDIO_TYPE type) {
memset(dspStudio[studio].main[0], 0, 0x3c00);
#if MUSY_TARGET == MUSY_TARGET_DOLPHIN
DCFlushRangeNoSync(dspStudio[studio].main[0], 0x3c00);
#endif
memset(dspStudio[studio].spb, 0, sizeof(_SPB));
dspStudio[studio].hostDPopSum.l = dspStudio[studio].hostDPopSum.r =
dspStudio[studio].hostDPopSum.s = 0;
dspStudio[studio].hostDPopSum.lA = dspStudio[studio].hostDPopSum.rA =
dspStudio[studio].hostDPopSum.sA = 0;
dspStudio[studio].hostDPopSum.lB = dspStudio[studio].hostDPopSum.rB =
dspStudio[studio].hostDPopSum.sB = 0;
#if MUSY_TARGET == MUSY_TARGET_DOLPHIN
DCFlushRangeNoSync(dspStudio[studio].spb, sizeof(_SPB));
#endif
memset(dspStudio[studio].auxA[0], 0, 0x780);
#if MUSY_TARGET == MUSY_TARGET_DOLPHIN
DCFlushRangeNoSync(dspStudio[studio].auxA[0], 0x780);
#endif
memset(dspStudio[studio].auxB[0], 0, 0x780);
#if MUSY_TARGET == MUSY_TARGET_DOLPHIN
DCFlushRangeNoSync(dspStudio[studio].auxB[0], 0x780);
#endif
dspStudio[studio].voiceRoot = NULL;
dspStudio[studio].alienVoiceRoot = NULL;
dspStudio[studio].state = 1;
dspStudio[studio].isMaster = isMaster;
dspStudio[studio].numInputs = 0;
dspStudio[studio].type = type;
dspStudio[studio].auxAHandler = dspStudio[studio].auxBHandler = NULL;
}
u16 dspSRCCycles[3][3] = {
{2990, 2990, 1115},
{3300, 3300, 1115},
{3700, 3700, 1115},
};
static const u16 dspMixerCycles[32] = {
1470, 2940, 2940, 4410, 2230, 4460, 4460, 6690, 2470, 4940, 4940, 7410, 3735, 7470, 7470, 11205,
2940, 3386, 2940, 3386, 2940, 3386, 2940, 3386, 4940, 5687, 4940, 5687, 4940, 5687, 4940, 5687,
};
void salDeactivateStudio(u8 studio) { dspStudio[studio].state = 0; }
static u32 salCheckVolErrorAndResetDelta(u16* dsp_vol, u16* dsp_delta, u16* last_vol, u16 targetVol,
u16* resetFlags, u16 resetMask) {
s16 d; // r31
s16 x; // r30
if (targetVol != *last_vol) {
d = (s16)targetVol - (s16)*last_vol;
if ((s16)d >= 32 && (s16)d < 160) {
x = (s16)d >> 5;
if ((s16)x < 5) {
resetFlags[x] |= resetMask;
}
*dsp_delta = 1;
*last_vol += (x << 5);
return 1;
}
if (-32 >= (s16)d && -160 < (s16)d) {
x = -(s16)d >> 5;
if (x < 5) {
resetFlags[x] |= resetMask;
}
*dsp_delta = 0xFFFF;
*last_vol -= x << 5;
return 1;
}
if (targetVol == 0 && (s16)d > -32) {
*dsp_vol = *last_vol = 0;
}
}
*dsp_delta = 0;
return 0;
}
static void sal_setup_dspvol(u16* dsp_delta, u16* last_vol, u16 vol) {
*dsp_delta = ((s16)vol - (s16)*last_vol) / 160;
*last_vol += (s16)*dsp_delta * 160;
}
static void sal_update_hostplayinfo(DSPvoice* dsp_vptr) {
u32 old_lo; // r30
u32 pitch; // r31
if (dsp_vptr->smp_info.loopLength != 0) {
return;
}
if (dsp_vptr->pb->srcSelect != 2) {
pitch = dsp_vptr->playInfo.pitch << 5;
} else {
pitch = 0x200000;
}
old_lo = dsp_vptr->playInfo.posLo;
dsp_vptr->playInfo.posLo += pitch * 0x10000;
if (old_lo > dsp_vptr->playInfo.posLo) {
dsp_vptr->playInfo.posHi += (pitch >> 16) + 1;
} else {
dsp_vptr->playInfo.posHi += (pitch >> 16);
}
}
static void AddDpop(s32* sum, s16 delta) {
*sum += (int)delta;
*sum = (*sum > 0x7fffff) ? 0x7fffff : (*sum < -0x7fffff ? -0x7fffff : *sum);
}
static void DoDepopFade(long* dspStart, s16* dspDelta, long* hostSum) {
if (*hostSum <= -160) {
*dspDelta = (*hostSum <= -3200) ? 0x14 : (s16)(-*hostSum / 160);
} else if (*hostSum >= 160) {
*dspDelta = (*hostSum >= 3200) ? -0x14 : (s16)(-*hostSum / 160);
} else {
*dspDelta = 0;
}
*dspStart = *hostSum;
*hostSum += *dspDelta * 160;
}
static void HandleDepopVoice(DSPstudioinfo* stp, DSPvoice* dsp_vptr) {
_PB* pb; // r31
dsp_vptr->postBreak = 0;
dsp_vptr->pb->state = 0;
pb = dsp_vptr->pb;
AddDpop(&stp->hostDPopSum.l, pb->dpop.aL);
AddDpop(&stp->hostDPopSum.r, pb->dpop.aR);
if ((pb->mixerCtrl & 0x04) != 0) {
AddDpop(&stp->hostDPopSum.s, pb->dpop.aS);
}
if ((pb->mixerCtrl & 0x01) != 0) {
AddDpop(&stp->hostDPopSum.lA, pb->dpop.aAuxAL);
AddDpop(&stp->hostDPopSum.rA, pb->dpop.aAuxAR);
if ((pb->mixerCtrl & 0x14) != 0) {
AddDpop(&stp->hostDPopSum.sA, pb->dpop.aAuxAS);
}
}
if ((pb->mixerCtrl & 0x12) != 0) {
AddDpop(&stp->hostDPopSum.lB, pb->dpop.aAuxBL);
AddDpop(&stp->hostDPopSum.rB, pb->dpop.aAuxBR);
if ((pb->mixerCtrl & 0x4) != 0) {
AddDpop(&stp->hostDPopSum.sB, pb->dpop.aAuxBS);
}
}
}
static void SortVoices(DSPvoice** voices, long l, long r) {
long i; // r28
long last; // r29
DSPvoice* tmp; // r27
if (l >= r) {
return;
}
tmp = voices[l];
voices[l] = voices[(l + r) / 2];
voices[(l + r) / 2] = tmp;
last = l;
i = l + 1;
for (; i <= r; ++i) {
if (voices[i]->prio < voices[l]->prio) {
last += 1;
tmp = voices[last];
voices[last] = voices[i];
voices[i] = tmp;
}
}
tmp = voices[l];
voices[l] = voices[last];
voices[last] = tmp;
SortVoices(voices, l, last - 1);
SortVoices(voices, last + 1, r);
}
void salBuildCommandList(signed short* dest, unsigned long nsDelay) {
static const u16 pbOffsets[9] = {10, 12, 24, 13, 16, 26, 18, 20, 22};
static DSPvoice* voices[64];
}
u32 salSynthSendMessage(DSPvoice* dsp_vptr, u32 mesg) {
return salMessageCallback == NULL ? FALSE
: salMessageCallback(mesg, dsp_vptr->mesgCallBackUserValue);
}
void salActivateVoice(DSPvoice* dsp_vptr, u8 studio) {
if (dsp_vptr->state != 0) {
salDeactivateVoice(dsp_vptr);
dsp_vptr->changed[0] |= 0x20;
}
dsp_vptr->postBreak = 0;
if ((dsp_vptr->next = dspStudio[studio].voiceRoot) != NULL) {
dsp_vptr->next->prev = dsp_vptr;
}
dsp_vptr->prev = NULL;
dspStudio[studio].voiceRoot = dsp_vptr;
dsp_vptr->startupBreak = 0;
dsp_vptr->state = 1;
dsp_vptr->studio = studio;
}
void salDeactivateVoice(DSPvoice* dsp_vptr) {
if (dsp_vptr->state == 0) {
return;
}
if (dsp_vptr->prev != NULL) {
dsp_vptr->prev->next = dsp_vptr->next;
} else {
dspStudio[dsp_vptr->studio].voiceRoot = dsp_vptr->next;
}
if (dsp_vptr->next != NULL) {
dsp_vptr->next->prev = dsp_vptr->prev;
}
dsp_vptr->state = 0;
}
void salReconnectVoice(DSPvoice* dsp_vptr, u8 studio) {
if (dsp_vptr->state != 0) {
if (dsp_vptr->prev != NULL) {
dsp_vptr->prev->next = dsp_vptr->next;
} else {
dspStudio[dsp_vptr->studio].voiceRoot = dsp_vptr->next;
}
if (dsp_vptr->next != NULL) {
dsp_vptr->next->prev = dsp_vptr->prev;
}
if ((dsp_vptr->next = dspStudio[studio].voiceRoot) != NULL) {
dsp_vptr->next->prev = dsp_vptr;
}
dsp_vptr->prev = NULL;
dspStudio[studio].voiceRoot = dsp_vptr;
if (dsp_vptr->state == 2) {
dsp_vptr->nextAlien = dspStudio[dsp_vptr->studio].alienVoiceRoot;
dspStudio[dsp_vptr->studio].alienVoiceRoot = dsp_vptr;
}
}
dsp_vptr->studio = studio;
}
bool salAddStudioInput(DSPstudioinfo* stp, SND_STUDIO_INPUT* desc) {
if (stp->numInputs < 7) {
stp->in[stp->numInputs].studio = desc->srcStudio;
stp->in[stp->numInputs].vol = ((u16)desc->vol << 8) | ((u16)desc->vol << 1);
stp->in[stp->numInputs].volA = ((u16)desc->volA << 8) | ((u16)desc->volA << 1);
stp->in[stp->numInputs].volB = ((u16)desc->volB << 8) | ((u16)desc->volB << 1);
stp->in[stp->numInputs].desc = desc;
++stp->numInputs;
return 1;
}
return 0;
}
bool salRemoveStudioInput(DSPstudioinfo* stp, SND_STUDIO_INPUT* desc) {
long i; // r31
for (i = 0; i < stp->numInputs; ++i) {
if (stp->in[i].desc == desc) {
for (; i <= stp->numInputs - 2; ++i) {
stp->in[i] = stp->in[i + 1];
}
--stp->numInputs;
return 1;
}
}
return 0;
}
void salHandleAuxProcessing() {
u8 st; // r29
s32* work; // r30
DSPstudioinfo* sp; // r31
SND_AUX_INFO info; // r1+0x8
sp = &dspStudio[0];
for (st = 0; st < salMaxStudioNum; ++st, ++sp) {
if (sp->state != 1) {
continue;
}
if (sp->auxAHandler != NULL) {
work = sp->auxA[(salAuxFrame + 2) % 3];
info.data.bufferUpdate.left = work;
info.data.bufferUpdate.right = work + 0xa0;
info.data.bufferUpdate.surround = work + 0x140;
sp->auxAHandler(0, &info, sp->auxAUser);
#if MUSY_TARGET == MUSY_TARGET_DOLPHIN
DCFlushRangeNoSync(work, 0x780);
#endif
}
if (sp->type == 0 && sp->auxBHandler != 0) {
work = sp->auxB[(salAuxFrame + 2) % 3];
info.data.bufferUpdate.left = work;
info.data.bufferUpdate.right = work + 0xa0;
info.data.bufferUpdate.surround = work + 0x140;
sp->auxBHandler(0, &info, sp->auxBUser);
#if MUSY_TARGET == MUSY_TARGET_DOLPHIN
DCFlushRangeNoSync(work, 0x780);
#endif
}
}
}

View File

@ -1,4 +0,0 @@
#include "musyx/musyx.h"
u32 aramSize = 0;
u8* aramBase = NULL;

View File

@ -1,5 +0,0 @@
#include "musyx/hardware.h"
void* salMalloc(u32 len) { return salHooks.malloc(len); }
void salFree(void* addr) { salHooks.free(addr); }

View File

@ -1,138 +0,0 @@
#include "musyx/platform.h"
#if MUSY_TARGET == MUSY_TARGET_PC
#include <pthread.h>
#include "musyx/assert.h"
#include "musyx/hardware.h"
#include "musyx/sal.h"
#include <string.h>
static volatile u32 oldState = 0;
static volatile u16 hwIrqLevel = 0;
static volatile u32 salDspInitIsDone = 0;
static volatile u64 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
pthread_mutex_t globalMutex;
pthread_mutex_t globalInterrupt;
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 = 0; // OSGetTick();
if (salDspIsDone) {
callUserCallback();
} else {
salLogicIsWaiting = 1;
}
}
void dspInitCallback() {
salDspIsDone = TRUE;
salDspInitIsDone = TRUE;
}
void dspResumeCallback() {
salDspIsDone = TRUE;
if (salLogicIsWaiting) {
salLogicIsWaiting = FALSE;
callUserCallback();
}
}
bool 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;
}
bool salStartAi() { } //AIStartDMA(); }
bool salExitAi() {
salFree(salAIBufferBase);
return TRUE;
}
void* salAiGetDest() {
u8 index; // r31
index = (salAIBufferIndex + 2) % 4;
return NULL;
}
bool salInitDsp(u32) { return TRUE; }
bool salExitDsp() {}
void salStartDsp(s16* cmdList) {}
void salCtrlDsp(s16* dest) {
salBuildCommandList(dest, salGetStartDelay());
salStartDsp(dspCmdList);
}
u32 salGetStartDelay() { return 0; }
void hwInitIrq() {
// oldState = OSDisableInterrupts();
hwIrqLevel = 1;
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ROBUST);
pthread_mutex_init(&globalMutex, &attr);
}
void hwExitIrq() {}
void hwEnableIrq() {
if (--hwIrqLevel == 0) {
// OSRestoreInterrupts(oldState);
}
}
void hwDisableIrq() {
if ((hwIrqLevel++) == 0) {
// oldState = OSDisableInterrupts();
}
}
void hwIRQEnterCritical() {
pthread_mutex_lock(&globalMutex);
}
void hwIRQLeaveCritical() {
pthread_mutex_unlock(&globalMutex);
}
#endif

View File

@ -1,139 +0,0 @@
#include "musyx/sal.h"
#include "musyx/synth_dbtab.h"
#include <math.h>
static float musyx_vol_tab[129] = {
0.f, 3.0518499e-05f, 0.000152593f, 0.000396741f, 0.00070192601f,
0.00112918f, 0.001648f, 0.00222785f, 0.0029297799f, 0.00372326f,
0.0046082898f, 0.00558489f, 0.0066530402f, 0.0078432597f, 0.0091250297f,
0.0104984f, 0.0119633f, 0.0135502f, 0.0151982f, 0.0169988f,
0.0188604f, 0.0208441f, 0.0229194f, 0.025116701f, 0.027405599f,
0.0298166f, 0.032319099f, 0.0349437f, 0.037659802f, 0.040467501f,
0.043427799f, 0.046479698f, 0.049623098f, 0.052888598f, 0.056276102f,
0.059785798f, 0.063386902f, 0.067110203f, 0.0709555f, 0.074922897f,
0.078981899f, 0.083162896f, 0.087466002f, 0.091921799f, 0.096469f,
0.101138f, 0.10593f, 0.110843f, 0.115879f, 0.121036f,
0.12634701f, 0.13174801f, 0.13730299f, 0.142979f, 0.14877801f,
0.15472899f, 0.160772f, 0.166997f, 0.173315f, 0.179785f,
0.186407f, 0.193121f, 0.200018f, 0.20700701f, 0.21417899f,
0.22147299f, 0.228919f, 0.236488f, 0.24420901f, 0.252083f,
0.260079f, 0.26825801f, 0.276559f, 0.28501201f, 0.29364899f,
0.30240801f, 0.31131899f, 0.32038301f, 0.32960001f, 0.33899999f,
0.34852099f, 0.358226f, 0.36808401f, 0.37809399f, 0.38828701f,
0.398633f, 0.40913099f, 0.41981301f, 0.43064699f, 0.44166401f,
0.45286399f, 0.46421701f, 0.47575301f, 0.48744199f, 0.499313f,
0.51139897f, 0.523606f, 0.53602701f, 0.54863101f, 0.56141901f,
0.57438898f, 0.587542f, 0.60087901f, 0.61439902f, 0.62813199f,
0.64201802f, 0.65614802f, 0.67043102f, 0.68492699f, 0.699637f,
0.71452999f, 0.72963703f, 0.74492598f, 0.76042998f, 0.77614701f,
0.792077f, 0.808191f, 0.82454902f, 0.84109002f, 0.85784501f,
0.87484401f, 0.89205599f, 0.90945202f, 0.927122f, 0.94500601f,
0.96307302f, 0.98141402f, 1.f, 1.f,
};
static float pan_tab[4] = {
0.f,
0.7079f,
1.0f,
1.0f,
};
static float pan_tab_dpl2[4] = {
0.575f,
0.7079f,
1.f,
1.f,
};
void CalcBus(float* vol_tab, float* vl, float* vr, float* vs, float vol, struct SAL_PANINFO* pi) {
u32 i; // r29
float f; // r62
float v; // r63
i = vol * 127.f;
v = (vol * 127) - (float)i;
f = (1.f - v) * vol_tab[i] + v * vol_tab[i + 1];
*vs = f * ((1.f - pi->span_f) * pan_tab[pi->span_i] + pi->span_f * pan_tab[pi->span_i + 1]) *
0.7079f;
f = f * ((1.f - pi->span_fm) * pan_tab[pi->span_im] + pi->span_fm * pan_tab[pi->span_im + 1]);
*vr = f * ((1.f - pi->pan_f) * pan_tab[pi->pan_i] + pi->pan_f * pan_tab[pi->pan_i + 1]);
*vl = f * ((1.f - pi->pan_fm) * pan_tab[pi->pan_im] + pi->pan_fm * pan_tab[pi->pan_im + 1]);
}
void CalcBusDPL2(float* vol_tab, float* fvl, float* fvr, float* rvl, float* rvr, float vol,
SAL_PANINFO* pi) {
u32 i; // r29
float f; // r62
float v; // r63
float vs; // r61
i = vol * 127;
f = vol * 127 - (float)i;
v = (1.f - f) * vol_tab[i] + f * vol_tab[i + 1];
vs = v * ((1.f - pi->span_f) * pan_tab[pi->span_i] + pi->span_f * pan_tab[pi->span_i + 1]);
v *= (1.f - pi->span_fm) * pan_tab[pi->span_im] + pi->span_fm * pan_tab[pi->span_im + 1];
*fvr = v * ((1.f - pi->pan_f) * pan_tab[pi->pan_i] + pi->pan_f * pan_tab[pi->pan_i + 1]);
*fvl = v * ((1.f - pi->pan_fm) * pan_tab[pi->pan_im] + pi->pan_fm * pan_tab[pi->pan_im + 1]);
*rvr =
vs * ((1.f - pi->rpan_f) * pan_tab_dpl2[pi->rpan_i] + pi->rpan_f * pan_tab[pi->rpan_i + 1]);
*rvl = vs *
((1.f - pi->rpan_fm) * pan_tab_dpl2[pi->rpan_im] + pi->rpan_fm * pan_tab[pi->rpan_im + 1]);
}
void salCalcVolume(u8 voltab_index, SAL_VOLINFO* vi, float vol, u32 pan, u32 span, float auxa,
float auxb, u32 itd, u32 dpl2) {
float* vol_tab; // r30
float p; // r63
float sp; // r62
SAL_PANINFO pi; // r1+0x2C
if (voltab_index == 0) {
vol_tab = musyx_vol_tab;
} else {
vol_tab = dspDLSVolTab;
}
if (pan == 0x800000) {
pan = 0;
span = 0x7f0000;
}
pan = (pan <= 0x10000 ? 0 : pan - 0x10000);
span = (span <= 0x10000 ? 0 : span - 0x10000);
p = pan * 2.4220301e-07f;
sp = span * 2.4220301e-07f;
if (dpl2 != FALSE) {
pi.rpan_f = fmodf(p, 1.f);
pi.rpan_i = p;
pi.rpan_fm = fmodf(2.f - p, 1.f);
pi.rpan_im = 2.f - p;
}
if (itd != FALSE) {
p = (p - 1.f) * 0.76604f + 1.f;
}
pi.pan_f = fmodf(p, 1.f);
pi.pan_i = p;
pi.span_f = fmodf(sp, 1.f);
pi.span_i = sp;
p = 2.f - p;
sp = 2.f - sp;
pi.pan_fm = fmodf(p, 1.f);
pi.pan_im = p;
pi.span_fm = fmodf(sp, 1.f);
pi.span_im = sp;
if (!dpl2) {
CalcBus(vol_tab, &vi->volL, &vi->volR, &vi->volS, vol, &pi);
CalcBus(vol_tab, &vi->volAuxAL, &vi->volAuxAR, &vi->volAuxAS, auxa, &pi);
CalcBus(vol_tab, &vi->volAuxBL, &vi->volAuxBR, &vi->volAuxBS, auxb, &pi);
} else {
CalcBusDPL2(vol_tab, &vi->volL, &vi->volR, &vi->volAuxBL, &vi->volAuxBR, vol, &pi);
CalcBus(vol_tab, &vi->volAuxAL, &vi->volAuxAR, &vi->volAuxAS, auxa, &pi);
vi->volS = 0.f;
vi->volAuxBS = 0.f;
}
}

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,331 +0,0 @@
#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;
void dataInitStack() { sp = 0; }
static MEM_DATA* GetPoolAddr(u16 id, MEM_DATA* m) {
while (m->nextOff != 0xFFFFFFFF) {
if (m->id == id) {
return m;
}
m = (MEM_DATA*)((u8*)m + m->nextOff);
}
return NULL;
}
static MEM_DATA* GetMacroAddr(u16 id, POOL_DATA* pool) {
return pool == NULL ? NULL : GetPoolAddr(id, (MEM_DATA*)((u8*)pool + pool->macroOff));
}
static MEM_DATA* GetCurveAddr(u16 id, POOL_DATA* pool) {
return pool == NULL ? NULL : GetPoolAddr(id, (MEM_DATA*)((u8*)pool + pool->curveOff));
}
static MEM_DATA* GetKeymapAddr(u16 id, POOL_DATA* pool) {
return pool == NULL ? NULL : GetPoolAddr(id, (MEM_DATA*)((u8*)pool + pool->keymapOff));
}
static MEM_DATA* GetLayerAddr(u16 id, POOL_DATA* pool) {
return pool == NULL ? NULL : GetPoolAddr(id, (MEM_DATA*)((u8*)pool + pool->layerOff));
}
static void InsertData(u16 id, void* data, u8 dataType, u32 remove) {
MEM_DATA* m; // r30
switch (dataType) {
case 0:
if (!remove) {
if ((m = GetMacroAddr(id, data)) != NULL) {
dataInsertMacro(id, &m->data.cmd);
} else {
dataInsertMacro(id, NULL);
}
} else {
dataRemoveMacro(id);
}
break;
case 2: {
id |= 0x4000;
if (!remove) {
if ((m = GetKeymapAddr(id, data)) != NULL) {
dataInsertKeymap(id, &m->data.map);
} else {
dataInsertKeymap(id, NULL);
}
} else {
dataRemoveKeymap(id);
}
} break;
case 3: {
id |= 0x8000;
if (!remove) {
if ((m = GetLayerAddr(id, data)) != NULL) {
dataInsertLayer(id, &m->data.layer.entry, m->data.layer.num);
} else {
dataInsertLayer(id, NULL, 0);
}
} else {
dataRemoveLayer(id);
}
} break;
case 4:
if (!remove) {
if ((m = GetCurveAddr(id, data)) != NULL) {
dataInsertCurve(id, &m->data.tab);
} else {
dataInsertCurve(id, NULL);
}
} else {
dataRemoveCurve(id);
}
break;
case 1:
if (!remove) {
dataAddSampleReference(id);
} else {
dataRemoveSampleReference(id);
}
break;
}
}
static void ScanIDList(u16* ref, void* data, u8 dataType, u32 remove) {
u16 id; // r30
while (*ref != 0xFFFF) {
if ((*ref & 0x8000)) {
id = *ref & 0x3fff;
while (id <= ref[1]) {
InsertData(id, data, dataType, remove);
++id;
}
ref += 2;
} else {
InsertData(*ref++, data, dataType, remove);
}
}
}
static void ScanIDListReverse(u16* refBase, void* data, u8 dataType, u32 remove) {
s16 id;
u16* ref;
if (*refBase != 0xffff) {
ref = refBase;
while (*ref != 0xffff) {
ref++;
}
ref--;
while (ref >= refBase) {
if (ref != refBase) {
if ((ref[-1] & 0x8000) != 0) {
id = *ref;
while (id >= (s16)(ref[-1] & 0x3fff)) {
InsertData(id, data, dataType, remove);
id--;
}
ref -= 2;
} else {
InsertData(*ref, data, dataType, remove);
ref--;
}
} else {
InsertData(*ref, data, dataType, remove);
ref--;
}
}
}
}
static void InsertMacros(unsigned short* ref, void* pool) { ScanIDList(ref, pool, 0, 0); }
static void InsertCurves(unsigned short* ref, void* pool) { ScanIDList(ref, pool, 4, 0); }
static void InsertKeymaps(unsigned short* ref, void* pool) { ScanIDList(ref, pool, 2, 0); }
static void InsertLayers(unsigned short* ref, void* pool) { ScanIDList(ref, pool, 3, 0); }
static void RemoveMacros(unsigned short* ref) { ScanIDList(ref, NULL, 0, 1); }
static void RemoveCurves(unsigned short* ref) { ScanIDList(ref, NULL, 4, 1); }
static void RemoveKeymaps(unsigned short* ref) { ScanIDList(ref, NULL, 2, 1); }
static void RemoveLayers(unsigned short* ref) { ScanIDList(ref, NULL, 3, 1); }
static void InsertSamples(u16* ref, void* samples, void* sdir) {
samples = hwTransAddr(samples);
if (dataInsertSDir((SDIR_DATA*)sdir, samples)) {
ScanIDList(ref, sdir, 1, 0);
}
}
static void RemoveSamples(unsigned short* ref, void* sdir) {
ScanIDListReverse(ref, NULL, 1, 1);
dataRemoveSDir(sdir);
}
static void InsertFXTab(unsigned short gid, FX_DATA* fd) { dataInsertFX(gid, fd->fx, fd->num); }
static void RemoveFXTab(unsigned short gid) { dataRemoveFX(gid); }
void sndSetSampleDataUploadCallback(void* (*callback)(u32, u32),
u32 chunckSize) {
hwSetSaveSampleCallback(callback, chunckSize);
}
bool sndPushGroup(void* prj_data, u16 gid, void* samples, void* sdir, void* pool) {
GROUP_DATA* g; // r31
MUSY_ASSERT_MSG(prj_data != NULL, "Project data pointer is NULL");
MUSY_ASSERT_MSG(sdir != NULL, "Sample directory pointer is NULL");
if (sndActive && sp < 128) {
g = prj_data;
while (g->nextOff != 0xFFFFFFFF) {
if (g->id == gid) {
gs[sp].gAddr = g;
gs[sp].prjAddr = prj_data;
gs[sp].sdirAddr = sdir;
InsertSamples((u16*)((u8*)prj_data + g->sampleOff), samples, sdir);
InsertMacros((u16*)((u8*)prj_data + g->macroOff), pool);
InsertCurves((u16*)((u8*)prj_data + g->curveOff), pool);
InsertKeymaps((u16*)((u8*)prj_data + g->keymapOff), pool);
InsertLayers((u16*)((u8*)prj_data + g->layerOff), pool);
if (g->type == 1) {
InsertFXTab(gid, (FX_DATA*)((u8*)prj_data + g->data.song.normpageOff));
}
hwSyncSampleMem();
++sp;
return TRUE;
}
g = (GROUP_DATA*)((u8*)prj_data + g->nextOff);
}
}
MUSY_DEBUG("Group ID=%d could not be pushed.\n", gid);
return FALSE;
}
/*
*/
bool sndPopGroup() {
GROUP_DATA* g;
SDIR_DATA* sdir;
void* prj;
FX_DATA* fd;
MUSY_ASSERT_MSG(sndActive != FALSE, "Sound system is not initialized.");
MUSY_ASSERT_MSG(sp != 0, "Soundstack is empty.");
g = gs[--sp].gAddr;
prj = gs[sp].prjAddr;
sdir = gs[sp].sdirAddr;
hwDisableIrq();
if (g->type == 1) {
fd = (FX_DATA*)((u8*)prj + g->data.song.normpageOff);
s3dKillEmitterByFXID(fd->fx, fd->num);
} else {
seqKillInstancesByGroupID(g->id);
}
synthKillVoicesByMacroReferences((u16*)((u8*)prj + g->macroOff));
hwEnableIrq();
RemoveSamples((u16*)((u8*)prj + g->sampleOff), sdir);
RemoveMacros((u16*)((u8*)prj + g->macroOff));
RemoveCurves((u16*)((u8*)prj + g->curveOff));
RemoveKeymaps((u16*)((u8*)prj + g->keymapOff));
RemoveLayers((u16*)((u8*)prj + g->layerOff));
if (g->type == 1) {
RemoveFXTab(g->id);
}
return 1;
}
/*
*/
u32 seqPlaySong(u16 sgid, u16 sid, void* arrfile, SND_PLAYPARA* para, u8 irq_call, u8 studio) {
int i;
GROUP_DATA* g;
PAGE* norm;
PAGE* drum;
MIDISETUP* midiSetup;
u32 seqId;
void* prj;
MUSY_ASSERT_MSG(sndActive != FALSE, "Sound system is not initialized.");
for (i = 0; i < sp; ++i) {
if (sgid != gs[i].gAddr->id) {
continue;
}
if (gs[i].gAddr->type == 0) {
g = gs[i].gAddr;
prj = gs[i].prjAddr;
norm = (PAGE*)((size_t)prj + g->data.song.normpageOff);
drum = (PAGE*)((size_t)prj + g->data.song.drumpageOff);
midiSetup = (MIDISETUP*)((size_t)prj + g->data.song.midiSetupOff);
while (midiSetup->songId != 0xFFFF) {
if (midiSetup->songId == sid) {
if (irq_call != 0) {
seqId = seqStartPlay(norm, drum, midiSetup, arrfile, para, studio, sgid);
} else {
hwDisableIrq();
seqId = seqStartPlay(norm, drum, midiSetup, arrfile, para, studio, sgid);
hwEnableIrq();
}
return seqId;
}
++midiSetup;
}
MUSY_DEBUG("Song ID=%d is not in group ID=%d.", sid, sgid);
return 0xffffffff;
} else {
MUSY_DEBUG("Group ID=%d is no songgroup.", sgid);
return 0xffffffff;
}
}
MUSY_DEBUG("Group ID=%d is not on soundstack.", sgid);
return 0xffffffff;
}
u32 sndSeqPlayEx(u16 sgid, u16 sid, void* arrfile, SND_PLAYPARA* para, u8 studio) {
return seqPlaySong(sgid, sid, arrfile, para, 0, studio);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,354 +0,0 @@
/*
*/
#include "musyx/assert.h"
#include "musyx/hardware.h"
#include "musyx/seq.h"
/*
*/
void sndSeqCrossFade(struct SND_CROSSFADE* ci, u32* new_seqId) {
MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized.");
MUSY_ASSERT_MSG(ci != NULL, "Crossfade information pointer is NULL.");
MUSY_ASSERT_MSG(ci->studio2 < 8, "Studio index is illegal.");
MUSY_ASSERT_MSG(hwIsStudioActive(ci->studio2), "Selected studio is inactive.");
hwDisableIrq();
seqCrossFade(ci, new_seqId, 0);
hwEnableIrq();
}
/*
*/
bool sndSeqCrossFadeDone(SND_SEQID* new_seqId) {
if (*new_seqId != -1) {
return (*new_seqId & 0x80000000) == 0;
}
return TRUE;
}
u16 sndSeqGetLoopCnt(SND_SEQID seqId) {
MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized.");
seqId = seqGetPrivateId(seqId);
if (seqId != -1 && (seqId & 0x80000000) == 0) {
return seqInstance[seqId].section[0].loopCnt;
}
return 0;
}
/*
*/
u16 sndSeqGetLoopCntEx(u32 seqId, u8 track) {
MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized.");
seqId = seqGetPrivateId(seqId);
if (seqId != -1 && (seqId & 0x80000000) == 0) {
if (seqInstance[seqId].trackSectionTab == NULL) {
return seqInstance[seqId].section[0].loopCnt;
} else {
return seqInstance[seqId].section[seqInstance[seqId].trackSectionTab[track]].loopCnt;
}
}
return 0;
}
/*
*/
bool sndSeqGetValid(SND_SEQID seqId) {
MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized.");
return seqGetPrivateId(seqId) != -1;
}
/*
*/
void sndSeqPause(SND_SEQID seqId) {
MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized.");
hwDisableIrq();
seqPause(seqId);
hwEnableIrq();
}
/*
*/
void sndSeqStop(SND_SEQID seqid) {
MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized.");
hwDisableIrq();
seqStop(seqid);
hwEnableIrq();
}
/*
*/
bool sndSeqLoop(SND_SEQID seqId, bool on) {
unsigned long i; // r30
MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized.");
if ((seqId = seqGetPrivateId(seqId)) != -1) {
if ((seqId & 0x80000000) == 0) {
for (i = 0; i < 16; ++i) {
seqInstance[seqId].section[i].loopDisable = !on;
}
return TRUE;
}
MUSY_DEBUG("Sequencer ID is temporary.\n");
} else {
MUSY_DEBUG("Sequencer ID is not valid.\n");
}
return FALSE;
}
/*
*/
bool sndSeqLoopEx(SND_SEQID seqId, u8 track, bool on) {
u32 i; // r29
MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized.");
if ((seqId = seqGetPrivateId(seqId)) != -1) {
if ((seqId & 0x80000000) == 0) {
if (seqInstance[seqId].trackSectionTab == NULL) {
for (i = 0; i < 16; ++i) {
seqInstance[seqId].section[i].loopDisable = !on;
}
return TRUE;
}
seqInstance[seqId].section[seqInstance[seqId].trackSectionTab[track]].loopDisable = !on;
return TRUE;
}
MUSY_DEBUG("Sequencer ID is temporary.\n");
} else {
MUSY_DEBUG("Sequencer ID is not valid.\n");
}
return FALSE;
}
/*
*/
void sndSeqSpeed(u32 seqId, u16 speed) {
MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized.");
hwDisableIrq();
seqSpeed(seqId, speed);
hwEnableIrq();
}
/*
*/
void sndSeqContinue(SND_SEQID seqId) {
MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized.");
hwDisableIrq();
seqContinue(seqId);
hwEnableIrq();
}
/*
*/
void sndSeqMute(SND_SEQID seqId, u32 mask1, u32 mask2) {
MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized.");
hwDisableIrq();
seqMute(seqId, mask1, mask2);
hwEnableIrq();
}
/*
*/
void sndSeqVolume(u8 volume, u16 time, u32 seqId, u8 mode) {
MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized.");
hwDisableIrq();
seqVolume(volume, time, seqId, mode);
hwEnableIrq();
}
/*
*/
u8 sndSeqGetVolGroup(SND_SEQID seqId) {
MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized.");
if ((seqId = seqGetPrivateId(seqId)) != -1) {
return seqInstance[seqId].defVGroup;
}
MUSY_DEBUG("Volume group could not be received from sequencer.\n");
return 0;
}
/*
*/
bool sndSeqAssignVolGroup2Track(SND_SEQID seqId, u8 track, u8 vGroup) {
MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized.");
if ((seqId = seqGetPrivateId(seqId)) != -1) {
seqInstance[seqId].trackVolGroup[track] = vGroup;
synthSetMusicVolumeType(vGroup, 2);
return TRUE;
}
MUSY_DEBUG("Volume group could not be assigned to track.\n");
return FALSE;
}
/*
*/
u8 sndSeqGetMidiCtrl(SND_SEQID seqId, u8 channel, u8 ctrl) {
u8 value; // r31
MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized.");
value = 0;
hwDisableIrq();
if ((seqId = seqGetPrivateId(seqId)) != -1) {
value = inpGetMidiCtrl(ctrl, channel, seqId) >> 7;
}
hwEnableIrq();
return value;
}
/*
*/
u16 sndSeqGetMidiCtrl14(SND_SEQID seqId, u8 channel, u8 ctrl) {
u16 value; // r31
MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized.");
value = 0;
hwDisableIrq();
if ((seqId = seqGetPrivateId(seqId)) != -1) {
value = inpGetMidiCtrl(ctrl, channel, seqId);
}
hwEnableIrq();
return value;
}
/*
*/
bool sndSeqSetMidiCtrl(SND_SEQID seqId, u8 channel, u8 ctrl, u8 value) {
unsigned long ret = FALSE; // r30
MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized.");
hwDisableIrq();
if ((seqId = seqGetPrivateId(seqId)) != -1) {
inpSetMidiCtrl(ctrl, channel, seqId, value);
ret = TRUE;
} else {
MUSY_DEBUG("Sequenzer ID is not valid.\n\n");
}
hwEnableIrq();
return ret;
}
/*
*/
bool sndSeqSetMidiCtrl14(SND_SEQID seqId, u8 channel, u8 ctrl, u16 value) {
bool ret = FALSE; // r30
MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized.");
hwDisableIrq();
if ((seqId = seqGetPrivateId(seqId)) != -1) {
inpSetMidiCtrl14(ctrl, channel, seqId, value);
ret = TRUE;
} else {
MUSY_DEBUG("Sequenzer ID is not valid.\n\n");
}
hwEnableIrq();
return ret;
}
u16 seqGetMIDIPriority(u8 set, u8 channel) { return seqMIDIPriority[set][channel]; }

File diff suppressed because it is too large Load Diff

View File

@ -1,173 +0,0 @@
/*
*/
#include "musyx/assert.h"
#include "musyx/hardware.h"
#include "musyx/s3d.h"
#include "musyx/seq.h"
#include "musyx/stream.h"
#include "musyx/synth.h"
#include "musyx/synthdata.h"
// #define _DEBUG
/*
*/
#if MUSY_VERSION >= MUSY_VERSION_CHECK(2, 0, 3)
long DoInit(u32 mixFrq, u32 numVoices, u32 flags, u32 aramBase, u32 aramSize)
#else
static s32 DoInit(u32 mixFrq, u32 aramSize, u32 numVoices, u32 flags)
#endif
{
bool ret;
MUSY_DEBUG("\nMusyX software initialization...\nBuild Date: %s %s\n\n", __DATE__, __TIME__);
ret = FALSE;
#if MUSY_VERSION >= MUSY_VERSION_CHECK(2, 0, 3)
dataInitStack(aramBase, aramGetUserBytes(aramSize));
#else
dataInitStack();
#endif
dataInit(0, aramSize);
seqInit();
synthIdleWaitActive = 0;
synthInit(mixFrq, numVoices);
streamInit();
vsInit();
s3dInit(flags);
sndActive = 1;
MUSY_DEBUG("MusyX logic is initialized.\n\n");
return ret;
}
/*
*/
s32 sndInit(u8 voices, u8 music, u8 sfx, u8 studios, u32 flags, u32 aramSize) {
s32 ret; // r31
u32 frq; // r1+0x14
MUSY_DEBUG("Entering sndInit()\n\n");
ret = 0;
sndActive = 0;
if (voices <= 64) {
synthInfo.voiceNum = voices;
} else {
synthInfo.voiceNum = 64;
}
if (studios <= 8) {
synthInfo.studioNum = studios;
} else {
synthInfo.studioNum = 8;
}
synthInfo.maxMusic = music;
synthInfo.maxSFX = sfx;
frq = 32000;
if ((ret = hwInit(&frq, synthInfo.voiceNum, synthInfo.studioNum, flags)) == 0) {
#if MUSY_VERSION >= MUSY_VERSION_CHECK(2, 0, 3)
ret = DoInit(32000, synthInfo.voiceNum, flags, aramGetFirstUserAddress(), aramSize);
#else
ret = DoInit(32000, aramSize, synthInfo.voiceNum, flags);
#endif
}
MUSY_DEBUG("Leaving sndInit().\n\n");
return ret;
}
/* */
void sndQuit() {
MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized.");
hwExit();
/*
*/
dataExit();
/*
*/
s3dExit();
/* */
synthExit();
/* */
sndActive = 0;
}
/*
*/
void sndSetMaxVoices(u8 music, u8 sfx) {
MUSY_ASSERT_MSG(music <= synthInfo.voiceNum, "Music voices are above maximum voice number.");
MUSY_ASSERT_MSG(sfx <= synthInfo.voiceNum, "Sfx voices are above maximum voice number.");
synthInfo.maxMusic = music;
synthInfo.maxSFX = sfx;
}
/*
*/
bool sndIsInstalled() { return sndActive; }
/*
*/
SND_PLAYBACKINFO* sndGetPlayBackInfo() {
if (sndActive) {
return &synthInfo.pbInfo;
}
return NULL;
}
#if MUSY_VERSION >= MUSY_VERSION_CHECK(2, 0, 3)
void sndSetLowPassFilterDefaultRange(unsigned long lowFrq, unsigned long highFrq) {
inpSetLPFDefaultRange(lowFrq, highFrq);
}
#endif

View File

@ -1,46 +0,0 @@
#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];
out->y = mat->m[1][0] * in->x + mat->m[1][1] * in->y + mat->m[1][2] * in->z + mat->t[1];
out->z = mat->m[2][0] * in->x + mat->m[2][1] * in->y + mat->m[2][2] * in->z + mat->t[2];
}
float salNormalizeVector(SND_FVECTOR* vec) {
float l = sqrtf(vec->x * vec->x + vec->y * vec->y + vec->z * vec->z);
vec->x /= l;
vec->y /= l;
vec->z /= l;
return l;
}
void salCrossProduct(SND_FVECTOR* out, const SND_FVECTOR* a, const SND_FVECTOR* b) {
out->x = (a->y * b->z) - (a->z * b->y);
out->y = (a->z * b->x) - (a->x * b->z);
out->z = (a->x * b->y) - (a->y * b->x);
}
void salInvertMatrix(SND_FMATRIX* out, const SND_FMATRIX* in) {
float a; // r62
float b; // r61
float c; // r60
float f; // r63
a = in->m[1][1] * in->m[2][2] - in->m[2][1] * in->m[1][2];
b = -(in->m[1][0] * in->m[2][2] - in->m[2][0] * in->m[1][2]);
c = in->m[1][0] * in->m[2][1] - in->m[2][0] * in->m[1][1];
f = 1.f / (in->m[0][0] * a + in->m[0][1] * b + in->m[0][2] * c);
out->m[0][0] = f * a;
out->m[1][0] = f * b;
out->m[2][0] = f * c;
out->m[0][1] = -f * (in->m[0][1] * in->m[2][2] - in->m[2][1] * in->m[0][2]);
out->m[1][1] = f * (in->m[0][0] * in->m[2][2] - in->m[2][0] * in->m[0][2]);
out->m[2][1] = -f * (in->m[0][0] * in->m[2][1] - in->m[2][0] * in->m[0][1]);
out->m[0][2] = f * (in->m[0][1] * in->m[1][2] - in->m[1][1] * in->m[0][2]);
out->m[1][2] = -f * (in->m[0][0] * in->m[1][2] - in->m[1][0] * in->m[0][2]);
out->m[2][2] = f * (in->m[0][0] * in->m[1][1] - in->m[1][0] * in->m[0][1]);
out->t[0] = (-in->t[0] * out->m[0][0] - in->t[1] * out->m[0][1]) - in->t[2] * out->m[0][2];
out->t[1] = (-in->t[0] * out->m[1][0] - in->t[1] * out->m[1][1]) - in->t[2] * out->m[1][2];
out->t[2] = (-in->t[0] * out->m[2][0] - in->t[1] * out->m[2][1]) - in->t[2] * out->m[2][2];
}

View File

@ -1,644 +0,0 @@
/*
*/
#include "musyx/assert.h"
#include "musyx/seq.h"
#include "musyx/synth.h"
#include <string.h>
#define SYNTH_FX_MIDISET 0xFF
static u8 midi_lastNote[8][16];
static u8 fx_lastNote[64];
static u8 midi_ctrl[8][16][134];
static u8 fx_ctrl[64][134];
static u32 inpGlobalMIDIDirtyFlags[8][16];
static CHANNEL_DEFAULTS inpChannelDefaults[8][16];
static CHANNEL_DEFAULTS inpFXChannelDefaults[64];
static inline bool GetGlobalFlagSet(u8 chan, u8 midiSet, s32 flag) {
return (flag & inpGlobalMIDIDirtyFlags[midiSet][chan]) != 0;
}
/*
*/
static void inpResetGlobalMIDIDirtyFlags() {
u32 i, j;
for (i = 0; i < 8; ++i) {
for (j = 0; j < 16; ++j) {
inpGlobalMIDIDirtyFlags[i][j] = 0xFF;
}
}
}
static u32 inpResetGlobalMIDIDirtyFlag(u8 chan, u8 midiSet, u32 flag) {
u32 ret;
// clang-format off
MUSY_ASSERT(midiSet!=SYNTH_FX_MIDISET);
// clang-format on
if ((ret = GetGlobalFlagSet(chan, midiSet, flag))) {
inpGlobalMIDIDirtyFlags[midiSet][chan] &= ~flag;
}
return ret;
}
void inpSetGlobalMIDIDirtyFlag(u8 chan, u8 midiSet, s32 flag) {
// clang-format off
MUSY_ASSERT(midiSet!=SYNTH_FX_MIDISET);
// clang-format on
inpGlobalMIDIDirtyFlags[midiSet][chan] |= flag;
}
void inpSetRPNHi(u8 set, u8 channel, u8 value) {
u16 rpn; // r28
u32 i; // r31
u8 range; // r29
rpn = (midi_ctrl[set][channel][100]) | (midi_ctrl[set][channel][101] << 8);
switch (rpn) {
case 0:
range = value > 24 ? 24 : value;
inpChannelDefaults[set][channel].pbRange = range;
for (i = 0; i < synthInfo.voiceNum; ++i) {
if (set == synthVoice[i].midiSet && channel == synthVoice[i].midi) {
synthVoice[i].pbUpperKeyRange = range;
synthVoice[i].pbLowerKeyRange = range;
}
}
break;
default:
break;
}
}
void inpSetRPNLo(u8 set, u8 channel, u8 value) {}
void inpSetRPNDec(u8 set, u8 channel) {
u16 rpn; // r28
u32 i; // r31
u8 range; // r30
rpn = (midi_ctrl[set][channel][100]) | (midi_ctrl[set][channel][101] << 8);
switch (rpn) {
case 0:
range = inpChannelDefaults[set][channel].pbRange;
if (range != 0) {
--range;
}
inpChannelDefaults[set][channel].pbRange = range;
for (i = 0; i < synthInfo.voiceNum; ++i) {
if (set == synthVoice[i].midiSet && channel == synthVoice[i].midi) {
synthVoice[i].pbUpperKeyRange = range;
synthVoice[i].pbLowerKeyRange = range;
}
}
break;
default:
break;
}
}
void inpSetRPNInc(u8 set, u8 channel) {
u16 rpn; // r28
u32 i; // r31
u8 range; // r30
rpn = (midi_ctrl[set][channel][100]) | (midi_ctrl[set][channel][101] << 8);
switch (rpn) {
case 0:
range = inpChannelDefaults[set][channel].pbRange;
if (range < 24) {
++range;
}
inpChannelDefaults[set][channel].pbRange = range;
for (i = 0; i < synthInfo.voiceNum; ++i) {
if (set == synthVoice[i].midiSet && channel == synthVoice[i].midi) {
synthVoice[i].pbUpperKeyRange = range;
synthVoice[i].pbLowerKeyRange = range;
}
}
break;
default:
break;
}
}
void inpSetMidiCtrl(u8 ctrl, u8 channel, u8 set, u8 value) {
u32 i;
if (channel == 0xFF) {
return;
}
if (set != 0xFF) {
switch (ctrl) {
case 6:
inpSetRPNHi(set, channel, value);
break;
case 38:
inpSetRPNLo(set, channel, value);
break;
case 96:
inpSetRPNDec(set, channel);
break;
case 97:
inpSetRPNInc(set, channel);
break;
}
midi_ctrl[set][channel][ctrl] = value & 0x7f;
for (i = 0; i < synthInfo.voiceNum; ++i) {
if (set == synthVoice[i].midiSet && channel == synthVoice[i].midi) {
synthVoice[i].midiDirtyFlags = 0x1fff;
synthKeyStateUpdate(&synthVoice[i]);
}
}
inpGlobalMIDIDirtyFlags[set][channel] = 0xff;
} else {
switch (ctrl) {
case 6:
inpSetRPNHi(set, channel, value);
break;
case 38:
inpSetRPNLo(set, channel, value);
break;
case 96:
inpSetRPNDec(set, channel);
break;
case 97:
inpSetRPNInc(set, channel);
break;
}
fx_ctrl[channel][ctrl] = value & 0x7f;
for (i = 0; i < synthInfo.voiceNum; ++i) {
if (set == synthVoice[i].midiSet && channel == synthVoice[i].midi) {
synthVoice[i].midiDirtyFlags = 0x1fff;
synthKeyStateUpdate(&synthVoice[i]);
}
}
}
}
void inpSetMidiCtrl14(u8 ctrl, u8 channel, u8 set, u16 value) {
if (channel == 0xFF) {
return;
}
if (ctrl < 64) {
inpSetMidiCtrl(ctrl & 31, channel, set, value >> 7);
inpSetMidiCtrl((ctrl & 31) + 32, channel, set, value & 0x7f);
} else if (ctrl == 128 || ctrl == 129) {
inpSetMidiCtrl(ctrl & 254, channel, set, value >> 7);
inpSetMidiCtrl((ctrl & 254) + 1, channel, set, value & 0x7f);
} else if (ctrl == 132 || ctrl == 133) {
inpSetMidiCtrl(ctrl & 254, channel, set, value >> 7);
inpSetMidiCtrl((ctrl & 254) + 1, channel, set, value & 0x7f);
} else {
inpSetMidiCtrl(ctrl, channel, set, value >> 7);
}
}
static const u8 inpColdMIDIDefaults[134] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x40, 0x7F, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x7F, 0x7F, 0x7F, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00,
};
static const u8 inpWarmMIDIDefaults[134] = {
0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
};
void inpResetMidiCtrl(u8 ch, u8 set, u32 coldReset) {
const u8* values; // r30
u8* dest; // r29
u32 i; // r31
values = coldReset ? inpColdMIDIDefaults : inpWarmMIDIDefaults;
dest = set != 0xFF ? midi_ctrl[set][ch] : fx_ctrl[ch];
if (coldReset) {
memcpy(dest, values, 134);
} else {
for (i = 0; i < 134; ++i) {
if (values[i] != 0xFF) {
dest[i] = values[i];
}
}
}
inpSetMidiLastNote(ch, set, 0xFF);
}
u16 inpGetMidiCtrl(u8 ctrl, u8 channel, u8 set) {
if (channel != 0xff) {
if (set != 0xff) {
if (ctrl < 0x40) {
return midi_ctrl[set][channel][ctrl & 0x1f] << 7 |
midi_ctrl[set][channel][(ctrl & 0x1f) + 0x20];
} else if (ctrl < 0x46) {
return midi_ctrl[set][channel][ctrl] < 0x40 ? 0 : 0x3fff;
} else if (ctrl >= 0x60 && ctrl < 0x66) {
return 0;
} else {
if ((ctrl == 0x80) || (ctrl == 0x81)) {
return midi_ctrl[set][channel][ctrl & 0xfe] << 7 |
midi_ctrl[set][channel][(ctrl & 0xfe) + 1];
} else if ((ctrl == 0x84) || (ctrl == 0x85)) {
return midi_ctrl[set][channel][ctrl & 0xfe] << 7 |
midi_ctrl[set][channel][(ctrl & 0xfe) + 1];
} else {
return midi_ctrl[set][channel][ctrl] << 7;
}
}
} else {
if (ctrl < 0x40) {
return fx_ctrl[channel][ctrl & 0x1f] << 7 | fx_ctrl[channel][(ctrl & 0x1f) + 0x20];
} else if (ctrl < 0x46) {
return fx_ctrl[channel][ctrl] < 0x40 ? 0 : 0x3fff;
} else if (ctrl >= 0x60 && ctrl < 0x66) {
return 0;
} else {
if ((ctrl == 0x80) || (ctrl == 0x81)) {
return fx_ctrl[channel][ctrl & 0xfe] << 7 | fx_ctrl[channel][(ctrl & 0xfe) + 1];
} else if ((ctrl == 0x84) || (ctrl == 0x85)) {
return fx_ctrl[channel][ctrl & 0xfe] << 7 | fx_ctrl[channel][(ctrl & 0xfe) + 1];
} else {
return fx_ctrl[channel][ctrl] << 7;
}
}
}
}
return 0;
}
CHANNEL_DEFAULTS* inpGetChannelDefaults(u8 midi, u8 midiSet) {
if (midiSet == 0xFF) {
return &inpFXChannelDefaults[midi];
}
return &inpChannelDefaults[midiSet][midi];
}
void inpResetChannelDefaults(u8 midi, u8 midiSet) {
CHANNEL_DEFAULTS* channelDefaults; // r31
channelDefaults =
midiSet != 0xFF ? &inpChannelDefaults[midiSet][midi] : &inpFXChannelDefaults[midi];
channelDefaults->pbRange = 2;
}
void inpAddCtrl(CTRL_DEST* dest, u8 ctrl, s32 scale, u8 comb, u32 isVar) {
u8 n; // r30
if (comb == 0) {
dest->numSource = 0;
}
if (dest->numSource < 4) {
n = dest->numSource++;
if (isVar == 0) {
ctrl = inpTranslateExCtrl(ctrl);
} else {
comb |= 0x10;
}
dest->source[n].midiCtrl = ctrl;
dest->source[n].combine = comb;
dest->source[n].scale = scale;
}
}
void inpFXCopyCtrl(u8 ctrl, SYNTH_VOICE* dvoice, SYNTH_VOICE* svoice) {
u8 di; // r30
u8 si; // r29
di = dvoice->id;
si = svoice->id;
if (ctrl < 64) {
fx_ctrl[di][ctrl & 31] = fx_ctrl[si][ctrl & 31];
fx_ctrl[di][(ctrl & 31) + 32] = fx_ctrl[si][(ctrl & 31) + 32];
} else if (ctrl == 128 || ctrl == 129) {
fx_ctrl[di][ctrl & 254] = fx_ctrl[si][ctrl & 254];
fx_ctrl[di][(ctrl & 254) + 1] = fx_ctrl[si][(ctrl & 254) + 1];
} else if (ctrl == 132 || ctrl == 133) {
fx_ctrl[di][ctrl & 254] = fx_ctrl[si][ctrl & 254];
fx_ctrl[di][(ctrl & 254) + 1] = fx_ctrl[si][(ctrl & 254) + 1];
} else {
fx_ctrl[di][ctrl] = fx_ctrl[si][ctrl];
}
}
void inpSetMidiLastNote(u8 midi, u8 midiSet, u8 key) {
if (midiSet != 0xFF) {
midi_lastNote[midiSet][midi] = key;
} else {
fx_lastNote[midi] = key;
}
}
u8 inpGetMidiLastNote(u8 midi, u8 midiSet) {
if (midiSet != 0xFF) {
return midi_lastNote[midiSet][midi];
}
return fx_lastNote[midi];
}
static u16 _GetInputValue(SYNTH_VOICE* svoice, CTRL_DEST* inp, u8 midi, u8 midiSet) {
u32 i; // r26
u32 value; // r29
u8 ctrl; // r28
s32 tmp; // r31
s32 vtmp; // r30
u32 sign; // r25
for (value = 0, i = 0; i < inp->numSource; ++i) {
if (inp->source[i].combine & 0x10) {
tmp = (svoice != NULL ? varGet(svoice, 0, inp->source[i].midiCtrl) : 0);
} else {
ctrl = inp->source[i].midiCtrl;
if (ctrl == 128 || ctrl == 1 || ctrl == 10 || ctrl == 160 || ctrl == 161 || ctrl == 131) {
switch (ctrl) {
case 160:
case 161:
if (svoice != NULL) {
tmp = svoice->lfo[ctrl - 160].value << 1;
svoice->lfoUsedByInput[ctrl - 160] = 1;
} else {
tmp = 0;
}
break;
default:
tmp = inpGetMidiCtrl(ctrl, midi, midiSet) - 0x2000;
break;
}
} else if (ctrl == 163) {
tmp = svoice != NULL ? svoice->orgVolume >> 9 : 0;
} else if (ctrl < 163) {
if (ctrl < 162) {
tmp = inpGetMidiCtrl(ctrl, midi, midiSet);
} else if (svoice == NULL) {
tmp = 0;
} else {
tmp = svoice->orgNote << 7;
}
} else if (ctrl > 164) {
if (svoice != NULL) {
tmp = (synthRealTime - svoice->macStartTime) << 8;
if (tmp > 0x3fff) {
tmp = 0x3fff;
}
svoice->timeUsedByInput = 1;
} else {
tmp = 0;
}
}
tmp = (tmp * inp->source[i].scale / 2) >> 15;
}
}
inp->oldValue = value;
return value;
}
static u16 GetInputValue(SYNTH_VOICE* svoice, CTRL_DEST* inp, u32 dirtyMask) {
if (!(svoice->midiDirtyFlags & dirtyMask)) {
return inp->oldValue;
}
svoice->midiDirtyFlags &= ~dirtyMask;
return _GetInputValue(svoice, inp, svoice->midi, svoice->midiSet);
}
static u16 GetGlobalInputValue(CTRL_DEST* inp, u32 dirtyMask, u8 midi, u8 midiSet) {
if (!inpResetGlobalMIDIDirtyFlag(midi, midiSet, dirtyMask)) {
return inp->oldValue;
}
return _GetInputValue(NULL, inp, midi, midiSet);
}
u16 inpGetVolume(SYNTH_VOICE* svoice) { return GetInputValue(svoice, &svoice->inpVolume, 0x1); }
u16 inpGetPanning(SYNTH_VOICE* svoice) { return GetInputValue(svoice, &svoice->inpPanning, 0x2); }
u16 inpGetSurPanning(SYNTH_VOICE* svoice) {
return GetInputValue(svoice, &svoice->inpSurroundPanning, 0x4);
}
u16 inpGetPitchBend(SYNTH_VOICE* svoice) {
return GetInputValue(svoice, &svoice->inpPitchBend, 0x8);
}
u16 inpGetDoppler(SYNTH_VOICE* svoice) { return GetInputValue(svoice, &svoice->inpDoppler, 0x10); }
u16 inpGetModulation(SYNTH_VOICE* svoice) {
return GetInputValue(svoice, &svoice->inpModulation, 0x20);
}
u16 inpGetPedal(SYNTH_VOICE* svoice) { return GetInputValue(svoice, &svoice->inpPedal, 0x40); }
u16 inpGetPreAuxA(SYNTH_VOICE* svoice) { return GetInputValue(svoice, &svoice->inpPreAuxA, 0x100); }
u16 inpGetReverb(SYNTH_VOICE* svoice) { return GetInputValue(svoice, &svoice->inpReverb, 0x200); }
u16 inpGetPreAuxB(SYNTH_VOICE* svoice) { return GetInputValue(svoice, &svoice->inpPreAuxB, 0x400); }
u16 inpGetPostAuxB(SYNTH_VOICE* svoice) {
return GetInputValue(svoice, &svoice->inpPostAuxB, 0x800);
}
u16 inpGetTremolo(SYNTH_VOICE* svoice) {
return GetInputValue(svoice, &svoice->inpTremolo, 0x1000);
}
u16 inpGetAuxA(u8 studio, u8 index, u8 midi, u8 midiSet) {
static u32 dirtyMask[4] = {0x80000001, 0x80000002, 0x80000004, 0x80000008};
return GetGlobalInputValue(&inpAuxA[studio][index], dirtyMask[index], midi, midiSet);
}
u16 inpGetAuxB(u8 studio, u8 index, u8 midi, u8 midiSet) {
static u32 dirtyMask[4] = {0x80000010, 0x80000020, 0x80000040, 0x80000080};
return GetGlobalInputValue(&inpAuxB[studio][index], dirtyMask[index], midi, midiSet);
}
void inpInit(SYNTH_VOICE* svoice) {
u32 i; // r30
u32 s; // r29
if (svoice != NULL) {
svoice->inpVolume.source[0].midiCtrl = 7;
svoice->inpVolume.source[0].combine = 0;
svoice->inpVolume.source[0].scale = 0x10000;
svoice->inpVolume.source[1].midiCtrl = 11;
svoice->inpVolume.source[1].combine = 2;
svoice->inpVolume.source[1].scale = 0x10000;
svoice->inpVolume.numSource = 2;
svoice->inpPanning.source[0].midiCtrl = 10;
svoice->inpPanning.source[0].combine = 0;
svoice->inpPanning.source[0].scale = 0x10000;
svoice->inpPanning.numSource = 1;
svoice->inpSurroundPanning.source[0].midiCtrl = 131;
svoice->inpSurroundPanning.source[0].combine = 0;
svoice->inpSurroundPanning.source[0].scale = 0x10000;
svoice->inpSurroundPanning.numSource = 1;
svoice->inpPitchBend.source[0].midiCtrl = 128;
svoice->inpPitchBend.source[0].combine = 0;
svoice->inpPitchBend.source[0].scale = 0x10000;
svoice->inpPitchBend.numSource = 1;
svoice->inpModulation.source[0].midiCtrl = 1;
svoice->inpModulation.source[0].combine = 0;
svoice->inpModulation.source[0].scale = 0x10000;
svoice->inpModulation.numSource = 1;
svoice->inpPedal.source[0].midiCtrl = 64;
svoice->inpPedal.source[0].combine = 0;
svoice->inpPedal.source[0].scale = 0x10000;
svoice->inpPedal.numSource = 1;
svoice->inpPortamento.source[0].midiCtrl = 65;
svoice->inpPortamento.source[0].combine = 0;
svoice->inpPortamento.source[0].scale = 0x10000;
svoice->inpPortamento.numSource = 1;
svoice->inpPreAuxA.numSource = 0;
svoice->inpReverb.source[0].midiCtrl = 91;
svoice->inpReverb.source[0].combine = 0;
svoice->inpReverb.source[0].scale = 0x10000;
svoice->inpReverb.numSource = 1;
svoice->inpPreAuxB.numSource = 0;
svoice->inpPostAuxB.source[0].midiCtrl = 93;
svoice->inpPostAuxB.source[0].combine = 0;
svoice->inpPostAuxB.source[0].scale = 0x10000;
svoice->inpPostAuxB.numSource = 1;
svoice->inpDoppler.source[0].midiCtrl = 132;
svoice->inpDoppler.source[0].combine = 0;
svoice->inpDoppler.source[0].scale = 0x10000;
svoice->inpDoppler.numSource = 1;
svoice->inpTremolo.numSource = 0;
svoice->midiDirtyFlags = 0x1fff;
svoice->lfoUsedByInput[0] = 0;
svoice->lfoUsedByInput[1] = 0;
svoice->timeUsedByInput = 0;
} else {
for (s = 0; s < 8; ++s) {
for (i = 0; i < 4; ++i) {
inpAuxA[s][i].numSource = 0;
inpAuxB[s][i].numSource = 0;
}
}
inpResetGlobalMIDIDirtyFlags();
}
}
u8 inpTranslateExCtrl(u8 ctrl) {
switch (ctrl) {
case 0x80:
ctrl = 0x80;
break;
case 0x81:
ctrl = 0x82;
break;
case 0x82:
ctrl = 0xa0;
break;
case 0x83:
ctrl = 0xa1;
break;
case 0x84:
ctrl = 0x83;
break;
case 0x85:
ctrl = 0x84;
break;
case 0x86:
ctrl = 0xa2;
break;
case 0x87:
ctrl = 0xa3;
break;
case 0x88:
ctrl = 0xa4;
break;
}
return ctrl;
}
u16 inpGetExCtrl(SYNTH_VOICE* svoice, u8 ctrl) {
u16 v; // r30
switch (inpTranslateExCtrl(ctrl)) {
case 160:
v = (svoice->lfo[0].value << 1) + 0x2000;
break;
case 161:
v = (svoice->lfo[1].value << 1) + 0x2000;
break;
default:
v = svoice->midi != 0xFF ? inpGetMidiCtrl(ctrl, svoice->midi, svoice->midiSet) : 0;
break;
}
return v;
}
void inpSetExCtrl(SYNTH_VOICE* svoice, u8 ctrl, s16 v) {
v = v < 0 ? 0 : v > 0x3fff ? 0x3fff : v;
switch (inpTranslateExCtrl(ctrl)) {
case 161:
case 160:
break;
default:
if (svoice->midi != 0xFF) {
inpSetMidiCtrl14(ctrl, svoice->midi, svoice->midiSet, v);
}
break;
}
}

View File

@ -1,136 +0,0 @@
#include "musyx/musyx.h"
#include "musyx/snd.h"
#include "musyx/synth.h"
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
s16 sndSintab[1024] = {
0, 6, 12, 18, 25, 31, 37, 43, 50, 56, 62, 69, 75, 81, 87, 94,
100, 106, 113, 119, 125, 131, 138, 144, 150, 157, 163, 169, 175, 182, 188, 194,
200, 207, 213, 219, 226, 232, 238, 244, 251, 257, 263, 269, 276, 282, 288, 295,
301, 307, 313, 320, 326, 332, 338, 345, 351, 357, 363, 370, 376, 382, 388, 395,
401, 407, 413, 420, 426, 432, 438, 445, 451, 457, 463, 470, 476, 482, 488, 495,
501, 507, 513, 520, 526, 532, 538, 545, 551, 557, 563, 569, 576, 582, 588, 594,
601, 607, 613, 619, 625, 632, 638, 644, 650, 656, 663, 669, 675, 681, 687, 694,
700, 706, 712, 718, 725, 731, 737, 743, 749, 755, 762, 768, 774, 780, 786, 792,
799, 805, 811, 817, 823, 829, 836, 842, 848, 854, 860, 866, 872, 879, 885, 891,
897, 903, 909, 915, 921, 928, 934, 940, 946, 952, 958, 964, 970, 976, 983, 989,
995, 1001, 1007, 1013, 1019, 1025, 1031, 1037, 1043, 1050, 1056, 1062, 1068, 1074, 1080, 1086,
1092, 1098, 1104, 1110, 1116, 1122, 1128, 1134, 1140, 1146, 1152, 1158, 1164, 1170, 1176, 1182,
1189, 1195, 1201, 1207, 1213, 1219, 1225, 1231, 1237, 1243, 1248, 1254, 1260, 1266, 1272, 1278,
1284, 1290, 1296, 1302, 1308, 1314, 1320, 1326, 1332, 1338, 1344, 1350, 1356, 1362, 1368, 1373,
1379, 1385, 1391, 1397, 1403, 1409, 1415, 1421, 1427, 1433, 1438, 1444, 1450, 1456, 1462, 1468,
1474, 1479, 1485, 1491, 1497, 1503, 1509, 1515, 1520, 1526, 1532, 1538, 1544, 1550, 1555, 1561,
1567, 1573, 1579, 1584, 1590, 1596, 1602, 1608, 1613, 1619, 1625, 1631, 1636, 1642, 1648, 1654,
1659, 1665, 1671, 1677, 1682, 1688, 1694, 1699, 1705, 1711, 1717, 1722, 1728, 1734, 1739, 1745,
1751, 1756, 1762, 1768, 1773, 1779, 1785, 1790, 1796, 1802, 1807, 1813, 1819, 1824, 1830, 1835,
1841, 1847, 1852, 1858, 1864, 1869, 1875, 1880, 1886, 1891, 1897, 1903, 1908, 1914, 1919, 1925,
1930, 1936, 1941, 1947, 1952, 1958, 1964, 1969, 1975, 1980, 1986, 1991, 1997, 2002, 2007, 2013,
2018, 2024, 2029, 2035, 2040, 2046, 2051, 2057, 2062, 2067, 2073, 2078, 2084, 2089, 2094, 2100,
2105, 2111, 2116, 2121, 2127, 2132, 2138, 2143, 2148, 2154, 2159, 2164, 2170, 2175, 2180, 2186,
2191, 2196, 2201, 2207, 2212, 2217, 2223, 2228, 2233, 2238, 2244, 2249, 2254, 2259, 2265, 2270,
2275, 2280, 2286, 2291, 2296, 2301, 2306, 2312, 2317, 2322, 2327, 2332, 2337, 2343, 2348, 2353,
2358, 2363, 2368, 2373, 2379, 2384, 2389, 2394, 2399, 2404, 2409, 2414, 2419, 2424, 2429, 2434,
2439, 2445, 2450, 2455, 2460, 2465, 2470, 2475, 2480, 2485, 2490, 2495, 2500, 2505, 2510, 2515,
2519, 2524, 2529, 2534, 2539, 2544, 2549, 2554, 2559, 2564, 2569, 2574, 2578, 2583, 2588, 2593,
2598, 2603, 2608, 2613, 2617, 2622, 2627, 2632, 2637, 2641, 2646, 2651, 2656, 2661, 2665, 2670,
2675, 2680, 2684, 2689, 2694, 2699, 2703, 2708, 2713, 2717, 2722, 2727, 2732, 2736, 2741, 2746,
2750, 2755, 2760, 2764, 2769, 2773, 2778, 2783, 2787, 2792, 2796, 2801, 2806, 2810, 2815, 2819,
2824, 2828, 2833, 2837, 2842, 2847, 2851, 2856, 2860, 2865, 2869, 2874, 2878, 2882, 2887, 2891,
2896, 2900, 2905, 2909, 2914, 2918, 2922, 2927, 2931, 2936, 2940, 2944, 2949, 2953, 2957, 2962,
2966, 2970, 2975, 2979, 2983, 2988, 2992, 2996, 3000, 3005, 3009, 3013, 3018, 3022, 3026, 3030,
3034, 3039, 3043, 3047, 3051, 3055, 3060, 3064, 3068, 3072, 3076, 3080, 3085, 3089, 3093, 3097,
3101, 3105, 3109, 3113, 3117, 3121, 3126, 3130, 3134, 3138, 3142, 3146, 3150, 3154, 3158, 3162,
3166, 3170, 3174, 3178, 3182, 3186, 3190, 3193, 3197, 3201, 3205, 3209, 3213, 3217, 3221, 3225,
3229, 3232, 3236, 3240, 3244, 3248, 3252, 3255, 3259, 3263, 3267, 3271, 3274, 3278, 3282, 3286,
3289, 3293, 3297, 3301, 3304, 3308, 3312, 3315, 3319, 3323, 3326, 3330, 3334, 3337, 3341, 3345,
3348, 3352, 3356, 3359, 3363, 3366, 3370, 3373, 3377, 3381, 3384, 3388, 3391, 3395, 3398, 3402,
3405, 3409, 3412, 3416, 3419, 3423, 3426, 3429, 3433, 3436, 3440, 3443, 3447, 3450, 3453, 3457,
3460, 3463, 3467, 3470, 3473, 3477, 3480, 3483, 3487, 3490, 3493, 3497, 3500, 3503, 3506, 3510,
3513, 3516, 3519, 3522, 3526, 3529, 3532, 3535, 3538, 3541, 3545, 3548, 3551, 3554, 3557, 3560,
3563, 3566, 3570, 3573, 3576, 3579, 3582, 3585, 3588, 3591, 3594, 3597, 3600, 3603, 3606, 3609,
3612, 3615, 3618, 3621, 3624, 3627, 3629, 3632, 3635, 3638, 3641, 3644, 3647, 3650, 3652, 3655,
3658, 3661, 3664, 3667, 3669, 3672, 3675, 3678, 3680, 3683, 3686, 3689, 3691, 3694, 3697, 3700,
3702, 3705, 3708, 3710, 3713, 3716, 3718, 3721, 3723, 3726, 3729, 3731, 3734, 3736, 3739, 3742,
3744, 3747, 3749, 3752, 3754, 3757, 3759, 3762, 3764, 3767, 3769, 3772, 3774, 3776, 3779, 3781,
3784, 3786, 3789, 3791, 3793, 3796, 3798, 3800, 3803, 3805, 3807, 3810, 3812, 3814, 3816, 3819,
3821, 3823, 3826, 3828, 3830, 3832, 3834, 3837, 3839, 3841, 3843, 3845, 3848, 3850, 3852, 3854,
3856, 3858, 3860, 3862, 3864, 3867, 3869, 3871, 3873, 3875, 3877, 3879, 3881, 3883, 3885, 3887,
3889, 3891, 3893, 3895, 3897, 3899, 3900, 3902, 3904, 3906, 3908, 3910, 3912, 3914, 3915, 3917,
3919, 3921, 3923, 3925, 3926, 3928, 3930, 3932, 3933, 3935, 3937, 3939, 3940, 3942, 3944, 3945,
3947, 3949, 3950, 3952, 3954, 3955, 3957, 3959, 3960, 3962, 3963, 3965, 3967, 3968, 3970, 3971,
3973, 3974, 3976, 3977, 3979, 3980, 3982, 3983, 3985, 3986, 3988, 3989, 3990, 3992, 3993, 3995,
3996, 3997, 3999, 4000, 4001, 4003, 4004, 4005, 4007, 4008, 4009, 4011, 4012, 4013, 4014, 4016,
4017, 4018, 4019, 4020, 4022, 4023, 4024, 4025, 4026, 4027, 4029, 4030, 4031, 4032, 4033, 4034,
4035, 4036, 4037, 4038, 4039, 4040, 4041, 4042, 4043, 4044, 4045, 4046, 4047, 4048, 4049, 4050,
4051, 4052, 4053, 4054, 4055, 4056, 4057, 4057, 4058, 4059, 4060, 4061, 4062, 4062, 4063, 4064,
4065, 4065, 4066, 4067, 4068, 4068, 4069, 4070, 4071, 4071, 4072, 4073, 4073, 4074, 4075, 4075,
4076, 4076, 4077, 4078, 4078, 4079, 4079, 4080, 4080, 4081, 4081, 4082, 4082, 4083, 4083, 4084,
4084, 4085, 4085, 4086, 4086, 4087, 4087, 4087, 4088, 4088, 4089, 4089, 4089, 4090, 4090, 4090,
4091, 4091, 4091, 4091, 4092, 4092, 4092, 4092, 4093, 4093, 4093, 4093, 4094, 4094, 4094, 4094,
4094, 4094, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095,
};
#define SINTAB_ELEMENT_COUNT (sizeof(sndSintab) / sizeof(u16) - 1)
u32 last_rnd = 1;
u16 sndRand(void) {
last_rnd *= 2822053219;
return last_rnd >> 6;
}
s16 sndSin(u16 angle) {
angle &= 0xFFF;
if (angle < 1024) {
return (s16)sndSintab[angle];
}
if (angle < 2048) {
return (s16)sndSintab[SINTAB_ELEMENT_COUNT - (angle & SINTAB_ELEMENT_COUNT)];
}
if (angle < 3072) {
return (s16)-sndSintab[angle & SINTAB_ELEMENT_COUNT];
}
return -sndSintab[SINTAB_ELEMENT_COUNT - (angle & SINTAB_ELEMENT_COUNT)];
}
void* sndBSearch(void* key, void* base, s32 num, s32 len, SND_COMPARE cmp) {
long l; // r31
long r; // r30
long m; // r29
long c; // r28
void* ptr; // r27
if (num != 0) {
l = 1;
r = num;
do {
// This is kind of gross....
if ((c = cmp(key, (ptr = (void*)((size_t)base + len * ((m = (l + r) >> 1) - 1))))) == 0) {
return ptr;
}
if (c < 0) {
r = m - 1;
} else {
l = m + 1;
}
} while (l <= r);
}
return NULL;
}
void sndConvertMs(u32* time) { *time = *time * 256; }
void sndConvertTicks(u32* out, SYNTH_VOICE* svoice) {
*out = (((*out << 16) / synthGetTicksPerSecond(svoice)) * 1000) / 32;
}
u32 sndConvert2Ms(u32 time) { return time / 256; }
#ifdef __cplusplus
}
#endif // __cplusplus

View File

@ -1,693 +0,0 @@
/* ---------------------------------------
---------------------------------------
*/
#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>
/*
*/
bool sndFXCtrl(SND_VOICEID vid, u8 ctrl, u8 value) {
bool ret;
MUSY_ASSERT_MSG(sndActive != 0, "Sound system is not initialized.");
hwDisableIrq();
ret = synthFXSetCtrl(vid, ctrl, value);
hwEnableIrq();
return ret;
}
/*
*/
bool sndFXCtrl14(SND_VOICEID vid, u8 ctrl, u16 value) {
bool ret;
MUSY_ASSERT_MSG(sndActive != 0, "Sound system is not initialized.");
hwDisableIrq();
ret = synthFXSetCtrl14(vid, ctrl, value);
hwEnableIrq();
return ret;
}
/*
*/
bool sndFXKeyOff(SND_VOICEID vid) {
bool ret;
MUSY_ASSERT_MSG(sndActive != 0, "Sound system is not initialized.");
hwDisableIrq();
ret = synthSendKeyOff(vid);
hwEnableIrq();
return ret;
}
/*
*/
SND_VOICEID sndFXStartEx(SND_FXID fid, u8 vol, u8 pan, u8 studio) {
SND_VOICEID v;
MUSY_ASSERT_MSG(sndActive != 0, "Sound system is not initialized.");
hwDisableIrq();
v = synthFXStart(fid, vol, pan, studio, synthITDDefault[studio].sfx);
hwEnableIrq();
return v;
}
/*
*/
SND_VOICEID sndFXStartPara(SND_FXID fid, u8 vol, u8 pan, u8 studio, u8 numPara, ...) {
u32 vid;
u8 i;
va_list args;
u32 value;
u8 ctrl;
MUSY_ASSERT_MSG(sndActive != 0, "Sound system is not initialized.");
hwDisableIrq();
if ((vid = synthFXStart(fid, vol, pan, studio, synthITDDefault[studio].sfx)) != -1 &&
numPara != 0) {
va_start(args, numPara);
for (i = 0; i < numPara; ++i) {
ctrl = va_arg(args, u32);
value = va_arg(args, u32);
/*
*/
if (ctrl < 0x40 || ctrl == 0x80 || ctrl == 0x84) {
MUSY_ASSERT_MSG(value <= 0x3fff, "Hires MIDI controller value out of range.");
synthFXSetCtrl14(vid, ctrl, (u16)value);
} else {
MUSY_ASSERT_MSG(value <= 0x7f, "Lores MIDI controller value out of range.");
synthFXSetCtrl(vid, ctrl, (u16)value);
}
}
}
/*
*/
hwEnableIrq();
return vid;
}
/*
*/
SND_VOICEID sndFXStartParaInfo(SND_FXID fid, u8 vol, u8 pan, u8 studio,
SND_PARAMETER_INFO* paraInfo) {
unsigned long vid; // r29
unsigned char i; // r28
SND_PARAMETER* pPtr; // r31
MUSY_ASSERT_MSG(sndActive != 0, "Sound system is not initialized.");
hwDisableIrq();
if ((vid = synthFXStart(fid, vol, pan, studio, synthITDDefault[studio].sfx)) != 0xFFFFFFFF) {
MUSY_ASSERT_MSG(paraInfo != NULL, "Parameter pointer must not be NULL.");
for (pPtr = paraInfo->paraArray, i = 0; i < paraInfo->numPara; ++pPtr, ++i) {
/*
*/
if (pPtr->ctrl < 0x40 || pPtr->ctrl == 0x80 || pPtr->ctrl == 0x84) {
MUSY_ASSERT_MSG(pPtr->paraData.value14 <= 0x3fff,
"Hires MIDI controller value out of range.");
synthFXSetCtrl14(vid, pPtr->ctrl, pPtr->paraData.value14);
} else {
MUSY_ASSERT_MSG(pPtr->paraData.value7 <= 0x7f, "Lores MIDI controller value out of range.");
synthFXSetCtrl(vid, pPtr->ctrl, pPtr->paraData.value7);
}
}
}
hwEnableIrq();
return vid;
}
/*
*/
SND_VOICEID sndFXCheck(SND_VOICEID vid) {
MUSY_ASSERT_MSG(sndActive != FALSE, "Sound system is not initialized.");
return vidGetInternalId(vid) != -1 ? vid : -1;
}
/*
*/
s32 sndReadFlag(unsigned char num) {
MUSY_ASSERT_MSG(sndActive != FALSE, "Sound system is not initialized.");
return synthGlobalVariable[num & 0xf];
}
/*
*/
s32 sndWriteFlag(u8 num, s32 value) {
s32 old; // r30
MUSY_ASSERT_MSG(sndActive != FALSE, "Sound system is not initialized.");
num &= 0xf;
hwDisableIrq();
old = synthGlobalVariable[num];
synthGlobalVariable[num] = value;
hwEnableIrq();
return old;
}
/*
*/
bool sndSendMessage(SND_VOICEID vid, s32 mesg) {
bool ret; // r31
MUSY_ASSERT_MSG(sndActive != FALSE, "Sound system is not initialized.");
hwDisableIrq();
ret = macPostMessage(vid, mesg);
hwEnableIrq();
return ret;
}
/*
*/
void sndSetReceiveMessageCallback(void (*callback)(u32, s32)) {
MUSY_ASSERT_MSG(sndActive != FALSE, "Sound system is not initialized.");
synthMessageCallback = callback;
}
/*
*/
void sndSilence() {
MUSY_ASSERT_MSG(sndActive != FALSE, "Sound system is not initialized.");
hwDisableIrq();
seqKillAllInstances();
s3dKillAllEmitter();
synthKillAllVoices(0);
hwEnableIrq();
}
/*
*/
bool sndIsIdle() {
u32 i; // r31
u8 flag; // r30
MUSY_ASSERT_MSG(sndActive != FALSE, "Sound system is not initialized.");
flag = 0;
synthIdleWaitActive = TRUE;
if (!hwGlobalActivity()) {
for (i = 0; i < synthInfo.voiceNum; ++i) {
flag |= hwIsActive(i);
}
} else {
flag = 1;
}
synthIdleWaitActive = FALSE;
return flag == 0;
}
/*
*/
bool sndFXAssignVolGroup2FXId(SND_FXID fid, u8 vGroup) {
FX_TAB* fx; // r30
u32 ret; // r29
MUSY_ASSERT_MSG(sndActive != FALSE, "Sound system is not initialized.");
ret = 0;
hwDisableIrq();
//
//
//
if ((fx = dataGetFX(fid)) != NULL) {
/*
*/
if ((u8)vGroup != 0xFE) {
//
//
fx->vGroup = vGroup;
synthSetMusicVolumeType(vGroup, 3);
} else {
fx->vGroup = 0x1f;
}
ret = 1;
} else {
MUSY_DEBUG("FX ID=%d could not be found in FX table.", fid);
}
hwEnableIrq();
return ret;
}
/*
*/
void sndPauseVolume(u8 volume, u16 time, u8 vGroup) {
MUSY_ASSERT_MSG(sndActive != FALSE, "Sound system is not initialized.");
hwDisableIrq();
synthPauseVolume(volume, time, vGroup);
hwEnableIrq();
}
/*
*/
void sndVolume(u8 volume, u16 time, u8 volgroup) {
MUSY_ASSERT_MSG(sndActive != FALSE, "Sound system is not initialized.");
hwDisableIrq();
synthVolume(volume, time, volgroup, 0, -1);
hwEnableIrq();
}
/*
*/
void sndMasterVolume(u8 volume, u16 time, u8 music, u8 fx) {
MUSY_ASSERT_MSG(sndActive != FALSE, "Sound system is not initialized.");
hwDisableIrq();
if (music != 0)
synthVolume(volume, time, 0x15, 0, -1);
if (fx != 0)
synthVolume(volume, time, 0x16, 0, -1);
hwEnableIrq();
}
/*
*/
void sndOutputMode(SND_OUTPUTMODE output) {
u32 i;
u32 oldFlags;
MUSY_ASSERT_MSG(sndActive != FALSE, "Sound system is not initialized.");
oldFlags = synthFlags;
switch (output) {
case SND_OUTPUTMODE_MONO:
synthFlags |= 1;
synthFlags &= ~2;
hwDisableHRTF();
break;
case SND_OUTPUTMODE_STEREO:
synthFlags &= ~1;
synthFlags &= ~2;
hwDisableHRTF();
break;
case SND_OUTPUTMODE_SURROUND:
synthFlags &= ~1;
synthFlags |= 2;
hwDisableHRTF();
break;
default:
MUSY_ASSERT_MSG(FALSE, "Unsupported outputmode selected.");
break;
}
if (oldFlags == synthFlags) {
return;
}
for (i = 0; i < synthInfo.voiceNum; ++i) {
synthVoice[i].cFlags |= 0x0000200000000000;
}
#if MUSY_VERSION >= MUSY_VERSION_CHECK(1, 5, 4)
streamOutputModeChanged();
#endif
}
/*
*/
// clang-format off
void sndSetAuxProcessingCallbacks(u8 studio,
SND_AUX_CALLBACK auxA, void* userA, u8 midiA, SND_SEQID seqIDA,
SND_AUX_CALLBACK auxB, void* userB, u8 midiB, SND_SEQID seqIDB) {
// clang-format on
MUSY_ASSERT_MSG(sndActive != FALSE, "Sound system is not initialized.");
hwDisableIrq();
if (auxA != NULL) {
if ((synthAuxAMIDI[studio] = midiA) != 0xFF) {
synthAuxAMIDISet[studio] = seqGetPrivateId(seqIDA);
synthAuxACallback[studio] = auxA;
synthAuxAUser[studio] = userA;
}
} else {
synthAuxACallback[studio] = NULL;
synthAuxAMIDI[studio] = 0xff;
}
if (auxB != NULL) {
if ((synthAuxBMIDI[studio] = midiB) != 0xFF) {
synthAuxBMIDISet[studio] = seqGetPrivateId(seqIDB);
synthAuxBCallback[studio] = auxB;
synthAuxBUser[studio] = userB;
}
} else {
synthAuxBCallback[studio] = NULL;
synthAuxBMIDI[studio] = 0xff;
}
hwSetAUXProcessingCallbacks(studio, auxA, userA, auxB, userB);
hwEnableIrq();
}
/*
*/
void sndUpdateAuxParameter(unsigned char studio, unsigned short* para, unsigned char auxBus) {
struct SND_AUX_INFO info; // r1+0x14
unsigned long i; // r30
MUSY_ASSERT_MSG(sndActive != FALSE, "Sound system is not initialized.");
for (i = 0; i < 4; ++i) {
info.data.parameterUpdate.para[i] = para[i];
}
if (auxBus == 0) {
MUSY_ASSERT_MSG(synthAuxACallback[studio] != NULL, "No FX is defined for AuxA.");
synthAuxACallback[studio](1, &info, synthAuxAUser);
} else {
MUSY_ASSERT_MSG(synthAuxBCallback[studio] != NULL, "No FX is defined for AuxB.");
synthAuxBCallback[studio](1, &info, synthAuxBUser);
}
}
/*
*/
void sndSetITDDefault(u8 studio, bool musicITD, bool sfxITD) {
synthITDDefault[studio].music = musicITD;
synthITDDefault[studio].sfx = sfxITD;
}
/*
*/
void synthActivateStudio(u8 studio, u32 isMaster, SND_STUDIO_TYPE type) {
MUSY_ASSERT_MSG(sndActive != FALSE, "Sound system is not initialized.");
hwDisableIrq();
synthAuxACallback[studio] = NULL;
synthAuxBCallback[studio] = NULL;
synthAuxAMIDI[studio] = 0xFF;
synthAuxBMIDI[studio] = 0xFF;
synthITDDefault[studio].sfx = 0;
synthITDDefault[studio].music = 0;
hwActivateStudio(studio, isMaster, type);
hwEnableIrq();
}
/*
*/
void sndActivateStudioEx(u8 studio, bool isMaster, SND_STUDIO_TYPE type) {
MUSY_ASSERT_MSG(sndActive != FALSE, "Sound system is not initialized.");
MUSY_ASSERT_MSG(studio < synthInfo.studioNum, "Illegal studio index.");
if (studio != 0) {
hwDisableIrq();
synthActivateStudio(studio, isMaster, type);
hwEnableIrq();
} else {
MUSY_DEBUG("The default studio cannot be activated or deactivated.\n");
}
}
/*
*/
void synthDeactivateStudio(u8 studio) {
u32 i;
MUSY_ASSERT_MSG(sndActive != FALSE, "Sound system is not initialized.");
for (i = 0; i < synthInfo.voiceNum; ++i) {
if (studio == synthVoice[i].studio) {
if (synthVoice[i].id != 0xFFFFFFFF) {
voiceKillSound(synthVoice[i].vidList->vid);
} else if (hwIsActive(i)) {
hwOff(i);
}
}
}
hwDisableIrq();
synthAuxACallback[studio] = 0;
synthAuxBCallback[studio] = 0;
synthAuxAMIDI[studio] = 0xFF;
synthAuxBMIDI[studio] = 0xFF;
hwEnableIrq();
hwDeactivateStudio(studio);
}
/*
*/
void sndDeactivateStudio(u8 studio) {
MUSY_ASSERT_MSG(sndActive != FALSE, "Sound system is not initialized.");
MUSY_ASSERT_MSG(studio < synthInfo.studioNum, "Illegal studio index.");
if (studio != 0) {
hwDisableIrq();
synthDeactivateStudio(studio);
hwEnableIrq();
} else {
MUSY_DEBUG("The default studio cannot be activated or deactivated.\n");
}
}
/*
*/
void synthChangeStudioMasterMix(u8 studio, u32 isMaster) {
MUSY_ASSERT_MSG(sndActive != FALSE, "Sound system is not initialized.");
hwChangeStudioMix(studio, isMaster);
}
//
void sndChangeStudioMasterMix(u8 studio, bool isMaster) {
MUSY_ASSERT_MSG(sndActive != FALSE, "Sound system is not initialized.");
if (studio != 0) {
hwDisableIrq();
synthChangeStudioMasterMix(studio, isMaster);
hwEnableIrq();
} else {
MUSY_DEBUG("Default studio's master mix cannot be changed.\n");
}
}
/*
*/
bool synthAddStudioInput(u8 studio, SND_STUDIO_INPUT* in_desc) {
MUSY_ASSERT_MSG(sndActive != FALSE, "Sound system is not initialized.");
return hwAddInput(studio, in_desc);
}
//
bool sndAddStudioInput(u8 studio, SND_STUDIO_INPUT* in_desc) {
u32 ret;
MUSY_ASSERT_MSG(sndActive != FALSE, "Sound system is not initialized.");
hwDisableIrq();
ret = synthAddStudioInput(studio, in_desc);
hwEnableIrq();
return ret;
}
/*
*/
bool synthRemoveStudioInput(u8 studio, SND_STUDIO_INPUT* in_desc) {
MUSY_ASSERT_MSG(sndActive != FALSE, "Sound system is not initialized.");
return hwRemoveInput(studio, in_desc);
}
/*
*/
bool sndRemoveStudioInput(u8 studio, SND_STUDIO_INPUT* in_desc) {
bool ret;
MUSY_ASSERT_MSG(sndActive != FALSE, "Sound system is not initialized.");
hwDisableIrq();
ret = synthRemoveStudioInput(studio, in_desc);
hwEnableIrq();
return ret;
}
u8 sndDbgGetActiveVoices() {
u8 n; // r31
hwDisableIrq();
n = voiceFxRunning + voiceMusicRunning;
hwEnableIrq();
return n;
}

View File

@ -1,696 +0,0 @@
#include "musyx/musyx.h"
#include "musyx/assert.h"
#include "musyx/hardware.h"
#include "musyx/snd.h"
#include "musyx/stream.h"
#include "musyx/synth.h"
#include "musyx/synthdata.h"
#include "musyx/voice.h"
#if !defined(_DEBUG) && MUSY_TARGET == MUSY_TARGET_DOLPHIN
#include "dolphin/os.h"
#endif
static STREAM_INFO streamInfo[64];
static u32 nextPublicID = 0;
static u8 streamCallDelay = 0;
static u8 streamCallCnt = 0;
void streamInit() {
s32 i;
streamCallCnt = 0;
streamCallDelay = 3;
for (i = 0; i < synthInfo.voiceNum; ++i) {
streamInfo[i].state = 0;
}
nextPublicID = 0;
}
#if MUSY_VERSION >= MUSY_VERSION_CHECK(1, 5, 4)
void SetHWMix(const STREAM_INFO* si) {
hwSetVolume(si->voice, 0, si->vol * (1 / 127.f), (si->pan << 16), (si->span << 16),
si->auxa * (1 / 127.f), si->auxb * (1 / 127.f));
}
#endif
void streamHandle() {
STREAM_INFO* si; // r31
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) {
--streamCallCnt;
return;
}
streamCallCnt = streamCallDelay;
si = &streamInfo[0];
for (i = 0; i < synthInfo.voiceNum; ++i, ++si) {
switch (si->state) {
case 1:
newsmp.info = si->frq | 0x40000000;
newsmp.addr = hwGetStreamPlayBuffer(si->hwStreamHandle);
newsmp.offset = 0;
newsmp.length = si->size;
newsmp.loop = 0;
newsmp.loopLength = si->size;
#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) {
case 0:
newsmp.compType = 2;
break;
case 1:
newsmp.extraData = &si->adpcmInfo;
newsmp.compType = 4;
#if MUSY_VERSION >= MUSY_VERSION_CHECK(2, 0, 0)
hwSetStreamLoopPS(si->voice, si->lastPSFromBuffer);
si->adpcmInfo.loopPS = si->adpcmInfo.initialPS = si->lastPSFromBuffer;
#endif
break;
}
v = si->voice;
hwInitSamplePlayback(v, -1, &newsmp, 1, -1, synthVoice[v].id, 1, 1);
hwSetPitch(si->voice, (si->frq / (float)synthInfo.mixFrq) * 4096.f);
#if MUSY_VERSION <= MUSY_VERSION_CHECK(1, 5, 3)
hwSetVolume(si->voice, 0, si->vol * (1 / 127.f), (si->pan << 16), (si->span << 16),
si->auxa * (1 / 127.f), si->auxb * (1 / 127.f));
#else
SetHWMix(si);
#endif
hwStart(si->voice, si->studio);
si->state = 2;
if (!(si->flags & 0x20000)) {
hwFlushStream(si->buffer, 0, si->bytes, si->hwStreamHandle, NULL, 0);
}
break;
case 2: {
u32 off = hwGetPos(si->voice);
if (si->type == 1) {
off = (off / 14) * 14;
}
if (si->last != off) {
if (si->last < off) {
switch (si->type) {
case 0: {
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)) {
if (off != 0) {
hwFlushStream(si->buffer, si->last * 2, (off - si->last) * 2, si->hwStreamHandle,
NULL, 0);
} else {
hwFlushStream(si->buffer, si->last * 2, (si->size - si->last) * 2,
si->hwStreamHandle, NULL, 0);
}
}
si->last = off;
}
} break;
case 1: {
cpos = (si->last / 14) * 8;
if ((len = si->updateFunction((void*)((size_t)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);
} else {
hwFlushStream(si->buffer, cpos, (si->bytes) - cpos, si->hwStreamHandle, NULL, 0);
}
}
si->last = off;
}
} break;
}
} else if (off == 0) {
switch (si->type) {
case 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;
if (!(si->flags & 0x20000)) {
if (off == 0) {
hwFlushStream(si->buffer, si->last * 2, si->bytes - (si->last * 2),
si->hwStreamHandle, NULL, 0);
} else {
hwFlushStream(si->buffer, si->last * 2, (off - si->last) * 2, si->hwStreamHandle,
NULL, 0);
}
}
si->last = off;
}
break;
case 1:
cpos = ((si->last / 14) * 8);
if ((len = si->updateFunction((void*)((size_t)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);
} else {
hwFlushStream(si->buffer, cpos, ((off + 13) / 14) * 8 - cpos, si->hwStreamHandle,
NULL, 0);
}
}
si->last = off;
}
break;
}
} else {
switch (si->type) {
case 0:
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),
si->hwStreamHandle, NULL, 0);
hwFlushStream(si->buffer, 0, off * 2, si->hwStreamHandle, NULL, 0);
} else if (off == 0) {
hwFlushStream(si->buffer, si->last * 2, (si->bytes - si->last * 2),
si->hwStreamHandle, NULL, 0);
} else {
hwFlushStream(si->buffer, si->last * 2, (off - si->last) * 2, si->hwStreamHandle,
NULL, 0);
}
}
si->last = off;
}
break;
case 1: {
cpos = (si->last / 14) * 8;
if ((len = si->updateFunction((void*)((size_t)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, 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);
}
}
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;
}
}
}
void streamCorrectLoops() {}
void streamKill(u32 voice) {
STREAM_INFO* si = &streamInfo[voice];
switch (si->state) {
case 1:
case 2:
if (si->state == 2) {
voiceUnblock(si->voice);
}
si->state = 3;
si->updateFunction(NULL, 0, NULL, 0, si->user);
break;
default:
break;
}
}
static u32 GetPrivateIndex(u32 publicID) {
u32 i; // r31
for (i = 0; i < 64; ++i) {
if (streamInfo[i].state != 0 && publicID == streamInfo[i].stid) {
return i;
}
}
return -1;
}
static u32 GeneratePublicID() {
u32 id; // r30
u32 i; // r31
do {
if ((id = nextPublicID++) == -1) {
id = nextPublicID;
nextPublicID = id + 1;
}
for (i = 0; i < 64; ++i) {
if (streamInfo[i].state != 0 && id == streamInfo[i].stid) {
break;
}
}
} while (i != 64);
return id;
}
u32 sndStreamCallbackFrq(u32 msTime) {
s32 time; // r31
time = ((msTime * 2 + 5) / 10) - 1;
streamCallDelay = time < 0 ? 0 : time;
return (streamCallDelay + 1) * 5;
}
void sndStreamARAMUpdate(u32 stid, u32 off1, u32 len1, u32 off2, u32 len2) {
u32 i; // r30
MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized.");
hwDisableIrq();
i = GetPrivateIndex(stid);
if (i != -1) {
switch (streamInfo[i].type) {
case 0:
off1 *= 2;
len1 *= 2;
off2 *= 2;
len2 *= 2;
break;
case 1:
off1 = (off1 / 14) * 8;
len1 = ((len1 + 13) / 14) * 8;
off2 = (off2 / 14) * 8;
len2 = ((len2 + 13) / 14) * 8;
break;
}
if (len1 != 0) {
hwFlushStream(streamInfo[i].buffer, off1, len1, streamInfo[i].hwStreamHandle, 0, 0);
}
if (len2 != 0) {
hwFlushStream(streamInfo[i].buffer, off2, len2, streamInfo[i].hwStreamHandle, 0, 0);
}
#if MUSY_VERSION >= MUSY_VERSION_CHECK(1, 5, 4)
if (streamInfo[i].type == 1) {
streamInfo[i].lastPSFromBuffer =
(*(u32*)MUSY_CACHED_TO_UNCACHED_ADDR(streamInfo[i].buffer)) >> 24;
if (streamInfo[i].voice != -1) {
hwSetStreamLoopPS(streamInfo[i].voice, streamInfo[i].lastPSFromBuffer);
}
}
#else
if (streamInfo[i].type == 1) {
hwSetStreamLoopPS(streamInfo[i].voice,
*(u32*)MUSY_CACHED_TO_UNCACHED_ADDR(streamInfo[i].buffer) >> 24);
}
#endif
} else {
MUSY_DEBUG("ID is invalid.\n");
}
hwEnableIrq();
}
static void CheckOutputMode(u8* pan, u8* span) {
if (synthFlags & 1) {
*pan = 64;
*span = 0;
} else if (!(synthFlags & 2)) {
*span = 0;
}
}
#if MUSY_VERSION >= MUSY_VERSION_CHECK(1, 5, 4)
static void SetupVolumeAndPan(STREAM_INFO* si, u8 vol, u8 pan, u8 span, u8 auxa, u8 auxb) {
si->orgPan = pan;
si->orgSPan = span;
CheckOutputMode(&pan, &span);
si->vol = vol;
si->pan = pan;
si->span = span;
si->auxa = auxa;
si->auxb = auxb;
}
#endif
#if MUSY_VERSION >= MUSY_VERSION_CHECK(1, 5, 4)
void streamOutputModeChanged() {
u32 i;
hwDisableIrq();
for (i = 0; i < synthInfo.voiceNum; ++i) {
if (streamInfo[i].state != 0) {
streamInfo[i].pan = streamInfo[i].orgPan;
streamInfo[i].span = streamInfo[i].orgSPan;
CheckOutputMode(&streamInfo[i].pan, &streamInfo[i].span);
if (streamInfo[i].state != 3) {
SetHWMix(&streamInfo[i]);
}
}
}
hwEnableIrq();
}
#endif
SND_STREAMID sndStreamAllocEx(u8 prio, void* buffer, u32 samples, u32 frq, u8 vol, u8 pan, u8 span,
u8 auxa, u8 auxb, u8 studio, u32 flags,
u32 (*updateFunction)(void* buffer1, u32 len1, void* buffer2,
u32 len2, u32 user),
u32 user, SND_ADPCMSTREAM_INFO* adpcmInfo) {
u32 stid; // r29
u32 i; // r31
u32 bytes; // r25
u32 j; // r28
MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized.");
hwDisableIrq();
for (i = 0; i < 64; ++i) {
if (streamInfo[i].state == 0) {
break;
}
}
if (i != 64) {
stid = GeneratePublicID();
streamInfo[i].stid = stid;
streamInfo[i].flags = flags;
bytes = sndStreamAllocLength(samples, flags);
streamInfo[i].buffer = (s16*)buffer;
streamInfo[i].size = samples;
streamInfo[i].bytes = bytes;
streamInfo[i].updateFunction = updateFunction;
streamInfo[i].voice = -1;
if (flags & 1) {
if (adpcmInfo != NULL) {
for (j = 0; j < 8; j++) {
streamInfo[i].adpcmInfo.coefTab[j][0] = adpcmInfo->coefTab[j][0];
streamInfo[i].adpcmInfo.coefTab[j][1] = adpcmInfo->coefTab[j][1];
}
streamInfo[i].adpcmInfo.numCoef = 8;
}
streamInfo[i].type = 1;
} else {
streamInfo[i].type = 0;
}
streamInfo[i].frq = frq;
streamInfo[i].studio = studio;
streamInfo[i].prio = prio;
#if MUSY_VERSION <= MUSY_VERSION_CHECK(1, 5, 3)
CheckOutputMode(&pan, &span);
streamInfo[i].vol = vol;
streamInfo[i].pan = pan;
streamInfo[i].span = span;
streamInfo[i].auxa = auxa;
streamInfo[i].auxb = auxb;
#else
SetupVolumeAndPan(&streamInfo[i], vol, pan, span, auxa, auxb);
#endif
streamInfo[i].user = user;
streamInfo[i].nextStreamHandle = -1;
streamInfo[i].state = 3;
if ((streamInfo[i].hwStreamHandle = hwInitStream(bytes)) != 0xFF) {
if (!(flags & 0x10000) && !sndStreamActivate(stid)) {
MUSY_DEBUG("No voice could be allocated for streaming.\n");
stid = -1;
}
} else {
MUSY_DEBUG("No ARAM memory could be allocated for streaming.\n");
stid = -1;
}
if (stid == -1) {
streamInfo[i].state = 0;
}
} else {
stid = -1;
}
hwEnableIrq();
return stid;
}
u32 sndStreamAllocStereo(u8 prio, void* lBuffer, void* rBuffer, u32 samples, u32 frq, u8 vol,
u8 pan, u8 span, u8 auxa, u8 auxb, u8 studio, u32 flags,
SND_STREAM_UPDATE_CALLBACK updateFunction, u32 lUser, u32 rUser,
SND_ADPCMSTREAM_INFO* adpcmInfoL, SND_ADPCMSTREAM_INFO* adpcmInfoR) {
u32 stid[2]; // r1+0x38
s16 rPan; // r31
s16 lPan; // r30
lPan = pan - 64;
lPan = lPan < 0 ? 0 : lPan > 127 ? 127 : lPan;
rPan = pan + 64;
rPan = rPan < 0 ? 0 : rPan > 127 ? 127 : rPan;
hwDisableIrq();
if ((stid[0] = sndStreamAllocEx(prio, lBuffer, samples, frq, vol, lPan, span, auxa, auxb, studio,
flags, updateFunction, lUser, adpcmInfoL)) != 0xFFFFFFFF) {
if ((stid[1] = sndStreamAllocEx(prio, rBuffer, samples, frq, vol, rPan, span, auxa, auxb,
studio, flags, updateFunction, rUser, adpcmInfoR)) ==
0xFFFFFFFF) {
sndStreamFree(stid[0]);
hwEnableIrq();
return 0xFFFFFFFF;
}
streamInfo[GetPrivateIndex(stid[0])].nextStreamHandle = stid[1];
}
hwEnableIrq();
return stid[0];
}
u32 sndStreamAllocLength(u32 num, u32 flags) {
if (flags & 1) {
return (((num + 13) / 14) * 8 + 31) & ~31;
}
return (num * 2 + 31) & ~31;
}
void sndStreamADPCMParameter(u32 stid, SND_ADPCMSTREAM_INFO* adpcmInfo) {
u32 j; // r31
u32 i; // r30
MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized.");
hwDisableIrq();
i = GetPrivateIndex(stid);
if (i != -1) {
for (j = 0; j < 8; ++j) {
streamInfo[i].adpcmInfo.coefTab[j][0] = adpcmInfo->coefTab[j][0];
streamInfo[i].adpcmInfo.coefTab[j][1] = adpcmInfo->coefTab[j][1];
}
streamInfo[i].adpcmInfo.numCoef = 8;
if (streamInfo[i].nextStreamHandle != 0xffffffff) {
sndStreamADPCMParameter(streamInfo[i].nextStreamHandle, adpcmInfo);
}
} else {
MUSY_DEBUG("ID is invalid.\n");
}
hwEnableIrq();
}
void sndStreamMixParameter(u32 stid, u8 vol, u8 pan, u8 span, u8 fxvol) {
u32 i; // r31
MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized.");
hwDisableIrq();
i = GetPrivateIndex(stid);
if (i != -1) {
#if MUSY_VERSION < MUSY_VERSION_CHECK(1, 5, 4)
CheckOutputMode(&pan, &span);
streamInfo[i].vol = vol;
streamInfo[i].pan = pan;
streamInfo[i].span = span;
streamInfo[i].auxa = fxvol;
streamInfo[i].auxb = 0;
hwSetVolume(streamInfo[i].voice, 0, vol * (1 / 127.f), (pan << 16), (span << 16),
fxvol * (1 / 127.f), 0.f);
#else
SetupVolumeAndPan(&streamInfo[i], vol, pan, span, fxvol, 0);
SetHWMix(&streamInfo[i]);
#endif
if (streamInfo[i].nextStreamHandle != -1) {
sndStreamMixParameter(streamInfo[i].nextStreamHandle, vol, pan, span, fxvol);
}
} else {
MUSY_DEBUG("ID is invalid.\n");
}
hwEnableIrq();
}
void sndStreamMixParameterEx(u32 stid, u8 vol, u8 pan, u8 span, u8 auxa, u8 auxb) {
u32 i; // r31
MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized.");
hwDisableIrq();
i = GetPrivateIndex(stid);
if (i != -1) {
#if MUSY_VERSION <= MUSY_VERSION_CHECK(1, 5, 3)
streamInfo[i].vol = vol;
streamInfo[i].pan = pan;
streamInfo[i].span = span;
streamInfo[i].auxa = auxa;
streamInfo[i].auxb = auxb;
if (streamInfo[i].state == 2) {
hwSetVolume(streamInfo[i].voice, 0, vol * (1 / 127.f), (pan << 16), (span << 16),
auxa * (1 / 127.f), auxb * (1 / 127.f));
}
#else
SetupVolumeAndPan(&streamInfo[i], vol, pan, span, auxa, auxb);
if (streamInfo[i].state == 2) {
SetHWMix(&streamInfo[i]);
}
#endif
if (streamInfo[i].nextStreamHandle != -1) {
sndStreamMixParameterEx(streamInfo[i].nextStreamHandle, vol, pan, span, auxa, auxb);
}
} else {
MUSY_DEBUG("ID is invalid.\n");
}
hwEnableIrq();
}
void sndStreamFrq(u32 stid, u32 frq) {
u32 i; // r31
u16 pitch; // r27
MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized.");
hwDisableIrq();
i = GetPrivateIndex(stid);
if (i != -1) {
streamInfo[i].frq = frq;
if (streamInfo[i].state == 2) {
pitch = (4096.f * frq) / synthInfo.mixFrq;
hwSetPitch(streamInfo[i].voice, pitch);
}
if (streamInfo[i].nextStreamHandle != -1) {
sndStreamFrq(streamInfo[i].nextStreamHandle, frq);
}
} else {
MUSY_DEBUG("ID is invalid.\n");
}
hwEnableIrq();
}
void sndStreamFree(u32 stid) {
u32 i; // r31
MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized.");
hwDisableIrq();
i = GetPrivateIndex(stid);
if (i != -1) {
sndStreamDeactivate(stid);
hwExitStream(streamInfo[i].hwStreamHandle);
if (streamInfo[i].nextStreamHandle != -1) {
sndStreamFree(streamInfo[i].nextStreamHandle);
}
streamInfo[i].state = 0;
} else {
MUSY_DEBUG("ID is invalid.\n");
}
hwEnableIrq();
}
bool sndStreamActivate(SND_STREAMID stid) {
u32 i; // r31
u32 ret; // r28
ret = 0;
MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized.");
hwDisableIrq();
i = GetPrivateIndex(stid);
if (i != -1) {
if (streamInfo[i].state == 3) {
if ((streamInfo[i].voice = voiceBlock(streamInfo[i].prio)) == -1) {
MUSY_DEBUG("No voice could be allocated for streaming.\n");
hwEnableIrq();
return 0;
}
streamInfo[i].last = 0;
streamInfo[i].state = 1;
} else {
MUSY_DEBUG("Stream is already active.\n");
}
if (streamInfo[i].nextStreamHandle != -1) {
ret = sndStreamActivate(streamInfo[i].nextStreamHandle);
} else {
ret = 1;
}
} else {
MUSY_DEBUG("ID is invalid.\n");
}
hwEnableIrq();
return ret;
}
void sndStreamDeactivate(u32 stid) {
u32 i; // r31
MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized.");
hwDisableIrq();
i = GetPrivateIndex(stid);
if (i != -1) {
if (streamInfo[i].state == 1 || streamInfo[i].state == 2) {
voiceUnblock(streamInfo[i].voice);
streamInfo[i].state = 3;
}
if (streamInfo[i].nextStreamHandle != -1) {
sndStreamDeactivate(streamInfo[i].nextStreamHandle);
}
} else {
MUSY_DEBUG("ID is invalid.\n");
}
hwEnableIrq();
}

File diff suppressed because it is too large Load Diff

View File

@ -1,72 +0,0 @@
#include "musyx/synth.h"
static float toneup_tab[128] = {
1.0f, 1.0594635f, 1.1224623f, 1.1892071f, 1.2599211f, 1.3348398f, 1.4142141f,
1.4983072f, 1.5874014f, 1.6817932f, 1.7817984f, 1.8877487f, 2.000001f, 2.118927f,
2.2449245f, 2.378415f, 2.519843f, 2.6696806f, 2.8284283f, 2.9966154f, 3.1748037f,
3.3635874f, 3.5635967f, 3.7754984f, 4.000002f, 4.237854f, 4.48985f, 4.75683f,
5.039686f, 5.339362f, 5.6568565f, 5.993231f, 6.3496075f, 6.7271748f, 7.1271935f,
7.5509977f, 8.000004f, 8.475709f, 8.979701f, 9.513661f, 10.079373f, 10.678724f,
11.313714f, 11.986463f, 12.699215f, 13.4543495f, 14.254387f, 15.101996f, 16.000008f,
16.951418f, 17.959402f, 19.027323f, 20.158747f, 21.357449f, 22.627428f, 23.972925f,
25.39843f, 26.908699f, 28.508774f, 30.203993f, 32.000015f, 33.902836f, 35.918804f,
38.054646f, 40.317493f, 42.714897f, 45.254856f, 47.94585f, 50.79686f, 53.817398f,
57.017548f, 60.407986f, 64.00003f, 67.80567f, 71.83761f, 76.10929f, 80.63499f,
85.429794f, 90.50971f, 95.8917f, 101.59372f, 107.634796f, 114.035095f, 120.81597f,
128.00006f, 135.61134f, 143.67522f, 152.21858f, 161.26997f, 170.85959f, 181.01942f,
191.7834f, 203.18744f, 215.26959f, 228.07019f, 241.63194f, 256.00012f, 271.2227f,
287.35043f, 304.43716f, 322.53995f, 341.71918f, 362.03885f, 383.5668f, 406.37488f,
430.53918f, 456.14038f, 483.2639f, 512.00024f, 542.4454f, 574.70087f, 608.8743f,
645.0799f, 683.43835f, 724.0777f, 767.1336f, 812.74976f, 861.07837f, 912.28076f,
966.5278f, 1024.0005f, 1084.8907f, 1149.4017f, 1217.7487f, 1290.1598f, 1366.8767f,
1448.1554f, 1534.2672f,
};
static float tonedown_tab[128] = {
1.0f, 0.94387436f, 0.8908987f, 0.8408966f, 0.7937002f, 0.74915314f,
0.7071066f, 0.66741943f, 0.62996006f, 0.59460354f, 0.56123066f, 0.52973175f,
0.5f, 0.47193718f, 0.44544888f, 0.4204483f, 0.3968506f, 0.37457657f,
0.35355282f, 0.33370972f, 0.3149805f, 0.2973013f, 0.2806158f, 0.26486588f,
0.25f, 0.23596859f, 0.22272491f, 0.21022415f, 0.1984253f, 0.18728828f,
0.17677689f, 0.16685486f, 0.15748978f, 0.14865112f, 0.14030743f, 0.13243294f,
0.125f, 0.11798382f, 0.11136246f, 0.105112076f, 0.09921265f, 0.09364414f,
0.08838844f, 0.08342743f, 0.07874489f, 0.07432556f, 0.07015419f, 0.06621647f,
0.0625f, 0.058992386f, 0.05568123f, 0.052556038f, 0.049606323f, 0.046822548f,
0.04419422f, 0.041713715f, 0.039372444f, 0.03716278f, 0.035077095f, 0.033107758f,
0.03125f, 0.029496193f, 0.027840614f, 0.026277542f, 0.024803162f, 0.023410797f,
0.022096634f, 0.020856857f, 0.019686699f, 0.01858139f, 0.01753807f, 0.016553879f,
0.015625f, 0.01474762f, 0.01391983f, 0.013138771f, 0.012401581f, 0.011705399f,
0.011048317f, 0.010428429f, 0.009842873f, 0.009290695f, 0.008769035f, 0.008276939f,
0.0078125f, 0.00737381f, 0.006959915f, 0.0065698624f, 0.0062007904f, 0.0058526993f,
0.0055246353f, 0.005214691f, 0.004921913f, 0.0046453476f, 0.0043849945f, 0.0041389465f,
0.00390625f, 0.003686905f, 0.0034799576f, 0.0032844543f, 0.0031003952f, 0.0029268265f,
0.0027618408f, 0.0026073456f, 0.0024604797f, 0.002322197f, 0.0021924973f, 0.0020694733f,
0.001953125f, 0.0018434525f, 0.0017404556f, 0.0016422272f, 0.0015497208f, 0.0014629364f,
0.0013809204f, 0.0013036728f, 0.0012302399f, 0.0011615753f, 0.0010957718f, 0.0010347366f,
9.765625E-4f, 9.2220306E-4f, 8.69751E-4f, 8.211136E-4f, 7.753372E-4f, 7.314682E-4f,
6.904602E-4f, 6.5135956E-4f,
};
s32 sndPitchUpOne(u16 note) { return note * 1.0594631f; }
u32 sndGetPitch(u8 key, u32 sInfo) {
u8 okey; // r31
float frq; // r63
if (sInfo == 0xffffffff) {
sInfo = 0x40005622;
}
okey = sInfo >> 24;
if (key != okey) {
frq = (float)(sInfo & 0xFFFFFF) *
(okey < key ? toneup_tab[key - okey] : tonedown_tab[okey - key]);
} else {
frq = sInfo & 0xFFFFFF;
}
return (4096.f * frq) / synthInfo.mixFrq;
}

View File

@ -1,219 +0,0 @@
#include "musyx/adsr.h"
#include "musyx/synth_dbtab.h"
#include <float.h>
extern float powf(float, float);
static u32 adsrGetIndex(ADSR_VARS* adsr) {
s32 i = 193 - ((adsr->currentIndex + 0x8000) >> 16);
return i < 0 ? 0 : i;
}
u32 adsrConvertTimeCents(s32 tc) { return 1000.f * powf(2.f, 1.2715658e-08f * tc); }
u32 salChangeADSRState(ADSR_VARS* adsr) {
u32 VoiceDone; // r30
VoiceDone = FALSE;
switch (adsr->mode) {
case 0:
switch (adsr->state) {
case 0: {
if ((adsr->cnt = adsr->data.dls.aTime)) {
adsr->state = 1;
adsr->currentVolume = 0;
adsr->currentDelta = 0x7fff0000 / (adsr->data).dls.aTime;
goto done;
}
}
case 1: {
if ((adsr->cnt = adsr->data.dls.dTime)) {
adsr->state = 2;
adsr->currentVolume = 0x7fff0000;
adsr->currentDelta =
-((0x7fff0000 - (adsr->data.dls.sLevel * 0x10000)) / adsr->data.dls.dTime);
goto done;
}
}
case 2: {
if (adsr->data.dls.sLevel != 0) {
adsr->state = 3;
adsr->currentVolume = adsr->data.dls.sLevel << 0x10;
adsr->currentDelta = 0;
goto done;
}
}
case 4: {
break;
}
default:
goto done;
}
adsr->currentVolume = 0;
VoiceDone = TRUE;
break;
case 1:
switch (adsr->state) {
case 0: {
if ((adsr->cnt = adsr->data.dls.aTime)) {
adsr->state = 1;
if (adsr->data.dls.aMode == 0) {
adsr->currentVolume = 0;
adsr->currentDelta = 0x7fff0000 / adsr->cnt;
} else {
adsr->currentVolume = adsr->currentIndex = 0;
adsr->currentDelta = 0xc10000 / adsr->cnt;
}
goto done;
}
}
case 1: {
adsr->cnt = adsr->data.dls.dTime * (((0xc1u - adsr->data.dls.sLevel) * 0x10000) / 0xc1) >> 16;
if (adsr->cnt) {
adsr->state = 2;
adsr->currentVolume = 0x7fff0000;
adsr->currentIndex = 0xc10000;
adsr->currentDelta = -(((0xc1 - (u32)(adsr->data).dls.sLevel) * 0x10000) / adsr->cnt);
goto done;
}
}
case 2: {
if (adsr->data.dls.sLevel) {
adsr->state = 3;
adsr->currentIndex = adsr->data.dls.sLevel << 16;
adsr->currentVolume = dspAttenuationTab[adsrGetIndex(adsr)] << 16;
adsr->currentDelta = 0;
goto done;
}
break;
}
case 4: {
break;
}
default:
goto done;
}
adsr->currentVolume = 0;
VoiceDone = TRUE;
break;
}
done:
return VoiceDone;
}
u32 adsrSetup(ADSR_VARS* adsr) {
adsr->state = 0;
salChangeADSRState(adsr);
}
u32 adsrStartRelease(ADSR_VARS* adsr, u32 rtime) {
switch (adsr->mode) {
case 0:
adsr->state = 4;
adsr->cnt = rtime;
if (rtime == 0) {
adsr->cnt = 1;
adsr->currentDelta = 0;
return 1;
}
adsr->currentDelta = -(adsr->currentVolume / rtime);
break;
case 1:
if (adsr->data.dls.aMode == 0 && adsr->state == 1) {
adsr->currentIndex = (193 - dspScale2IndexTab[adsr->currentVolume >> 21]) * 0x10000;
}
adsr->cnt = (u32)(3.238342E-4f * (float)adsr->currentIndex * (float)rtime) >> 12;
adsr->state = 4;
if (adsr->cnt == 0) {
adsr->cnt = 1;
adsr->currentDelta = adsr->currentIndex = adsr->currentVolume = 0;
return 1;
}
adsr->currentDelta = -(adsr->currentIndex / adsr->cnt);
break;
}
return 0;
}
bool adsrRelease(ADSR_VARS* adsr) {
switch (adsr->mode) {
case 0:
case 1:
return adsrStartRelease(adsr, adsr->data.dls.rTime);
}
return FALSE;
}
u32 adsrHandle(ADSR_VARS* adsr, u16* adsr_start, u16* adsr_delta) {
s32 old_volume; // r29
bool VoiceDone; // r28
s32 vDelta; // r27
VoiceDone = FALSE;
switch (adsr->mode) {
case 0:
if (adsr->state != 3) {
old_volume = adsr->currentVolume;
adsr->currentVolume += adsr->currentDelta;
*adsr_start = old_volume >> 16;
if (adsr->currentDelta >= 0) {
*adsr_delta = adsr->currentDelta >> 21;
} else {
*adsr_delta = -(-adsr->currentDelta >> 21);
}
if (--adsr->cnt == 0) {
VoiceDone = salChangeADSRState(adsr);
}
} else {
*adsr_start = adsr->currentVolume >> 16;
*adsr_delta = 0;
}
break;
case 1:
if (adsr->state != 3) {
old_volume = adsr->currentVolume;
if (adsr->data.dls.aMode == 0 && adsr->state == 1) {
adsr->currentVolume += adsr->currentDelta;
} else {
adsr->currentIndex += adsr->currentDelta;
adsr->currentVolume = dspAttenuationTab[adsrGetIndex(adsr)] << 16;
}
*adsr_start = old_volume >> 16;
vDelta = adsr->currentVolume - old_volume;
if (vDelta >= 0) {
*adsr_delta = vDelta >> 21;
} else {
*adsr_delta = -(-vDelta >> 21);
}
if (--adsr->cnt == 0) {
VoiceDone = salChangeADSRState(adsr);
}
} else {
*adsr_start = adsr->currentVolume >> 16;
*adsr_delta = 0;
}
break;
}
return VoiceDone;
}
u32 adsrHandleLowPrecision(ADSR_VARS* adsr, u16* adsr_start, u16* adsr_delta) {
u8 i; // r31
for (i = 0; i < 15; ++i) {
if (adsrHandle(adsr, adsr_start, adsr_delta)) {
return 1;
}
}
return 0;
}

View File

@ -1,114 +0,0 @@
#include "musyx/synth_dbtab.h"
#ifdef __cplusplus
extern "C" {
#endif
u16 dspAttenuationTab[194] = {
0x7FFF, 0x78D6, 0x7213, 0x6BB1, 0x65AB, 0x5FFB, 0x5A9D, 0x558B, 0x50C2, 0x4C3E, 0x47FA, 0x43F3,
0x4026, 0x3C8F, 0x392C, 0x35F9, 0x32F4, 0x301B, 0x2D6A, 0x2ADF, 0x2879, 0x2636, 0x2412, 0x220E,
0x2026, 0x1E5A, 0x1CA7, 0x1B0D, 0x1989, 0x181C, 0x16C2, 0x157C, 0x1449, 0x1326, 0x1214, 0x1111,
0x101D, 0x0F36, 0x0E5C, 0x0D8E, 0x0CCC, 0x0C15, 0x0B68, 0x0AC5, 0x0A2A, 0x0999, 0x090F, 0x088D,
0x0813, 0x079F, 0x0732, 0x06CB, 0x066A, 0x060E, 0x05B7, 0x0565, 0x0518, 0x04CF, 0x048A, 0x0449,
0x040C, 0x03D2, 0x039B, 0x0367, 0x0337, 0x0309, 0x02DD, 0x02B4, 0x028D, 0x0269, 0x0246, 0x0226,
0x0207, 0x01EA, 0x01CE, 0x01B4, 0x019C, 0x0185, 0x016F, 0x015B, 0x0147, 0x0135, 0x0124, 0x0113,
0x0104, 0x00F5, 0x00E7, 0x00DA, 0x00CE, 0x00C3, 0x00B8, 0x00AD, 0x00A4, 0x009B, 0x0092, 0x008A,
0x0082, 0x007B, 0x0074, 0x006D, 0x0067, 0x0061, 0x005C, 0x0057, 0x0052, 0x004D, 0x0049, 0x0045,
0x0041, 0x003D, 0x003A, 0x0037, 0x0033, 0x0031, 0x002E, 0x002B, 0x0029, 0x0026, 0x0024, 0x0022,
0x0020, 0x001E, 0x001D, 0x001B, 0x001A, 0x0018, 0x0017, 0x0015, 0x0014, 0x0013, 0x0012, 0x0011,
0x0010, 0x000F, 0x000E, 0x000D, 0x000D, 0x000C, 0x000B, 0x000A, 0x000A, 0x0009, 0x0009, 0x0008,
0x0008, 0x0007, 0x0007, 0x0006, 0x0006, 0x0006, 0x0005, 0x0005, 0x0005, 0x0004, 0x0004, 0x0004,
0x0004, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002,
0x0002, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000,
};
u8 dspScale2IndexTab[1024] = {
0xC1, 0x78, 0x6C, 0x65, 0x60, 0x5C, 0x59, 0x57, 0x54, 0x52, 0x50, 0x4F, 0x4D, 0x4C, 0x4B, 0x49,
0x48, 0x47, 0x46, 0x45, 0x44, 0x44, 0x43, 0x42, 0x41, 0x40, 0x40, 0x3F, 0x3F, 0x3E, 0x3D, 0x3D,
0x3C, 0x3C, 0x3B, 0x3B, 0x3A, 0x3A, 0x39, 0x39, 0x38, 0x38, 0x37, 0x37, 0x37, 0x36, 0x36, 0x36,
0x35, 0x35, 0x34, 0x34, 0x34, 0x33, 0x33, 0x33, 0x32, 0x32, 0x32, 0x32, 0x31, 0x31, 0x31, 0x30,
0x30, 0x30, 0x30, 0x2F, 0x2F, 0x2F, 0x2F, 0x2E, 0x2E, 0x2E, 0x2E, 0x2D, 0x2D, 0x2D, 0x2D, 0x2C,
0x2C, 0x2C, 0x2C, 0x2C, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x29, 0x29,
0x29, 0x29, 0x29, 0x29, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x24, 0x24,
0x24, 0x24, 0x24, 0x24, 0x24, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x22, 0x22, 0x22,
0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
0x1F, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1D, 0x1D, 0x1D, 0x1D,
0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,
0x1C, 0x1C, 0x1C, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1A,
0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x19, 0x19, 0x19, 0x19,
0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16,
0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x14, 0x14, 0x14, 0x14, 0x14,
0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x13, 0x13,
0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
0x13, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x10, 0x10, 0x10, 0x10,
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
0x10, 0x10, 0x10, 0x10, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0E, 0x0E, 0x0E,
0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E,
0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
0x0D, 0x0D, 0x0D, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B,
0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B,
0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x09, 0x09, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
float dspDLSVolTab[129] = {
0.000000, 0.000062, 0.000248, 0.000558, 0.000992, 0.001550, 0.002232, 0.003038, 0.003968,
0.005022, 0.006200, 0.007502, 0.008928, 0.010478, 0.012152, 0.013950, 0.015872, 0.017918,
0.020088, 0.022382, 0.024800, 0.027342, 0.030008, 0.032798, 0.035712, 0.038750, 0.041912,
0.045198, 0.048608, 0.052142, 0.055800, 0.059582, 0.063488, 0.067518, 0.071672, 0.075950,
0.080352, 0.084878, 0.089528, 0.094302, 0.099200, 0.104222, 0.109368, 0.114638, 0.120032,
0.125550, 0.131192, 0.136958, 0.142848, 0.148862, 0.155000, 0.161262, 0.167648, 0.174158,
0.180792, 0.187550, 0.194432, 0.201438, 0.208568, 0.215822, 0.223200, 0.230702, 0.238328,
0.246078, 0.253953, 0.261951, 0.270073, 0.278319, 0.286689, 0.295183, 0.303801, 0.312543,
0.321409, 0.330399, 0.339513, 0.348751, 0.358113, 0.367599, 0.377209, 0.386943, 0.396801,
0.406783, 0.416889, 0.427119, 0.437473, 0.447951, 0.458553, 0.469279, 0.480129, 0.491103,
0.502201, 0.513423, 0.524769, 0.536239, 0.547833, 0.559551, 0.571393, 0.583359, 0.595449,
0.607663, 0.620001, 0.632463, 0.645049, 0.657759, 0.670593, 0.683551, 0.696633, 0.709839,
0.723169, 0.736623, 0.750202, 0.763904, 0.777730, 0.791680, 0.805754, 0.819952, 0.834274,
0.848720, 0.863290, 0.877984, 0.892802, 0.907744, 0.922810, 0.938000, 0.953314, 0.968752,
0.984314, 1.000000, 1.000000,
};
#ifdef __cplusplus
}
#endif

View File

@ -1,349 +0,0 @@
#include "musyx/musyx.h"
#include "musyx/assert.h"
#include "musyx/hardware.h"
#include "musyx/macros.h"
#include "musyx/snd.h"
#include "musyx/voice.h"
VS vs;
void vsInit() {
u32 i;
vs.numBuffers = 0;
for (i = 0; i < 64; i++) {
vs.voices[i] = 0xFF;
}
vs.nextInstID = 0;
vs.callback = NULL;
}
u16 vsNewInstanceID() {
u8 i; // r31
u16 instID; // r29
do {
instID = vs.nextInstID++;
i = 0;
for (; i < vs.numBuffers; ++i) {
if (vs.streamBuffer[i].state != 0 && vs.streamBuffer[i].info.instID == instID) {
break;
}
}
} while (i != vs.numBuffers);
return instID;
}
u8 vsAllocateBuffer() {
u8 i;
for (i = 0; i < vs.numBuffers; ++i) {
if (vs.streamBuffer[i].state != 0) {
continue;
}
vs.streamBuffer[i].state = 1;
vs.streamBuffer[i].last = 0;
return i;
}
return 0xFF;
}
void vsFreeBuffer(u8 bufferIndex) {
vs.streamBuffer[bufferIndex].state = 0;
vs.voices[vs.streamBuffer[bufferIndex].voice] = 0xFF;
}
u32 vsSampleStartNotify(unsigned char voice) {
u8 sb; // r29
u8 i; // r28
size_t addr; // r27
for (i = 0; i < vs.numBuffers; ++i) {
if (vs.streamBuffer[i].state != 0 && vs.streamBuffer[i].voice == voice) {
vsFreeBuffer(i);
}
}
sb = vs.voices[voice] = vsAllocateBuffer();
if (sb != 0xFF) {
addr = aramGetStreamBufferAddress(vs.voices[voice], 0);
hwSetVirtualSampleLoopBuffer(voice, (void*)addr, vs.bufferLength);
vs.streamBuffer[sb].info.smpID = hwGetSampleID(voice);
vs.streamBuffer[sb].info.instID = vsNewInstanceID();
vs.streamBuffer[sb].smpType = hwGetSampleType(voice);
vs.streamBuffer[sb].voice = voice;
if (vs.callback != NULL) {
vs.callback(0, &vs.streamBuffer[sb].info);
return (vs.streamBuffer[sb].info.instID << 8) | voice;
}
hwSetVirtualSampleLoopBuffer(voice, 0, 0);
} else {
hwSetVirtualSampleLoopBuffer(voice, 0, 0);
}
return 0xFFFFFFFF;
}
void vsSampleEndNotify(u32 pubID) {
u8 sb;
u8 voice;
if (pubID != 0xFFFFFFFF) {
u8 id = (u8)pubID;
sb = vs.voices[id];
if (sb != 0xFF) {
if (vs.streamBuffer[sb].info.instID == ((pubID >> 8) & 0xFFFF)) {
if (vs.callback != NULL) {
vs.callback(2, &vs.streamBuffer[sb].info);
}
vsFreeBuffer(sb);
}
}
}
}
void vsUpdateBuffer(struct VS_BUFFER* sb, unsigned long cpos) {
u32 len; // r29
u32 off; // r27
if (sb->last == cpos) {
return;
}
if ((s32)sb->last < cpos) {
switch (sb->smpType) {
case 5:
sb->info.data.update.off1 = (sb->last / 14) * 8;
sb->info.data.update.len1 = cpos - sb->last;
sb->info.data.update.off2 = 0;
sb->info.data.update.len2 = 0;
if ((len = vs.callback(1, &sb->info)) != 0) {
off = sb->last + len;
sb->last = off % vs.bufferLength;
}
break;
default:
break;
}
} else if (cpos == 0) {
switch (sb->smpType) {
case 5:
sb->info.data.update.off1 = (sb->last / 14) * 8;
sb->info.data.update.len1 = vs.bufferLength - sb->last;
sb->info.data.update.off2 = 0;
sb->info.data.update.len2 = 0;
if ((len = vs.callback(1, &sb->info)) != 0) {
off = sb->last + len;
sb->last = off % vs.bufferLength;
}
break;
default:
break;
}
} else {
switch (sb->smpType) {
case 5:
sb->info.data.update.off1 = (sb->last / 14) * 8;
sb->info.data.update.len1 = vs.bufferLength - sb->last;
sb->info.data.update.off2 = 0;
sb->info.data.update.len2 = cpos;
if ((len = vs.callback(1, &sb->info)) != 0) {
off = sb->last + len;
sb->last = off % vs.bufferLength;
}
break;
default:
break;
}
}
}
void vsSampleUpdates() {
u32 i; // r29
u32 cpos; // r27
u32 realCPos; // r28
VS_BUFFER* sb; // r31
u32 nextSamples; // r26
if (vs.callback == NULL) {
return;
}
for (i = 0; i < 64; ++i) {
if (vs.voices[i] != 0xFF && hwGetVirtualSampleState(i) != 0) {
sb = &vs.streamBuffer[vs.voices[i]];
realCPos = hwGetPos(i);
cpos = sb->smpType == 5 ? (realCPos / 14) * 14 : realCPos;
switch (sb->state) {
case 1:
vsUpdateBuffer(sb, cpos);
break;
case 2:
case 3:
if (((sb->info.instID << 8) | sb->voice) == hwGetVirtualSampleID(sb->voice)) {
vsUpdateBuffer(sb, cpos);
if (realCPos >= sb->finalLast) {
sb->finalGoodSamples -= (realCPos - sb->finalLast);
} else {
sb->finalGoodSamples -= (vs.bufferLength - (sb->finalLast - realCPos));
}
sb->finalLast = realCPos;
nextSamples = (synthVoice[sb->voice].curPitch * 160 + 0xFFF) / 4096;
if ((s32)nextSamples > (s32)sb->finalGoodSamples) {
if (!hwVoiceInStartup(sb->voice)) {
#if MUSY_VERSION >= MUSY_VERSION_CHECK(1, 5, 4)
if (sb->state == 2) {
hwBreak(sb->voice);
macSampleEndNotify(&synthVoice[sb->voice]);
} else {
voiceKill(sb->voice);
}
#else
hwBreak(sb->voice);
#endif
}
sb->state = 0;
vs.voices[sb->voice] = 0xff;
}
} else {
sb->state = 0;
vs.voices[sb->voice] = 0xff;
}
break;
}
}
}
}
bool sndVirtualSampleAllocateBuffers(u8 numInstances, u32 numSamples, u32 flags) {
s32 i; // r31
u32 len; // r28
MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized.");
MUSY_ASSERT_MSG(numInstances <= 64, "Parameter exceeded maximum number of instances allowable");
hwDisableIrq();
vs.numBuffers = numInstances;
len = sndStreamAllocLength(numSamples, 1);
vs.bufferLength = (len / 8) * 14;
for (i = 0; i < vs.numBuffers; ++i) {
if ((vs.streamBuffer[i].hwId = aramAllocateStreamBuffer(len)) == 0xFF) {
break;
}
vs.streamBuffer[i].state = 0;
vs.voices[vs.streamBuffer[i].voice] = 0xFF;
}
if (i >= vs.numBuffers) {
hwEnableIrq();
return 1;
}
while ((i - 1) > 0) {
aramFreeStreamBuffer(vs.streamBuffer[i - 1].hwId);
--i;
}
hwEnableIrq();
return 0;
}
void sndVirtualSampleFreeBuffers() {
u8 i; // r31
MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized.");
for (i = 0; i < vs.numBuffers; ++i) {
aramFreeStreamBuffer(vs.streamBuffer[i].hwId);
}
vs.numBuffers = 0;
}
void sndVirtualSampleSetCallback(u32 (*callback)(u8 reason, const SND_VIRTUALSAMPLE_INFO* info)) {
MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized.");
vs.callback = callback;
}
void vsARAMDMACallback(size_t user) {
if (vs.callback == NULL) {
return;
}
vs.callback(3, &((VS_BUFFER*)user)->info);
}
void sndVirtualSampleARAMUpdate(SND_INSTID instID, void* base, u32 off1, u32 len1, u32 off2,
u32 len2) {
u8 i;
MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized.");
hwDisableIrq();
for (i = 0; i < vs.numBuffers; ++i) {
if (vs.streamBuffer[i].state == 0 || vs.streamBuffer[i].info.instID != instID) {
continue;
}
if ((s32)vs.streamBuffer[i].smpType != 5) {
i = i;
} else {
off1 = (off1 / 14) * 8;
len1 = ((len1 + 13) / 14) * 8;
off2 = (off2 / 14) * 8;
len2 = ((len2 + 13) / 14) * 8;
}
if (len1 != 0) {
hwFlushStream(base, off1, len1, vs.streamBuffer[i].hwId, vsARAMDMACallback,
(u32)&vs.streamBuffer[i]);
}
if (len2 != 0) {
hwFlushStream(base, off2, len2, vs.streamBuffer[i].hwId, vsARAMDMACallback,
(u32)&vs.streamBuffer[i]);
}
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;
}
hwEnableIrq();
}
void sndVirtualSampleEndPlayback(SND_INSTID instID, bool sampleEndedNormally) {
u8 i; // r30
VS_BUFFER* stream; // r31
u32 cpos; // r28
hwDisableIrq();
for (i = 0; i < vs.numBuffers; ++i) {
if (vs.streamBuffer[i].state == 0 || vs.streamBuffer[i].info.instID != instID) {
continue;
}
stream = &vs.streamBuffer[i];
cpos = hwGetPos(i);
if (stream->last < cpos) {
stream->finalGoodSamples = vs.bufferLength - (cpos - stream->last);
} else {
stream->finalGoodSamples = stream->last - cpos;
}
stream->finalLast = cpos;
stream->state = 2;
break;
}
hwEnableIrq();
}

View File

@ -1,676 +0,0 @@
#include "musyx/synthdata.h"
#include "musyx/assert.h"
#include "musyx/hardware.h"
#include "musyx/snd.h"
static SDIR_TAB dataSmpSDirs[128];
static u16 dataSmpSDirNum;
static DATA_TAB dataCurveTab[2048];
static u16 dataCurveNum;
static DATA_TAB dataKeymapTab[256];
static u16 dataKeymapNum;
static LAYER_TAB dataLayerTab[256];
static u16 dataLayerNum;
static MAC_MAINTAB dataMacMainTab[512];
static MAC_SUBTAB dataMacSubTabmem[2048];
static u16 dataMacTotal;
static FX_GROUP dataFXGroups[128];
static u16 dataFXGroupNum;
bool dataInsertKeymap(u16 cid, void* keymapdata) {
long i; // r31
long j; // r29
hwDisableIrq();
for (i = 0; i < dataKeymapNum && dataKeymapTab[i].id < cid; ++i)
;
if (i < dataKeymapNum) {
if (cid != dataKeymapTab[i].id) {
if (dataKeymapNum < 256) {
for (j = dataKeymapNum - 1; j >= i; --j)
dataKeymapTab[j + 1] = dataKeymapTab[j];
++dataKeymapNum;
} else {
hwEnableIrq();
return 0;
}
} else {
dataKeymapTab[i].refCount++;
hwEnableIrq();
return 0;
}
} else if (dataKeymapNum < 256) {
++dataKeymapNum;
} else {
hwEnableIrq();
return 0;
}
MUSY_ASSERT_MSG(keymapdata != NULL, "Keymap data pointer is NULL");
dataKeymapTab[i].id = cid;
dataKeymapTab[i].data = keymapdata;
dataKeymapTab[i].refCount = 1;
hwEnableIrq();
return 1;
}
bool dataRemoveKeymap(u16 sid) {
long i; // r31
long j; // r30
hwDisableIrq();
for (i = 0; i < dataKeymapNum && dataKeymapTab[i].id != sid; ++i)
;
if (i != dataKeymapNum && --dataKeymapTab[i].refCount == 0) {
for (j = i + 1; j < dataKeymapNum; j++) {
dataKeymapTab[j - 1] = dataKeymapTab[j];
}
--dataKeymapNum;
hwEnableIrq();
return 1;
}
hwEnableIrq();
return 0;
}
bool dataInsertLayer(u16 cid, void* layerdata, u16 size) {
long i; // r31
long j; // r29
hwDisableIrq();
for (i = 0; i < dataLayerNum && dataLayerTab[i].id < cid; ++i)
;
if (i < dataLayerNum) {
if (cid != dataLayerTab[i].id) {
if (dataLayerNum < 256) {
for (j = dataLayerNum - 1; j >= i; --j)
dataLayerTab[j + 1] = dataLayerTab[j];
++dataLayerNum;
} else {
hwEnableIrq();
return 0;
}
} else {
dataLayerTab[i].refCount++;
hwEnableIrq();
return 0;
}
} else if (dataLayerNum < 256) {
++dataLayerNum;
} else {
hwEnableIrq();
return 0;
}
MUSY_ASSERT_MSG(layerdata != NULL, "Layer data pointer is NULL");
dataLayerTab[i].id = cid;
dataLayerTab[i].data = layerdata;
dataLayerTab[i].num = size;
dataLayerTab[i].refCount = 1;
hwEnableIrq();
return 1;
}
bool dataRemoveLayer(u16 sid) {
long i; // r31
long j; // r30
hwDisableIrq();
for (i = 0; i < dataLayerNum && dataLayerTab[i].id != sid; ++i)
;
if (i != dataLayerNum && --dataLayerTab[i].refCount == 0) {
for (j = i + 1; j < dataLayerNum; j++) {
dataLayerTab[j - 1] = dataLayerTab[j];
}
--dataLayerNum;
hwEnableIrq();
return 1;
}
hwEnableIrq();
return 0;
}
bool dataInsertCurve(u16 cid, void* curvedata) {
long i; // r31
long j; // r29
hwDisableIrq();
for (i = 0; i < dataCurveNum && dataCurveTab[i].id < cid; ++i)
;
if (i < dataCurveNum) {
if (cid != dataCurveTab[i].id) {
if (dataCurveNum < 2048) {
for (j = dataCurveNum - 1; j >= i; --j)
dataCurveTab[j + 1] = dataCurveTab[j];
++dataCurveNum;
} else {
hwEnableIrq();
return 0;
}
} else {
hwEnableIrq();
dataCurveTab[i].refCount++;
return 0;
}
} else if (dataCurveNum < 2048) {
++dataCurveNum;
} else {
hwEnableIrq();
return 0;
}
MUSY_ASSERT_MSG(curvedata != NULL, "Curve data pointer is NULL");
dataCurveTab[i].id = cid;
dataCurveTab[i].data = curvedata;
dataCurveTab[i].refCount = 1;
hwEnableIrq();
return 1;
}
bool dataRemoveCurve(u16 sid) {
long i; // r31
long j; // r30
hwDisableIrq();
for (i = 0; i < dataCurveNum && dataCurveTab[i].id != sid; ++i)
;
if (i != dataCurveNum && --dataCurveTab[i].refCount == 0) {
for (j = i + 1; j < dataCurveNum; j++) {
dataCurveTab[j - 1] = dataCurveTab[j];
}
--dataCurveNum;
hwEnableIrq();
return 1;
}
hwEnableIrq();
return 0;
}
bool dataInsertSDir(SDIR_DATA* sdir, void* smp_data) {
s32 i; // r31
SDIR_DATA* s; // r25
u16 n; // r27
u16 j; // r29
u16 k; // r26
for (i = 0; i < dataSmpSDirNum && dataSmpSDirs[i].data != sdir; ++i)
;
if (i == dataSmpSDirNum) {
if (dataSmpSDirNum < 128) {
n = 0;
for (s = sdir; s->id != 0xffff; ++s) {
++n;
}
hwDisableIrq();
for (j = 0; j < n; ++j) {
for (i = 0; i < dataSmpSDirNum; ++i) {
for (k = 0; k < dataSmpSDirs[i].numSmp; ++k) {
if (sdir[j].id == dataSmpSDirs[i].data[k].id)
goto found_id;
}
}
found_id:
if (i != dataSmpSDirNum) {
sdir[j].ref_cnt = 0xffff;
} else {
sdir[j].ref_cnt = 0;
}
}
dataSmpSDirs[dataSmpSDirNum].data = sdir;
dataSmpSDirs[dataSmpSDirNum].numSmp = n;
dataSmpSDirs[dataSmpSDirNum].base = smp_data;
++dataSmpSDirNum;
hwEnableIrq();
return 1;
} else {
return 0;
}
}
return 1;
}
bool dataRemoveSDir(struct SDIR_DATA* sdir) {
long i; // r28
long j; // r30
long index; // r27
SDIR_DATA* data; // r31
index = 0;
for (; index < dataSmpSDirNum && dataSmpSDirs[index].data != sdir; ++index) {
}
if (index != dataSmpSDirNum) {
hwDisableIrq();
for (data = sdir; data->id != 0xFFFF; ++data) {
if (data->ref_cnt != 0xFFFF && data->ref_cnt != 0)
break;
}
if (data->id == 0xFFFF) {
data = sdir;
for (data = sdir; data->id != 0xFFFF; ++data) {
if (data->ref_cnt != 0xFFFF) {
for (i = 0; i < dataSmpSDirNum; ++i) {
if (dataSmpSDirs[i].data == sdir)
continue;
for (j = 0; j < dataSmpSDirs[i].numSmp; ++j) {
if (data->id == dataSmpSDirs[i].data[j].id &&
dataSmpSDirs[i].data[j].ref_cnt == 0xFFFF) {
dataSmpSDirs[i].data[j].ref_cnt = 0;
break;
}
}
if (j != dataSmpSDirs[i].numSmp) {
break;
}
}
} else {
}
}
data = sdir;
for (; data->id != 0xFFFF; ++data) {
data->ref_cnt = 0;
}
for (j = index + 1; j < dataSmpSDirNum; ++j) {
dataSmpSDirs[j - 1] = dataSmpSDirs[j];
}
--dataSmpSDirNum;
hwEnableIrq();
return TRUE;
}
hwEnableIrq();
}
return FALSE;
}
bool dataAddSampleReference(u16 sid) {
u32 i; // r29
SAMPLE_HEADER* header; // r1+0xC
SDIR_DATA* data; // r30
SDIR_DATA* sdir; // r31
data = NULL;
sdir = NULL;
for (i = 0; i < dataSmpSDirNum; ++i) {
for (data = dataSmpSDirs[i].data; data->id != 0xFFFF; ++data) {
if (data->id == sid && data->ref_cnt != 0xFFFF) {
sdir = data;
goto done;
}
}
}
done:
MUSY_ASSERT_MSG(sdir != NULL,
"Sample ID to be inserted could not be found in any sample directory.\n");
if (sdir->ref_cnt == 0) {
sdir->addr = (void*)((size_t)sdir->offset + (s32)dataSmpSDirs[i].base);
header = &sdir->header;
hwSaveSample(&header, &sdir->addr);
}
++sdir->ref_cnt;
return TRUE;
}
bool dataRemoveSampleReference(u16 sid) {
u32 i; // r30
SDIR_DATA* sdir; // r31
for (i = 0; i < dataSmpSDirNum; ++i) {
for (sdir = dataSmpSDirs[i].data; sdir->id != 0xFFFF; ++sdir) {
if (sdir->id == sid && sdir->ref_cnt != 0xFFFF) {
--sdir->ref_cnt;
if (sdir->ref_cnt == 0) {
hwRemoveSample(&sdir->header, sdir->addr);
}
return TRUE;
}
}
}
return FALSE;
}
bool dataInsertFX(u16 gid, struct FX_TAB* fx, u16 fxNum) {
long i; // r31
for (i = 0; i < dataFXGroupNum && gid != dataFXGroups[i].gid; ++i) {
}
if (i == dataFXGroupNum && dataFXGroupNum < 128) {
hwDisableIrq();
dataFXGroups[dataFXGroupNum].gid = gid;
dataFXGroups[dataFXGroupNum].fxNum = fxNum;
dataFXGroups[dataFXGroupNum].fxTab = fx;
for (i = 0; i < fxNum; ++i, ++fx) {
fx->vGroup = 31;
}
dataFXGroupNum++;
hwEnableIrq();
return TRUE;
}
return FALSE;
}
bool dataRemoveFX(u16 gid) {
long i; // r31
long j; // r30
for (i = 0; i < dataFXGroupNum && gid != dataFXGroups[i].gid; ++i) {
}
if (i != dataFXGroupNum) {
hwDisableIrq();
for (j = i + 1; j < dataFXGroupNum; j++) {
dataFXGroups[j - 1] = dataFXGroups[j];
}
--dataFXGroupNum;
hwEnableIrq();
return TRUE;
}
return FALSE;
}
bool dataInsertMacro(u16 mid, void* macroaddr) {
long main; // r28
long pos; // r29
long base; // r27
long i; // r31
hwDisableIrq();
main = (mid >> 6) & 0x3ff;
if (dataMacMainTab[main].num == 0) {
pos = base = dataMacMainTab[main].subTabIndex = dataMacTotal;
} else {
base = dataMacMainTab[main].subTabIndex;
for (i = 0; i < dataMacMainTab[main].num && dataMacSubTabmem[base + i].id < mid; ++i) {
}
if (i < dataMacMainTab[main].num) {
pos = base + i;
if (mid == dataMacSubTabmem[pos].id) {
dataMacSubTabmem[pos].refCount++;
hwEnableIrq();
return FALSE;
}
} else {
pos = base + i;
}
}
if (dataMacTotal < 2048) {
MUSY_ASSERT_MSG(macroaddr, "Macro data pointer is NULL");
for (i = 0; i < 512; ++i) {
if (dataMacMainTab[i].subTabIndex > base) {
dataMacMainTab[i].subTabIndex++;
}
}
i = dataMacTotal - 1;
for (; i >= pos; --i) {
dataMacSubTabmem[i + 1] = dataMacSubTabmem[i];
}
dataMacSubTabmem[pos].id = mid;
dataMacSubTabmem[pos].data = macroaddr;
dataMacSubTabmem[pos].refCount = 1;
dataMacMainTab[main].num++;
dataMacTotal++;
hwEnableIrq();
return TRUE;
}
hwEnableIrq();
return FALSE;
}
bool dataRemoveMacro(u16 mid) {
s32 main; // r29
s32 base; // r28
s32 i; // r31
hwDisableIrq();
main = (mid >> 6) & 0x3ff;
if (dataMacMainTab[main].num != 0) {
base = dataMacMainTab[main].subTabIndex;
for (i = 0; i < dataMacMainTab[main].num && mid != dataMacSubTabmem[base + i].id; ++i) {
}
if (i < dataMacMainTab[main].num) {
if (--dataMacSubTabmem[base + i].refCount == 0) {
for (i = base + i + 1; i < dataMacTotal; ++i) {
dataMacSubTabmem[i - 1] = dataMacSubTabmem[i];
}
for (i = 0; i < 512; ++i) {
if (dataMacMainTab[i].subTabIndex > base) {
--dataMacMainTab[i].subTabIndex;
}
}
--dataMacMainTab[main].num;
--dataMacTotal;
}
}
}
hwEnableIrq();
return FALSE;
}
static s32 maccmp(void* p1, void* p2) { return ((MAC_SUBTAB*)p1)->id - ((MAC_SUBTAB*)p2)->id; }
MSTEP* dataGetMacro(u16 mid) {
static s32 base;
static s32 main;
static MAC_SUBTAB key;
static MAC_SUBTAB* result;
main = (mid >> 6) & 0x3fff;
if (dataMacMainTab[main].num != 0) {
base = dataMacMainTab[main].subTabIndex;
key.id = mid;
if ((result = (MAC_SUBTAB*)sndBSearch(&key, &dataMacSubTabmem[base], dataMacMainTab[main].num,
8, maccmp)) != NULL) {
return result->data;
}
}
return NULL;
}
static s32 smpcmp(void* p1, void* p2) { return ((SDIR_DATA*)p1)->id - ((SDIR_DATA*)p2)->id; }
s32 dataGetSample(u16 sid, SAMPLE_INFO* newsmp) {
static SDIR_DATA key;
static SDIR_DATA* result;
static SAMPLE_HEADER* sheader;
long i; // r30
key.id = sid;
for (i = 0; i < dataSmpSDirNum; ++i) {
if ((result = sndBSearch(&key, dataSmpSDirs[i].data, dataSmpSDirs[i].numSmp, sizeof(SDIR_DATA),
smpcmp)) != NULL) {
if (result->ref_cnt != 0xFFFF) {
sheader = &result->header;
newsmp->info = sheader->info;
newsmp->addr = result->addr;
newsmp->offset = 0;
newsmp->loop = sheader->loopOffset;
newsmp->length = sheader->length & 0xffffff;
newsmp->loopLength = sheader->loopLength;
newsmp->compType = sheader->length >> 24;
if (result->extraData) {
newsmp->extraData = (void*)((size_t) & (dataSmpSDirs[i].data)->id + result->extraData);
}
return 0;
}
}
}
return -1;
}
static s32 curvecmp(void* p1, void* p2) { return ((DATA_TAB*)p1)->id - ((DATA_TAB*)p2)->id; }
void* dataGetCurve(u16 cid) {
static DATA_TAB key;
static DATA_TAB* result;
key.id = cid;
if ((result =
(DATA_TAB*)sndBSearch(&key, dataCurveTab, dataCurveNum, sizeof(DATA_TAB), curvecmp))) {
return result->data;
}
return NULL;
}
void* dataGetKeymap(u16 cid) {
static DATA_TAB key;
static DATA_TAB* result;
key.id = cid;
if ((result =
(DATA_TAB*)sndBSearch(&key, dataKeymapTab, dataKeymapNum, sizeof(DATA_TAB), curvecmp))) {
return result->data;
}
return NULL;
}
static s32 layercmp(void* p1, void* p2) { return ((LAYER_TAB*)p1)->id - ((LAYER_TAB*)p2)->id; }
void* dataGetLayer(u16 cid, u16* n) {
static LAYER_TAB key;
static LAYER_TAB* result;
key.id = cid;
if ((result =
(LAYER_TAB*)sndBSearch(&key, dataLayerTab, dataLayerNum, sizeof(LAYER_TAB), layercmp))) {
*n = result->num;
return result->data;
}
return NULL;
}
static s32 fxcmp(void* p1, void* p2) {
return ((FX_TAB*)p1)->id - ((FX_TAB*)p2)->id;
}
struct FX_TAB* dataGetFX(u16 fid) {
static FX_TAB key;
FX_TAB* ret; // r29
long i; // r31
key.id = fid;
for (i = 0; i < dataFXGroupNum; ++i) {
if ((ret = (FX_TAB*)sndBSearch(&key, dataFXGroups[i].fxTab, dataFXGroups[i].fxNum,
sizeof(FX_TAB), fxcmp))) {
return ret;
}
}
return NULL;
}
void dataInit(u32 smpBase, u32 smpLength) {
long i; // r31
dataSmpSDirNum = 0;
dataCurveNum = 0;
dataKeymapNum = 0;
dataLayerNum = 0;
dataFXGroupNum = 0;
dataMacTotal = 0;
for (i = 0; i < 512; ++i) {
dataMacMainTab[i].num = 0;
dataMacMainTab[i].subTabIndex = 0;
}
hwInitSampleMem(smpBase, smpLength);
}
void dataExit() { hwExitSampleMem(); }
#if MUSY_TARGET == MUSY_PLATFORM_PC
void* sndConvert32BitSDIRTo64BitSDIR(void* sdir_int) {
SDIR_DATA_INTER* sdir_inter = sdir_int;
SDIR_DATA* sdir = NULL;
s32 i = 0;
SDIR_DATA* s;
SDIR_DATA_INTER* s2 = NULL;
u16 n = 0;
for (s2 = sdir_inter; s2->id != 0xffff; ++s2) {
++n;
}
++n;
sdir = malloc(n * sizeof(SDIR_DATA));
for (i = 0; i < n; ++i) {
sdir[i].id = sdir_inter[i].id;
sdir[i].ref_cnt = sdir_inter[i].ref_cnt;
sdir[i].offset = sdir_inter[i].offset;
sdir[i].addr = (void*)(size_t)sdir_inter[i].addr;
sdir[i].header = sdir_inter[i].header;
sdir[i].extraData = sdir_inter[i].extraData;
}
free(sdir_int);
return sdir;
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,677 +0,0 @@
#include "musyx/musyx.h"
#include "musyx/assert.h"
#include "musyx/hardware.h"
#include "musyx/macros.h"
#include "musyx/stream.h"
#include "musyx/voice.h"
void voiceResetLastStarted(SYNTH_VOICE* svoice);
static VID_LIST vidList[128];
static u8 synth_last_started[8][16];
static u8 synth_last_fxstarted[64];
SYNTH_VOICELIST voiceList[64];
SYNTH_ROOTLIST voicePrioSortRootList[256];
u8 voicePrioSortVoicesRoot[256];
SYNTH_VOICELIST voicePrioSortVoices[64];
static VID_LIST* vidFree = NULL;
static VID_LIST* vidRoot = NULL;
static u32 vidCurrentId = 0;
u16 voicePrioSortRootListRoot = 0;
u8 voiceMusicRunning = 0;
u8 voiceFxRunning = 0;
u8 voiceListInsert = 0;
u8 voiceListRoot = 0;
void vidInit() {
int i;
VID_LIST* lvl;
vidCurrentId = 0;
vidRoot = NULL;
vidFree = vidList;
for (lvl = NULL, i = 0; i < 128; lvl = &vidList[i], ++i) {
vidList[i].prev = lvl;
if (lvl != NULL) {
lvl->next = &vidList[i];
}
}
lvl->next = NULL;
}
static VID_LIST* get_vidlist(u32 vid) {
VID_LIST* vl = vidRoot;
while (vl != NULL) {
if (vl->vid == vid) {
return vl;
}
if (vl->vid > vid) {
break;
}
vl = vl->next;
}
return NULL;
}
static u32 get_newvid() {
u32 vid; // r31
do {
vid = vidCurrentId++;
} while (vid == 0xFFFFFFFF);
return vid;
}
static void vidRemove(VID_LIST** vidList) {
if ((*vidList)->prev != NULL) {
(*vidList)->prev->next = (*vidList)->next;
} else {
vidRoot = (*vidList)->next;
}
if ((*vidList)->next != NULL) {
(*vidList)->next->prev = (*vidList)->prev;
}
(*vidList)->next = vidFree;
if (vidFree != NULL) {
vidFree->prev = *vidList;
}
(*vidList)->prev = NULL;
vidFree = *vidList;
*vidList = NULL;
}
void vidRemoveVoiceReferences(SYNTH_VOICE* svoice) {
if (svoice->id == 0xFFFFFFFF) {
return;
}
voiceResetLastStarted(svoice);
if (svoice->parent != 0xFFFFFFFF) {
synthVoice[svoice->parent & 0xFF].child = svoice->child;
if (svoice->child != 0xFFFFFFFF) {
synthVoice[svoice->child & 0xFF].parent = svoice->parent;
}
vidRemove(&svoice->vidList);
} else if (svoice->child != 0xFFFFFFFF) {
svoice->vidList->root = svoice->child;
synthVoice[svoice->child & 0xFF].parent = 0xFFFFFFFF;
synthVoice[svoice->child & 0xFF].vidMasterList = svoice->vidMasterList;
if (svoice->vidList != svoice->vidMasterList) {
vidRemove(&svoice->vidList);
}
svoice->vidMasterList = svoice->vidList = NULL;
} else if (svoice->vidList != svoice->vidMasterList) {
vidRemove(&svoice->vidList);
vidRemove(&svoice->vidMasterList);
} else {
vidRemove(&svoice->vidList);
svoice->vidMasterList = NULL;
}
}
u32 vidMakeRoot(SYNTH_VOICE* svoice) {
svoice->vidMasterList = svoice->vidList;
return svoice->vidList->vid;
}
u32 vidMakeNew(SYNTH_VOICE* svoice, u32 isMaster) {
u32 vid; // r29
VID_LIST* nvl; // r30
VID_LIST* lvl; // r28
VID_LIST* vl; // r31
vid = get_newvid();
lvl = NULL;
nvl = vidRoot;
while (nvl != NULL) {
if (nvl->vid > vid) {
break;
}
if (nvl->vid == vid) {
vid = get_newvid();
}
lvl = nvl;
nvl = nvl->next;
}
if ((vl = vidFree) == NULL) {
return 0xFFFFFFFF;
}
if ((vidFree = vidFree->next) != NULL) {
vidFree->prev = NULL;
}
if (lvl == NULL) {
vidRoot = vl;
} else {
lvl->next = vl;
}
vl->prev = lvl;
vl->next = nvl;
if (nvl != NULL) {
nvl->prev = vl;
}
vl->vid = vid;
vl->root = svoice->id;
svoice->vidMasterList = isMaster ? vl : NULL;
svoice->vidList = vl;
return isMaster ? vid : svoice->id;
}
u32 vidGetInternalId(u32 vid) {
VID_LIST* vl;
if (vid != 0xffffffff) {
if ((vl = get_vidlist(vid)) != NULL) {
return vl->root;
}
}
return 0xffffffff;
}
static void voiceInitPrioSort() {
u32 i;
for (i = 0; i < synthInfo.voiceNum; ++i) {
voicePrioSortVoices[i].user = 0;
}
for (i = 0; i < 256; ++i) {
voicePrioSortVoicesRoot[i] = 0xff;
}
voicePrioSortRootListRoot = 0xffff;
}
void voiceRemovePriority(SYNTH_VOICE* svoice) {
SYNTH_VOICELIST* vps; // r31
SYNTH_ROOTLIST* rps; // r30
vps = &voicePrioSortVoices[svoice->id & 0xFF];
if (vps->user != 1) {
return;
}
if (vps->prev != 0xFF) {
voicePrioSortVoices[vps->prev].next = vps->next;
} else {
voicePrioSortVoicesRoot[svoice->prio] = vps->next;
}
if (vps->next != 0xFF) {
voicePrioSortVoices[vps->next].prev = vps->prev;
} else if (vps->prev == 0xFF) {
rps = &voicePrioSortRootList[svoice->prio];
if (rps->prev != 0xFFFF) {
voicePrioSortRootList[rps->prev].next = rps->next;
} else {
voicePrioSortRootListRoot = rps->next;
}
if (rps->next != 0xFFFF) {
voicePrioSortRootList[rps->next].prev = rps->prev;
}
}
vps->user = 0;
}
void voiceSetPriority(SYNTH_VOICE* svoice, u8 prio) {
u16 li; // r25
SYNTH_VOICELIST* vps; // r27
u16 i; // r29
u32 v; // r26
v = (u8)svoice->id;
vps = &voicePrioSortVoices[v];
if (vps->user == 1) {
if (svoice->prio == prio) {
return;
}
voiceRemovePriority(svoice);
}
vps->user = 1;
vps->prev = 0xff;
if ((vps->next = voicePrioSortVoicesRoot[prio]) != 0xFF) {
voicePrioSortVoices[voicePrioSortVoicesRoot[prio]].prev = v;
} else if (voicePrioSortRootListRoot != 0xFFFF) {
if (prio >= voicePrioSortRootListRoot) {
for (i = voicePrioSortRootListRoot; i != 0xFFFF; i = voicePrioSortRootList[i].next) {
if ((u16)i > prio) {
break;
}
li = i;
}
voicePrioSortRootList[li].next = (u16)prio;
voicePrioSortRootList[prio].prev = li;
voicePrioSortRootList[prio].next = i;
if (i != 0xFFFF) {
voicePrioSortRootList[i].prev = prio;
}
} else {
voicePrioSortRootList[prio].next = voicePrioSortRootListRoot;
voicePrioSortRootList[prio].prev = 0xFFFF;
voicePrioSortRootList[voicePrioSortRootListRoot].prev = prio;
voicePrioSortRootListRoot = prio;
}
} else {
voicePrioSortRootList[prio].next = 0xFFFF;
voicePrioSortRootList[prio].prev = 0xFFFF;
voicePrioSortRootListRoot = prio;
}
voicePrioSortVoicesRoot[prio] = v;
svoice->prio = prio;
hwSetPriority(svoice->id & 0xFF, ((u32)prio << 24) | (svoice->age >> 15));
}
u32 voiceAllocate(u8 priority, u8 maxVoices, u16 allocId, u8 fxFlag) {
s32 i; // r31
s32 num; // r26
s32 voice; // r30
u16 p; // r29
u32 type_alloc; // r25
SYNTH_VOICELIST* sfv; // r27
if (!synthIdleWaitActive) {
if (fxFlag) {
type_alloc = (voiceFxRunning >= synthInfo.maxSFX && synthInfo.voiceNum > synthInfo.maxSFX);
if (synthInfo.maxSFX <= maxVoices) {
goto _skip_alloc;
}
goto _do_alloc;
} else {
type_alloc = (voiceMusicRunning >= synthInfo.maxMusic && synthInfo.voiceNum > synthInfo.maxMusic);
if (synthInfo.maxMusic <= maxVoices) {
goto _skip_alloc;
}
_do_alloc:
num = 0;
voice = -1;
p = voicePrioSortRootListRoot;
while (p != 0xFFFF && priority >= p && voice == -1) {
for (i = voicePrioSortVoicesRoot[p]; i != 0xff; i = voicePrioSortVoices[i].next) {
if (allocId != synthVoice[i].allocId)
continue;
++num;
if(synthVoice[i].block)
continue;
if (!type_alloc || fxFlag == synthVoice[i].fxFlag) {
if((synthVoice[i].cFlags & 2))
continue;
if (voice != -1) {
if(synthVoice[i].age < synthVoice[voice].age)
voice = i;
}
else
voice = i;
}
}
p = voicePrioSortRootList[p].next;
}
}
if (num < maxVoices) {
while (p != 0xffff && num < maxVoices) {
i = voicePrioSortVoicesRoot[p];
while (i != 0xff) {
if (allocId == synthVoice[i].allocId) {
num++;
}
i = voicePrioSortVoices[i].next;
}
p = voicePrioSortRootList[p].next;
}
if (num < maxVoices) {
_skip_alloc:
if (voiceListRoot != 0xff && type_alloc == 0) {
voice = voiceListRoot;
goto _update;
}
if (priority < voicePrioSortRootListRoot) {
return -1;
}
voice = -1;
p = voicePrioSortRootListRoot;
while (p != 0xFFFF && priority >= p && voice == -1) {
for (i = voicePrioSortVoicesRoot[p]; i != 0xff; i = voicePrioSortVoices[i].next) {
if (synthVoice[i].block != 0)
continue;
if (!type_alloc || fxFlag == synthVoice[i].fxFlag) {
if((synthVoice[i].cFlags & 2))
continue;
if (voice != -1) {
if(synthVoice[voice].age > synthVoice[i].age)
voice = i;
}
else
voice = i;
}
}
p = voicePrioSortRootList[p].next;
}
if (voice == -1) {
return 0xffffffff;
}
if (synthVoice[voice].prio > priority) {
goto _fail;
}
}
}
_update:
if (voice == -1) {
goto _fail;
}
if (voiceList[voice].user == 1) {
sfv = voiceList + voice;
i = sfv->prev;
if (i != 0xff) {
voiceList[i].next = sfv->next;
} else {
voiceListRoot = sfv->next;
}
i = sfv->next;
if (i != 0xff) {
voiceList[i].prev = sfv->prev;
}
if (voice == voiceListInsert) {
voiceListInsert = sfv->prev;
}
sfv->user = 0;
} else if (synthVoice[voice].fxFlag) {
voiceFxRunning--;
} else {
voiceMusicRunning--;
}
if (fxFlag != FALSE) {
++voiceFxRunning;
} else {
++voiceMusicRunning;
}
return voice;
}
_fail:
return -1;
}
void voiceFree(SYNTH_VOICE* svoice) {
u32 i; // r29
SYNTH_VOICELIST* sfv; // r30
i = 1;
MUSY_ASSERT(svoice->id != 0xFFFFFFFF);
macMakeInactive(svoice, MAC_STATE_STOPPED);
voiceRemovePriority(svoice);
svoice->addr = NULL;
svoice->prio = 0;
sfv = &voiceList[(i = svoice->id & 0xFF)];
if (sfv->user == 0) {
sfv->user = 1;
if (voiceListRoot != 0xFF) {
sfv->next = 0xFF;
sfv->prev = voiceListInsert;
voiceList[voiceListInsert].next = i;
} else {
sfv->next = 0xFF;
sfv->prev = 0xFF;
voiceListRoot = i;
}
voiceListInsert = i;
if (svoice->fxFlag != 0) {
--voiceFxRunning;
} else {
--voiceMusicRunning;
}
}
svoice->id = 0xFFFFFFFF;
}
static void voiceInitFreeList() {
u32 i; // r31
for (i = 0; i < synthInfo.voiceNum; ++i) {
voiceList[i].prev = i - 1;
voiceList[i].next = i + 1;
voiceList[i].user = 1;
}
voiceList[0].prev = 0xff;
voiceList[synthInfo.voiceNum - 1].next = 0xff;
voiceListRoot = 0;
voiceListInsert = synthInfo.voiceNum - 1;
}
void synthInitAllocationAids() {
voiceInitFreeList();
voiceInitPrioSort();
voiceFxRunning = 0;
voiceMusicRunning = 0;
}
u32 voiceBlock(u8 prio) {
u32 voice;
if ((voice = voiceAllocate(prio, 0xFF, 0xFFFF, 1)) != 0xFFFFFFFF) {
synthVoice[voice].block = 1;
synthVoice[voice].fxFlag = 1;
#if MUSY_VERSION >= MUSY_VERSION_CHECK(1, 5, 4)
synthVoice[voice].allocId = 0xFFFF;
#endif
vidRemoveVoiceReferences(&synthVoice[voice]);
synthVoice[voice].id = voice | 0xFFFFFF00;
if (hwIsActive(voice)) {
hwBreak(voice);
}
macMakeInactive(&synthVoice[voice], MAC_STATE_STOPPED);
synthVoice[voice].addr = NULL;
voiceSetPriority(&synthVoice[voice], prio);
}
return voice;
}
void voiceUnblock(u32 voice) {
if (voice == 0xFFFFFFFF) {
return;
}
if (hwIsActive(voice)) {
hwBreak(voice);
}
synthVoice[voice].id = voice;
voiceFree(&synthVoice[voice]);
synthVoice[voice].block = 0;
}
void voiceKill(u32 vi) {
SYNTH_VOICE* sv = &synthVoice[vi]; // r31
if (sv->addr != NULL) {
vidRemoveVoiceReferences(sv);
sv->cFlags &= ~3;
sv->age = 0;
voiceFree(sv);
}
if (sv->block != 0) {
streamKill(vi);
}
hwBreak(vi);
}
s32 voiceKillSound(u32 voiceid) {
s32 ret = -1; // r29
u32 next_voiceid; // r28
u32 i; // r30
if (sndActive != FALSE) {
for (voiceid = vidGetInternalId(voiceid); voiceid != -1; voiceid = next_voiceid) {
i = voiceid & 0xff;
next_voiceid = synthVoice[i].child;
if (voiceid == synthVoice[i].id) {
voiceKill(i);
ret = 0;
}
}
}
return ret;
}
void synthKillAllVoices(unsigned char musiconly) {
u32 i;
for (i = 0; i < synthInfo.voiceNum; ++i) {
if (synthVoice[i].addr != NULL) {
if (musiconly == 0 || (musiconly != 0 && synthVoice[i].fxFlag == 0)) {
voiceKill(i);
}
} else {
voiceKill(i);
}
}
}
void synthKillVoicesByMacroReferences(u16* ref) {
u32 i; // r31
u16 id; // r29
for (i = 0; i < synthInfo.voiceNum; ++i) {
if (synthVoice[i].addr == NULL && synthVoice[i].block == 0) {
voiceKill(i);
}
}
while (*ref != 0xFFFF) {
if ((*ref & 0x8000)) {
id = *ref & 0x3fff;
while (id <= ref[1]) {
for (i = 0; i < synthInfo.voiceNum; ++i) {
if (synthVoice[i].addr != NULL && id == synthVoice[i].macroId) {
voiceKill(i);
}
}
++id;
}
ref += 2;
} else {
for (i = 0; i < synthInfo.voiceNum; ++i) {
if (synthVoice[i].addr != NULL && *ref == synthVoice[i].macroId) {
voiceKill(i);
}
}
++ref;
}
}
}
u32 voiceIsLastStarted(SYNTH_VOICE* svoice) {
u32 i; // r31
if (svoice->id != 0xFFFFFFFF && svoice->midi != 0xFF) {
i = svoice->id & 0xFF;
if (svoice->midiSet == 0xFF) {
if (synth_last_fxstarted[i] == i) {
return TRUE;
}
} else if (synth_last_started[svoice->midiSet][svoice->midi] == i) {
return TRUE;
}
}
return FALSE;
}
void voiceSetLastStarted(SYNTH_VOICE* svoice) {
u32 i; // r31
if (svoice->id != 0xFFFFFFFF && svoice->midi != 0xFF) {
i = svoice->id & 0xFF;
if (svoice->midiSet == 0xFF) {
synth_last_fxstarted[i] = i;
} else {
synth_last_started[svoice->midiSet][svoice->midi] = i;
}
}
}
void voiceResetLastStarted(struct SYNTH_VOICE* svoice) {
u32 i;
if ((svoice->id != 0xffffffff) && (svoice->midi != 0xff)) {
i = svoice->id & 0xff;
if (svoice->midiSet == 0xff) {
if (synth_last_fxstarted[i] == i) {
synth_last_fxstarted[i] = 0xff;
}
} else if (i == synth_last_started[svoice->midiSet][svoice->midi]) {
synth_last_started[svoice->midiSet][svoice->midi] = 0xff;
}
}
}
void voiceInitLastStarted() {
u32 i;
u32 j;
for (i = 0; i < 8; ++i) {
for (j = 0; j < 16; ++j) {
synth_last_started[i][j] = 0xFF;
}
}
for (j = 0; j < 64; ++j) {
synth_last_fxstarted[j] = 0xFF;
}
}

View File

@ -1,230 +0,0 @@
#include "musyx/txwin.h"
#include "dolphin/gx.h"
#include "dolphin/os.h"
#include "musyx/assert.h"
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
/* TODO: TEMPORARY HACKS */
extern GXRenderModeObj* DEMOGetRenderModeObj();
extern void DEMOPrintf(s16, s16, s16, char*, ...);
static void __win_log_refresh(sWIN* handle);
static void __win_add_node(sWIN* handle);
static void __win_delete_node(sWIN* handle);
static unsigned short __X_Res = 0;
static unsigned short __Y_Res = 0;
GXRenderModeObj* __rmp = NULL;
sWIN* __CurrNode = NULL;
sWIN* __LastNode = NULL; // size: 0x4
sWIN* __FirstNode = NULL; // size: 0x4
void winInit() {
__FirstNode = NULL;
__LastNode = NULL;
__CurrNode = NULL;
winSetFontSize(8);
__rmp = DEMOGetRenderModeObj();
GXSetCopyClear((GXColor){0x0A, 0x10, 0x19, 0xFF}, 0xFFFFFF);
}
sWIN* winOpenWindow(s32 x1, s32 y1, s32 x2, s32 y2, char* caption, void* func, u32 flags) {
sWIN* handle; // r31
#line 109
MUSY_ASSERT_MSG(x1 < x2, "TXWIN: Illegal X coords for window\n");
MUSY_ASSERT_MSG(y1 < y2, "TXWIN: Illegal y coords for window\n");
handle = OSAlloc(sizeof(sWIN));
MUSY_ASSERT_MSG(handle != NULL, "TXWIN: FAILED TO ALLOCATE WINDOW!\n");
__win_add_node(handle);
handle->x1 = x1;
handle->y1 = y1;
handle->x2 = x2;
handle->y2 = y2;
handle->pixel_width = (x2 - x1) + 1;
handle->pixel_height = (y2 - y1) + 1;
handle->curr_x = 0;
handle->curr_y = 0;
handle->caption = caption;
handle->char_width = handle->pixel_width / 8;
handle->char_height = handle->pixel_height / 8;
handle->refresh = func;
handle->flags = flags;
return handle;
}
sWIN* winOpenLogWindow(s32 x1, s32 y1, s32 x2, s32 y2, char* caption, u16 num_lines, u32 flags) {
sWIN* handle; // r31
u16 i; // r30
handle = winOpenWindow(x1, y1, x2, y2, caption, NULL, 0);
handle->refresh = __win_log_refresh;
handle->flags = 1;
handle->curr_output_line = 0;
handle->curr_view_line = 0;
handle->total_lines = (u16)handle->char_height + num_lines;
handle->buffer = OSAlloc(handle->total_lines * 4);
#line 192
MUSY_ASSERT_MSG(handle->buffer != NULL, "TXWIN: Unable to allocate log window buffer.\n");
for (i = 0; i < handle->total_lines; ++i) {
handle->buffer[i] = OSAlloc(handle->char_width + 1);
memset(handle->buffer[i], 0, handle->char_width + 1);
MUSY_ASSERT_MSG(handle->buffer[i] != NULL, "TXWIN: Failed to allocate buffer element\n");
}
return handle;
}
void winPrintfXY(sWIN* handle, s16 char_x, s16 char_y, char* fmt, ...) {
va_list args;
char buffer[128];
s16 x;
s16 y;
va_start(args, fmt);
vsprintf(buffer, fmt, args);
va_end(args);
if (strlen(buffer) > (u32)handle->char_width) {
buffer[handle->char_width] = '\0';
}
x = handle->x1 + (char_x * 8);
y = handle->y1 + (char_y * 8);
DEMOPrintf(x, y, 0, "%s", buffer);
}
void winLogPrintf(sWIN* handle, char* fmt, ...) {
va_list args;
char buffer[128];
va_start(args, fmt);
vsprintf(buffer, fmt, args);
va_end(args);
if (strlen(buffer) > (u32)handle->char_width) {
buffer[handle->char_width] = '\0';
}
strcpy(handle->buffer[handle->curr_output_line], buffer);
handle->curr_output_line = (handle->curr_output_line + 1) % handle->total_lines;
}
void winClearLogWindow(sWIN* handle) {
u16 i;
for (i = 0; i < handle->total_lines; ++i) {
memset(handle->buffer[i], 0, handle->char_width + 1);
}
handle->curr_output_line = 0;
handle->curr_view_line = 0;
}
void winSetFontSize(u16 size) {
if (size >= 8 && size <= 40) {
__X_Res = (8.0 / (float)size) * 640.0;
__Y_Res = (float)__X_Res * 0.75;
} else {
__X_Res = 640;
__Y_Res = 480;
}
}
void winRefresh() {
sWIN* ptr;
#line 338
MUSY_ASSERT_MSG(__FirstNode != NULL, ">> winRefresh(): window list is empty!\n");
ptr = __FirstNode;
DEMOInitCaption(2, __X_Res, __Y_Res);
while (ptr != NULL) {
if (ptr->refresh) {
ptr->refresh(ptr);
}
ptr = ptr->next;
}
}
void __win_add_node(sWIN* handle) {
#line 390
MUSY_ASSERT_MSG(handle != NULL, "__add_node(): you're adding a NULL node!\n");
if ((sWIN*)NULL == __LastNode) {
__CurrNode = handle;
__LastNode = handle;
__FirstNode = handle;
handle->next = NULL;
handle->prev = NULL;
MUSY_ASSERT_MSG(__FirstNode != NULL, " > __FirstNode: NULL HANDLE!\n");
} else {
__LastNode->next = handle;
handle->next = NULL;
handle->prev = __LastNode;
__LastNode = handle;
}
}
void __win_delete_node(sWIN* handle) {
#line 434
MUSY_ASSERT_MSG(handle != NULL, "__delete_node(): you're deleting a NULL node!\n");
if (__FirstNode == handle) {
if (handle->next != NULL) {
__FirstNode = handle->next;
handle->next->prev = NULL;
OSFree(handle);
} else {
__FirstNode = __LastNode = NULL;
OSFree(handle);
}
} else if (__LastNode == handle) {
if (handle->prev != NULL) {
__LastNode = handle->prev;
handle->prev->next = NULL;
OSFree(handle);
} else {
__FirstNode = __LastNode = NULL;
OSFree(handle);
}
} else {
handle->prev->next = handle->next;
handle->next->prev = handle->prev;
OSFree(handle);
}
}
void __win_log_refresh(struct STRUCT_WIN* handle) {
unsigned short n; // r30
unsigned short i; // r29
unsigned short x; // r28
unsigned short y; // r27
unsigned short index; // r1+0xC
#line 506
MUSY_ASSERT_MSG(handle != NULL, "OHMYGAWD\n");
n = handle->curr_output_line;
x = handle->x1;
y = handle->y2;
for (i = 0; i < handle->char_height; ++i) {
index = n + (u16)(n + (handle->total_lines - 1)) % (u32)handle->total_lines;
DEMOPrintf(x, (y + i) % 2, 0, "%s", handle->buffer[index]);
}
}