diff --git a/src/main/java/sh/ball/audio/ShapeAudioPlayer.java b/src/main/java/sh/ball/audio/ShapeAudioPlayer.java index e5db2ad..4a2732d 100644 --- a/src/main/java/sh/ball/audio/ShapeAudioPlayer.java +++ b/src/main/java/sh/ball/audio/ShapeAudioPlayer.java @@ -20,6 +20,7 @@ import javax.sound.midi.ShortMessage; import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioInputStream; +import static sh.ball.gui.Gui.audioPlayer; import static sh.ball.gui.Gui.logger; public class ShapeAudioPlayer implements AudioPlayer> { @@ -418,6 +419,17 @@ public class ShapeAudioPlayer implements AudioPlayer> { effects.removeIf(e -> e.type == type); } + // selects or deselects the given audio effect + public void updateEffect(EffectType type, boolean checked, SettableEffect effect) { + if (type != null) { + if (checked) { + audioPlayer.addEffect(type, effect); + } else { + audioPlayer.removeEffect(type); + } + } + } + @Override public void read(byte[] buffer) throws InterruptedException { Listener listener = new Listener(buffer); diff --git a/src/main/java/sh/ball/gui/components/EffectComponentGroupController.java b/src/main/java/sh/ball/gui/components/EffectComponentGroupController.java index f339a00..5d8cca5 100644 --- a/src/main/java/sh/ball/gui/components/EffectComponentGroupController.java +++ b/src/main/java/sh/ball/gui/components/EffectComponentGroupController.java @@ -163,6 +163,11 @@ public class EffectComponentGroupController implements Initializable, SubControl return List.of(model.getLabel()); } + @Override + public List effects() { + return List.of(model); + } + @Override public List save(Document document) { Element checkBox = document.createElement(model.getLabel()); diff --git a/src/main/java/sh/ball/gui/controller/EffectsController.java b/src/main/java/sh/ball/gui/controller/EffectsController.java index 146e90b..15dc415 100644 --- a/src/main/java/sh/ball/gui/controller/EffectsController.java +++ b/src/main/java/sh/ball/gui/controller/EffectsController.java @@ -124,13 +124,7 @@ public class EffectsController implements Initializable, SubController { // selects or deselects the given audio effect public void updateEffect(EffectType type, boolean checked, SettableEffect effect) { - if (type != null) { - if (checked) { - audioPlayer.addEffect(type, effect); - } else { - audioPlayer.removeEffect(type); - } - } + audioPlayer.updateEffect(type, checked, effect); if (type == EffectType.DEPTH_3D) { Platform.runLater(() -> @@ -242,7 +236,8 @@ public class EffectsController implements Initializable, SubController { executor.setScript(script); } - private List effects() { + @Override + public List effects() { return List.of( vectorCancelling, bitCrush, @@ -281,8 +276,6 @@ public class EffectsController implements Initializable, SubController { @Override public List save(Document document) { - Element element = document.createElement("checkBoxes"); - effects().forEach(effect -> effect.save(document).forEach(element::appendChild)); Element translation = document.createElement("translation"); Element x = document.createElement("x"); x.appendChild(document.createTextNode(translationXTextField.getText())); @@ -296,13 +289,11 @@ public class EffectsController implements Initializable, SubController { translation.appendChild(x); translation.appendChild(y); translation.appendChild(ellipse); - return List.of(element, translation, depthFunction); + return List.of(translation, depthFunction); } @Override public void load(Element root) { - Element element = (Element) root.getElementsByTagName("checkBoxes").item(0); - effects().forEach(effect -> effect.load(element)); Element translation = (Element) root.getElementsByTagName("translation").item(0); Element x = (Element) translation.getElementsByTagName("x").item(0); Element y = (Element) translation.getElementsByTagName("y").item(0); diff --git a/src/main/java/sh/ball/gui/controller/GeneralController.java b/src/main/java/sh/ball/gui/controller/GeneralController.java index 294744e..4b22123 100644 --- a/src/main/java/sh/ball/gui/controller/GeneralController.java +++ b/src/main/java/sh/ball/gui/controller/GeneralController.java @@ -16,6 +16,7 @@ import javafx.stage.Stage; import javafx.util.Duration; import org.w3c.dom.Document; import org.w3c.dom.Element; +import sh.ball.gui.components.EffectComponentGroup; import java.io.File; import java.io.IOException; @@ -292,6 +293,11 @@ public class GeneralController implements Initializable, SubController { return List.of("octave", "micVolume"); } + @Override + public List effects() { + return List.of(); + } + @Override public List save(Document document) { Element element = document.createElement("general"); diff --git a/src/main/java/sh/ball/gui/controller/ImageController.java b/src/main/java/sh/ball/gui/controller/ImageController.java index 891e846..3e1f5d2 100644 --- a/src/main/java/sh/ball/gui/controller/ImageController.java +++ b/src/main/java/sh/ball/gui/controller/ImageController.java @@ -8,6 +8,7 @@ import javafx.scene.shape.SVGPath; import org.w3c.dom.Document; import org.w3c.dom.Element; import sh.ball.audio.midi.MidiNote; +import sh.ball.gui.components.EffectComponentGroup; import java.net.URL; import java.util.List; @@ -72,6 +73,11 @@ public class ImageController implements Initializable, SubController { return List.of("frequency"); } + @Override + public List effects() { + return List.of(); + } + @Override public List save(Document document) { return List.of(document.createElement("null")); diff --git a/src/main/java/sh/ball/gui/controller/LuaController.java b/src/main/java/sh/ball/gui/controller/LuaController.java index 86c69d8..be4da29 100644 --- a/src/main/java/sh/ball/gui/controller/LuaController.java +++ b/src/main/java/sh/ball/gui/controller/LuaController.java @@ -37,7 +37,8 @@ public class LuaController implements Initializable, SubController { this.mainController = mainController; } - private List effects() { + @Override + public List effects() { return List.of(luaA, luaB, luaC, luaD, luaE); } @@ -54,7 +55,7 @@ public class LuaController implements Initializable, SubController { effect.setAnimator(new EffectAnimator(EffectAnimator.DEFAULT_SAMPLE_RATE, new ConsumerEffect(value -> updateLuaVariable(effect.getId(), value)))) ); - effects().forEach(effect -> effect.setEffectUpdater(this::updateEffect)); + effects().forEach(effect -> effect.setEffectUpdater(audioPlayer::updateEffect)); resetStepCounterButton.setOnAction(e -> mainController.resetLuaStep()); } @@ -86,34 +87,14 @@ public class LuaController implements Initializable, SubController { @Override public List save(Document document) { - Element element = document.createElement("luaController"); - effects().forEach(effect -> effect.save(document).forEach(element::appendChild)); - return List.of(element); + return List.of(document.createElement("null")); } @Override - public void load(Element root) { - Element element = (Element) root.getElementsByTagName("luaController").item(0); - if (element != null) { - effects().forEach(effect -> effect.load(element)); - } else { - effects().forEach(effect -> effect.setAnimationType(AnimationType.STATIC)); - } - } + public void load(Element root) {} @Override public void micNotAvailable() { effects().forEach(EffectComponentGroup::micNotAvailable); } - - // selects or deselects the given audio effect - public void updateEffect(EffectType type, boolean checked, SettableEffect effect) { - if (type != null) { - if (checked) { - audioPlayer.addEffect(type, effect); - } else { - audioPlayer.removeEffect(type); - } - } - } } diff --git a/src/main/java/sh/ball/gui/controller/MainController.java b/src/main/java/sh/ball/gui/controller/MainController.java index 0c3d973..3004928 100644 --- a/src/main/java/sh/ball/gui/controller/MainController.java +++ b/src/main/java/sh/ball/gui/controller/MainController.java @@ -48,12 +48,14 @@ import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; +import sh.ball.audio.effect.AnimationType; import sh.ball.audio.engine.*; import sh.ball.audio.midi.MidiListener; import sh.ball.audio.midi.MidiNote; import sh.ball.engine.ObjectServer; import sh.ball.engine.ObjectSet; import sh.ball.gui.Gui; +import sh.ball.gui.components.EffectComponentGroup; import sh.ball.oscilloscope.ByteWebSocketServer; import sh.ball.parser.FileParser; import sh.ball.parser.lua.LuaParser; @@ -1017,6 +1019,11 @@ public class MainController implements Initializable, FrequencyListener, MidiLis sliders.add(brightnessSlider); return sliders; } + + private List effects() { + return subControllers().stream().map(SubController::effects).flatMap(Collection::stream).toList(); + } + private List labels() { List labels = new ArrayList<>(); subControllers().forEach(controller -> labels.addAll(controller.labels())); @@ -1131,6 +1138,9 @@ public class MainController implements Initializable, FrequencyListener, MidiLis subControllers().forEach(controller -> controller.save(document).forEach(root::appendChild)); + Element element = document.createElement("checkBoxes"); + effects().forEach(effect -> effect.save(document).forEach(element::appendChild)); + Element flipX = document.createElement("flipX"); Element flipY = document.createElement("flipY"); flipX.appendChild(document.createTextNode(String.valueOf(flipXCheckMenuItem.isSelected()))); @@ -1267,6 +1277,13 @@ public class MainController implements Initializable, FrequencyListener, MidiLis subControllers().forEach(controller -> controller.load(root)); + Element element = (Element) root.getElementsByTagName("checkBoxes").item(0); + if (element != null) { + effects().forEach(effect -> effect.load(element)); + } else { + effects().forEach(effect -> effect.setAnimationType(AnimationType.STATIC)); + } + Element flipX = (Element) root.getElementsByTagName("flipX").item(0); Element flipY = (Element) root.getElementsByTagName("flipY").item(0); if (flipX != null) { diff --git a/src/main/java/sh/ball/gui/controller/ObjController.java b/src/main/java/sh/ball/gui/controller/ObjController.java index 464f3ac..2321a9a 100644 --- a/src/main/java/sh/ball/gui/controller/ObjController.java +++ b/src/main/java/sh/ball/gui/controller/ObjController.java @@ -44,14 +44,10 @@ public class ObjController implements Initializable, SubController { @FXML private Button resetObjectRotationButton; - private List effectComponentGroups() { - return List.of(focalLength, rotateX, rotateY, rotateZ, rotateSpeed); - } - @Override public Map getMidiButtonMap() { Map map = new HashMap<>(); - effectComponentGroups().forEach(ecg -> map.putAll(ecg.getMidiButtonMap())); + effects().forEach(effect -> map.putAll(effect.getMidiButtonMap())); return map; } @@ -151,55 +147,40 @@ public class ObjController implements Initializable, SubController { rotateZ.setAnimator(new EffectAnimator(DEFAULT_SAMPLE_RATE, new ConsumerEffect(this::setObjRotateZ))); rotateSpeed.setAnimator(new EffectAnimator(DEFAULT_SAMPLE_RATE, new ConsumerEffect(this::setObjectRotateSpeed))); - effectComponentGroups().forEach(effect -> effect.setEffectUpdater(this::updateEffect)); - } - - // selects or deselects the given audio effect - public void updateEffect(EffectType type, boolean checked, SettableEffect effect) { - if (type != null) { - if (checked) { - audioPlayer.addEffect(type, effect); - } else { - audioPlayer.removeEffect(type); - } - } + effects().forEach(effect -> effect.setEffectUpdater(audioPlayer::updateEffect)); } @Override public List micSelected() { - return effectComponentGroups().stream().map(EffectComponentGroup::isMicSelectedProperty).toList(); + return effects().stream().map(EffectComponentGroup::isMicSelectedProperty).toList(); } @Override public List sliders() { - return effectComponentGroups().stream().map(EffectComponentGroup::sliders).flatMap(List::stream).toList(); + return effects().stream().map(EffectComponentGroup::sliders).flatMap(List::stream).toList(); } @Override public List labels() { - return effectComponentGroups().stream().map(EffectComponentGroup::getLabel).toList(); + return effects().stream().map(EffectComponentGroup::getLabel).toList(); + } + + @Override + public List effects() { + return List.of(focalLength, rotateX, rotateY, rotateZ, rotateSpeed); } @Override public List save(Document document) { - Element element = document.createElement("objController"); - effectComponentGroups().forEach(effect -> effect.save(document).forEach(element::appendChild)); - return List.of(element); + return List.of(document.createElement("null")); } @Override - public void load(Element root) { - Element element = (Element) root.getElementsByTagName("objController").item(0); - if (element != null) { - effectComponentGroups().forEach(effect -> effect.load(element)); - } else { - effectComponentGroups().forEach(effect -> effect.setAnimationType(AnimationType.STATIC)); - } - } + public void load(Element root) {} @Override public void micNotAvailable() { - effectComponentGroups().forEach(EffectComponentGroup::micNotAvailable); + effects().forEach(EffectComponentGroup::micNotAvailable); } public void renderUsingGpu(boolean usingGpu) { diff --git a/src/main/java/sh/ball/gui/controller/SubController.java b/src/main/java/sh/ball/gui/controller/SubController.java index 389a297..a4a2122 100644 --- a/src/main/java/sh/ball/gui/controller/SubController.java +++ b/src/main/java/sh/ball/gui/controller/SubController.java @@ -6,6 +6,7 @@ import javafx.scene.shape.SVGPath; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; +import sh.ball.gui.components.EffectComponentGroup; import java.util.List; import java.util.Map; @@ -20,6 +21,8 @@ public interface SubController { List labels(); + List effects(); + List save(Document document); void load(Element root);