183 lines
5.1 KiB
Java
Executable File
183 lines
5.1 KiB
Java
Executable File
package soundtrack.optical;
|
|
|
|
import processing.core.*;
|
|
import processing.sound.*;
|
|
|
|
public class SoundtrackOptical {
|
|
String TYPE = "dual variable area";
|
|
int DPI = 2880;
|
|
boolean POSITIVE = true;
|
|
float VOLUME = (float) 1.0;
|
|
String pitch = "long";
|
|
String FILEPATH;
|
|
|
|
float IN = (float) 25.4;
|
|
float FRAME_H = (float) 7.62;
|
|
float FRAME_W = (float) (12.52 - 10.26);
|
|
|
|
float DPMM = (float) (DPI / IN);
|
|
int FRAME_H_PIXELS = (int) Math.round(DPMM * FRAME_H);
|
|
int SAMPLE_RATE = FRAME_H_PIXELS * 24;
|
|
int DEPTH = (int) Math.round(DPMM * FRAME_W);
|
|
|
|
int RAW_RATE = 0;
|
|
int RAW_FRAME_H = 0;
|
|
int RAW_FRAME_W = 0;
|
|
|
|
int LINE_W = 0;
|
|
float DENSITY = 0;
|
|
int LEFT = 0;
|
|
int FRAMES = 0;
|
|
int i = 0;
|
|
|
|
float max = 0;
|
|
float min = 0;
|
|
float compare;
|
|
|
|
float[] frameSample;
|
|
SoundFile soundfile;
|
|
PGraphics raw;
|
|
PApplet parent;
|
|
|
|
/**
|
|
* @constructor
|
|
*
|
|
*
|
|
* @param parent {PApplet} Parent process (usually this)
|
|
* @param soundtrackFile {String} Path to soundtrackFile
|
|
* @param dpi {Integer} Target DPI of printer
|
|
* @param volume {Float} Volume of output soundtrack, 0 to 1.0
|
|
* @param type {String} Type of soundtrack either "unilateral", "variable area", "dual variable area", "multiple variable area", "variable density"
|
|
* @param pitch {String} Pitch of the film, either "long" for projection or "short" for camera stock
|
|
* @param positive {Boolean} Whether or not soundtrack is positive or negative
|
|
*/
|
|
|
|
@SuppressWarnings("static-access")
|
|
public SoundtrackOptical (PApplet parent, String soundtrackFile, int dpi, float volume, String type, String pitch, boolean positive ) {
|
|
this.parent = parent;
|
|
|
|
FILEPATH = soundtrackFile;
|
|
TYPE = type;
|
|
DPI = dpi;
|
|
VOLUME = volume;
|
|
POSITIVE = positive;
|
|
FRAME_H = (float) ((pitch == "long") ? 7.62 : 7.605);
|
|
DPMM = DPI / IN;
|
|
FRAME_H_PIXELS = (int) Math.round(DPMM * FRAME_H);
|
|
SAMPLE_RATE = FRAME_H_PIXELS * 24;
|
|
DEPTH = (int) Math.floor(DPMM * FRAME_W);
|
|
|
|
soundfile = new SoundFile(parent, FILEPATH);
|
|
|
|
RAW_RATE = soundfile.sampleRate();
|
|
RAW_FRAME_H = Math.round(RAW_RATE / 24);
|
|
RAW_FRAME_W = Math.round(((RAW_RATE / 24) / FRAME_H ) * FRAME_W);
|
|
FRAMES = (int) Math.ceil(soundfile.frames() / RAW_FRAME_H);
|
|
|
|
frameSample = new float[RAW_FRAME_H];
|
|
raw = parent.createGraphics(RAW_FRAME_W, RAW_FRAME_H);//mode option?
|
|
|
|
|
|
for (int x = 0; x < soundfile.frames(); x++) {
|
|
compare = soundfile.read(x);
|
|
if (compare > max) {
|
|
max = compare;
|
|
}
|
|
if (compare < min) {
|
|
min = compare;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void draw (int X, int Y) {
|
|
frame(X, Y, parent.frameCount);
|
|
}
|
|
|
|
@SuppressWarnings("static-access")
|
|
public void frame(int X, int Y, int frameNumber) {
|
|
if (frameNumber != -1) {
|
|
i = frameNumber;
|
|
}
|
|
if (i >= FRAMES) {
|
|
return;
|
|
}
|
|
raw.beginDraw();
|
|
//draw bg
|
|
raw.noStroke();
|
|
if (POSITIVE) {
|
|
raw.fill(0);
|
|
} else {
|
|
raw.fill(255);
|
|
}
|
|
|
|
if (TYPE != "variable density") {
|
|
raw.rect(0, 0, RAW_FRAME_W, RAW_FRAME_H);
|
|
}
|
|
|
|
//draw top
|
|
if (POSITIVE) {
|
|
raw.stroke(255);
|
|
} else {
|
|
raw.stroke(0);
|
|
}
|
|
|
|
soundfile.read(i * RAW_FRAME_H, frameSample, 0, RAW_FRAME_H);
|
|
|
|
for (int y = 0; y < RAW_FRAME_H; y++) {
|
|
if (TYPE != "variable density") {
|
|
LINE_W = Math.round(parent.map(frameSample[y], min, max, (float) 0, RAW_FRAME_W * VOLUME));
|
|
}
|
|
if (TYPE == "unilateral") {
|
|
unilateral(y, LINE_W);
|
|
} else if (TYPE == "dual unilateral") {
|
|
/* TODO!!!! */
|
|
} else if (TYPE == "single variable area" || TYPE == "variable area") {
|
|
variableArea(y, LINE_W);
|
|
} else if (TYPE == "dual variable area") {
|
|
dualVariableArea(y, LINE_W);
|
|
} else if (TYPE == "multiple variable area" || TYPE == "maurer") {
|
|
multipleVariableArea(y, LINE_W);
|
|
} else if (TYPE == "variable density") {
|
|
variableDensity(y);
|
|
}
|
|
}
|
|
raw.endDraw();
|
|
parent.image(raw, X, Y, DEPTH, FRAME_H_PIXELS);
|
|
if (frameNumber == -1) {
|
|
i++;
|
|
}
|
|
}
|
|
|
|
private void unilateral (int y, int LINE_W) {
|
|
raw.line(0, y, LINE_W, y);
|
|
}
|
|
|
|
private void variableArea (int y, int LINE_W) {
|
|
LEFT = Math.round((RAW_FRAME_W - LINE_W) / 2);
|
|
raw.line(LEFT, y, LEFT + LINE_W, y);
|
|
}
|
|
|
|
private void dualVariableArea (int y, int LINE_W) {
|
|
LEFT = Math.round((RAW_FRAME_W / 4) - (LINE_W / 4));
|
|
raw.line(LEFT, y, LEFT + (LINE_W / 2), y);
|
|
raw.line(LEFT + (RAW_FRAME_W / 2), y, LEFT + (RAW_FRAME_W / 2) + (LINE_W / 2), y);
|
|
}
|
|
|
|
private void multipleVariableArea (int y, int LINE_W) {
|
|
LEFT = Math.round((RAW_FRAME_W / 16) - (LINE_W / 16));
|
|
for (int x = 1; x < 7; x++) {
|
|
raw.line(LEFT + ((x * RAW_FRAME_W) / 8), y, LEFT + ((x * RAW_FRAME_W) / 8) + (LINE_W / 8), y);
|
|
}
|
|
}
|
|
@SuppressWarnings("static-access")
|
|
private void variableDensity(int y) {
|
|
DENSITY = parent.map(frameSample[y], min, max, (float) 0, 255 * VOLUME);
|
|
if (POSITIVE) {
|
|
raw.stroke(DENSITY);
|
|
} else {
|
|
raw.stroke(255 - DENSITY);
|
|
}
|
|
raw.line(0, y, RAW_FRAME_W, y);
|
|
}
|
|
}
|