musyx/runtime/synth progress

This commit is contained in:
Luke Street 2023-07-04 17:18:48 -04:00
parent 19e9b9791f
commit bfd8a4e1b3
4 changed files with 411 additions and 65 deletions

View File

@ -10,6 +10,10 @@
extern "C" { extern "C" {
#endif #endif
#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))
typedef struct SYNTH_VOICELIST { typedef struct SYNTH_VOICELIST {
// total size: 0x4 // total size: 0x4
u8 prev; // offset 0x0, size 0x1 u8 prev; // offset 0x0, size 0x1
@ -862,6 +866,9 @@ u32 dataInsertLayer(u16 cid, void* layerdata, u16 size);
u32 dataRemoveLayer(u16 sid); u32 dataRemoveLayer(u16 sid);
u32 dataInsertFX(u16 gid, FX_TAB* fx, u16 fxNum); u32 dataInsertFX(u16 gid, FX_TAB* fx, u16 fxNum);
FX_TAB* dataGetFX(u16 fid); FX_TAB* dataGetFX(u16 fid);
void* dataGetLayer(u16 cid, u16* n);
void* dataGetKeymap(u16 cid);
s32 hwInit(u32* frq, u16 numVoices, u16 numStudios, u32 flags); /* extern */ s32 hwInit(u32* frq, u16 numVoices, u16 numStudios, u32 flags); /* extern */
void hwInitSamplePlayback(u32 v, u16 smpID, void* newsmp, u32 set_defadsr, u32 prio, void hwInitSamplePlayback(u32 v, u16 smpID, void* newsmp, u32 set_defadsr, u32 prio,
u32 callbackUserValue, u32 setSRC, u8 itdMode); u32 callbackUserValue, u32 setSRC, u8 itdMode);
@ -886,6 +893,7 @@ void synthInit(u32, u8); /* extern */
void synthSetBpm(u32 pbm, u8 set, u8 section); void synthSetBpm(u32 pbm, u8 set, u8 section);
void synthFXCloneMidiSetup(SYNTH_VOICE* dest, SYNTH_VOICE* src); void synthFXCloneMidiSetup(SYNTH_VOICE* dest, SYNTH_VOICE* src);
void synthSetMusicVolumeType(u8 vGroup, u8 type); void synthSetMusicVolumeType(u8 vGroup, u8 type);
void synthAddJob(SYNTH_VOICE* svoice, SYNTH_JOBTYPE jobType, u32 deltaTime);
extern s32 synthGlobalVariable[16]; extern s32 synthGlobalVariable[16];
extern u16 voicePrioSortRootListRoot; extern u16 voicePrioSortRootListRoot;
@ -895,6 +903,9 @@ extern u8 voiceListInsert;
extern u8 voiceListRoot; extern u8 voiceListRoot;
void voiceSetPriority(SYNTH_VOICE* svoice, u8 prio); void voiceSetPriority(SYNTH_VOICE* svoice, u8 prio);
u32 voiceIsLastStarted(SYNTH_VOICE* svoice); u32 voiceIsLastStarted(SYNTH_VOICE* svoice);
void voiceSetLastStarted(SYNTH_VOICE* svoice);
void voiceResetLastStarted(SYNTH_VOICE* svoice);
void voiceInitLastStarted();
s32 voiceKillSound(u32 voiceid); s32 voiceKillSound(u32 voiceid);
extern u64 synthRealTime; extern u64 synthRealTime;
@ -923,6 +934,7 @@ u8 hwInitStream(u32 len);
s16 varGet(SYNTH_VOICE* svoice, u32 ctrl, u8 index); s16 varGet(SYNTH_VOICE* svoice, u32 ctrl, u8 index);
u32 sndGetPitch(u8 key, u32 sInfo); u32 sndGetPitch(u8 key, u32 sInfo);
s32 sndPitchUpOne(u16 note);
extern SND_HOOKS salHooks; extern SND_HOOKS salHooks;
extern u8 sndActive; extern u8 sndActive;
extern u8 synthIdleWaitActive; extern u8 synthIdleWaitActive;
@ -1033,6 +1045,9 @@ void inpSetMidiLastNote(u8 midi, u8 midiSet, u8 key);
u16 inpGetModulation(SYNTH_VOICE* svoice); u16 inpGetModulation(SYNTH_VOICE* svoice);
void inpResetMidiCtrl(u8 ch, u8 set, u32 coldReset); void inpResetMidiCtrl(u8 ch, u8 set, u32 coldReset);
void inpResetChannelDefaults(u8 midi, u8 midiSet); void inpResetChannelDefaults(u8 midi, u8 midiSet);
u16 inpGetPitchBend(SYNTH_VOICE* svoice);
u16 inpGetDoppler(SYNTH_VOICE* svoice);
/* TODO: Figure out what `unk` is */ /* TODO: Figure out what `unk` is */
void hwSetSRCType(u32 v, u8 salSRCType); void hwSetSRCType(u32 v, u8 salSRCType);
void hwSetITDMode(u32 v, u8 mode); void hwSetITDMode(u32 v, u8 mode);
@ -1066,6 +1081,12 @@ void sndProfUpdateMisc(SND_PROFILE_INFO* info);
void sndProfResetPMC(SND_PROFILE_DATA* info); void sndProfResetPMC(SND_PROFILE_DATA* info);
void sndProfStartPMC(SND_PROFILE_DATA* info); void sndProfStartPMC(SND_PROFILE_DATA* info);
void vidRemoveVoiceReferences(SYNTH_VOICE* svoice);
u32 vidMakeNew(SYNTH_VOICE* svoice, u32 isMaster);
u32 vidMakeRoot(SYNTH_VOICE* svoice);
u32 adsrHandleLowPrecision(ADSR_VARS* adsr, u16* adsr_start, u16* adsr_delta);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -1082,8 +1082,6 @@ static SEQ_EVENT* GetGlobalEvent(SEQ_SECTION* section) {
return ev; return ev;
} }
#define Clamp(value, min, max) ((value) > (max) ? (max) : (value) < (min) ? (min) : (value))
static SEQ_EVENT* HandleEvent(SEQ_EVENT* event, u8 secIndex, u32* loopFlag) { static SEQ_EVENT* HandleEvent(SEQ_EVENT* event, u8 secIndex, u32* loopFlag) {
CPAT* pa; // r26 CPAT* pa; // r26
NOTE_DATA* pe; // r24 NOTE_DATA* pe; // r24
@ -1169,10 +1167,10 @@ static SEQ_EVENT* HandleEvent(SEQ_EVENT* event, u8 secIndex, u32* loopFlag) {
if ((cseq->trackMute[event->trackId / 32] & (1 << (event->trackId & 0x1f))) != 0) { if ((cseq->trackMute[event->trackId / 32] & (1 << (event->trackId & 0x1f))) != 0) {
if ((macId = cseq->prgState[midi].macId) != 0xffff) { if ((macId = cseq->prgState[midi].macId) != 0xffff) {
key += pa->patternInfo->transpose; key += pa->patternInfo->transpose;
key = Clamp(key, 0, 0x7f); key = CLAMP(key, 0, 0x7f);
velocity += pa->patternInfo->velocityAdd; velocity += pa->patternInfo->velocityAdd;
velocity = Clamp(velocity, 0, 0x7f); velocity = CLAMP(velocity, 0, 0x7f);
if ((note = AllocateNote(event->time + pe->length, secIndex)) != NULL) { if ((note = AllocateNote(event->time + pe->length, secIndex)) != NULL) {
if ((note->id = synthStartSound( if ((note->id = synthStartSound(

View File

@ -5,7 +5,7 @@ static u32 synthTicksPerSecond[9][16];
static SYNTH_JOBTAB synthJobTable[32]; static SYNTH_JOBTAB synthJobTable[32];
CTRL_DEST inpAuxA[8][4]; CTRL_DEST inpAuxA[8][4];
CTRL_DEST inpAuxB[8][4]; CTRL_DEST inpAuxB[8][4];
long synthGlobalVariable[16]; s32 synthGlobalVariable[16];
synthITDInfo synthITDDefault[8]; synthITDInfo synthITDDefault[8];
void* synthAuxBUser[8]; void* synthAuxBUser[8];
SND_AUX_CALLBACK synthAuxBCallback[8]; SND_AUX_CALLBACK synthAuxBCallback[8];
@ -85,7 +85,53 @@ static u32 do_voice_portamento(u8 key, u8 midi, u8 midiSet, u32 isMaster, u32* r
u32 id; // r27 u32 id; // r27
SYNTH_VOICE* sv; // r31 SYNTH_VOICE* sv; // r31
SYNTH_VOICE* last_sv; // r28 SYNTH_VOICE* last_sv; // r28
u32 legatoVoiceIsStarting; // r26 bool legatoVoiceIsStarting; // r26
legatoVoiceIsStarting = FALSE;
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 ((sv->cFlags & 2) != 0) {
legatoVoiceIsStarting = TRUE;
}
if ((sv->cFlags & 0x10) != 0 && (sv->cFlags & 0x10000000008) != 0x8 && hwIsActive(i)) {
if (vid == SND_ID_ERROR && (sv->cFlags & 0x20002) == 0x20002) {
*rejected = TRUE;
return SND_ID_ERROR;
}
last_sv = sv;
sv->portCurPitch = (sv->curNote * 65536) + (sv->curDetune * 65536) / 100;
sv->lastNote = sv->curNote;
sv->curNote = key + ((sv->curNote & 0xff) - sv->orgNote);
sv->orgNote = key;
sv->curDetune = 0;
sv->portTime = 0;
sv->cFlags |= 0x20000;
vidRemoveVoiceReferences(&synthVoice[i]);
if (vid == SND_ID_ERROR) {
sv->child = SND_ID_ERROR;
sv->parent = SND_ID_ERROR;
vid = vidMakeNew(&synthVoice[i], isMaster);
id = sv->id;
} else {
synthVoice[id & 0xff].child = sv->id;
sv->parent = id;
id = sv->id;
vidMakeNew(&synthVoice[i], FALSE);
}
}
}
}
if (vid != SND_ID_ERROR) {
voiceSetLastStarted(last_sv);
inpSetMidiLastNote(last_sv->midi, last_sv->midiSet, last_sv->curNote);
*rejected = FALSE;
} else {
*rejected = legatoVoiceIsStarting;
}
return vid;
} }
static u32 check_portamento(u8 key, u8 midi, u8 midiSet, u32 newVID, u32* vid) { static u32 check_portamento(u8 key, u8 midi, u8 midiSet, u32 newVID, u32* vid) {
@ -99,6 +145,10 @@ static u32 check_portamento(u8 key, u8 midi, u8 midiSet, u32 newVID, u32* vid) {
return 1; return 1;
} }
static u32 StartKeymap(u16 keymapID, s16 prio, u8 maxVoices, u16 allocId, u8 key, u8 vol,
u8 panning, u8 midi, u8 midiSet, u8 section, u16 step, u16 trackid,
u32 vidFlag, u8 vGroup, u8 studio, u32 itd);
static u32 StartLayer(u16 layerID, s16 prio, u8 maxVoices, u16 allocId, u8 key, u8 vol, u8 panning, static u32 StartLayer(u16 layerID, s16 prio, u8 maxVoices, u16 allocId, u8 key, u8 vol, u8 panning,
u8 midi, u8 midiSet, u8 section, u16 step, u16 trackid, u32 vidFlag, u8 midi, u8 midiSet, u8 section, u16 step, u16 trackid, u32 vidFlag,
u8 vGroup, u8 studio, u32 itd) { u8 vGroup, u8 studio, u32 itd) {
@ -107,33 +157,178 @@ static u32 StartLayer(u16 layerID, s16 prio, u8 maxVoices, u16 allocId, u8 key,
u32 new_id; // r1+0x34 u32 new_id; // r1+0x34
u32 id; // r27 u32 id; // r27
LAYER* l; // r31 LAYER* l; // r31
long p; // r30 s32 p; // r30
long k; // r29 s32 k; // r29
u8 v; // r25 u8 v; // r25
u8 mKey; // r24 u8 mKey; // r24
vid = SND_ID_ERROR;
if ((l = dataGetLayer(layerID, &n)) == NULL) {
goto end;
}
mKey = key & 0x7f;
for (; n != 0; --n, ++l) {
if (l->id == 0xffff || l->keyLow > mKey || l->keyHigh < mKey) {
continue;
}
k = mKey + l->transpose;
k = CLAMP(k, 0, 127);
if ((l->id & 0xC000) == 0) {
if (check_portamento(k, midi, midiSet, vidFlag, &new_id)) {
if (new_id != 0xFFFFFFFF) {
goto apply_new_id;
} else {
goto start_new_id;
}
}
continue;
}
start_new_id:
if ((l->panning & 0x80) == 0) {
p = l->panning - 0x40;
p += panning;
// TODO
// p = CLAMP(p, 0, 0x7f);
p = CLAMP_INV(p, 0, 0x7f);
} else {
p = 0x80;
}
v = (vol * l->volume) / 0x7f;
prio += l->prioOffset;
prio = CLAMP(prio, 0, 0xff);
switch (l->id & 0xC000) {
case 0:
new_id = macStart(l->id, prio, maxVoices, allocId, k | key & 0x80, v, p, midi, midiSet,
section, step, trackid, 0, vGroup, studio, itd);
break;
case 0x4000:
new_id = StartKeymap(l->id, prio, maxVoices, allocId, k | key & 0x80, v, p, midi, midiSet,
section, step, trackid, 0, vGroup, studio, itd);
break;
case 0x8000:
new_id = StartLayer(l->id, prio, maxVoices, allocId, k | key & 0x80, v, p, midi, midiSet,
section, step, trackid, 0, vGroup, studio, itd);
break;
}
if (new_id != SND_ID_ERROR) {
apply_new_id:
if (vid == SND_ID_ERROR) {
if (vidFlag != 0) {
vid = vidMakeRoot(&synthVoice[new_id & 0xff]);
} else {
vid = new_id;
}
} else {
synthVoice[id & 0xff].child = new_id;
synthVoice[new_id & 0xff].parent = id;
}
id = new_id;
while (synthVoice[id & 0xff].child != SND_ID_ERROR) {
id = synthVoice[id & 0xff].child;
}
}
}
end:
return vid;
} }
static u32 StartKeymap(u16 keymapID, s16 prio, u8 maxVoices, u16 allocId, u8 key, u8 vol, static u32 StartKeymap(u16 keymapID, s16 prio, u8 maxVoices, u16 allocId, u8 key, u8 vol,
u8 panning, u8 midi, u8 midiSet, u8 section, u16 step, u16 trackid, u8 panning, u8 midi, u8 midiSet, u8 section, u16 step, u16 trackid,
u32 vidFlag, u8 vGroup, u8 studio, u32 itd) { u32 vidFlag, u8 vGroup, u8 studio, u32 itd) {
u8 o; // r30 u8 o; // r30
struct KEYMAP* keymap; // r31 KEYMAP* keymap; // r31
long p; // r26 s32 p; // r26
long k; // r29 s32 k; // r29
u32 vid; // r1+0x34 u32 vid; // r1+0x34
if ((keymap = dataGetKeymap(keymapID)) != NULL) {
o = key & 0x7f;
if (keymap[o].id != 0xffff && (keymap[o].id & 0xc000) != 0x4000) {
if ((keymap[o].panning & 0x80) == 0) {
p = (keymap[key].panning - 0x40);
p += panning;
if (p < 0) {
panning = 0;
} else if (p > 0x7f) {
panning = 0x7f;
} else {
panning = p;
}
} else {
panning = 0x80;
}
k = (key & 0x7f) + keymap[o].transpose;
k = CLAMP(k, 0, 127);
prio += keymap[o].prioOffset;
prio = CLAMP(prio, 0, 0xff);
if ((keymap[o].id & 0xc000) == 0) {
if (!check_portamento(k & 0xff, midi, midiSet, vidFlag, &vid)) {
return 0xffffffff;
}
if (vid != 0xffffffff) {
return vid;
}
return macStart(keymap[o].id, prio, maxVoices, allocId, k | key & 0x80, vol, panning, midi,
midiSet, section, step, trackid, vidFlag, vGroup, studio, itd);
}
return StartLayer(keymap[o].id, prio, maxVoices, allocId, k | key & 0x80, vol, panning, midi,
midiSet, section, step, trackid, vidFlag & 0xff, vGroup, studio, itd);
}
}
return SND_ID_ERROR;
} }
#pragma dont_inline on
u32 synthStartSound(u16 id, u8 prio, u8 max, u8 key, u8 vol, u8 panning, u8 midi, u8 midiSet, 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, u8 section, u16 step, u16 trackid, u8 vGroup, s16 prioOffset, u8 studio,
u32 itd) { u32 itd) {
u32 vid; // r1+0x34 u32 vid; // r1+0x34
prio += prioOffset;
prio = CLAMP(prio, 0, 0xff);
switch (id & 0xC000) {
case 0:
if (!check_portamento(key, midi, midiSet, 1, &vid)) {
return 0xffffffff;
}
if (vid != 0xffffffff) {
return vid;
}
return macStart(id, prio, max, id, key, vol, panning, midi, midiSet, section, step, trackid, 1,
vGroup, studio, itd);
case 0x4000:
return StartKeymap(id, prio, max, id, key, vol, panning, midi, midiSet, section, step, trackid,
1, vGroup, studio, itd);
case 0x8000:
return StartLayer(id, prio, max, id, key, vol, panning, midi, midiSet, section, step, trackid,
1, vGroup, studio, itd);
default:
return SND_ID_ERROR;
}
} }
#pragma dont_inline reset
static u32 convert_cents(SYNTH_VOICE* svoice, u32 ccents) { static u32 convert_cents(SYNTH_VOICE* svoice, u32 ccents) {
unsigned long curDetune; // r30 u32 curDetune; // r30
unsigned long cpitch; // r31 u32 cpitch; // r31
cpitch = sndGetPitch(ccents / 65536, svoice->sInfo) * 65536;
if ((curDetune = ccents & 0xffff) != 0) {
cpitch += curDetune * ((sndPitchUpOne(cpitch / 65536) & 0xffff) - (cpitch / 65536 & 0xffff));
}
return cpitch;
} }
static void UpdateTimeMIDICtrl(SYNTH_VOICE* sv) { static void UpdateTimeMIDICtrl(SYNTH_VOICE* sv) {
@ -145,42 +340,174 @@ static void UpdateTimeMIDICtrl(SYNTH_VOICE* sv) {
sv->midiDirtyFlags = 0x1fff; sv->midiDirtyFlags = 0x1fff;
} }
static void LowPrecisionHandler(unsigned long i) { static void LowPrecisionHandler(u32 i) {
unsigned long j; // r30 u32 j; // r30
long pbend; // r29 s32 pbend; // r29
unsigned long ccents; // r28 u32 ccents; // r28
unsigned long cpitch; // r26 u32 cpitch; // r26
unsigned short Modulation; // r24 u16 Modulation; // r24
unsigned short portamento; // r25 u16 portamento; // r25
unsigned long lowDeltaTime; // r27 u32 lowDeltaTime; // r27
struct SYNTH_VOICE* sv; // r31 SYNTH_VOICE* sv; // r31
unsigned long cntDelta; // r20 u32 cntDelta; // r20
unsigned long addFactor; // r19 u32 addFactor; // r19
unsigned short adsr_start; // r1+0xE u16 adsr_start; // r1+0xE
unsigned short adsr_delta; // r1+0xC u16 adsr_delta; // r1+0xC
long vrange; // r23 s32 vrange; // r23
long voff; // r22 s32 voff; // r22
sv = &synthVoice[i];
if (!hwIsActive(i) && sv->addr == NULL) {
goto end;
} }
static void ZeroOffsetHandler(unsigned long i) { lowDeltaTime = synthRealTime - sv->lastLowCallTime;
struct SYNTH_VOICE* sv; // r31 sv->lastLowCallTime = synthRealTime;
unsigned long lowDeltaTime; // r26 for (j = 0; j < 2; ++j) {
unsigned short Modulation; // r25 if (sv->lfo[j].period == 0) {
float vol; // r62 continue;
float auxa; // r57 }
float auxb; // r56 sv->lfo[j].time += lowDeltaTime;
float f; // r59 sv->lfo[j].value =
float voiceVol; // r60 sndSin((sv->lfo[j].time % sv->lfo[j].period * 16) / (sv->lfo[j].period / 256));
unsigned long volUpdate; // r30 if (sv->lfo[j].value != sv->lfo[j].lastValue) {
float lfo; // r55 sv->lfo[j].lastValue = sv->lfo[j].value;
float scale; // r63 if (sv->lfoUsedByInput[j]) {
float mscale; // r54 sv->lfoUsedByInput[j] = 0;
long pan; // r28 sv->midiDirtyFlags |= 0x1fff;
float preVol; // r58 }
float postVol; // r61 }
} }
static void EventHandler(unsigned long i) { if ((sv->cFlags & 0x2000) != 0) {
sv->vibCurTime += lowDeltaTime;
sv->vibCurOffset = sndSin((sv->vibCurTime % sv->vibPeriod * 16) / (sv->vibPeriod / 256));
}
if (sv->sweepNum[0] | sv->sweepNum[1]) {
cntDelta = (lowDeltaTime & 0x00ffffff) << 4;
addFactor = lowDeltaTime & 0x0fffffff;
for (j = 0; j < 2; ++j) {
if (sv->sweepNum[j] == 0) {
continue;
}
sv->sweepCnt[j] -= cntDelta;
if (sv->sweepCnt[j] <= 0) {
sv->sweepCnt[j] = sv->sweepNum[j] << 16;
sv->sweepOff[j] = 0;
} else {
sv->sweepOff[j] += (sv->sweepAdd[j] >> 12) * addFactor;
}
}
}
for (j = 0; j < 2; ++j) {
if (sv->panning[j] == sv->panTarget[j]) {
continue;
}
sv->panTime[j] -= lowDeltaTime;
if ((s32)sv->panTime[j] <= 0) {
sv->panning[j] = sv->panTarget[j];
sv->panTime[j] = 0;
} else {
sv->panning[j] = sv->panTarget[j] - (sv->panTime[j] / 256) * sv->panDelta[j];
sv->panning[j] = CLAMP_INV((s32)sv->panning[j], 0, 0x7f0000u);
}
sv->cFlags |= 0x200000000000;
}
if ((sv->cFlags & 0x20000000000) != 0 &&
adsrHandleLowPrecision(&sv->pitchADSR, &adsr_start, &adsr_delta)) {
sv->cFlags &= ~0x20000000000;
}
ccents = sv->curNote * 65536 + (sv->curDetune * 65536) / 100;
if ((sv->cFlags & 0x10010) != 0) {
if (sv->midi != 0xff) {
pbend = inpGetPitchBend(sv);
sv->pbLast = pbend;
goto pbend_adjust;
}
} else {
pbend = sv->pbLast;
pbend_adjust:
if (pbend != 0x2000) {
pbend -= 0x2000;
if (pbend < 0) {
ccents += sv->pbLowerKeyRange * pbend * 8;
} else {
ccents += sv->pbUpperKeyRange * pbend * 8;
}
}
}
if ((sv->cFlags & 0x2000) != 0) {
Modulation = inpGetModulation(sv);
vrange = sv->vibKeyRange * 256 + (sv->vibCentRange * 256) / 100;
if (sv->vibModAddScale != 0) {
vrange += (sv->vibModAddScale * ((Modulation >> 7) & 0x1ff)) >> 7;
}
if ((sv->cFlags & 0x4000) != 0) {
voff = (sv->vibCurOffset * ((Modulation >> 7) & 0x1ff)) >> 7;
} else {
voff = sv->vibCurOffset;
}
ccents += (vrange * voff) >> 4;
}
if (sv->midi != 0xff) {
portamento = inpGetMidiCtrl(SND_MIDICTRL_PORTAMENTO, sv->midi, sv->midiSet);
if (portamento != sv->portLastCtrlState || (sv->cFlags & 0x21000) == 0x20000) {
if (portamento <= 0x1f80) {
sv->cFlags &= ~0x400;
} else {
if ((sv->cFlags & 0x400) == 0) {
synthInitPortamento(sv);
}
sv->cFlags |= 0x400;
}
sv->cFlags |= 0x1000;
sv->portLastCtrlState = portamento;
}
}
ccents = apply_portamento(sv, ccents, lowDeltaTime);
if ((sv->cFlags & 0x20000000000) != 0) {
ccents += sv->pitchADSRRange * (sv->pitchADSR.currentVolume >> 16) >> 7;
}
cpitch = convert_cents(sv, ccents);
cpitch += sv->sweepOff[0] + sv->sweepOff[1];
cpitch = ((cpitch >> 16) * inpGetDoppler(sv)) >> 13;
sv->curPitch = cpitch;
hwSetPitch(i, cpitch);
synthAddJob(sv, 0, 0xf00);
end:
UpdateTimeMIDICtrl(sv);
}
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
s32 pan; // r28
f32 preVol; // r58
f32 postVol; // r61
}
static void EventHandler(u32 i) {
SYNTH_VOICE* sv; // r31 SYNTH_VOICE* sv; // r31
} }
@ -197,7 +524,7 @@ static void synthInitJobQueue() {
} }
#pragma dont_inline on #pragma dont_inline on
void synthAddJob(SYNTH_VOICE* svoice, SYNTH_JOBTYPE jobType, unsigned long deltaTime) { void synthAddJob(SYNTH_VOICE* svoice, SYNTH_JOBTYPE jobType, u32 deltaTime) {
SYNTH_QUEUE* newJq; // r31 SYNTH_QUEUE* newJq; // r31
SYNTH_QUEUE** root; // r30 SYNTH_QUEUE** root; // r30
u8 jobTabIndex; // r29 u8 jobTabIndex; // r29
@ -219,7 +546,7 @@ void synthForceLowPrecisionUpdate(SYNTH_VOICE* svoice) {
void synthKeyStateUpdate(SYNTH_VOICE* svoice) { synthAddJob(svoice, SYNTH_JOBTYPE_EVENT, 0); } void synthKeyStateUpdate(SYNTH_VOICE* svoice) { synthAddJob(svoice, SYNTH_JOBTYPE_EVENT, 0); }
void HandleJobQueue(SYNTH_QUEUE** queueRoot, void (*handler)(unsigned long)) { void HandleJobQueue(SYNTH_QUEUE** queueRoot, void (*handler)(u32)) {
SYNTH_QUEUE* jq; // r31 SYNTH_QUEUE* jq; // r31
SYNTH_QUEUE* nextJq; // r30 SYNTH_QUEUE* nextJq; // r30
@ -259,15 +586,15 @@ void HandleFaderTermination(SYNTHMasterFader* smf) {
} }
} }
void synthHandle(unsigned long deltaTime) { void synthHandle(u32 deltaTime) {
unsigned long i; // r29 u32 i; // r29
unsigned long s; // r30 u32 s; // r30
SYNTHMasterFader* smf; // r31 SYNTHMasterFader* smf; // r31
unsigned long testFlag; // r27 u32 testFlag; // r27
SND_AUX_INFO info; // r1+0x18 SND_AUX_INFO info; // r1+0x18
} }
unsigned char synthFXGetMaxVoices(u16 fid) { u8 synthFXGetMaxVoices(u16 fid) {
FX_TAB* fx; FX_TAB* fx;
if ((fx = dataGetFX(fid)) != NULL) { if ((fx = dataGetFX(fid)) != NULL) {
return fx->maxVoices; return fx->maxVoices;

View File

@ -202,7 +202,7 @@ void* dataGetKeymap(unsigned short cid) {
long layercmp(void* p1, void* p2) { return ((LAYER_TAB*)p1)->id - ((LAYER_TAB*)p2)->id; } long layercmp(void* p1, void* p2) { return ((LAYER_TAB*)p1)->id - ((LAYER_TAB*)p2)->id; }
void* dataGetLayer(unsigned short cid, unsigned short* n) { void* dataGetLayer(u16 cid, u16* n) {
static LAYER_TAB key; static LAYER_TAB key;
static LAYER_TAB* result; static LAYER_TAB* result;