Heavy refactor of main function

pull/35/head
James Ball 2020-10-18 14:29:47 +01:00
rodzic c67225c21f
commit 7b7e3b8464
3 zmienionych plików z 90 dodań i 29 usunięć

Wyświetl plik

@ -0,0 +1,59 @@
package audio;
// Helper class for AudioClient that deals with optional program arguments.
final class AudioArgs {
final String objFilePath;
final float[] optionalArgs;
AudioArgs(String[] args) throws IllegalAudioArgumentException {
if (args.length < 1 || args.length > 6) {
throw new IllegalAudioArgumentException();
}
objFilePath = args[0];
optionalArgs = new float[args.length - 1];
for (int i = 0; i < optionalArgs.length; i++) {
optionalArgs[i] = Float.parseFloat(args[i + 1]);
}
}
String objFilePath() {
return objFilePath;
}
float rotateSpeed() {
return getArg(0, 0);
}
float cameraX() {
return getArg(1, 0);
}
float cameraY() {
return getArg(2, 0);
}
float cameraZ() {
return getArg(3, 0);
}
float focalLength() {
return getArg(4, 1);
}
private float getArg(int n, float defaultVal) {
return optionalArgs.length > n ? optionalArgs[n] : defaultVal;
}
private class IllegalAudioArgumentException extends IllegalArgumentException {
private static final String USAGE = "Incorrect usage.\nUsage: osci-render objFilePath "
+ "[rotateSpeed] [cameraX] [cameraY] [cameraZ] [focalLength]";
public IllegalAudioArgumentException() {
super(USAGE);
}
}
}

Wyświetl plik

@ -12,6 +12,7 @@ import shapes.Shapes;
import shapes.Vector2;
public class AudioClient {
private static final int SAMPLE_RATE = 192000;
private static double OBJ_ROTATE_SPEED = Math.PI / 1000;
private static final float ROTATE_SPEED = 0;
@ -30,32 +31,38 @@ public class AudioClient {
//
// example:
// osci-render models/cube.obj 1 0 0 -3 10
public static void main(String[] args) {
public static void main(String[] programArgs) {
// 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.
String objFilePath = args[0];
float focalLength = Float.parseFloat(args[1]);
float cameraX = Float.parseFloat(args[2]);
float cameraY = Float.parseFloat(args[3]);
float cameraZ = Float.parseFloat(args[4]);
AudioArgs args = new AudioArgs(programArgs);
OBJ_ROTATE_SPEED *= Double.parseDouble(args[5]);
OBJ_ROTATE_SPEED *= args.rotateSpeed();
int numFrames = (int) (2 * Math.PI / OBJ_ROTATE_SPEED);
Camera camera = new Camera(focalLength, new Vector3(cameraX, cameraY, cameraZ));
WorldObject object = new WorldObject(objFilePath);
Vector3 cameraPos = new Vector3(args.cameraX(), args.cameraY(), args.cameraZ());
Camera camera = new Camera(args.focalLength(), cameraPos);
WorldObject object = new WorldObject(args.objFilePath());
Vector3 rotation = new Vector3(0, OBJ_ROTATE_SPEED, OBJ_ROTATE_SPEED);
System.out.println("Begin pre-render...");
List<List<? extends Shape>> frames = preRender(object, rotation, camera);
System.out.println("Finish pre-render");
System.out.println("Connecting to audio player");
AudioPlayer player = new AudioPlayer(SAMPLE_RATE, frames, ROTATE_SPEED, TRANSLATION_SPEED, TRANSLATION, SCALE, WEIGHT);
System.out.println("Starting audio stream");
player.play();
}
private static List<List<? extends Shape>> preRender(WorldObject object, Vector3 rotation, Camera camera) {
List<List<? extends Shape>> preRenderedFrames = new ArrayList<>();
int numFrames = (int) (2 * Math.PI / OBJ_ROTATE_SPEED);
for (int i = 0; i < numFrames; i++) {
preRenderedFrames.add(new ArrayList<>());
}
System.out.println("Begin pre-render...");
AtomicInteger renderedFrames = new AtomicInteger();
// pre-renders the WorldObject in parallel
@ -70,16 +77,6 @@ public class AudioClient {
}
});
System.out.println("Finish pre-render");
System.out.println("Connecting to audio player");
AudioPlayer player = new AudioPlayer(SAMPLE_RATE, preRenderedFrames);
player.setRotateSpeed(ROTATE_SPEED);
player.setTranslation(TRANSLATION_SPEED, TRANSLATION);
player.setScale(SCALE);
player.setWeight(WEIGHT);
System.out.println("Starting audio stream");
player.start();
return preRenderedFrames;
}
}

Wyświetl plik

@ -1,14 +1,12 @@
package audio;
import com.xtaudio.xt.*;
import java.time.Duration;
import java.time.Instant;
import shapes.Shape;
import shapes.Vector2;
import java.util.List;
public class AudioPlayer extends Thread {
public class AudioPlayer {
private final XtFormat FORMAT;
private final List<List<? extends Shape>> frames;
@ -31,6 +29,14 @@ public class AudioPlayer extends Thread {
this.frames = frames;
}
public AudioPlayer(int sampleRate, List<List<? extends Shape>> frames, float rotateSpeed, float translateSpeed, Vector2 translateVector, float scale, float weight) {
this(sampleRate, frames);
setRotateSpeed(rotateSpeed);
setTranslation(translateSpeed, translateVector);
setScale(scale);
setWeight(weight);
}
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++) {
@ -126,14 +132,13 @@ public class AudioPlayer extends Thread {
return frames.get(currentFrame).get(currentShape);
}
@Override
public void run() {
public void play() {
try (XtAudio audio = new XtAudio(null, null, null, null)) {
XtService service = XtAudio.getServiceBySetup(XtSetup.CONSUMER_AUDIO);
try (XtDevice device = service.openDefaultDevice(true)) {
if (device != null && device.supportsFormat(FORMAT)) {
XtBuffer buffer = device.getBuffer(FORMAT);
try (XtStream stream = device.openStream(FORMAT, true, false,
buffer.current, this::render, null, null)) {
stream.start();