MacroPad改造(その2)

改造終了。

とりあえずノートとVelocityは調整できるようにしました。

コード

RP2040 Macropad上で動くCircuitPythonのコードになります。
(勿論ライブラリも別途必要)


# simple_test
import board
import time
import random
import usb_midi
import adafruit_midi
import simpleio
import rotaryio

from adafruit_midi.control_change import ControlChange
from adafruit_midi.note_off import NoteOff
from adafruit_midi.note_on import NoteOn
from adafruit_midi.pitch_bend import PitchBend
from adafruit_midi.stop import Stop

from digitalio import DigitalInOut, Pull
from adafruit_macropad import MacroPad
from adafruit_display_text import label
# from adafruit_progressbar.progressbar import HorizontalProgressBar

# ボタンの状態確認
button = [DigitalInOut(board.KEY1),
DigitalInOut(board.KEY2),
DigitalInOut(board.KEY3),
DigitalInOut(board.KEY4),
DigitalInOut(board.KEY5),
DigitalInOut(board.KEY6),
DigitalInOut(board.KEY7),
DigitalInOut(board.KEY8),
DigitalInOut(board.KEY9),
DigitalInOut(board.KEY10),
DigitalInOut(board.KEY11),
DigitalInOut(board.KEY12),
]

encoder = rotaryio.IncrementalEncoder(board.ENCODER_A, board.ENCODER_B)
enc_btn=DigitalInOut(board.ENCODER_SWITCH)
enc_btn.pull = Pull.UP # 内部のプルアップ抵抗を有効化する
enc_state=False

# ノート管理

# 再生中のノート番号を格納する
note=[0,0,0,0,0,0, 0,0,0,0,0,0]

# 再生中のノートのVelocityを格納する
note_vel=[0,0,0,0,0,0, 0,0,0,0,0,0]

# キーに対応する音の高さを定義する
note_tbl=[9,10,11,
6,7,8,
3,4,5,
0,1,2]

# キーごとの押しっぱなし状態を格納する
note_state=[False,False,False,False,False,False,
False,False,False,False,False,False]

for i in range(12):
    button[i].pull = Pull.UP # 内部のプルアップ抵抗を有効化する
    note[i]=0
    note_vel[i]=100

led = simpleio.DigitalOut(board.LED)

# MIDIポートの入出力についてデバイス取得
midi = adafruit_midi.MIDI(
    midi_out=usb_midi.ports[1], out_channel=0
)

# 必要な変数
cnt=0
tone=5
velocity=100
input_mode=0
velocity_lock= False

# 関数
def encoder_tone(tn, enc_delta=0):
    tn =tn - enc_delta
    return tn

def macro_note_off( note_no, velocity):
    midi.send(NoteOff(note_no, velocity))

def macro_note_on( note_no, velocity):
    midi.send(NoteOn(note_no, velocity))

def value_cap( value, min, max):
    if value < min:
        value=min
    if value > max:
        value=max

    return value

def tf_change( val):
    if val==True:
        val=False
    elif val==False:
        val=True
    return val

# すべての音停止。
for i in range(128):
    macro_note_off(i,0)

print("velocity: "+str(velocity))
print("Octave Mode:"+str(tone-2) )

while True:
    # ボタンによって処理を変更するがとりあえずはノート再生処理
    for i in range(12):
        if button[i].value==False:
            if note_state[i]==False:
                # ノート番号とベロシティを反映
                note[i]=note_tbl[i]+tone*12
                note_vel[i]=velocity
                # MIDI output
                macro_note_on( note[i], note_vel[i])
                # ボタン押しっぱなしフラグを立てる
                note_state[i]=True
        else:
            if note_state[i]==True:
                macro_note_off( note[i], note_vel[i])
                note_state[i]=False

    # エンコーダの確認
    if cnt!=encoder.position:
        if velocity_lock==True:
            velocity = encoder_tone(velocity, encoder.position-cnt)
            velocity=value_cap( velocity, 0,127)
            print("velocity: "+str(velocity))
        else:
            tone = encoder_tone(tone, encoder.position-cnt)
            tone=value_cap( tone, 0,9)
            print("Note Octave: "+ str(tone-2))
            # エンコーダの位置を覚えておく
        cnt=encoder.position
    # エンコーダボタン
    if enc_btn.value==False:
        if enc_state==False:
            enc_state=True
    else:
        if enc_state==True:
            velocity_lock = tf_change( velocity_lock)
            if velocity_lock == True:
                print("Velocity Mode:"+str(velocity))
            else:
                print("Octave Mode:"+str(tone-2) ) 
            enc_state=False

ちなみになんでこれが必要かって

腱鞘炎の対策で打ち込み環境を効率化するのは以前から書いてるとおりです。
現在使っているAbletonLiveがキーボードで曲書くのに一番ましなDAWなんですが、
それでも不都合な点がいくつか存在して、一番致命的なのは「キーボードで入力する場合Velocityが10刻みでしか変更できない」ことになります。
よって、上記の部分を補完するためのデバイスが欲しかったわけですね。
そのため、入力キーボードに依存しないキー入力で譜面が入力できるデバイス(MIDIデバイス)を作りました。
当初は数字でVelocity入力する方式を検討してましたが、ダイヤルで調整する方式は実装も楽だしこのままでいっかってなってます。

あとの拡張として、CC入力ができる機能も追加しようかと。
これがあればだいたいのことはできると思うので。