Processing – sound

⊥ Źródło: Sound, R. Luke DuBois and Wilm Thoben


/**
 * Processing Sound Library, Example 1
 * 
 * Five sine waves are layered to construct a cluster of frequencies. 
 * This method is called additive synthesis. Use the mouse position 
 * inside the display window to detune the cluster.
 */

import processing.sound.*;

SinOsc[] sineWaves; // Array of sines
float[] sineFreq; // Array of frequencies
int numSines = 5; // Number of oscillators to use

void setup() {  
  size(640, 360);
  background(255);

  sineWaves = new SinOsc[numSines]; // Initialize the oscillators
  sineFreq = new float[numSines]; // Initialize array for Frequencies

  for (int i = 0; i < numSines; i++) {
    // Calculate the amplitude for each oscillator
    float sineVolume = (1.0 / numSines) / (i + 1);
    // Create the oscillators
    sineWaves[i] = new SinOsc(this);
    // Start Oscillators
    sineWaves[i].play();
    // Set the amplitudes for all oscillators
    sineWaves[i].amp(sineVolume);
  }
}

void draw() {
  //Map mouseY from 0 to 1
  float yoffset = map(mouseY, 0, height, 0, 1);
  //Map mouseY logarithmically to 150 - 1150 to create a base frequency range
  float frequency = pow(1000, yoffset) + 150;
  //Use mouseX mapped from -0.5 to 0.5 as a detune argument
  float detune = map(mouseX, 0, width, -0.5, 0.5);

  for (int i = 0; i < numSines; i++) { 
    sineFreq[i] = frequency * (i + 1 * detune);
    // Set the frequencies for all oscillators
    sineWaves[i].freq(sineFreq[i]);
  }
}
 

Ten skecz odgrywa losowo pięć różnych sampli, które wcześniej musimy załadować jako pliki o nazwach 1.aiff, 2.aiff…, 5.aiff. (Wystarczy upuścić nad oknem programu). Zamieniłem w szkicu aif na aiff, bo sample zwykle zapisywane są w ten sposób. Dodatkowo program wyświetla losowo różnobarwne prostokąty. Sample mają różne oktawy. Również losowo przydzielane jak i ilość współbrzmiących sampli. Efekt ciekawy.

 

/**
 * Processing Sound Library, Example 3
 * 
 * This example shows how to make a simple sampler and sequencer 
 * with the Sound library. In this sketch, five different samples are 
 * loaded and played back at different pitches, in this case five 
 * different octaves. The sequencer triggers an event every 200-1000 
 * milliseconds randomly. Each time a sound is played a colored 
 * rect with a random color is displayed.
 */

import processing.sound.*;

SoundFile[] files;

// Create an array of values which represent the octaves. 
// 1.0 is playback at normal speed, 0.5 is half and therefore 
// one octave down. 2.0 is double so one octave up.
float[] octave = { 
  0.25, 0.5, 1.0, 2.0, 4.0
};

// The playSound array is defining how many samples will be 
// played at each trigger event
int[] playSound = { 
  1, 1, 1, 1, 1
};

// The trigger is an integer number in milliseconds so we 
// can schedule new events in the draw loop
int trigger=0;

// This array holds the pixel positions of the rectangles 
// that are drawn each event
int[] posx = {
  0, 128, 256, 384, 512
};


void setup() {
  size(640, 360);
  background(255);

  // Create an array of 5 empty soundfiles
  files = new SoundFile[5];

  // Load 5 soundfiles from a folder in a for loop. By naming 
  // the files 1., 2., 3., [...], n.aif it is easy to iterate 
  // through the folder and load all files in one line of code.
  for (int i = 0; i < files.length; i++) { files[i] = new SoundFile(this, (i+1) + ".aiff"); } } void draw() { // If the determined trigger moment in time matches up with // the computer clock events get triggered. if (millis() > trigger) {

    // Redraw the background every time to erase old rects
    background(0);

    // By iterating through the playSound array we check for 
    // 1 or 0, 1 plays a sound and draws a rect, for 0 nothing happens

    for (int i = 0; i < files.length; i++) {      
      // Check which indexes are 1 and 0.
      if (playSound[i] == 1) {
        float rate;
        // Choose a random color and get set to noStroke()
        fill(int(random(0,255)),int(random(0,255)),int(random(0,255)));
        noStroke();
        // Draw the rect in the positions we defined earlier in posx
        rect(posx[i], 50, 128, 260);
        // Choose a random index of the octave array
        rate = octave[int(random(0, 5))];
        // Play the soundfile from the array with the respective 
        // rate and loop set to false
        files[i].play(rate, 1.0);
      }

      // Renew the indexes of playSound so that at the next event 
      // the order is different and randomized.
      playSound[i] = int(random(0, 4));
    }

    // Create a new triggertime in the future, with a random offset 
    // between 200 and 1000 milliseconds
    trigger = millis() + int(random(200, 1000));
  }
}

/**
 * Processing Sound Library, Example 4
 * 
 * Five soundfiles are mapped to the numbers on the keyboard. 
 * Numbers 1-5 are played back an octave lower and numbers
 * 6-0 an octave higher.
 */

import processing.sound.*;

AudioDevice device;
SoundFile[] file;

int red, green, blue;

void setup() {
  //size(1920, 1080);
  size(640, 320);
  background(255);

  // Create an AudioDevice with low buffer size 
  // and create an array containing 5 empty soundfiles
  device = new AudioDevice(this, 44100, 32);
  file = new SoundFile[5];

  // Load 5 soundfiles from a folder in a for loop. 
  for (int i = 0; i < file.length; i++) {
    file[i] = new SoundFile(this, (i+1) + ".aiff");
  }
}

void draw() {
  background(red, green, blue);
}

void keyPressed() {
  // Set a random background color each time you hit then number keys
  red=int(random(255));
  green=int(random(255));
  blue=int(random(255));

  // Assign a sound to each number on your keyboard. 1-5 play at
  // an octave below the original pitch of the file, 6-0 play at
  // an octave above.
  switch(key) {
  case '1':
    file[0].play(0.5, 1.0);
    break;
  case '2':
    file[1].play(0.5, 1.0);
    break;
  case '3':
    file[2].play(0.5, 1.0);
    break;
  case '4':
    file[3].play(0.5, 1.0);
    break;
  case '5':
    file[4].play(0.5, 1.0);
    break;
  case '6':
    file[0].play(2.0, 1.0);
    break;
  case '7':
    file[1].play(2.0, 1.0);
    break;
  case '8':
    file[2].play(2.0, 1.0);
    break;
  case '9':
    file[3].play(2.0, 1.0);
    break;
  case '0':
    file[4].play(2.0, 1.0);
    break;
  }
}