動機
- ブラウザで動く64パッドのレイアウト図示用MIDIモニタを作った
- 主に受け取ったコード演奏を図示する
- 一つのMIDIノート(音高)に複数のパッドが対応するので、実際に何を押しているのか分かりにくい
- 押した位置を図時するためのモードも作ったが不便
- ブラウザとDAWを切り替えたりデスクトップ録画するのが面倒
- 音を出せるようにしたいがMIDIのルーティングや遅延を考えるとブラウザではやりたくない
- DAW内で動くものを作りたい
- ReaperのJSFX(EEL2)、
Effects/midi/MIDI Transpose Notes
あたりを見てたらできそうな気がしてきた - ReaperのJSFXをVSTとして別のDAWで動かすソフトが存在する(YSFX)
- 他のDAWでも動かせそう
- ReaperのJSFX(EEL2)、
作ったもの
- 64 Pad Software Note Mode JSFX
- Ableton LiveのDrumrack相当のMIDI入力を、押した位置の図示しながら音高を変換する
- 自分で使いたいレイアウトとP4thに対応
- Mm3rdRotatedLayout
- P4thLayout(完全四度クロマチック、4ths String Layout)
- コードは長くなったので記事末尾参照
動かしてみた
- 注意:素人が作ったプラグインなので何かあっても責任は負えません
動作例:Reaper
動作例:Ableton Live + ysfx-s instrument
動作例:Dorico + Modalics Plugin Buddy + ysfx-s instrument
- Doricoは譜面ソフトなのでMIDIのルーティングはほとんどできない
- Modalics Plugin Buddy(VSTをロードできるVST)でysfx-sをMIDI FXスロットに入れ、Instrumentスロットに演奏用のVSTを入れて使用している
動作例:Bitwig 8-Track + ysfx-s instrument
この記事のJSFXのプラグインを動かすには
-
Reaper
-
Reaper以外
-
音高変換後のMIDI Noteの記録は各DAWのMIDI Burn機能か、BirdBird MIDICapを使うと便利
余談:BirdBird MIDICapはとてもおすすめ(レトロスペクティブMIDIキャプチャ)
- https://www.birdsthings.com/midi-cap
- レトロスペクティブMIDIキャプチャ機能を提供するVSTi/CLAPプラグイン
- 直近60秒のMIDI入力から好きな部分を切り出して保存できる
- 好きなDAWの好きな場所に置けるのでものすごくお勧め
- アルペジエーター等MIDI-FXの出力も直感的にキャプチャできる
- 操作方法
- Lite版(無償)と有償版の違いは記録できる時間の長さだけ
作成したJSFXのコード
64PadSwNoteMode.eel2
desc:64Pad Software Note Mode
//tags: MIDI processing
in_pin:none
out_pin:none
options:gfx_hz=60
slider1:layout=0<0, 5, 1{Mm3rdRotated,P5thRotated,P5th,P4th,MonitorOnly}>Layout
slider2:octave=0<-3, 3, 1>Octave
slider3:transpose=0<-12, 12, 1>Transpose
slider4:text_alpha=0.9<0.0, 1.0, 0.1>TextAlpha
@init
RECT_SIZE = 50;
PAD_COUNT = 64;
PAD_COLS = 8;
NOTE_NUM_MAX = 127;
notebuf = 0; // 4 entries per open note: orignote, channel, vel, transnote
buflen = 0;
// Midi Note Numberをパッドの位置として、pad_*_arrayインデックスに変換するための配列
n2p = 400; idx = 0; loop(NOTE_NUM_MAX, (n2p[idx]=0; idx+=1;));
n2p[64]=0; n2p[65]=1; n2p[66]=2; n2p[67]=3; n2p[96]=4; n2p[97]=5; n2p[98]=6; n2p[99]=7;
n2p[60]=8; n2p[61]=9; n2p[62]=10; n2p[63]=11; n2p[92]=12; n2p[93]=13; n2p[94]=14; n2p[95]=15;
n2p[56]=16; n2p[57]=17; n2p[58]=18; n2p[59]=19; n2p[88]=20; n2p[89]=21; n2p[90]=22; n2p[91]=23;
n2p[52]=24; n2p[53]=25; n2p[54]=26; n2p[55]=27; n2p[84]=28; n2p[85]=29; n2p[86]=30; n2p[87]=31;
n2p[48]=32; n2p[49]=33; n2p[50]=34; n2p[51]=35; n2p[80]=36; n2p[81]=37; n2p[82]=38; n2p[83]=39;
n2p[44]=40; n2p[45]=41; n2p[46]=42; n2p[47]=43; n2p[76]=44; n2p[77]=45; n2p[78]=46; n2p[79]=47;
n2p[40]=48; n2p[41]=49; n2p[42]=50; n2p[43]=51; n2p[72]=52; n2p[73]=53; n2p[74]=54; n2p[75]=55;
n2p[36]=56; n2p[37]=57; n2p[38]=58; n2p[39]=59; n2p[68]=60; n2p[69]=61; n2p[70]=62; n2p[71]=63;
note2name = 700;
note2name[0] = "C"; note2name[1] = "C#"; note2name[2] = "D"; note2name[3] = "D#";
note2name[4] = "E"; note2name[5] = "F"; note2name[6] = "F#"; note2name[7] = "G";
note2name[8] = "G#"; note2name[9] = "A"; note2name[10] = "A#"; note2name[11] = "B";
function get_note_name(note_num) (
note2name[(note_num % 12)|0];
);
function get_note_name_diatonic(note_num) (
num = (note_num % 12)|0;
(num == 1) ? ""
: num == 3 ? ""
: num == 6 ? ""
: num == 8 ? ""
: num == 10 ? ""
: note2name[num];
);
function set_note_name_array(n2t, n2n) (
idx = 36; loop(PAD_COUNT,
note = n2t[idx];
pos = n2p[idx];
n2n[pos] = get_note_name(note);
idx+=1;);
);
function set_note_name_array_note_num(n2t, n2n) (
idx = 36; loop(PAD_COUNT,
note = n2t[idx];
pos = n2p[idx];
n2n[pos] = note;
idx+=1;);
);
function apply_offset(n2t, offset) (
idx = 36; loop(PAD_COUNT, (n2t[idx] += offset; idx += 1;));
);
function set_layout_Mm3rdRotated(n2t, n2n, offset) (
idx = 0; loop(NOTE_NUM_MAX, (n2t[idx]=0; idx+=1;));
n2t[64]=43; n2t[65]=47; n2t[66]=50; n2t[67]=54; n2t[96]=57; n2t[97]=61; n2t[98]=64; n2t[99]=68;
n2t[60]=42; n2t[61]=46; n2t[62]=49; n2t[63]=53; n2t[92]=56; n2t[93]=60; n2t[94]=63; n2t[95]=67;
n2t[56]=41; n2t[57]=45; n2t[58]=48; n2t[59]=52; n2t[88]=55; n2t[89]=59; n2t[90]=62; n2t[91]=66;
n2t[52]=40; n2t[53]=44; n2t[54]=47; n2t[55]=51; n2t[84]=54; n2t[85]=58; n2t[86]=61; n2t[87]=65;
n2t[48]=39; n2t[49]=43; n2t[50]=46; n2t[51]=50; n2t[80]=53; n2t[81]=57; n2t[82]=60; n2t[83]=64;
n2t[44]=38; n2t[45]=42; n2t[46]=45; n2t[47]=49; n2t[76]=52; n2t[77]=56; n2t[78]=59; n2t[79]=63;
n2t[40]=37; n2t[41]=41; n2t[42]=44; n2t[43]=48; n2t[72]=51; n2t[73]=55; n2t[74]=58; n2t[75]=62;
n2t[36]=36; n2t[37]=40; n2t[38]=43; n2t[39]=47; n2t[68]=50; n2t[69]=54; n2t[70]=57; n2t[71]=61;
apply_offset(n2t, offset);
set_note_name_array(n2t, n2n);
n2n[0]=1?n2n[0]:""; n2n[1]=1?n2n[1]:""; n2n[2]=1?n2n[2]:""; n2n[3]=0?n2n[3]:""; n2n[4]=1?n2n[4]:""; n2n[5]=0?n2n[5]:""; n2n[6]=1?n2n[6]:""; n2n[7]=0?n2n[7]:"";
n2n[8]=0?n2n[8]:""; n2n[9]=0?n2n[9]:""; n2n[10]=0?n2n[10]:""; n2n[11]=1?n2n[11]:""; n2n[12]=0?n2n[12]:""; n2n[13]=1?n2n[13]:""; n2n[14]=0?n2n[14]:""; n2n[15]=1?n2n[15]:"";
n2n[16]=1?n2n[16]:""; n2n[17]=1?n2n[17]:""; n2n[18]=1?n2n[18]:""; n2n[19]=1?n2n[19]:""; n2n[20]=1?n2n[20]:""; n2n[21]=1?n2n[21]:""; n2n[22]=1?n2n[22]:""; n2n[23]=0?n2n[23]:"";
n2n[24]=1?n2n[24]:""; n2n[25]=0?n2n[25]:""; n2n[26]=1?n2n[26]:""; n2n[27]=0?n2n[27]:""; n2n[28]=0?n2n[28]:""; n2n[29]=0?n2n[29]:""; n2n[30]=0?n2n[30]:""; n2n[31]=1?n2n[31]:"";
n2n[32]=0?n2n[32]:""; n2n[33]=1?n2n[33]:""; n2n[34]=0?n2n[34]:""; n2n[35]=1?n2n[35]:""; n2n[36]=1?n2n[36]:""; n2n[37]=1?n2n[37]:""; n2n[38]=1?n2n[38]:""; n2n[39]=1?n2n[39]:"";
n2n[40]=1?n2n[40]:""; n2n[41]=0?n2n[41]:""; n2n[42]=1?n2n[42]:""; n2n[43]=0?n2n[43]:""; n2n[44]=1?n2n[44]:""; n2n[45]=0?n2n[45]:""; n2n[46]=1?n2n[46]:""; n2n[47]=0?n2n[47]:"";
n2n[48]=0?n2n[48]:""; n2n[49]=1?n2n[49]:""; n2n[50]=0?n2n[50]:""; n2n[51]=1?n2n[51]:""; n2n[52]=0?n2n[52]:""; n2n[53]=1?n2n[53]:""; n2n[54]=0?n2n[54]:""; n2n[55]=1?n2n[55]:"";
n2n[56]=1?n2n[56]:""; n2n[57]=1?n2n[57]:""; n2n[58]=1?n2n[58]:""; n2n[59]=1?n2n[59]:""; n2n[60]=1?n2n[60]:""; n2n[61]=0?n2n[61]:""; n2n[62]=1?n2n[62]:""; n2n[63]=0?n2n[63]:"";
);
function set_layout_P4th(n2t, n2n, offset) (
idx = 0; loop(NOTE_NUM_MAX, (n2t[idx]=0; idx+=1;));
n2t[64]=71; n2t[65]=72; n2t[66]=73; n2t[67]=74; n2t[96]=75; n2t[97]=76; n2t[98]=77; n2t[99]=78;
n2t[60]=66; n2t[61]=67; n2t[62]=68; n2t[63]=69; n2t[92]=70; n2t[93]=71; n2t[94]=72; n2t[95]=73;
n2t[56]=61; n2t[57]=62; n2t[58]=63; n2t[59]=64; n2t[88]=65; n2t[89]=66; n2t[90]=67; n2t[91]=68;
n2t[52]=56; n2t[53]=57; n2t[54]=58; n2t[55]=59; n2t[84]=60; n2t[85]=61; n2t[86]=62; n2t[87]=63;
n2t[48]=51; n2t[49]=52; n2t[50]=53; n2t[51]=54; n2t[80]=55; n2t[81]=56; n2t[82]=57; n2t[83]=58;
n2t[44]=46; n2t[45]=47; n2t[46]=48; n2t[47]=49; n2t[76]=50; n2t[77]=51; n2t[78]=52; n2t[79]=53;
n2t[40]=41; n2t[41]=42; n2t[42]=43; n2t[43]=44; n2t[72]=45; n2t[73]=46; n2t[74]=47; n2t[75]=48;
n2t[36]=36; n2t[37]=37; n2t[38]=38; n2t[39]=39; n2t[68]=40; n2t[69]=41; n2t[70]=42; n2t[71]=43;
apply_offset(n2t, offset);
set_note_name_array(n2t, n2n);
n2n[0]=1?n2n[0]:""; n2n[1]=1?n2n[1]:""; n2n[2]=0?n2n[2]:""; n2n[3]=1?n2n[3]:""; n2n[4]=0?n2n[4]:""; n2n[5]=1?n2n[5]:""; n2n[6]=1?n2n[6]:""; n2n[7]=0?n2n[7]:"";
n2n[8]=0?n2n[8]:""; n2n[9]=1?n2n[9]:""; n2n[10]=0?n2n[10]:""; n2n[11]=1?n2n[11]:""; n2n[12]=0?n2n[12]:""; n2n[13]=1?n2n[13]:""; n2n[14]=1?n2n[14]:""; n2n[15]=0?n2n[15]:"";
n2n[16]=0?n2n[16]:""; n2n[17]=1?n2n[17]:""; n2n[18]=0?n2n[18]:""; n2n[19]=1?n2n[19]:""; n2n[20]=1?n2n[20]:""; n2n[21]=0?n2n[21]:""; n2n[22]=1?n2n[22]:""; n2n[23]=0?n2n[23]:"";
n2n[24]=0?n2n[24]:""; n2n[25]=1?n2n[25]:""; n2n[26]=0?n2n[26]:""; n2n[27]=1?n2n[27]:""; n2n[28]=1?n2n[28]:""; n2n[29]=0?n2n[29]:""; n2n[30]=1?n2n[30]:""; n2n[31]=0?n2n[31]:"";
n2n[32]=0?n2n[32]:""; n2n[33]=1?n2n[33]:""; n2n[34]=1?n2n[34]:""; n2n[35]=0?n2n[35]:""; n2n[36]=1?n2n[36]:""; n2n[37]=0?n2n[37]:""; n2n[38]=1?n2n[38]:""; n2n[39]=0?n2n[39]:"";
n2n[40]=0?n2n[40]:""; n2n[41]=1?n2n[41]:""; n2n[42]=1?n2n[42]:""; n2n[43]=0?n2n[43]:""; n2n[44]=1?n2n[44]:""; n2n[45]=0?n2n[45]:""; n2n[46]=1?n2n[46]:""; n2n[47]=1?n2n[47]:"";
n2n[48]=1?n2n[48]:""; n2n[49]=0?n2n[49]:""; n2n[50]=1?n2n[50]:""; n2n[51]=0?n2n[51]:""; n2n[52]=1?n2n[52]:""; n2n[53]=0?n2n[53]:""; n2n[54]=1?n2n[54]:""; n2n[55]=1?n2n[55]:"";
n2n[56]=1?n2n[56]:""; n2n[57]=0?n2n[57]:""; n2n[58]=1?n2n[58]:""; n2n[59]=0?n2n[59]:""; n2n[60]=1?n2n[60]:""; n2n[61]=1?n2n[61]:""; n2n[62]=0?n2n[62]:""; n2n[63]=1?n2n[63]:"";
);
function set_layout_P5th(n2t, n2n, offset) (
idx = 0; loop(NOTE_NUM_MAX, (n2t[idx]=0; idx+=1;));
n2t[64]=85; n2t[65]=86; n2t[66]=87; n2t[67]=88; n2t[96]=89; n2t[97]=90; n2t[98]=91; n2t[99]=92;
n2t[60]=78; n2t[61]=79; n2t[62]=80; n2t[63]=81; n2t[92]=82; n2t[93]=83; n2t[94]=84; n2t[95]=85;
n2t[56]=71; n2t[57]=72; n2t[58]=73; n2t[59]=74; n2t[88]=75; n2t[89]=76; n2t[90]=77; n2t[91]=78;
n2t[52]=64; n2t[53]=65; n2t[54]=66; n2t[55]=67; n2t[84]=68; n2t[85]=69; n2t[86]=70; n2t[87]=71;
n2t[48]=57; n2t[49]=58; n2t[50]=59; n2t[51]=60; n2t[80]=61; n2t[81]=62; n2t[82]=63; n2t[83]=64;
n2t[44]=50; n2t[45]=51; n2t[46]=52; n2t[47]=53; n2t[76]=54; n2t[77]=55; n2t[78]=56; n2t[79]=57;
n2t[40]=43; n2t[41]=44; n2t[42]=45; n2t[43]=46; n2t[72]=47; n2t[73]=48; n2t[74]=49; n2t[75]=50;
n2t[36]=36; n2t[37]=37; n2t[38]=38; n2t[39]=39; n2t[68]=40; n2t[69]=41; n2t[70]=42; n2t[71]=43;
apply_offset(n2t, offset);
set_note_name_array(n2t, n2n);
n2n[0]=0?n2n[0]:""; n2n[1]=1?n2n[1]:""; n2n[2]=0?n2n[2]:""; n2n[3]=1?n2n[3]:""; n2n[4]=1?n2n[4]:""; n2n[5]=0?n2n[5]:""; n2n[6]=1?n2n[6]:""; n2n[7]=0?n2n[7]:"";
n2n[8]=0?n2n[8]:""; n2n[9]=1?n2n[9]:""; n2n[10]=0?n2n[10]:""; n2n[11]=1?n2n[11]:""; n2n[12]=0?n2n[12]:""; n2n[13]=1?n2n[13]:""; n2n[14]=1?n2n[14]:""; n2n[15]=0?n2n[15]:"";
n2n[16]=1?n2n[16]:""; n2n[17]=1?n2n[17]:""; n2n[18]=0?n2n[18]:""; n2n[19]=1?n2n[19]:""; n2n[20]=0?n2n[20]:""; n2n[21]=1?n2n[21]:""; n2n[22]=1?n2n[22]:""; n2n[23]=0?n2n[23]:"";
n2n[24]=1?n2n[24]:""; n2n[25]=1?n2n[25]:""; n2n[26]=0?n2n[26]:""; n2n[27]=1?n2n[27]:""; n2n[28]=0?n2n[28]:""; n2n[29]=1?n2n[29]:""; n2n[30]=0?n2n[30]:""; n2n[31]=1?n2n[31]:"";
n2n[32]=1?n2n[32]:""; n2n[33]=0?n2n[33]:""; n2n[34]=1?n2n[34]:""; n2n[35]=1?n2n[35]:""; n2n[36]=0?n2n[36]:""; n2n[37]=1?n2n[37]:""; n2n[38]=0?n2n[38]:""; n2n[39]=1?n2n[39]:"";
n2n[40]=1?n2n[40]:""; n2n[41]=0?n2n[41]:""; n2n[42]=1?n2n[42]:""; n2n[43]=1?n2n[43]:""; n2n[44]=0?n2n[44]:""; n2n[45]=1?n2n[45]:""; n2n[46]=0?n2n[46]:""; n2n[47]=1?n2n[47]:"";
n2n[48]=1?n2n[48]:""; n2n[49]=0?n2n[49]:""; n2n[50]=1?n2n[50]:""; n2n[51]=0?n2n[51]:""; n2n[52]=1?n2n[52]:""; n2n[53]=1?n2n[53]:""; n2n[54]=0?n2n[54]:""; n2n[55]=1?n2n[55]:"";
n2n[56]=1?n2n[56]:""; n2n[57]=0?n2n[57]:""; n2n[58]=1?n2n[58]:""; n2n[59]=0?n2n[59]:""; n2n[60]=1?n2n[60]:""; n2n[61]=1?n2n[61]:""; n2n[62]=0?n2n[62]:""; n2n[63]=1?n2n[63]:"";
);
function set_layout_P5thRotated(n2t, n2n, offset) (
idx = 0; loop(NOTE_NUM_MAX, (n2t[idx]=0; idx+=1;));
n2t[64]=43; n2t[65]=50; n2t[66]=57; n2t[67]=64; n2t[96]=71; n2t[97]=78; n2t[98]=85; n2t[99]=92;
n2t[60]=42; n2t[61]=49; n2t[62]=56; n2t[63]=63; n2t[92]=70; n2t[93]=77; n2t[94]=84; n2t[95]=91;
n2t[56]=41; n2t[57]=48; n2t[58]=55; n2t[59]=62; n2t[88]=69; n2t[89]=76; n2t[90]=83; n2t[91]=90;
n2t[52]=40; n2t[53]=47; n2t[54]=54; n2t[55]=61; n2t[84]=68; n2t[85]=75; n2t[86]=82; n2t[87]=89;
n2t[48]=39; n2t[49]=46; n2t[50]=53; n2t[51]=60; n2t[80]=67; n2t[81]=74; n2t[82]=81; n2t[83]=88;
n2t[44]=38; n2t[45]=45; n2t[46]=52; n2t[47]=59; n2t[76]=66; n2t[77]=73; n2t[78]=80; n2t[79]=87;
n2t[40]=37; n2t[41]=44; n2t[42]=51; n2t[43]=58; n2t[72]=65; n2t[73]=72; n2t[74]=79; n2t[75]=86;
n2t[36]=36; n2t[37]=43; n2t[38]=50; n2t[39]=57; n2t[68]=64; n2t[69]=71; n2t[70]=78; n2t[71]=85;
apply_offset(n2t, offset);
set_note_name_array(n2t, n2n);
n2n[0]=1?n2n[0]:""; n2n[1]=1?n2n[1]:""; n2n[2]=1?n2n[2]:""; n2n[3]=1?n2n[3]:""; n2n[4]=1?n2n[4]:""; n2n[5]=0?n2n[5]:""; n2n[6]=0?n2n[6]:""; n2n[7]=0?n2n[7]:"";
n2n[8]=0?n2n[8]:""; n2n[9]=0?n2n[9]:""; n2n[10]=0?n2n[10]:""; n2n[11]=0?n2n[11]:""; n2n[12]=0?n2n[12]:""; n2n[13]=1?n2n[13]:""; n2n[14]=1?n2n[14]:""; n2n[15]=1?n2n[15]:"";
n2n[16]=1?n2n[16]:""; n2n[17]=1?n2n[17]:""; n2n[18]=1?n2n[18]:""; n2n[19]=1?n2n[19]:""; n2n[20]=1?n2n[20]:""; n2n[21]=1?n2n[21]:""; n2n[22]=1?n2n[22]:""; n2n[23]=0?n2n[23]:"";
n2n[24]=1?n2n[24]:""; n2n[25]=1?n2n[25]:""; n2n[26]=0?n2n[26]:""; n2n[27]=0?n2n[27]:""; n2n[28]=0?n2n[28]:""; n2n[29]=0?n2n[29]:""; n2n[30]=0?n2n[30]:""; n2n[31]=1?n2n[31]:"";
n2n[32]=0?n2n[32]:""; n2n[33]=0?n2n[33]:""; n2n[34]=1?n2n[34]:""; n2n[35]=1?n2n[35]:""; n2n[36]=1?n2n[36]:""; n2n[37]=1?n2n[37]:""; n2n[38]=1?n2n[38]:""; n2n[39]=1?n2n[39]:"";
n2n[40]=1?n2n[40]:""; n2n[41]=1?n2n[41]:""; n2n[42]=1?n2n[42]:""; n2n[43]=1?n2n[43]:""; n2n[44]=0?n2n[44]:""; n2n[45]=0?n2n[45]:""; n2n[46]=0?n2n[46]:""; n2n[47]=0?n2n[47]:"";
n2n[48]=0?n2n[48]:""; n2n[49]=0?n2n[49]:""; n2n[50]=0?n2n[50]:""; n2n[51]=0?n2n[51]:""; n2n[52]=1?n2n[52]:""; n2n[53]=1?n2n[53]:""; n2n[54]=1?n2n[54]:""; n2n[55]=1?n2n[55]:"";
n2n[56]=1?n2n[56]:""; n2n[57]=1?n2n[57]:""; n2n[58]=1?n2n[58]:""; n2n[59]=1?n2n[59]:""; n2n[60]=1?n2n[60]:""; n2n[61]=1?n2n[61]:""; n2n[62]=0?n2n[62]:""; n2n[63]=0?n2n[63]:"";
);
function set_layout_nop(n2t, n2n, offset) (
idx = 0; loop(NOTE_NUM_MAX, (n2t[idx]=0; idx+=1;));
n2t[64]=64; n2t[65]=65; n2t[66]=66; n2t[67]=67; n2t[96]=96; n2t[97]=97; n2t[98]=98; n2t[99]=99;
n2t[60]=60; n2t[61]=61; n2t[62]=62; n2t[63]=63; n2t[92]=92; n2t[93]=93; n2t[94]=94; n2t[95]=95;
n2t[56]=56; n2t[57]=57; n2t[58]=58; n2t[59]=59; n2t[88]=88; n2t[89]=89; n2t[90]=90; n2t[91]=91;
n2t[52]=52; n2t[53]=53; n2t[54]=54; n2t[55]=55; n2t[84]=84; n2t[85]=85; n2t[86]=86; n2t[87]=87;
n2t[48]=48; n2t[49]=49; n2t[50]=50; n2t[51]=51; n2t[80]=80; n2t[81]=81; n2t[82]=82; n2t[83]=83;
n2t[44]=44; n2t[45]=45; n2t[46]=46; n2t[47]=47; n2t[76]=76; n2t[77]=77; n2t[78]=78; n2t[79]=79;
n2t[40]=40; n2t[41]=41; n2t[42]=42; n2t[43]=43; n2t[72]=72; n2t[73]=73; n2t[74]=74; n2t[75]=75;
n2t[36]=36; n2t[37]=37; n2t[38]=38; n2t[39]=39; n2t[68]=68; n2t[69]=69; n2t[70]=70; n2t[71]=71;
apply_offset(n2t, offset);
set_note_name_array(n2t, n2n);
);
function select_layout(layout_num, n2t, n2n, offset) (
layout_num == 0 ? set_layout_Mm3rdRotated(n2t, n2n, offset)
: layout_num == 1 ? set_layout_P5thRotated(n2t, n2n, offset)
: layout_num == 2 ? set_layout_P5th(n2t, n2n, offset)
: layout_num == 3 ? set_layout_P4th(n2t, n2n, offset)
: layout_num == 4 ? set_layout_nop(n2t, n2n, offset)
: set_layout_nop(n2t, n2n, offset);
);
function calc_offset() (
transpose + octave * 12;
);
// 64パッドの各パッドの状態を管理するための配列 インデックス0は左上 値は変換後の音程(値0はオフ)
pad_state_array = 330; idx = 0; loop(PAD_COUNT, (pad_state_array[idx]=0; idx+=1;));
pad_name_array = 530; // idx = 0; loop(PAD_COUNT, (pad_name_array[idx]=sprintf("%i", idx); idx+=1;));
// Midi Note Numberを新しいNote Numberに変換するための配列
n2t = 200;
select_layout(layout, n2t, pad_name_array, calc_offset());
function set_pad_state(note_num, val) (
pad_state_array[n2p[note_num]] = val;
);
// color setting
function set_color_panel_off() (
gfx_r = 0.17; gfx_g = 0.17; gfx_b = 0.25;
);
function set_color_panel_on() (
gfx_r = 0.92; gfx_g = 0.88; gfx_b = 0.08;
);
function set_color_label_on() (
set_color_panel_off();
);
function set_color_label_off() (
// gfx_r = 0.41; gfx_g = 0.4; gfx_b = 0.03;
gfx_r = 0.31; gfx_g = 0.3; gfx_b = 0.02;
);
function set_color_panel_zero() (
gfx_r = 0; gfx_g = 0; gfx_b = 0;
);
// slider
octave_last = octave;
transpose_last = transpose;
layout_last = layout;
@slider
octave_last != octave ? (
select_layout(layout, n2t, pad_name_array, calc_offset());
octave_last = octave;
);
transpose_last != transpose ? (
select_layout(layout, n2t, pad_name_array, calc_offset());
transpose_last = transpose;
);
layout_last != layout ? (
layout_last = layout;
select_layout(layout, n2t, pad_name_array, calc_offset());
);
@block
while
(
midirecv(offs, m1, m2) ?
(
s = m1&$xF0;
s == $x90 || s == $x80 ? // note-on or note-off
(
n = m2&$xFF; // original note
c = m1&$xF; // channel
v = (m2&$xFF00)/256; // velocity
t = n2t[n]; // transposed note
m2 = m2+t-n; // apply transposition
i = -1;
while // look for this note|channel already in the buffer
(
i = i+1;
i < buflen && (notebuf[4*i]|0 != n || notebuf[4*i+1]|0 != c);
);
(s == $x90 && v > 0) ? // note-on, add to buffer
(
set_pad_state(n, t); // pad_state_array[n2p[n]] = t;
notebuf[4*i] = n;
notebuf[4*i+1] = c;
notebuf[4*i+2] = v;
notebuf[4*i+3] = t;
i == buflen ? buflen = buflen+1;
)
: // note-off, remove from buffer
(
set_pad_state(n, 0); // pad_state_array[n2p[n]] = 0;
i < buflen ?
(
memcpy(notebuf+4*i, notebuf+4*(i+1), 4*(buflen-i-1)); // delete the entry
buflen = buflen-1;
);
);
);
midisend(offs, m1, m2);
);
);
@gfx 400 400
gfx_x = 0;
gfx_y = 0;
// clear canvas
gfx_w = PAD_COLS*RECT_SIZE; gfx_h = gfx_w;
set_color_panel_off();
gfx_rect(0, 0, PAD_COLS*RECT_SIZE, PAD_COLS*RECT_SIZE);
function draw_pad_label(label)(
gfx_setfont(1, "Arial", 36);
tmp_x = gfx_x; gfx_x += 4;
tmp_a = gfx_a; gfx_a = text_alpha;
gfx_drawstr(label, 8, gfx_x+RECT_SIZE, gfx_y+RECT_SIZE);
gfx_a = tmp_a;
gfx_x = tmp_x;
);
function draw_pad_label_num(num)(
gfx_setfont(1, "Arial", 24);
tmp_x = gfx_x; gfx_x += 4;
tmp_a = gfx_a; gfx_a = text_alpha;
gfx_printf("%i", num);
gfx_a = tmp_a;
gfx_x = tmp_x;
);
// draw note-on pad
idx = 0; loop(64,
next_x = gfx_x + RECT_SIZE;
label = pad_name_array[idx];
(pad_state_array[idx]>0) ? (
// rect
set_color_panel_on();
gfx_rect(gfx_x+1, gfx_y+1, RECT_SIZE-1, RECT_SIZE-1);
// label text color
set_color_label_on();
// draw_pad_label(label);
draw_pad_label(get_note_name(pad_state_array[idx]));
) : (
// label text color
set_color_label_off();
draw_pad_label(label);
);
// draw_pad_label(get_note_name(pad_state_array[idx]));
// draw_pad_label_num(label);
gfx_x = next_x;
(PAD_COLS-1) == (idx % PAD_COLS) ? (
gfx_x = 0;
gfx_y += RECT_SIZE;
);
idx += 1;
);
// draw grid
set_color_panel_zero();
idx = 0; loop(9,
unit = idx*RECT_SIZE;
last = RECT_SIZE*PAD_COLS;
gfx_x = unit; gfx_y = 0;
end_x = unit; end_y = last;
gfx_lineto(end_x, end_y);
idx += 1;
);
idx = 0; loop(9,
unit = idx*RECT_SIZE;
last = RECT_SIZE*PAD_COLS;
gfx_x = 0; gfx_y = unit;
end_x = last; end_y = unit;
gfx_lineto(end_x, end_y);
idx += 1;
);