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:
@@ -226,7 +226,7 @@ chan_end
|
|||||||
.delay_interrupt:
|
.delay_interrupt:
|
||||||
chan_setpanmix 127
|
chan_setpanmix 127
|
||||||
chan_setvolscale 127
|
chan_setvolscale 127
|
||||||
chan_setvibratoextent 0
|
chan_setvibratoextent 0xff // 0xff represents disabled value
|
||||||
chan_ioreadval 1 // IO slots 0-3 are reset to -1 when read; restore the value
|
chan_ioreadval 1 // IO slots 0-3 are reset to -1 when read; restore the value
|
||||||
chan_iowriteval 0
|
chan_iowriteval 0
|
||||||
chan_break // break out of the loop
|
chan_break // break out of the loop
|
||||||
@@ -1147,6 +1147,9 @@ chan_setbank 4
|
|||||||
chan_setinstr 14
|
chan_setinstr 14
|
||||||
chan_setdecayrelease 12
|
chan_setdecayrelease 12
|
||||||
chan_setvibratoextent 10
|
chan_setvibratoextent 10
|
||||||
|
chan_setval 0x7f
|
||||||
|
chan_call .delay
|
||||||
|
chan_setvibratoextent 0xff
|
||||||
chan_end
|
chan_end
|
||||||
|
|
||||||
.layer_68F:
|
.layer_68F:
|
||||||
@@ -1317,7 +1320,7 @@ chan_setlayer 0, .layer_79D
|
|||||||
chan_setlayer 1, .layer_79B
|
chan_setlayer 1, .layer_79B
|
||||||
chan_setval 36
|
chan_setval 36
|
||||||
chan_call .delay
|
chan_call .delay
|
||||||
chan_setvibratoextent 0
|
chan_setvibratoextent 0xff
|
||||||
chan_end
|
chan_end
|
||||||
|
|
||||||
.layer_79B:
|
.layer_79B:
|
||||||
@@ -3025,6 +3028,9 @@ chan_setvibratorate 60
|
|||||||
chan_setval 25
|
chan_setval 25
|
||||||
chan_call .set_reverb
|
chan_call .set_reverb
|
||||||
chan_setlayer 0, .layer_11E4
|
chan_setlayer 0, .layer_11E4
|
||||||
|
chan_setval 0x45
|
||||||
|
chan_call .delay
|
||||||
|
chan_setvibratoextent 0xff
|
||||||
chan_end
|
chan_end
|
||||||
|
|
||||||
.layer_11E4:
|
.layer_11E4:
|
||||||
@@ -3070,7 +3076,7 @@ chan_setbank 4
|
|||||||
chan_setinstr 6
|
chan_setinstr 6
|
||||||
chan_setval 49
|
chan_setval 49
|
||||||
chan_call .delay
|
chan_call .delay
|
||||||
chan_setvibratoextent 0
|
chan_setvibratoextent 0xff
|
||||||
chan_end
|
chan_end
|
||||||
|
|
||||||
.layer_1242:
|
.layer_1242:
|
||||||
@@ -4389,7 +4395,7 @@ chan_setlayer 0, .layer_1AEB
|
|||||||
chan_setlayer 1, .layer_1AE9
|
chan_setlayer 1, .layer_1AE9
|
||||||
chan_setval 35
|
chan_setval 35
|
||||||
chan_call .delay
|
chan_call .delay
|
||||||
chan_setvibratoextent 0
|
chan_setvibratoextent 0xff
|
||||||
chan_end
|
chan_end
|
||||||
|
|
||||||
.layer_1AE9:
|
.layer_1AE9:
|
||||||
@@ -6055,7 +6061,7 @@ chan_setvibratorate 60
|
|||||||
chan_setlayer 0, .layer_259B
|
chan_setlayer 0, .layer_259B
|
||||||
chan_setval 30
|
chan_setval 30
|
||||||
chan_call .delay
|
chan_call .delay
|
||||||
chan_setvibratoextent 0
|
chan_setvibratoextent 0xff
|
||||||
chan_end
|
chan_end
|
||||||
|
|
||||||
.layer_259B:
|
.layer_259B:
|
||||||
@@ -6189,7 +6195,7 @@ chan_setvibratorate 5
|
|||||||
chan_setlayer 0, .layer_2684
|
chan_setlayer 0, .layer_2684
|
||||||
chan_setval 88
|
chan_setval 88
|
||||||
chan_call .delay
|
chan_call .delay
|
||||||
chan_setvibratoextent 0
|
chan_setvibratoextent 0xff
|
||||||
chan_end
|
chan_end
|
||||||
|
|
||||||
.layer_2684:
|
.layer_2684:
|
||||||
@@ -6360,7 +6366,7 @@ chan_setlayer 0, .layer_27B7
|
|||||||
chan_setlayer 1, .layer_27B5
|
chan_setlayer 1, .layer_27B5
|
||||||
chan_setval 56
|
chan_setval 56
|
||||||
chan_call .delay
|
chan_call .delay
|
||||||
chan_setvibratoextent 0
|
chan_setvibratoextent 0xff
|
||||||
chan_end
|
chan_end
|
||||||
|
|
||||||
.layer_27B5:
|
.layer_27B5:
|
||||||
@@ -7067,6 +7073,9 @@ chan_setenvelope .envelope_3444
|
|||||||
chan_setvibratorate 1
|
chan_setvibratorate 1
|
||||||
chan_setvibratoextent 100
|
chan_setvibratoextent 100
|
||||||
chan_setlayer 0, .layer_2CA0
|
chan_setlayer 0, .layer_2CA0
|
||||||
|
chan_setval 0x12
|
||||||
|
chan_call .delay
|
||||||
|
chan_setvibratoextent 0xff
|
||||||
chan_end
|
chan_end
|
||||||
|
|
||||||
.layer_2CA0:
|
.layer_2CA0:
|
||||||
@@ -7094,7 +7103,7 @@ chan_call .delay
|
|||||||
chan_setvibratoextent 80
|
chan_setvibratoextent 80
|
||||||
chan_setval 67
|
chan_setval 67
|
||||||
chan_call .delay
|
chan_call .delay
|
||||||
chan_setvibratoextent 0
|
chan_setvibratoextent 0xff
|
||||||
chan_end
|
chan_end
|
||||||
|
|
||||||
.layer_2CD6:
|
.layer_2CD6:
|
||||||
@@ -7292,6 +7301,13 @@ chan_setval 70
|
|||||||
chan_call .delay
|
chan_call .delay
|
||||||
chan_setbank 10
|
chan_setbank 10
|
||||||
chan_setinstr 8
|
chan_setinstr 8
|
||||||
|
chan_setval 0x7f
|
||||||
|
chan_call .delay
|
||||||
|
chan_setval 0x7f
|
||||||
|
chan_call .delay
|
||||||
|
chan_setval 0x4
|
||||||
|
chan_call .delay
|
||||||
|
chan_setvibratoextent 0xff
|
||||||
chan_end
|
chan_end
|
||||||
|
|
||||||
.layer_2E28:
|
.layer_2E28:
|
||||||
|
|||||||
@@ -189,23 +189,33 @@ s32 get_vibrato_pitch_change(struct VibratoState *vib) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
f32 get_vibrato_freq_scale(struct VibratoState *vib) {
|
f32 get_vibrato_freq_scale(struct VibratoState *vib) {
|
||||||
|
s32 vibratoExtentTarget;
|
||||||
|
|
||||||
if (vib->delay != 0) {
|
if (vib->delay != 0) {
|
||||||
vib->delay--;
|
vib->delay--;
|
||||||
return 1;
|
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) {
|
||||||
if (vib->extentChangeTimer == 1) {
|
if (vib->extentChangeTimer == 1) {
|
||||||
vib->extent = (s32) vib->seqChannel->vibratoExtentTarget;
|
vib->extent = vibratoExtentTarget;
|
||||||
} else {
|
} else {
|
||||||
vib->extent +=
|
vib->extent +=
|
||||||
((s32) vib->seqChannel->vibratoExtentTarget - vib->extent) / (s32) vib->extentChangeTimer;
|
(vibratoExtentTarget - vib->extent) / (s32) vib->extentChangeTimer;
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
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);
|
note->vibratoFreqScale = get_vibrato_freq_scale(¬e->vibratoState);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (note->vibratoState.active) {
|
if (note->vibratoState.activeFlags & VIBMODE_PORTAMENTO) {
|
||||||
note->portamentoFreqScale = get_portamento_freq_scale(¬e->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
|
#endif
|
||||||
}
|
}
|
||||||
@@ -265,18 +275,23 @@ void note_vibrato_init(struct Note *note) {
|
|||||||
|
|
||||||
struct VibratoState *vib = ¬e->vibratoState;
|
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 defined(VERSION_JP) || defined(VERSION_US)
|
||||||
if (note->parentLayer->seqChannel->vibratoExtentStart == 0
|
vib->activeFlags = VIBMODE_NONE;
|
||||||
&& note->parentLayer->seqChannel->vibratoExtentTarget == 0
|
if (note->parentLayer->portamento.mode != 0) {
|
||||||
&& note->parentLayer->portamento.mode == 0) {
|
vib->activeFlags |= VIBMODE_PORTAMENTO;
|
||||||
vib->active = FALSE;
|
note->portamento = note->parentLayer->portamento;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(note->parentLayer->seqChannel->vibratoExtentStart == 0
|
||||||
|
&& note->parentLayer->seqChannel->vibratoExtentTarget >= VIBRATO_DISABLED_VALUE)) {
|
||||||
|
vib->activeFlags |= VIBMODE_VIBRATO;
|
||||||
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#else
|
||||||
*/
|
|
||||||
|
|
||||||
vib->active = TRUE;
|
vib->active = TRUE;
|
||||||
|
#endif
|
||||||
|
|
||||||
vib->time = 0;
|
vib->time = 0;
|
||||||
|
|
||||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||||
@@ -313,8 +328,6 @@ void note_vibrato_init(struct Note *note) {
|
|||||||
vib->rate = seqChannel->vibratoRateStart;
|
vib->rate = seqChannel->vibratoRateStart;
|
||||||
}
|
}
|
||||||
vib->delay = seqChannel->vibratoDelay;
|
vib->delay = seqChannel->vibratoDelay;
|
||||||
|
|
||||||
note->portamento = note->parentLayer->portamento;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,12 @@ enum ADSRDelays {
|
|||||||
ADSR_RESTART = -3,
|
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
|
// Envelopes are always stored as big endian, to match sequence files which are
|
||||||
// byte blobs and can embed envelopes. Hence this byteswapping macro.
|
// byte blobs and can embed envelopes. Hence this byteswapping macro.
|
||||||
#if IS_BIG_ENDIAN
|
#if IS_BIG_ENDIAN
|
||||||
|
|||||||
@@ -27,6 +27,8 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif // EXPAND_AUDIO_HEAP
|
#endif // EXPAND_AUDIO_HEAP
|
||||||
|
|
||||||
|
#define VIBRATO_DISABLED_VALUE (0xFF * 8)
|
||||||
|
|
||||||
#define NO_LAYER ((struct SequenceChannelLayer *)(-1))
|
#define NO_LAYER ((struct SequenceChannelLayer *)(-1))
|
||||||
|
|
||||||
enum MuteBehaviors {
|
enum MuteBehaviors {
|
||||||
@@ -139,7 +141,7 @@ struct VibratoState {
|
|||||||
/* , 0x14*/ u8 active;
|
/* , 0x14*/ u8 active;
|
||||||
#else
|
#else
|
||||||
/*0x08, */ s8 *curve;
|
/*0x08, */ s8 *curve;
|
||||||
/*0x0C, */ u8 active;
|
/*0x0C, */ u8 activeFlags;
|
||||||
/*0x0E, */ u16 rate;
|
/*0x0E, */ u16 rate;
|
||||||
/*0x10, */ u16 extent;
|
/*0x10, */ u16 extent;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1423,6 +1423,7 @@ void note_init_all(void) {
|
|||||||
note->prevParentLayer = NO_LAYER;
|
note->prevParentLayer = NO_LAYER;
|
||||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||||
note->waveId = 0;
|
note->waveId = 0;
|
||||||
|
note->vibratoState.active = FALSE;
|
||||||
#else
|
#else
|
||||||
note->reverbVol = 0;
|
note->reverbVol = 0;
|
||||||
note->usesHeadsetPanEffects = FALSE;
|
note->usesHeadsetPanEffects = FALSE;
|
||||||
@@ -1432,12 +1433,12 @@ void note_init_all(void) {
|
|||||||
note->targetVolRight = 0;
|
note->targetVolRight = 0;
|
||||||
note->frequency = 0.0f;
|
note->frequency = 0.0f;
|
||||||
note->unused1 = 0x3f;
|
note->unused1 = 0x3f;
|
||||||
|
note->vibratoState.activeFlags = VIBMODE_NONE;
|
||||||
#endif
|
#endif
|
||||||
note->attributes.velocity = 0.0f;
|
note->attributes.velocity = 0.0f;
|
||||||
note->adsrVolScale = 0;
|
note->adsrVolScale = 0;
|
||||||
note->adsr.state = ADSR_STATE_DISABLED;
|
note->adsr.state = ADSR_STATE_DISABLED;
|
||||||
note->adsr.action = 0;
|
note->adsr.action = 0;
|
||||||
note->vibratoState.active = FALSE;
|
|
||||||
note->portamento.cur = 0.0f;
|
note->portamento.cur = 0.0f;
|
||||||
note->portamento.speed = 0.0f;
|
note->portamento.speed = 0.0f;
|
||||||
#if defined(VERSION_SH)
|
#if defined(VERSION_SH)
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ void sequence_channel_init(struct SequenceChannel *seqChannel) {
|
|||||||
#endif
|
#endif
|
||||||
seqChannel->vibratoRateTarget = 0x800;
|
seqChannel->vibratoRateTarget = 0x800;
|
||||||
seqChannel->vibratoRateStart = 0x800;
|
seqChannel->vibratoRateStart = 0x800;
|
||||||
seqChannel->vibratoExtentTarget = 0;
|
seqChannel->vibratoExtentTarget = VIBRATO_DISABLED_VALUE;
|
||||||
seqChannel->vibratoExtentStart = 0;
|
seqChannel->vibratoExtentStart = 0;
|
||||||
seqChannel->vibratoRateChangeDelay = 0;
|
seqChannel->vibratoRateChangeDelay = 0;
|
||||||
seqChannel->vibratoExtentChangeDelay = 0;
|
seqChannel->vibratoExtentChangeDelay = 0;
|
||||||
@@ -1942,7 +1942,7 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xec:
|
case 0xec:
|
||||||
seqChannel->vibratoExtentTarget = 0;
|
seqChannel->vibratoExtentTarget = VIBRATO_DISABLED_VALUE;
|
||||||
seqChannel->vibratoExtentStart = 0;
|
seqChannel->vibratoExtentStart = 0;
|
||||||
seqChannel->vibratoExtentChangeDelay = 0;
|
seqChannel->vibratoExtentChangeDelay = 0;
|
||||||
seqChannel->vibratoRateTarget = 0;
|
seqChannel->vibratoRateTarget = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user