diff --git a/java/libraries/minim/examples/AnalyzeSound/AnalyzeSound.pde b/java/libraries/minim/examples/AnalyzeSound/AnalyzeSound.pde new file mode 100644 index 000000000..d2122efb7 --- /dev/null +++ b/java/libraries/minim/examples/AnalyzeSound/AnalyzeSound.pde @@ -0,0 +1,55 @@ +/** + * This sketch demonstrates how to use an FFT to analyze + * the audio being generated by an AudioPlayer. + *
+ * FFT stands for Fast Fourier Transform, which is a
+ * method of analyzing audio that allows you to visualize
+ * the frequency content of a signal. You've seen
+ * visualizations like this before in music players
+ * and car stereos.
+ */
+
+import ddf.minim.analysis.*;
+import ddf.minim.*;
+
+Minim minim;
+AudioPlayer jingle;
+FFT fft;
+
+void setup()
+{
+ size(512, 200, P3D);
+
+ minim = new Minim(this);
+
+ // specify that we want the audio buffers of the AudioPlayer
+ // to be 1024 samples long because our FFT needs to have
+ // a power-of-two buffer size and this is a good size.
+ jingle = minim.loadFile("jingle.mp3", 1024);
+
+ // loop the file indefinitely
+ jingle.loop();
+
+ // create an FFT object that has a time-domain buffer
+ // the same size as jingle's sample buffer
+ // note that this needs to be a power of two
+ // and that it means the size of the spectrum will be half as large.
+ fft = new FFT( jingle.bufferSize(), jingle.sampleRate() );
+
+}
+
+void draw()
+{
+ background(0);
+ stroke(255);
+
+ // perform a forward FFT on the samples in jingle's mix buffer,
+ // which contains the mix of both the left and right channels of the file
+ fft.forward( jingle.mix );
+
+ for(int i = 0; i < fft.specSize(); i++)
+ {
+ // draw the line for frequency band i, scaling it up a bit so we can see it
+ line( i, height, i, height - fft.getBand(i)*8 );
+ }
+}
diff --git a/java/libraries/minim/examples/AnalyzeSound/data/jingle.mp3 b/java/libraries/minim/examples/AnalyzeSound/data/jingle.mp3
new file mode 100644
index 000000000..8774a7632
Binary files /dev/null and b/java/libraries/minim/examples/AnalyzeSound/data/jingle.mp3 differ
diff --git a/java/libraries/minim/examples/GetMetaData/GetMetaData.pde b/java/libraries/minim/examples/GetMetaData/GetMetaData.pde
new file mode 100644
index 000000000..fe47ea429
--- /dev/null
+++ b/java/libraries/minim/examples/GetMetaData/GetMetaData.pde
@@ -0,0 +1,65 @@
+/**
+ * Get Meta Data
+ * by Damien Di Fede.
+ *
+ * This sketch demonstrates how to use the getMetaData
+ * method of AudioPlayer. This method is also available
+ * for AudioSnippet and AudioSample.
+ * You should use this method when you want to retrieve metadata
+ * about a file that you have loaded, like ID3 tags from an mp3 file.
+ * 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.
+ */
+
+import ddf.minim.*;
+
+Minim minim;
+AudioPlayer groove;
+AudioMetaData meta;
+
+void setup()
+{
+ size(512, 256, P2D);
+
+ minim = new Minim(this);
+ groove = minim.loadFile("groove.mp3");
+ meta = groove.getMetaData();
+
+ textFont(createFont("Serif", 12));
+}
+
+int ys = 25;
+int yi = 15;
+
+void draw()
+{
+ background(0);
+ int y = ys;
+ text("File Name: " + meta.fileName(), 5, y);
+ text("Length (in milliseconds): " + meta.length(), 5, y+=yi);
+ text("Title: " + meta.title(), 5, y+=yi);
+ text("Author: " + meta.author(), 5, y+=yi);
+ text("Album: " + meta.album(), 5, y+=yi);
+ text("Date: " + meta.date(), 5, y+=yi);
+ text("Comment: " + meta.comment(), 5, y+=yi);
+ text("Track: " + meta.track(), 5, y+=yi);
+ text("Genre: " + meta.genre(), 5, y+=yi);
+ text("Copyright: " + meta.copyright(), 5, y+=yi);
+ text("Disc: " + meta.disc(), 5, y+=yi);
+ text("Composer: " + meta.composer(), 5, y+=yi);
+ text("Orchestra: " + meta.orchestra(), 5, y+=yi);
+ 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();
+}
diff --git a/java/libraries/minim/examples/GetMetaData/data/groove.mp3 b/java/libraries/minim/examples/GetMetaData/data/groove.mp3
new file mode 100644
index 000000000..abfd3c811
Binary files /dev/null and b/java/libraries/minim/examples/GetMetaData/data/groove.mp3 differ
diff --git a/java/libraries/minim/examples/GetMetaData/data/serif.vlw b/java/libraries/minim/examples/GetMetaData/data/serif.vlw
new file mode 100644
index 000000000..dbb25086b
Binary files /dev/null and b/java/libraries/minim/examples/GetMetaData/data/serif.vlw differ
diff --git a/java/libraries/minim/examples/MonitorInput/MonitorInput.pde b/java/libraries/minim/examples/MonitorInput/MonitorInput.pde
new file mode 100644
index 000000000..3ec94cc6f
--- /dev/null
+++ b/java/libraries/minim/examples/MonitorInput/MonitorInput.pde
@@ -0,0 +1,41 @@
+/**
+ * This sketch demonstrates how to monitor the currently active audio input
+ * 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
+ * as the active audio input, or something else entirely.
+ *
+ * When you run your sketch as an applet you will need to sign it in order to get an input.
+ */
+
+import ddf.minim.*;
+
+Minim minim;
+AudioInput in;
+
+void setup()
+{
+ size(512, 200, P3D);
+
+ minim = new Minim(this);
+
+ // 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()
+{
+ background(0);
+ stroke(255);
+
+ // draw the waveforms so we can see what we are monitoring
+ for(int i = 0; i < in.bufferSize() - 1; i++)
+ {
+ 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 );
+ }
+}
diff --git a/java/libraries/minim/examples/PatchingAnInput/PatchingAnInput.pde b/java/libraries/minim/examples/PatchingAnInput/PatchingAnInput.pde
new file mode 100644
index 000000000..54b8719aa
--- /dev/null
+++ b/java/libraries/minim/examples/PatchingAnInput/PatchingAnInput.pde
@@ -0,0 +1,53 @@
+/**
+ * This sketch demonstrates how to create a simple synthesis chain that
+ * involves controlling the value of a UGenInput with the output of
+ * 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.
+ */
+
+import ddf.minim.*;
+import ddf.minim.ugens.*;
+
+Minim minim;
+AudioOutput out;
+Oscil wave;
+Oscil mod;
+
+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();
+
+ // create a triangle wave Oscil, set to 440 Hz, at 1.0 amplitude
+ // in this case, the amplitude we construct the Oscil with
+ // doesn't matter because we will be patching something to
+ // its amplitude input.
+ wave = new Oscil( 440, 1.0f, Waves.TRIANGLE );
+
+ // create a sine wave Oscil for modulating the amplitude of wave
+ mod = new Oscil( 2, 0.4f, Waves.SINE );
+
+ // connect up the modulator
+ mod.patch( wave.amplitude );
+
+ // patch wave to the output
+ wave.patch( out );
+}
+
+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 );
+ }
+}
diff --git a/java/libraries/minim/examples/PlayAFile/PlayAFile.pde b/java/libraries/minim/examples/PlayAFile/PlayAFile.pde
new file mode 100644
index 000000000..a906820ea
--- /dev/null
+++ b/java/libraries/minim/examples/PlayAFile/PlayAFile.pde
@@ -0,0 +1,43 @@
+/**
+ * This sketch demonstrates how to play a file with Minim using an AudioPlayer.
+ * It's also a good example of how to draw the waveform of the audio.
+ */
+
+import ddf.minim.*;
+
+Minim minim;
+AudioPlayer player;
+
+void setup()
+{
+ size(512, 200, P3D);
+
+ // we pass this to Minim so that it can load files from the data directory
+ minim = new Minim(this);
+
+ // loadFile will look in all the same places as loadImage does.
+ // this means you can find files that are in the data folder and the
+ // sketch folder. you can also pass an absolute path, or a URL.
+ player = minim.loadFile("marcus_kellis_theme.mp3");
+
+ // play the file
+ player.play();
+}
+
+void draw()
+{
+ background(0);
+ stroke(255);
+
+ // draw the waveforms
+ // the values returned by left.get() and right.get() will be between -1 and 1,
+ // so we need to scale them up to see the waveform
+ // note that if the file is MONO, left.get() and right.get() will return the same value
+ for(int i = 0; i < player.bufferSize() - 1; i++)
+ {
+ float x1 = map( i, 0, player.bufferSize(), 0, width );
+ float x2 = map( i+1, 0, player.bufferSize(), 0, width );
+ line( x1, 50 + player.left.get(i)*50, x2, 50 + player.left.get(i+1)*50 );
+ line( x1, 150 + player.right.get(i)*50, x2, 150 + player.right.get(i+1)*50 );
+ }
+}
diff --git a/java/libraries/minim/examples/PlayAFile/data/marcus_kellis_theme.mp3 b/java/libraries/minim/examples/PlayAFile/data/marcus_kellis_theme.mp3
new file mode 100644
index 000000000..ba57c5aac
Binary files /dev/null and b/java/libraries/minim/examples/PlayAFile/data/marcus_kellis_theme.mp3 differ
diff --git a/java/libraries/minim/examples/RecordAudioInput/RecordAudioInput.pde b/java/libraries/minim/examples/RecordAudioInput/RecordAudioInput.pde
new file mode 100644
index 000000000..296d23814
--- /dev/null
+++ b/java/libraries/minim/examples/RecordAudioInput/RecordAudioInput.pde
@@ -0,0 +1,84 @@
+/**
+ * This sketch demonstrates how to an AudioRecorder 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.
+ * The recorded file will be placed in the sketch folder of the sketch.
+ */
+
+import ddf.minim.*;
+
+Minim minim;
+AudioInput in;
+AudioRecorder recorder;
+
+void setup()
+{
+ size(512, 200, P3D);
+
+ 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
+ // the file will be located in the sketch's root folder.
+ recorder = minim.createRecorder(in, "myrecording.wav", true);
+
+ textFont(createFont("Arial", 12));
+}
+
+void draw()
+{
+ background(0);
+ stroke(255);
+ // draw the waveforms
+ // the values returned by left.get() and right.get() will be between -1 and 1,
+ // so we need to scale them up to see the waveform
+ for(int i = 0; i < in.bufferSize() - 1; i++)
+ {
+ 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);
+ }
+
+ if ( recorder.isRecording() )
+ {
+ text("Currently recording...", 5, 15);
+ }
+ else
+ {
+ text("Not recording.", 5, 15);
+ }
+}
+
+void keyReleased()
+{
+ if ( key == 'r' )
+ {
+ // to indicate that you want to start or stop capturing audio data, you must call
+ // beginRecord() and endRecord() on the AudioRecorder object. You can start and stop
+ // as many times as you like, the audio data will be appended to the end of the buffer
+ // (in the case of buffered recording) or to the end of the file (in the case of streamed recording).
+ if ( recorder.isRecording() )
+ {
+ recorder.endRecord();
+ }
+ else
+ {
+ recorder.beginRecord();
+ }
+ }
+ if ( key == 's' )
+ {
+ // we've filled the file out buffer,
+ // now write it to the file we specified in createRecorder
+ // in the case of buffered recording, if the buffer is large,
+ // this will appear to freeze the sketch for sometime
+ // in the case of streamed recording,
+ // it will not freeze as the data is already in the file and all that is being done
+ // is closing the file.
+ // the method returns the recorded audio as an AudioRecording,
+ // see the example AudioRecorder >> RecordAndPlayback for more about that
+ recorder.save();
+ println("Done saving.");
+ }
+}
diff --git a/java/libraries/minim/examples/RecordAudioOutput/RecordAudioOutput.pde b/java/libraries/minim/examples/RecordAudioOutput/RecordAudioOutput.pde
new file mode 100644
index 000000000..ae7cefdbf
--- /dev/null
+++ b/java/libraries/minim/examples/RecordAudioOutput/RecordAudioOutput.pde
@@ -0,0 +1,92 @@
+/**
+ * This sketch demonstrates how to use an AudioRecorder 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.
+ */
+
+import ddf.minim.*;
+import ddf.minim.ugens.*;
+
+Minim minim;
+AudioOutput out;
+AudioRecorder recorder;
+
+void setup()
+{
+ size(512, 200, P3D);
+
+ minim = new Minim(this);
+
+ 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
+ // the file will be located in the sketch's root folder.
+ recorder = minim.createRecorder(out, "myrecording.wav", true);
+
+ // patch some sound into the output so we have something to record
+ Oscil wave = new Oscil( 440.f, 1.0f );
+ Oscil mod = new Oscil( 4.0f, 0.25f, Waves.SAW );
+ mod.offset.setLastValue( 0.5f );
+ mod.patch( wave.amplitude );
+ wave.patch( out );
+
+ textFont(createFont("Arial", 12));
+}
+
+void draw()
+{
+ background(0);
+ stroke(255);
+ // draw the waveforms
+ // the values returned by left.get() and right.get() will be between -1 and 1,
+ // so we need to scale them up to see the waveform
+ 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);
+ }
+
+ if ( recorder.isRecording() )
+ {
+ text("Currently recording...", 5, 15);
+ }
+ else
+ {
+ text("Not recording.", 5, 15);
+ }
+}
+
+void keyReleased()
+{
+ if ( key == 'r' )
+ {
+ // to indicate that you want to start or stop capturing audio data, you must call
+ // beginRecord() and endRecord() on the AudioRecorder object. You can start and stop
+ // as many times as you like, the audio data will be appended to the end of the buffer
+ // (in the case of buffered recording) or to the end of the file (in the case of streamed recording).
+ if ( recorder.isRecording() )
+ {
+ recorder.endRecord();
+ }
+ else
+ {
+ recorder.beginRecord();
+ }
+ }
+ if ( key == 's' )
+ {
+ // we've filled the file out buffer,
+ // now write it to the file we specified in createRecorder
+ // in the case of buffered recording, if the buffer is large,
+ // this will appear to freeze the sketch for sometime
+ // in the case of streamed recording,
+ // it will not freeze as the data is already in the file and all that is being done
+ // is closing the file.
+ // the method returns the recorded audio as an AudioRecording,
+ // see the example AudioRecorder >> RecordAndPlayback for more about that
+ recorder.save();
+ println("Done saving.");
+ }
+}
diff --git a/java/libraries/minim/examples/Scrubbing/Scrubbing.pde b/java/libraries/minim/examples/Scrubbing/Scrubbing.pde
new file mode 100644
index 000000000..dc3c5fedd
--- /dev/null
+++ b/java/libraries/minim/examples/Scrubbing/Scrubbing.pde
@@ -0,0 +1,68 @@
+/**
+ * This is a relatively simple file player that lets you scrub forward and backward in an audio file.
+ * It should be noted that it's not *exactly* scrubbing because the playback speed is not changed,
+ * it's simply that the position in the song is changed by very small increments when fast-forwarding or rewinding.
+ * But the end result is convincing enough.
+ *
+ * The positioning code is inside of the Play, Rewind, and Forward classes, which are in button.pde.
+ */
+
+import ddf.minim.*;
+
+Minim minim;
+AudioPlayer song;
+Play play;
+Rewind rewind;
+Forward ffwd;
+
+void setup()
+{
+ size(512, 200, P3D);
+ minim = new Minim(this);
+ // load a file from the data folder, use a sample buffer of 1024 samples
+ song = minim.loadFile("fair1939.wav", 512);
+ // buttons for control
+ play = new Play(width/2 - 50, 130, 20, 10);
+ rewind = new Rewind(width/2, 130, 20, 10);
+ ffwd = new Forward(width/2 + 50, 130, 20, 10);
+}
+
+void draw()
+{
+ background(0);
+ // draw the wave form
+ // this wav is MONO, so we only need the left channel,
+ // though we could have used the right channel and gotten the same values
+ stroke(255);
+ for (int i = 0; i < song.bufferSize() - 1; i++)
+ {
+ line(i, 50 - song.left.get(i)*50, i+1, 50 - song.left.get(i+1)*10);
+ }
+ // draw the position in the song
+ // the position is in milliseconds,
+ // to get a meaningful graphic, we need to map the value to the range [0, width]
+ float x = map(song.position(), 0, song.length(), 0, width);
+ stroke(255, 0, 0);
+ line(x, 50 - 20, x, 50 + 20);
+ // do the controls
+ play.update();
+ play.draw();
+ rewind.update();
+ rewind.draw();
+ ffwd.update();
+ ffwd.draw();
+}
+
+void mousePressed()
+{
+ play.mousePressed();
+ rewind.mousePressed();
+ ffwd.mousePressed();
+}
+
+void mouseReleased()
+{
+ play.mouseReleased();
+ rewind.mouseReleased();
+ ffwd.mouseReleased();
+}
diff --git a/java/libraries/minim/examples/Scrubbing/button.pde b/java/libraries/minim/examples/Scrubbing/button.pde
new file mode 100755
index 000000000..90cc1b15b
--- /dev/null
+++ b/java/libraries/minim/examples/Scrubbing/button.pde
@@ -0,0 +1,255 @@
+abstract class Button
+{
+ int x, y, hw, hh;
+
+ Button(int x, int y, int hw, int hh)
+ {
+ this.x = x;
+ this.y = y;
+ this.hw = hw;
+ this.hh = hh;
+ }
+
+ boolean pressed()
+ {
+ return mouseX > x - hw && mouseX < x + hw && mouseY > y - hh && mouseY < y + hh;
+ }
+
+ abstract void mousePressed();
+ abstract void mouseReleased();
+ abstract void update();
+ abstract void draw();
+}
+
+class Play extends Button
+{
+ boolean play;
+ boolean invert;
+
+ Play(int x, int y, int hw, int hh)
+ {
+ super(x, y, hw, hh);
+ play = true;
+ }
+
+ // code to handle playing and pausing the file
+ void mousePressed()
+ {
+ if ( pressed() )
+ {
+ invert = true;
+ if ( song.isPlaying() )
+ {
+ song.pause();
+ play = true;
+ }
+ else
+ {
+ song.loop();
+ play = false;
+ }
+ }
+ }
+
+ void mouseReleased()
+ {
+ invert = false;
+ }
+
+ // play is a boolean value used to determine what to draw on the button
+ void update()
+ {
+ if ( song.isPlaying() ) play = false;
+ else play = true;
+ }
+
+ void draw()
+ {
+ if ( invert )
+ {
+ fill(255);
+ stroke(0);
+ }
+ else
+ {
+ noFill();
+ stroke(255);
+ }
+ rect(x - hw, y - hh, hw*2, hh*2);
+ if ( invert )
+ {
+ fill(0);
+ stroke(255);
+ }
+ else
+ {
+ fill(255);
+ noStroke();
+ }
+ if ( play )
+ {
+ triangle(x - hw/3, y - hh/2, x - hw/3, y + hh/2, x + hw/2, y);
+ }
+ else
+ {
+ rect(x - hw/3, y - hh/2, hw/4, hh);
+ rect(x + hw/8, y - hh/2, hw/4, hh);
+ }
+ }
+}
+
+class Rewind extends Button
+{
+ boolean invert;
+ boolean pressed;
+
+ Rewind(int x, int y, int hw, int hh)
+ {
+ super(x, y, hw, hh);
+ invert = false;
+ }
+
+ // code used to scrub backward in the file
+ void update()
+ {
+ // if the rewind button is currently being pressed
+ if (pressed)
+ {
+ // get the current song position
+ int pos = song.position();
+ // if it greater than 200 milliseconds
+ if ( pos > 200 )
+ {
+ // rewind the song by 200 milliseconds
+ song.skip(-200);
+ }
+ else
+ {
+ // if the song hasn't played more than 100 milliseconds
+ // just rewind to the beginning
+ song.rewind();
+ }
+ }
+ }
+
+ void mousePressed()
+ {
+ pressed = pressed();
+ if ( pressed )
+ {
+ invert = true;
+ // if the song isn't currently playing, rewind it to the beginning
+ if ( !song.isPlaying() ) song.rewind();
+ }
+ }
+
+ void mouseReleased()
+ {
+ pressed = false;
+ invert = false;
+ }
+
+ void draw()
+ {
+ if ( invert )
+ {
+ fill(255);
+ stroke(0);
+ }
+ else
+ {
+ noFill();
+ stroke(255);
+ }
+ rect(x - hw, y - hh, hw*2, hh*2);
+ if ( invert )
+ {
+ fill(0);
+ stroke(255);
+ }
+ else
+ {
+ fill(255);
+ noStroke();
+ }
+ triangle(x - hw/2, y, x, y - hh/2, x, y + hh/2);
+ triangle(x, y, x + hw/2, y - hh/2, x + hw/2, y + hh/2);
+ }
+}
+
+class Forward extends Button
+{
+ boolean invert;
+ boolean pressed;
+
+ Forward(int x, int y, int hw, int hh)
+ {
+ super(x, y, hw, hh);
+ invert = false;
+ }
+
+ void update()
+ {
+ // if the forward button is currently being pressed
+ if (pressed)
+ {
+ // get the current position of the song
+ int pos = song.position();
+ // if the song's position is more than 40 milliseconds from the end of the song
+ if ( pos < song.length() - 40 )
+ {
+ // forward the song by 40 milliseconds
+ song.skip(40);
+ }
+ else
+ {
+ // otherwise, cue the song at the end of the song
+ song.cue( song.length() );
+ }
+ // start the song playing
+ song.play();
+ }
+ }
+
+ void mousePressed()
+ {
+ pressed = pressed();
+ if ( pressed )
+ {
+ invert = true;
+ }
+ }
+
+ void mouseReleased()
+ {
+ pressed = false;
+ invert = false;
+ }
+
+ void draw()
+ {
+ if ( invert )
+ {
+ fill(255);
+ stroke(0);
+ }
+ else
+ {
+ noFill();
+ stroke(255);
+ }
+ rect(x - hw, y - hh, hw*2, hh*2);
+ if ( invert )
+ {
+ fill(0);
+ stroke(255);
+ }
+ else
+ {
+ fill(255);
+ noStroke();
+ }
+ triangle(x, y, x - hw/2, y - hh/2, x - hw/2, y + hh/2);
+ triangle(x, y - hh/2, x, y + hh/2, x + hw/2, y);
+ }
+}
diff --git a/java/libraries/minim/examples/Scrubbing/data/fair1939.wav b/java/libraries/minim/examples/Scrubbing/data/fair1939.wav
new file mode 100755
index 000000000..815a691e6
Binary files /dev/null and b/java/libraries/minim/examples/Scrubbing/data/fair1939.wav differ
diff --git a/java/libraries/minim/examples/SequenceSound/SequenceSound.pde b/java/libraries/minim/examples/SequenceSound/SequenceSound.pde
new file mode 100644
index 000000000..9d4878e94
--- /dev/null
+++ b/java/libraries/minim/examples/SequenceSound/SequenceSound.pde
@@ -0,0 +1,66 @@
+/**
+ * This sketch demonstrates how to create synthesized sound with Minim using an AudioOutput and the
+ * default instrument built into an AudioOutput. 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. It also demonstrates
+ * a couple different versions of the playNote method.
+ *
+ * For more complex examples of using playNote check out algorithmicCompExample and compositionExample
+ * in the Synthesis folder.
+ */
+
+import ddf.minim.*;
+import ddf.minim.ugens.*;
+
+Minim minim;
+AudioOutput 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();
+
+ // given start time, duration, and frequency
+ out.playNote( 0.0, 0.9, 97.99 );
+ out.playNote( 1.0, 0.9, 123.47 );
+
+ // given start time, duration, and note name
+ out.playNote( 2.0, 2.9, "C3" );
+ out.playNote( 3.0, 1.9, "E3" );
+ out.playNote( 4.0, 0.9, "G3" );
+
+ // given start time and note name or frequency
+ // (duration defaults to 1.0)
+ out.playNote( 5.0, "" );
+ out.playNote( 6.0, 329.63);
+ 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.
+ 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 );
+}
+
+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 );
+ }
+}
diff --git a/java/libraries/minim/examples/SoundSpectrum/SoundSpectrum.pde b/java/libraries/minim/examples/SoundSpectrum/SoundSpectrum.pde
new file mode 100644
index 000000000..c9095d953
--- /dev/null
+++ b/java/libraries/minim/examples/SoundSpectrum/SoundSpectrum.pde
@@ -0,0 +1,178 @@
+/**
+ * An FFT object is used to convert an audio signal into its frequency domain representation. This representation
+ * lets you see how much of each frequency is contained in an audio signal. Sometimes you might not want to
+ * work with the entire spectrum, so it's possible to have the FFT object calculate average frequency bands by
+ * simply averaging the values of adjacent frequency bands in the full spectrum. There are two different ways
+ * these can be calculated: Linearly, by grouping equal numbers of adjacent frequency bands, or
+ * Logarithmically, by grouping frequency bands by octave, which is more akin to how humans hear sound.
+ *
+ * This sketch illustrates the difference between viewing the full spectrum, linearly spaced averaged bands,
+ * and logarithmically spaced averaged bands.
+ *
+ * From top to bottom: + *
loadSample method of Minim.
+ * The loadSample method allows you to specify the sample you want to load
+ * with a String and optionally specify what you want the buffer size of the
+ * returned AudioSample to be. Minim is able to load wav files, au files, aif
+ * files, snd files, and mp3 files. When you call loadSample, if you just
+ * specify the filename it will try to load the sample from the data folder of your sketch.
+ * However, you can also specify an absolute path (such as "C:\foo\bar\thing.wav") and the
+ * file will be loaded from that location (keep in mind that won't work from an applet).
+ * You can also specify a URL (such as "http://www.mysite.com/mp3/song.mp3") but keep in mind
+ * that if you run the sketch as an applet you may run in to security restrictions
+ * if the applet is not on the same domain as the file you want to load. You can get around
+ * the restriction by signing all of the jars in the applet.
+ *
+ * An AudioSample is a special kind of file playback that allows
+ * you to repeatedly trigger an audio file. It does this by keeping the
+ * entire file in an internal buffer and then keeping a list of trigger points.
+ * AudioSample supports up to 20 overlapping triggers, which
+ * should be plenty for short sounds. It is not advised that you use this class
+ * for long sounds (like entire songs, for example) because the entire file is
+ * kept in memory.
+ *
+ * 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. + */ + +import ddf.minim.*; + +Minim minim; +AudioSample kick; +AudioSample snare; + +void setup() +{ + size(512, 200, P3D); + minim = new Minim(this); + + // load BD.wav from the data folder + kick = minim.loadSample( "BD.mp3", // filename + 512 // buffer size + ); + + // An AudioSample will spawn its own audio processing Thread, + // and since audio processing works by generating one buffer + // of samples at a time, we can specify how big we want that + // buffer to be in the call to loadSample. + // above, we requested a buffer size of 512 because + // this will make the triggering of the samples sound more responsive. + // on some systems, this might be too small and the audio + // will sound corrupted, in that case, you can just increase + // the buffer size. + + // if a file doesn't exist, loadSample will return null + if ( kick == null ) println("Didn't get kick!"); + + // load SD.wav from the data folder + snare = minim.loadSample("SD.wav", 512); + if ( snare == null ) println("Didn't get snare!"); +} + +void draw() +{ + background(0); + stroke(255); + + // use the mix buffer to draw the waveforms. + for (int i = 0; i < kick.bufferSize() - 1; i++) + { + float x1 = map(i, 0, kick.bufferSize(), 0, width); + float x2 = map(i+1, 0, kick.bufferSize(), 0, width); + line(x1, 50 - kick.mix.get(i)*50, x2, 50 - kick.mix.get(i+1)*50); + line(x1, 150 - snare.mix.get(i)*50, x2, 150 - snare.mix.get(i+1)*50); + } +} + +void keyPressed() +{ + if ( key == 's' ) snare.trigger(); + if ( key == 'k' ) kick.trigger(); +} + diff --git a/java/libraries/minim/examples/TriggerASample/data/BD.mp3 b/java/libraries/minim/examples/TriggerASample/data/BD.mp3 new file mode 100644 index 000000000..9d1aa49fe Binary files /dev/null and b/java/libraries/minim/examples/TriggerASample/data/BD.mp3 differ diff --git a/java/libraries/minim/examples/TriggerASample/data/SD.wav b/java/libraries/minim/examples/TriggerASample/data/SD.wav new file mode 100644 index 000000000..5020ce899 Binary files /dev/null and b/java/libraries/minim/examples/TriggerASample/data/SD.wav differ diff --git a/java/libraries/minim/examples/delayExample/delayExample.pde b/java/libraries/minim/examples/delayExample/delayExample.pde new file mode 100644 index 000000000..dbf69a4ac --- /dev/null +++ b/java/libraries/minim/examples/delayExample/delayExample.pde @@ -0,0 +1,88 @@ +/* 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) +*/ + +// import everything necessary to make sound. +import ddf.minim.*; +import ddf.minim.ugens.*; + +// create all of the variables that will need to be accessed in +// more than one methods (setup(), draw(), stop()). +Minim minim; +AudioOutput out; +Delay myDelay1; + +// setup is run once at the beginning +void setup() +{ + // initialize the drawing window + size( 512, 200, P2D ); + + // initialize the minim and out objects + minim = new Minim(this); + out = minim.getLineOut( Minim.MONO, 2048 ); + + // initialize myDelay1 with continual feedback and no audio passthrough + myDelay1 = new Delay( 0.6, 0.9, true, false ); + // create the Blip that will be used + Oscil myBlip = new Oscil( 245.0, 0.3, Waves.saw( 15 ) ); + + // 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 ); + + // the Blip is patched directly into the sum + myBlip.patch( sum ); + + // 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 ); +} + +// draw is run many times +void draw() +{ + // erase the window to dark grey + background( 64 ); + // draw using a light gray stroke + stroke( 192 ); + // draw the waveforms + for( int i = 0; i < out.bufferSize() - 1; i++ ) + { + // find the x position of each buffer value + float x1 = map( i, 0, out.bufferSize(), 0, width ); + float x2 = map( i+1, 0, out.bufferSize(), 0, width ); + // 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); + } +} + +// when the mouse is moved, change the delay parameters +void mouseMoved() +{ + // set the delay time by the horizontal location + float delayTime = map( mouseX, 0, width, 0.0001, 0.5 ); + myDelay1.setDelTime( delayTime ); + // set the feedback factor by the vertical location + float feedbackFactor = map( mouseY, 0, height, 0.0, 0.99 ); + myDelay1.setDelAmp( feedbackFactor ); +} diff --git a/java/libraries/minim/examples/filterExample/filterExample.pde b/java/libraries/minim/examples/filterExample/filterExample.pde new file mode 100644 index 000000000..3035fc5f1 --- /dev/null +++ b/java/libraries/minim/examples/filterExample/filterExample.pde @@ -0,0 +1,81 @@ +/* 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) +*/ + +// import everything necessary to make sound. +import ddf.minim.*; +import ddf.minim.ugens.*; +// the effects package is needed because the filters are there for now. +import ddf.minim.effects.*; + +// create all of the variables that will need to be accessed in +// more than one methods (setup(), draw(), stop()). +Minim minim; +AudioOutput out; + +// setup is run once at the beginning +void setup() +{ +// initialize the drawing window + size(300, 200, P2D); + + // initialize the minim and out objects + minim = new Minim(this); + out = minim.getLineOut(); + + // create all of the variables + IIRFilter filt; + Oscil osc; + Oscil cutOsc; + Constant cutoff; + + // initialize the oscillator + // (a sawtooth wave has energy across the spectrum) + osc = new Oscil(500, 0.2, Waves.SAW); + + // uncoment one of the filters to hear it's effect + //filt = new LowPassSP(400, out.sampleRate()); + //filt = new LowPassFS(400, out.sampleRate()); + filt = new BandPass(400, 100, out.sampleRate()); + //filt = new HighPassSP(400, out.sampleRate()); + //filt = new NotchFilter(400, 100, out.sampleRate()); + + // create an Oscil we will use to modulate + // the cutoff frequency of the filter. + // by using an amplitude of 800 and an + // offset of 1000, the cutoff frequency + // will sweep between 200 and 1800 Hertz. + cutOsc = new Oscil(1, 800, Waves.SINE); + // offset the center value of the Oscil by 1000 + cutOsc.offset.setLastValue( 1000 ); + + // patch the oscil to the cutoff frequency of the filter + cutOsc.patch(filt.cutoff); + + // patch the sawtooth oscil through the filter and then to the output + osc.patch(filt).patch(out); +} + + +// draw is run many times +void draw() +{ + // erase the window to black + background( 0 ); + // draw using a white stroke + stroke( 255 ); + // draw the waveforms + for( int i = 0; i < out.bufferSize() - 1; i++ ) + { + // find the x position of each buffer value + float x1 = map( i, 0, out.bufferSize(), 0, width ); + float x2 = map( i+1, 0, out.bufferSize(), 0, width ); + // 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); + } +} diff --git a/java/libraries/minim/examples/frequencyModulation/frequencyModulation.pde b/java/libraries/minim/examples/frequencyModulation/frequencyModulation.pde new file mode 100644 index 000000000..8338ea098 --- /dev/null +++ b/java/libraries/minim/examples/frequencyModulation/frequencyModulation.pde @@ -0,0 +1,76 @@ +/* frequencyModulation +
+ A simple example for doing FM (frequency modulation) using two Oscils. + Use the mouse to control the speed and range of the frequency modulation. +
+ Author: Damien Di Fede
+*/
+
+// import everything necessary to make sound.
+import ddf.minim.*;
+import ddf.minim.ugens.*;
+
+// create all of the variables that will need to be accessed in
+// more than one methods (setup(), draw(), stop()).
+Minim minim;
+AudioOutput out;
+
+// the Oscil we use for modulating frequency.
+Oscil fm;
+
+// setup is run once at the beginning
+void setup()
+{
+ // initialize the drawing window
+ size( 512, 200, P3D );
+
+ // initialize the minim and out objects
+ minim = new Minim( this );
+ out = minim.getLineOut();
+
+ // make the Oscil we will hear.
+ // arguments are frequency, amplitude, and waveform
+ Oscil wave = new Oscil( 200, 0.8, Waves.TRIANGLE );
+ // make the Oscil we will use to modulate the frequency of wave.
+ // the frequency of this Oscil will determine how quickly the
+ // frequency of wave changes and the amplitude determines how much.
+ // since we are using the output of fm directly to set the frequency
+ // of wave, you can think of the amplitude as being expressed in Hz.
+ fm = new Oscil( 10, 2, Waves.SINE );
+ // set the offset of fm so that it generates values centered around 200 Hz
+ fm.offset.setLastValue( 200 );
+ // patch it to the frequency of wave so it controls it
+ fm.patch( wave.frequency );
+ // and patch wave to the output
+ wave.patch( out );
+}
+
+// draw is run many times
+void draw()
+{
+ // erase the window to black
+ background( 0 );
+ // draw using a white stroke
+ stroke( 255 );
+ // draw the waveforms
+ for( int i = 0; i < out.bufferSize() - 1; i++ )
+ {
+ // find the x position of each buffer value
+ float x1 = map( i, 0, out.bufferSize(), 0, width );
+ float x2 = map( i+1, 0, out.bufferSize(), 0, width );
+ // 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);
+ }
+}
+
+// we can change the parameters of the frequency modulation Oscil
+// in real-time using the mouse.
+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 );
+}
diff --git a/java/libraries/minim/examples/loadFileIntoBuffer/data/SD.wav b/java/libraries/minim/examples/loadFileIntoBuffer/data/SD.wav
new file mode 100644
index 000000000..5020ce899
Binary files /dev/null and b/java/libraries/minim/examples/loadFileIntoBuffer/data/SD.wav differ
diff --git a/java/libraries/minim/examples/loadFileIntoBuffer/loadFileIntoBuffer.pde b/java/libraries/minim/examples/loadFileIntoBuffer/loadFileIntoBuffer.pde
new file mode 100644
index 000000000..ec5c6d1b4
--- /dev/null
+++ b/java/libraries/minim/examples/loadFileIntoBuffer/loadFileIntoBuffer.pde
@@ -0,0 +1,90 @@
+/**
+ * This sketch demonstrates how to use the loadFileIntoBuffer method of the Minim class and is also a good
+ * reference for some of the methods of the MultiChannelBuffer class. When the sketch begins it loads
+ * 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.
+ */
+
+import ddf.minim.*;
+import ddf.minim.ugens.*;
+
+Minim minim;
+MultiChannelBuffer sampleBuffer;
+
+AudioOutput output;
+Sampler sampler;
+
+void setup()
+{
+ size(512, 200, P3D);
+
+ // create Minim and an AudioOutput
+ minim = new Minim(this);
+ output = minim.getLineOut();
+
+ // construct a new MultiChannelBuffer with 2 channels and 1024 sample frames.
+ // in our particular case, it doesn't really matter what we choose for these
+ // two values because loadFileIntoBuffer will reconfigure the buffer
+ // to match the channel count and length of the file.
+ sampleBuffer = new MultiChannelBuffer( 1, 1024 );
+
+ // we pass the buffer to the method and Minim will reconfigure it to match
+ // the file. if the file doesn't exist, or there is some other problen with
+ // loading it, the function will return 0 as the sample rate.
+ float sampleRate = minim.loadFileIntoBuffer( "SD.wav", sampleBuffer );
+
+ // make sure the file load worked
+ if ( sampleRate > 0 )
+ {
+ // double the size of the buffer to give ourselves some silence to play with
+ int originalBufferSize = sampleBuffer.getBufferSize();
+ sampleBuffer.setBufferSize( originalBufferSize * 2 );
+
+ // go through first half of the buffer, which contains the original sample,
+ // and add a delayed version of each sample at some random position.
+ // we happen to know that the source file is only one channel
+ // but in general you'd want to iterate over all channels when doing something like this
+ for( int s = 0; s < originalBufferSize; ++s )
+ {
+ int delayIndex = s + int( random( 0, originalBufferSize ) );
+ float sampleValue = sampleBuffer.getSample( 0, s );
+ float destValue = sampleBuffer.getSample( 0, delayIndex );
+ sampleBuffer.setSample( 0, // channel
+ delayIndex, // sample frame to set
+ sampleValue + destValue // the value to set
+ );
+ }
+
+ // create a sampler that will use our buffer to generate audio.
+ // we must provide the sample rate of the audio and the number of voices.
+ sampler = new Sampler( sampleBuffer, sampleRate, 1 );
+
+ // and finally, connect to the output so we can hear it
+ sampler.patch( output );
+ }
+}
+
+void draw()
+{
+ background(0);
+ stroke(255);
+
+ // use the mix buffer to draw the waveforms.
+ for (int i = 0; i < output.bufferSize() - 1; i++)
+ {
+ float x1 = map(i, 0, output.bufferSize(), 0, width);
+ float x2 = map(i+1, 0, output.bufferSize(), 0, width);
+ line(x1, 50 - output.left.get(i)*50, x2, 50 - output.left.get(i+1)*50);
+ line(x1, 150 - output.right.get(i)*50, x2, 150 - output.right.get(i+1)*50);
+ }
+}
+
+void keyPressed()
+{
+ if ( key == ' ' && sampler != null )
+ {
+ sampler.trigger();
+ }
+}
+
diff --git a/java/libraries/minim/library/export.txt b/java/libraries/minim/library/export.txt
new file mode 100644
index 000000000..f2681acab
--- /dev/null
+++ b/java/libraries/minim/library/export.txt
@@ -0,0 +1 @@
+name = Minim Audio
diff --git a/java/libraries/minim/license.txt b/java/libraries/minim/license.txt
new file mode 100644
index 000000000..fc8a5de7e
--- /dev/null
+++ b/java/libraries/minim/license.txt
@@ -0,0 +1,165 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.