リコーダー型のMIDIコントローラがついに出来上がってきた。
とりあえず圧電スピーカは洗濯バサミで上にくっつけている。
接続はピンソケット2つで行っているので、
つばで汚れたら新しいものに付け替えることができるようにしている。
もう普通に演奏できる。
まだファームウェア書き換えでは試してないので
音を鳴らす方法は下記のまま。
http://program.alphabrend.com/?p=150
ただちょっと遅延があって演奏しづらいので、
可能な箇所があればプログラムや回路の見直しと、
ASIOドライバというものを導入してみたいと考えている。
最終的にはアクリルを筒状っぽくしてそれっぽい入れものに入れてみたい。
とりあえずは段ボールでケースでもつくろかな…。
arduino
|c|
const int BUTTON_MIN = 2;
const int BUTTON_MAX = 12;
const int BREATH = 0;
const int BASE_PITCH = 53;
const int BREATH_CUT = 670;
const int MIN_BREATH = 300;
const int MAX_DIFF = 3;
const int BREATH_DELAY = 70000;
int playing = -1;
unsigned long lastHigh = micros();
unsigned long lastVelo = micros();
byte currentVelocity = 0;
char* notes[] = {
"01111110011",
"01111110110",
"01111110010",
"01111111000",
"01111110000",
"01111100000",
"01111010010",
"01111000000",
"01110111000",
"01110000000",
"01101100000",
"01100000000",
"01010000000",
"00110000000",
"00010000000",
"00111110010",
"10111110000",
"10111100000",
"10111010000",
"10111000000",
"10110100000",
"10110000000",
"10110010010",
"10110110000",
"10100110000",
"10101100011",
"10101100010",
};
int noteCount = sizeof(notes) / sizeof(notes[0]);
void setup() {
for (int i = BUTTON_MIN; i <= BUTTON_MAX; i++) {
pinMode(i, INPUT_PULLUP);
}
MIDI.begin();
}
void loop() {
char currentValue[] = "00000000000";
int exist = 0;
for (int i = BUTTON_MIN; i <= BUTTON_MAX; i++) {
if (digitalRead(i) == LOW) {
currentValue[i - BUTTON_MIN] = '1';
exist = 1;
} else {
currentValue[i - BUTTON_MIN] = '0';
}
}
if (exist == 1) {
short breath = analogRead(BREATH);
breath = abs(breath - BREATH_CUT);
if (breath > MIN_BREATH) {
for (int i = 0; i < noteCount; i++) {
if (strcmp(currentValue, notes[i]) == 0) {
breath = 127;
breath = map(breath, MIN_BREATH, 1023 - BREATH_CUT, 64, 127);
if (i != playing) {
if (playing > -1) {
MIDI.sendNoteOff(BASE_PITCH + playing, 0, 1);
}
playing = i;
MIDI.sendNoteOn(BASE_PITCH + playing, breath, 1);
currentVelocity = breath;
} else {
if (micros() - lastVelo > BREATH_DELAY) {
if (breath > currentVelocity) {
short plus = min(MAX_DIFF, breath - currentVelocity);
if (plus + (short)currentVelocity > 127) {
plus = 127 - currentVelocity;
}
currentVelocity += plus;
MIDI.sendControlChange(7, currentVelocity, 1);
} else if (breath < currentVelocity) {
short minus = min(MAX_DIFF, currentVelocity - breath);
if (minus > currentVelocity) {
minus = currentVelocity;
}
currentVelocity -= minus;
MIDI.sendControlChange(7, currentVelocity, 1);
}
}
}
lastVelo = micros();
break;
}
}
lastHigh = micros();
} else {
if (micros() - lastHigh > BREATH_DELAY) {
noteOff();
}
}
} else {
noteOff();
}
}
void noteOff() {
if (playing > -1) {
MIDI.sendNoteOff(BASE_PITCH + playing, 0, 1);
playing = -1;
}
}
||
processing
|c|
import processing.serial.*;
import themidibus.*; //Import the library
MidiBus myBus; // The MidiBus
Serial port;
int[] val = new int[3];
int valno = 0;
int lastInput = 0;
void setup() {
size(400, 400);
background(0);
MidiBus.list(); // List all available Midi devices on STDOUT. This will show each device's index and name.
myBus = new MidiBus(this, -1, "loopMIDI Port"); // Create a new MidiBus with no input device and the default Java Sound Synthesizer as the output device.
String portName = Serial.list()[0];
port=new Serial(this, portName, 31250);
}
void draw() {
while (port.available() > 0) {
int inByte = port.read();
println(inByte);
if (valno == 0) {
if (inByte >= 128) {
val[0] = inByte;
valno++;
} else if (lastInput > 0) {
val[0] = lastInput;
val[1] = inByte;
valno += 2;
}
} else {
val[valno++] = inByte;
if (valno == 3) {
valno = 0;
if (val[0] == 128) {
println(val);
myBus.sendNoteOff(0, val[1], val[2]);
lastInput = 0;
} else if (val[0] == 144) {
// println(val);
setVolume(val[2]);
myBus.sendNoteOn(0, val[1], /val[2]/127);
lastInput = val[0];
} else if (val[0] == 176) {
setVolume(val[2]);
// println(val);
lastInput = val[0];
}
}
}
}
}
void setVolume(int velocity) {
if (velocity < 64) {
velocity = 64;
}
myBus.sendControllerChange(0, 7, velocity);
}
||
とりあえずボリュームはマックス固定にしている。
変動を試したい場合はNO_VOLUME_CHANGEをコメントアウト。
多少安定はしてきたが、あんまりいいかんじではない。
ビブラートも上手くは再現できないので。
このあとのASIO対応やファームウェア書き換えでまた
上手く動かなくなってつまづきそうだがとりあえず一段落。
Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。
また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!
こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?
コメント