Daily Creative Coding

元「30 min. Processing」。毎日、Creative Codingします。

鳴らす位置を自由に設定できるシーケンサー

f:id:aa_debdeb:20161130211921j:plain
/**
* non-step sequncer
*
* @author aa_debdeb
* @date 2016/12/05
*/

import ddf.minim.spi.*;
import ddf.minim.signals.*;
import ddf.minim.*;
import ddf.minim.analysis.*;
import ddf.minim.ugens.*;
import ddf.minim.effects.*;

Minim minim;
AudioOutput out;
float beat;
float beatSpeed = 0.005;
ArrayList<Oscillator> oscillators;

void setup(){
  size(640, 480);
  minim = new Minim(this);
  out = minim.getLineOut();
  beat = 0.0;
  oscillators = new ArrayList<Oscillator>();
}

void draw(){
  background(0);
  stroke(255);
  strokeWeight(2);
  for(int i = 0; i < 4; i++){
    line(width / 4.0 * i, 0, width / 4.0 * i, height);
  }
  stroke(200, 0, 0);
  strokeWeight(2);
  line(beat * width, 0, beat * width, height);
  for(Oscillator oscillator: oscillators){
    oscillator.display();
  }
  
  for(Oscillator oscillator: oscillators){
    if(beat * width <= oscillator.loc.x && (beat + beatSpeed) * width > oscillator.loc.x){
      out.playNote(0.0, 0.5, oscillator.makeNote());
    }
  }
  
  beat += beatSpeed;
  if(beat >= 1.0){
    beat -= 1.0;
  }
}

void mousePressed(){
  PVector loc = new PVector(mouseX, mouseY);
  oscillators.add(new Oscillator(loc));
}

class Oscillator {

  PVector loc;
  
  Oscillator(PVector _loc){
    loc = _loc;
  }
  
  Instrument makeNote(){
    float freq = map(loc.y, 0, height, 2000, 0);
    return(new Note(freq));  
  }
  
  void display(){
    fill(100, 100, 255, 50);
    stroke(255, 150);
    strokeWeight(2);
    ellipse(loc.x, loc.y, 75, 75);
  }
}

class Note implements Instrument {

  Oscil oscil;
  Line line;
  
  Note(float freq){
    oscil = new Oscil(freq, 1.0, Waves.SINE);
    line = new Line(0.5);
    line.patch(oscil.amplitude);
  }
  
  void noteOn(float duration){
    line.activate();
    oscil.patch(out);
  }
  
  void noteOff(){
    oscil.unpatch(out); 
  }
  
}