diff --git a/src/main/java/sh/ball/audio/effect/RotateEffect.java b/src/main/java/sh/ball/audio/effect/RotateEffect.java index d3c3ef79..2f99f472 100644 --- a/src/main/java/sh/ball/audio/effect/RotateEffect.java +++ b/src/main/java/sh/ball/audio/effect/RotateEffect.java @@ -3,7 +3,7 @@ package sh.ball.audio.effect; import sh.ball.shapes.Vector2; // rotates the vector about (0,0) -public class RotateEffect extends PhaseEffect { +public class RotateEffect extends PhaseEffect implements SettableEffect { public RotateEffect(int sampleRate, double speed) { super(sampleRate, speed); @@ -17,4 +17,9 @@ public class RotateEffect extends PhaseEffect { public Vector2 apply(int count, Vector2 vector) { return vector.rotate(nextTheta()); } + + @Override + public void setValue(double value) { + setSpeed(value); + } } diff --git a/src/main/java/sh/ball/audio/effect/TranslateEffect.java b/src/main/java/sh/ball/audio/effect/TranslateEffect.java index 82d09bf1..df831564 100644 --- a/src/main/java/sh/ball/audio/effect/TranslateEffect.java +++ b/src/main/java/sh/ball/audio/effect/TranslateEffect.java @@ -4,7 +4,7 @@ import sh.ball.shapes.Vector2; // Translates the given vector in a sinusoidal fashion if ellipse is true, // otherwise applies a constant translation -public class TranslateEffect extends PhaseEffect { +public class TranslateEffect extends PhaseEffect implements SettableEffect { private Vector2 translation; private boolean ellipse = false; @@ -43,4 +43,9 @@ public class TranslateEffect extends PhaseEffect { public void setScale(double scale) { this.scale = scale; } + + @Override + public void setValue(double value) { + setScale(value); + } } diff --git a/src/main/java/sh/ball/gui/components/EffectComponentGroup.java b/src/main/java/sh/ball/gui/components/EffectComponentGroup.java index 93e16cf1..94d43c7d 100644 --- a/src/main/java/sh/ball/gui/components/EffectComponentGroup.java +++ b/src/main/java/sh/ball/gui/components/EffectComponentGroup.java @@ -48,6 +48,11 @@ public class EffectComponentGroup extends HBox { return controller.effectCheckBox.getText(); } + public void removeCheckBox() { + controller.effectCheckBox.setSelected(true); + controller.effectCheckBox.setVisible(false); + } + public void setType(EffectType type) { controller.setType(type); } @@ -110,4 +115,12 @@ public class EffectComponentGroup extends HBox { public double getIncrement() { return controller.getIncrement(); } + + public void setMajorTickUnit(double tickUnit) { + controller.setMajorTickUnit(tickUnit); + } + + public double getMajorTickUnit() { + return controller.getMajorTickUnit(); + } } diff --git a/src/main/java/sh/ball/gui/components/EffectComponentGroupController.java b/src/main/java/sh/ball/gui/components/EffectComponentGroupController.java index d2af15f9..3891ee27 100644 --- a/src/main/java/sh/ball/gui/components/EffectComponentGroupController.java +++ b/src/main/java/sh/ball/gui/components/EffectComponentGroupController.java @@ -208,4 +208,12 @@ public class EffectComponentGroupController implements Initializable, SubControl public double getIncrement() { return increment; } + + public void setMajorTickUnit(double tickUnit) { + slider.setMajorTickUnit(tickUnit); + } + + public double getMajorTickUnit() { + return slider.getMajorTickUnit(); + } } diff --git a/src/main/java/sh/ball/gui/controller/EffectsController.java b/src/main/java/sh/ball/gui/controller/EffectsController.java index e591c51d..36f2f4bc 100644 --- a/src/main/java/sh/ball/gui/controller/EffectsController.java +++ b/src/main/java/sh/ball/gui/controller/EffectsController.java @@ -19,6 +19,7 @@ import sh.ball.audio.effect.*; import sh.ball.audio.engine.AudioDevice; import sh.ball.gui.components.EffectComponentGroup; import sh.ball.shapes.Shape; +import sh.ball.shapes.Vector2; import java.net.URL; import java.util.*; @@ -31,10 +32,10 @@ public class EffectsController implements Initializable, SubController { private static final int DEFAULT_SAMPLE_RATE = 192000; - private Map effectTypes; - private final WobbleEffect wobbleEffect; private final PerspectiveEffect perspectiveEffect; + private final TranslateEffect translateEffect; + private final RotateEffect rotateEffect; @FXML private EffectComponentGroup vectorCancelling; @@ -54,10 +55,22 @@ public class EffectsController implements Initializable, SubController { private EffectComponentGroup traceMin; @FXML private EffectComponentGroup perspective; + @FXML + private EffectComponentGroup translationScale; + @FXML + private EffectComponentGroup translationSpeed; + @FXML + private EffectComponentGroup rotateSpeed; + @FXML + private EffectComponentGroup volume; + @FXML + private EffectComponentGroup backingMidi; public EffectsController() { this.wobbleEffect = new WobbleEffect(DEFAULT_SAMPLE_RATE); this.perspectiveEffect = new PerspectiveEffect(DEFAULT_SAMPLE_RATE); + this.translateEffect = new TranslateEffect(DEFAULT_SAMPLE_RATE, 1, new Vector2()); + this.rotateEffect = new RotateEffect(DEFAULT_SAMPLE_RATE); } private Map mergeEffectMaps(Function> map) { @@ -77,18 +90,14 @@ public class EffectsController implements Initializable, SubController { return mergeEffectMaps(effect -> effect.controller.getComboBoxAnimatorMap()); } - // Maps EffectTypes to the slider that controls the effect so that they can be - // toggled when the appropriate checkbox is ticked. - private void initializeEffectTypes() { - effectTypes = mergeEffectMaps(effect -> effect.controller.getEffectSliderMap()); - } - // selects or deselects the given audio effect public void updateEffect(EffectType type, boolean checked, SettableEffect effect, double value) { - if (checked) { - audioPlayer.addEffect(type, effect); - } else { - audioPlayer.removeEffect(type); + if (type != null) { + if (checked) { + audioPlayer.addEffect(type, effect); + } else { + audioPlayer.removeEffect(type); + } } } @@ -120,8 +129,6 @@ public class EffectsController implements Initializable, SubController { @Override public void initialize(URL url, ResourceBundle resourceBundle) { - initializeEffectTypes(); - wobble.controller.setAnimator(new EffectAnimator(DEFAULT_SAMPLE_RATE, wobbleEffect)); perspective.controller.setAnimator(new EffectAnimator(DEFAULT_SAMPLE_RATE, perspectiveEffect)); traceMin.controller.setAnimator(new EffectAnimator(DEFAULT_SAMPLE_RATE, new ConsumerEffect(audioPlayer::setTraceMin))); @@ -131,30 +138,56 @@ public class EffectsController implements Initializable, SubController { smoothing.controller.setAnimator(new EffectAnimator(DEFAULT_SAMPLE_RATE, new SmoothEffect(1))); verticalDistort.controller.setAnimator(new EffectAnimator(DEFAULT_SAMPLE_RATE, new VerticalDistortEffect(0.2))); horizontalDistort.controller.setAnimator(new EffectAnimator(DEFAULT_SAMPLE_RATE, new HorizontalDistortEffect(0.2))); + translationScale.controller.setAnimator(new EffectAnimator(DEFAULT_SAMPLE_RATE, translateEffect)); + translationSpeed.controller.setAnimator(new EffectAnimator(DEFAULT_SAMPLE_RATE, new ConsumerEffect(translateEffect::setSpeed))); + rotateSpeed.controller.setAnimator(new EffectAnimator(DEFAULT_SAMPLE_RATE, rotateEffect)); + volume.controller.setAnimator(new EffectAnimator(DEFAULT_SAMPLE_RATE, new ConsumerEffect((value) -> audioPlayer.setVolume(value / 3.0)))); + backingMidi.controller.setAnimator(new EffectAnimator(DEFAULT_SAMPLE_RATE, new ConsumerEffect(audioPlayer::setBackingMidiVolume))); effects().forEach(effect -> { effect.controller.setEffectUpdater(this::updateEffect); - // specific functionality for some effects - switch (effect.getType()) { - case WOBBLE -> effect.controller.onToggle((animator, value, selected) -> wobbleEffect.update()); - case TRACE_MIN, TRACE_MAX -> effect.controller.onToggle((animator, value, selected) -> { - if (selected) { - animator.setValue(value); - } else if (effect.getType().equals(EffectType.TRACE_MAX)) { - animator.setValue(1.0); - } else { - animator.setValue(0.0); - } - }); + if (effect.getType() != null) { + // specific functionality for some effects + switch (effect.getType()) { + case WOBBLE -> effect.controller.onToggle((animator, value, selected) -> wobbleEffect.update()); + case TRACE_MIN, TRACE_MAX -> effect.controller.onToggle((animator, value, selected) -> { + if (selected) { + animator.setValue(value); + } else if (effect.getType().equals(EffectType.TRACE_MAX)) { + animator.setValue(1.0); + } else { + animator.setValue(0.0); + } + }); + } } effect.controller.lateInitialize(); + + if (effect.getType() == null) { + effect.removeCheckBox(); + } }); } private List effects() { - return List.of(vectorCancelling, bitCrush, verticalDistort, horizontalDistort, wobble, smoothing, traceMin, traceMax, perspective); + return List.of( + vectorCancelling, + bitCrush, + verticalDistort, + horizontalDistort, + wobble, + smoothing, + traceMin, + traceMax, + perspective, + translationScale, + translationSpeed, + rotateSpeed, + volume, + backingMidi + ); } @Override diff --git a/src/main/resources/fxml/effects.fxml b/src/main/resources/fxml/effects.fxml index 37b94167..3f96c034 100644 --- a/src/main/resources/fxml/effects.fxml +++ b/src/main/resources/fxml/effects.fxml @@ -6,22 +6,26 @@ - - + - + - - - - - - - - - + + + + + + + + + + + + + + diff --git a/src/main/resources/fxml/lua.fxml b/src/main/resources/fxml/lua.fxml index 369ead6c..8dc32241 100644 --- a/src/main/resources/fxml/lua.fxml +++ b/src/main/resources/fxml/lua.fxml @@ -7,26 +7,26 @@ - - -