User Tools

Site Tools


prensf2010:adsr_envelope
Ess Minim
[[cs276:addsynth2]]
DokuWiki
 
Trace: » minim_vs_ess » nsf_2010_prelude » todo » code_examples » addsynth2
 
/**
 * Additive Synthesizer 2
 *
 * Sound is generated at setup with a sine wave and a simple envelope generator
 * is added to each note. Insert your own array of notes/durations as 'rawSequence' and let it roll.
 *
 * Modified 10/28/2007 by spc 
 * Based on example Synthesizer 2 by R. Luke DuBois
 */
 
import krister.Ess.*;
import java.util.ArrayList;
 
AudioChannel myChannel; // Create channel
SineWave myWave,        // Create sine waveform
         myWaveHarmonic2,
         myWaveHarmonic3;
Envelope myEnvelope;    // Create envelope
int numNotes = 200;     // Number of notes
 
// Music notation - one possibility
int noteDuration = 300; // default note Duration in milliseconds
float[] rawSequence = { 293.6648, 0.75, 293.6648, 0.25, 329.62756, 1, 293.6648, 1, 391.995, 1,
                        369.99445, 2, 293.6648, 0.75, 293.6648, 0.25, 329.62756, 1, 293.6648, 1,
                        439.997, 1, 391.995, 2, 293.6648, 0.75, 293.6648, 0.25, 587.3294, 1, 493.8834, 1,
                        391.995, 1, 369.9945, 1, 329.62756, 3, 523.2516, 0.75, 523.2516, 0.25, 
                        493.8834, 1, 391.995, 1, 439.997, 1, 391.995, 2}; // Happy birthday
 
// A Better (in the sense of more structured) Possibility
// Read notes from file
class NoteEvent {
   float freq;   // in Hertz
   int duration;  // in milliseconds
   public NoteEvent(float pitch, int length, int metro) {  // metro of 60 means 1 quarter note per sec
 
   }
 
   public int eventTime(int currentTime) { // returns updated temporal value for this event
     return 0;
   }
}
 
class Score {
  // array of note events
  ArrayList score;
 
  public Score() { score = new ArrayList(); }
 
  // read notes from file
  public void readScore(String filename) { }
}
 
void setup() {
  size(100, 100);
  Ess.start(this); // Start Ess
 
  // Create a new AudioChannel
  myChannel = new AudioChannel(); 
  myChannel.initChannel(myChannel.frames(rawSequence.length * noteDuration));
 
  // Create sine wave and envelope
  myWave = new SineWave(480, 0.35); 
  myWaveHarmonic2 = new SineWave(840, 0.15);
  myWaveHarmonic3 = new SineWave(1680, 0.15);
  EPoint[] myEnv = new EPoint[3]; // Three-step breakpoint function
  myEnv[0] = new EPoint(0, 0); // Start at 0
  myEnv[1] = new EPoint(0.25, 1); // Attack
  myEnv[2] = new EPoint(2, 0); // Release
  myEnvelope = new Envelope(myEnv); // Bind Envelope to the breakpoint function
 
  // Store notes in AudioChannel
  int time = 0;
  for (int i = 0; i < rawSequence.length; i+=2) {
    myWave.frequency = rawSequence[i];            // Update waveform frequency + harmonics
    myWaveHarmonic2.frequency = rawSequence[i] * 2;
    myWaveHarmonic3.frequency = rawSequence[i] * 3;
    int begin = myChannel.frames(time);           // Starting position within Channel
    int e = int(noteDuration * rawSequence[i+1]); // duration of this note
    int end = myChannel.frames(e);                // Ending position within Channel
    println("("+begin+", "+end+")");
    myWave.generate(myChannel, begin, end);       // Render sine wave + harmonics
    myWaveHarmonic2.generate(myChannel, Ess.ADD, begin, end);
    myWaveHarmonic3.generate(myChannel, Ess.ADD, begin, end);
    myEnvelope.filter(myChannel, begin, end);     // Apply envelope
    time += noteDuration;                         // Increment the Channel output point
  }
 
  // Play the sound!
  myChannel.play(); 
}
 
void draw() { } // Empty draw() keeps the program running
 
void stop() {
  Ess.stop(); // When program stops, stop Ess too
  super.stop();
}
// Demostration of the use of minim's uGens
// to create an ADSR envelope.
import ddf.minim.signals.*;
import ddf.minim.*;
import ddf.minim.effects.*;
import ddf.minim.ugens.*;
 
AudioOutput out;
Minim minim;
 
float[] rawSequence = { 293.6648, 0.75, 293.6648, 0.25, 329.62756, 1, 293.6648, 1, 391.995, 1,
                        369.99445, 2, 293.6648, 0.75, 293.6648, 0.25, 329.62756, 1, 293.6648, 1,
                        439.997, 1, 391.995, 2, 293.6648, 0.75, 293.6648, 0.25, 587.3294, 1, 493.8834, 1,
                        391.995, 1, 369.9945, 1, 329.62756, 3, 523.2516, 0.75, 523.2516, 0.25, 
                        493.8834, 1, 391.995, 1, 439.997, 1, 391.995, 2};
void setup(){
  minim=new Minim(this);
  // Get the line out that will handle your notes. 
  out=minim.getLineOut(Minim.MONO);
  // Set the start time of each note
  float time=0;
  // and its duration
  float dur=0.4;
  // pause playback on the output line, this will 
  // "store" the notes to the playback buffer.
  out.pauseNotes();
  for(int i=0; i<rawSequence.length-1; i+=2){
 
    float freq=rawSequence[i];
    float freq2=freq*2;
    float freq3=freq*3;
 
    out.playNote(time,rawSequence[i+1],new Sine(freq,out));  
    out.playNote(time,rawSequence[i+1],new Sine(freq2,out));
    out.playNote(time,rawSequence[i+1],new Sine(freq3,out));
 
    // Make sure you increment your start time
    time+=rawSequence[i+1];
  }
  // play it all back.
  out.resumeNotes();
}
 
void draw(){}
 
void stop(){
  minim.stop();
  super.stop();
}
 
class Sine implements Instrument{
    Oscil osc;
    AudioOutput output;
    ADSR env;
 
    Sine(float freq, AudioOutput out){
      output=out;
      env=new ADSR();
      osc=new Oscil(freq,0.5,Waves.SINE);
      osc.patch(env);
    }
 
    void noteOn(float dur){
      env.setParameters(0.5,dur/5,dur/4,0.3,0.2,0.0,0.0);
      env.noteOn();
      env.patch(output);
    }
 
    void noteOff(){
      env.unpatchAfterRelease(output);
      env.unpatch(output);
    }
}
prensf2010/adsr_envelope.txt · Last modified: 2010/07/03 10:49 by nels_oscar