You've already forked Microtransactions64
mirror of
https://github.com/Print-and-Panic/Microtransactions64.git
synced 2026-01-21 10:17:19 -08:00
Vibrato optimizations (#530)
Optimize vibrato to even exceed vanilla's implementation, all without restricting usability from the current implementation. This should save up to about 1ms of audio runtime.
This commit is contained in:
@@ -189,23 +189,33 @@ s32 get_vibrato_pitch_change(struct VibratoState *vib) {
|
||||
#endif
|
||||
|
||||
f32 get_vibrato_freq_scale(struct VibratoState *vib) {
|
||||
s32 vibratoExtentTarget;
|
||||
|
||||
if (vib->delay != 0) {
|
||||
vib->delay--;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// This needs to be set locally because changing the original value to 0 overrides the whole channel,
|
||||
// effectively negating the ability to disable vibrato and bypass this function in the first place.
|
||||
// This function isn't huge but it otherwise would get called many thousands of times per second.
|
||||
vibratoExtentTarget = vib->seqChannel->vibratoExtentTarget;
|
||||
if (vibratoExtentTarget >= VIBRATO_DISABLED_VALUE) {
|
||||
vibratoExtentTarget = 0;
|
||||
}
|
||||
|
||||
if (vib->extentChangeTimer) {
|
||||
if (vib->extentChangeTimer == 1) {
|
||||
vib->extent = (s32) vib->seqChannel->vibratoExtentTarget;
|
||||
vib->extent = vibratoExtentTarget;
|
||||
} else {
|
||||
vib->extent +=
|
||||
((s32) vib->seqChannel->vibratoExtentTarget - vib->extent) / (s32) vib->extentChangeTimer;
|
||||
(vibratoExtentTarget - vib->extent) / (s32) vib->extentChangeTimer;
|
||||
}
|
||||
|
||||
vib->extentChangeTimer--;
|
||||
} else if (vib->seqChannel->vibratoExtentTarget != (s32) vib->extent) {
|
||||
} else if (vibratoExtentTarget != (s32) vib->extent) {
|
||||
if ((vib->extentChangeTimer = vib->seqChannel->vibratoExtentChangeDelay) == 0) {
|
||||
vib->extent = (s32) vib->seqChannel->vibratoExtentTarget;
|
||||
vib->extent = vibratoExtentTarget;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -246,11 +256,11 @@ void note_vibrato_update(struct Note *note) {
|
||||
note->vibratoFreqScale = get_vibrato_freq_scale(¬e->vibratoState);
|
||||
}
|
||||
#else
|
||||
if (note->vibratoState.active) {
|
||||
if (note->vibratoState.activeFlags & VIBMODE_PORTAMENTO) {
|
||||
note->portamentoFreqScale = get_portamento_freq_scale(¬e->portamento);
|
||||
if (note->parentLayer != NO_LAYER) {
|
||||
note->vibratoFreqScale = get_vibrato_freq_scale(¬e->vibratoState);
|
||||
}
|
||||
}
|
||||
if ((note->vibratoState.activeFlags & VIBMODE_VIBRATO) && note->parentLayer != NO_LAYER) {
|
||||
note->vibratoFreqScale = get_vibrato_freq_scale(¬e->vibratoState);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -265,18 +275,23 @@ void note_vibrato_init(struct Note *note) {
|
||||
|
||||
struct VibratoState *vib = ¬e->vibratoState;
|
||||
|
||||
/* This code was probably removed from EU and SH for a reason; probably because it's dumb and makes vibrato harder to use well.
|
||||
#if defined(VERSION_JP) || defined(VERSION_US)
|
||||
if (note->parentLayer->seqChannel->vibratoExtentStart == 0
|
||||
&& note->parentLayer->seqChannel->vibratoExtentTarget == 0
|
||||
&& note->parentLayer->portamento.mode == 0) {
|
||||
vib->active = FALSE;
|
||||
vib->activeFlags = VIBMODE_NONE;
|
||||
if (note->parentLayer->portamento.mode != 0) {
|
||||
vib->activeFlags |= VIBMODE_PORTAMENTO;
|
||||
note->portamento = note->parentLayer->portamento;
|
||||
}
|
||||
|
||||
if (!(note->parentLayer->seqChannel->vibratoExtentStart == 0
|
||||
&& note->parentLayer->seqChannel->vibratoExtentTarget >= VIBRATO_DISABLED_VALUE)) {
|
||||
vib->activeFlags |= VIBMODE_VIBRATO;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
|
||||
#else
|
||||
vib->active = TRUE;
|
||||
#endif
|
||||
|
||||
vib->time = 0;
|
||||
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
@@ -313,8 +328,6 @@ void note_vibrato_init(struct Note *note) {
|
||||
vib->rate = seqChannel->vibratoRateStart;
|
||||
}
|
||||
vib->delay = seqChannel->vibratoDelay;
|
||||
|
||||
note->portamento = note->parentLayer->portamento;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,12 @@ enum ADSRDelays {
|
||||
ADSR_RESTART = -3,
|
||||
};
|
||||
|
||||
enum VibratoModes {
|
||||
VIBMODE_NONE = 0,
|
||||
VIBMODE_VIBRATO = (1 << 0),
|
||||
VIBMODE_PORTAMENTO = (1 << 1),
|
||||
};
|
||||
|
||||
// Envelopes are always stored as big endian, to match sequence files which are
|
||||
// byte blobs and can embed envelopes. Hence this byteswapping macro.
|
||||
#if IS_BIG_ENDIAN
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
#endif
|
||||
#endif // EXPAND_AUDIO_HEAP
|
||||
|
||||
#define VIBRATO_DISABLED_VALUE (0xFF * 8)
|
||||
|
||||
#define NO_LAYER ((struct SequenceChannelLayer *)(-1))
|
||||
|
||||
enum MuteBehaviors {
|
||||
@@ -139,7 +141,7 @@ struct VibratoState {
|
||||
/* , 0x14*/ u8 active;
|
||||
#else
|
||||
/*0x08, */ s8 *curve;
|
||||
/*0x0C, */ u8 active;
|
||||
/*0x0C, */ u8 activeFlags;
|
||||
/*0x0E, */ u16 rate;
|
||||
/*0x10, */ u16 extent;
|
||||
#endif
|
||||
|
||||
@@ -1423,6 +1423,7 @@ void note_init_all(void) {
|
||||
note->prevParentLayer = NO_LAYER;
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
note->waveId = 0;
|
||||
note->vibratoState.active = FALSE;
|
||||
#else
|
||||
note->reverbVol = 0;
|
||||
note->usesHeadsetPanEffects = FALSE;
|
||||
@@ -1432,12 +1433,12 @@ void note_init_all(void) {
|
||||
note->targetVolRight = 0;
|
||||
note->frequency = 0.0f;
|
||||
note->unused1 = 0x3f;
|
||||
note->vibratoState.activeFlags = VIBMODE_NONE;
|
||||
#endif
|
||||
note->attributes.velocity = 0.0f;
|
||||
note->adsrVolScale = 0;
|
||||
note->adsr.state = ADSR_STATE_DISABLED;
|
||||
note->adsr.action = 0;
|
||||
note->vibratoState.active = FALSE;
|
||||
note->portamento.cur = 0.0f;
|
||||
note->portamento.speed = 0.0f;
|
||||
#if defined(VERSION_SH)
|
||||
|
||||
@@ -64,7 +64,7 @@ void sequence_channel_init(struct SequenceChannel *seqChannel) {
|
||||
#endif
|
||||
seqChannel->vibratoRateTarget = 0x800;
|
||||
seqChannel->vibratoRateStart = 0x800;
|
||||
seqChannel->vibratoExtentTarget = 0;
|
||||
seqChannel->vibratoExtentTarget = VIBRATO_DISABLED_VALUE;
|
||||
seqChannel->vibratoExtentStart = 0;
|
||||
seqChannel->vibratoRateChangeDelay = 0;
|
||||
seqChannel->vibratoExtentChangeDelay = 0;
|
||||
@@ -1942,7 +1942,7 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) {
|
||||
break;
|
||||
|
||||
case 0xec:
|
||||
seqChannel->vibratoExtentTarget = 0;
|
||||
seqChannel->vibratoExtentTarget = VIBRATO_DISABLED_VALUE;
|
||||
seqChannel->vibratoExtentStart = 0;
|
||||
seqChannel->vibratoExtentChangeDelay = 0;
|
||||
seqChannel->vibratoRateTarget = 0;
|
||||
|
||||
Reference in New Issue
Block a user