Fix when MIDI activates and deactivates, and add translation scale

pull/50/head v1.18.1
James Ball 2022-03-04 22:27:09 +00:00
rodzic 971bda35bb
commit 54d539e9f1
7 zmienionych plików z 72 dodań i 37 usunięć

Wyświetl plik

@ -6,7 +6,7 @@
<groupId>sh.ball</groupId> <groupId>sh.ball</groupId>
<artifactId>osci-render</artifactId> <artifactId>osci-render</artifactId>
<version>1.18.0</version> <version>1.18.1</version>
<name>osci-render</name> <name>osci-render</name>

Wyświetl plik

@ -91,7 +91,7 @@ public class ShapeAudioPlayer implements AudioPlayer<List<Shape>> {
communicator.addListener(this); communicator.addListener(this);
} }
private void resetMidi() { public void resetMidi() {
keysDown.clear(); keysDown.clear();
for (int i = 0; i < keyTargetVolumes.length; i++) { for (int i = 0; i < keyTargetVolumes.length; i++) {
Arrays.fill(keyTargetVolumes[i], (short) 0); Arrays.fill(keyTargetVolumes[i], (short) 0);
@ -102,6 +102,7 @@ public class ShapeAudioPlayer implements AudioPlayer<List<Shape>> {
keyActualVolumes[0][60] = (short) MidiNote.MAX_VELOCITY; keyActualVolumes[0][60] = (short) MidiNote.MAX_VELOCITY;
keysDown.add(new MidiNote(60)); keysDown.add(new MidiNote(60));
midiStarted = false; midiStarted = false;
notesChanged();
} }
public void stopMidiNotes() { public void stopMidiNotes() {
@ -118,6 +119,11 @@ public class ShapeAudioPlayer implements AudioPlayer<List<Shape>> {
public void setVolume(DoubleProperty volume) { public void setVolume(DoubleProperty volume) {
this.volume = Objects.requireNonNullElseGet(volume, () -> new SimpleDoubleProperty(1)); this.volume = Objects.requireNonNullElseGet(volume, () -> new SimpleDoubleProperty(1));
this.volume.addListener(e -> {
if (keysDown.size() == 0) {
resetMidi();
}
});
} }
private Vector2 generateChannels() throws InterruptedException { private Vector2 generateChannels() throws InterruptedException {
@ -477,6 +483,7 @@ public class ShapeAudioPlayer implements AudioPlayer<List<Shape>> {
return; return;
} }
} }
} }
public void setTrace(double trace) { public void setTrace(double trace) {
@ -489,7 +496,8 @@ public class ShapeAudioPlayer implements AudioPlayer<List<Shape>> {
return; return;
} }
int command = message.getCommand(); int command = message.getCommand();
if (!midiStarted) {
if (!midiStarted && (command == ShortMessage.NOTE_ON || command == ShortMessage.NOTE_OFF)) {
stopMidiNotes(); stopMidiNotes();
midiStarted = true; midiStarted = true;
} }

Wyświetl plik

@ -8,6 +8,7 @@ public class TranslateEffect extends PhaseEffect {
private Vector2 translation; private Vector2 translation;
private boolean ellipse = false; private boolean ellipse = false;
private double scale;
public TranslateEffect(int sampleRate, double speed, Vector2 translation) { public TranslateEffect(int sampleRate, double speed, Vector2 translation) {
super(sampleRate, speed); super(sampleRate, speed);
@ -22,9 +23,9 @@ public class TranslateEffect extends PhaseEffect {
public Vector2 apply(int count, Vector2 vector) { public Vector2 apply(int count, Vector2 vector) {
if (ellipse) { if (ellipse) {
double theta = nextTheta(); double theta = nextTheta();
return vector.translate(translation.scale(new Vector2(Math.sin(theta), Math.cos(theta)))); return vector.translate(translation.scale(new Vector2(Math.sin(theta), Math.cos(theta))).scale(scale));
} else { } else {
return vector.translate(translation); return vector.translate(translation.scale(scale));
} }
} }
@ -38,4 +39,8 @@ public class TranslateEffect extends PhaseEffect {
} }
this.ellipse = ellipse; this.ellipse = ellipse;
} }
public void setScale(double scale) {
this.scale = scale;
}
} }

Wyświetl plik

@ -51,6 +51,10 @@ public class ImageController implements Initializable, SubController {
@FXML @FXML
private CheckBox translateCheckBox; private CheckBox translateCheckBox;
@FXML @FXML
private Slider translationScaleSlider;
@FXML
private SVGPath translationScaleMidi;
@FXML
private Slider frequencySlider; private Slider frequencySlider;
@FXML @FXML
private SVGPath frequencyMidi; private SVGPath frequencyMidi;
@ -133,6 +137,8 @@ public class ImageController implements Initializable, SubController {
translateEllipseCheckBox.selectedProperty().addListener((e, old, ellipse) -> translateEffect.setEllipse(ellipse)); translateEllipseCheckBox.selectedProperty().addListener((e, old, ellipse) -> translateEffect.setEllipse(ellipse));
translationScaleSlider.valueProperty().addListener((e, old, scale) -> translateEffect.setScale(scale.doubleValue()));
// converts the value of frequencySlider to the actual frequency that it represents so that it // converts the value of frequencySlider to the actual frequency that it represents so that it
// can increase at an exponential scale. // can increase at an exponential scale.
frequencySlider.valueProperty().addListener((o, old, f) -> frequency.set(Math.pow(MAX_FREQUENCY, f.doubleValue()))); frequencySlider.valueProperty().addListener((o, old, f) -> frequency.set(Math.pow(MAX_FREQUENCY, f.doubleValue())));
@ -150,20 +156,21 @@ public class ImageController implements Initializable, SubController {
rotateSpeedMidi, rotateSpeedSlider, rotateSpeedMidi, rotateSpeedSlider,
translationSpeedMidi, translationSpeedSlider, translationSpeedMidi, translationSpeedSlider,
volumeMidi, volumeSlider, volumeMidi, volumeSlider,
visibilityMidi, visibilitySlider visibilityMidi, visibilitySlider,
translationScaleMidi, translationScaleSlider
); );
} }
@Override @Override
public List<Slider> sliders() { public List<Slider> sliders() {
return List.of(frequencySlider, rotateSpeedSlider, translationSpeedSlider, return List.of(frequencySlider, rotateSpeedSlider, translationSpeedSlider,
volumeSlider, visibilitySlider); volumeSlider, visibilitySlider, translationScaleSlider);
} }
@Override @Override
public List<String> labels() { public List<String> labels() {
return List.of("frequency", "rotateSpeed", "translationSpeed", "volume", return List.of("frequency", "rotateSpeed", "translationSpeed", "volume",
"visibility"); "visibility", "translationScale");
} }
@Override @Override

Wyświetl plik

@ -102,6 +102,8 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
@FXML @FXML
private MenuItem stopMidiNotesMenuItem; private MenuItem stopMidiNotesMenuItem;
@FXML @FXML
private MenuItem resetMidiMenuItem;
@FXML
private Spinner<Integer> midiChannelSpinner; private Spinner<Integer> midiChannelSpinner;
public MainController() throws Exception { public MainController() throws Exception {
@ -198,8 +200,8 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
}); });
resetMidiMappingMenuItem.setOnAction(e -> resetCCMap()); resetMidiMappingMenuItem.setOnAction(e -> resetCCMap());
stopMidiNotesMenuItem.setOnAction(e -> audioPlayer.stopMidiNotes()); stopMidiNotesMenuItem.setOnAction(e -> audioPlayer.stopMidiNotes());
resetMidiMenuItem.setOnAction(e -> audioPlayer.resetMidi());
NumberFormat format = NumberFormat.getIntegerInstance(); NumberFormat format = NumberFormat.getIntegerInstance();
UnaryOperator<TextFormatter.Change> filter = c -> { UnaryOperator<TextFormatter.Change> filter = c -> {
@ -489,8 +491,12 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
private void loadSliderValues(List<Slider> sliders, List<String> labels, Element root) { private void loadSliderValues(List<Slider> sliders, List<String> labels, Element root) {
for (int i = 0; i < sliders.size(); i++) { for (int i = 0; i < sliders.size(); i++) {
String value = root.getElementsByTagName(labels.get(i)).item(0).getTextContent(); NodeList nodes = root.getElementsByTagName(labels.get(i));
sliders.get(i).setValue(Float.parseFloat(value)); // backwards compatibility
if (nodes.getLength() > 0) {
String value = nodes.item(0).getTextContent();
sliders.get(i).setValue(Float.parseFloat(value));
}
} }
} }
@ -581,6 +587,7 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
resetCCMap(); resetCCMap();
for (int i = 0; i < labels.size(); i++) { for (int i = 0; i < labels.size(); i++) {
NodeList elements = midiElement.getElementsByTagName(labels.get(i)); NodeList elements = midiElement.getElementsByTagName(labels.get(i));
// backwards compatibility
if (elements.getLength() > 0) { if (elements.getLength() > 0) {
Element midi = (Element) elements.item(0); Element midi = (Element) elements.item(0);
int cc = Integer.parseInt(midi.getTextContent()); int cc = Integer.parseInt(midi.getTextContent());

Wyświetl plik

@ -8,28 +8,28 @@
<?import javafx.scene.shape.SVGPath?> <?import javafx.scene.shape.SVGPath?>
<?import javafx.scene.text.Font?> <?import javafx.scene.text.Font?>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="296.0" prefWidth="511.0" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sh.ball.gui.controller.ImageController"> <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="329.0" prefWidth="511.0" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sh.ball.gui.controller.ImageController">
<children> <children>
<CheckBox fx:id="translateEllipseCheckBox" layoutX="324.0" layoutY="19.0" mnemonicParsing="false" text="Ellipse" /> <CheckBox fx:id="translateEllipseCheckBox" layoutX="324.0" layoutY="19.0" mnemonicParsing="false" text="Ellipse" />
<Slider fx:id="rotateSpeedSlider" blockIncrement="0.05" layoutX="116.0" layoutY="122.0" majorTickUnit="1.0" max="10.0" prefHeight="42.0" prefWidth="254.0" showTickLabels="true" showTickMarks="true" /> <Slider fx:id="rotateSpeedSlider" blockIncrement="0.05" layoutX="116.0" layoutY="159.0" majorTickUnit="1.0" max="10.0" prefHeight="42.0" prefWidth="254.0" showTickLabels="true" showTickMarks="true" />
<Label layoutX="13.0" layoutY="121.0" text="2D Rotate speed"> <Label layoutX="13.0" layoutY="158.0" text="2D Rotate speed">
<font> <font>
<Font size="13.0" /> <Font size="13.0" />
</font> </font>
</Label> </Label>
<Slider fx:id="translationSpeedSlider" blockIncrement="0.05" layoutX="116.0" layoutY="160.0" majorTickUnit="1.0" max="10.0" prefHeight="42.0" prefWidth="254.0" showTickLabels="true" showTickMarks="true" value="1.0" /> <Slider fx:id="translationSpeedSlider" blockIncrement="0.05" layoutX="116.0" layoutY="197.0" majorTickUnit="1.0" max="10.0" prefHeight="42.0" prefWidth="254.0" showTickLabels="true" showTickMarks="true" value="1.0" />
<Label layoutX="7.0" layoutY="159.0" text="Translation speed"> <Label layoutX="7.0" layoutY="196.0" text="Translation speed">
<font> <font>
<Font size="13.0" /> <Font size="13.0" />
</font> </font>
</Label> </Label>
<Slider fx:id="volumeSlider" blockIncrement="0.05" layoutX="116.0" layoutY="199.0" majorTickUnit="1.0" max="10.0" prefHeight="42.0" prefWidth="253.0" showTickLabels="true" showTickMarks="true" value="1.0" /> <Slider fx:id="volumeSlider" blockIncrement="0.05" layoutX="116.0" layoutY="236.0" majorTickUnit="1.0" max="10.0" prefHeight="42.0" prefWidth="253.0" showTickLabels="true" showTickMarks="true" value="1.0" />
<Label layoutX="33.0" layoutY="198.0" text="Volume scale"> <Label layoutX="33.0" layoutY="235.0" text="Volume scale">
<font> <font>
<Font size="13.0" /> <Font size="13.0" />
</font> </font>
</Label> </Label>
<Label layoutX="11.0" layoutY="82.0" text="Target frequency"> <Label layoutX="11.0" layoutY="119.0" text="Target frequency">
<font> <font>
<Font size="13.0" /> <Font size="13.0" />
</font> </font>
@ -39,32 +39,39 @@
<Label layoutX="120.0" layoutY="18.0" text="x :" /> <Label layoutX="120.0" layoutY="18.0" text="x :" />
<Label layoutX="222.0" layoutY="18.0" text="y :" /> <Label layoutX="222.0" layoutY="18.0" text="y :" />
<TextField fx:id="translationYTextField" layoutX="241.0" layoutY="15.0" prefHeight="26.0" prefWidth="69.0" text="0.0" /> <TextField fx:id="translationYTextField" layoutX="241.0" layoutY="15.0" prefHeight="26.0" prefWidth="69.0" text="0.0" />
<Slider fx:id="frequencySlider" blockIncrement="0.001" layoutX="116.0" layoutY="77.0" majorTickUnit="0.07389" max="1.0" minorTickCount="2" prefHeight="42.0" prefWidth="253.0" showTickMarks="true" value="0.59269" /> <Slider fx:id="frequencySlider" blockIncrement="0.001" layoutX="116.0" layoutY="114.0" majorTickUnit="0.07389" max="1.0" minorTickCount="2" prefHeight="42.0" prefWidth="253.0" showTickMarks="true" value="0.59269" />
<SVGPath fx:id="frequencyMidi" 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="371.0" layoutY="81.0" pickOnBounds="true" /> <SVGPath fx:id="frequencyMidi" 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="371.0" layoutY="118.0" pickOnBounds="true" />
<SVGPath fx:id="rotateSpeedMidi" 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="371.0" layoutY="119.0" pickOnBounds="true" /> <SVGPath fx:id="rotateSpeedMidi" 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="371.0" layoutY="156.0" pickOnBounds="true" />
<SVGPath fx:id="translationSpeedMidi" 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="371.0" layoutY="157.0" pickOnBounds="true" /> <SVGPath fx:id="translationSpeedMidi" 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="371.0" layoutY="194.0" pickOnBounds="true" />
<SVGPath fx:id="volumeMidi" 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="371.0" layoutY="196.0" pickOnBounds="true" /> <SVGPath fx:id="volumeMidi" 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="371.0" layoutY="233.0" pickOnBounds="true" />
<Label layoutX="257.0" layoutY="103.0" text="C4" /> <Label layoutX="257.0" layoutY="140.0" text="C4" />
<Label layoutX="239.0" layoutY="103.0" text="C3" /> <Label layoutX="239.0" layoutY="140.0" text="C3" />
<Label layoutX="222.0" layoutY="103.0" text="C2" /> <Label layoutX="222.0" layoutY="140.0" text="C2" />
<Label layoutX="193.0" layoutY="103.0" text="20" /> <Label layoutX="193.0" layoutY="140.0" text="20" />
<Label layoutX="274.0" layoutY="103.0" text="C5" /> <Label layoutX="274.0" layoutY="140.0" text="C5" />
<Label layoutX="292.0" layoutY="103.0" text="C6" /> <Label layoutX="292.0" layoutY="140.0" text="C6" />
<Label layoutX="310.0" layoutY="103.0" text="C7" /> <Label layoutX="310.0" layoutY="140.0" text="C7" />
<Label layoutX="344.0" layoutY="103.0" text="12000"> <Label layoutX="344.0" layoutY="140.0" text="12000">
<font> <font>
<Font size="11.0" /> <Font size="11.0" />
</font> </font>
</Label> </Label>
<Label layoutX="162.0" layoutY="103.0" text="5" /> <Label layoutX="162.0" layoutY="140.0" text="5" />
<Label layoutX="122.0" layoutY="103.0" text="0" /> <Label layoutX="122.0" layoutY="140.0" text="0" />
<Label layoutX="24.0" layoutY="238.0" text="Image visibility"> <Label layoutX="24.0" layoutY="275.0" text="Image visibility">
<font> <font>
<Font size="13.0" /> <Font size="13.0" />
</font> </font>
</Label> </Label>
<Slider fx:id="visibilitySlider" blockIncrement="0.005" layoutX="116.0" layoutY="239.0" majorTickUnit="0.1" max="1.0" prefHeight="42.0" prefWidth="253.0" showTickLabels="true" showTickMarks="true" value="0.5" /> <Slider fx:id="visibilitySlider" blockIncrement="0.005" layoutX="116.0" layoutY="276.0" majorTickUnit="0.1" max="1.0" prefHeight="42.0" prefWidth="253.0" showTickLabels="true" showTickMarks="true" value="0.5" />
<SVGPath fx:id="visibilityMidi" 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="371.0" layoutY="236.0" pickOnBounds="true" /> <SVGPath fx:id="visibilityMidi" 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="371.0" layoutY="273.0" pickOnBounds="true" />
<CheckBox fx:id="translateCheckBox" layoutX="104.0" layoutY="53.0" mnemonicParsing="false" text="Translate with Mouse (Esc to disable)" /> <CheckBox fx:id="translateCheckBox" layoutX="104.0" layoutY="53.0" mnemonicParsing="false" text="Translate with Mouse (Esc to disable)" />
<Slider fx:id="translationScaleSlider" blockIncrement="0.05" layoutX="115.0" layoutY="83.0" majorTickUnit="1.0" max="10.0" prefHeight="42.0" prefWidth="254.0" showTickLabels="true" showTickMarks="true" value="1.0" />
<Label layoutX="12.0" layoutY="82.0" text="Translation Scale">
<font>
<Font size="13.0" />
</font>
</Label>
<SVGPath fx:id="translationScaleMidi" 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="370.0" layoutY="80.0" pickOnBounds="true" />
</children> </children>
</AnchorPane> </AnchorPane>

Wyświetl plik

@ -43,6 +43,7 @@
</accelerator> </accelerator>
</MenuItem> </MenuItem>
<MenuItem fx:id="stopMidiNotesMenuItem" mnemonicParsing="false" text="Stop MIDI Notes" /> <MenuItem fx:id="stopMidiNotesMenuItem" mnemonicParsing="false" text="Stop MIDI Notes" />
<MenuItem fx:id="resetMidiMenuItem" mnemonicParsing="false" text="Reset MIDI" />
<CustomMenuItem hideOnClick="false" mnemonicParsing="false" text="MIDI Channel"> <CustomMenuItem hideOnClick="false" mnemonicParsing="false" text="MIDI Channel">
<content> <content>
<AnchorPane> <AnchorPane>