Basic Electroacoustics II: Music-Making Systems

Music G6602Y
TueThu 3:10-5:00pm
Spring 2008
Professor: Douglas Repetto [douglas at music columbia edu]
TA: Victor Adan [vga2102 at columbia edu]
Our Motto: "Why and how."
syllabus | lectures




February 12

Today we'll continue the generative art discussion and listening from last week.

Processing, continued...

Let's make some sound! We'll use the minim library, rather the Ess. It's more suited to the kinds of real time processes we'll look at today.

/*
upward walker

let's do a sinewave with a frequency that does a slow wiggling walk upwards
*/

import ddf.minim.*;
import ddf.minim.signals.*;

AudioOutput out;
SineWave sine;

float baseFreq = 100.0;
float wiggleFreq = 0.0;
int noteNum = 0;
int notesPerChange = 10;

void setup()
{
  size(500, 500);
  background(0);
  
  //we'll get 15 chances per second to change our frequency
  frameRate(15);
  
  // always start Minim before you do anything with it
  Minim.start(this);
  // get a line out from Minim, default sample rate is 44100, bit depth is 16
  out = Minim.getLineOut();
  // create a sine wave Oscillator, set to 440 Hz, at .8 amplitude, sample rate 44100 to match the line out
  sine = new SineWave(baseFreq, 0.8, 44100);
  // set the portamento speed on the oscillator to 200 milliseconds
  sine.portamento(200);
  // add the oscillator to the line out
  out.addSignal(sine);
}

void draw()
{
  //we'll bounce our freq around a bit just for fun
  wiggleFreq = random((baseFreq * 0.1));
  float newFreq = baseFreq + wiggleFreq;
  //update the freq of the sinewave
  sine.setFreq(newFreq);
  
  println("new freq: " + newFreq);

  //after notesPerChange number of notes we bump the freq up a bit
  if (noteNum % notesPerChange == 0)
  {
    //bump freq up by 10%
    baseFreq = baseFreq * 1.1;

    //wrap around if we get too ear-piercing
    if (baseFreq > 2500.0)
      baseFreq = 100.0;

    println("new base freq: " + baseFreq);
  }

  //just for fun draw a graph of our wiggling freq
  //we do % width so that we wrap around right to left when 
  //we hit the edge of the screen.
  int x = noteNum % width;
  //same thing here, wrap top to bottom 
  int y = int(newFreq) % height;
  //erase just the current column of pixels
  stroke(0);
  line(x, 0, x, height);
  //set the greyscale based on the wiggle freq
  int greyScale = int((wiggleFreq) % 220) + 35;
  stroke(greyScale);
  //draw the line
  line(x, height, x, height - y);

  //we need to keep track of how many notes we've played
  noteNum++;
}

void mousePressed() 
{
  stop();
  exit();
}

void stop()
{
  out.close();
  Minim.stop();
  super.stop();
}


++++++++++++++

/*
  minimal looping
  two loops going at different speeds, in STEREO!
*/

import ddf.minim.*;
import ddf.minim.signals.*;

//doing stereo this time!
AudioOutput outL;
AudioOutput outR;

SquareWave squareL;
SquareWave squareR;

float baseFreqL = 100.0;
float botFreqL = 100.0;
float topFreqL = 500.0;
float baseFreqR = 110.0;
float botFreqR = 100.0;
float topFreqR = 500;

int loopRateL = 2;
int loopRateR = 3;

int colorL = 0;
int colorR = 255;

//this will keep our pulse time constant
//even if we change the loop rates
int framesPerSecond = loopRateL * 2;

int noteNum = 0;

void setup()
{
  size(200, 200);
  background(0);
  
  //we'll get  chances per second to change our frequency
  frameRate(framesPerSecond);
  
  // always start Minim before you do anything with it
  Minim.start(this);
  // get a line out from Minim, default sample rate is 44100, bit depth is 16
  outL = Minim.getLineOut();
  outR = Minim.getLineOut();

  squareL = new SquareWave(baseFreqL, 0.5, 44100);
  squareL.setPan(0.2);
  squareR = new SquareWave(baseFreqR, 0.5, 41000);
  squareR.setPan(0.8);
  
  // set the portamento speed on the oscillator to 200 milliseconds
  squareL.portamento(100);
  // set the portamento speed on the oscillator to 200 milliseconds
  squareR.portamento(100);
  
  // add the oscillator to the line out
  outL.addSignal(squareL);
  outR.addSignal(squareR);
}

void draw()
{
  if (noteNum % loopRateL == 0)
  {
    baseFreqL *= 1.2;
    if (baseFreqL > topFreqL)
      baseFreqL -= (topFreqL - botFreqL);
    squareL.setFreq(baseFreqL);
    stroke(colorL);
    fill(colorL);
    rect(10,10, 50, 50);
    if (colorL == 255)
      colorL = 0;
    else
      colorL = 255;
  }
  
  if (noteNum % loopRateR == 0)
  {
    baseFreqR *= 1.2;
    if (baseFreqR > topFreqR)
      baseFreqR -= (topFreqR - botFreqR);
    squareR.setFreq(baseFreqR);
    
    stroke(colorR);
    fill(colorR);
    rect(60,10, 50, 50);
    if (colorR == 255)
      colorR = 0;
    else
      colorR = 255;
  }
  
  noteNum++;
}

void mousePressed() 
{
  stop();
  exit();
}

void stop()
{
  outL.close();
  outR.close();
  Minim.stop();
  super.stop();
}


++++++++++++++++

/*
  an arbitrary number of loops!
 */

import ddf.minim.*;
import ddf.minim.signals.*;

//doing stereo this time!
AudioOutput outL;
AudioOutput outR;

int numWaves = 5;

//allocate our storage space for all arrays
SquareWave[] squares = new SquareWave[numWaves];
float[] baseFreqs = new float[numWaves];
float[] topFreqs = new float[numWaves];
float[] botFreqs = new float[numWaves];
int[] loopRates = new int[numWaves];
int[] colors = new int[numWaves];

float globalBaseFreq = 100.0;
float globalTopFreq = 700.0;
float globalBotFreq = 100.0;

//we'll set this later!
int framesPerSecond = 0;

boolean doWiggle = false;

int noteNum = 0;

void setup()
{
  size(60 * numWaves, 200);
  background(0);

  // always start Minim before you do anything with it
  Minim.start(this);
  // get a line out from Minim, default sample rate is 44100, bit depth is 16
  outL = Minim.getLineOut();
  outR = Minim.getLineOut();


  for (int i = 0; i < numWaves; i++)
  {
    baseFreqs[i] = globalBaseFreq;
    topFreqs[i] = globalTopFreq;
    botFreqs[i] = globalBotFreq;
    squares[i] = new SquareWave(baseFreqs[i], 0.5, 44100);

    float pan = i * (1.0/numWaves);
    pan += 1.0 / (numWaves * 2);
    println("i: " + i + " pan: " + pan);

    squares[i].setPan(pan);
    squares[i].portamento(100);

    //2 will be our lowest loop rate
    loopRates[i] = i + 2;
    //they'll all start at black
    colors[i] = 0;

    if (i % 2 == 0)
      outL.addSignal(squares[i]);
    else
      outR.addSignal(squares[i]);
  }
  
  framesPerSecond = loopRates[0] * 2;
  frameRate(framesPerSecond);
  
}

void draw()
{
  for (int i = 0; i < numWaves; i++)
  {
    if (noteNum % loopRates[i] == 0)
    {
      baseFreqs[i] *= 1.2;
      if (baseFreqs[i] > topFreqs[i])
        baseFreqs[i] -= (topFreqs[i] - botFreqs[i]);
        
      //add a little frequency wiggle in there!
      float wiggle = 0.0;
      
      if (doWiggle)
      {
        wiggle = random(baseFreqs[i] * 0.2);
        println("wiggle for " + i + ": " + wiggle);
      }
      
      squares[i].setFreq(baseFreqs[i] + wiggle);
      stroke(colors[i]);
      fill(colors[i]);
      
      int x = (i * 50) + 10;
      
      rect(x,10, 50, 50);
      if (colors[i] == 255)
        colors[i] = 0;
      else
        colors[i] = 255;
    }
  }

  noteNum++;
}

void mousePressed() 
{
  //turn frequency wiggle on and off with a simple click! magic!
  doWiggle = !doWiggle;
}

void stop()
{
  outL.close();
  outR.close();
  Minim.stop();
  super.stop();
}

Your assignment: make a sound piece with a variable number of voices. At least a couple parameters should change under algorithmic control. Add in some mouse control as a bonus.