Looks great. Really want to see / hear that in an exhibition. You know, big, empty, dark room, just a projector and the sound.
class ChikInstrument implements Instrument
{
// to make a chik sound we'll just filter some noise
Noise noize;
BandPass bpFilt;
AudioOutput out;
ADSR adsr;
ChikInstrument( AudioOutput output )
{
out = output;
// amplitude and noise tint
noize = new Noise( 1.f, Noise.Tint.WHITE);
adsr = new ADSR( 0.1, 0.4, 0.1, 0.1, 0.1 );
// make a bandpass with center frequency of 400Hz, bandwidth of 20Hz and sample rate of 44100.
bpFilt = new BandPass( 1000.0, random(200,600), 44100.f );
// patch the noise through the filter
noize.patch( bpFilt );
noize.patch( adsr );
}
// called by the note manager when this instrument should play
void noteOn(float dur)
{
adsr.noteOn();
bpFilt.patch(out);
}
// called by the note manager when this instrument should stop playing
void noteOff()
{
adsr.noteOff();
bpFilt.unpatch(out);
}
}
// this instrument uses a WaveShaper to shape an Oscil
// over time.
class WaveShaperInstrument implements Instrument
{
// our tone
Oscil sineOsc;
// what we'll shape our oscil with
WaveShaper shaper;
// a line to change the amount of shaping over time
Line shaperAmountLine;
// and a reciprocal to change the output amplitude over time
Reciprocal reciprocal;
AudioOutput out;
WaveShaperInstrument(float frequency, float amplitude, AudioOutput output)
{
out = output;
sineOsc = new Oscil(frequency, amplitude, Waves.SAW);
// We've created three different waves to shape the sine with. Just uncomment
// one of the "shaper =" lines to hear the different waves.
// The first is a modified saw wave. We made this while we were experimenting
// with the WaveShaper and liked it, so it remains.
Wavetable shapeA = new Wavetable( Waves.TRIANGLE );
shapeA.set(0, -1.0);
shapeA.set(shapeA.size()-1, 1.0);
// The second argument in WaveShaper
// is the amount of shaping to be applied, which in our case doesn't
// really matter because we are going to drive that with a Line.
shaper = new WaveShaper(amplitude, 5, shapeA);
// If we want to shape the sine with a saw wave...
//shaper = new WaveShaper( amplitude, 5, Waves.SAW );
// We can choose to wrap around the ends of the waveshaping map for interesting
// effects, and one does this by setting the fourth argument to true.
//shaper = new WaveShaper( amplitude, 5, Waves.SAW, true );
shaperAmountLine = new Line(5.f, 1.f, 25.f);
reciprocal = new Reciprocal();
// patch the line into the mapAmplitude of the WaveShaper
shaperAmountLine.patch( shaper.mapAmplitude );
// Patch the reciprocal of the line into the outAmplitude.
// Since the line goes from 1 to 25, the reciprocal goes from 1/1 to 1/25.
// This creates a pretty good approximation of a drum envelope.
shaperAmountLine.patch( reciprocal ).patch( shaper.outAmplitude );
sineOsc.patch( shaper );
}
void noteOn(float dur)
{
// set our line time based on duration
shaperAmountLine.setLineTime( dur );
shaperAmountLine.activate();
shaper.patch( out );
}
void noteOff()
{
shaper.unpatch( out );
}
}
import ddf.minim.*;
import ddf.minim.ugens.*;
import ddf.minim.effects.*; // for BandPass
////////////////////////////////////
String notesLow[], notesHigh[], notesMid[];
int pitchLow = 1;
int pitchMid = 3;
int pitchHigh = 6;
float[][] vals;
int nn = 10;
String notes[]= {
"A", "C", "E", "G"
};
int period = 200;
////////////////////////////////////
boolean neg = false;
float amp = 0.2;
int num = 1;
float dur = 10;
Minim minim;
AudioOutput out;
Waveform disWave;
int cnt = 0;
int melody = 0;
////////////////////////////////////
void setup()
{
size( 600, 320, P2D );
textFont(loadFont("53Maya-8.vlw"));
textMode(SCREEN);
makeScale();
// initialize the minim and out objects
minim = new Minim( this );
out = minim.getLineOut( Minim.STEREO, 1024 );
vals = new float[nn][out.bufferSize()];
colorMode(HSB);
background(0);
addNotesNow();
}
////////////////////////////////////
void makeScale() {
if (random(50)<40) {
disWave = Waves.SINE;
}
else {
disWave = Waves.TRIANGLE;
}
notesLow = new String[notes.length];
notesMid = new String[notes.length];
notesHigh = new String[notes.length];
for (int i = 0 ; i < notes.length;i++) {
notesLow[i] = notes[i]+""+pitchLow;
notesMid[i] = notes[i]+""+pitchMid;
notesHigh[i] = notes[i]+""+pitchHigh;
}
}
////////////////////////////////////
void draw() {
noStroke();
fill(noise(frameCount)*30+40, 25, neg?250:25, random(90, 120));
rect(0, 0, width, height);
if (frameCount%period==0) {
addNotesNow();
}
pushMatrix();
translate(width/2, height/2);
rotate(frameCount/3.0);
////////////////////////////////////
// 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
int cnt = 0;
for (int j = 2 ; j < nn;j++) {
if (j==2) {
resetMatrix();
translate(map(i, 0, out.bufferSize(), 0, width), height/2);
//rotate(radians(frameCount*8.0));
}
for (int z = 200 ; z < 10000;z+=2000) {
vals[j][i] += ((out.left.get(i)*noise((i+j+frameCount)/30.0)*z)-vals[j][i])/(float)(j+800.1+2.0);
translate(j/30.0, vals[j][i]);
rotate(i/(out.bufferSize()+0.0));
stroke(noise(0, (frameCount+i+j+z)/200.0)*255, 35, neg?24:250, 15);
// stroke( 255, 15);
point(0, 0);
}
}
}
popMatrix();
////////////////////////////////////
pushStyle();
resetMatrix();
strokeWeight(10);
stroke(0);
noFill();
rect(0, 0, width, height);
popStyle();
fill(neg?0:255, 50);
textAlign(RIGHT);
text("Random Generative Composition by Kof "+nf(month(), 2)+"/"+nf(day(), 2)+"/"+year(), width-10, height-8);
}
void addNotesNow() {
pitchLow = (int)random(1, 3);
pitchMid = (int)random(3, 6);
pitchHigh = (int)random(6, 8);
makeScale();
for (int i = 0 ; i < num ; i++ ) {
out.playNote( i*(dur/(num+0.0))+random(-1.0, 1.0), (dur/(num+0.0)+random(0.0, 1.0)), new ToneInstrument( notesLow[(int)random(notesLow.length)]+" ", amp, disWave, out ) );
out.playNote( i*(dur/(num+0.0))+random(-1.0, 1.0), (dur/(num+0.0)+random(0.0, 1.0)), new ToneInstrument( notesMid[(int)random(notesHigh.length)]+" ", amp, disWave, out ) );
out.playNote( i*(dur/(num+0.0))+random(-1.0, 1.0), (dur/(num+0.0)+random(0.0, 1.0)), new ToneInstrument( notesHigh[(int)random(notesHigh.length)]+" ", amp, disWave, out ) );
// out.playNote( (dur/(num+0.0))*2, 0.5, new ChikInstrument( out ) );
}
out.playNote( 0, 0.5, new ChikInstrument( out ) );
cnt++;
neg=!neg;
rectMode(CENTER);
noStroke();
fill(neg?0:255);
pushMatrix();
translate(random(width),random(height));
rotate(random(-PI,PI));
// rect(0,0,80,80);
popMatrix();
rectMode(CORNER);
if (cnt%2==0)
melody++;
switch(melody%4) {
case 0:
out.playNote( 1.f, 4.4f, new WaveShaperInstrument( Frequency.ofPitch("C1").asHz(), 0.1, out ) );
out.playNote( 1.2f, 1.2f, new WaveShaperInstrument( Frequency.ofPitch("C6").asHz(), 0.1, out ) );
break;
case 1:
out.playNote( 1.f, 4.4f, new WaveShaperInstrument( Frequency.ofPitch("E1").asHz(), 0.1, out ) );
out.playNote( 1.2f, 1.2f, new WaveShaperInstrument( Frequency.ofPitch("E7").asHz(), 0.1, out ) );
break;
case 2:
out.playNote( 1.f, 4.4f, new WaveShaperInstrument( Frequency.ofPitch("A2").asHz(), 0.1, out ) );
out.playNote( 1.2f, 1.2f, new WaveShaperInstrument( Frequency.ofPitch("A5").asHz(), 0.1, out ) );
break;
case 3:
out.playNote( 1.f, 4.4f, new WaveShaperInstrument( Frequency.ofPitch("G1").asHz(), 0.1, out ) );
out.playNote( 1.2f, 1.2f, new WaveShaperInstrument( Frequency.ofPitch("G3").asHz(), 0.1, out ) );
break;
}
//out.playNote( 5.f, 1.0f, new WaveShaperInstrument( Frequency.ofPitch(notesHigh[(int)random(notesLow.length)]).asHz(), 0.2, out ) );
}
// stop is run when the user presses stop
void stop()
{
// close the AudioOutput
out.close();
// stop the minim object
minim.stop();
// stop the processing object
super.stop();
}
// Every instrument must implement the Instrument interface so
// playNote() can call the instrument's methods.
class ToneInstrument implements Instrument
{
// create all variables that must be used throughout the class
Oscil toneOsc;
ADSR adsr;
AudioOutput out;
Delay myDelay1;
Damp damp;
// BitCrush bitCrush;
Line crushLine;
// constructors for this intsrument
ToneInstrument( String note, float amplitude, Waveform wave, AudioOutput output )
{
// equate class variables to constructor variables as necessary
out = output;
//bitCrush = new BitCrush(random(0,10.0));
// crushLine = new Line(0.1, random(0.1,50.0), random(0.01,40));
// crushLine.patch(bitCrush.bitRes);
// make any calculations necessary for the new UGen objects
// this turns a note name into a frequency
float frequency = Frequency.ofPitch( note ).asHz();
// create new instances of any UGen objects as necessary
toneOsc = new Oscil( frequency, amplitude, wave );
adsr = new ADSR( 1.0, 0.9, 0.01, 1.0, 0.1 );
damp = new Damp( random(0.0001,10.0), random(0.001,20.0) );
myDelay1 = new Delay( random(0.0,100.0), random(0.0,100.0), true, false );
Summer sum = new Summer();
toneOsc.patch( sum ).patch(damp).patch(myDelay1);
// patch everything together up to the final output
toneOsc.patch( adsr );
}
// every instrument must have a noteOn( float ) method
void noteOn( float dur )
{
// turn on the adsr
adsr.noteOn();
// patch the adsr into the output
//adsr.patch(bitCrush);
// set the damp time from the duration given to the note
damp.setDampTimeFromDuration( dur );
// activate the damp
damp.activate();
adsr.patch( out );
}
void noteOff()
{
// turn off the note in the adsr
adsr.noteOff();
// adsr.unpatchAfterRelease(bitCrush);
// but don't unpatch until the release is through
damp.unpatchAfterDamp( out );
adsr.unpatchAfterRelease( out );
}
}
Kryštof Pešek (Kof)
Kryštof Pešek (Kof)