Add time-varying pitch modulation and built-in procedural glitch effects
This commit is contained in:
@@ -23,6 +23,7 @@ package com.example.soundmod.client.audio;
|
||||
|
||||
import com.example.soundmod.SoundMod;
|
||||
import com.example.soundmod.common.AttenuationMode;
|
||||
import com.example.soundmod.common.PitchModulationMode;
|
||||
import com.example.soundmod.common.SoundSettings;
|
||||
import com.example.soundmod.core.ModConfig;
|
||||
import com.example.soundmod.core.SoundDebug;
|
||||
@@ -235,6 +236,7 @@ public final class AudioPlaybackService {
|
||||
dominantCategory = src.settings.category;
|
||||
}
|
||||
for (PlayingSource src : this.active.values()) {
|
||||
src.elapsedTicks++;
|
||||
int state = AL10.alGetSourcei((int)src.source, (int)4112);
|
||||
if (SoundDebug.enabled(SoundDebug.Level.L3)) {
|
||||
SoundDebug.log(SoundDebug.Level.L3, "PLAYBACK", src.sourceId, "tick state={} gainTarget={}", state, Float.valueOf(src.targetGain));
|
||||
@@ -250,6 +252,7 @@ public final class AudioPlaybackService {
|
||||
gain = this.applyPriorityDucking(src, gain, topPriority, dominantCategory);
|
||||
AL10.alSourcef((int)src.source, (int)4106, (float)Math.max(0.0f, gain));
|
||||
float pitch = src.settings.pitch;
|
||||
pitch *= this.computePitchModulation(src);
|
||||
if (src.settings.occlusion && src.settings.use3d && occlusionFactor < 0.999f && !"voice".equals(src.settings.category)) {
|
||||
pitch *= Math.max(0.9f, 1.0f - src.settings.occlusionStrength * 0.12f);
|
||||
}
|
||||
@@ -261,16 +264,69 @@ public final class AudioPlaybackService {
|
||||
float dopplerPitch = (float)Math.max(0.75, Math.min(1.25, 1.0 + radial * 0.04));
|
||||
pitch *= dopplerPitch;
|
||||
}
|
||||
pitch = Math.max(0.05f, Math.min(4.0f, pitch));
|
||||
AL10.alSourcef((int)src.source, (int)4099, (float)pitch);
|
||||
if (src.reverbSource <= 0) continue;
|
||||
float wetGain = Math.max(0.0f, gain * src.settings.reverbStrength * 0.45f);
|
||||
AL10.alSourcef((int)src.reverbSource, (int)4106, (float)wetGain);
|
||||
AL10.alSourcef((int)src.reverbSource, (int)4099, (float)Math.max(0.05f, Math.min(4.0f, pitch * 0.97f)));
|
||||
}
|
||||
for (String id : remove) {
|
||||
this.stop(id);
|
||||
}
|
||||
}
|
||||
|
||||
private float computePitchModulation(PlayingSource src) {
|
||||
if (src.settings.pitchMode == null || src.settings.pitchMode == PitchModulationMode.STATIC) {
|
||||
return 1.0f;
|
||||
}
|
||||
float speed = Math.max(0.05f, src.settings.pitchModSpeed);
|
||||
float depth = Math.max(0.0f, src.settings.pitchModDepth);
|
||||
float t = (float) src.elapsedTicks / 20.0f;
|
||||
|
||||
switch (src.settings.pitchMode) {
|
||||
case VIBRATO: {
|
||||
float freq = speed * 5.0f;
|
||||
return 1.0f + (float) Math.sin(t * freq * (2.0 * Math.PI)) * (depth * 0.4f);
|
||||
}
|
||||
case GLITCH: {
|
||||
int stepTicks = Math.max(1, (int)(8.0f / speed));
|
||||
int step = src.elapsedTicks / stepTicks;
|
||||
int hash = (step * 0x1f1f1f1f) ^ (src.sourceId.hashCode() * 31);
|
||||
int choice = Math.abs(hash) % 7;
|
||||
float glitchFactor = 1.0f;
|
||||
switch (choice) {
|
||||
case 0: glitchFactor = 0.5f; break;
|
||||
case 1: glitchFactor = 0.75f; break;
|
||||
case 2: glitchFactor = 1.25f; break;
|
||||
case 3: glitchFactor = 1.5f; break;
|
||||
case 4: glitchFactor = 2.0f; break;
|
||||
case 5: glitchFactor = 0.9f; break;
|
||||
case 6: glitchFactor = 1.15f; break;
|
||||
}
|
||||
return 1.0f + (glitchFactor - 1.0f) * Math.min(1.5f, depth);
|
||||
}
|
||||
case TAPE_STOP: {
|
||||
float progress = Math.min(1.0f, t * speed * 0.2f);
|
||||
float decay = (1.0f - progress);
|
||||
float factor = 1.0f - (1.0f - decay * decay) * Math.min(1.0f, depth);
|
||||
return Math.max(0.1f, factor);
|
||||
}
|
||||
case RAMP_UP: {
|
||||
float progress = t * speed * 0.25f;
|
||||
return Math.min(4.0f, 1.0f + progress * depth);
|
||||
}
|
||||
case RANDOM_JITTER: {
|
||||
float wow = (float) Math.sin(t * speed * 1.8f * Math.PI) * 0.5f;
|
||||
int noiseHash = (src.elapsedTicks * 1103515245 + 12345);
|
||||
float flutter = (((noiseHash >> 16) & 0x7fff) / 32767.0f - 0.5f);
|
||||
return 1.0f + (wow * 0.7f + flutter * 0.3f) * (depth * 0.25f);
|
||||
}
|
||||
default:
|
||||
return 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
private float applyFades(PlayingSource src, float gain) {
|
||||
if (src.fadeInTicks > 0) {
|
||||
int elapsed = src.settings.fadeInTicks - src.fadeInTicks;
|
||||
@@ -596,6 +652,7 @@ public final class AudioPlaybackService {
|
||||
int fadeInTicks;
|
||||
int fadeOutTicks;
|
||||
int reverbSource;
|
||||
int elapsedTicks;
|
||||
long lastLiveUpdateTick = Long.MIN_VALUE;
|
||||
|
||||
PlayingSource(String sourceId, int source, int buffer, BlockPos pos, SoundSettings settings, long startedAtTick) {
|
||||
|
||||
Reference in New Issue
Block a user