Daily Creative Coding

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

MinimとcontrolP5でシーケンサー

f:id:aa_debdeb:20161026213156p:plain
/**
* sequncer by minim and controlP5
*
* @author aa_debdeb
* @date 2016/11/02
*/

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

Minim minim;
AudioOutput out;
ControlP5 cp5;
Knob[] pitches;
Toggle[] switches;

int bpm = 100;
int desiredFrameRate = 60; 
int count = 0;

void setup(){
  size(800, 400);
  frameRate(desiredFrameRate);
  minim = new Minim(this);
  out = minim.getLineOut();
  cp5 = new ControlP5(this);
  pitches = new Knob[16];
  float radius = 20;
  for(int i = 0; i < 16; i++){
    float x = (i < 8 ? i * 80: (i - 8) * 80) - radius + width / 2 - 80 * 3.5;
    float y = (i < 8 ? height / 3: height * 2.0 / 3) - radius; 
    pitches[i] = cp5.addKnob("pitch" + i)
                    .setRange(220, 880)
                    .setValue(440)
                    .setPosition(x, y)
                    .setRadius(radius)
                    .setDragDirection(Knob.VERTICAL);
  }
  switches = new Toggle[16];
  for(int i = 0; i < 16; i++){
    float x = (i < 8 ? i * 80: (i - 8) * 80) - 15 + width / 2 - 80 * 3.5;
    float y = (i < 8 ? height / 3: height * 2.0 / 3) - 10 - radius * 2;
    switches[i] = cp5.addToggle("switch" + i)
                    .setLabel("")
                    .setSize(30, 20)
                    .setValue(true)
                    .setPosition(x, y);
  }
}

void draw(){
  if(frameCount % int((desiredFrameRate / (bpm / 60.0)) / 4.0) == 0){
    if(switches[count].getBooleanValue()){
      out.playNote(0.0, 0.2, new MyInstrument(pitches[count].getValue())); 
    }
    count++;
    if(count == 16) count = 0;
  }
  println(int((desiredFrameRate / (bpm / 60.0)) / 4.0));
}

class MyInstrument implements Instrument {
  Oscil osc; 
  Line ampEnv;
  MyInstrument(float frequency){
    osc = new Oscil(frequency, 0.0, Waves.SINE);
    ampEnv = new Line();
    ampEnv.patch(osc.amplitude);
  }
  
  void noteOn(float duration){
    ampEnv.activate(duration, 0.5, 0);
    osc.patch(out);
  }
  
  void noteOff(){
    osc.unpatch(out);
  }
}