Add time-varying pitch modulation and built-in procedural glitch effects
This commit is contained in:
@@ -3,6 +3,7 @@ package com.example.soundmod.client.screen;
|
||||
import com.example.soundmod.client.audio.AudioPlaybackService;
|
||||
import com.example.soundmod.common.ActivationMode;
|
||||
import com.example.soundmod.common.AttenuationMode;
|
||||
import com.example.soundmod.common.PitchModulationMode;
|
||||
import com.example.soundmod.common.RedstoneMode;
|
||||
import com.example.soundmod.common.ScenarioQueue;
|
||||
import com.example.soundmod.common.SoundManifestEntry;
|
||||
@@ -111,6 +112,9 @@ public class SoundPlayerScreen extends ContainerScreen<SoundPlayerContainer> {
|
||||
private Button crossfadeButton;
|
||||
private TextFieldWidget fadeInField;
|
||||
private TextFieldWidget fadeOutField;
|
||||
private Button pitchModeButton;
|
||||
private TextFieldWidget pitchModSpeedField;
|
||||
private TextFieldWidget pitchModDepthField;
|
||||
|
||||
// Controls - Trigger
|
||||
private Button activationModeButton;
|
||||
@@ -349,6 +353,14 @@ public class SoundPlayerScreen extends ContainerScreen<SoundPlayerContainer> {
|
||||
this.fadeInField = this.createField(x + 88, y + 147, 44, Integer.toString(this.localSettings.fadeInTicks));
|
||||
this.fadeOutField = this.createField(x + 226, y + 147, 44, Integer.toString(this.localSettings.fadeOutTicks));
|
||||
|
||||
this.pitchModeButton = this.addButtonTracked(new Button(x, y + 172, 114, 20, new StringTextComponent("Pitch: " + this.localSettings.pitchMode.getDisplayName()), b -> {
|
||||
this.localSettings.pitchMode = this.cyclePitchMode(this.localSettings.pitchMode);
|
||||
b.setMessage(new StringTextComponent("Pitch: " + this.localSettings.pitchMode.getDisplayName()));
|
||||
this.sendLiveApply("pitchMode");
|
||||
}), this.effectsButtons);
|
||||
this.pitchModSpeedField = this.createField(x + 152, y + 173, 34, this.floatText(this.localSettings.pitchModSpeed, 1));
|
||||
this.pitchModDepthField = this.createField(x + 228, y + 173, 34, this.floatText(this.localSettings.pitchModDepth, 2));
|
||||
|
||||
// --- TAB 3: TRIGGER ---
|
||||
this.activationModeButton = this.addButtonTracked(new Button(x, y + 42, 128, 20, new StringTextComponent("Режим: " + this.modeRu(this.localSettings.activationMode)), b -> {
|
||||
this.localSettings.activationMode = this.cycleMode(this.localSettings.activationMode);
|
||||
@@ -478,6 +490,8 @@ public class SoundPlayerScreen extends ContainerScreen<SoundPlayerContainer> {
|
||||
this.addFieldTracked(this.reverbStrengthField, this.effectsFields);
|
||||
this.addFieldTracked(this.fadeInField, this.effectsFields);
|
||||
this.addFieldTracked(this.fadeOutField, this.effectsFields);
|
||||
this.addFieldTracked(this.pitchModSpeedField, this.effectsFields);
|
||||
this.addFieldTracked(this.pitchModDepthField, this.effectsFields);
|
||||
|
||||
this.addFieldTracked(this.startDelayField, this.triggerFields);
|
||||
this.addFieldTracked(this.repeatDelayField, this.triggerFields);
|
||||
@@ -741,6 +755,8 @@ public class SoundPlayerScreen extends ContainerScreen<SoundPlayerContainer> {
|
||||
if (this.reverbStrengthField != null) this.localSettings.reverbStrength = this.clampFloat(this.parseFloat(this.reverbStrengthField.getValue(), 0.35f), 0.0f, 1.0f);
|
||||
if (this.fadeInField != null) this.localSettings.fadeInTicks = this.clampInt(this.parseInt(this.fadeInField.getValue(), 0), 0, 72000);
|
||||
if (this.fadeOutField != null) this.localSettings.fadeOutTicks = this.clampInt(this.parseInt(this.fadeOutField.getValue(), 0), 0, 72000);
|
||||
if (this.pitchModSpeedField != null) this.localSettings.pitchModSpeed = this.clampFloat(this.parseFloat(this.pitchModSpeedField.getValue(), 1.0f), 0.05f, 20.0f);
|
||||
if (this.pitchModDepthField != null) this.localSettings.pitchModDepth = this.clampFloat(this.parseFloat(this.pitchModDepthField.getValue(), 0.25f), 0.0f, 2.0f);
|
||||
|
||||
if (this.startDelayField != null) this.localSettings.startDelayTicks = this.clampInt(this.parseInt(this.startDelayField.getValue(), 0), 0, 72000);
|
||||
if (this.repeatDelayField != null) this.localSettings.repeatDelayTicks = this.clampInt(this.parseInt(this.repeatDelayField.getValue(), 0), 0, 72000);
|
||||
@@ -792,6 +808,15 @@ public class SoundPlayerScreen extends ContainerScreen<SoundPlayerContainer> {
|
||||
this.zoneStopOnExitButton.setMessage(this.boolLabel("Стоп-выход", this.zoneStopOnExit));
|
||||
this.zoneUseCustomCoordsButton.setMessage(this.boolLabel("Смещение центра", this.zoneUseCustomCoords));
|
||||
this.scenarioLoopButton.setMessage(this.boolLabel("Цикл", this.activeScenarioLoop()));
|
||||
if (this.pitchModSpeedField != null) {
|
||||
this.pitchModSpeedField.setValue(this.floatText(this.localSettings.pitchModSpeed, 1));
|
||||
}
|
||||
if (this.pitchModDepthField != null) {
|
||||
this.pitchModDepthField.setValue(this.floatText(this.localSettings.pitchModDepth, 2));
|
||||
}
|
||||
if (this.pitchModeButton != null) {
|
||||
this.pitchModeButton.setMessage(new StringTextComponent("Pitch: " + this.localSettings.pitchMode.getDisplayName()));
|
||||
}
|
||||
if (this.scenarioShuffleButton != null) {
|
||||
this.scenarioShuffleButton.setMessage(this.boolLabel("Случайно", this.activeScenarioShuffle()));
|
||||
}
|
||||
@@ -801,6 +826,12 @@ public class SoundPlayerScreen extends ContainerScreen<SoundPlayerContainer> {
|
||||
this.updateTabVisibility();
|
||||
}
|
||||
|
||||
private PitchModulationMode cyclePitchMode(PitchModulationMode current) {
|
||||
PitchModulationMode[] values = PitchModulationMode.values();
|
||||
int next = (current.ordinal() + 1) % values.length;
|
||||
return values[next];
|
||||
}
|
||||
|
||||
private void addScenarioStep() {
|
||||
String sid = this.scenarioSoundField.getValue().trim();
|
||||
if (sid.isEmpty()) {
|
||||
@@ -1113,7 +1144,9 @@ public class SoundPlayerScreen extends ContainerScreen<SoundPlayerContainer> {
|
||||
this.font.draw(matrixStack, new StringTextComponent("Сила:"), (float) (x + 176), (float) (y + 99), COLOR_TEXT_LABEL);
|
||||
this.font.draw(matrixStack, new StringTextComponent("Fade In:"), (float) x, (float) (y + 151), COLOR_TEXT_LABEL);
|
||||
this.font.draw(matrixStack, new StringTextComponent("Fade Out:"), (float) (x + 148), (float) (y + 151), COLOR_TEXT_LABEL);
|
||||
this.font.draw(matrixStack, new StringTextComponent("⚡ Изменения применяются мгновенно во время звука"), (float) x, (float) (y + 176), COLOR_TEXT_MUTED);
|
||||
this.font.draw(matrixStack, new StringTextComponent("Скор:"), (float) (x + 118), (float) (y + 177), COLOR_TEXT_LABEL);
|
||||
this.font.draw(matrixStack, new StringTextComponent("Глуб:"), (float) (x + 192), (float) (y + 177), COLOR_TEXT_LABEL);
|
||||
this.font.draw(matrixStack, new StringTextComponent("⚡ Изменения применяются на лету во время звука"), (float) x, (float) (y + 195), COLOR_TEXT_MUTED);
|
||||
break;
|
||||
|
||||
case TRIGGER:
|
||||
@@ -1321,6 +1354,7 @@ public class SoundPlayerScreen extends ContainerScreen<SoundPlayerContainer> {
|
||||
lines.add("• ▶ Тест: мгновенное предпрослушивание выбранного звука.");
|
||||
lines.add("• 2x клик по списку: запускает предпрослушивание трека.");
|
||||
lines.add("• Эффекты: 3D звук, приглушение за стенами (окклюзия), эхо.");
|
||||
lines.add("• Модуляция Pitch: вибрато, глитч, tape stop (замедление), разгон.");
|
||||
lines.add("• Триггер: настройка запуска редстоуном, кликом или таймером.");
|
||||
lines.add("• Зона: музыка включается при входе в зону и гаснет при выходе.");
|
||||
lines.add("• Вид зоны: отображает 3D границы зоны прямо в игровом мире.");
|
||||
@@ -1467,6 +1501,8 @@ public class SoundPlayerScreen extends ContainerScreen<SoundPlayerContainer> {
|
||||
this.renderTooltip(matrixStack, new StringTextComponent("Вставить текущие координаты игрока как центр звука"), mouseX, mouseY);
|
||||
} else if (this.zoneVisualizerButton != null && this.zoneVisualizerButton.isHovered()) {
|
||||
this.renderTooltip(matrixStack, new StringTextComponent("Отображать 3D границы зоны в игровом мире"), mouseX, mouseY);
|
||||
} else if (this.pitchModeButton != null && this.pitchModeButton.isHovered()) {
|
||||
this.renderTooltip(matrixStack, new StringTextComponent("Динамическое изменение тона звука во времени (Вибрато, Глитч, Tape Stop и др.)"), mouseX, mouseY);
|
||||
} else if (this.copyConfigButton != null && this.copyConfigButton.isHovered()) {
|
||||
this.renderTooltip(matrixStack, new StringTextComponent("Скопировать все настройки блока в буфер обмена"), mouseX, mouseY);
|
||||
} else if (this.pasteConfigButton != null && this.pasteConfigButton.isHovered()) {
|
||||
|
||||
Reference in New Issue
Block a user