Sample Playback

This example is for Processing (BETA) version 149+. If you have a previous version, use the examples included with your software. If you see any errors or have comments, please let us know.

Synthesizer 1 by R. Luke DuBois.

Sound is generated in real time by summing together harmonically related sine tones. Overall pitch and harmonic detuning is controlled by the mouse. Based on the Spooky Stream Save Ess example by Krister Olsson.

This example requires the Ess library. Download from this address and then follow the installation instructions: http://www.tree-axis.com/Ess/



import krister.Ess.*;

int numSines = 5; // Number of oscillators to use
AudioStream myStream; // Audio stream to write into
SineWave[] myWave; // Array of sines
FadeOut myFadeOut; // Amplitude ramp function
FadeIn myFadeIn; // Amplitude ramp function

void setup() 
{
  size(256, 200);
  Ess.start(this); // Start Ess
  myStream = new AudioStream(); // Create a new AudioStream
  myStream.smoothPan = true;
  myWave = new SineWave[numSines]; // Initialize the oscillators
  for (int i = 0; i < myWave.length; i++) {
    float sinVolume = (1.0 / myWave.length) / (i + 1);
    myWave[i] = new SineWave(0, sinVolume);
  }
  myFadeOut = new FadeOut(); // Create amplitude ramp
  myFadeIn = new FadeIn(); // Create amplitude ramp
  myStream.start(); // Start audio
}

void draw() 
{
  noStroke();
  fill(0, 20);
  rect(0, 0, width, height); // Draw the background
  float offset = millis() - myStream.bufferStartTime;
  int interp = int((offset / myStream.duration) * myStream.size);
  stroke(255);
  for (int i = 0; i < width; i++) {
    float y1 = mouseY;
    float y2 = y1;
    if (i + interp + 1 < myStream.buffer2.length) {
      y1 -= myStream.buffer2[i+interp] * height / 2;
      y2 -= myStream.buffer2[i+interp+1] * height / 2;
    }
    line(i, y1, i + 1, y2); // Draw the waves
  }
}

void audioStreamWrite(AudioStream s) 
{
  // Figure out frequencies and detune amounts from the mouse
  // using exponential scaling to approximate pitch perception
  float yoffset = (height - mouseY) / float(height);
  float frequency = pow(1000, yoffset) + 150;
  float detune = float(mouseX) / width - 0.5;
  myWave[0].generate(myStream); // Generate first sine, replace Stream
  myWave[0].phase += myStream.size; // Increment the phase
  myWave[0].phase %= myStream.sampleRate;
  for (int i = 1; i < myWave.length; i++) { // Add remaining sines into the Stream
    myWave[i].generate(myStream, Ess.ADD);
    myWave[i].phase = myWave[0].phase;
  }
  myFadeOut.filter(myStream); // Fade down the audio
  for (int i = 0; i < myWave.length; i++) { // Set the frequencies
    myWave[i].frequency = round(frequency * (i + 1 + i * detune));
    myWave[i].phase = 0;
  }
  myFadeIn.filter(myStream); // Fade up the audio
}