Add micVolume slider, change bitCrush start/end, make mic move around the original set point

pull/50/head v1.18.4
James Ball 2022-03-05 17:13:47 +00:00
rodzic b880c165a3
commit 30317b8d33
8 zmienionych plików z 69 dodań i 20 usunięć

Wyświetl plik

@ -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>

Wyświetl plik

@ -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) {

Wyświetl plik

@ -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);
}
}

Wyświetl plik

@ -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

Wyświetl plik

@ -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

Wyświetl plik

@ -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);
}
}

Wyświetl plik

@ -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>

Wyświetl plik

@ -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" />