こちらは、7/7にfabcafeで開催された「電子楽器はつくれる! ワークショップ#1 」でのハンズオンの資料です。
- ブレッドボード
- Teensy 3.6
- イヤホン
- マイクロSDカード
- ボリューム
- スイッチ
- ケーブル
https://www.arduino.cc/en/Main/Software から、ご自身の使っているOS用のソフトをダウンロードして、 インストールしてください。
一度Arduinoを起動して、終了してください。
Teensyduinoのダウンロードページから、ご自身の使っているOS用のソフトをダウンロードして、 インストールしてください。
シリアルドライバーも必要なので、こちらもダウンロードして、実行してください。(実行すると、「不要です」というメッセージが出る場合もあります。)
Arduinoを起動します。 メニューから、ツール->ボード を選び、Teensyが追加できているかを確認します。 今回使うのは Teensy 3.6なので、それを選びます。
teensyで音を出すソフトを書くツール(webベース) Audio System Design Tool for Teensy Audio Library
左の箱の"output" にある dacs をドラッグして何もない白いところに置く(ちょっと右よりくらい) 左の箱の"synth" にある sin をドラッグして何もない白いところに置く(dacsより左)
sine1の右端の小さい■をドラッグして、dacs1の左端の上の■のところでマウスを離します。
sine1の右端の小さい■をドラッグして、dacs1の左端の下の■のところでマウスを離します。(もしうまくいかない場合、dacs1の方からやってみてください)
画面上部の赤い "Export"を押します。
この画面が表示されたら、コードをコピーします。コピーするには、ctrl+cボタンを押します(macの方はcmd+c)
Arduinoを起動します。
void setup()の中にコードを追加して、以下のようにします。
void setup() {
AudioMemory(15); // 最低限必要 TeensyでAudioが使うメモリーの量を決めます。
AudioNoInterrupts(); // 最低限必要 Audio全体の設定をするので、一度動作を止めます。
sine1.frequency(1000); // 最低限必要 作った sine の周波数を決めます。
sine1.amplitude(1.0); // 最低限必要 作った sineの音量を決めます。
AudioInterrupts(); // 最低限必要 設定が終わったので、Audioを動かします。
}
micoro USBケーブルでPCとteensyをつなぎます。
Arduinoの画面左上の、左から2番目のボタン、「マイコンボードに書き込む」を押します。
うまくいけば、ヘッドフォンから音がします。
ノブを取りだします。35 と書かれている所に差しこみます。
黒い線、赤い線、緑の線を図のように差します。
先ほどのプログラムの、 void loop() のところを、以下のように書きかえます。
void loop() {
const auto knob = analogRead(0) >> 2 << 2; // knobの値を読む。最小は0で、最大は1023になります。
const auto frequency = map(knob, 0, 1023, 0, 10000); // 0 ~~ 10000Hzの範囲にする
sine1.frequency(frequency); // sine1の周波数を設定する
}
Arduinoの画面左上の、左から2番目のボタン、「マイコンボードに書き込む」を押します。 うまくいけば、ノブを回した時に音の高さが変わります。
60 と書いてあるところの下にボタンを差します。 (ボタンには縦横の向きがあります。金属が自分に向かうような方向でとりつけます。) 黒い線、緑の線を図のように差します。
「ボタンを押す」をできるようにコードに追加していきます。 // 追加! というところが増えたところです。
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
#include <Bounce2.h> // 追加! ボタン用クラスを使いたい
// GUItool: begin automatically generated code
AudioSynthWaveformSine sine1; //xy=189,184
AudioOutputAnalogStereo dacs1; //xy=443,188
AudioConnection patchCord1(sine1, 0, dacs1, 0);
AudioConnection patchCord2(sine1, 0, dacs1, 1);
// GUItool: end automatically generated code
constexpr int SWITCH_1_PIN = 2; // 追加!2番ピンを使う
Bounce sw1 = Bounce(); // 追加! ボタン用クラスを作った
void setup() {
pinMode(SWITCH_1_PIN, INPUT_PULLUP); // 追加! ピンの設定 2番のピンを入力として使う
sw1.attach(SWITCH_1_PIN); // 追加! ボタン用クラスは2番ピンを使う
sw1.interval(10);// 追加! ボタンが押されたと判断するまでの時間間隔(10msec)
AudioMemory(15);
AudioNoInterrupts();
sine1.frequency(1000);
// sine1.amplitude(1.0); // 追加! ボタンで操作したいので、 コメントにする
AudioInterrupts();
}
void loop() {
sw1.update(); // 追加! スイッチの状態をスキャン
// 押した // 追加!
if (sw1.fell()) { // 追加! 押したときは・・・
sine1.amplitude(1.0); // 追加! 音量を最大にする = on
} // 追加!
// 離した // 追加!
if (sw1.rose()) { // 追加! 離したときは・・・
sine1.amplitude(0.0); // 追加! 音量を0にする = off
} // 追加!
const auto knob = analogRead(0) >> 2 << 2;
const auto frequency = map(knob, 0, 1023, 0, 10000); // 0 ~ 10000Hz
sine1.frequency(frequency);
}
参考 スイッチを増やすには
Audio System Design Tool for Teensy Audio Library を開きます。
sine1とdacs1の間の線をクリックしてオレンジにして、deleteボタンを押します(2本ともやる)。
sine1をちょっと左にずらします。
左の箱の"effect" にある reverb をドラッグして、sine1とdacs1の間に置きます。
sine1とreverb1、reverb1とdacs1を図のように■をドラッグしてつなぎます。
「1 とりあえず音を出す」でやったように、"Export"を押してコピー、Arduinoにペーストします。ボタン用に
#include <Bounce2.h>
を追加していますので、ここだけ追加します。
このようになります。
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
#include <Bounce2.h> // // スイッチ用ライブラリ
// GUItool: begin automatically generated code
AudioSynthWaveformSine sine1; //xy=111,185
AudioEffectReverb reverb1; //xy=375,188
AudioOutputAnalogStereo dacs1; //xy=645,199
AudioConnection patchCord1(sine1, reverb1);
AudioConnection patchCord2(reverb1, 0, dacs1, 0);
AudioConnection patchCord3(reverb1, 0, dacs1, 1);
// GUItool: end automatically generated code
リバーブの時間を、ボリュームでコントロールできるようにします。 「3.ボタンを押したら音が出る」で作ったコードに追加します。 // 追加! というところが増えたところです。
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
#include <Bounce2.h> // // スイッチ用ライブラリ
// GUItool: begin automatically generated code
AudioSynthWaveformSine sine1; //xy=111,185
AudioEffectReverb reverb1; //xy=375,188
AudioOutputAnalogStereo dacs1; //xy=645,199
AudioConnection patchCord1(sine1, reverb1);
AudioConnection patchCord2(reverb1, 0, dacs1, 0);
AudioConnection patchCord3(reverb1, 0, dacs1, 1);
// GUItool: end automatically generated code
constexpr int SWITCH_1_PIN = 2; //2番ピンを使う
Bounce sw1 = Bounce();
void setup() {
pinMode(SWITCH_1_PIN, INPUT_PULLUP);
sw1.attach(SWITCH_1_PIN);
sw1.interval(10);
AudioMemory(800);
AudioNoInterrupts();
sine1.frequency(0);
reverb1.reverbTime(0.0); // 追加! リバーブを初期設定しています。
AudioInterrupts();
}
void loop() {
sw1.update(); // スイッチの状態をスキャン
if (sw1.fell()) {
sine1.amplitude(0.3); //最大振幅を少し小くする
}
if (sw1.rose()) {
sine1.amplitude(0.001); // ちょっと残す(不自然じゃないように)
}
const auto knob = analogRead(0) >> 2 << 2;
const auto frequency = map(knob, 0, 1023, 0, 10000); // 0 ~~ 10000Hz
sine1.frequency(frequency);
// reverb // 追加!
const auto reverbTime = map(analogRead(1), 0, 1023, 0, 100); // 追加! リバーブの時間をボリュームから読んで・・・
reverb1.reverbTime(reverbTime); // 追加! それを反映させます。
}
手順は「リバーブをかけてみる」と同じですが複雑です。
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
#include <Bounce2.h> // // スイッチ用ライブラリ
// GUItool: begin automatically generated code
AudioSynthWaveformSine sine1; //xy=111,185
AudioEffectDelay delay1; //xy=304,372
AudioMixer4 delayFeedback_mixer; //xy=373,204
AudioAmplifier delayFeedback_amp; //xy=548,406
AudioOutputAnalogStereo dacs1; //xy=645,199
AudioConnection patchCord1(sine1, 0, delayFeedback_mixer, 0);
AudioConnection patchCord2(delay1, 0, delayFeedback_amp, 0);
AudioConnection patchCord3(delayFeedback_mixer, 0, dacs1, 0);
AudioConnection patchCord4(delayFeedback_mixer, 0, dacs1, 1);
AudioConnection patchCord5(delayFeedback_mixer, delay1);
AudioConnection patchCord6(delayFeedback_amp, 0, delayFeedback_mixer, 1);
// GUItool: end automatically generated code
constexpr int SWITCH_1_PIN = 2; //2番ピンを使う
Bounce sw1 = Bounce();
void setup() {
pinMode(SWITCH_1_PIN, INPUT_PULLUP);
sw1.attach(SWITCH_1_PIN);
sw1.interval(10);
AudioMemory(800);
AudioNoInterrupts();
sine1.frequency(1000);
delayFeedback_amp.gain(0.0); //
AudioInterrupts();
Serial.begin(115200);
}
void loop() {
sw1.update(); // スイッチの状態をスキャン
if (sw1.fell()) {
sine1.amplitude(0.4);
}
if (sw1.rose()) {
sine1.amplitude(0.0);
}
const auto knob = analogRead(0) >> 2 << 2;
const auto frequency = map(knob, 0, 1023, 0, 10000); // 0 ~~ 10000Hz
sine1.frequency(frequency);
// delay
const auto delayTime = map(analogRead(1), 0, 1023, 0, 750);
delay1.delay(0, delayTime);
const auto delayValue = analogRead(2) >> 2 << 2;
const auto mappedDelayValue = map(delayValue, 0, 1023, 0, 9000);
const auto floatDelayValue = mappedDelayValue / 10000.0;
delayFeedback_amp.gain(floatDelayValue);
}
https://www.pjrc.com/teensy/td_libs_AudioPlayMemory.html をコンパイルして使う(配布データに同梱) Arduinoのプログラムと同じフォルダに、.wavファイルと、wav2sketchを入れて ./wav2sketch と打てば、Arduinoで必要なファイルが自動的に作られます。
Audio System Design Tool for Teensy Audio Library を開きます。 下図のようにつなぎます。playMemは"play"にあります。
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
#include <Bounce2.h> // // スイッチ用ライブラリ
#include "AudioSampleSnare.h"
// GUItool: begin automatically generated code
AudioPlayMemory playMem1; //xy=194,454
AudioOutputAnalogStereo dacs1; //xy=445,454
AudioConnection patchCord1(playMem1, 0, dacs1, 0);
AudioConnection patchCord2(playMem1, 0, dacs1, 1);
// GUItool: end automatically generated code
constexpr int SWITCH_1_PIN = 2; //2番ピンを使う
Bounce sw1 = Bounce();
void setup() {
pinMode(SWITCH_1_PIN, INPUT_PULLUP);
sw1.attach(SWITCH_1_PIN);
sw1.interval(10);
AudioMemory(800);
AudioNoInterrupts();
AudioInterrupts();
Serial.begin(115200);
}
void loop() {
sw1.update(); // スイッチの状態をスキャン
if (sw1.fell()) {
playMem1.play(AudioSampleSnare);
}
}
マイクロSDカードをPCに差し込み、直下(フォルダではないところ)に、wavファイルを置く。 ファイル名は大文字で8文字まで、拡張子も大文字で .WAVにする。 例 MEOW.WAV
マイクロSDカードをTeensyに差して、以下のプログラムを書き込みます。
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
#include <Bounce2.h> // // スイッチ用ライブラリ
#include "play_sd_wav_modified.h" // AudioPlaySdWavがうまく動かなかったので改造したもの
// GUItool: begin automatically generated code
AudioPlaySdWav_modified playSdWav1; //xy=153,263
AudioOutputAnalogStereo dacs1; //xy=486,258
AudioConnection patchCord1(playSdWav1, 0, dacs1, 0);
AudioConnection patchCord2(playSdWav1, 1, dacs1, 1);
// GUItool: end automatically generated code
constexpr int SWITCH_1_PIN = 2; //2番ピンを使う
Bounce sw1 = Bounce();
void setup() {
pinMode(SWITCH_1_PIN, INPUT_PULLUP);
if (!SD.begin(BUILTIN_SDCARD)) {
return;
}
sw1.attach(SWITCH_1_PIN);
sw1.interval(10);
AudioMemory(100);
AudioNoInterrupts();
AudioInterrupts();
}
void loop() {
sw1.update(); // スイッチの状態をスキャン
if (sw1.fell()) {
playSdWav1.play("LONG.WAV"); // ボタンをおしいたら "LONG.WAV"を再生
}
}