kopia lustrzana https://github.com/jameshball/osci-render
rodzic
f5f9246408
commit
9fdab5a4f1
|
@ -1,3 +1,8 @@
|
|||
- 1.24.1
|
||||
- Various optimisations
|
||||
- Mic-based control is now slightly smoother
|
||||
|
||||
|
||||
- 1.24.0
|
||||
- Add spinners to all effect sliders
|
||||
- Add spinner to frequency slider
|
||||
|
|
2
pom.xml
2
pom.xml
|
@ -6,7 +6,7 @@
|
|||
|
||||
<groupId>sh.ball</groupId>
|
||||
<artifactId>osci-render</artifactId>
|
||||
<version>1.24.0</version>
|
||||
<version>1.24.1</version>
|
||||
|
||||
<name>osci-render</name>
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ public class ShapeAudioPlayer implements AudioPlayer<List<Shape>> {
|
|||
private final Callable<AudioEngine> audioEngineBuilder;
|
||||
private final BlockingQueue<List<Shape>> frameQueue = new ArrayBlockingQueue<>(BUFFER_SIZE);
|
||||
private final Map<Object, Effect> effects = new ConcurrentHashMap<>();
|
||||
private final List<Listener> listeners = new CopyOnWriteArrayList<>();
|
||||
private final Queue<Listener> listeners = new ConcurrentLinkedQueue<>();
|
||||
|
||||
private AudioEngine audioEngine;
|
||||
private ByteArrayOutputStream outputStream;
|
||||
|
@ -223,17 +223,19 @@ public class ShapeAudioPlayer implements AudioPlayer<List<Shape>> {
|
|||
}
|
||||
|
||||
private Vector2 cutoff(Vector2 vector) {
|
||||
if (vector.getX() < -1) {
|
||||
vector = vector.setX(-1);
|
||||
} else if (vector.getX() > 1) {
|
||||
vector = vector.setX(1);
|
||||
double x = vector.x;
|
||||
double y = vector.y;
|
||||
if (x < -1) {
|
||||
x = -1;
|
||||
} else if (x > 1) {
|
||||
x = 1;
|
||||
}
|
||||
if (vector.getY() < -1) {
|
||||
vector = vector.setY(-1);
|
||||
} else if (vector.getY() > 1) {
|
||||
vector = vector.setY(1);
|
||||
if (y < -1) {
|
||||
y = -1;
|
||||
} else if (y > 1) {
|
||||
y = 1;
|
||||
}
|
||||
return vector;
|
||||
return new Vector2(x, y);
|
||||
}
|
||||
|
||||
private Vector2 applyEffects(int frame, Vector2 vector) {
|
||||
|
|
|
@ -12,9 +12,7 @@ public class BitCrushEffect implements SettableEffect {
|
|||
|
||||
@Override
|
||||
public Vector2 apply(int count, Vector2 vector) {
|
||||
double x = vector.getX();
|
||||
double y = vector.getY();
|
||||
return new Vector2(round(x, crush), round(y, crush));
|
||||
return new Vector2(round(vector.x, crush), round(vector.y, crush));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -39,8 +39,9 @@ public class WobbleEffect extends PhaseEffect implements FrequencyListener, Sett
|
|||
@Override
|
||||
public Vector2 apply(int count, Vector2 vector) {
|
||||
double theta = nextTheta();
|
||||
double x = vector.getX() + volume * Math.sin(frequency * theta);
|
||||
double y = vector.getY() + volume * Math.sin(frequency * theta);
|
||||
double delta = volume * Math.sin(frequency * theta);
|
||||
double x = vector.x + delta;
|
||||
double y = vector.y + delta;
|
||||
|
||||
return new Vector2(x, y);
|
||||
}
|
||||
|
|
|
@ -9,7 +9,8 @@ import java.util.List;
|
|||
public class JavaAudioInput implements AudioInput {
|
||||
|
||||
private static final int DEFAULT_SAMPLE_RATE = 44100;
|
||||
private static final int BUFFER_SIZE = 50;
|
||||
private static final int CHUNK_SIZE = 512;
|
||||
private static final int STEP_SIZE = 32;
|
||||
// java sound doesn't support anything more than 16 bit :(
|
||||
private static final int BIT_DEPTH = 16;
|
||||
// mono
|
||||
|
@ -45,17 +46,19 @@ public class JavaAudioInput implements AudioInput {
|
|||
return;
|
||||
}
|
||||
try {
|
||||
microphone.open(format, BUFFER_SIZE);
|
||||
microphone.open(format);
|
||||
|
||||
// I am well aware this is inefficient - sufficient for the needs of
|
||||
// modifying sliders
|
||||
byte[] data = new byte[2];
|
||||
byte[] data = new byte[CHUNK_SIZE];
|
||||
microphone.start();
|
||||
while (!stopped) {
|
||||
microphone.read(data, 0, 2);
|
||||
short sample = (short) ((data[1] << 8) + data[0]);
|
||||
for (AudioInputListener listener : listeners) {
|
||||
listener.transmit((double) sample / Short.MAX_VALUE);
|
||||
if (microphone.available() >= CHUNK_SIZE) {
|
||||
microphone.read(data, 0, CHUNK_SIZE);
|
||||
for (int i = 0; i < CHUNK_SIZE / 2; i += 2 * STEP_SIZE) {
|
||||
short sample = (short) ((data[2 * i + 1] << 8) + data[2 * i]);
|
||||
for (AudioInputListener listener : listeners) {
|
||||
listener.transmit((double) sample / Short.MAX_VALUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
microphone.close();
|
||||
|
|
|
@ -1109,8 +1109,7 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
|
|||
} else if (sliderValue < slider.getMin()) {
|
||||
sliderValue = slider.getMin();
|
||||
}
|
||||
// TODO: Correctly update frequency spinner!
|
||||
subControllers().forEach(sub -> sub.micSignalReceived());
|
||||
subControllers().forEach(SubController::micSignalReceived);
|
||||
sliders.get(i).setValue(sliderValue);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,7 +59,10 @@ public final class Line extends Shape {
|
|||
|
||||
@Override
|
||||
public Vector2 nextVector(double drawingProgress) {
|
||||
return a.add(b.sub(a).scale(drawingProgress));
|
||||
return new Vector2(
|
||||
a.x + drawingProgress * (b.x - a.x),
|
||||
a.y + drawingProgress * (b.y - a.y)
|
||||
);
|
||||
}
|
||||
|
||||
public Vector2 getA() {
|
||||
|
|
|
@ -61,10 +61,12 @@ public final class Vector2 extends Shape {
|
|||
|
||||
@Override
|
||||
public Vector2 rotate(double theta) {
|
||||
Vector2 vector = setX(getX() * Math.cos(theta) - getY() * Math.sin(theta));
|
||||
vector = vector.setY(getX() * Math.sin(theta) + getY() * Math.cos(theta));
|
||||
|
||||
return vector;
|
||||
double cosTheta = Math.cos(theta);
|
||||
double sinTheta = Math.sin(theta);
|
||||
return new Vector2(
|
||||
x * cosTheta - y * sinTheta,
|
||||
x * sinTheta + y * cosTheta
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -74,12 +76,12 @@ public final class Vector2 extends Shape {
|
|||
|
||||
@Override
|
||||
public Vector2 scale(Vector2 vector) {
|
||||
return new Vector2(getX() * vector.getX(), getY() * vector.getY());
|
||||
return new Vector2(x * vector.x, y * vector.y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector2 translate(Vector2 vector) {
|
||||
return new Vector2(getX() + vector.getX(), getY() + vector.getY());
|
||||
return new Vector2(x + vector.x, y + vector.y);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -96,13 +98,12 @@ public final class Vector2 extends Shape {
|
|||
return false;
|
||||
}
|
||||
Vector2 point = (Vector2) obj;
|
||||
return round(x, 2) == round(point.x, 2)
|
||||
&& round(y, 2) == round(point.y, 2);
|
||||
return x == point.x && y == point.y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(round(x, 2), round(y, 2));
|
||||
return Objects.hash(x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Ładowanie…
Reference in New Issue