kopia lustrzana https://github.com/jameshball/osci-render
Allow files to be created and deleted and provide some default files for svg, lua, obj, and txt
rodzic
a4a6f4bb53
commit
ad8f939ad5
|
@ -3,9 +3,11 @@ package sh.ball.gui.controller;
|
|||
import javafx.animation.KeyFrame;
|
||||
import javafx.animation.Timeline;
|
||||
import javafx.application.Platform;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.shape.SVGPath;
|
||||
import javafx.stage.DirectoryChooser;
|
||||
import javafx.stage.FileChooser;
|
||||
|
@ -19,10 +21,12 @@ import javax.xml.parsers.ParserConfigurationException;
|
|||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.util.*;
|
||||
|
||||
import static sh.ball.gui.Gui.audioPlayer;
|
||||
import static sh.ball.gui.Gui.main;
|
||||
|
||||
public class GeneralController implements Initializable, SubController {
|
||||
|
||||
|
@ -61,6 +65,14 @@ public class GeneralController implements Initializable, SubController {
|
|||
private Slider micVolumeSlider;
|
||||
@FXML
|
||||
private SVGPath micVolumeMidi;
|
||||
@FXML
|
||||
private TextField createFileTextField;
|
||||
@FXML
|
||||
private ComboBox<String> createFileComboBox;
|
||||
@FXML
|
||||
private Button createFileButton;
|
||||
@FXML
|
||||
private Button deleteFileButton;
|
||||
|
||||
public void setRecordResult(String result) {
|
||||
recordLabel.setText(result);
|
||||
|
@ -216,6 +228,38 @@ public class GeneralController implements Initializable, SubController {
|
|||
});
|
||||
|
||||
editFileButton.setOnAction(e -> mainController.openCodeEditor());
|
||||
deleteFileButton.setOnAction(e -> mainController.deleteCurrentFile());
|
||||
|
||||
createFileComboBox.setItems(FXCollections.observableList(List.of(".lua", ".svg", ".obj", ".txt")));
|
||||
createFileComboBox.setValue(".lua");
|
||||
|
||||
try {
|
||||
Map<String, byte[]> defaultFileMap = Map.of(
|
||||
".lua", getClass().getResourceAsStream("/lua/demo.lua").readAllBytes(),
|
||||
".svg", getClass().getResourceAsStream("/svg/demo.svg").readAllBytes(),
|
||||
".obj", getClass().getResourceAsStream("/models/cube.obj").readAllBytes(),
|
||||
".txt", "hello".getBytes(StandardCharsets.UTF_8)
|
||||
);
|
||||
|
||||
createFileButton.setOnAction(e -> {
|
||||
try {
|
||||
String fileName = createFileTextField.getText() + createFileComboBox.getValue();
|
||||
byte[] fileData = defaultFileMap.get(createFileComboBox.getValue());
|
||||
mainController.createFile(fileName, fileData);
|
||||
createFileTextField.setText("");
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
});
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
createFileTextField.setOnKeyPressed(event -> {
|
||||
if (event.getCode() == KeyCode.ENTER) {
|
||||
createFileButton.getOnAction().handle(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -233,7 +277,7 @@ public class GeneralController implements Initializable, SubController {
|
|||
|
||||
public void updateFrequency(double leftFrequency, double rightFrequency) {
|
||||
Platform.runLater(() ->
|
||||
frequencyLabel.setText(String.format("L/R Frequency:\n%d Hz / %d Hz", Math.round(leftFrequency), Math.round(rightFrequency)))
|
||||
frequencyLabel.setText(String.format("L/R Frequency: %5d Hz\t / %5d Hz", Math.round(leftFrequency), Math.round(rightFrequency)))
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@ import sh.ball.engine.ObjectServer;
|
|||
import sh.ball.engine.ObjectSet;
|
||||
import sh.ball.gui.Gui;
|
||||
import sh.ball.oscilloscope.ByteWebSocketServer;
|
||||
import sh.ball.parser.FileParser;
|
||||
import sh.ball.parser.lua.LuaParser;
|
||||
import sh.ball.parser.obj.ObjFrameSettings;
|
||||
import sh.ball.parser.obj.ObjParser;
|
||||
|
@ -96,11 +97,10 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
|
|||
// frames
|
||||
private static final InputStream DEFAULT_OBJ = MainController.class.getResourceAsStream("/models/cube.obj");
|
||||
private final ExecutorService executor = Executors.newSingleThreadExecutor();
|
||||
private final LuaParser luaParser = new LuaParser();
|
||||
private final Set<String> unsavedFileNames = new LinkedHashSet<>();
|
||||
private List<byte[]> openFiles = new ArrayList<>();
|
||||
private List<String> frameSourcePaths = new ArrayList<>();
|
||||
private List<FrameSource<Vector2>> sampleSources = new ArrayList<>();
|
||||
private List<FileParser<FrameSource<Vector2>>> sampleParsers = new ArrayList<>();
|
||||
private List<FrameSource<List<Shape>>> frameSources = new ArrayList<>();
|
||||
private FrameProducer<List<Shape>> producer;
|
||||
private int currentFrameSource;
|
||||
|
@ -190,7 +190,7 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
|
|||
|
||||
openFiles.add(baos.toByteArray());
|
||||
frameSources.add(frames);
|
||||
sampleSources.add(null);
|
||||
sampleParsers.add(null);
|
||||
frameSourcePaths.add("cube.obj");
|
||||
currentFrameSource = 0;
|
||||
this.producer = new FrameProducer<>(audioPlayer, frames);
|
||||
|
@ -518,8 +518,12 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
|
|||
}
|
||||
|
||||
public void setLuaVariable(String variableName, Object value) {
|
||||
sampleParsers.forEach(sampleParser -> {
|
||||
if (sampleParser instanceof LuaParser luaParser) {
|
||||
luaParser.setVariable(variableName, value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setSoftwareOscilloscopeAction(Runnable openBrowser) {
|
||||
softwareOscilloscopeMenuItem.setOnAction((e) -> openBrowser.run());
|
||||
|
@ -620,17 +624,42 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
|
|||
new Thread(analyser).start();
|
||||
}
|
||||
|
||||
private void disableSources() {
|
||||
frameSources.stream().filter(Objects::nonNull).forEach(FrameSource::disable);
|
||||
sampleParsers.stream().filter(Objects::nonNull).forEach(parser -> {
|
||||
try {
|
||||
parser.get().disable();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 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.
|
||||
private void changeFrameSource(int index) {
|
||||
if (frameSources.size() == 0) {
|
||||
generalController.setFrameSourceName("No file open!");
|
||||
generalController.updateFrameLabels();
|
||||
audioPlayer.removeSampleSource();
|
||||
audioPlayer.addFrame(List.of(new Vector2()));
|
||||
return;
|
||||
}
|
||||
index = Math.max(0, Math.min(index, frameSources.size() - 1));
|
||||
currentFrameSource = index;
|
||||
frameSources.stream().filter(Objects::nonNull).forEach(FrameSource::disable);
|
||||
sampleSources.stream().filter(Objects::nonNull).forEach(FrameSource::disable);
|
||||
disableSources();
|
||||
|
||||
FrameSource<List<Shape>> frames = frameSources.get(index);
|
||||
FrameSource<Vector2> samples = sampleSources.get(index);
|
||||
FrameSource<Vector2> samples = null;
|
||||
try {
|
||||
FileParser<FrameSource<Vector2>> sampleParser = sampleParsers.get(index);
|
||||
if (sampleParser != null ) {
|
||||
samples = sampleParser.get();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (frames != null) {
|
||||
frames.enable();
|
||||
audioPlayer.removeSampleSource();
|
||||
|
@ -676,6 +705,56 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
|
|||
});
|
||||
}
|
||||
|
||||
private void createFile(String name, byte[] fileData, List<FileParser<FrameSource<Vector2>>> sampleParsers, List<FrameSource<List<Shape>>> frameSources, List<String> frameSourcePaths, List<byte[]> openFiles) throws Exception {
|
||||
if (frameSourcePaths.contains(name)) {
|
||||
throw new IOException("File already exists with this name");
|
||||
}
|
||||
if (LuaParser.isLuaFile(name)) {
|
||||
LuaParser luaParser = new LuaParser();
|
||||
luaParser.setScriptFromInputStream(new ByteArrayInputStream(fileData));
|
||||
luaParser.parse();
|
||||
sampleParsers.add(luaParser);
|
||||
luaController.updateLuaVariables();
|
||||
frameSources.add(null);
|
||||
} else {
|
||||
frameSources.add(ParserFactory.getParser(name, fileData).parse());
|
||||
sampleParsers.add(null);
|
||||
}
|
||||
frameSourcePaths.add(name);
|
||||
openFiles.add(fileData);
|
||||
Platform.runLater(() -> {
|
||||
generalController.showMultiFileTooltip(frameSources.size() > 1);
|
||||
if (generalController.framesPlaying() && frameSources.size() == 1) {
|
||||
generalController.disablePlayback();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void createFile(String name, byte[] fileData) throws Exception {
|
||||
createFile(name, fileData, sampleParsers, frameSources, frameSourcePaths, openFiles);
|
||||
changeFrameSource(frameSources.size() - 1);
|
||||
unsavedFileNames.add(name);
|
||||
setUnsavedFileWarning();
|
||||
}
|
||||
|
||||
public void deleteCurrentFile() {
|
||||
if (frameSources.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
disableSources();
|
||||
sampleParsers.remove(currentFrameSource);
|
||||
frameSources.remove(currentFrameSource);
|
||||
String name = frameSourcePaths.get(currentFrameSource);
|
||||
unsavedFileNames.remove(name);
|
||||
setUnsavedFileWarning();
|
||||
frameSourcePaths.remove(currentFrameSource);
|
||||
openFiles.remove(currentFrameSource);
|
||||
if (currentFrameSource >= frameSources.size()) {
|
||||
currentFrameSource--;
|
||||
}
|
||||
changeFrameSource(currentFrameSource);
|
||||
}
|
||||
|
||||
void updateFileData(byte[] file, String name) {
|
||||
int index = frameSourcePaths.indexOf(name);
|
||||
if (index == -1) {
|
||||
|
@ -685,16 +764,18 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
|
|||
openFiles.set(index, file);
|
||||
try {
|
||||
if (LuaParser.isLuaFile(name)) {
|
||||
FileParser<FrameSource<Vector2>> sampleParser = sampleParsers.get(index);
|
||||
if (sampleParser instanceof LuaParser luaParser) {
|
||||
luaParser.setScriptFromInputStream(new ByteArrayInputStream(file));
|
||||
FrameSource<Vector2> sampleSource = sampleSources.get(index);
|
||||
sampleSources.set(index, luaParser.parse());
|
||||
sampleSource.disable();
|
||||
}
|
||||
sampleParser.parse().disable();
|
||||
sampleParsers.set(index, sampleParser);
|
||||
frameSources.set(index, null);
|
||||
} else {
|
||||
FrameSource<List<Shape>> frameSource = frameSources.get(index);
|
||||
frameSources.set(index, ParserFactory.getParser(name, file).parse());
|
||||
frameSource.disable();
|
||||
sampleSources.set(index, null);
|
||||
sampleParsers.set(index, null);
|
||||
}
|
||||
|
||||
unsavedFileNames.add(name);
|
||||
|
@ -711,7 +792,7 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
|
|||
void setUnsavedFileWarning() {
|
||||
Platform.runLater(() -> {
|
||||
if (!unsavedFileNames.isEmpty()) {
|
||||
String warning = "(unsaved file changes: " + String.join(", ", unsavedFileNames) + ")";
|
||||
String warning = "(unsaved files: " + String.join(", ", unsavedFileNames) + ")";
|
||||
updateTitle(warning, openProjectPath);
|
||||
} else {
|
||||
updateTitle(null, openProjectPath);
|
||||
|
@ -720,7 +801,7 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
|
|||
}
|
||||
|
||||
void updateFiles(List<byte[]> files, List<String> names, int startingFrameSource) throws Exception {
|
||||
List<FrameSource<Vector2>> newSampleSources = new ArrayList<>();
|
||||
List<FileParser<FrameSource<Vector2>>> newSampleParsers = new ArrayList<>();
|
||||
List<FrameSource<List<Shape>>> newFrameSources = new ArrayList<>();
|
||||
List<String> newFrameSourcePaths = new ArrayList<>();
|
||||
List<byte[]> newOpenFiles = new ArrayList<>();
|
||||
|
@ -735,17 +816,8 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
|
|||
|
||||
for (int i = 0; i < files.size(); i++) {
|
||||
try {
|
||||
if (LuaParser.isLuaFile(names.get(i))) {
|
||||
luaParser.setScriptFromInputStream(new ByteArrayInputStream(files.get(i)));
|
||||
newSampleSources.add(luaParser.parse());
|
||||
newFrameSources.add(null);
|
||||
} else {
|
||||
newFrameSources.add(ParserFactory.getParser(names.get(i), files.get(i)).parse());
|
||||
newSampleSources.add(null);
|
||||
}
|
||||
newFrameSourcePaths.add(names.get(i));
|
||||
newOpenFiles.add(files.get(i));
|
||||
} catch (IOException | IllegalArgumentException e) {
|
||||
createFile(names.get(i), files.get(i), newSampleParsers, newFrameSources, newFrameSourcePaths, newOpenFiles);
|
||||
} catch (Exception e) {
|
||||
Platform.runLater(() -> {
|
||||
generalController.setFrameSourceName(e.getMessage());
|
||||
generalController.updateFrameLabels();
|
||||
|
@ -753,21 +825,14 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
|
|||
}
|
||||
}
|
||||
|
||||
Platform.runLater(() -> {
|
||||
if (newFrameSources.size() > 0) {
|
||||
generalController.showMultiFileTooltip(newFrameSources.size() > 1);
|
||||
if (generalController.framesPlaying() && newFrameSources.size() == 1) {
|
||||
generalController.disablePlayback();
|
||||
}
|
||||
frameSources.stream().filter(Objects::nonNull).forEach(FrameSource::disable);
|
||||
sampleSources.stream().filter(Objects::nonNull).forEach(FrameSource::disable);
|
||||
sampleSources = newSampleSources;
|
||||
disableSources();
|
||||
sampleParsers = newSampleParsers;
|
||||
frameSources = newFrameSources;
|
||||
frameSourcePaths = newFrameSourcePaths;
|
||||
openFiles = newOpenFiles;
|
||||
changeFrameSource(startingFrameSource);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// used so that the Controller has access to the stage, allowing it to open
|
||||
|
@ -1218,6 +1283,8 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
|
|||
updateFiles(files, fileNames, 0);
|
||||
}
|
||||
|
||||
luaController.updateLuaVariables();
|
||||
|
||||
openProjectPath = projectFileName;
|
||||
updateTitle(null, projectFileName);
|
||||
} catch (Exception e) {
|
||||
|
@ -1297,8 +1364,12 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
|
|||
}
|
||||
|
||||
public void resetLuaStep() {
|
||||
sampleParsers.forEach(sampleParser -> {
|
||||
if (sampleParser instanceof LuaParser luaParser) {
|
||||
luaParser.resetStep();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private record PrintableSlider(Slider slider) {
|
||||
@Override
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
package sh.ball.parser;
|
||||
|
||||
import java.io.IOException;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import java.io.IOException;
|
||||
|
||||
public abstract class FileParser<T> {
|
||||
|
||||
public abstract String getFileExtension();
|
||||
|
@ -21,4 +21,6 @@ public abstract class FileParser<T> {
|
|||
}
|
||||
|
||||
public abstract T parse() throws Exception;
|
||||
|
||||
public abstract T get() throws Exception;
|
||||
}
|
||||
|
|
|
@ -35,6 +35,11 @@ public class LuaParser extends FileParser<FrameSource<Vector2>> {
|
|||
return sampleSource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FrameSource<Vector2> get() {
|
||||
return sampleSource;
|
||||
}
|
||||
|
||||
public static boolean isLuaFile(String path) {
|
||||
return path.matches(".*\\.lua");
|
||||
}
|
||||
|
|
|
@ -55,6 +55,11 @@ public class ObjParser extends FileParser<FrameSource<List<Shape>>> {
|
|||
return new ObjFrameSource(object, camera);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FrameSource<List<Shape>> get() throws IOException {
|
||||
return parse();
|
||||
}
|
||||
|
||||
// If camera position arguments haven't been specified, automatically work out the position of
|
||||
// the camera based on the size of the object in the camera's view.
|
||||
public void setFocalLength(double focalLength) {
|
||||
|
|
|
@ -190,6 +190,11 @@ public class SvgParser extends FileParser<FrameSource<List<Shape>>> {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public FrameSource<List<Shape>> get() throws IOException, ParserConfigurationException, SAXException {
|
||||
return parse();
|
||||
}
|
||||
|
||||
/* Given a character, will return the glyph associated with it.
|
||||
* Assumes that the .svg loaded has character glyphs. */
|
||||
public List<Shape> parseGlyphsWithUnicode(char unicode) {
|
||||
|
|
|
@ -83,6 +83,11 @@ public class TextParser extends FileParser<FrameSource<List<Shape>>> {
|
|||
return new ShapeFrameSource(Shape.flip(Shape.normalize(shapes)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public FrameSource<List<Shape>> get() throws Exception {
|
||||
return parse();
|
||||
}
|
||||
|
||||
public static boolean isTxtFile(String path) {
|
||||
return path.matches(".*\\.txt");
|
||||
}
|
||||
|
|
|
@ -1,25 +1,31 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.ComboBox?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.Slider?>
|
||||
<?import javafx.scene.control.TextField?>
|
||||
<?import javafx.scene.layout.AnchorPane?>
|
||||
<?import javafx.scene.shape.SVGPath?>
|
||||
|
||||
<AnchorPane id="control-pane" prefHeight="324.0" prefWidth="364.0" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sh.ball.gui.controller.GeneralController">
|
||||
<AnchorPane id="control-pane" prefHeight="341.0" prefWidth="364.0" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sh.ball.gui.controller.GeneralController">
|
||||
<children>
|
||||
<Button fx:id="chooseFileButton" layoutX="14.0" layoutY="26.0" mnemonicParsing="false" prefHeight="26.0" prefWidth="114.0" text="Choose File" />
|
||||
<Label fx:id="fileLabel" alignment="TOP_LEFT" layoutX="143.0" layoutY="30.0" maxWidth="270.0" prefHeight="42.0" prefWidth="174.0" text="cube.obj" wrapText="true" />
|
||||
<Label fx:id="recordLabel" layoutX="13.0" layoutY="304.0" maxWidth="451.0" prefHeight="18.0" prefWidth="343.0" />
|
||||
<Label id="frequency" fx:id="frequencyLabel" layoutX="14.0" layoutY="141.0" prefHeight="58.0" prefWidth="343.0" text="L/R Frequency: " />
|
||||
<Button fx:id="chooseFolderButton" layoutX="14.0" layoutY="76.0" mnemonicParsing="false" prefHeight="26.0" prefWidth="114.0" text="Choose Folder" />
|
||||
<Label fx:id="jkLabel" layoutX="143.0" layoutY="69.0" maxWidth="270.0" prefHeight="70.0" prefWidth="210.0" text="Use j and k (or MIDI Program Change) to cycle between files, or i to start playback" visible="false" wrapText="true" />
|
||||
<Slider fx:id="octaveSlider" blockIncrement="1.0" layoutX="82.0" layoutY="215.0" majorTickUnit="1.0" max="5.0" min="-5.0" minorTickCount="0" prefHeight="42.0" prefWidth="246.0" showTickLabels="true" showTickMarks="true" snapToTicks="true" />
|
||||
<SVGPath fx:id="octaveMidi" 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="333.0" layoutY="211.0" pickOnBounds="true" />
|
||||
<Label layoutX="13.0" layoutY="214.0" text="Octave" />
|
||||
<Slider fx:id="micVolumeSlider" blockIncrement="1.0" layoutX="82.0" layoutY="254.0" majorTickUnit="1.0" max="10.0" prefHeight="42.0" prefWidth="246.0" showTickLabels="true" showTickMarks="true" value="1.0" />
|
||||
<SVGPath fx:id="micVolumeMidi" 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="333.0" layoutY="250.0" pickOnBounds="true" />
|
||||
<Label layoutX="13.0" layoutY="253.0" text="Mic Volume" />
|
||||
<Button fx:id="editFileButton" layoutX="325.0" layoutY="26.0" mnemonicParsing="false" text="Edit" />
|
||||
<Button fx:id="chooseFileButton" layoutX="14.0" layoutY="17.0" mnemonicParsing="false" prefHeight="26.0" prefWidth="114.0" text="Choose File" />
|
||||
<Label fx:id="fileLabel" alignment="TOP_LEFT" layoutX="143.0" layoutY="22.0" maxWidth="270.0" prefHeight="58.0" prefWidth="210.0" text="cube.obj" wrapText="true" />
|
||||
<Label fx:id="recordLabel" layoutX="14.0" layoutY="323.0" maxWidth="451.0" prefHeight="18.0" prefWidth="343.0" />
|
||||
<Label id="frequency" fx:id="frequencyLabel" layoutX="14.0" layoutY="152.0" prefHeight="58.0" prefWidth="343.0" text="L/R Frequency: " />
|
||||
<Button fx:id="chooseFolderButton" layoutX="14.0" layoutY="118.0" mnemonicParsing="false" prefHeight="26.0" prefWidth="114.0" text="Choose Folder" />
|
||||
<Label fx:id="jkLabel" layoutX="143.0" layoutY="89.0" maxWidth="270.0" prefHeight="70.0" prefWidth="218.0" text="Use j and k (or MIDI Program Change) to cycle between files, or i to start playback" visible="false" wrapText="true" />
|
||||
<Slider fx:id="octaveSlider" blockIncrement="1.0" layoutX="82.0" layoutY="198.0" majorTickUnit="1.0" max="5.0" min="-5.0" minorTickCount="0" prefHeight="42.0" prefWidth="246.0" showTickLabels="true" showTickMarks="true" snapToTicks="true" />
|
||||
<SVGPath fx:id="octaveMidi" 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="333.0" layoutY="194.0" pickOnBounds="true" />
|
||||
<Label layoutX="13.0" layoutY="197.0" text="Octave" />
|
||||
<Slider fx:id="micVolumeSlider" blockIncrement="1.0" layoutX="82.0" layoutY="237.0" majorTickUnit="1.0" max="10.0" prefHeight="42.0" prefWidth="246.0" showTickLabels="true" showTickMarks="true" value="1.0" />
|
||||
<SVGPath fx:id="micVolumeMidi" 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="333.0" layoutY="233.0" pickOnBounds="true" />
|
||||
<Label layoutX="13.0" layoutY="236.0" text="Mic Volume" />
|
||||
<Button fx:id="deleteFileButton" layoutX="14.0" layoutY="84.0" mnemonicParsing="false" prefHeight="26.0" prefWidth="114.0" text="Remove File" />
|
||||
<Button fx:id="createFileButton" layoutX="248.0" layoutY="286.0" minHeight="30.0" mnemonicParsing="false" prefHeight="30.0" prefWidth="95.0" text="Create File" />
|
||||
<ComboBox fx:id="createFileComboBox" layoutX="166.0" layoutY="286.0" minHeight="30.0" prefHeight="30.0" prefWidth="78.0" />
|
||||
<TextField fx:id="createFileTextField" alignment="CENTER_RIGHT" layoutX="35.0" layoutY="286.0" prefHeight="30.0" prefWidth="127.0" />
|
||||
<Button fx:id="editFileButton" layoutX="14.0" layoutY="51.0" mnemonicParsing="false" prefHeight="26.0" prefWidth="114.0" text="Edit File" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
|
|
|
@ -198,7 +198,7 @@
|
|||
</Menu>
|
||||
</menus>
|
||||
</MenuBar>
|
||||
<TitledPane animated="false" collapsible="false" layoutX="7.0" layoutY="33.0" minWidth="378.0" prefHeight="371.0" prefWidth="370.0" text="Main settings">
|
||||
<TitledPane animated="false" collapsible="false" layoutX="7.0" layoutY="33.0" minHeight="371.0" minWidth="378.0" prefHeight="364.0" prefWidth="378.0" text="Main settings">
|
||||
<fx:include fx:id="general" source="general.fxml" />
|
||||
</TitledPane>
|
||||
<TitledPane animated="false" collapsible="false" layoutX="478.0" layoutY="411.0" prefHeight="334.0" prefWidth="523.0" text="Image settings">
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
--
|
||||
-- .lua files can be used to make your own custom audio sources!
|
||||
-- Lua documentation: https://www.lua.org/docs.html
|
||||
--
|
||||
-- All variables are saved between calls to this script.
|
||||
--
|
||||
-- Below is a simple example of an audio effect that makes a
|
||||
-- nice visual on an oscilloscope and shows off some of the
|
||||
-- functionality available.
|
||||
--
|
||||
-- The variable 'step' used below is incremented with every
|
||||
-- call to this script, starting at 1.
|
||||
--
|
||||
|
||||
-- sets 'theta' to 0 initially, or the previous value of
|
||||
-- 'theta' the last time this script ran
|
||||
theta = theta or 0
|
||||
|
||||
-- updates 'theta' using 'step'
|
||||
theta = theta + math.sqrt(step) / 1000000000
|
||||
|
||||
-- 'slider_a', 'slider_b', ..., 'slider_e' are controlled by
|
||||
-- the respective sliders in the .lua file settings
|
||||
left_scale = 0.3 * slider_a
|
||||
right_scale = 0.3 * slider_b
|
||||
|
||||
-- Returns audio samples that will be played back
|
||||
return {
|
||||
-- left audio channel
|
||||
left_scale * math.tan(theta * step),
|
||||
-- right audio channel
|
||||
right_scale * math.tan(theta * step + math.pi / 2)
|
||||
}
|
|
@ -1,7 +1,3 @@
|
|||
# Blender v2.81 (sub 16) OBJ File: ''
|
||||
# www.blender.org
|
||||
mtllib cube.mtl
|
||||
o Cube
|
||||
v 1.000000 1.000000 -1.000000
|
||||
v 1.000000 -1.000000 -1.000000
|
||||
v 1.000000 1.000000 1.000000
|
||||
|
@ -10,28 +6,6 @@ v -1.000000 1.000000 -1.000000
|
|||
v -1.000000 -1.000000 -1.000000
|
||||
v -1.000000 1.000000 1.000000
|
||||
v -1.000000 -1.000000 1.000000
|
||||
vt 0.625000 0.500000
|
||||
vt 0.875000 0.500000
|
||||
vt 0.875000 0.750000
|
||||
vt 0.625000 0.750000
|
||||
vt 0.375000 0.750000
|
||||
vt 0.625000 1.000000
|
||||
vt 0.375000 1.000000
|
||||
vt 0.375000 0.000000
|
||||
vt 0.625000 0.000000
|
||||
vt 0.625000 0.250000
|
||||
vt 0.375000 0.250000
|
||||
vt 0.125000 0.500000
|
||||
vt 0.375000 0.500000
|
||||
vt 0.125000 0.750000
|
||||
vn 0.0000 1.0000 0.0000
|
||||
vn 0.0000 0.0000 1.0000
|
||||
vn -1.0000 0.0000 0.0000
|
||||
vn 0.0000 -1.0000 0.0000
|
||||
vn 1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 -1.0000
|
||||
usemtl Material
|
||||
s off
|
||||
f 1/1/1 5/2/1 7/3/1 3/4/1
|
||||
f 4/5/2 3/4/2 7/6/2 8/7/2
|
||||
f 8/8/3 7/9/3 5/10/3 6/11/3
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
<svg><path d="M 0,0 a 75,75 0 1,0 150,0 a 75,75 0 1,0 -150,0"/></svg>
|
Po Szerokość: | Wysokość: | Rozmiar: 69 B |
Ładowanie…
Reference in New Issue