User Tools

Site Tools


cs276: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();
}
cs276/addsynth2.txt · Last modified: 2007/11/29 13:02 by scarl