mirror of
https://github.com/processing/processing4.git
synced 2026-01-27 18:31:07 +01:00
New Minim for 2.0
This commit is contained in:
55
java/libraries/minim/examples/AnalyzeSound/AnalyzeSound.pde
Normal file
55
java/libraries/minim/examples/AnalyzeSound/AnalyzeSound.pde
Normal file
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* This sketch demonstrates how to use an FFT to analyze
|
||||
* the audio being generated by an AudioPlayer.
|
||||
* <p>
|
||||
* 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 );
|
||||
}
|
||||
}
|
||||
BIN
java/libraries/minim/examples/AnalyzeSound/data/jingle.mp3
Normal file
BIN
java/libraries/minim/examples/AnalyzeSound/data/jingle.mp3
Normal file
Binary file not shown.
65
java/libraries/minim/examples/GetMetaData/GetMetaData.pde
Normal file
65
java/libraries/minim/examples/GetMetaData/GetMetaData.pde
Normal file
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* Get Meta Data
|
||||
* by Damien Di Fede.
|
||||
*
|
||||
* This sketch demonstrates how to use the <code>getMetaData</code>
|
||||
* method of <code>AudioPlayer</code>. This method is also available
|
||||
* for <code>AudioSnippet</code> and <code>AudioSample</code>.
|
||||
* 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();
|
||||
}
|
||||
BIN
java/libraries/minim/examples/GetMetaData/data/groove.mp3
Normal file
BIN
java/libraries/minim/examples/GetMetaData/data/groove.mp3
Normal file
Binary file not shown.
BIN
java/libraries/minim/examples/GetMetaData/data/serif.vlw
Normal file
BIN
java/libraries/minim/examples/GetMetaData/data/serif.vlw
Normal file
Binary file not shown.
41
java/libraries/minim/examples/MonitorInput/MonitorInput.pde
Normal file
41
java/libraries/minim/examples/MonitorInput/MonitorInput.pde
Normal file
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* This sketch demonstrates how to monitor the currently active audio input
|
||||
* of the computer using an <code>AudioInput</code>. 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.
|
||||
* <p>
|
||||
* 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 );
|
||||
}
|
||||
}
|
||||
@@ -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 );
|
||||
}
|
||||
}
|
||||
43
java/libraries/minim/examples/PlayAFile/PlayAFile.pde
Normal file
43
java/libraries/minim/examples/PlayAFile/PlayAFile.pde
Normal file
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
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 );
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
* 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.
|
||||
* 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.");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
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.");
|
||||
}
|
||||
}
|
||||
68
java/libraries/minim/examples/Scrubbing/Scrubbing.pde
Normal file
68
java/libraries/minim/examples/Scrubbing/Scrubbing.pde
Normal file
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* This is a relatively simple file player that lets you scrub forward and backward in an audio file.<br />
|
||||
* 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.
|
||||
* <p>
|
||||
* 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();
|
||||
}
|
||||
255
java/libraries/minim/examples/Scrubbing/button.pde
Executable file
255
java/libraries/minim/examples/Scrubbing/button.pde
Executable file
@@ -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);
|
||||
}
|
||||
}
|
||||
BIN
java/libraries/minim/examples/Scrubbing/data/fair1939.wav
Executable file
BIN
java/libraries/minim/examples/Scrubbing/data/fair1939.wav
Executable file
Binary file not shown.
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* This sketch demonstrates how to create synthesized sound with Minim using an <code>AudioOutput</code> and the
|
||||
* default instrument built into an <code>AudioOutput</code>. By using the <code>playNote</code> 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 <code>playNote</code> method.
|
||||
* <p>
|
||||
* For more complex examples of using <code>playNote</code> 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 );
|
||||
}
|
||||
}
|
||||
178
java/libraries/minim/examples/SoundSpectrum/SoundSpectrum.pde
Normal file
178
java/libraries/minim/examples/SoundSpectrum/SoundSpectrum.pde
Normal file
@@ -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: <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.
|
||||
* <p>
|
||||
* From top to bottom:
|
||||
* <ul>
|
||||
* <li>The full spectrum.</li>
|
||||
* <li>The spectrum grouped into 30 linearly spaced averages.</li>
|
||||
* <li>The spectrum grouped logarithmically into 10 octaves, each split into 3 bands.</li>
|
||||
* </ul>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import ddf.minim.analysis.*;
|
||||
import ddf.minim.*;
|
||||
|
||||
Minim minim;
|
||||
AudioPlayer jingle;
|
||||
FFT fftLin;
|
||||
FFT fftLog;
|
||||
|
||||
float height3;
|
||||
float height23;
|
||||
float spectrumScale = 4;
|
||||
|
||||
PFont font;
|
||||
|
||||
void setup()
|
||||
{
|
||||
size(512, 480);
|
||||
height3 = height/3;
|
||||
height23 = 2*height/3;
|
||||
|
||||
minim = new Minim(this);
|
||||
jingle = minim.loadFile("jingle.mp3", 1024);
|
||||
|
||||
// loop the file
|
||||
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 1024.
|
||||
// see the online tutorial for more info.
|
||||
fftLin = new FFT( jingle.bufferSize(), jingle.sampleRate() );
|
||||
|
||||
// calculate the averages by grouping frequency bands linearly. use 30 averages.
|
||||
fftLin.linAverages( 30 );
|
||||
|
||||
// create an FFT object for calculating logarithmically spaced averages
|
||||
fftLog = new FFT( jingle.bufferSize(), jingle.sampleRate() );
|
||||
|
||||
// calculate averages based on a miminum octave width of 22 Hz
|
||||
// split each octave into three bands
|
||||
// this should result in 30 averages
|
||||
fftLog.logAverages( 22, 3 );
|
||||
|
||||
rectMode(CORNERS);
|
||||
font = loadFont("ArialMT-12.vlw");
|
||||
}
|
||||
|
||||
void draw()
|
||||
{
|
||||
background(0);
|
||||
|
||||
textFont(font);
|
||||
textSize( 18 );
|
||||
|
||||
float centerFrequency = 0;
|
||||
|
||||
// perform a forward FFT on the samples in jingle's mix buffer
|
||||
// note that if jingle were a MONO file, this would be the same as using jingle.left or jingle.right
|
||||
fftLin.forward( jingle.mix );
|
||||
fftLog.forward( jingle.mix );
|
||||
|
||||
// draw the full spectrum
|
||||
{
|
||||
noFill();
|
||||
for(int i = 0; i < fftLin.specSize(); i++)
|
||||
{
|
||||
// if the mouse is over the spectrum value we're about to draw
|
||||
// set the stroke color to red
|
||||
if ( i == mouseX )
|
||||
{
|
||||
centerFrequency = fftLin.indexToFreq(i);
|
||||
stroke(255, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
stroke(255);
|
||||
}
|
||||
line(i, height3, i, height3 - fftLin.getBand(i)*spectrumScale);
|
||||
}
|
||||
|
||||
fill(255, 128);
|
||||
text("Spectrum Center Frequency: " + centerFrequency, 5, height3 - 25);
|
||||
}
|
||||
|
||||
// no more outline, we'll be doing filled rectangles from now
|
||||
noStroke();
|
||||
|
||||
// draw the linear averages
|
||||
{
|
||||
// since linear averages group equal numbers of adjacent frequency bands
|
||||
// we can simply precalculate how many pixel wide each average's
|
||||
// rectangle should be.
|
||||
int w = int( width/fftLin.avgSize() );
|
||||
for(int i = 0; i < fftLin.avgSize(); i++)
|
||||
{
|
||||
// if the mouse is inside the bounds of this average,
|
||||
// print the center frequency and fill in the rectangle with red
|
||||
if ( mouseX >= i*w && mouseX < i*w + w )
|
||||
{
|
||||
centerFrequency = fftLin.getAverageCenterFrequency(i);
|
||||
|
||||
fill(255, 128);
|
||||
text("Linear Average Center Frequency: " + centerFrequency, 5, height23 - 25);
|
||||
|
||||
fill(255, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
fill(255);
|
||||
}
|
||||
// draw a rectangle for each average, multiply the value by spectrumScale so we can see it better
|
||||
rect(i*w, height23, i*w + w, height23 - fftLin.getAvg(i)*spectrumScale);
|
||||
}
|
||||
}
|
||||
|
||||
// draw the logarithmic averages
|
||||
{
|
||||
// since logarithmically spaced averages are not equally spaced
|
||||
// we can't precompute the width for all averages
|
||||
for(int i = 0; i < fftLog.avgSize(); i++)
|
||||
{
|
||||
centerFrequency = fftLog.getAverageCenterFrequency(i);
|
||||
// how wide is this average in Hz?
|
||||
float averageWidth = fftLog.getAverageBandWidth(i);
|
||||
|
||||
// we calculate the lowest and highest frequencies
|
||||
// contained in this average using the center frequency
|
||||
// and bandwidth of this average.
|
||||
float lowFreq = centerFrequency - averageWidth/2;
|
||||
float highFreq = centerFrequency + averageWidth/2;
|
||||
|
||||
// freqToIndex converts a frequency in Hz to a spectrum band index
|
||||
// that can be passed to getBand. in this case, we simply use the
|
||||
// index as coordinates for the rectangle we draw to represent
|
||||
// the average.
|
||||
int xl = (int)fftLog.freqToIndex(lowFreq);
|
||||
int xr = (int)fftLog.freqToIndex(highFreq);
|
||||
|
||||
// if the mouse is inside of this average's rectangle
|
||||
// print the center frequency and set the fill color to red
|
||||
if ( mouseX >= xl && mouseX < xr )
|
||||
{
|
||||
fill(255, 128);
|
||||
text("Logarithmic Average Center Frequency: " + centerFrequency, 5, height - 25);
|
||||
fill(255, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
fill(255);
|
||||
}
|
||||
// draw a rectangle for each average, multiply the value by spectrumScale so we can see it better
|
||||
rect( xl, height, xr, height - fftLog.getAvg(i)*spectrumScale );
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
java/libraries/minim/examples/SoundSpectrum/data/ArialMT-12.vlw
Normal file
BIN
java/libraries/minim/examples/SoundSpectrum/data/ArialMT-12.vlw
Normal file
Binary file not shown.
BIN
java/libraries/minim/examples/SoundSpectrum/data/jingle.mp3
Normal file
BIN
java/libraries/minim/examples/SoundSpectrum/data/jingle.mp3
Normal file
Binary file not shown.
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import ddf.minim.*;
|
||||
import ddf.minim.ugens.*;
|
||||
|
||||
Minim minim;
|
||||
AudioOutput out;
|
||||
Oscil wave;
|
||||
|
||||
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 sine wave Oscil, set to 440 Hz, at 0.5 amplitude
|
||||
wave = new Oscil( 440, 0.5f, Waves.SINE );
|
||||
// patch the Oscil 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 );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/**
|
||||
* This sketch demonstrates how to use the <code>loadSample</code> method of <code>Minim</code>.
|
||||
* The <code>loadSample</code> method allows you to specify the sample you want to load
|
||||
* with a <code>String</code> and optionally specify what you want the buffer size of the
|
||||
* returned <code>AudioSample</code> to be. Minim is able to load wav files, au files, aif
|
||||
* files, snd files, and mp3 files. When you call <code>loadSample</code>, 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.
|
||||
* <p>
|
||||
* An <code>AudioSample</code> is a special kind of file playback that allows
|
||||
* you to repeatedly <i>trigger</i> an audio file. It does this by keeping the
|
||||
* entire file in an internal buffer and then keeping a list of trigger points.
|
||||
* <code>AudioSample</code> 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.
|
||||
* <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.
|
||||
*/
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
BIN
java/libraries/minim/examples/TriggerASample/data/BD.mp3
Normal file
BIN
java/libraries/minim/examples/TriggerASample/data/BD.mp3
Normal file
Binary file not shown.
BIN
java/libraries/minim/examples/TriggerASample/data/SD.wav
Normal file
BIN
java/libraries/minim/examples/TriggerASample/data/SD.wav
Normal file
Binary file not shown.
88
java/libraries/minim/examples/delayExample/delayExample.pde
Normal file
88
java/libraries/minim/examples/delayExample/delayExample.pde
Normal file
@@ -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 );
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/* 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
|
||||
*/
|
||||
|
||||
// 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 );
|
||||
}
|
||||
BIN
java/libraries/minim/examples/loadFileIntoBuffer/data/SD.wav
Normal file
BIN
java/libraries/minim/examples/loadFileIntoBuffer/data/SD.wav
Normal file
Binary file not shown.
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
1
java/libraries/minim/library/export.txt
Normal file
1
java/libraries/minim/library/export.txt
Normal file
@@ -0,0 +1 @@
|
||||
name = Minim Audio
|
||||
165
java/libraries/minim/license.txt
Normal file
165
java/libraries/minim/license.txt
Normal file
@@ -0,0 +1,165 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
|
||||
0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
||||
1
java/libraries/minim/version.txt
Normal file
1
java/libraries/minim/version.txt
Normal file
@@ -0,0 +1 @@
|
||||
3.0 BETA
|
||||
Reference in New Issue
Block a user