• fullscreen
  • ChikIntr.pde
  • generativeComposition2.pde
  • instrument.pde
  • 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 );
      }
    }
    

    code

    tweaks (1)

    about this sketch

    This sketch is running as Java applet, exported from Processing.

    license

    advertisement

    Kryštof Pešek (Kof)
    Diana Lange
    23 Aug 2012
    Looks great. Really want to see / hear that in an exhibition. You know, big, empty, dark room, just a projector and the sound.
    Thanks Diana, I agree, dark room would be perfect for this one.. maybe at some higher resolution it would be nice.
    Kles4enko Andrey
    26 Aug 2012
    You are Devil!!!!! ;)))))
    bitcraft
    27 Aug 2012
    Cymatics Deluxe!
    This would indeed be awesome on a 360° Panorama Screen.
    )) Oh, good idea.. coincidentally, I have a medium size planetarium nearby.. it would be nice to screen it there..
    .. ok, it seems to be quite expensive screening, whatever
    You need to login/register to comment.