From 315f1bd2964d0995eec5ba17066b5652023026ab Mon Sep 17 00:00:00 2001 From: litter Date: Wed, 22 Jan 2020 12:29:53 -0500 Subject: [PATCH] Add a new `buffer()` method that returns the PGraphics object of a specific frame. This is needed for a new project that remains a secret. --- README.md | 12 +++- examples/BufferExample/BufferExample.pde | 27 +++++++++ examples/FrameExample/FrameExample.pde | 27 +++++++++ library/SoundtrackOptical.jar | Bin 1176389 -> 1177701 bytes src/soundtrack/optical/SoundtrackOptical.java | 52 ++++++++++++++++++ 5 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 examples/BufferExample/BufferExample.pde create mode 100644 examples/FrameExample/FrameExample.pde diff --git a/README.md b/README.md index ac05381..a003698 100755 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ void draw () { } ``` -### Alternate usage +### Alternate usages Use the `frame(int x, int y, int frameNumber)` method to draw specific frames--used for laying out multiple frames of soundtrack on a single screen. @@ -53,3 +53,13 @@ void draw () { } ``` + +Use the `buffer(int frameNumber)` method to return the internal `PGraphics` object that contains the specific frame of soundtrack data specified by the frameNumber. You can then draw onto the canvas, address the pixels directly, or as in the provided BufferExample.pde assign the image data to a PImage to be manipulated using the built-in transformation methods. + +```java +void draw () { + PGraphics soundtrackBuffer = soundtrack.buffer(frameCount); + image(soundtrackBuffer, 0, 0); +} + +``` diff --git a/examples/BufferExample/BufferExample.pde b/examples/BufferExample/BufferExample.pde new file mode 100644 index 0000000..3cfd6ba --- /dev/null +++ b/examples/BufferExample/BufferExample.pde @@ -0,0 +1,27 @@ +import processing.sound.*; +import soundtrack.optical.*; + +SoundtrackOptical soundtrack; +String type = "variable density"; +PGraphics soundtrackBuffer; +PImage transform; + +String soundtrackFile = "../../data/barking.wav"; +int dpi = 2400; +float volume = 1.0; +String pitch = "long"; +boolean positive = true; + +void setup() { + size(620, 213, P2D); + soundtrack = new SoundtrackOptical(this, soundtrackFile, dpi, volume, type, pitch, positive); + imageMode(CENTER); +} + +void draw () { + soundtrackBuffer = soundtrack.buffer(frameCount); + transform = soundtrackBuffer.get(); + translate(width>>1, height>>1); + rotate(HALF_PI); + image(transform, 0, 0); +} \ No newline at end of file diff --git a/examples/FrameExample/FrameExample.pde b/examples/FrameExample/FrameExample.pde new file mode 100644 index 0000000..499e663 --- /dev/null +++ b/examples/FrameExample/FrameExample.pde @@ -0,0 +1,27 @@ +import processing.sound.*; +import soundtrack.optical.*; + +SoundtrackOptical soundtrack; +String type = "dual variable area"; + +String soundtrackFile = "../../data/barking.wav"; +int dpi = 2400; +float volume = 1.0; +String pitch = "long"; +boolean positive = true; + +void setup() { + size(1065, 620, P2D); + soundtrack = new SoundtrackOptical(this, soundtrackFile, dpi, volume, type, pitch, positive); +} + +void draw () { + for (int i = 0; i < 5; i++) { + soundtrack.frame(i * 213, 0, frameCount + i); + } + + stroke(255, 0, 0); + for (int i = 1; i < 5; i++) { + line(213 * i, 0, 213 * i, height); + } +} \ No newline at end of file diff --git a/library/SoundtrackOptical.jar b/library/SoundtrackOptical.jar index b16b5b69f3daa3116a33d31651622914b287f365..b15a600e732871d3d81edb0c3fffbf2418b59afc 100644 GIT binary patch delta 5123 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 PN?9Zt0KniokW&302-rV+ diff --git a/src/soundtrack/optical/SoundtrackOptical.java b/src/soundtrack/optical/SoundtrackOptical.java index 9aacbb3..f79ca42 100755 --- a/src/soundtrack/optical/SoundtrackOptical.java +++ b/src/soundtrack/optical/SoundtrackOptical.java @@ -161,6 +161,58 @@ public class SoundtrackOptical { } } + @SuppressWarnings("static-access") + public PGraphics buffer (int frameNumber) { + if (frameNumber != -1) { + i = frameNumber; + } + if (i >= FRAMES) { + return null; + } + 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(); + return raw; + } + private void unilateral (int y, int LINE_W) { raw.line(0, y, LINE_W, y); }