Move effects section to separate FXML and add additional Java audio devices

pull/46/head
James Ball 2021-12-24 16:53:51 +00:00 zatwierdzone przez James H Ball
rodzic 4a6dd66cb0
commit e2b6a1e9ee
6 zmienionych plików z 276 dodań i 199 usunięć

Wyświetl plik

@ -21,7 +21,7 @@ public class ConglomerateAudioEngine implements AudioEngine {
// TODO: Try and make non-static
private static List<AudioDevice> xtDevices;
private static AudioDevice javaDevice;
private static List<AudioDevice> javaDevices;
private boolean playing = false;
private AudioDevice device;
@ -38,7 +38,7 @@ public class ConglomerateAudioEngine implements AudioEngine {
if (xtDevices.contains(device)) {
xtEngine.play(channelGenerator, device);
} else {
javaEngine.play(channelGenerator, javaDevice);
javaEngine.play(channelGenerator, device);
}
playing = false;
this.device = null;
@ -54,8 +54,8 @@ public class ConglomerateAudioEngine implements AudioEngine {
public List<AudioDevice> devices() {
List<AudioDevice> devices = new ArrayList<>();
if (javaDevice == null) {
javaDevice = javaEngine.getDefaultDevice();
if (javaDevices == null) {
javaDevices = javaEngine.devices();
}
if (xtDevices == null) {
@ -67,7 +67,7 @@ public class ConglomerateAudioEngine implements AudioEngine {
}
}
devices.add(javaDevice);
devices.addAll(javaDevices);
devices.addAll(xtDevices);
return devices;

Wyświetl plik

@ -2,11 +2,11 @@ package sh.ball.audio.engine;
import sh.ball.shapes.Vector2;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.*;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.stream.Stream;
public class JavaAudioEngine implements AudioEngine {
@ -88,7 +88,8 @@ public class JavaAudioEngine implements AudioEngine {
@Override
public List<AudioDevice> devices() {
return List.of(getDefaultDevice());
return Stream.of(44100, 48000, 96000, 192000).map(rate ->
(AudioDevice) new SimpleAudioDevice("default-" + rate, "default", rate, AudioSample.INT16)).toList();
}
@Override

Wyświetl plik

@ -0,0 +1,214 @@
package sh.ball.gui.controller;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Platform;
import javafx.beans.InvalidationListener;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.CheckBox;
import javafx.scene.control.Slider;
import javafx.scene.shape.SVGPath;
import javafx.util.Duration;
import sh.ball.audio.FrequencyAnalyser;
import sh.ball.audio.ShapeAudioPlayer;
import sh.ball.audio.effect.*;
import sh.ball.audio.engine.AudioDevice;
import sh.ball.shapes.Shape;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
public class EffectsController implements Initializable {
private ShapeAudioPlayer audioPlayer;
private Map<EffectType, Slider> effectTypes;
private final SmoothEffect smoothEffect;
private WobbleEffect wobbleEffect;
@FXML
private CheckBox vectorCancellingCheckBox;
@FXML
private Slider vectorCancellingSlider;
@FXML
private SVGPath vectorCancellingMidi;
@FXML
private CheckBox bitCrushCheckBox;
@FXML
private Slider bitCrushSlider;
@FXML
private SVGPath bitCrushMidi;
@FXML
private CheckBox verticalDistortCheckBox;
@FXML
private Slider verticalDistortSlider;
@FXML
private SVGPath verticalDistortMidi;
@FXML
private CheckBox horizontalDistortCheckBox;
@FXML
private Slider horizontalDistortSlider;
@FXML
private SVGPath horizontalDistortMidi;
@FXML
private CheckBox wobbleCheckBox;
@FXML
private Slider wobbleSlider;
@FXML
private SVGPath wobbleMidi;
@FXML
private CheckBox smoothCheckBox;
@FXML
private Slider smoothSlider;
@FXML
private SVGPath smoothMidi;
@FXML
private CheckBox traceCheckBox;
@FXML
private Slider traceSlider;
@FXML
private SVGPath traceMidi;
public EffectsController() {
this.smoothEffect = new SmoothEffect(1);
}
public Map<SVGPath, Slider> getMidiButtonMap() {
Map<SVGPath, Slider> midiMap = new HashMap<>();
midiMap.put(vectorCancellingMidi, vectorCancellingSlider);
midiMap.put(bitCrushMidi, bitCrushSlider);
midiMap.put(wobbleMidi, wobbleSlider);
midiMap.put(smoothMidi, smoothSlider);
midiMap.put(traceMidi, traceSlider);
midiMap.put(verticalDistortMidi, verticalDistortSlider);
midiMap.put(horizontalDistortMidi, horizontalDistortSlider);
return midiMap;
}
// 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 = Map.of(
EffectType.VECTOR_CANCELLING,
vectorCancellingSlider,
EffectType.BIT_CRUSH,
bitCrushSlider,
EffectType.VERTICAL_DISTORT,
verticalDistortSlider,
EffectType.HORIZONTAL_DISTORT,
horizontalDistortSlider,
EffectType.WOBBLE,
wobbleSlider,
EffectType.SMOOTH,
smoothSlider
);
}
// selects or deselects the given audio effect
private void updateEffect(EffectType type, boolean checked, Effect effect) {
if (checked) {
audioPlayer.addEffect(type, effect);
if (effectTypes.containsKey(type)) {
effectTypes.get(type).setDisable(false);
}
} else {
audioPlayer.removeEffect(type);
if (effectTypes.containsKey(type)) {
effectTypes.get(type).setDisable(true);
}
}
}
public void setAudioPlayer(ShapeAudioPlayer audioPlayer) {
this.audioPlayer = audioPlayer;
}
public void setAudioDevice(AudioDevice device) {
this.wobbleEffect = new WobbleEffect(device.sampleRate());
updateEffect(EffectType.WOBBLE, wobbleCheckBox.isSelected(), wobbleEffect);
restartEffects();
}
public void setFrequencyAnalyser(FrequencyAnalyser<List<Shape>> analyser) {
analyser.addListener(wobbleEffect);
}
public void restartEffects() {
// apply the wobble effect after a second as the frequency of the audio takes a while to
// propagate and send to its listeners.
KeyFrame kf1 = new KeyFrame(Duration.seconds(0), e -> wobbleEffect.setVolume(0));
KeyFrame kf2 = new KeyFrame(Duration.seconds(1), e -> {
wobbleEffect.update();
wobbleEffect.setVolume(wobbleSlider.getValue());
});
Timeline timeline = new Timeline(kf1, kf2);
Platform.runLater(timeline::play);
}
@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
initializeEffectTypes();
InvalidationListener vectorCancellingListener = e ->
updateEffect(EffectType.VECTOR_CANCELLING, vectorCancellingCheckBox.isSelected(),
EffectFactory.vectorCancelling((int) vectorCancellingSlider.getValue()));
InvalidationListener bitCrushListener = e ->
updateEffect(EffectType.BIT_CRUSH, bitCrushCheckBox.isSelected(),
EffectFactory.bitCrush(bitCrushSlider.getValue()));
InvalidationListener verticalDistortListener = e ->
updateEffect(EffectType.VERTICAL_DISTORT, verticalDistortCheckBox.isSelected(),
EffectFactory.verticalDistort(verticalDistortSlider.getValue()));
InvalidationListener horizontalDistortListener = e ->
updateEffect(EffectType.HORIZONTAL_DISTORT, horizontalDistortCheckBox.isSelected(),
EffectFactory.horizontalDistort(horizontalDistortSlider.getValue()));
InvalidationListener wobbleListener = e -> {
wobbleEffect.setVolume(wobbleSlider.getValue());
updateEffect(EffectType.WOBBLE, wobbleCheckBox.isSelected(), wobbleEffect);
};
InvalidationListener smoothListener = e -> {
smoothEffect.setWindowSize((int) smoothSlider.getValue());
updateEffect(EffectType.SMOOTH, smoothCheckBox.isSelected(), smoothEffect);
};
InvalidationListener traceListener = e -> {
double trace = traceCheckBox.isSelected() ? traceSlider.valueProperty().getValue() : 1;
audioPlayer.setTrace(trace);
traceSlider.setDisable(!traceCheckBox.isSelected());
};
vectorCancellingSlider.valueProperty().addListener(vectorCancellingListener);
vectorCancellingCheckBox.selectedProperty().addListener(vectorCancellingListener);
bitCrushSlider.valueProperty().addListener(bitCrushListener);
bitCrushCheckBox.selectedProperty().addListener(bitCrushListener);
verticalDistortSlider.valueProperty().addListener(verticalDistortListener);
verticalDistortCheckBox.selectedProperty().addListener(verticalDistortListener);
horizontalDistortSlider.valueProperty().addListener(horizontalDistortListener);
horizontalDistortCheckBox.selectedProperty().addListener(horizontalDistortListener);
wobbleSlider.valueProperty().addListener(wobbleListener);
wobbleCheckBox.selectedProperty().addListener(wobbleListener);
wobbleCheckBox.selectedProperty().addListener(e -> wobbleEffect.update());
smoothSlider.valueProperty().addListener(smoothListener);
smoothCheckBox.selectedProperty().addListener(smoothListener);
traceSlider.valueProperty().addListener(traceListener);
traceCheckBox.selectedProperty().addListener(traceListener);
}
public List<CheckBox> effectCheckBoxes() {
return List.of(vectorCancellingCheckBox, bitCrushCheckBox, verticalDistortCheckBox,
horizontalDistortCheckBox, wobbleCheckBox, smoothCheckBox, traceCheckBox);
}
public List<Slider> effectSliders() {
return List.of(vectorCancellingSlider, bitCrushSlider, verticalDistortSlider,
horizontalDistortSlider, wobbleSlider, smoothSlider, traceSlider);
}
}

Wyświetl plik

@ -6,6 +6,7 @@ import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.collections.FXCollections;
import javafx.scene.control.*;
import javafx.scene.layout.AnchorPane;
import javafx.scene.paint.Color;
import javafx.scene.paint.Paint;
import javafx.scene.shape.SVGPath;
@ -72,8 +73,6 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
private final ShapeAudioPlayer audioPlayer;
private final RotateEffect rotateEffect;
private final TranslateEffect translateEffect;
private final WobbleEffect wobbleEffect;
private final SmoothEffect smoothEffect;
private final DoubleProperty frequency;
private final AudioDevice defaultDevice;
private int sampleRate;
@ -110,6 +109,8 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
private final DirectoryChooser folderChooser = new DirectoryChooser();
private Stage stage;
@FXML
private EffectsController effectsController;
@FXML
private Label frequencyLabel;
@FXML
@ -163,52 +164,10 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
@FXML
private CheckBox rotateCheckBox;
@FXML
private CheckBox vectorCancellingCheckBox;
@FXML
private Slider vectorCancellingSlider;
@FXML
private SVGPath vectorCancellingMidi;
@FXML
private CheckBox bitCrushCheckBox;
@FXML
private Slider bitCrushSlider;
@FXML
private SVGPath bitCrushMidi;
@FXML
private CheckBox verticalDistortCheckBox;
@FXML
private Slider verticalDistortSlider;
@FXML
private SVGPath verticalDistortMidi;
@FXML
private CheckBox horizontalDistortCheckBox;
@FXML
private Slider horizontalDistortSlider;
@FXML
private SVGPath horizontalDistortMidi;
@FXML
private CheckBox wobbleCheckBox;
@FXML
private Slider wobbleSlider;
@FXML
private SVGPath wobbleMidi;
@FXML
private CheckBox smoothCheckBox;
@FXML
private Slider smoothSlider;
@FXML
private SVGPath smoothMidi;
@FXML
private Slider octaveSlider;
@FXML
private SVGPath octaveMidi;
@FXML
private CheckBox traceCheckBox;
@FXML
private Slider traceSlider;
@FXML
private SVGPath traceMidi;
@FXML
private Slider visibilitySlider;
@FXML
private SVGPath visibilityMidi;
@ -247,8 +206,6 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
this.sampleRate = defaultDevice.sampleRate();
this.rotateEffect = new RotateEffect(sampleRate);
this.translateEffect = new TranslateEffect(sampleRate);
this.wobbleEffect = new WobbleEffect(sampleRate);
this.smoothEffect = new SmoothEffect(1);
this.frequency = new SimpleDoubleProperty(0);
}
@ -262,15 +219,9 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
midiMap.put(volumeMidi, volumeSlider);
midiMap.put(focalLengthMidi, focalLengthSlider);
midiMap.put(objectRotateSpeedMidi, objectRotateSpeedSlider);
midiMap.put(vectorCancellingMidi, vectorCancellingSlider);
midiMap.put(bitCrushMidi, bitCrushSlider);
midiMap.put(wobbleMidi, wobbleSlider);
midiMap.put(smoothMidi, smoothSlider);
midiMap.put(octaveMidi, octaveSlider);
midiMap.put(traceMidi, traceSlider);
midiMap.put(visibilityMidi, visibilitySlider);
midiMap.put(verticalDistortMidi, verticalDistortSlider);
midiMap.put(horizontalDistortMidi, horizontalDistortSlider);
midiMap.putAll(effectsController.getMidiButtonMap());
return midiMap;
}
@ -286,27 +237,6 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
);
}
private Map<EffectType, Slider> effectTypes;
// 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 = Map.of(
EffectType.VECTOR_CANCELLING,
vectorCancellingSlider,
EffectType.BIT_CRUSH,
bitCrushSlider,
EffectType.VERTICAL_DISTORT,
verticalDistortSlider,
EffectType.HORIZONTAL_DISTORT,
horizontalDistortSlider,
EffectType.WOBBLE,
wobbleSlider,
EffectType.SMOOTH,
smoothSlider
);
}
@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
// converts the value of frequencySlider to the actual frequency that it represents so that it
@ -318,6 +248,8 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
frequency.set(MidiNote.MIDDLE_C);
audioPlayer.setVolume(volumeSlider.valueProperty());
effectsController.setAudioPlayer(audioPlayer);
this.midiButtonMap = initializeMidiButtonMap();
midiButtonMap.keySet().forEach(midi -> midi.setOnMouseClicked(e -> {
@ -338,7 +270,6 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
}));
Map<Slider, Consumer<Double>> sliders = initializeSliderMap();
initializeEffectTypes();
for (Slider slider : sliders.keySet()) {
slider.valueProperty().addListener((source, oldValue, newValue) ->
@ -349,56 +280,8 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
translationXTextField.textProperty().addListener(e -> updateTranslation());
translationYTextField.textProperty().addListener(e -> updateTranslation());
InvalidationListener vectorCancellingListener = e ->
updateEffect(EffectType.VECTOR_CANCELLING, vectorCancellingCheckBox.isSelected(),
EffectFactory.vectorCancelling((int) vectorCancellingSlider.getValue()));
InvalidationListener bitCrushListener = e ->
updateEffect(EffectType.BIT_CRUSH, bitCrushCheckBox.isSelected(),
EffectFactory.bitCrush(bitCrushSlider.getValue()));
InvalidationListener verticalDistortListener = e ->
updateEffect(EffectType.VERTICAL_DISTORT, verticalDistortCheckBox.isSelected(),
EffectFactory.verticalDistort(verticalDistortSlider.getValue()));
InvalidationListener horizontalDistortListener = e ->
updateEffect(EffectType.HORIZONTAL_DISTORT, horizontalDistortCheckBox.isSelected(),
EffectFactory.horizontalDistort(horizontalDistortSlider.getValue()));
InvalidationListener wobbleListener = e -> {
wobbleEffect.setVolume(wobbleSlider.getValue());
updateEffect(EffectType.WOBBLE, wobbleCheckBox.isSelected(), wobbleEffect);
};
InvalidationListener smoothListener = e -> {
smoothEffect.setWindowSize((int) smoothSlider.getValue());
updateEffect(EffectType.SMOOTH, smoothCheckBox.isSelected(), smoothEffect);
};
InvalidationListener traceListener = e -> {
double trace = traceCheckBox.isSelected() ? traceSlider.valueProperty().getValue() : 1;
audioPlayer.setTrace(trace);
traceSlider.setDisable(!traceCheckBox.isSelected());
};
vectorCancellingSlider.valueProperty().addListener(vectorCancellingListener);
vectorCancellingCheckBox.selectedProperty().addListener(vectorCancellingListener);
bitCrushSlider.valueProperty().addListener(bitCrushListener);
bitCrushCheckBox.selectedProperty().addListener(bitCrushListener);
verticalDistortSlider.valueProperty().addListener(verticalDistortListener);
verticalDistortCheckBox.selectedProperty().addListener(verticalDistortListener);
horizontalDistortSlider.valueProperty().addListener(horizontalDistortListener);
horizontalDistortCheckBox.selectedProperty().addListener(horizontalDistortListener);
wobbleSlider.valueProperty().addListener(wobbleListener);
wobbleCheckBox.selectedProperty().addListener(wobbleListener);
wobbleCheckBox.selectedProperty().addListener(e -> wobbleEffect.update());
smoothSlider.valueProperty().addListener(smoothListener);
smoothCheckBox.selectedProperty().addListener(smoothListener);
octaveSlider.valueProperty().addListener((e, old, octave) -> audioPlayer.setOctave(octave.intValue()));
traceSlider.valueProperty().addListener(traceListener);
traceCheckBox.selectedProperty().addListener(traceListener);
osciFileChooser.setInitialFileName("project.osci");
osciFileChooser.getExtensionFilters().add(
new FileChooser.ExtensionFilter("osci-render files", "*.osci")
@ -473,6 +356,7 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
audioPlayer.addEffect(EffectType.TRANSLATE, translateEffect);
audioPlayer.setDevice(defaultDevice);
effectsController.setAudioDevice(defaultDevice);
List<AudioDevice> devices = audioPlayer.devices();
deviceComboBox.setItems(FXCollections.observableList(devices));
deviceComboBox.setValue(defaultDevice);
@ -508,10 +392,12 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
e.printStackTrace();
}
audioPlayer.setDevice(device);
effectsController.setAudioDevice(device);
analyser.stop();
sampleRate = device.sampleRate();
analyser = new FrequencyAnalyser<>(audioPlayer, 2, sampleRate);
startFrequencyAnalyser(analyser);
effectsController.setFrequencyAnalyser(analyser);
startAudioPlayerThread();
}
@ -526,7 +412,7 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
// as listeners of it so that they can get updates as the frequency changes
private void startFrequencyAnalyser(FrequencyAnalyser<List<Shape>> analyser) {
analyser.addListener(this);
analyser.addListener(wobbleEffect);
effectsController.setFrequencyAnalyser(analyser);
new Thread(analyser).start();
}
@ -622,21 +508,6 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
));
}
// selects or deselects the given audio effect
private void updateEffect(EffectType type, boolean checked, Effect effect) {
if (checked) {
audioPlayer.addEffect(type, effect);
if (effectTypes.containsKey(type)) {
effectTypes.get(type).setDisable(false);
}
} else {
audioPlayer.removeEffect(type);
if (effectTypes.containsKey(type)) {
effectTypes.get(type).setDisable(true);
}
}
}
// changes the FrameProducer e.g. could be changing from a 3D object to an
// SVG. The old FrameProducer is stopped and a new one created and initialised
// with the same settings that the original had.
@ -657,16 +528,7 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
setObjRotate(settings.baseRotation, settings.currentRotation);
}
executor.submit(producer);
// apply the wobble effect after a second as the frequency of the audio takes a while to
// propagate and send to its listeners.
KeyFrame kf1 = new KeyFrame(Duration.seconds(0), e -> wobbleEffect.setVolume(0));
KeyFrame kf2 = new KeyFrame(Duration.seconds(1), e -> {
wobbleEffect.update();
wobbleEffect.setVolume(wobbleSlider.getValue());
});
Timeline timeline = new Timeline(kf1, kf2);
Platform.runLater(timeline::play);
effectsController.restartEffects();
updateFrameLabels();
// enable the .obj file settings iff the new frameSource is for a 3D object.
@ -925,14 +787,6 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
}
// must be functions, otherwise they are not initialised
private List<CheckBox> checkBoxes() {
return List.of(vectorCancellingCheckBox, bitCrushCheckBox, verticalDistortCheckBox,
horizontalDistortCheckBox, wobbleCheckBox, smoothCheckBox, traceCheckBox);
}
private List<Slider> checkBoxSliders() {
return List.of(vectorCancellingSlider, bitCrushSlider, verticalDistortSlider,
horizontalDistortSlider, wobbleSlider, smoothSlider, traceSlider);
}
private List<String> checkBoxLabels() {
return List.of("vectorCancelling", "bitCrush", "verticalDistort", "horizontalDistort",
"wobble", "smooth", "trace");
@ -946,7 +800,7 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
"visibility", "focalLength", "objectRotateSpeed");
}
private List<Slider> allSliders() {
List<Slider> sliders = new ArrayList<>(checkBoxSliders());
List<Slider> sliders = new ArrayList<>(effectsController.effectSliders());
sliders.addAll(otherSliders());
return sliders;
}
@ -983,8 +837,8 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
document.appendChild(root);
// Is there a nicer way of doing this?!
List<CheckBox> checkBoxes = checkBoxes();
List<Slider> checkBoxSliders = checkBoxSliders();
List<CheckBox> checkBoxes = effectsController.effectCheckBoxes();
List<Slider> checkBoxSliders = effectsController.effectSliders();
List<String> checkBoxLabels = checkBoxLabels();
List<Slider> otherSliders = otherSliders();
List<String> otherLabels = otherLabels();
@ -1080,8 +934,8 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
Document document = documentBuilder.parse(new File(projectFileName));
document.getDocumentElement().normalize();
List<CheckBox> checkBoxes = checkBoxes();
List<Slider> checkBoxSliders = checkBoxSliders();
List<CheckBox> checkBoxes = effectsController.effectCheckBoxes();
List<Slider> checkBoxSliders = effectsController.effectSliders();
List<String> checkBoxLabels = checkBoxLabels();
List<Slider> otherSliders = otherSliders();
List<String> otherLabels = otherLabels();

Wyświetl plik

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.CheckBox?>
<?import javafx.scene.control.Slider?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.shape.SVGPath?>
<AnchorPane fx:id="effects" minHeight="0.0" minWidth="0.0" prefHeight="262.0" prefWidth="402.0" stylesheets="@../css/main.css" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sh.ball.gui.controller.EffectsController">
<children>
<CheckBox fx:id="vectorCancellingCheckBox" layoutX="14.0" layoutY="15.0" mnemonicParsing="false" text="Vector cancelling" />
<Slider fx:id="vectorCancellingSlider" blockIncrement="0.05" disable="true" layoutX="154.0" layoutY="16.0" majorTickUnit="1.0" max="10.0" min="2.0" minorTickCount="0" prefHeight="42.0" prefWidth="219.0" showTickLabels="true" showTickMarks="true" snapToTicks="true" value="2.0" />
<CheckBox fx:id="bitCrushCheckBox" layoutX="14.0" layoutY="62.0" mnemonicParsing="false" text="Bit crush" />
<Slider fx:id="bitCrushSlider" blockIncrement="0.01" disable="true" layoutX="154.0" layoutY="64.0" majorTickUnit="0.5" max="3.0" prefHeight="42.0" prefWidth="219.0" showTickLabels="true" showTickMarks="true" value="2.0" />
<CheckBox fx:id="verticalDistortCheckBox" layoutX="14.0" layoutY="110.0" mnemonicParsing="false" text="Vertical Distort" />
<Slider fx:id="verticalDistortSlider" blockIncrement="0.005" disable="true" layoutX="154.0" layoutY="112.0" majorTickUnit="0.1" max="1.0" prefHeight="38.0" prefWidth="219.0" showTickLabels="true" showTickMarks="true" value="0.2" />
<CheckBox fx:id="horizontalDistortCheckBox" layoutX="14.0" layoutY="159.0" mnemonicParsing="false" text="Horizontal Distort" />
<Slider fx:id="horizontalDistortSlider" blockIncrement="0.005" disable="true" layoutX="154.0" layoutY="161.0" majorTickUnit="0.1" max="1.0" prefHeight="38.0" prefWidth="219.0" showTickLabels="true" showTickMarks="true" value="0.2" />
<CheckBox fx:id="wobbleCheckBox" layoutX="14.0" layoutY="208.0" mnemonicParsing="false" text="Wobble" />
<Slider fx:id="wobbleSlider" blockIncrement="0.005" disable="true" layoutX="154.0" layoutY="210.0" majorTickUnit="0.1" max="1.0" prefHeight="38.0" prefWidth="219.0" showTickLabels="true" showTickMarks="true" value="0.2" />
<SVGPath fx:id="vectorCancellingMidi" content="M20.15 8.26H22V15.74H20.15M13 8.26H18.43C19 8.26 19.3 8.74 19.3 9.3V14.81C19.3 15.5 19 15.74 18.38 15.74H13V11H14.87V13.91H17.5V9.95H13M10.32 8.26H12.14V15.74H10.32M2 8.26H8.55C9.1 8.26 9.41 8.74 9.41 9.3V15.74H7.59V10.15H6.5V15.74H4.87V10.15H3.83V15.74H2Z" fill="WHITE" layoutX="373.0" layoutY="13.0" pickOnBounds="true" />
<SVGPath fx:id="bitCrushMidi" content="M20.15 8.26H22V15.74H20.15M13 8.26H18.43C19 8.26 19.3 8.74 19.3 9.3V14.81C19.3 15.5 19 15.74 18.38 15.74H13V11H14.87V13.91H17.5V9.95H13M10.32 8.26H12.14V15.74H10.32M2 8.26H8.55C9.1 8.26 9.41 8.74 9.41 9.3V15.74H7.59V10.15H6.5V15.74H4.87V10.15H3.83V15.74H2Z" fill="WHITE" layoutX="373.0" layoutY="61.0" pickOnBounds="true" />
<SVGPath fx:id="verticalDistortMidi" content="M20.15 8.26H22V15.74H20.15M13 8.26H18.43C19 8.26 19.3 8.74 19.3 9.3V14.81C19.3 15.5 19 15.74 18.38 15.74H13V11H14.87V13.91H17.5V9.95H13M10.32 8.26H12.14V15.74H10.32M2 8.26H8.55C9.1 8.26 9.41 8.74 9.41 9.3V15.74H7.59V10.15H6.5V15.74H4.87V10.15H3.83V15.74H2Z" fill="WHITE" layoutX="373.0" layoutY="108.0" pickOnBounds="true" />
<SVGPath fx:id="horizontalDistortMidi" content="M20.15 8.26H22V15.74H20.15M13 8.26H18.43C19 8.26 19.3 8.74 19.3 9.3V14.81C19.3 15.5 19 15.74 18.38 15.74H13V11H14.87V13.91H17.5V9.95H13M10.32 8.26H12.14V15.74H10.32M2 8.26H8.55C9.1 8.26 9.41 8.74 9.41 9.3V15.74H7.59V10.15H6.5V15.74H4.87V10.15H3.83V15.74H2Z" fill="WHITE" layoutX="373.0" layoutY="157.0" pickOnBounds="true" />
<SVGPath fx:id="wobbleMidi" content="M20.15 8.26H22V15.74H20.15M13 8.26H18.43C19 8.26 19.3 8.74 19.3 9.3V14.81C19.3 15.5 19 15.74 18.38 15.74H13V11H14.87V13.91H17.5V9.95H13M10.32 8.26H12.14V15.74H10.32M2 8.26H8.55C9.1 8.26 9.41 8.74 9.41 9.3V15.74H7.59V10.15H6.5V15.74H4.87V10.15H3.83V15.74H2Z" fill="WHITE" layoutX="373.0" layoutY="206.0" pickOnBounds="true" />
<CheckBox fx:id="smoothCheckBox" layoutX="14.0" layoutY="255.0" mnemonicParsing="false" text="Smoothing" />
<Slider fx:id="smoothSlider" blockIncrement="1.0" disable="true" layoutX="154.0" layoutY="257.0" majorTickUnit="128.0" max="1024.0" minorTickCount="1" prefHeight="38.0" prefWidth="219.0" showTickLabels="true" showTickMarks="true" value="128.0" />
<SVGPath fx:id="smoothMidi" content="M20.15 8.26H22V15.74H20.15M13 8.26H18.43C19 8.26 19.3 8.74 19.3 9.3V14.81C19.3 15.5 19 15.74 18.38 15.74H13V11H14.87V13.91H17.5V9.95H13M10.32 8.26H12.14V15.74H10.32M2 8.26H8.55C9.1 8.26 9.41 8.74 9.41 9.3V15.74H7.59V10.15H6.5V15.74H4.87V10.15H3.83V15.74H2Z" fill="WHITE" layoutX="373.0" layoutY="253.0" pickOnBounds="true" />
<CheckBox fx:id="traceCheckBox" layoutX="14.0" layoutY="304.0" mnemonicParsing="false" text="Trace" />
<Slider fx:id="traceSlider" blockIncrement="0.005" disable="true" layoutX="154.0" layoutY="306.0" majorTickUnit="0.1" max="1.0" prefHeight="38.0" prefWidth="219.0" showTickLabels="true" showTickMarks="true" value="0.5" />
<SVGPath fx:id="traceMidi" content="M20.15 8.26H22V15.74H20.15M13 8.26H18.43C19 8.26 19.3 8.74 19.3 9.3V14.81C19.3 15.5 19 15.74 18.38 15.74H13V11H14.87V13.91H17.5V9.95H13M10.32 8.26H12.14V15.74H10.32M2 8.26H8.55C9.1 8.26 9.41 8.74 9.41 9.3V15.74H7.59V10.15H6.5V15.74H4.87V10.15H3.83V15.74H2Z" fill="WHITE" layoutX="373.0" layoutY="302.0" pickOnBounds="true" />
</children>
</AnchorPane>

Wyświetl plik

@ -16,34 +16,10 @@
<?import javafx.scene.text.Font?>
<AnchorPane prefHeight="658.0" prefWidth="837.0" stylesheets="@../css/main.css" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sh.ball.gui.controller.MainController">
<TitledPane animated="false" collapsible="false" layoutX="424.0" layoutY="38.0" prefHeight="387.0" prefWidth="402.0" text="Audio Effects">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="262.0" prefWidth="402.0">
<children>
<CheckBox fx:id="vectorCancellingCheckBox" layoutX="14.0" layoutY="15.0" mnemonicParsing="false" text="Vector cancelling" />
<Slider fx:id="vectorCancellingSlider" blockIncrement="0.05" disable="true" layoutX="154.0" layoutY="16.0" majorTickUnit="1.0" max="10.0" min="2.0" minorTickCount="0" prefHeight="42.0" prefWidth="219.0" showTickLabels="true" showTickMarks="true" snapToTicks="true" value="2.0" />
<CheckBox fx:id="bitCrushCheckBox" layoutX="14.0" layoutY="62.0" mnemonicParsing="false" text="Bit crush" />
<Slider fx:id="bitCrushSlider" blockIncrement="0.01" disable="true" layoutX="154.0" layoutY="64.0" majorTickUnit="0.5" max="3.0" prefHeight="42.0" prefWidth="219.0" showTickLabels="true" showTickMarks="true" value="2.0" />
<CheckBox fx:id="verticalDistortCheckBox" layoutX="14.0" layoutY="110.0" mnemonicParsing="false" text="Vertical Distort" />
<Slider fx:id="verticalDistortSlider" blockIncrement="0.005" disable="true" layoutX="154.0" layoutY="112.0" majorTickUnit="0.1" max="1.0" prefHeight="38.0" prefWidth="219.0" showTickLabels="true" showTickMarks="true" value="0.2" />
<CheckBox fx:id="horizontalDistortCheckBox" layoutX="14.0" layoutY="159.0" mnemonicParsing="false" text="Horizontal Distort" />
<Slider fx:id="horizontalDistortSlider" blockIncrement="0.005" disable="true" layoutX="154.0" layoutY="161.0" majorTickUnit="0.1" max="1.0" prefHeight="38.0" prefWidth="219.0" showTickLabels="true" showTickMarks="true" value="0.2" />
<CheckBox fx:id="wobbleCheckBox" layoutX="14.0" layoutY="208.0" mnemonicParsing="false" text="Wobble" />
<Slider fx:id="wobbleSlider" blockIncrement="0.005" disable="true" layoutX="154.0" layoutY="210.0" majorTickUnit="0.1" max="1.0" prefHeight="38.0" prefWidth="219.0" showTickLabels="true" showTickMarks="true" value="0.2" />
<SVGPath fx:id="vectorCancellingMidi" content="M20.15 8.26H22V15.74H20.15M13 8.26H18.43C19 8.26 19.3 8.74 19.3 9.3V14.81C19.3 15.5 19 15.74 18.38 15.74H13V11H14.87V13.91H17.5V9.95H13M10.32 8.26H12.14V15.74H10.32M2 8.26H8.55C9.1 8.26 9.41 8.74 9.41 9.3V15.74H7.59V10.15H6.5V15.74H4.87V10.15H3.83V15.74H2Z" fill="WHITE" layoutX="373.0" layoutY="13.0" pickOnBounds="true" />
<SVGPath fx:id="bitCrushMidi" content="M20.15 8.26H22V15.74H20.15M13 8.26H18.43C19 8.26 19.3 8.74 19.3 9.3V14.81C19.3 15.5 19 15.74 18.38 15.74H13V11H14.87V13.91H17.5V9.95H13M10.32 8.26H12.14V15.74H10.32M2 8.26H8.55C9.1 8.26 9.41 8.74 9.41 9.3V15.74H7.59V10.15H6.5V15.74H4.87V10.15H3.83V15.74H2Z" fill="WHITE" layoutX="373.0" layoutY="61.0" pickOnBounds="true" />
<SVGPath fx:id="verticalDistortMidi" content="M20.15 8.26H22V15.74H20.15M13 8.26H18.43C19 8.26 19.3 8.74 19.3 9.3V14.81C19.3 15.5 19 15.74 18.38 15.74H13V11H14.87V13.91H17.5V9.95H13M10.32 8.26H12.14V15.74H10.32M2 8.26H8.55C9.1 8.26 9.41 8.74 9.41 9.3V15.74H7.59V10.15H6.5V15.74H4.87V10.15H3.83V15.74H2Z" fill="WHITE" layoutX="373.0" layoutY="108.0" pickOnBounds="true" />
<SVGPath fx:id="horizontalDistortMidi" content="M20.15 8.26H22V15.74H20.15M13 8.26H18.43C19 8.26 19.3 8.74 19.3 9.3V14.81C19.3 15.5 19 15.74 18.38 15.74H13V11H14.87V13.91H17.5V9.95H13M10.32 8.26H12.14V15.74H10.32M2 8.26H8.55C9.1 8.26 9.41 8.74 9.41 9.3V15.74H7.59V10.15H6.5V15.74H4.87V10.15H3.83V15.74H2Z" fill="WHITE" layoutX="373.0" layoutY="157.0" pickOnBounds="true" />
<SVGPath fx:id="wobbleMidi" content="M20.15 8.26H22V15.74H20.15M13 8.26H18.43C19 8.26 19.3 8.74 19.3 9.3V14.81C19.3 15.5 19 15.74 18.38 15.74H13V11H14.87V13.91H17.5V9.95H13M10.32 8.26H12.14V15.74H10.32M2 8.26H8.55C9.1 8.26 9.41 8.74 9.41 9.3V15.74H7.59V10.15H6.5V15.74H4.87V10.15H3.83V15.74H2Z" fill="WHITE" layoutX="373.0" layoutY="206.0" pickOnBounds="true" />
<CheckBox fx:id="smoothCheckBox" layoutX="14.0" layoutY="255.0" mnemonicParsing="false" text="Smoothing" />
<Slider fx:id="smoothSlider" blockIncrement="1.0" disable="true" layoutX="154.0" layoutY="257.0" majorTickUnit="128.0" max="1024.0" minorTickCount="1" prefHeight="38.0" prefWidth="219.0" showTickLabels="true" showTickMarks="true" value="128.0" />
<SVGPath fx:id="smoothMidi" content="M20.15 8.26H22V15.74H20.15M13 8.26H18.43C19 8.26 19.3 8.74 19.3 9.3V14.81C19.3 15.5 19 15.74 18.38 15.74H13V11H14.87V13.91H17.5V9.95H13M10.32 8.26H12.14V15.74H10.32M2 8.26H8.55C9.1 8.26 9.41 8.74 9.41 9.3V15.74H7.59V10.15H6.5V15.74H4.87V10.15H3.83V15.74H2Z" fill="WHITE" layoutX="373.0" layoutY="253.0" pickOnBounds="true" />
<CheckBox fx:id="traceCheckBox" layoutX="14.0" layoutY="304.0" mnemonicParsing="false" text="Trace" />
<Slider fx:id="traceSlider" blockIncrement="0.005" disable="true" layoutX="154.0" layoutY="306.0" majorTickUnit="0.1" max="1.0" prefHeight="38.0" prefWidth="219.0" showTickLabels="true" showTickMarks="true" value="0.5" />
<SVGPath fx:id="traceMidi" content="M20.15 8.26H22V15.74H20.15M13 8.26H18.43C19 8.26 19.3 8.74 19.3 9.3V14.81C19.3 15.5 19 15.74 18.38 15.74H13V11H14.87V13.91H17.5V9.95H13M10.32 8.26H12.14V15.74H10.32M2 8.26H8.55C9.1 8.26 9.41 8.74 9.41 9.3V15.74H7.59V10.15H6.5V15.74H4.87V10.15H3.83V15.74H2Z" fill="WHITE" layoutX="373.0" layoutY="302.0" pickOnBounds="true" />
</children>
</AnchorPane>
</content>
<TitledPane animated="false" collapsible="false" layoutX="424.0"
layoutY="38.0" prefHeight="387.0" prefWidth="402.0"
text="Audio Effects">
<fx:include fx:id="effects" source="effects.fxml"/>
</TitledPane>
<TitledPane fx:id="objTitledPane" animated="false" collapsible="false" layoutX="424.0" layoutY="436.0" maxHeight="-Infinity" maxWidth="-Infinity" prefHeight="213.0" prefWidth="402.0" text="3D .obj file settings">
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="359.0">