kopia lustrzana https://github.com/jameshball/osci-render
Clean-up old code and make AudioPlayer non-static
rodzic
949d8f63f3
commit
b00734fb15
|
@ -14,20 +14,30 @@ public class AudioClient {
|
|||
public static final int SAMPLE_RATE = 192000;
|
||||
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) {
|
||||
// TODO: Calculate weight of lines using depth.
|
||||
// Reduce weight of lines drawn multiple times.
|
||||
// Find intersections of lines to (possibly) improve line cleanup.
|
||||
// Improve performance of line cleanup with a heuristic.
|
||||
|
||||
Camera camera = new Camera(0.6, new Vector3(0, 0, -0.08));
|
||||
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<>();
|
||||
|
||||
String objFilePath = args[0];
|
||||
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++) {
|
||||
preRenderedFrames.add(new ArrayList<>());
|
||||
|
@ -39,11 +49,10 @@ public class AudioClient {
|
|||
preRenderedFrames.set(frameNum, Shapes.sortLines(camera.draw(clone)));
|
||||
});
|
||||
|
||||
System.out.println(System.currentTimeMillis() - start);
|
||||
|
||||
AudioPlayer player = new AudioPlayer(SAMPLE_RATE, preRenderedFrames);
|
||||
//AudioPlayer.setRotateSpeed(1);
|
||||
//AudioPlayer.setTranslation(1, new Vector2(1, 1));
|
||||
player.setRotateSpeed(ROTATE_SPEED);
|
||||
player.setTranslation(TRANSLATION_SPEED, TRANSLATION);
|
||||
player.setScale(SCALE);
|
||||
player.start();
|
||||
}
|
||||
}
|
|
@ -2,30 +2,27 @@ package audio;
|
|||
|
||||
import com.xtaudio.xt.*;
|
||||
import shapes.Shape;
|
||||
import shapes.Shapes;
|
||||
import shapes.Vector2;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class AudioPlayer extends Thread {
|
||||
private static double[] phases = new double[2];
|
||||
private static XtFormat FORMAT;
|
||||
|
||||
private static List<Shape> shapes = new ArrayList<>();
|
||||
private static List<List<? extends Shape>> frames = new ArrayList<>();
|
||||
private static int currentFrame = 0;
|
||||
private static int currentShape = 0;
|
||||
private static long timeOfLastFrame;
|
||||
private static int audioFramesDrawn = 0;
|
||||
|
||||
private static double TRANSLATE_SPEED = 0;
|
||||
private static Vector2 TRANSLATE_VECTOR;
|
||||
private static final int TRANSLATE_PHASE_INDEX = 0;
|
||||
private static double ROTATE_SPEED = 0;
|
||||
private static final int ROTATE_PHASE_INDEX = 1;
|
||||
private static double SCALE = 1;
|
||||
private static double WEIGHT = 100;
|
||||
private double translateSpeed = 0;
|
||||
private Vector2 translateVector = new Vector2();
|
||||
private Phase translatePhase = new Phase();
|
||||
private double rotateSpeed = 0;
|
||||
private Phase rotatePhase = new Phase();
|
||||
private double scale = 1;
|
||||
private double weight = 100;
|
||||
|
||||
private volatile boolean stopped;
|
||||
|
||||
|
@ -35,12 +32,12 @@ public class AudioPlayer extends Thread {
|
|||
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) {
|
||||
for (int f = 0; f < audioFrames; f++) {
|
||||
Shape shape = getCurrentShape();
|
||||
|
||||
shape = shape.setWeight(WEIGHT);
|
||||
shape = shape.setWeight(weight);
|
||||
shape = scale(shape);
|
||||
shape = rotate(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) {
|
||||
if (ROTATE_SPEED != 0) {
|
||||
private Shape rotate(Shape shape, double sampleRate) {
|
||||
if (rotateSpeed != 0) {
|
||||
shape = shape.rotate(
|
||||
nextTheta(sampleRate, ROTATE_SPEED, TRANSLATE_PHASE_INDEX)
|
||||
nextTheta(sampleRate, rotateSpeed, translatePhase)
|
||||
);
|
||||
}
|
||||
|
||||
return shape;
|
||||
}
|
||||
|
||||
private static Shape translate(Shape shape, double sampleRate) {
|
||||
if (TRANSLATE_SPEED != 0 && !TRANSLATE_VECTOR.equals(new Vector2())) {
|
||||
return shape.translate(TRANSLATE_VECTOR.scale(
|
||||
Math.sin(nextTheta(sampleRate, TRANSLATE_SPEED, ROTATE_PHASE_INDEX))
|
||||
private Shape translate(Shape shape, double sampleRate) {
|
||||
if (translateSpeed != 0 && !translateVector.equals(new Vector2())) {
|
||||
return shape.translate(translateVector.scale(
|
||||
Math.sin(nextTheta(sampleRate, translateSpeed, rotatePhase))
|
||||
));
|
||||
}
|
||||
|
||||
return shape;
|
||||
}
|
||||
|
||||
static double nextTheta(double sampleRate, double frequency, int phaseIndex) {
|
||||
phases[phaseIndex] += frequency / sampleRate;
|
||||
private double nextTheta(double sampleRate, double frequency, Phase phase) {
|
||||
phase.value += frequency / sampleRate;
|
||||
|
||||
if (phases[phaseIndex] >= 1.0) {
|
||||
phases[phaseIndex] = -1.0;
|
||||
if (phase.value >= 1.0) {
|
||||
phase.value = -1.0;
|
||||
}
|
||||
|
||||
return phases[phaseIndex] * Math.PI;
|
||||
return phase.value * Math.PI;
|
||||
}
|
||||
|
||||
private static Shape scale(Shape shape) {
|
||||
if (SCALE != 1) {
|
||||
return shape.scale(SCALE);
|
||||
private Shape scale(Shape shape) {
|
||||
if (scale != 1) {
|
||||
return shape.scale(scale);
|
||||
}
|
||||
|
||||
return shape;
|
||||
}
|
||||
|
||||
public static void setRotateSpeed(double speed) {
|
||||
AudioPlayer.ROTATE_SPEED = speed;
|
||||
public void setRotateSpeed(double speed) {
|
||||
this.rotateSpeed = speed;
|
||||
}
|
||||
|
||||
public static void setTranslation(double speed, Vector2 translation) {
|
||||
AudioPlayer.TRANSLATE_SPEED = speed;
|
||||
AudioPlayer.TRANSLATE_VECTOR = translation;
|
||||
public void setTranslation(double speed, Vector2 translation) {
|
||||
this.translateSpeed = speed;
|
||||
this.translateVector = translation;
|
||||
}
|
||||
|
||||
public static void setScale(double scale) {
|
||||
AudioPlayer.SCALE = scale;
|
||||
public void setScale(double scale) {
|
||||
this.scale = scale;
|
||||
}
|
||||
|
||||
public static void addShape(Shape shape) {
|
||||
shapes.add(shape);
|
||||
public void setWeight(double weight) {
|
||||
this.weight = weight;
|
||||
}
|
||||
|
||||
public static void addShapes(List<? extends Shape> newShapes) {
|
||||
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() {
|
||||
private Shape getCurrentShape() {
|
||||
if (frames.size() == 0 || frames.get(currentFrame).size() == 0) {
|
||||
return new Vector2(0, 0);
|
||||
}
|
||||
|
@ -152,7 +137,7 @@ public class AudioPlayer extends Thread {
|
|||
|
||||
XtBuffer buffer = device.getBuffer(FORMAT);
|
||||
try (XtStream stream = device.openStream(FORMAT, true, false,
|
||||
buffer.current, AudioPlayer::render, null, null)) {
|
||||
buffer.current, this::render, null, null)) {
|
||||
stream.start();
|
||||
while (!stopped) {
|
||||
Thread.onSpinWait();
|
||||
|
@ -167,4 +152,9 @@ public class AudioPlayer extends Thread {
|
|||
public void stopPlaying() {
|
||||
stopped = true;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class Phase {
|
||||
private double value = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,15 @@ public class WorldObject {
|
|||
private Vector3 position;
|
||||
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) {
|
||||
this.vertices = new ArrayList<>();
|
||||
this.edgeData = new ArrayList<>();
|
||||
|
@ -80,18 +89,6 @@ public class WorldObject {
|
|||
}
|
||||
|
||||
public WorldObject clone() {
|
||||
List<Vector3> newVertices = new ArrayList<>();
|
||||
|
||||
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());
|
||||
return new WorldObject(new ArrayList<>(vertices), new ArrayList<>(edgeData), position, rotation);
|
||||
}
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue