kopia lustrzana https://github.com/jameshball/osci-render
Heavy refactor of main function
rodzic
c67225c21f
commit
7b7e3b8464
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
|
|
Ładowanie…
Reference in New Issue