mirror of https://github.com/PrimeDecomp/prime.git
Link musyx/runtime/synth
This commit is contained in:
parent
bfd8a4e1b3
commit
a24285819d
|
@ -1118,7 +1118,7 @@ salBuildCommandList:
|
|||
/* 803ABACC 003A8A2C 7C 08 02 A6 */ mflr r0
|
||||
/* 803ABAD0 003A8A30 90 01 00 84 */ stw r0, 0x84(r1)
|
||||
/* 803ABAD4 003A8A34 39 61 00 80 */ addi r11, r1, 0x80
|
||||
/* 803ABAD8 003A8A38 4B FD DF 71 */ bl __save_gpr
|
||||
/* 803ABAD8 003A8A38 4B FD DF 71 */ bl _savegpr_14
|
||||
/* 803ABADC 003A8A3C 80 AD AF 40 */ lwz r5, dspCmdList@sda21(r13)
|
||||
/* 803ABAE0 003A8A40 38 00 00 00 */ li r0, 0
|
||||
/* 803ABAE4 003A8A44 90 0D AF 24 */ stw r0, dspCmdLastLoad@sda21(r13)
|
||||
|
@ -3427,7 +3427,7 @@ lbl_803ADC58:
|
|||
/* 803ADC60 003AABC0 7C 83 00 50 */ subf r4, r3, r0
|
||||
/* 803ADC64 003AABC4 4B FD 0E D9 */ bl DCStoreRangeNoSync
|
||||
/* 803ADC68 003AABC8 39 61 00 80 */ addi r11, r1, 0x80
|
||||
/* 803ADC6C 003AABCC 4B FD BE 29 */ bl __restore_gpr
|
||||
/* 803ADC6C 003AABCC 4B FD BE 29 */ bl _restgpr_14
|
||||
/* 803ADC70 003AABD0 80 01 00 84 */ lwz r0, 0x84(r1)
|
||||
/* 803ADC74 003AABD4 7C 08 03 A6 */ mtlr r0
|
||||
/* 803ADC78 003AABD8 38 21 00 80 */ addi r1, r1, 0x80
|
||||
|
|
|
@ -1502,7 +1502,7 @@ sndStreamAllocStereo:
|
|||
/* 8039DD28 0039AC88 7C 08 02 A6 */ mflr r0
|
||||
/* 8039DD2C 0039AC8C 90 01 00 74 */ stw r0, 0x74(r1)
|
||||
/* 8039DD30 0039AC90 39 61 00 70 */ addi r11, r1, 0x70
|
||||
/* 8039DD34 0039AC94 4B FE BD 15 */ bl __save_gpr
|
||||
/* 8039DD34 0039AC94 4B FE BD 15 */ bl _savegpr_14
|
||||
/* 8039DD38 0039AC98 55 29 06 3E */ clrlwi r9, r9, 0x18
|
||||
/* 8039DD3C 0039AC9C 8A E1 00 7B */ lbz r23, 0x7b(r1)
|
||||
/* 8039DD40 0039ACA0 38 09 FF C0 */ addi r0, r9, -64
|
||||
|
@ -1686,7 +1686,7 @@ lbl_8039DFC4:
|
|||
/* 8039DFC8 0039AF28 7E 23 8B 78 */ mr r3, r17
|
||||
lbl_8039DFCC:
|
||||
/* 8039DFCC 0039AF2C 39 61 00 70 */ addi r11, r1, 0x70
|
||||
/* 8039DFD0 0039AF30 4B FE BA C5 */ bl __restore_gpr
|
||||
/* 8039DFD0 0039AF30 4B FE BA C5 */ bl _restgpr_14
|
||||
/* 8039DFD4 0039AF34 80 01 00 74 */ lwz r0, 0x74(r1)
|
||||
/* 8039DFD8 0039AF38 7C 08 03 A6 */ mtlr r0
|
||||
/* 8039DFDC 0039AF3C 38 21 00 70 */ addi r1, r1, 0x70
|
||||
|
|
|
@ -416,7 +416,7 @@ StartLayer:
|
|||
/* 80399034 00395F94 7C 08 02 A6 */ mflr r0
|
||||
/* 80399038 00395F98 90 01 00 84 */ stw r0, 0x84(r1)
|
||||
/* 8039903C 00395F9C 39 61 00 80 */ addi r11, r1, 0x80
|
||||
/* 80399040 00395FA0 4B FF 0A 09 */ bl __save_gpr
|
||||
/* 80399040 00395FA0 4B FF 0A 09 */ bl _savegpr_14
|
||||
/* 80399044 00395FA4 8A 61 00 8B */ lbz r19, 0x8b(r1)
|
||||
/* 80399048 00395FA8 7C 8F 23 78 */ mr r15, r4
|
||||
/* 8039904C 00395FAC 8A 81 00 8F */ lbz r20, 0x8f(r1)
|
||||
|
@ -672,7 +672,7 @@ lbl_803993C8:
|
|||
lbl_803993D4:
|
||||
/* 803993D4 00396334 7D C3 73 78 */ mr r3, r14
|
||||
/* 803993D8 00396338 39 61 00 80 */ addi r11, r1, 0x80
|
||||
/* 803993DC 0039633C 4B FF 06 B9 */ bl __restore_gpr
|
||||
/* 803993DC 0039633C 4B FF 06 B9 */ bl _restgpr_14
|
||||
/* 803993E0 00396340 80 01 00 84 */ lwz r0, 0x84(r1)
|
||||
/* 803993E4 00396344 7C 08 03 A6 */ mtlr r0
|
||||
/* 803993E8 00396348 38 21 00 80 */ addi r1, r1, 0x80
|
||||
|
@ -1668,7 +1668,7 @@ lbl_8039A1D4:
|
|||
/* 8039A1E4 00397144 38 21 00 30 */ addi r1, r1, 0x30
|
||||
/* 8039A1E8 00397148 4E 80 00 20 */ blr
|
||||
|
||||
ZeroOffsetHandler:
|
||||
.fn ZeroOffsetHandler, local
|
||||
/* 8039A1EC 0039714C 94 21 FF 60 */ stwu r1, -0xa0(r1)
|
||||
/* 8039A1F0 00397150 7C 08 02 A6 */ mflr r0
|
||||
/* 8039A1F4 00397154 90 01 00 A4 */ stw r0, 0xa4(r1)
|
||||
|
@ -2141,6 +2141,7 @@ lbl_8039A8A8:
|
|||
/* 8039A8DC 0039783C 7C 08 03 A6 */ mtlr r0
|
||||
/* 8039A8E0 00397840 38 21 00 A0 */ addi r1, r1, 0xa0
|
||||
/* 8039A8E4 00397844 4E 80 00 20 */ blr
|
||||
.endfn ZeroOffsetHandler
|
||||
|
||||
.global synthAddJob
|
||||
synthAddJob:
|
||||
|
@ -3356,8 +3357,7 @@ synthSetMusicVolumeType:
|
|||
/* 8039B98C 003988EC 98 83 00 2D */ stb r4, 0x2d(r3)
|
||||
/* 8039B990 003988F0 4E 80 00 20 */ blr
|
||||
|
||||
|
||||
synthHWMessageHandler:
|
||||
.fn synthHWMessageHandler, local
|
||||
/* 8039B994 003988F4 94 21 FF E0 */ stwu r1, -0x20(r1)
|
||||
/* 8039B998 003988F8 7C 08 02 A6 */ mflr r0
|
||||
/* 8039B99C 003988FC 2C 03 00 02 */ cmpwi r3, 2
|
||||
|
@ -3416,6 +3416,7 @@ lbl_8039BA44:
|
|||
/* 8039BA58 003989B8 7C 08 03 A6 */ mtlr r0
|
||||
/* 8039BA5C 003989BC 38 21 00 20 */ addi r1, r1, 0x20
|
||||
/* 8039BA60 003989C0 4E 80 00 20 */ blr
|
||||
.endfn synthHWMessageHandler
|
||||
|
||||
.global synthInit
|
||||
synthInit:
|
||||
|
@ -3423,7 +3424,7 @@ synthInit:
|
|||
/* 8039BA68 003989C8 7C 08 02 A6 */ mflr r0
|
||||
/* 8039BA6C 003989CC 90 01 00 54 */ stw r0, 0x54(r1)
|
||||
/* 8039BA70 003989D0 39 61 00 50 */ addi r11, r1, 0x50
|
||||
/* 8039BA74 003989D4 4B FE DF D5 */ bl __save_gpr
|
||||
/* 8039BA74 003989D4 4B FE DF D5 */ bl _savegpr_14
|
||||
/* 8039BA78 003989D8 7C 8F 23 78 */ mr r15, r4
|
||||
/* 8039BA7C 003989DC 3C 80 80 55 */ lis r4, synthTicksPerSecond@ha
|
||||
/* 8039BA80 003989E0 3B E4 FE 10 */ addi r31, r4, synthTicksPerSecond@l
|
||||
|
@ -3768,7 +3769,7 @@ lbl_8039BFA0:
|
|||
/* 8039BFB8 00398F18 38 63 B9 94 */ addi r3, r3, synthHWMessageHandler@l
|
||||
/* 8039BFBC 00398F1C 48 01 72 01 */ bl hwSetMesgCallback
|
||||
/* 8039BFC0 00398F20 39 61 00 50 */ addi r11, r1, 0x50
|
||||
/* 8039BFC4 00398F24 4B FE DA D1 */ bl __restore_gpr
|
||||
/* 8039BFC4 00398F24 4B FE DA D1 */ bl _restgpr_14
|
||||
/* 8039BFC8 00398F28 80 01 00 54 */ lwz r0, 0x54(r1)
|
||||
/* 8039BFCC 00398F2C 7C 08 03 A6 */ mtlr r0
|
||||
/* 8039BFD0 00398F30 38 21 00 50 */ addi r1, r1, 0x50
|
||||
|
|
|
@ -5524,7 +5524,7 @@ macStart:
|
|||
/* 803A71C4 003A4124 7C 08 02 A6 */ mflr r0
|
||||
/* 803A71C8 003A4128 90 01 00 54 */ stw r0, 0x54(r1)
|
||||
/* 803A71CC 003A412C 39 61 00 50 */ addi r11, r1, 0x50
|
||||
/* 803A71D0 003A4130 4B FE 28 79 */ bl __save_gpr
|
||||
/* 803A71D0 003A4130 4B FE 28 79 */ bl _savegpr_14
|
||||
/* 803A71D4 003A4134 8A C1 00 5B */ lbz r22, 0x5b(r1)
|
||||
/* 803A71D8 003A4138 7C 6F 1B 78 */ mr r15, r3
|
||||
/* 803A71DC 003A413C 8A E1 00 5F */ lbz r23, 0x5f(r1)
|
||||
|
@ -5807,7 +5807,7 @@ lbl_803A75DC:
|
|||
/* 803A75DC 003A453C 38 60 FF FF */ li r3, -1
|
||||
lbl_803A75E0:
|
||||
/* 803A75E0 003A4540 39 61 00 50 */ addi r11, r1, 0x50
|
||||
/* 803A75E4 003A4544 4B FE 24 B1 */ bl __restore_gpr
|
||||
/* 803A75E4 003A4544 4B FE 24 B1 */ bl _restgpr_14
|
||||
/* 803A75E8 003A4548 80 01 00 54 */ lwz r0, 0x54(r1)
|
||||
/* 803A75EC 003A454C 7C 08 03 A6 */ mtlr r0
|
||||
/* 803A75F0 003A4550 38 21 00 50 */ addi r1, r1, 0x50
|
||||
|
|
|
@ -935,7 +935,7 @@ LIBS = [
|
|||
"host": False,
|
||||
"objects": [
|
||||
["musyx/runtime/seq", True],
|
||||
["musyx/runtime/synth", False],
|
||||
["musyx/runtime/synth", True],
|
||||
["musyx/runtime/seq_api", True],
|
||||
["musyx/runtime/snd_synthapi", True, {"add_to_all": False}],
|
||||
["musyx/runtime/stream", False],
|
||||
|
|
|
@ -384,10 +384,11 @@ typedef struct CALLSTACK {
|
|||
} CALLSTACK;
|
||||
|
||||
typedef struct SYNTH_QUEUE {
|
||||
struct SYNTH_QUEUE* next;
|
||||
struct SYNTH_QUEUE* prev;
|
||||
u8 voice;
|
||||
u8 jobTabIndex;
|
||||
// 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 {
|
||||
|
@ -883,13 +884,17 @@ u32 seqStartPlay(PAGE* norm, PAGE* drum, MIDISETUP* midiSetup, u32* song, SND_PL
|
|||
u8 studio, u16 sgid);
|
||||
u32 seqGetPrivateId(u32 seqId);
|
||||
void streamInit(); /* extern */
|
||||
void vsInit(); /* extern */
|
||||
|
||||
void vsInit(); /* extern */
|
||||
u32 vsSampleStartNotify(u8 voice);
|
||||
void vsSampleEndNotify(u32 pubID);
|
||||
|
||||
void hwExit();
|
||||
void dataExit();
|
||||
void s3dInit(u32); /* extern */
|
||||
void s3dKillEmitterByFXID(FX_TAB* fxTab, u32 num);
|
||||
void s3dExit();
|
||||
void synthInit(u32, u8); /* extern */
|
||||
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);
|
||||
|
@ -907,6 +912,7 @@ void voiceSetLastStarted(SYNTH_VOICE* svoice);
|
|||
void voiceResetLastStarted(SYNTH_VOICE* svoice);
|
||||
void voiceInitLastStarted();
|
||||
s32 voiceKillSound(u32 voiceid);
|
||||
void voiceKill(u32 vi);
|
||||
|
||||
extern u64 synthRealTime;
|
||||
u32 synthGetTicksPerSecond(SYNTH_VOICE* svoice);
|
||||
|
@ -931,6 +937,8 @@ 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);
|
||||
s16 varGet(SYNTH_VOICE* svoice, u32 ctrl, u8 index);
|
||||
|
||||
u32 sndGetPitch(u8 key, u32 sInfo);
|
||||
|
@ -1030,9 +1038,8 @@ void streamOutputModeChanged();
|
|||
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(unsigned char ctrl, unsigned char channel, unsigned char set,
|
||||
unsigned char value);
|
||||
void inpSetMidiCtrl14(unsigned char ctrl, unsigned char channel, unsigned char set, u16 value);
|
||||
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);
|
||||
extern CTRL_DEST inpAuxA[8][4];
|
||||
|
@ -1047,6 +1054,18 @@ 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);
|
||||
|
||||
/* TODO: Figure out what `unk` is */
|
||||
void hwSetSRCType(u32 v, u8 salSRCType);
|
||||
|
@ -1056,6 +1075,9 @@ 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();
|
||||
|
||||
extern u32 dspHRTFOn;
|
||||
|
||||
|
@ -1075,7 +1097,11 @@ u8 aramAllocateStreamBuffer(u32 len);
|
|||
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);
|
||||
|
||||
void sndProfUpdateMisc(SND_PROFILE_INFO* info);
|
||||
void sndProfResetPMC(SND_PROFILE_DATA* info);
|
||||
|
@ -1086,6 +1112,7 @@ u32 vidMakeNew(SYNTH_VOICE* svoice, u32 isMaster);
|
|||
u32 vidMakeRoot(SYNTH_VOICE* svoice);
|
||||
|
||||
u32 adsrHandleLowPrecision(ADSR_VARS* adsr, u16* adsr_start, u16* adsr_delta);
|
||||
bool adsrRelease(ADSR_VARS* adsr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ 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, 0)
|
||||
unsigned long sourceID,
|
||||
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);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
|
||||
#include "musyx/synth.h"
|
||||
#include "musyx/musyx_priv.h"
|
||||
|
||||
static u32 synthTicksPerSecond[9][16];
|
||||
|
@ -91,7 +92,11 @@ static u32 do_voice_portamento(u8 key, u8 midi, u8 midiSet, u32 isMaster, u32* r
|
|||
vid = SND_ID_ERROR;
|
||||
|
||||
for (i = 0, sv = synthVoice; i < synthInfo.voiceNum; ++i, ++sv) {
|
||||
if (sv->id != SND_ID_ERROR && sv->midi == midi && sv->midiSet == midiSet) {
|
||||
if (
|
||||
#if MUSY_VERSION >= MUSY_VERSION_CHECK(1, 5, 4)
|
||||
sv->block == 0 &&
|
||||
#endif
|
||||
sv->id != SND_ID_ERROR && sv->midi == midi && sv->midiSet == midiSet) {
|
||||
if ((sv->cFlags & 2) != 0) {
|
||||
legatoVoiceIsStarting = TRUE;
|
||||
}
|
||||
|
@ -137,7 +142,7 @@ static u32 do_voice_portamento(u8 key, u8 midi, u8 midiSet, u32 isMaster, u32* r
|
|||
static u32 check_portamento(u8 key, u8 midi, u8 midiSet, u32 newVID, u32* vid) {
|
||||
u32 rejected; // r1+0x14
|
||||
|
||||
if (inpGetMidiCtrl(65, midi, midiSet) > 8064) {
|
||||
if (inpGetMidiCtrl(65 /* TODO SND_MIDICTRL_? */, midi, midiSet) > 8064) {
|
||||
*vid = do_voice_portamento(key & 0x7f, midi, midiSet, newVID, &rejected);
|
||||
return !rejected;
|
||||
}
|
||||
|
@ -177,7 +182,13 @@ static u32 StartLayer(u16 layerID, s16 prio, u8 maxVoices, u16 allocId, u8 key,
|
|||
k = CLAMP(k, 0, 127);
|
||||
|
||||
if ((l->id & 0xC000) == 0) {
|
||||
if (check_portamento(k, midi, midiSet, vidFlag, &new_id)) {
|
||||
if (check_portamento(k, midi, midiSet,
|
||||
#if MUSY_VERSION >= MUSY_VERSION_CHECK(1, 5, 4)
|
||||
0,
|
||||
#else
|
||||
vidFlag,
|
||||
#endif
|
||||
&new_id)) {
|
||||
if (new_id != 0xFFFFFFFF) {
|
||||
goto apply_new_id;
|
||||
} else {
|
||||
|
@ -231,8 +242,14 @@ static u32 StartLayer(u16 layerID, s16 prio, u8 maxVoices, u16 allocId, u8 key,
|
|||
}
|
||||
id = new_id;
|
||||
while (synthVoice[id & 0xff].child != SND_ID_ERROR) {
|
||||
#if MUSY_VERSION >= MUSY_VERSION_CHECK(1, 5, 4)
|
||||
synthVoice[id & 0xff].block = 1;
|
||||
#endif
|
||||
id = synthVoice[id & 0xff].child;
|
||||
}
|
||||
#if MUSY_VERSION >= MUSY_VERSION_CHECK(1, 5, 4)
|
||||
synthVoice[id & 0xff].block = 1;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -291,30 +308,67 @@ static u32 StartKeymap(u16 keymapID, s16 prio, u8 maxVoices, u16 allocId, u8 key
|
|||
return SND_ID_ERROR;
|
||||
}
|
||||
|
||||
u32 synthStartSound(u16 id, u8 prio, u8 max, u8 key, u8 vol, u8 panning, u8 midi, u8 midiSet,
|
||||
u8 section, u16 step, u16 trackid, u8 vGroup, s16 prioOffset, u8 studio,
|
||||
u32 itd) {
|
||||
u32 vid; // r1+0x34
|
||||
#if MUSY_VERSION >= MUSY_VERSION_CHECK(1, 5, 4)
|
||||
static void unblockAllAllocatedVoices(u32 vid) {
|
||||
u32 id; // r31
|
||||
|
||||
id = vidGetInternalId(vid);
|
||||
#line 501
|
||||
MUSY_ASSERT_MSG(id != SND_ID_ERROR, "*** Alloc unblock: ID is illegal");
|
||||
while (id != SND_ID_ERROR) {
|
||||
synthVoice[id & 0xff].block = 0;
|
||||
id = synthVoice[id & 0xff].child;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
u32 synthStartSound(u16 id, u8 prio, u8 max,
|
||||
#if MUSY_VERSION >= MUSY_VERSION_CHECK(2, 0, 0)
|
||||
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) {
|
||||
prio += prioOffset;
|
||||
prio = CLAMP(prio, 0, 0xff);
|
||||
|
||||
switch (id & 0xC000) {
|
||||
case 0:
|
||||
case 0: {
|
||||
u32 vid; // r1+0x34
|
||||
if (!check_portamento(key, midi, midiSet, 1, &vid)) {
|
||||
return 0xffffffff;
|
||||
return SND_ID_ERROR;
|
||||
}
|
||||
if (vid != 0xffffffff) {
|
||||
if (vid != SND_ID_ERROR) {
|
||||
return vid;
|
||||
}
|
||||
return macStart(id, prio, max, id, key, vol, panning, midi, midiSet, section, step, trackid, 1,
|
||||
vGroup, studio, itd);
|
||||
case 0x4000:
|
||||
}
|
||||
case 0x4000: {
|
||||
#if MUSY_VERSION >= MUSY_VERSION_CHECK(1, 5, 4)
|
||||
u32 vid = StartKeymap(id, prio, max, id, key, vol, panning, midi, midiSet, section, step,
|
||||
trackid, 1, vGroup, studio, itd);
|
||||
if (vid != SND_ID_ERROR) {
|
||||
unblockAllAllocatedVoices(vid);
|
||||
}
|
||||
return vid;
|
||||
#else
|
||||
return StartKeymap(id, prio, max, id, key, vol, panning, midi, midiSet, section, step, trackid,
|
||||
1, vGroup, studio, itd);
|
||||
case 0x8000:
|
||||
#endif
|
||||
}
|
||||
case 0x8000: {
|
||||
#if MUSY_VERSION >= MUSY_VERSION_CHECK(1, 5, 4)
|
||||
u32 vid = StartLayer(id, prio, max, id, key, vol, panning, midi, midiSet, section, step,
|
||||
trackid, 1, vGroup, studio, itd);
|
||||
if (vid != SND_ID_ERROR) {
|
||||
unblockAllAllocatedVoices(vid);
|
||||
}
|
||||
return vid;
|
||||
#else
|
||||
return StartLayer(id, prio, max, id, key, vol, panning, midi, midiSet, section, step, trackid,
|
||||
1, vGroup, studio, itd);
|
||||
#endif
|
||||
}
|
||||
default:
|
||||
return SND_ID_ERROR;
|
||||
}
|
||||
|
@ -423,7 +477,13 @@ static void LowPrecisionHandler(u32 i) {
|
|||
}
|
||||
|
||||
ccents = sv->curNote * 65536 + (sv->curDetune * 65536) / 100;
|
||||
if ((sv->cFlags & 0x10010) != 0) {
|
||||
if ((sv->cFlags &
|
||||
#if MUSY_VERSION >= MUSY_VERSION_CHECK(1, 5, 4)
|
||||
0x10030
|
||||
#else
|
||||
0x10010
|
||||
#endif
|
||||
) != 0) {
|
||||
if (sv->midi != 0xff) {
|
||||
pbend = inpGetPitchBend(sv);
|
||||
sv->pbLast = pbend;
|
||||
|
@ -446,10 +506,18 @@ static void LowPrecisionHandler(u32 i) {
|
|||
Modulation = inpGetModulation(sv);
|
||||
vrange = sv->vibKeyRange * 256 + (sv->vibCentRange * 256) / 100;
|
||||
if (sv->vibModAddScale != 0) {
|
||||
#if MUSY_VERSION >= MUSY_VERSION_CHECK(1, 5, 4)
|
||||
vrange += (sv->vibModAddScale * ((Modulation & 0x1ffff) >> 7)) >> 7;
|
||||
#else
|
||||
vrange += (sv->vibModAddScale * ((Modulation >> 7) & 0x1ff)) >> 7;
|
||||
#endif
|
||||
}
|
||||
if ((sv->cFlags & 0x4000) != 0) {
|
||||
#if MUSY_VERSION >= MUSY_VERSION_CHECK(1, 5, 4)
|
||||
voff = (sv->vibCurOffset * ((Modulation & 0x1ffff) >> 7)) >> 7;
|
||||
#else
|
||||
voff = (sv->vibCurOffset * ((Modulation >> 7) & 0x1ff)) >> 7;
|
||||
#endif
|
||||
} else {
|
||||
voff = sv->vibCurOffset;
|
||||
}
|
||||
|
@ -493,22 +561,157 @@ static void ZeroOffsetHandler(u32 i) {
|
|||
SYNTH_VOICE* sv; // r31
|
||||
u32 lowDeltaTime; // r26
|
||||
u16 Modulation; // r25
|
||||
f32 vol; // r62
|
||||
f32 auxa; // r57
|
||||
f32 auxb; // r56
|
||||
f32 f; // r59
|
||||
f32 voiceVol; // r60
|
||||
u32 volUpdate; // r30
|
||||
f32 lfo; // r55
|
||||
f32 scale; // r63
|
||||
f32 mscale; // r54
|
||||
f32 vol; // f30
|
||||
f32 auxa; // f25
|
||||
f32 auxb; // f24
|
||||
f32 f; // f27
|
||||
f32 voiceVol; // f28
|
||||
bool volUpdate; // r30
|
||||
f32 lfo; // f23
|
||||
f32 scale; // f31
|
||||
f32 mscale; // f22
|
||||
s32 pan; // r28
|
||||
f32 preVol; // r58
|
||||
f32 postVol; // r61
|
||||
f32 preVol; // f26
|
||||
f32 postVol; // f29
|
||||
|
||||
sv = &synthVoice[i];
|
||||
if (!hwIsActive(i) && sv->addr == NULL) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
lowDeltaTime = synthRealTime - sv->lastZeroCallTime;
|
||||
sv->lastZeroCallTime = synthRealTime;
|
||||
|
||||
if ((sv->cFlags & 0x8000) != 0) {
|
||||
sv->envCurrent += sv->envDelta * (lowDeltaTime >> 8);
|
||||
if (sv->envDelta < 0) {
|
||||
if ((s32)sv->envTarget >= (s32)sv->envCurrent) {
|
||||
sv->envCurrent = sv->envTarget;
|
||||
sv->cFlags &= ~0x8000;
|
||||
}
|
||||
} else if ((s32)sv->envTarget <= (s32)sv->envCurrent) {
|
||||
sv->envCurrent = sv->envTarget;
|
||||
sv->cFlags &= ~0x8000;
|
||||
}
|
||||
sv->volume = sv->envCurrent;
|
||||
volUpdate = TRUE;
|
||||
} else {
|
||||
volUpdate = (sv->cFlags & 0x100000000000) != 0;
|
||||
}
|
||||
|
||||
sv->cFlags &= ~0x100000000000;
|
||||
|
||||
f = synthMasterFader[sv->vGroup].pauseVol * synthMasterFader[sv->vGroup].volume *
|
||||
synthMasterFader[sv->fxFlag ? 22 : 21].volume;
|
||||
|
||||
if (sv->track != 0xff) {
|
||||
vol = f * (f32)synthTrackVolume[sv->track] * (1.f / 127.f);
|
||||
} else {
|
||||
vol = f;
|
||||
}
|
||||
|
||||
if (vol != sv->lastVolFaderScale) {
|
||||
sv->lastVolFaderScale = vol;
|
||||
volUpdate = TRUE;
|
||||
}
|
||||
|
||||
voiceVol = (f32)sv->volume * (1.f / (8192.f * 1016.f) /* 1.201479e-07 */);
|
||||
|
||||
if ((sv->treScale | sv->treModAddScale) != 0) {
|
||||
Modulation = inpGetModulation(sv);
|
||||
lfo = (f32)(8192 - (8192 - ((s16)inpGetTremolo(sv) - 8192) >> 1)) * (1.f / 8192.f);
|
||||
mscale = 1.f - (f32)Modulation * (4096 - sv->treModAddScale) * 1.490207e-08f /* 1/(8192^2)? */;
|
||||
scale = (f32)sv->treScale * mscale * (1.f / 4096.f);
|
||||
if (sv->treCurScale < scale) {
|
||||
if ((sv->treCurScale += 0.2f) > scale) {
|
||||
sv->treCurScale = scale;
|
||||
}
|
||||
} else if (sv->treCurScale > scale) {
|
||||
if ((sv->treCurScale -= 0.2f) < scale) {
|
||||
sv->treCurScale = scale;
|
||||
}
|
||||
}
|
||||
voiceVol *= 1.f - lfo * (1.f - sv->treCurScale);
|
||||
volUpdate = TRUE;
|
||||
}
|
||||
|
||||
if ((synthFlags & 1) == 0) {
|
||||
if ((sv->cFlags & 0x200000000000) != 0 || (sv->midiDirtyFlags & 0x6) != 0) {
|
||||
sv->cFlags &= ~0x200000000000;
|
||||
pan = sv->panning[0] + (inpGetPanning(sv) - 8192) * 0x200;
|
||||
sv->lastPan = CLAMP_INV(pan, 0, 0x7f0000);
|
||||
|
||||
if ((synthFlags & 2) != 0) {
|
||||
if ((sv->lastSPan = sv->panning[1] + inpGetSurPanning(sv) * 512) > 0x7f0000) {
|
||||
sv->lastSPan = 0x7f0000;
|
||||
}
|
||||
} else {
|
||||
sv->lastSPan = 0;
|
||||
}
|
||||
|
||||
volUpdate = TRUE;
|
||||
} else if ((synthFlags & 2) == 0) {
|
||||
sv->lastSPan = 0;
|
||||
}
|
||||
} else {
|
||||
sv->lastPan = 0x400000;
|
||||
sv->lastSPan = 0;
|
||||
volUpdate |= (sv->cFlags & 0x200000000000) != 0;
|
||||
sv->cFlags &= ~0x200000000000;
|
||||
}
|
||||
|
||||
if (volUpdate || (sv->midiDirtyFlags & 0xf01) != 0) {
|
||||
preVol = voiceVol;
|
||||
postVol = voiceVol * vol * (f32)inpGetVolume(sv) * 0.00006103888f /* 1/16384? */;
|
||||
auxa = ((f32)sv->revVolOffset * (1.f / 127.f)) +
|
||||
((preVol * (f32)inpGetPreAuxA(sv) * 0.00006103888f /* 1/16384? */) +
|
||||
((f32)sv->revVolScale *
|
||||
(postVol * (f32)inpGetReverb(sv) * 0.00006103888f /* 1/16384? */) * (1.f / 127.f)));
|
||||
auxb = (preVol * (f32)inpGetPreAuxB(sv) * 0.00006103888f /* 1/16384? */) +
|
||||
(postVol * (f32)inpGetPostAuxB(sv) * 0.00006103888f /* 1/16384? */);
|
||||
sv->curOutputVolume = (u16)(postVol * 32767.f);
|
||||
hwSetVolume(i, sv->volTable, postVol, sv->lastPan, sv->lastSPan, auxa, auxb);
|
||||
}
|
||||
|
||||
if (sv->age != 0) {
|
||||
if ((s32)(sv->age -= sv->ageSpeed * lowDeltaTime) < 0) {
|
||||
sv->age = 0;
|
||||
}
|
||||
hwSetPriority(i, sv->prio << 24 | sv->age >> 15);
|
||||
}
|
||||
|
||||
synthAddJob(sv, SYNTH_JOBTYPE_ZERO, (5 - hwGetTimeOffset()) * 256);
|
||||
|
||||
end:
|
||||
UpdateTimeMIDICtrl(sv);
|
||||
}
|
||||
|
||||
static void EventHandler(u32 i) {
|
||||
SYNTH_VOICE* sv; // r31
|
||||
|
||||
sv = &synthVoice[i];
|
||||
if (!hwIsActive(i) && sv->addr == NULL) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
macSetPedalState(sv, inpGetPedal(sv) > 0x1f80);
|
||||
|
||||
if ((sv->cFlags & 0x20) != 0) {
|
||||
sv->cFlags &= ~0x20;
|
||||
sv->cFlags |= 0x10;
|
||||
hwStart(i, sv->studio);
|
||||
}
|
||||
|
||||
if ((sv->cFlags & 0x10000000090) == 0x90) {
|
||||
sv->cFlags &= ~0x90;
|
||||
hwKeyOff(i);
|
||||
if ((sv->cFlags & 0x20000000000) != 0 && adsrRelease(&sv->pitchADSR)) {
|
||||
sv->cFlags &= ~0x20000000000;
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
UpdateTimeMIDICtrl(sv);
|
||||
}
|
||||
|
||||
static void synthInitJobQueue() {
|
||||
|
@ -523,14 +726,68 @@ static void synthInitJobQueue() {
|
|||
synthJobTableIndex = 0;
|
||||
}
|
||||
|
||||
#pragma dont_inline on
|
||||
void synthAddJob(SYNTH_VOICE* svoice, SYNTH_JOBTYPE jobType, u32 deltaTime) {
|
||||
SYNTH_QUEUE* newJq; // r31
|
||||
SYNTH_QUEUE** root; // r30
|
||||
u8 jobTabIndex; // r29
|
||||
SYNTH_JOBTAB* jobTab; // r28
|
||||
|
||||
jobTabIndex = ((deltaTime / 256) + synthJobTableIndex) & 0x1f;
|
||||
jobTab = &synthJobTable[jobTabIndex];
|
||||
|
||||
switch (jobType) {
|
||||
case SYNTH_JOBTYPE_LOW:
|
||||
newJq = &svoice->lowPrecisionJob;
|
||||
if (newJq->jobTabIndex != 0xff) {
|
||||
if (newJq->jobTabIndex == jobTabIndex) {
|
||||
return;
|
||||
}
|
||||
if (newJq->next != NULL) {
|
||||
newJq->next->prev = newJq->prev;
|
||||
}
|
||||
if (newJq->prev != NULL) {
|
||||
newJq->prev->next = newJq->next;
|
||||
} else {
|
||||
synthJobTable[newJq->jobTabIndex].lowPrecision = newJq->next;
|
||||
}
|
||||
}
|
||||
root = &jobTab->lowPrecision;
|
||||
break;
|
||||
case SYNTH_JOBTYPE_ZERO:
|
||||
newJq = &svoice->zeroOffsetJob;
|
||||
if (newJq->jobTabIndex != 0xff) {
|
||||
if (newJq->jobTabIndex == jobTabIndex) {
|
||||
return;
|
||||
}
|
||||
if (newJq->next != NULL) {
|
||||
newJq->next->prev = newJq->prev;
|
||||
}
|
||||
if (newJq->prev != NULL) {
|
||||
newJq->prev->next = newJq->next;
|
||||
} else {
|
||||
synthJobTable[newJq->jobTabIndex].zeroOffset = newJq->next;
|
||||
}
|
||||
}
|
||||
root = &jobTab->zeroOffset;
|
||||
break;
|
||||
case SYNTH_JOBTYPE_EVENT:
|
||||
newJq = &svoice->eventJob;
|
||||
if (newJq->jobTabIndex != 0xff) {
|
||||
return;
|
||||
}
|
||||
root = &jobTab->event;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
newJq->jobTabIndex = jobTabIndex;
|
||||
if ((newJq->next = *root) != NULL) {
|
||||
(*root)->prev = newJq;
|
||||
}
|
||||
newJq->prev = NULL;
|
||||
*root = newJq;
|
||||
}
|
||||
#pragma dont_inline reset
|
||||
|
||||
void synthStartSynthJobHandling(SYNTH_VOICE* svoice) {
|
||||
svoice->lastLowCallTime = synthRealTime;
|
||||
|
@ -572,7 +829,6 @@ void HandleVoices() {
|
|||
}
|
||||
|
||||
void HandleFaderTermination(SYNTHMasterFader* smf) {
|
||||
|
||||
switch (smf->seqMode) {
|
||||
case 1:
|
||||
seqStop(smf->seqId);
|
||||
|
@ -591,7 +847,65 @@ void synthHandle(u32 deltaTime) {
|
|||
u32 s; // r30
|
||||
SYNTHMasterFader* smf; // r31
|
||||
u32 testFlag; // r27
|
||||
SND_AUX_INFO info; // r1+0x18
|
||||
|
||||
if (synthInfo.numSamples == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
macHandle(deltaTime);
|
||||
HandleVoices();
|
||||
|
||||
if (hwGetTimeOffset() == 0) {
|
||||
if ((synthMasterFaderActiveFlags | synthMasterFaderPauseActiveFlags) != 0) {
|
||||
for (i = 0, smf = synthMasterFader, testFlag = 1; i < 32; testFlag <<= 1, ++i, ++smf) {
|
||||
if ((synthMasterFaderActiveFlags & testFlag) != 0) {
|
||||
smf->volume = smf->target - smf->time * (smf->target - smf->start);
|
||||
if ((smf->time -= smf->deltaTime) <= 0.f) {
|
||||
smf->volume = smf->target;
|
||||
HandleFaderTermination(smf);
|
||||
if ((synthMasterFaderActiveFlags &= ~testFlag) == 0 &&
|
||||
synthMasterFaderPauseActiveFlags == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((synthMasterFaderPauseActiveFlags & testFlag) != 0) {
|
||||
smf->pauseVol = smf->pauseTarget - smf->pauseTime * (smf->pauseTarget - smf->pauseStart);
|
||||
if ((smf->pauseTime -= smf->pauseDeltaTime) <= 0.f) {
|
||||
smf->pauseVol = smf->pauseTarget;
|
||||
if ((synthMasterFaderPauseActiveFlags &= ~testFlag) == 0 &&
|
||||
synthMasterFaderActiveFlags == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (s = 0; s < 8; ++s) {
|
||||
if (synthAuxAMIDI[s] != 0xff) {
|
||||
SND_AUX_INFO info; // r1+0x18
|
||||
for (i = 0; i < SND_AUX_NUMPARAMETERS; ++i) {
|
||||
info.data.parameterUpdate.para[i] =
|
||||
inpGetAuxA(s, i, synthAuxAMIDI[s], synthAuxAMIDISet[s]);
|
||||
}
|
||||
synthAuxACallback[s](SND_AUX_REASON_PARAMETERUPDATE, &info, synthAuxAUser[s]);
|
||||
}
|
||||
|
||||
if (synthAuxBMIDI[s] != 0xff) {
|
||||
SND_AUX_INFO info; // r1+0xC
|
||||
for (i = 0; i < SND_AUX_NUMPARAMETERS; ++i) {
|
||||
info.data.parameterUpdate.para[i] =
|
||||
inpGetAuxB(s, i, synthAuxBMIDI[s], synthAuxBMIDISet[s]);
|
||||
}
|
||||
synthAuxBCallback[s](SND_AUX_REASON_PARAMETERUPDATE, &info, synthAuxBUser[s]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hwFrameDone();
|
||||
synthRealTime += deltaTime;
|
||||
}
|
||||
|
||||
u8 synthFXGetMaxVoices(u16 fid) {
|
||||
|
@ -616,9 +930,437 @@ u32 synthFXStart(u16 fid, u8 vol, u8 pan, u8 studio, u32 itd) {
|
|||
pan = fx->panning;
|
||||
}
|
||||
|
||||
v = synthStartSound(fx->macro, fx->priority, fx->maxVoices, fx->key | 0x80, vol, pan, 0xFF,
|
||||
0xFF, 0, 0, 0xFF, fx->vGroup, 0, studio, itd);
|
||||
v = synthStartSound(fx->macro, fx->priority, fx->maxVoices,
|
||||
#if MUSY_VERSION >= MUSY_VERSION_CHECK(2, 0, 0)
|
||||
0, // TODO
|
||||
#endif
|
||||
fx->key | 0x80, vol, pan, 0xFF, 0xFF, 0, 0, 0xFF, fx->vGroup, 0, studio,
|
||||
itd);
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
bool synthFXSetCtrl(u32 vid, u8 ctrl, u8 value) {
|
||||
u32 i; // r31
|
||||
u32 ret; // r29
|
||||
|
||||
ret = FALSE;
|
||||
vid = vidGetInternalId(vid);
|
||||
|
||||
while (vid != SND_ID_ERROR) {
|
||||
i = vid & 0xff;
|
||||
if (vid == synthVoice[i].id) {
|
||||
if ((synthVoice[i].cFlags & 0x2) != 0) {
|
||||
inpSetMidiCtrl(ctrl, i, synthVoice[i].setup.midiSet, value);
|
||||
} else {
|
||||
inpSetMidiCtrl(ctrl, i, synthVoice[i].midiSet, value);
|
||||
}
|
||||
|
||||
vid = synthVoice[i].child;
|
||||
ret = TRUE;
|
||||
} else {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool synthFXSetCtrl14(u32 vid, u8 ctrl, u16 value) {
|
||||
u32 i; // r31
|
||||
u32 ret; // r29
|
||||
|
||||
ret = FALSE;
|
||||
vid = vidGetInternalId(vid);
|
||||
|
||||
while (vid != SND_ID_ERROR) {
|
||||
i = vid & 0xff;
|
||||
if (vid == synthVoice[i].id) {
|
||||
if ((synthVoice[i].cFlags & 0x2) != 0) {
|
||||
inpSetMidiCtrl14(ctrl, i, synthVoice[i].setup.midiSet, value);
|
||||
} else {
|
||||
inpSetMidiCtrl14(ctrl, i, synthVoice[i].midiSet, value);
|
||||
}
|
||||
|
||||
vid = synthVoice[i].child;
|
||||
ret = TRUE;
|
||||
} else {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void synthFXCloneMidiSetup(SYNTH_VOICE* dest, SYNTH_VOICE* src) {
|
||||
inpFXCopyCtrl(SND_MIDICTRL_VOLUME, dest, src);
|
||||
inpFXCopyCtrl(SND_MIDICTRL_PANNING, dest, src);
|
||||
inpFXCopyCtrl(SND_MIDICTRL_REVERB, dest, src);
|
||||
inpFXCopyCtrl(SND_MIDICTRL_PITCHBEND, dest, src);
|
||||
inpFXCopyCtrl(SND_MIDICTRL_DOPPLER, dest, src);
|
||||
}
|
||||
|
||||
bool synthFXVolume(u32 vid, u8 vol) {
|
||||
u32 i; // r31
|
||||
u32 ret; // r29
|
||||
|
||||
ret = FALSE;
|
||||
vid = vidGetInternalId(vid);
|
||||
|
||||
while (vid != SND_ID_ERROR) {
|
||||
i = vid & 0xff;
|
||||
if (vid == synthVoice[i].id) {
|
||||
if ((synthVoice[i].cFlags & 0x2) != 0) {
|
||||
inpSetMidiCtrl(SND_MIDICTRL_VOLUME, i, synthVoice[i].setup.midiSet, vol);
|
||||
} else {
|
||||
inpSetMidiCtrl(SND_MIDICTRL_VOLUME, i, synthVoice[i].midiSet, vol);
|
||||
}
|
||||
|
||||
vid = synthVoice[i].child;
|
||||
ret = TRUE;
|
||||
} else {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
u32 synthSendKeyOff(u32 voiceid) {
|
||||
u32 i; // r30
|
||||
u32 ret; // r29
|
||||
|
||||
ret = FALSE;
|
||||
|
||||
if (sndActive != 0) {
|
||||
voiceid = vidGetInternalId(voiceid);
|
||||
|
||||
while (voiceid != SND_ID_ERROR) {
|
||||
i = voiceid & 0xff;
|
||||
|
||||
if (voiceid == synthVoice[i].id) {
|
||||
macSetExternalKeyoff(&synthVoice[i]);
|
||||
ret = TRUE;
|
||||
}
|
||||
|
||||
voiceid = synthVoice[i].child;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
u16 synthGetVolume(u32 vid) {
|
||||
u32 i; // r30
|
||||
|
||||
vid = vidGetInternalId(vid);
|
||||
if (vid != SND_ID_ERROR) {
|
||||
i = vid & 0xff;
|
||||
if (vid == synthVoice[i].id && (synthVoice[i].cFlags & 0x2) == 0) {
|
||||
return synthVoice[i].curOutputVolume;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SetupFader(SYNTHMasterFader* smf, u8 volume, u32 time, u8 seqMode, u32 seqId) {
|
||||
smf->seqMode = seqMode;
|
||||
smf->seqId = seqId;
|
||||
if (time != 0) {
|
||||
smf->start = smf->volume;
|
||||
smf->target = (f32)volume * (1.f / 127.f);
|
||||
smf->time = 1.f;
|
||||
smf->deltaTime = 1280.f / (f32)time;
|
||||
} else {
|
||||
smf->volume = smf->target = (f32)volume * (1.f / 127.f);
|
||||
if (smf->seqId != SND_ID_ERROR) {
|
||||
HandleFaderTermination(smf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void synthVolume(u8 volume, u16 time, u8 vGroup, u8 seqMode, u32 seqId) {
|
||||
u32 ltime; // r1+0x14
|
||||
u32 i; // r30
|
||||
u8 type; // r29
|
||||
SYNTHMasterFader* smf; // r31
|
||||
|
||||
if ((ltime = time) != 0) {
|
||||
sndConvertMs(<ime);
|
||||
}
|
||||
|
||||
switch (vGroup) {
|
||||
case SND_ALL_VOLGROUPS:
|
||||
for (smf = synthMasterFader, i = 0; i < 32; ++i, ++smf) {
|
||||
if (smf->type == 0 || smf->type == 1) {
|
||||
SetupFader(smf, volume, ltime, seqMode, SND_ID_ERROR);
|
||||
synthMasterFaderActiveFlags |= 1 << i;
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
||||
case SND_USERALL_VOLGROUPS:
|
||||
for (smf = synthMasterFader, i = 0; i < 32; ++i, ++smf) {
|
||||
if (smf->type == 2 || smf->type == 3) {
|
||||
SetupFader(smf, volume, ltime, seqMode, SND_ID_ERROR);
|
||||
synthMasterFaderActiveFlags |= 1 << i;
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
||||
case SND_USERMUSIC_VOLGROUPS:
|
||||
type = 2;
|
||||
goto setup_type;
|
||||
|
||||
case SND_USERFX_VOLGROUPS:
|
||||
type = 3;
|
||||
goto setup_type;
|
||||
|
||||
case SND_MUSIC_VOLGROUPS:
|
||||
type = 0;
|
||||
goto setup_type;
|
||||
|
||||
case SND_FX_VOLGROUPS:
|
||||
type = 1;
|
||||
goto setup_type;
|
||||
|
||||
setup_type:
|
||||
for (smf = synthMasterFader, i = 0; i < 32; ++i, ++smf) {
|
||||
if (smf->type == type) {
|
||||
SetupFader(smf, volume, ltime, seqMode, SND_ID_ERROR);
|
||||
synthMasterFaderActiveFlags |= 1 << i;
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
||||
default:
|
||||
SetupFader(&synthMasterFader[vGroup], volume, ltime, seqMode, seqId);
|
||||
synthMasterFaderActiveFlags |= 1 << vGroup;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
u32 synthIsFadeOutActive(u8 vGroup) {
|
||||
if (synthMasterFader[vGroup].type != 4 && (synthMasterFaderActiveFlags & (1 << vGroup)) != 0 &&
|
||||
synthMasterFader[vGroup].start > synthMasterFader[vGroup].target) {
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void synthPauseVolume(u8 volume, u16 time, u8 vGroup) {
|
||||
u32 i; // r30
|
||||
u32 ltime; // r1+0x10
|
||||
u8 type; // r28
|
||||
SYNTHMasterFader* smf; // r31
|
||||
|
||||
if (time == 0) {
|
||||
++time;
|
||||
}
|
||||
ltime = time & 0xffff;
|
||||
sndConvertMs(<ime);
|
||||
|
||||
switch (vGroup) {
|
||||
case SND_ALL_VOLGROUPS:
|
||||
for (smf = synthMasterFader, i = 0; i < 32; ++i, ++smf) {
|
||||
if (synthMasterFader[i].type == 0 || synthMasterFader[i].type == 1) {
|
||||
smf->pauseStart = smf->pauseVol;
|
||||
smf->pauseTarget = (f32)volume * (1.f / 127.f);
|
||||
smf->pauseTime = 1.f;
|
||||
smf->pauseDeltaTime = 1280.f / (f32)ltime;
|
||||
synthMasterFaderActiveFlags |= 1 << i;
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
||||
case SND_USERALL_VOLGROUPS:
|
||||
for (smf = synthMasterFader, i = 0; i < 32; ++i, ++smf) {
|
||||
if (synthMasterFader[i].type == 2 || synthMasterFader[i].type == 3) {
|
||||
smf->pauseStart = smf->pauseVol;
|
||||
smf->pauseTarget = (f32)volume * (1.f / 127.f);
|
||||
smf->pauseTime = 1.f;
|
||||
smf->pauseDeltaTime = 1280.f / (f32)ltime;
|
||||
synthMasterFaderActiveFlags |= 1 << i;
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
||||
case SND_USERMUSIC_VOLGROUPS:
|
||||
type = 2;
|
||||
goto setup_type;
|
||||
|
||||
case SND_USERFX_VOLGROUPS:
|
||||
type = 3;
|
||||
goto setup_type;
|
||||
|
||||
case SND_MUSIC_VOLGROUPS:
|
||||
type = 0;
|
||||
goto setup_type;
|
||||
|
||||
case SND_FX_VOLGROUPS:
|
||||
type = 1;
|
||||
goto setup_type;
|
||||
|
||||
setup_type:
|
||||
for (smf = synthMasterFader, i = 0; i < 32; ++i, ++smf) {
|
||||
if (synthMasterFader[i].type == type) {
|
||||
smf->pauseStart = smf->pauseVol;
|
||||
smf->pauseTarget = (f32)volume * (1.f / 127.f);
|
||||
smf->pauseTime = 1.f;
|
||||
smf->pauseDeltaTime = 1280.f / (f32)ltime;
|
||||
synthMasterFaderActiveFlags |= 1 << i;
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
||||
default:
|
||||
smf = &synthMasterFader[vGroup];
|
||||
smf->pauseStart = smf->pauseVol;
|
||||
smf->pauseTarget = (f32)volume * (1.f / 127.f);
|
||||
smf->pauseTime = 1.f;
|
||||
smf->pauseDeltaTime = 1280.f / (f32)ltime;
|
||||
synthMasterFaderActiveFlags |= 1 << vGroup;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void synthSetMusicVolumeType(u8 vGroup, u8 type) {
|
||||
if (sndActive) {
|
||||
synthMasterFader[vGroup].type = type;
|
||||
}
|
||||
}
|
||||
|
||||
u32 synthHWMessageHandler(u32 mesg, u32 voiceID) {
|
||||
u32 ret; // r30
|
||||
|
||||
ret = FALSE;
|
||||
|
||||
switch (mesg) {
|
||||
case 0:
|
||||
if (synthVoice[voiceID & 0xff].block != 0) {
|
||||
break;
|
||||
}
|
||||
vsSampleEndNotify(hwGetVirtualSampleID(voiceID & 0xff));
|
||||
if (voiceID != synthVoice[voiceID & 0xff].id) {
|
||||
break;
|
||||
}
|
||||
macSampleEndNotify(&synthVoice[voiceID & 0xff]);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
voiceKill(voiceID & 0xff);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
ret = vsSampleStartNotify(voiceID);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
vsSampleEndNotify(hwGetVirtualSampleID(voiceID & 0xff));
|
||||
break;
|
||||
|
||||
default:
|
||||
#line 1975
|
||||
MUSY_ASSERT(FALSE);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void synthInit(u32 mixFrq, u32 numVoices) {
|
||||
u32 i; // r31
|
||||
|
||||
synthRealTime = 0;
|
||||
synthInfo.mixFrq = mixFrq;
|
||||
synthSetBpm(120, 255, 0);
|
||||
synthFlags = 0;
|
||||
synthMessageCallback = NULL;
|
||||
|
||||
synthVoice = salMalloc(numVoices * sizeof(SYNTH_VOICE));
|
||||
if (synthVoice == NULL) {
|
||||
#line 2135
|
||||
MUSY_FATAL("Fatal: Could not allocate synthesizer voice array.");
|
||||
}
|
||||
memset(synthVoice, 0, numVoices * sizeof(SYNTH_VOICE));
|
||||
|
||||
for (i = 0; i < numVoices; ++i) {
|
||||
synthVoice[i].id = 0xffffffff;
|
||||
synthVoice[i].cFlags = 0;
|
||||
synthVoice[i].age = 0;
|
||||
synthVoice[i].prio = 0;
|
||||
synthVoice[i].midi = 0xff;
|
||||
synthVoice[i].volume = 0;
|
||||
synthVoice[i].volTable = 0;
|
||||
synthVoice[i].revVolScale = 128;
|
||||
synthVoice[i].revVolOffset = 0;
|
||||
synthVoice[i].panning[0] = synthVoice[i].panTarget[0] = 0x400000;
|
||||
synthVoice[i].panning[1] = synthVoice[i].panTarget[1] = 0;
|
||||
synthVoice[i].sweepOff[0] = 0;
|
||||
synthVoice[i].sweepOff[1] = 0;
|
||||
synthVoice[i].sweepNum[0] = 0;
|
||||
synthVoice[i].sweepNum[1] = 0;
|
||||
synthVoice[i].block = 0;
|
||||
synthVoice[i].vGroup = 23;
|
||||
synthVoice[i].keyGroup = 0;
|
||||
synthVoice[i].itdMode = 1;
|
||||
synthVoice[i].lfo[0].period = 0;
|
||||
synthVoice[i].lfo[0].value = 0;
|
||||
synthVoice[i].lfo[0].lastValue = 0x7fff;
|
||||
synthVoice[i].lfo[1].period = 0;
|
||||
synthVoice[i].lfo[1].value = 0;
|
||||
synthVoice[i].lfo[1].lastValue = 0x7fff;
|
||||
synthVoice[i].portTime = 25600;
|
||||
synthVoice[i].portType = 0;
|
||||
synthVoice[i].studio = 0;
|
||||
synthVoice[i].lowPrecisionJob.voice = i;
|
||||
synthVoice[i].lowPrecisionJob.jobTabIndex = 0xff;
|
||||
synthVoice[i].zeroOffsetJob.voice = i;
|
||||
synthVoice[i].zeroOffsetJob.jobTabIndex = 0xff;
|
||||
synthVoice[i].eventJob.voice = i;
|
||||
synthVoice[i].eventJob.jobTabIndex = 0xff;
|
||||
}
|
||||
|
||||
for (i = 0; i < 32; ++i) {
|
||||
synthMasterFader[i].volume = 0.f;
|
||||
synthMasterFader[i].pauseVol = 1.f;
|
||||
synthMasterFader[i].type = 4;
|
||||
}
|
||||
|
||||
synthMasterFaderActiveFlags = 0;
|
||||
synthMasterFaderPauseActiveFlags = 0;
|
||||
synthMasterFader[31].type = 1;
|
||||
|
||||
for (i = 0; i < 8; ++i) {
|
||||
synthMasterFader[i + 23].type = 0;
|
||||
}
|
||||
|
||||
synthMasterFader[21].volume = 1.f;
|
||||
synthMasterFader[22].volume = 1.f;
|
||||
inpInit(0);
|
||||
|
||||
for (i = 0; i < 8; ++i) {
|
||||
synthAuxACallback[i] = NULL;
|
||||
synthAuxAMIDI[i] = 0xff;
|
||||
synthAuxBCallback[i] = NULL;
|
||||
synthAuxBMIDI[i] = 0xff;
|
||||
synthITDDefault[i].sfx = 0;
|
||||
synthITDDefault[i].music = 0;
|
||||
}
|
||||
|
||||
macInit();
|
||||
vidInit();
|
||||
synthInitAllocationAids();
|
||||
|
||||
for (i = 0; i < 16; ++i) {
|
||||
synthGlobalVariable[i] = 0;
|
||||
}
|
||||
|
||||
voiceInitLastStarted();
|
||||
synthInitJobQueue();
|
||||
hwSetMesgCallback(synthHWMessageHandler);
|
||||
}
|
||||
|
||||
void synthExit() { salFree(synthVoice); }
|
||||
|
|
Loading…
Reference in New Issue