kopia lustrzana https://github.com/jameshball/osci-render
Add micVolume slider, change bitCrush start/end, make mic move around the original set point
rodzic
b880c165a3
commit
30317b8d33
2
pom.xml
2
pom.xml
|
@ -6,7 +6,7 @@
|
|||
|
||||
<groupId>sh.ball</groupId>
|
||||
<artifactId>osci-render</artifactId>
|
||||
<version>1.18.3</version>
|
||||
<version>1.18.4</version>
|
||||
|
||||
<name>osci-render</name>
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ public class ShapeAudioPlayer implements AudioPlayer<List<Shape>> {
|
|||
private double lengthIncrement = MIN_LENGTH_INCREMENT;
|
||||
private double shapeDrawn = 0;
|
||||
private int count = 0;
|
||||
private DoubleProperty volume = new SimpleDoubleProperty(1);
|
||||
private double volume = 1;
|
||||
private double octaveFrequency;
|
||||
private DoubleProperty frequency;
|
||||
private double baseFrequencyVolumeScale = 0.5;
|
||||
|
@ -91,6 +91,10 @@ public class ShapeAudioPlayer implements AudioPlayer<List<Shape>> {
|
|||
communicator.addListener(this);
|
||||
}
|
||||
|
||||
public boolean midiPlaying() {
|
||||
return keysDown.size() > 0;
|
||||
}
|
||||
|
||||
public void resetMidi() {
|
||||
keysDown.clear();
|
||||
for (int i = 0; i < keyTargetVolumes.length; i++) {
|
||||
|
@ -117,13 +121,8 @@ public class ShapeAudioPlayer implements AudioPlayer<List<Shape>> {
|
|||
frequency.addListener((o, old, f) -> setBaseFrequency(f.doubleValue()));
|
||||
}
|
||||
|
||||
public void setVolume(DoubleProperty volume) {
|
||||
this.volume = Objects.requireNonNullElseGet(volume, () -> new SimpleDoubleProperty(1));
|
||||
this.volume.addListener(e -> {
|
||||
if (keysDown.size() == 0) {
|
||||
resetMidi();
|
||||
}
|
||||
});
|
||||
public void setVolume(double volume) {
|
||||
this.volume = volume;
|
||||
}
|
||||
|
||||
private Vector2 generateChannels() throws InterruptedException {
|
||||
|
@ -257,7 +256,7 @@ public class ShapeAudioPlayer implements AudioPlayer<List<Shape>> {
|
|||
vector = smoothEffect.apply(frame, vector);
|
||||
}
|
||||
|
||||
return vector.scale(volume.get());
|
||||
return vector.scale(volume);
|
||||
}
|
||||
|
||||
private void setBaseFrequency(double baseFrequency) {
|
||||
|
|
|
@ -19,6 +19,6 @@ public class BitCrushEffect implements SettableEffect {
|
|||
|
||||
@Override
|
||||
public void setValue(double value) {
|
||||
this.crush = 3.0 * value;
|
||||
this.crush = 3.0 * (1 - value);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,6 +75,10 @@ public class GeneralController implements Initializable, SubController {
|
|||
@FXML
|
||||
private SVGPath octaveMidi;
|
||||
@FXML
|
||||
private Slider micVolumeSlider;
|
||||
@FXML
|
||||
private SVGPath micVolumeMidi;
|
||||
@FXML
|
||||
private ComboBox<AudioDevice> deviceComboBox;
|
||||
|
||||
// alternates between recording and not recording when called.
|
||||
|
@ -316,7 +320,10 @@ public class GeneralController implements Initializable, SubController {
|
|||
|
||||
@Override
|
||||
public Map<SVGPath, Slider> getMidiButtonMap() {
|
||||
return Map.of(octaveMidi, octaveSlider);
|
||||
return Map.of(
|
||||
octaveMidi, octaveSlider,
|
||||
micVolumeMidi, micVolumeSlider
|
||||
);
|
||||
}
|
||||
|
||||
public void updateLastVisitedDirectory(File dir) {
|
||||
|
@ -331,20 +338,25 @@ public class GeneralController implements Initializable, SubController {
|
|||
);
|
||||
}
|
||||
|
||||
public double getMicVolume() {
|
||||
return micVolumeSlider.getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CheckBox> micCheckBoxes() {
|
||||
List<CheckBox> checkboxes = new ArrayList<>();
|
||||
checkboxes.add(null);
|
||||
checkboxes.add(null);
|
||||
return checkboxes;
|
||||
}
|
||||
@Override
|
||||
public List<Slider> sliders() {
|
||||
return List.of(octaveSlider);
|
||||
return List.of(octaveSlider, micVolumeSlider);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> labels() {
|
||||
return List.of("octave");
|
||||
return List.of("octave", "micVolume");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -158,7 +158,14 @@ public class ImageController implements Initializable, SubController {
|
|||
audioPlayer.setFrequency(frequency);
|
||||
// default value is middle C
|
||||
frequency.set(MidiNote.MIDDLE_C);
|
||||
audioPlayer.setVolume(volumeSlider.valueProperty());
|
||||
volumeSlider.valueProperty().addListener((e, old, value) -> {
|
||||
audioPlayer.setVolume(value.doubleValue() / 3.0);
|
||||
});
|
||||
volumeSlider.valueProperty().addListener(e -> {
|
||||
if (!audioPlayer.midiPlaying()) {
|
||||
audioPlayer.resetMidi();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -56,6 +56,7 @@ import static sh.ball.gui.Gui.defaultDevice;
|
|||
public class MainController implements Initializable, FrequencyListener, MidiListener, AudioInputListener {
|
||||
|
||||
private static final double SCROLL_SPEED = 0.003;
|
||||
public static final double MIN_MIC_VOLUME = 0.025;
|
||||
|
||||
private String openProjectPath;
|
||||
|
||||
|
@ -64,6 +65,7 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
|
|||
private FrequencyAnalyser<List<Shape>> analyser;
|
||||
private final double[] micSamples = new double[64];
|
||||
private int micSampleIndex = 0;
|
||||
private double[] targetSliderValue;
|
||||
|
||||
// midi
|
||||
private final Map<Integer, SVGPath> CCMap = new HashMap<>();
|
||||
|
@ -144,6 +146,22 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
|
|||
|
||||
@Override
|
||||
public void initialize(URL url, ResourceBundle resourceBundle) {
|
||||
List<Slider> sliders = sliders();
|
||||
List<CheckBox> micCheckBoxes = micCheckBoxes();
|
||||
targetSliderValue = new double[sliders.size()];
|
||||
for (int i = 0; i < sliders.size(); i++) {
|
||||
targetSliderValue[i] = sliders.get(i).getValue();
|
||||
if (micCheckBoxes.get(i) != null) {
|
||||
CheckBox checkBox = micCheckBoxes.get(i);
|
||||
int finalI = i;
|
||||
sliders.get(i).valueProperty().addListener((e, old, value) -> {
|
||||
if (!checkBox.isSelected()) {
|
||||
targetSliderValue[finalI] = value.doubleValue();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
scrollPane.getContent().setOnScroll(scrollEvent -> {
|
||||
double deltaY = scrollEvent.getDeltaY() * SCROLL_SPEED;
|
||||
scrollPane.setVvalue(scrollPane.getVvalue() - deltaY);
|
||||
|
@ -518,6 +536,7 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
|
|||
if (nodes.getLength() > 0) {
|
||||
String value = nodes.item(0).getTextContent();
|
||||
sliders.get(i).setValue(Float.parseFloat(value));
|
||||
targetSliderValue[i] = Float.parseFloat(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -700,7 +719,10 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
|
|||
volume += Math.abs(micSample);
|
||||
}
|
||||
volume /= micSamples.length;
|
||||
volume = Math.min(1.0, volume * 2);
|
||||
volume = Math.min(1.0, Math.max(-1.0, volume * generalController.getMicVolume()));
|
||||
if (volume < MIN_MIC_VOLUME && volume > -MIN_MIC_VOLUME) {
|
||||
volume = 0;
|
||||
}
|
||||
|
||||
List<Slider> sliders = sliders();
|
||||
List<CheckBox> checkBoxes = micCheckBoxes();
|
||||
|
@ -711,7 +733,13 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
|
|||
// allow for sliders without a mic checkbox
|
||||
if (checkBoxes.get(i) != null) {
|
||||
if (checkBoxes.get(i).isSelected()) {
|
||||
double sliderValue = getValueInSliderRange(sliders.get(i), finalVolume);
|
||||
Slider slider = sliders.get(i);
|
||||
double sliderValue = targetSliderValue[i] + getValueInSliderRange(slider, finalVolume);
|
||||
if (sliderValue > slider.getMax()) {
|
||||
sliderValue = slider.getMax();
|
||||
} else if (sliderValue < slider.getMin()) {
|
||||
sliderValue = slider.getMin();
|
||||
}
|
||||
sliders.get(i).setValue(sliderValue);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<?import javafx.scene.layout.AnchorPane?>
|
||||
<?import javafx.scene.shape.SVGPath?>
|
||||
|
||||
<AnchorPane id="control-pane" prefHeight="315.0" prefWidth="511.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="352.0" prefWidth="511.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="53.0" mnemonicParsing="false" prefHeight="26.0" prefWidth="114.0" text="Choose File" />
|
||||
<Label fx:id="fileLabel" layoutX="143.0" layoutY="57.0" maxWidth="270.0" prefHeight="18.0" prefWidth="246.0" text="cube.obj" />
|
||||
|
@ -22,8 +22,11 @@
|
|||
<TextField fx:id="recordTextField" disable="true" layoutX="370.0" layoutY="154.0" prefHeight="26.0" prefWidth="70.0" text="2.0" />
|
||||
<Label fx:id="recordLengthLabel" disable="true" layoutX="360.0" layoutY="128.0" text="Record length (s)" />
|
||||
<CheckBox fx:id="recordCheckBox" layoutX="154.0" layoutY="146.0" mnemonicParsing="false" text="Timed record" />
|
||||
<Slider fx:id="octaveSlider" blockIncrement="1.0" layoutX="65.0" layoutY="271.0" majorTickUnit="1.0" max="5.0" min="-5.0" minorTickCount="0" prefHeight="42.0" prefWidth="358.0" showTickLabels="true" showTickMarks="true" snapToTicks="true" />
|
||||
<Slider fx:id="octaveSlider" blockIncrement="1.0" layoutX="81.0" layoutY="271.0" majorTickUnit="1.0" max="5.0" min="-5.0" minorTickCount="0" prefHeight="42.0" prefWidth="342.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="433.0" layoutY="267.0" pickOnBounds="true" />
|
||||
<Label layoutX="12.0" layoutY="270.0" text="Octave" />
|
||||
<Slider fx:id="micVolumeSlider" blockIncrement="1.0" layoutX="81.0" layoutY="310.0" majorTickUnit="1.0" max="10.0" prefHeight="42.0" prefWidth="342.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="433.0" layoutY="306.0" pickOnBounds="true" />
|
||||
<Label layoutX="12.0" layoutY="309.0" text="Mic Volume" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
<Font size="13.0" />
|
||||
</font>
|
||||
</Label>
|
||||
<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" />
|
||||
<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="3.0" />
|
||||
<Label layoutX="33.0" layoutY="235.0" text="Volume scale">
|
||||
<font>
|
||||
<Font size="13.0" />
|
||||
|
|
Ładowanie…
Reference in New Issue