Merge branch 'master' of github.com:processing/processing

This commit is contained in:
Ben Fry
2014-01-21 18:26:36 -05:00
54 changed files with 2230 additions and 1032 deletions
@@ -1,13 +0,0 @@
import processing.glw.*;
void setup() {
size(2560, 1440, GLW.P2D);
frameRate(180);
}
void draw() {
background(255, 0, 0);
fill(255);
text("FPS: " + frameRate, mouseX, mouseY);
}
@@ -0,0 +1,25 @@
import processing.glw.*;
PGraphics stage;
void setup() {
// The main window will be hidden, only GLW.RENDERER
// can be used in size()
size(100, 100, GLW.RENDERER);
stage = createGraphics(2560, 1440, GLW.P2D);
GLW.createWindow(stage);
frameRate(180);
}
void draw() {
// The draw() method is used to update the offscreen surfaces,
// but not to draw directly to the screen.
stage.beginDraw();
stage.background(200);
stage.fill(255);
stage.ellipse(mouseX, mouseY, 50, 50);
stage.fill(0);
stage.text(frameRate, 100, 100);
stage.endDraw();
}
@@ -0,0 +1,28 @@
import processing.glw.*;
PGraphics canvas1;
PGraphics canvas2;
void setup() {
size(100, 100, GLW.RENDERER);
canvas1 = createGraphics(320, 240, GLW.P2D);
canvas2 = createGraphics(320, 240, GLW.P2D);
GLW.createWindow(canvas1);
GLW.createWindow(canvas2);
}
void draw() {
canvas1.beginDraw();
canvas1.background(200);
canvas1.ellipse(mouseX, mouseY, 100, 100);
canvas1.endDraw();
canvas2.beginDraw();
canvas2.background(170);
canvas2.ellipse(mouseX, mouseY, 50, 50);
canvas2.endDraw();
}
void keyPressed() {
GLW.getFocusedWindow().setVisible(false);
}
+49 -3
View File
@@ -1,6 +1,52 @@
package processing.glw;
public interface GLW {
static final String P2D = "processing.glw.PGraphics2D";
static final String P3D = "processing.glw.PGraphics3D";
import processing.core.PGraphics;
import com.jogamp.newt.opengl.GLWindow;
import java.util.HashMap;
public class GLW {
static public final String RENDERER = "processing.glw.PGraphicsGLW";
static public final String OPENGL = "processing.glw.PGraphicsGLW";
static public final String P2D = "processing.glw.PGraphics2D";
static public final String P3D = "processing.glw.PGraphics3D";
static protected HashMap<PGraphics, GLWindow> windows =
new HashMap<PGraphics, GLWindow>();
public GLW() {
}
static public void createWindow(PGraphics pg) {
if (pg instanceof PGraphics2D || pg instanceof PGraphics3D) {
windows.put(pg, null);
} else {
throw new RuntimeException("Only GLW.P2D or GLW.P3D surfaces can be attached to a window");
}
}
static public GLWindow getWindow(PGraphics pg) {
return windows.get(pg);
}
static public boolean isFocused(PGraphics pg) {
GLWindow win = windows.get(pg);
return win != null && win.hasFocus();
}
static public PGraphics getFocusedGraphics() {
for (PGraphics pg: windows.keySet()) {
if (isFocused(pg)) return pg;
}
return null;
}
static public GLWindow getFocusedWindow() {
for (PGraphics pg: windows.keySet()) {
if (isFocused(pg)) return windows.get(pg);
}
return null;
}
}
@@ -6,5 +6,5 @@ import processing.opengl.PGraphicsOpenGL;
public class PGraphics2D extends processing.opengl.PGraphics2D {
protected PGL createPGL(PGraphicsOpenGL pg) {
return new PNEWT(pg);
}
}
}
@@ -26,11 +26,60 @@ import processing.opengl.PGL;
import processing.opengl.PGraphicsOpenGL;
/**
* LWJGL renderer.
* GLW renderer. It's only role is to drive the main animation loop by calling
* requestDraw() and so allowing the offscreen canvases to be drawn inside the
* draw() method of the sketch. Currently, it cannot be used to draw into.
*
*/
public class PGraphicsGLW extends PGraphicsOpenGL {
protected PGL createPGL(PGraphicsOpenGL pg) {
return new PNEWT(pg);
}
}
public void beginDraw() {
if (primarySurface) {
setCurrentPG(this);
} else {
throw new RuntimeException("GLW renderer cannot be used as an offscreen surface");
}
report("top beginDraw()");
if (!checkGLThread()) {
return;
}
if (drawing) {
return;
}
if (!glParamsRead) {
getGLParameters();
}
drawing = true;
report("bot beginDraw()");
}
public void endDraw() {
report("top endDraw()");
if (!drawing) {
return;
}
if (primarySurface) {
setCurrentPG(null);
} else {
throw new RuntimeException("GLW renderer cannot be used as an offscreen surface.");
}
drawing = false;
report("bot endDraw()");
}
protected void vertexImpl(float x, float y, float z, float u, float v) {
throw new RuntimeException("The main GLW renderer cannot be used to draw to.");
}
}
+206 -32
View File
@@ -24,15 +24,24 @@
package processing.glw;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.newt.event.WindowAdapter;
import com.jogamp.newt.event.WindowEvent;
import processing.core.PApplet;
import processing.core.PGraphics;
import processing.opengl.PGL;
import processing.opengl.PGraphicsOpenGL;
import processing.opengl.PJOGL;
import processing.opengl.Texture;
public class PNEWT extends PJOGL {
@@ -43,51 +52,216 @@ public class PNEWT extends PJOGL {
USE_JOGL_FBOLAYER = false;
}
protected static GLCapabilities sharedCaps;
protected static GLAutoDrawable sharedDrawable;
public PNEWT(PGraphicsOpenGL pg) {
super(pg);
}
protected void initSurface(int antialias) {
if (!(pg instanceof PGraphicsGLW)) {
throw new RuntimeException("GLW.RENDERER is the only option in size() when using the GLW library.");
}
if (profile == null) {
profile = GLProfile.getDefault();
} else {
window.removeGLEventListener(listener);
pg.parent.remove(canvasNEWT);
if (PROFILE == 2) {
try {
profile = GLProfile.getGL2ES1();
} catch (GLException ex) {
profile = GLProfile.getMaxFixedFunc(true);
}
} else if (PROFILE == 3) {
try {
profile = GLProfile.getGL2GL3();
} catch (GLException ex) {
profile = GLProfile.getMaxProgrammable(true);
}
if (!profile.isGL3()) {
PGraphics.showWarning("Requested profile GL3 but is not available, got: " + profile);
}
} else if (PROFILE == 4) {
try {
profile = GLProfile.getGL4ES3();
} catch (GLException ex) {
profile = GLProfile.getMaxProgrammable(true);
}
if (!profile.isGL4()) {
PGraphics.showWarning("Requested profile GL4 but is not available, got: " + profile);
}
} else throw new RuntimeException(UNSUPPORTED_GLPROF_ERROR);
if (2 < PROFILE) {
texVertShaderSource = convertVertexSource(texVertShaderSource, 120, 150);
tex2DFragShaderSource = convertFragmentSource(tex2DFragShaderSource, 120, 150);
texRectFragShaderSource = convertFragmentSource(texRectFragShaderSource, 120, 150);
}
}
// Setting up the desired capabilities;
GLCapabilities caps = new GLCapabilities(profile);
caps.setAlphaBits(REQUESTED_ALPHA_BITS);
caps.setDepthBits(REQUESTED_DEPTH_BITS);
caps.setStencilBits(REQUESTED_STENCIL_BITS);
if (1 < antialias) {
caps.setSampleBuffers(true);
caps.setNumSamples(antialias);
} else {
caps.setSampleBuffers(false);
}
fboLayerRequested = false;
window = GLWindow.create(caps);
window.setSize(pg.width, pg.height);
window.setVisible(true);
pg.parent.frame.setVisible(false);
canvas = canvasNEWT;
canvasAWT = null;
sharedCaps = new GLCapabilities(profile);
sharedCaps.setAlphaBits(REQUESTED_ALPHA_BITS);
sharedCaps.setDepthBits(REQUESTED_DEPTH_BITS);
sharedCaps.setStencilBits(REQUESTED_STENCIL_BITS);
window.addWindowListener(new WindowAdapter() {
@Override
public void windowDestroyNotify(final WindowEvent e) {
System.exit(0);
}
});
sharedCaps.setPBuffer(false);
sharedCaps.setFBO(false);
sharedCaps.setSampleBuffers(false);
registerListeners();
fboLayerRequested = false;
sharedDrawable = GLDrawableFactory.getFactory(profile).createDummyAutoDrawable(null, true, sharedCaps, null);
sharedDrawable.display(); // triggers GLContext object creation and native realization.
DummyListener listener = new DummyListener();
sharedDrawable.addGLEventListener(listener);
pg.parent.frame.setVisible(false);
}
protected boolean displayable() {
return false;
}
protected void beginDraw(boolean clear0) {
}
protected void endDraw(boolean clear0) {
}
protected void requestDraw() {
createWindows();
// Calling display() so the main draw() method is triggered, where the
// offscreen GLW canvases can be updated.
sharedDrawable.display();
displayWindows();
}
private void createWindows() {
for (PGraphics pg: GLW.windows.keySet()) {
GLWindow win = GLW.windows.get(pg);
if (win == null) {
win = GLWindow.create(sharedCaps);
win.setSharedAutoDrawable(sharedDrawable);
win.setSize(pg.width, pg.height);
win.setTitle("TEST");
win.setVisible(true);
GLW.windows.put(pg, win);
NEWTListener listener = new NEWTListener(pg);
win.addGLEventListener(listener);
NEWTMouseListener mouseListener = new NEWTMouseListener();
win.addMouseListener(mouseListener);
NEWTKeyListener keyListener = new NEWTKeyListener();
win.addKeyListener(keyListener);
NEWTWindowListener winListener = new NEWTWindowListener();
win.addWindowListener(winListener);
win.addWindowListener(new WindowAdapter() {
@Override
public void windowDestroyNotify(final WindowEvent e) {
}
});
}
}
}
private void displayWindows() {
int totalCount = 0;
int realizedCount = 0;
for (GLWindow win: GLW.windows.values()) {
if (win != null) {
totalCount++;
if (win.isRealized()) realizedCount++;
win.display();
}
}
if (0 < totalCount && realizedCount == 0) {
// All windows where closed, exit the application
sharedDrawable.destroy();
System.exit(0);
}
}
protected class DummyListener implements GLEventListener {
public DummyListener() {
}
@Override
public void display(GLAutoDrawable glDrawable) {
getGL(glDrawable);
pg.parent.handleDraw();
}
@Override
public void dispose(GLAutoDrawable adrawable) {
}
@Override
public void init(GLAutoDrawable glDrawable) {
getGL(glDrawable);
capabilities = glDrawable.getChosenGLCapabilities();
if (!hasFBOs()) {
throw new RuntimeException(MISSING_FBO_ERROR);
}
if (!hasShaders()) {
throw new RuntimeException(MISSING_GLSL_ERROR);
}
if (USE_JOGL_FBOLAYER && capabilities.isFBO()) {
int maxs = maxSamples();
numSamples = PApplet.min(capabilities.getNumSamples(), maxs);
}
}
@Override
public void reshape(GLAutoDrawable glDrawable, int x, int y, int w, int h) {
}
}
protected class NEWTListener implements GLEventListener {
PGraphicsOpenGL pg;
PNEWT pgl;
public NEWTListener(PGraphics pg) {
this.pg = (PGraphicsOpenGL)pg;
pgl = (PNEWT)this.pg.pgl;
}
@Override
public void display(GLAutoDrawable glDrawable) {
pgl.getGL(glDrawable);
Texture tex = pg.getTexture(false);
if (tex != null) {
pgl.disable(PGL.BLEND);
pgl.drawTexture(tex.glTarget, tex.glName,
tex.glWidth, tex.glHeight,
0, 0, pg.width, pg.height);
pgl.enable(PGL.BLEND);
}
}
@Override
public void dispose(GLAutoDrawable adrawable) {
}
@Override
public void init(GLAutoDrawable glDrawable) {
}
@Override
public void reshape(GLAutoDrawable glDrawable, int x, int y, int w, int h) {
}
}
}
@@ -125,6 +125,11 @@ public class PLWJGL extends PGL {
if (glu == null) glu = new GLU();
}
public Canvas getCanvas() {
return canvas;
}
protected void setFps(float fps) {
if (!setFps || targetFps != fps) {
@@ -1991,4 +1996,9 @@ public class PLWJGL extends PGL {
public void drawBuffer(int buf) {
GL11.glDrawBuffer(buf);
}
@Override
protected void getGL(PGL pgl) {
}
}
@@ -7,6 +7,9 @@
* the frequency content of a signal. You've seen
* visualizations like this before in music players
* and car stereos.
* <p>
* For more information about Minim and additional features,
* visit http://code.compartmental.net/minim/
*/
import ddf.minim.analysis.*;
@@ -0,0 +1,85 @@
/**
* This sketch demonstrates how to create synthesized sound with Minim using an AudioOutput and
* an Instrument we define. By using the playNote method you can schedule notes to played
* at some point in the future, essentially allowing to you create musical scores with code.
* Because they are constructed with code, they can be either deterministic or different every time.
* This sketch creates a deterministic score, meaning it is the same every time you run the sketch.
* <p>
* For more complex examples of using playNote check out algorithmicCompExample and compositionExample
* in the Synthesis folder.
* <p>
* For more information about Minim and additional features, visit http://code.compartmental.net/minim/
*/
import ddf.minim.*;
import ddf.minim.ugens.*;
Minim minim;
AudioOutput out;
// to make an Instrument we must define a class
// that implements the Instrument interface.
class SineInstrument implements Instrument
{
Oscil wave;
Line ampEnv;
SineInstrument( float frequency )
{
// make a sine wave oscillator
// the amplitude is zero because
// we are going to patch a Line to it anyway
wave = new Oscil( frequency, 0, Waves.SINE );
ampEnv = new Line();
ampEnv.patch( wave.amplitude );
}
// this is called by the sequencer when this instrument
// should start making sound. the duration is expressed in seconds.
void noteOn( float duration )
{
// start the amplitude envelope
ampEnv.activate( duration, 0.5f, 0 );
// attach the oscil to the output so it makes sound
wave.patch( out );
}
// this is called by the sequencer when the instrument should
// stop making sound
void noteOff()
{
wave.unpatch( out );
}
}
void setup()
{
size(512, 200, P3D);
minim = new Minim(this);
// use the getLineOut method of the Minim object to get an AudioOutput object
out = minim.getLineOut();
// when providing an Instrument, we always specify start time and duration
out.playNote( 0.0, 0.9, new SineInstrument( 97.99 ) );
out.playNote( 1.0, 0.9, new SineInstrument( 123.47 ) );
// we can use the Frequency class to create frequencies from pitch names
out.playNote( 2.0, 2.9, new SineInstrument( Frequency.ofPitch( "C3" ).asHz() ) );
out.playNote( 3.0, 1.9, new SineInstrument( Frequency.ofPitch( "E3" ).asHz() ) );
out.playNote( 4.0, 0.9, new SineInstrument( Frequency.ofPitch( "G3" ).asHz() ) );
}
void draw()
{
background(0);
stroke(255);
// draw the waveforms
for(int i = 0; i < out.bufferSize() - 1; i++)
{
line( i, 50 + out.left.get(i)*50, i+1, 50 + out.left.get(i+1)*50 );
line( i, 150 + out.right.get(i)*50, i+1, 150 + out.right.get(i+1)*50 );
}
}
@@ -10,6 +10,9 @@
* If you load WAV file or other non-tagged file, most of the metadata
* will be empty, but you will still have information like the filename
* and the length.
* <p>
* For more information about Minim and additional features,
* visit http://code.compartmental.net/minim/
*/
import ddf.minim.*;
@@ -52,14 +55,3 @@ void draw()
text("Publisher: " + meta.publisher(), 5, y+=yi);
text("Encoded: " + meta.encoded(), 5, y+=yi);
}
void stop()
{
// always close Minim audio classes when you are done with them
groove.close();
// always stop Minim before exiting
minim.stop();
super.stop();
}
@@ -1,12 +1,17 @@
/**
* This sketch demonstrates how to monitor the currently active audio input
* of the computer using an <code>AudioInput</code>. What you will actually
* of the computer using an AudioInput. What you will actually
* be monitoring depends on the current settings of the machine the sketch is running on.
* Typically, you will be monitoring the built-in microphone, but if running on a desktop
* its feasible that the user may have the actual audio output of the computer
* it's feasible that the user may have the actual audio output of the computer
* as the active audio input, or something else entirely.
* <p>
* When you run your sketch as an applet you will need to sign it in order to get an input.
* Press 'm' to toggle monitoring on and off.
* <p>
* When you run your sketch as an applet you will need to sign it in order to get an input.
* <p>
* For more information about Minim and additional features,
* visit http://code.compartmental.net/minim/
*/
import ddf.minim.*;
@@ -22,9 +27,6 @@ void setup()
// use the getLineIn method of the Minim object to get an AudioInput
in = minim.getLineIn();
// uncomment this line to *hear* what is being monitored, in addition to seeing it
in.enableMonitoring();
}
void draw()
@@ -38,4 +40,22 @@ void draw()
line( i, 50 + in.left.get(i)*50, i+1, 50 + in.left.get(i+1)*50 );
line( i, 150 + in.right.get(i)*50, i+1, 150 + in.right.get(i+1)*50 );
}
String monitoringState = in.isMonitoring() ? "enabled" : "disabled";
text( "Input monitoring is currently " + monitoringState + ".", 5, 15 );
}
void keyPressed()
{
if ( key == 'm' || key == 'M' )
{
if ( in.isMonitoring() )
{
in.disableMonitoring();
}
else
{
in.enableMonitoring();
}
}
}
@@ -4,6 +4,9 @@
* a UGen. In this case, we patch an Oscil generating a sine wave into
* the amplitude input of an Oscil generating a square wave. The result
* is known as amplitude modulation.
* <p>
* For more information about Minim and additional features,
* visit http://code.compartmental.net/minim/
*/
import ddf.minim.*;
@@ -1,6 +1,9 @@
/**
* This sketch demonstrates how to play a file with Minim using an AudioPlayer. <br />
* It's also a good example of how to draw the waveform of the audio.
* <p>
* For more information about Minim and additional features,
* visit http://code.compartmental.net/minim/
*/
import ddf.minim.*;
@@ -20,7 +23,9 @@ void setup()
// sketch folder. you can also pass an absolute path, or a URL.
player = minim.loadFile("marcus_kellis_theme.mp3");
// play the file
// play the file from start to finish.
// if you want to play the file again,
// you need to call rewind() first.
player.play();
}
@@ -1,8 +1,13 @@
/**
* This sketch demonstrates how to an <code>AudioRecorder</code> to record audio to disk.
* To use this sketch you need to have something plugged into the line-in on your computer, or else be working on a
* laptop with an active built-in microphone. Press 'r' to toggle recording on and off and the press 's' to save to disk.
* To use this sketch you need to have something plugged into the line-in on your computer,
* or else be working on a laptop with an active built-in microphone.
* <p>
* Press 'r' to toggle recording on and off and the press 's' to save to disk.
* The recorded file will be placed in the sketch folder of the sketch.
* <p>
* For more information about Minim and additional features,
* visit http://code.compartmental.net/minim/
*/
import ddf.minim.*;
@@ -18,11 +23,9 @@ void setup()
minim = new Minim(this);
in = minim.getLineIn();
// create a recorder that will record from the input to the filename specified, using buffered recording
// buffered recording means that all captured audio will be written into a sample buffer
// then when save() is called, the contents of the buffer will actually be written to a file
// create a recorder that will record from the input to the filename specified
// the file will be located in the sketch's root folder.
recorder = minim.createRecorder(in, "myrecording.wav", true);
recorder = minim.createRecorder(in, "myrecording.wav");
textFont(createFont("Arial", 12));
}
@@ -2,6 +2,9 @@
* This sketch demonstrates how to use an <code>AudioRecorder</code> to record audio to disk.
* Press 'r' to toggle recording on and off and the press 's' to save to disk.
* The recorded file will be placed in the sketch folder of the sketch.
* <p>
* For more information about Minim and additional features,
* visit http://code.compartmental.net/minim/
*/
import ddf.minim.*;
@@ -19,11 +22,9 @@ void setup()
out = minim.getLineOut();
// create a recorder that will record from the input to the filename specified, using buffered recording
// buffered recording means that all captured audio will be written into a sample buffer
// then when save() is called, the contents of the buffer will actually be written to a file
// create a recorder that will record from the output to the filename specified
// the file will be located in the sketch's root folder.
recorder = minim.createRecorder(out, "myrecording.wav", true);
recorder = minim.createRecorder(out, "myrecording.wav");
// patch some sound into the output so we have something to record
Oscil wave = new Oscil( 440.f, 1.0f );
@@ -5,6 +5,9 @@
* But the end result is convincing enough.
* <p>
* The positioning code is inside of the Play, Rewind, and Forward classes, which are in button.pde.
* <p>
* For more information about Minim and additional features,
* visit http://code.compartmental.net/minim/
*/
import ddf.minim.*;
@@ -6,8 +6,11 @@
* sketch creates a deterministic score, meaning it is the same every time you run the sketch. It also demonstrates
* a couple different versions of the <code>playNote</code> method.
* <p>
* For more complex examples of using <code>playNote</code> check out algorithmicCompExample and compositionExample
* in the Synthesis folder.
* For more complex examples of using <code>playNote</code> check out
* algorithmicCompExample and compositionExample in the Synthesis folder.
* <p>
* For more information about Minim and additional features,
* visit http://code.compartmental.net/minim/
*/
import ddf.minim.*;
@@ -25,6 +28,20 @@ void setup()
// use the getLineOut method of the Minim object to get an AudioOutput object
out = minim.getLineOut();
// set the tempo of the sequencer
// this makes the first argument of playNote
// specify the start time in quarter notes
// and the duration becomes relative to the length of a quarter note
// by default the tempo is 60 BPM (beats per minute).
// at 60 BPM both start time and duration can be interpreted as seconds.
// to retrieve the current tempo, use getTempo().
out.setTempo( 80 );
// pause the sequencer so our note play back will be rock solid
// if you don't do this, then tiny bits of error can occur since
// the sequencer is running in parallel with you note queueing.
out.pauseNotes();
// given start time, duration, and frequency
out.playNote( 0.0, 0.9, 97.99 );
out.playNote( 1.0, 0.9, 123.47 );
@@ -41,15 +58,17 @@ void setup()
out.playNote( 7.0, "G4" );
// the note offset is simply added into the start time of
// every subsequenct call to playNote. It's expressed in beats,
// but since the default tempo of an AudioOuput is 60 beats per minute,
// this particular call translates to 8.1 seconds, as you might expect.
// every subsequenct call to playNote. It's expressed in beats.
// to get the current note offset, use getNoteOffset().
out.setNoteOffset( 8.1 );
// because only given a note name or frequency
// starttime defaults to 0.0 and duration defaults to 1.0
out.playNote( "G5" );
out.playNote( 987.77 );
// now we can start the sequencer again to hear our sequence
out.resumeNotes();
}
void draw()
@@ -6,8 +6,8 @@
* these can be calculated: <b>Linearly</b>, by grouping equal numbers of adjacent frequency bands, or
* <b>Logarithmically</b>, by grouping frequency bands by <i>octave</i>, which is more akin to how humans hear sound.
* <br/>
* This sketch illustrates the difference between viewing the full spectrum, linearly spaced averaged bands,
* and logarithmically spaced averaged bands.
* This sketch illustrates the difference between viewing the full spectrum,
* linearly spaced averaged bands, and logarithmically spaced averaged bands.
* <p>
* From top to bottom:
* <ul>
@@ -19,6 +19,8 @@
* Moving the mouse across the sketch will highlight a band in each spectrum and display what the center
* frequency of that band is. The averaged bands are drawn so that they line up with full spectrum bands they
* are averages of. In this way, you can clearly see how logarithmic averages differ from linear averages.
* <p>
* For more information about Minim and additional features, visit http://code.compartmental.net/minim/
*/
import ddf.minim.analysis.*;
@@ -1,9 +1,16 @@
/**
* This sketch demonstrates how to create synthesized sound with Minim
* using an AudioOutput and an Oscil. An Oscil is a UGen object,
* one of many different types included with Minim. For many more examples
* of UGens included with Minim, have a look in the Synthesis
* folder of the Minim examples.
* one of many different types included with Minim. By using
* the numbers 1 thru 5, you can change the waveform being used
* by the Oscil to make sound. These basic waveforms are the
* basis of much audio synthesis.
*
* For many more examples of UGens included with Minim,
* have a look in the Synthesis folder of the Minim examples.
* <p>
* For more information about Minim and additional features,
* visit http://code.compartmental.net/minim/
*/
import ddf.minim.*;
@@ -32,11 +39,62 @@ void draw()
{
background(0);
stroke(255);
strokeWeight(1);
// draw the waveforms
// draw the waveform of the output
for(int i = 0; i < out.bufferSize() - 1; i++)
{
line( i, 50 + out.left.get(i)*50, i+1, 50 + out.left.get(i+1)*50 );
line( i, 150 + out.right.get(i)*50, i+1, 150 + out.right.get(i+1)*50 );
line( i, 50 - out.left.get(i)*50, i+1, 50 - out.left.get(i+1)*50 );
line( i, 150 - out.right.get(i)*50, i+1, 150 - out.right.get(i+1)*50 );
}
// draw the waveform we are using in the oscillator
stroke( 128, 0, 0 );
strokeWeight(4);
for( int i = 0; i < width-1; ++i )
{
point( i, height/2 - (height*0.49) * wave.getWaveform().value( (float)i / width ) );
}
}
void mouseMoved()
{
// usually when setting the amplitude and frequency of an Oscil
// you will want to patch something to the amplitude and frequency inputs
// but this is a quick and easy way to turn the screen into
// an x-y control for them.
float amp = map( mouseY, 0, height, 1, 0 );
wave.setAmplitude( amp );
float freq = map( mouseX, 0, width, 110, 880 );
wave.setFrequency( freq );
}
void keyPressed()
{
switch( key )
{
case '1':
wave.setWaveform( Waves.SINE );
break;
case '2':
wave.setWaveform( Waves.TRIANGLE );
break;
case '3':
wave.setWaveform( Waves.SAW );
break;
case '4':
wave.setWaveform( Waves.SQUARE );
break;
case '5':
wave.setWaveform( Waves.QUARTERPULSE );
break;
default: break;
}
}
@@ -22,6 +22,9 @@
* <p>
* Use 'k' and 's' to trigger a kick drum sample and a snare sample, respectively.
* You will see their waveforms drawn when they are played back.
* <p>
* For more information about Minim and additional features,
* visit http://code.compartmental.net/minim/
*/
import ddf.minim.*;
@@ -1,10 +1,12 @@
/* delayExample
is an example of using the Delay UGen in a continuous sound example.
Use the mouse to control the delay time and the amount of feedback
in the delay unit.
author: Anderson Mills
Anderson Mills's work was supported by numediart (www.numediart.org)
*/
/* delayExample<br/>
* is an example of using the Delay UGen in a continuous sound example.
* <p>
* For more information about Minim and additional features,
* visit http://code.compartmental.net/minim/
* <p>
* author: Anderson Mills<br/>
* Anderson Mills's work was supported by numediart (www.numediart.org)
*/
// import everything necessary to make sound.
import ddf.minim.*;
@@ -14,47 +16,44 @@ import ddf.minim.ugens.*;
// more than one methods (setup(), draw(), stop()).
Minim minim;
AudioOutput out;
Delay myDelay1;
Delay myDelay;
// setup is run once at the beginning
void setup()
{
// initialize the drawing window
size( 512, 200, P2D );
size( 512, 200 );
// initialize the minim and out objects
minim = new Minim(this);
out = minim.getLineOut( Minim.MONO, 2048 );
out = minim.getLineOut();
// initialize myDelay1 with continual feedback and no audio passthrough
myDelay1 = new Delay( 0.6, 0.9, true, false );
// initialize myDelay with continual feedback and audio passthrough
myDelay = new Delay( 0.4, 0.5, true, true );
// sawh will create a Sawtooth wave with the requested number of harmonics.
// like with Waves.randomNHarms for sine waves,
// you can create a richer sounding sawtooth this way.
Waveform saw = Waves.sawh( 15 );
// create the Blip that will be used
Oscil myBlip = new Oscil( 245.0, 0.3, Waves.saw( 15 ) );
Oscil myBlip = new Oscil( 245.0, 0.3, saw );
// Waves.square will create a square wave with an uneven duty-cycle,
// also known as a pulse wave. a square wave has only two values,
// either -1 or 1 and the duty cycle indicates how much of the wave
// should -1 and how much 1. in this case, we are asking for a square
// wave that is -1 90% of the time, and 1 10% of the time.
Waveform square = Waves.square( 0.9 );
// create an LFO to be used for an amplitude envelope
Oscil myLFO = new Oscil( 0.5, 0.3, Waves.square( 0.005 ) );
// our LFO will operate on a base amplitude
Constant baseAmp = new Constant(0.3);
// we get the final amplitude by summing the two
Summer ampSum = new Summer();
Summer sum = new Summer();
// patch everything together
// the LFO is patched into a summer along with a constant value
// and that sum is used to drive the amplitude of myBlip
baseAmp.patch( ampSum );
myLFO.patch( ampSum );
ampSum.patch( myBlip.amplitude );
Oscil myLFO = new Oscil( 1, 0.3, square );
// offset the center value of the LFO so that it outputs 0
// for the long portion of the duty cycle
myLFO.offset.setLastValue( 0.3 );
// the Blip is patched directly into the sum
myBlip.patch( sum );
myLFO.patch( myBlip.amplitude );
// and the Blip is patched through the delay into the sum.
myBlip.patch( myDelay1 ).patch( sum );
// patch the sum into the output
sum.patch( out );
// and the Blip is patched through the delay into the output
myBlip.patch( myDelay ).patch( out );
}
// draw is run many times
@@ -73,7 +72,10 @@ void draw()
// draw a line from one buffer position to the next for both channels
line( x1, 50 + out.left.get(i)*50, x2, 50 + out.left.get(i+1)*50);
line( x1, 150 + out.right.get(i)*50, x2, 150 + out.right.get(i+1)*50);
}
}
text( "Delay time is " + myDelay.delTime.getLastValue(), 5, 15 );
text( "Delay amplitude (feedback) is " + myDelay.delAmp.getLastValue(), 5, 30 );
}
// when the mouse is moved, change the delay parameters
@@ -81,8 +83,8 @@ void mouseMoved()
{
// set the delay time by the horizontal location
float delayTime = map( mouseX, 0, width, 0.0001, 0.5 );
myDelay1.setDelTime( delayTime );
myDelay.setDelTime( delayTime );
// set the feedback factor by the vertical location
float feedbackFactor = map( mouseY, 0, height, 0.0, 0.99 );
myDelay1.setDelAmp( feedbackFactor );
float feedbackFactor = map( mouseY, 0, height, 0.99, 0.0 );
myDelay.setDelAmp( feedbackFactor );
}
@@ -1,10 +1,13 @@
/* filterExample
is an example of using the different filters
in continuous sound.
author: Damien Di Fede, Anderson Mills
Anderson Mills's work was supported by numediart (www.numediart.org)
*/
/* filterExample<br/>
* is an example of using the different filters
* in continuous sound.
* <p>
* For more information about Minim and additional features,
* visit http://code.compartmental.net/minim/
* <p>
* author: Damien Di Fede, Anderson Mills<br/>
* Anderson Mills's work was supported by numediart (www.numediart.org)
*/
// import everything necessary to make sound.
import ddf.minim.*;
@@ -1,10 +1,12 @@
/* frequencyModulation
<p>
A simple example for doing FM (frequency modulation) using two Oscils.
Use the mouse to control the speed and range of the frequency modulation.
<p>
Author: Damien Di Fede
*/
<p>
A simple example for doing FM (frequency modulation) using two Oscils.
<p>
For more information about Minim and additional features,
visit http://code.compartmental.net/minim/
<p>
Author: Damien Di Fede
*/
// import everything necessary to make sound.
import ddf.minim.*;
@@ -62,6 +64,9 @@ void draw()
line( x1, 50 + out.left.get(i)*50, x2, 50 + out.left.get(i+1)*50);
line( x1, 150 + out.right.get(i)*50, x2, 150 + out.right.get(i+1)*50);
}
text( "Modulation frequency: " + fm.frequency.getLastValue(), 5, 15 );
text( "Modulation amplitude: " + fm.amplitude.getLastValue(), 5, 30 );
}
// we can change the parameters of the frequency modulation Oscil
@@ -71,6 +76,6 @@ void mouseMoved()
float modulateAmount = map( mouseY, 0, height, 220, 1 );
float modulateFrequency = map( mouseX, 0, width, 0.1, 100 );
fm.frequency.setLastValue( modulateFrequency );
fm.amplitude.setLastValue( modulateAmount );
fm.setFrequency( modulateFrequency );
fm.setAmplitude( modulateAmount );
}
@@ -4,6 +4,9 @@
* a file from the data folder into a MultiChannelBuffer and then modifies that sample data before
* using it to create a Sampler UGen. You can hear the result of this modification by hitting
* the space bar.
* <p>
* For more information about Minim and additional features,
* visit http://code.compartmental.net/minim/
*/
import ddf.minim.*;
@@ -33,7 +33,7 @@ void setup() {
ypos = height/2;
// Print a list of the serial ports, for debugging purposes:
println(Serial.list());
printArray(Serial.list());
// I know that the first port in the serial list on my mac
// is always my FTDI adaptor, so I open Serial.list()[0].
@@ -22,7 +22,7 @@ void setup() {
textFont(myFont);
// List all the available serial ports:
println(Serial.list());
printArray(Serial.list());
// I know that the first port in the serial list on my mac
// is always my FTDI adaptor, so I open Serial.list()[0].
@@ -13,7 +13,7 @@ int[] dataIn = new int[2]; // a list to hold data from the serial ports
void setup() {
size(400, 300);
// print a list of the serial ports:
println(Serial.list());
printArray(Serial.list());
// On my machine, the first and third ports in the list
// were the serial ports that my microcontrollers were
// attached to.
@@ -166,7 +166,7 @@ public class Serial implements SerialPortEventListener {
}
}
public boolean getCTS() {
try {
return port.isCTS();
@@ -189,7 +189,7 @@ public class Serial implements SerialPortEventListener {
return SerialPortList.getPortProperties(portName);
}
public int last() {
if (inBuffer == readOffset) {
return -1;
@@ -366,6 +366,10 @@ public class Serial implements SerialPortEventListener {
while (0 < (toRead = port.getInputBufferBytesCount())) {
// this method can be called from the context of another thread
synchronized (buffer) {
// read one byte at a time if the sketch is using serialEvent
if (serialEventMethod != null) {
toRead = 1;
}
// enlarge buffer if necessary
if (buffer.length < inBuffer+toRead) {
byte temp[] = new byte[buffer.length<<1];
@@ -376,27 +380,27 @@ public class Serial implements SerialPortEventListener {
byte[] read = port.readBytes(toRead);
System.arraycopy(read, 0, buffer, inBuffer, read.length);
inBuffer += read.length;
if (serialEventMethod != null) {
if ((0 < bufferUntilSize && bufferUntilSize <= inBuffer-readOffset) ||
(0 == bufferUntilSize && bufferUntilByte == buffer[inBuffer-1])) {
try {
// serialEvent() is invoked in the context of the current (serial) thread
// which means that serialization and atomic variables need to be used to
// guarantee reliable operation (and better not draw() etc..)
// serialAvailable() does not provide any real benefits over using
// available() and read() inside draw - but this function has no
// thread-safety issues since it's being invoked during pre in the context
// of the Processing applet
serialEventMethod.invoke(parent, new Object[] { this });
} catch (Exception e) {
System.err.println("Error, disabling serialEvent() for "+port.getPortName());
System.err.println(e.getLocalizedMessage());
serialEventMethod = null;
}
}
if (serialEventMethod != null) {
if ((0 < bufferUntilSize && bufferUntilSize <= inBuffer-readOffset) ||
(0 == bufferUntilSize && bufferUntilByte == buffer[inBuffer-1])) {
try {
// serialEvent() is invoked in the context of the current (serial) thread
// which means that serialization and atomic variables need to be used to
// guarantee reliable operation (and better not draw() etc..)
// serialAvailable() does not provide any real benefits over using
// available() and read() inside draw - but this function has no
// thread-safety issues since it's being invoked during pre in the context
// of the Processing applet
serialEventMethod.invoke(parent, new Object[] { this });
} catch (Exception e) {
System.err.println("Error, disabling serialEvent() for "+port.getPortName());
System.err.println(e.getLocalizedMessage());
serialEventMethod = null;
}
}
invokeSerialAvailable = true;
}
invokeSerialAvailable = true;
}
} catch (SerialPortException e) {
throw new RuntimeException("Error reading from serial port " + e.getPortName() + ": " + e.getExceptionType());
@@ -0,0 +1,12 @@
void setup() {
Serial.begin(115200);
}
void loop() {
while (true) {
int in = Serial.read();
if (in != -1) {
Serial.write(in);
}
}
}
@@ -0,0 +1,53 @@
// Arduino Duemilanove (168) on OS X 10.9
// with either 115200 or 38400 bps
// on Processing 2.0.3 (cu & tty): 24 ms avg, 35 ms max
// on Processing 2.1b1 (cu & tty): 18 ms avg, 35 ms max
import processing.serial.*;
Serial serial;
int start;
byte out = '@';
int last_send = 0;
byte[] in = new byte[32768];
long num_fail = 0;
long num_recv = 0;
int max_latency = 0;
void setup() {
println(serial.list());
// change this accordingly
serial = new Serial(this, serial.list()[0], 115200);
start = millis();
}
void draw() {
background(255);
if (0 < serial.available()) {
int recv = serial.readBytes(in);
for (int i=0; i < recv; i++) {
if (in[i] == out) {
num_recv++;
int now = millis();
if (max_latency < now-last_send) {
max_latency = now-last_send;
}
last_send = 0;
}
}
}
if (last_send != 0 && 1000 < millis()-last_send) {
num_fail++;
last_send = 0;
println(num_fail+" bytes timed out");
}
if (last_send == 0) {
if (out == 'Z') {
out = '@';
}
serial.write(++out);
last_send = millis();
}
fill(0);
text(((millis()-start)/(float)num_recv+" ms avg"), 0, height/2);
text(max_latency+" ms max", 0, height/2+20);
}
@@ -0,0 +1,9 @@
void setup() {
Serial.begin(115200);
}
void loop() {
while (true) {
Serial.write('.');
}
}
@@ -0,0 +1,32 @@
import processing.serial.*;
Serial serial;
int start;
byte[] in = new byte[32768];
long num_ok = 0;
long num_fail = 0;
long num_recv = 0;
void setup() {
println(serial.list());
// change this accordingly
serial = new Serial(this, serial.list()[0], 115200);
start = millis();
}
void draw() {
background(255);
if (0 < serial.available()) {
int recv = serial.readBytes(in);
for (int i=0; i < recv; i++) {
if (in[i] == '.') {
num_ok++;
} else {
num_fail++;
println("Received "+num_fail+" unexpected bytes");
}
num_recv++;
}
}
fill(0);
text(num_recv/((millis()-start)/1000.0), 0, height/2);
}
@@ -80,8 +80,9 @@ void draw() {
rotateY(radians(36 + leftRightAngle)); //, 0, 1, 0);
rotateX(radians(-228 + upDownAngle)); //, 1, 0, 0);
if (blobby) {
stroke(0.35, 0.35, 0.25, 0.15);
strokeWeight(0.1);
if (blobby) {
stroke(0.35, 0.35, 0.25, 0.15);
wireCone(MAX_RADIUS, MAX_RADIUS * CONE_HEIGHT, 18, 18);
}
else {
@@ -107,6 +107,7 @@ public class Capture extends PImage implements PConstants {
protected int reqHeight;
protected boolean useBufferSink = false;
protected boolean outdatedPixels = true;
protected Object bufferSink;
protected Method sinkCopyMethod;
protected Method sinkSetMethod;
@@ -375,6 +376,7 @@ public class Capture extends PImage implements PConstants {
}
if (useBufferSink) { // The native buffer from gstreamer is copied to the buffer sink.
outdatedPixels = true;
if (natBuffer == null) {
return;
}
@@ -442,10 +444,32 @@ public class Capture extends PImage implements PConstants {
e.printStackTrace();
}
}
// super.loadPixels() sets loaded to true, but in the useBufferSink mode,
// the contents of the pixels array is overriden by the buffers coming
// from gstreamer, so we don't want PGraphicsOpenGL replacing the OpenGL
// texture with the pixels.
setLoaded(false);
outdatedPixels = false;
}
}
public int get(int x, int y) {
if (outdatedPixels) loadPixels();
return super.get(x, y);
}
protected void getImpl(int sourceX, int sourceY,
int sourceWidth, int sourceHeight,
PImage target, int targetX, int targetY) {
if (outdatedPixels) loadPixels();
super.getImpl(sourceX, sourceY, sourceWidth, sourceHeight,
target, targetX, targetY);
}
////////////////////////////////////////////////////////////
// List methods.
@@ -79,6 +79,7 @@ public class Movie extends PImage implements PConstants {
protected boolean seeking = false;
protected boolean useBufferSink = false;
protected boolean outdatedPixels = true;
protected Object bufferSink;
protected Method sinkCopyMethod;
protected Method sinkSetMethod;
@@ -487,6 +488,7 @@ public class Movie extends PImage implements PConstants {
}
if (useBufferSink) { // The native buffer from gstreamer is copied to the buffer sink.
outdatedPixels = true;
if (natBuffer == null) {
return;
}
@@ -565,11 +567,33 @@ public class Movie extends PImage implements PConstants {
} catch (Exception e) {
e.printStackTrace();
}
}
}
// super.loadPixels() sets loaded to true, but in the useBufferSink mode,
// the contents of the pixels array is overriden by the buffers coming
// from gstreamer, so we don't want PGraphicsOpenGL replacing the OpenGL
// texture with the pixels.
setLoaded(false);
outdatedPixels = false;
}
}
public int get(int x, int y) {
if (outdatedPixels) loadPixels();
return super.get(x, y);
}
protected void getImpl(int sourceX, int sourceY,
int sourceWidth, int sourceHeight,
PImage target, int targetX, int targetY) {
if (outdatedPixels) loadPixels();
super.getImpl(sourceX, sourceY, sourceWidth, sourceHeight,
target, targetX, targetY);
}
////////////////////////////////////////////////////////////
// Initialization methods.