Week 9

2023 Tokyo University of the Arts Art media Center「Code and Design」 #

Slides (in Japanese) #

Slides(PDF) Slides(HTML)

Arduino Example #

tone_minimal.ino

DL
const int button_pin = 2;
const int sound_pin = 9;

void setup() {
  pinMode(button_pin, INPUT);
  //tone()を使うときは3,11以外
  pinMode(sound_pin, OUTPUT);
}

void loop() {
  if (digitalRead(2) == HIGH) {
    tone(sound_pin, 1000);
  } else {
    noTone(sound_pin);
  }
  delay(20);
}

tone_random_flip.ino

DL
const int button_pin = 2;
const int sound_pin = 9;

bool is_playing = false;
int button_prev= LOW;
float freq = 440;

float midiToFreq(int midi){
  return 440.*pow(2.,(midi-69.)/12.);
}

void setup() {
  pinMode(button_pin,INPUT);
  pinMode(sound_pin, OUTPUT);
}

void loop() {
  auto button_state = digitalRead(button_pin);

  if(button_prev == LOW && button_state==HIGH){
    is_playing = !is_playing;
    freq = midiToFreq(random(65,100));
  }
  if(is_playing){
    tone(sound_pin,freq);
  }else{
    noTone(sound_pin);
  }

  delay(20);
  button_prev = button_state;
}

mozzi_sine.ino

DL
#include <MozziGuts.h>
#include <Oscil.h>
#include <tables/sin2048_int8.h>

Oscil <SIN2048_NUM_CELLS, AUDIO_RATE> aSin(SIN2048_DATA);

void setup(){
  startMozzi();
  aSin.setFreq(440);
}

void updateControl(){

}

int updateAudio(){
  return aSin.next();
}

void loop(){
  audioHook();
}

mozzi_envelope.ino

DL
#include <MozziGuts.h>
#include <mozzi_midi.h>
#include <Oscil.h>

#include <ADSR.h>
#include <tables/sin8192_int8.h>

Oscil<8192, AUDIO_RATE> aOscil(SIN8192_DATA);  //元となる音色
ADSR<AUDIO_RATE, AUDIO_RATE> envelope;         //エンベロープをかけるためのクラス

unsigned int Dur, Atk, Dec, Sus, Rel;  //ADSRの長さを入れておく変数
int button_prev = LOW;

void setup() {
  startMozzi(1024);
  Atk = 10;
  Dec = 10;
  Sus = 50;
  Rel = 100;
  envelope.setTimes(Atk, Dec, Sus, Rel);
  envelope.setADLevels(255, 128);
}

void updateControl() {
  auto button_state = digitalRead(2);
  if (button_prev == LOW && button_state == HIGH) {
    auto f = mtof((int)random(65, 100));
    aOscil.setFreq(f);
    envelope.noteOn();
  }
  if (button_prev == HIGH && button_state == LOW) {
    envelope.noteOff();
  }
  button_prev = button_state;
}

int updateAudio() {
  envelope.update();
  return envelope.next() * aOscil.next() / 255;
}

void loop() {
  audioHook();
}

mozzi_reich.ino

DL
#include <MozziGuts.h>
#include <mozzi_midi.h>
#include <Oscil.h>
#include <EventDelay.h>
#include <ADSR.h>
#include <tables/sin8192_int8.h>

Oscil <8192, AUDIO_RATE> aOscil(SIN8192_DATA);//元となる音色
Oscil <8192, AUDIO_RATE> aOscil2(SIN8192_DATA);//元となる音色
ADSR <AUDIO_RATE, AUDIO_RATE> envelope_A;//エンベロープをかけるためのクラス
ADSR <AUDIO_RATE, AUDIO_RATE> envelope_B;//エンベロープをかけるためのクラス
unsigned int Dur, Atk, Dec, Sus, Rel;//ADSRの長さを入れておく変数

//piano phaseのパターン
unsigned int pattern[] = {64, 66, 71, 73, 74, 66, 64, 73, 71, 66, 74, 73};

//二つのタイマーを用意
int phase_A = 0;
int phase_B = 0;
EventDelay timer_B;
EventDelay timer_A;

void setup() {
  startMozzi(1024);
  Atk = 10;
  Dec = 10;
  Sus = 50;
  Rel = 100;
  envelope_A.setTimes(Atk, Dec, Sus, Rel);
  envelope_A.setADLevels(255, 128);
  envelope_B.setTimes(Atk, Dec, Sus, Rel);
  envelope_B.setADLevels(255, 128);

  timer_A.set(150);
  timer_B.set(151);
  timer_B.start();
  timer_A.start();
}

void updateControl()
{  
  if (timer_A.ready())
  {
    int note = pattern[phase_A];
    phase_A = (phase_A + 1) % 12;
    aOscil.setFreq(mtof(note));
    envelope_A.noteOn();
    timer_A.start();
  }

  if (timer_B.ready())
  {
    int note = pattern[phase_B];
    phase_B = (phase_B + 1) % 12;
    aOscil2.setFreq(mtof(note));
    envelope_B.noteOn();
    timer_B.start();
  }
}

int updateAudio()
{
  envelope_A.update();
  envelope_B.update();
  int A = (envelope_A.next() * aOscil.next()) >> 8;
  int B = (envelope_B.next() * aOscil2.next()) >> 8;

  return (A + B) / 2;
}

void loop() {
  audioHook();
}