Clean-up old code and make AudioPlayer non-static

pull/35/head
James Ball 2020-10-01 12:12:07 +01:00
rodzic 949d8f63f3
commit b00734fb15
3 zmienionych plików z 70 dodań i 74 usunięć

Wyświetl plik

@ -14,20 +14,30 @@ public class AudioClient {
public static final int SAMPLE_RATE = 192000; public static final int SAMPLE_RATE = 192000;
public static final double TARGET_FRAMERATE = 30; public static final double TARGET_FRAMERATE = 30;
private static final double OBJ_ROTATE = Math.PI / 100;
private static final float ROTATE_SPEED = 0;
private static final float TRANSLATION_SPEED = 0;
private static final Vector2 TRANSLATION = new Vector2(1, 1);
private static final float SCALE = 2;
private static final float WEIGHT = 100;
public static void main(String[] args) { public static void main(String[] args) {
// TODO: Calculate weight of lines using depth. // TODO: Calculate weight of lines using depth.
// Reduce weight of lines drawn multiple times. // Reduce weight of lines drawn multiple times.
// Find intersections of lines to (possibly) improve line cleanup. // Find intersections of lines to (possibly) improve line cleanup.
// Improve performance of line cleanup with a heuristic. // Improve performance of line cleanup with a heuristic.
Camera camera = new Camera(0.6, new Vector3(0, 0, -0.08)); String objFilePath = args[0];
WorldObject object = new WorldObject(args[0], new Vector3(0, 0, 0), new Vector3());
Vector3 rotation = new Vector3(0,Math.PI / 100,Math.PI / 100);
List<List<? extends Shape>> preRenderedFrames = new ArrayList<>();
int numFrames = (int) (Float.parseFloat(args[1]) * TARGET_FRAMERATE); int numFrames = (int) (Float.parseFloat(args[1]) * TARGET_FRAMERATE);
float focalLength = Float.parseFloat(args[2]);
float cameraX = Float.parseFloat(args[3]);
float cameraY = Float.parseFloat(args[4]);
float cameraZ = Float.parseFloat(args[5]);
long start = System.currentTimeMillis(); Camera camera = new Camera(focalLength, new Vector3(cameraX, cameraY, cameraZ));
WorldObject object = new WorldObject(objFilePath);
Vector3 rotation = new Vector3(0, OBJ_ROTATE, OBJ_ROTATE);
List<List<? extends Shape>> preRenderedFrames = new ArrayList<>();
for (int i = 0; i < numFrames; i++) { for (int i = 0; i < numFrames; i++) {
preRenderedFrames.add(new ArrayList<>()); preRenderedFrames.add(new ArrayList<>());
@ -39,11 +49,10 @@ public class AudioClient {
preRenderedFrames.set(frameNum, Shapes.sortLines(camera.draw(clone))); preRenderedFrames.set(frameNum, Shapes.sortLines(camera.draw(clone)));
}); });
System.out.println(System.currentTimeMillis() - start);
AudioPlayer player = new AudioPlayer(SAMPLE_RATE, preRenderedFrames); AudioPlayer player = new AudioPlayer(SAMPLE_RATE, preRenderedFrames);
//AudioPlayer.setRotateSpeed(1); player.setRotateSpeed(ROTATE_SPEED);
//AudioPlayer.setTranslation(1, new Vector2(1, 1)); player.setTranslation(TRANSLATION_SPEED, TRANSLATION);
player.setScale(SCALE);
player.start(); player.start();
} }
} }

Wyświetl plik

@ -2,30 +2,27 @@ package audio;
import com.xtaudio.xt.*; import com.xtaudio.xt.*;
import shapes.Shape; import shapes.Shape;
import shapes.Shapes;
import shapes.Vector2; import shapes.Vector2;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
public class AudioPlayer extends Thread { public class AudioPlayer extends Thread {
private static double[] phases = new double[2];
private static XtFormat FORMAT; private static XtFormat FORMAT;
private static List<Shape> shapes = new ArrayList<>();
private static List<List<? extends Shape>> frames = new ArrayList<>(); private static List<List<? extends Shape>> frames = new ArrayList<>();
private static int currentFrame = 0; private static int currentFrame = 0;
private static int currentShape = 0; private static int currentShape = 0;
private static long timeOfLastFrame; private static long timeOfLastFrame;
private static int audioFramesDrawn = 0; private static int audioFramesDrawn = 0;
private static double TRANSLATE_SPEED = 0; private double translateSpeed = 0;
private static Vector2 TRANSLATE_VECTOR; private Vector2 translateVector = new Vector2();
private static final int TRANSLATE_PHASE_INDEX = 0; private Phase translatePhase = new Phase();
private static double ROTATE_SPEED = 0; private double rotateSpeed = 0;
private static final int ROTATE_PHASE_INDEX = 1; private Phase rotatePhase = new Phase();
private static double SCALE = 1; private double scale = 1;
private static double WEIGHT = 100; private double weight = 100;
private volatile boolean stopped; private volatile boolean stopped;
@ -35,12 +32,12 @@ public class AudioPlayer extends Thread {
AudioPlayer.timeOfLastFrame = System.currentTimeMillis(); AudioPlayer.timeOfLastFrame = System.currentTimeMillis();
} }
static void render(XtStream stream, Object input, Object output, int audioFrames, private void render(XtStream stream, Object input, Object output, int audioFrames,
double time, long position, boolean timeValid, long error, Object user) { double time, long position, boolean timeValid, long error, Object user) {
for (int f = 0; f < audioFrames; f++) { for (int f = 0; f < audioFrames; f++) {
Shape shape = getCurrentShape(); Shape shape = getCurrentShape();
shape = shape.setWeight(WEIGHT); shape = shape.setWeight(weight);
shape = scale(shape); shape = scale(shape);
shape = rotate(shape, FORMAT.mix.rate); shape = rotate(shape, FORMAT.mix.rate);
shape = translate(shape, FORMAT.mix.rate); shape = translate(shape, FORMAT.mix.rate);
@ -68,74 +65,62 @@ public class AudioPlayer extends Thread {
} }
} }
private static Shape rotate(Shape shape, double sampleRate) { private Shape rotate(Shape shape, double sampleRate) {
if (ROTATE_SPEED != 0) { if (rotateSpeed != 0) {
shape = shape.rotate( shape = shape.rotate(
nextTheta(sampleRate, ROTATE_SPEED, TRANSLATE_PHASE_INDEX) nextTheta(sampleRate, rotateSpeed, translatePhase)
); );
} }
return shape; return shape;
} }
private static Shape translate(Shape shape, double sampleRate) { private Shape translate(Shape shape, double sampleRate) {
if (TRANSLATE_SPEED != 0 && !TRANSLATE_VECTOR.equals(new Vector2())) { if (translateSpeed != 0 && !translateVector.equals(new Vector2())) {
return shape.translate(TRANSLATE_VECTOR.scale( return shape.translate(translateVector.scale(
Math.sin(nextTheta(sampleRate, TRANSLATE_SPEED, ROTATE_PHASE_INDEX)) Math.sin(nextTheta(sampleRate, translateSpeed, rotatePhase))
)); ));
} }
return shape; return shape;
} }
static double nextTheta(double sampleRate, double frequency, int phaseIndex) { private double nextTheta(double sampleRate, double frequency, Phase phase) {
phases[phaseIndex] += frequency / sampleRate; phase.value += frequency / sampleRate;
if (phases[phaseIndex] >= 1.0) { if (phase.value >= 1.0) {
phases[phaseIndex] = -1.0; phase.value = -1.0;
} }
return phases[phaseIndex] * Math.PI; return phase.value * Math.PI;
} }
private static Shape scale(Shape shape) { private Shape scale(Shape shape) {
if (SCALE != 1) { if (scale != 1) {
return shape.scale(SCALE); return shape.scale(scale);
} }
return shape; return shape;
} }
public static void setRotateSpeed(double speed) { public void setRotateSpeed(double speed) {
AudioPlayer.ROTATE_SPEED = speed; this.rotateSpeed = speed;
} }
public static void setTranslation(double speed, Vector2 translation) { public void setTranslation(double speed, Vector2 translation) {
AudioPlayer.TRANSLATE_SPEED = speed; this.translateSpeed = speed;
AudioPlayer.TRANSLATE_VECTOR = translation; this.translateVector = translation;
} }
public static void setScale(double scale) { public void setScale(double scale) {
AudioPlayer.SCALE = scale; this.scale = scale;
} }
public static void addShape(Shape shape) { public void setWeight(double weight) {
shapes.add(shape); this.weight = weight;
} }
public static void addShapes(List<? extends Shape> newShapes) { private Shape getCurrentShape() {
shapes.addAll(newShapes);
}
public static void updateFrame(List<? extends Shape> frame) {
currentShape = 0;
shapes = new ArrayList<>();
shapes.addAll(frame);
// Arbitrary function for changing weights based on frame draw-time.
AudioPlayer.WEIGHT = 200 * Math.exp(-0.017 * Shapes.totalLength(frame));
}
private static Shape getCurrentShape() {
if (frames.size() == 0 || frames.get(currentFrame).size() == 0) { if (frames.size() == 0 || frames.get(currentFrame).size() == 0) {
return new Vector2(0, 0); return new Vector2(0, 0);
} }
@ -152,7 +137,7 @@ public class AudioPlayer extends Thread {
XtBuffer buffer = device.getBuffer(FORMAT); XtBuffer buffer = device.getBuffer(FORMAT);
try (XtStream stream = device.openStream(FORMAT, true, false, try (XtStream stream = device.openStream(FORMAT, true, false,
buffer.current, AudioPlayer::render, null, null)) { buffer.current, this::render, null, null)) {
stream.start(); stream.start();
while (!stopped) { while (!stopped) {
Thread.onSpinWait(); Thread.onSpinWait();
@ -167,4 +152,9 @@ public class AudioPlayer extends Thread {
public void stopPlaying() { public void stopPlaying() {
stopped = true; stopped = true;
} }
private static final class Phase {
private double value = 0;
} }
}

Wyświetl plik

@ -14,6 +14,15 @@ public class WorldObject {
private Vector3 position; private Vector3 position;
private Vector3 rotation; private Vector3 rotation;
public WorldObject(String filename) {
this.vertices = new ArrayList<>();
this.edgeData = new ArrayList<>();
this.position = new Vector3();
this.rotation = new Vector3();
loadFromFile(filename);
}
public WorldObject(String filename, Vector3 position, Vector3 rotation) { public WorldObject(String filename, Vector3 position, Vector3 rotation) {
this.vertices = new ArrayList<>(); this.vertices = new ArrayList<>();
this.edgeData = new ArrayList<>(); this.edgeData = new ArrayList<>();
@ -80,18 +89,6 @@ public class WorldObject {
} }
public WorldObject clone() { public WorldObject clone() {
List<Vector3> newVertices = new ArrayList<>(); return new WorldObject(new ArrayList<>(vertices), new ArrayList<>(edgeData), position, rotation);
for (Vector3 vertex : vertices) {
newVertices.add(vertex.clone());
}
List<Integer> newEdgeData = new ArrayList<>();
for (int edge : edgeData) {
newEdgeData.add(edge);
}
return new WorldObject(newVertices, newEdgeData, position.clone(), rotation.clone());
} }
} }