Lab 2: Sensors => Chuck

In this lab, you'll learn how to control the parameters of a synth running in ChucK using sensors connected to a microntroller (Teensy).

Download this lab's code here.

Electronic Basics

Sensors and Teensy Basics

void setup() {
  Serial.begin(9600); // initializing serial port
}

void loop() {
  int sensorValue = analogRead(A0); // retrieving sensor value on Analog pin 0
  Serial.println(sensorValue);
  delay(30); // wait for 30ms
}
#include <Bounce.h>
int midiValue = sensorValue*127/1024;
#include <Bounce.h>

void setup() {
}

void loop() {
  int sensorValue = analogRead(A0); // retrieving sensor value on Analog pin 0
  int midiCC = 0;
  int midiValue = sensorValue*127/1024; // value between 0-127
  int midiChannel = 0; // doesn't really matter
  usbMIDI.sendControlChange(midiCC,midiValue,midiChannel); // sending on CC 0
  delay(30); // wait for 30ms
}
chuck --probe
// synth algorithm
SawOsc saw => dac;

// synth default params
50 => saw.freq;

// number of the device to open (see: chuck --probe)
1 => int device;
// get command line
if( me.args() ) me.arg(0) => Std.atoi => device;

// the midi event
MidiIn min;
// the message for retrieving data
MidiMsg msg;

// open the device
if( !min.open( device ) ) me.exit();

// print out device that was opened
<<< "MIDI device:", min.num(), " -> ", min.name() >>>;

// infinite time-loop
while( true ){
  // wait on the event 'min'
  min => now;

  // get the message(s)
  while( min.recv(msg) ){
    if(msg.data2 == 0){ // 0 is the MIDI CC number
      // formating sawtooth freq
      msg.data3*10 + 50 => saw.freq;
    }
  }
}
// synth algorithm
SawOsc saw => dac;

// oscillator base frequency
50 => float baseFreq;

// the interpolator
vec3 i;
// the interpolation rate
2::ms => dur irate;
// set initial .value, .goal, .slew
i.set( baseFreq, baseFreq, .05 * (second/irate) );

// function to drive interpolator(s) concurrently
fun void interpolate( dur delta )
{
  while( true ){
    // interpolate oscillator frequency
    i.interp( delta ) => saw.freq;
    // advance time by rate
    delta => now;
  }
}

// spork interpolate function
spork ~ interpolate( irate );

// number of the device to open (see: chuck --probe)
2 => int device;
// get command line
if( me.args() ) me.arg(0) => Std.atoi => device;

// the midi event
MidiIn min;
// the message for retrieving data
MidiMsg msg;

// open the device
if( !min.open( device ) ) me.exit();

// print out device that was opened
<<< "MIDI device:", min.num(), " -> ", min.name() >>>;

// infinite time-loop
while( true ){
  // wait on the event 'min'
  min => now;

  // get the message(s)
  while( min.recv(msg) ){
    if(msg.data2 == 0){ // 0 is the MIDI CC number
      // formating sawtooth freq
      msg.data3*10 + baseFreq => i.update;
    }
  }
}

Exercise 1: Adding a Lowpass Filter and Controlling Its Cutoff Frequency

SawOsc saw => LPF lowpass => dac;
50 => saw.freq;
100 => lowpass.freq;
7 => lowpass.Q;

Exercise 2: Add a Toggle Switch to Your Instrument

SawOsc saw => LPF lowpass => Gain g => dac;
1 => g.gain; // on
0 => g.gain; // off

Optional Readings

Assignment (Due on Jan. 25, 2018)