mirror of https://github.com/PrimeDecomp/prime.git
musyx/runtime/synth progress
This commit is contained in:
parent
19e9b9791f
commit
bfd8a4e1b3
|
@ -10,6 +10,10 @@
|
|||
extern "C" {
|
||||
#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 {
|
||||
// total size: 0x4
|
||||
u8 prev; // offset 0x0, size 0x1
|
||||
|
@ -862,6 +866,9 @@ u32 dataInsertLayer(u16 cid, void* layerdata, u16 size);
|
|||
u32 dataRemoveLayer(u16 sid);
|
||||
u32 dataInsertFX(u16 gid, FX_TAB* fx, u16 fxNum);
|
||||
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 */
|
||||
void hwInitSamplePlayback(u32 v, u16 smpID, void* newsmp, u32 set_defadsr, u32 prio,
|
||||
u32 callbackUserValue, u32 setSRC, u8 itdMode);
|
||||
|
@ -886,6 +893,7 @@ void synthInit(u32, u8); /* extern */
|
|||
void synthSetBpm(u32 pbm, u8 set, u8 section);
|
||||
void synthFXCloneMidiSetup(SYNTH_VOICE* dest, SYNTH_VOICE* src);
|
||||
void synthSetMusicVolumeType(u8 vGroup, u8 type);
|
||||
void synthAddJob(SYNTH_VOICE* svoice, SYNTH_JOBTYPE jobType, u32 deltaTime);
|
||||
|
||||
extern s32 synthGlobalVariable[16];
|
||||
extern u16 voicePrioSortRootListRoot;
|
||||
|
@ -895,6 +903,9 @@ extern u8 voiceListInsert;
|
|||
extern u8 voiceListRoot;
|
||||
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);
|
||||
|
||||
extern u64 synthRealTime;
|
||||
|
@ -923,6 +934,7 @@ u8 hwInitStream(u32 len);
|
|||
s16 varGet(SYNTH_VOICE* svoice, u32 ctrl, u8 index);
|
||||
|
||||
u32 sndGetPitch(u8 key, u32 sInfo);
|
||||
s32 sndPitchUpOne(u16 note);
|
||||
extern SND_HOOKS salHooks;
|
||||
extern u8 sndActive;
|
||||
extern u8 synthIdleWaitActive;
|
||||
|
@ -1033,6 +1045,9 @@ 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);
|
||||
|
||||
/* TODO: Figure out what `unk` is */
|
||||
void hwSetSRCType(u32 v, u8 salSRCType);
|
||||
void hwSetITDMode(u32 v, u8 mode);
|
||||
|
@ -1066,6 +1081,12 @@ void sndProfUpdateMisc(SND_PROFILE_INFO* info);
|
|||
void sndProfResetPMC(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
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1082,8 +1082,6 @@ static SEQ_EVENT* GetGlobalEvent(SEQ_SECTION* section) {
|
|||
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) {
|
||||
CPAT* pa; // r26
|
||||
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 ((macId = cseq->prgState[midi].macId) != 0xffff) {
|
||||
key += pa->patternInfo->transpose;
|
||||
key = Clamp(key, 0, 0x7f);
|
||||
key = CLAMP(key, 0, 0x7f);
|
||||
|
||||
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->id = synthStartSound(
|
||||
|
|
|
@ -5,7 +5,7 @@ static u32 synthTicksPerSecond[9][16];
|
|||
static SYNTH_JOBTAB synthJobTable[32];
|
||||
CTRL_DEST inpAuxA[8][4];
|
||||
CTRL_DEST inpAuxB[8][4];
|
||||
long synthGlobalVariable[16];
|
||||
s32 synthGlobalVariable[16];
|
||||
synthITDInfo synthITDDefault[8];
|
||||
void* synthAuxBUser[8];
|
||||
SND_AUX_CALLBACK synthAuxBCallback[8];
|
||||
|
@ -80,12 +80,58 @@ void synthInitPortamento(SYNTH_VOICE* svoice) {
|
|||
}
|
||||
|
||||
static u32 do_voice_portamento(u8 key, u8 midi, u8 midiSet, u32 isMaster, u32* rejected) {
|
||||
u32 i; // r30
|
||||
u32 vid; // r29
|
||||
u32 id; // r27
|
||||
SYNTH_VOICE* sv; // r31
|
||||
SYNTH_VOICE* last_sv; // r28
|
||||
u32 legatoVoiceIsStarting; // r26
|
||||
u32 i; // r30
|
||||
u32 vid; // r29
|
||||
u32 id; // r27
|
||||
SYNTH_VOICE* sv; // r31
|
||||
SYNTH_VOICE* last_sv; // r28
|
||||
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) {
|
||||
|
@ -99,6 +145,10 @@ static u32 check_portamento(u8 key, u8 midi, u8 midiSet, u32 newVID, u32* vid) {
|
|||
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,
|
||||
u8 midi, u8 midiSet, u8 section, u16 step, u16 trackid, u32 vidFlag,
|
||||
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 id; // r27
|
||||
LAYER* l; // r31
|
||||
long p; // r30
|
||||
long k; // r29
|
||||
s32 p; // r30
|
||||
s32 k; // r29
|
||||
u8 v; // r25
|
||||
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,
|
||||
u8 panning, u8 midi, u8 midiSet, u8 section, u16 step, u16 trackid,
|
||||
u32 vidFlag, u8 vGroup, u8 studio, u32 itd) {
|
||||
u8 o; // r30
|
||||
struct KEYMAP* keymap; // r31
|
||||
long p; // r26
|
||||
long k; // r29
|
||||
u32 vid; // r1+0x34
|
||||
u8 o; // r30
|
||||
KEYMAP* keymap; // r31
|
||||
s32 p; // r26
|
||||
s32 k; // r29
|
||||
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,
|
||||
u8 section, u16 step, u16 trackid, u8 vGroup, s16 prioOffset, u8 studio,
|
||||
u32 itd) {
|
||||
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) {
|
||||
unsigned long curDetune; // r30
|
||||
unsigned long cpitch; // r31
|
||||
u32 curDetune; // r30
|
||||
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) {
|
||||
|
@ -145,42 +340,174 @@ static void UpdateTimeMIDICtrl(SYNTH_VOICE* sv) {
|
|||
sv->midiDirtyFlags = 0x1fff;
|
||||
}
|
||||
|
||||
static void LowPrecisionHandler(unsigned long i) {
|
||||
unsigned long j; // r30
|
||||
long pbend; // r29
|
||||
unsigned long ccents; // r28
|
||||
unsigned long cpitch; // r26
|
||||
unsigned short Modulation; // r24
|
||||
unsigned short portamento; // r25
|
||||
unsigned long lowDeltaTime; // r27
|
||||
struct SYNTH_VOICE* sv; // r31
|
||||
unsigned long cntDelta; // r20
|
||||
unsigned long addFactor; // r19
|
||||
unsigned short adsr_start; // r1+0xE
|
||||
unsigned short adsr_delta; // r1+0xC
|
||||
long vrange; // r23
|
||||
long voff; // r22
|
||||
static void LowPrecisionHandler(u32 i) {
|
||||
u32 j; // r30
|
||||
s32 pbend; // r29
|
||||
u32 ccents; // r28
|
||||
u32 cpitch; // r26
|
||||
u16 Modulation; // r24
|
||||
u16 portamento; // r25
|
||||
u32 lowDeltaTime; // r27
|
||||
SYNTH_VOICE* sv; // r31
|
||||
u32 cntDelta; // r20
|
||||
u32 addFactor; // r19
|
||||
u16 adsr_start; // r1+0xE
|
||||
u16 adsr_delta; // r1+0xC
|
||||
s32 vrange; // r23
|
||||
s32 voff; // r22
|
||||
|
||||
sv = &synthVoice[i];
|
||||
if (!hwIsActive(i) && sv->addr == NULL) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
lowDeltaTime = synthRealTime - sv->lastLowCallTime;
|
||||
sv->lastLowCallTime = synthRealTime;
|
||||
for (j = 0; j < 2; ++j) {
|
||||
if (sv->lfo[j].period == 0) {
|
||||
continue;
|
||||
}
|
||||
sv->lfo[j].time += lowDeltaTime;
|
||||
sv->lfo[j].value =
|
||||
sndSin((sv->lfo[j].time % sv->lfo[j].period * 16) / (sv->lfo[j].period / 256));
|
||||
if (sv->lfo[j].value != sv->lfo[j].lastValue) {
|
||||
sv->lfo[j].lastValue = sv->lfo[j].value;
|
||||
if (sv->lfoUsedByInput[j]) {
|
||||
sv->lfoUsedByInput[j] = 0;
|
||||
sv->midiDirtyFlags |= 0x1fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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(unsigned long i) {
|
||||
struct SYNTH_VOICE* sv; // r31
|
||||
unsigned long lowDeltaTime; // r26
|
||||
unsigned short Modulation; // r25
|
||||
float vol; // r62
|
||||
float auxa; // r57
|
||||
float auxb; // r56
|
||||
float f; // r59
|
||||
float voiceVol; // r60
|
||||
unsigned long volUpdate; // r30
|
||||
float lfo; // r55
|
||||
float scale; // r63
|
||||
float mscale; // r54
|
||||
long pan; // r28
|
||||
float preVol; // r58
|
||||
float postVol; // r61
|
||||
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(unsigned long i) {
|
||||
static void EventHandler(u32 i) {
|
||||
SYNTH_VOICE* sv; // r31
|
||||
}
|
||||
|
||||
|
@ -197,13 +524,13 @@ static void synthInitJobQueue() {
|
|||
}
|
||||
|
||||
#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** root; // r30
|
||||
u8 jobTabIndex; // r29
|
||||
SYNTH_JOBTAB* jobTab; // r28
|
||||
}
|
||||
#pragma dont_inline reset
|
||||
#pragma dont_inline reset
|
||||
|
||||
void synthStartSynthJobHandling(SYNTH_VOICE* svoice) {
|
||||
svoice->lastLowCallTime = synthRealTime;
|
||||
|
@ -219,7 +546,7 @@ void synthForceLowPrecisionUpdate(SYNTH_VOICE* svoice) {
|
|||
|
||||
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* nextJq; // r30
|
||||
|
||||
|
@ -259,15 +586,15 @@ void HandleFaderTermination(SYNTHMasterFader* smf) {
|
|||
}
|
||||
}
|
||||
|
||||
void synthHandle(unsigned long deltaTime) {
|
||||
unsigned long i; // r29
|
||||
unsigned long s; // r30
|
||||
SYNTHMasterFader* smf; // r31
|
||||
unsigned long testFlag; // r27
|
||||
SND_AUX_INFO info; // r1+0x18
|
||||
void synthHandle(u32 deltaTime) {
|
||||
u32 i; // r29
|
||||
u32 s; // r30
|
||||
SYNTHMasterFader* smf; // r31
|
||||
u32 testFlag; // r27
|
||||
SND_AUX_INFO info; // r1+0x18
|
||||
}
|
||||
|
||||
unsigned char synthFXGetMaxVoices(u16 fid) {
|
||||
u8 synthFXGetMaxVoices(u16 fid) {
|
||||
FX_TAB* fx;
|
||||
if ((fx = dataGetFX(fid)) != NULL) {
|
||||
return fx->maxVoices;
|
||||
|
|
|
@ -202,7 +202,7 @@ void* dataGetKeymap(unsigned short cid) {
|
|||
|
||||
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* result;
|
||||
|
||||
|
|
Loading…
Reference in New Issue