since 2006 ~ 2013
自作電子楽器ノブログ
ブログ更新は以下に移行中です。
->Analogfeeder.com
自作midiデバイス1
f0097833_14251643.jpg


自作のmidiデバイス作ります。

最近の電子楽器は標準でmidiが組み込まれているものが多くなってきています。
今後midiを通して、コンピュータとのかかわりがより深くなっていくことが予想されるので、midiをコントロールできるようになることは、独自の音楽性を売りにしている人にとってはとても重要なことです。midiがコントロールできれば、パソコン、エフェクターやシーケンサー、ドラムマシン、照明など、いろいろな要素を統合的に操ることができます。よって、今まで考えられないようなことができるようになるのです。

とくにmax/mspreaktorなど、自分でなんでも作れちゃう系のソフトでは、自作midiに興味がある人がいると思う(自分がそうだった)ので、これを機にうまいmidiが作れたらなあと思います。



では、自作midiデバイスを作るにはどうすればいいか。
まず、midi信号について知る必要があります。

-------midi信号とは?-------

簡単にいうと、楽器(ここでは鍵盤を想定します)の演奏情報です。
つまり、あなたが鍵盤の”ピアノどの音どれくらいの強さで押したか”という情報です。
これは、別に”どのつまみどのくらい回しているか”とか
どのセンサーどれくらい感知しているか”とか
なんでもいいです。
ここでは鍵盤話がもっともmidiでスタンダードなのでそれにしただけです。

ここで
上の鍵盤の話の” ”の中に太字の情報が三つあるのがわかります。
実は、midi信号とはこの三つの情報を鍵盤が押されたときにパソコンやらシンセなど送信するだけで実現できるものなのです。
なのでmidi信号そのものは、音ではないので、注意してください。ここをごっちゃにしている人がかなり多いです。
もちろん受信する側はそれを、”ピアノどの音どれくらいの強さで押したか”を認識して、実際に音を出す役割をするだけです。
これが一連のmidi信号の仕組みです。

では
-------midi信号が実際にどうゆう形で送信、受信されているのでしょうか?-------

ここからは、多少理系の知識がいるのですが、なるべく分かりやすいように書くことにします。
しかし、僕は理系の人間なので、一般の方に理解できてない言葉を平気で使う可能性があります。
なので、わからないことがあるならば気軽に書き込んでいただいて結構です。
しかし、多少のことはできるだけ自分で調べてください。
今やgoogle先生がなんでも答えてくれるでしょう。

midi信号は上の三つの情報をおくればいいのです。
ではたとえば、どれくらいの強さって情報をどうおくるの?って考えます。
てっとりばやく数値で送りましょう。たとえば、127の強さで送りましょう。
でも127って何?って、これは卑怯ですが、midi信号で送れる最大の強さなんですが、これは今わからないと思うので、ここでは扱うのに都合のいい数字だと思ってください。
では127で送れば鳴るのかというと、そうあまくなく、このままではあっち(パソコンとかシンセなど、まあ受信する側)が認識してくれないのです。

実は127っていうのは、人間が都合よく認識する為のものでしかないのです。
つまり、パソコンやら、シンセなど、、、、っていうか機械全部、127のまんまでは認識できません。
したらどうすればいいか?

-------10進法、2進法-------
いきなりですが、127は10進法と呼ばれる数字です。
しかし、それは機械では認識できないので、ここで2進法が登場します。
2進法は機械が認識できる数字です。
上の127を2進法で書くと、1111111になります。
なぜって、思う人にこれを説明するのは大変なので、この辺はgoogle先生に相談してください。

ここではwindowsのアクセサリ”関数電卓”を使って計算して確かめてもらいます。
まず、

スタートメニューからすべてのプログラム
アクセサリ→電卓

で電卓を起動してください。
あとは、電卓の上のタブの”表示”から”関数電卓”を選んでもらって、
10進法ってところを選択してもらって、127を入力します。
そして2進法を選択すれば、1111111と表示されるはずです。
これで人間数字(10進法)から機械数字(2進法)に変換されました。

このやりかたは、midiデバイスをつくるときの必要になるテクニックなので、覚えておいて損はありません。

これで127の強さを機械が認識できる1111111にできたので、これを送信すれば、あっちが勝手に認識して鳴らしてくれるわけです。

今度は、1111111って信号をどう作るかって話ですね。

-------マイコン-------
この1111111って信号を作るには”マイコン”が優れています。
マイコンとは、マイクロコンピュータとかマイクロコントローラーとかいいます。
簡単にいうと、電気を制御するものです。
人間でいうと脳にあたるのかな?
脳が手や足に命令することによって、手がどのくらい、足がどのくらい動かすのかを制御しているわけです。
ここで、midi信号を送る線(midiケーブル)はニューロンみたいなものですね。

話がそれましたが、用はマイコンが使えれば、midiデバイスが作れます。
つまりマイコンを使うことによって、11111111という信号を作れればいいわけですね。

ここでマイコンをゼロから説明するのは、大変なので、カテゴリの”picマイコン”に最低限のことを書いておきます。(picという単語に反応すると思いますが、これはマイコンの種類です。あまり気にしないでください。)
なので、マイコンが使えるような状態になるまで、ここから先の話は、実現できないので、適当に読み進めてもかまいませんし、マイコンを作りにかかってもどっちでもかまいません。
picマイコンでは、電気と2進法との関係など、ハード(電気回路)的な説明も加えたいと思います。


話をmidiに戻します。

-------midiの規格-------
上の話からmidi信号は'0'と'1'の数字の組み合わせで表現できることがわかりました。
ここでもし、送りたい信号が'10000000'だとしたら、これは、数字が8個ならんでいるので8bit(ビット)と表現されます。
さらに8bitを1byte(バイト)ともいいます。

ここでいきなりmidiの規格について書くと、

midi信号は、転送速度31.25Kbit/sec(誤差±1%)非同期シリアル転送で伝えられるデジタル信号で、各データは8ビットで構成されます。

転送速度31.25Kbit/secとは、一秒間に31250bitの信号をおくりますよっていう速さのことです。
つまり'0'か'1'の数字を一秒間に31250個送るってことです。
非同期シリアル転送とは、送信側と受信側のタイミングを合わせないで、データのやり取りする方法です。
どういうものかというと(下図参照)
スタートビット→データバイト(ビット0、…ビット7の塊)→ストップビットの順番に、計10ビットで転送される方法で、
スタートビットは論理0、ストップビットは論理1で、受信側におくるものです。
受信側はこのスタートビットを認識して、データがおくわれてくるかを探っています。
そしてmidiはこのデータバイトの部分にメインのmidi信号を入れて送ります。

一般にバイトと最下位ビットをLSB(Least Significant Bit)といい、最上位ビットをMSB(Most Significant Bit)といいます。

MIDIではステータスバイトデータバイトの区別にMSBをつかい、1のときをステータスバイト、0のときをデータバイトとします。
そして、残りを有効なデータとして使います。
つまりMIDIにおいて1バイトで表現できるデータは7ビット分0~127(0h~7Fh)しかありません。
3バイトのmidiデータ(点線で囲まれている部分)には

ノートオン
ノートオフ
コントロールチェンジ
etc....

があります。
midiでは1バイトを転送する際には32.0μsecぐらい(ここでは31.6μs)が必要です。


という感じにかけます。
いきなりすぎてわからないと思いますが↓の図を見ればなんとか分かると思います。
詳しくは、自作midiデバイス2に書こうかな?それかmidi信号でgoogle先生に聞いてください。

f0097833_17535677.jpg


-------midiケーブルの仕組みとpicマイコンとの接続-------
midiケーブルは、下図のように5つの端子で構成されているのですが、実際使うのは、2つの端子だけ(4と5)です。
picマイコンのRA2midiの45V電源midiの5に接続すれば、完成です。

f0097833_17522595.jpg



間に抵抗220Ωをつけるのを忘れずに。
実はめちゃくちゃシンプルにできるんです。



とりあえずマイコンにこのアセンブラを書き込んで動作を確認しましょう。

-------アセンブラプログラム---------------------------------------------
ノートオンとノートオフをおくるプログラムです。


;MIDISEND.ASM
;10MHz PIC16F84 microcontrollerで動きます。
;毎秒ごとにmidiメッセージを送ります。
;rewrited 2006/06/22

                         ; CPU configuration
processor 16f84              ;マイコンの種類の選択
include
        __config _HS_OSC & _WDT_OFF & _PWRTE_ON 
                         ;オシレータを4MHzから20MHz
;ウォッチドックタイマ無効
                         ;パワーアップタイマ有効

                         ; 変数

temp equ  H'1F'
xmit  equ  H'1D'
i     equ  H'1C'
j     equ  H'1B'
k     equ  H'1A'

                         ; プログラム

org0             ; リセットベクタの0番地を指定


start:
bsf STATUS,RP0 ; ファイルレジスタSTATUSのRP0をセット(1)する → バンク1
movlw H'00'
movwf TRISA ; ファイルレジスタTRISAのすべてのポートを出力設定
bcf STATUS,RP0 ; STATUSのRP0をクリア(0) → バンク0
bsf PORTA, 0x02    ;RA2をmidi出力

mainloop:

call secdelay        ; secdelay関数の呼び込み(1秒待ち)

movlw 0x90         ; ノートオン、チャンネル1
movwf xmit    ;xmitに10010000(Ox90)を格納
call sendmidi        ;sendmidi関数を呼び込み(midi信号を送る)

movlw 0x3C         ; ミドルC
movwf xmit         ;xmitに01110000(Ox3C)を格納
call sendmidi     ;sendmidi関数を呼び込み(midi信号を送る)

movlw 0x7F         ; ベロシティー127
movwf xmit     ;xmitに01111111(Ox3C)を格納
call sendmidi     ;sendmidi関数を呼び込み(midi信号を送る)

call secdelay      ; secdelay関数の呼び込み(1秒待ち)

movlw 0x80         ; ノートオフ、チャンネル1
movwf xmit         ;xmitに10000000(Ox90)を格納
call sendmidi        ;sendmidi関数を呼び込み(midi信号を送る)

movlw 0x3C         ; middle C
movwf xmit
call sendmidi

movlw 0x7F         ; velocity 127
movwf xmit
call sendmidi

goto mainloop    ; mainloopに戻る(無限loop)

sendmidi:               ;ここから重要いろいろ使いまわして

startb:bcfPORTA, 0x02    ; スタートビット

movlw D'23'       ; delay 70 サイクル: 2 + (22 * 3 + 1 * 2)
movwf temp       ; 0.4μs * 70 = 28.0μs
loop1:
decfsz temp, f      ; |
goto loop1         ;end delay

movlwD'8'         ; midi信号は8ビット 28.4μs
movwfj ;28.8μs

sendloop:         
rrfxmit, f ; xmitの内容を右に1ビットシフトしてSTATUSのCに入れる 29.2μs
btfsc STATUS, C ; STATUSのCが0ならば、gotoをスキップ、1ならばgoto 29.6μs
goto send1 ;30.4μs

send0:
nop ;30.0μs
nop ;30.4μs
nop ;30.8μs
nop ;31.2μs
bcfPORTA, 0x02     ;0ビットを送る 31.6μs
goto endloop

send1:
nop ;30.8μs
nop ;31.2μs
bsfPORTA, 0x02     ;1ビットを送る 31.6μs
nop
nop

endloop:           ;

movlw D'22'       ;delay 67 instructions 2 + (21 * 3 + 1 * 2)
movwf temp       ; 0.4μs * 67 = 26.8μs
loop2:
decfsz temp, f  ; |
goto loop2         ; end delay

decfsz j, f          ;
goto sendloop

stopb:
nop
nop
nop
nop
nop
bsfPORTA, 0x02        ; ストップビット
movlw D'26'           ; delay 79 サイクル: 2 + (25 * 3 + 1 * 2)
movwf temp           ; |
loop3:
decfsz temp, f          ; |
goto loop3            ; end delay

return

; secdelay delays for one second ( 2500000 instructions )
; kloop = (2 + 254 * 3 + 1 * 2) = 766
; jloop = 2 + kloop * 255 + (3 * 254 + 1 * 2) = 196096
; iloop = 2 + jloop * 13 + (3*254 + 1*2) = 2550014 = 1.02 seconds
; x =
secdelay: ;secdelay関数(1秒を作るため)
movlw D'13'
movwf i
iloop:
movlw D'255'
movwf j
jloop:
movlw D'255'
movwf k
kloop:
decfszk, f
gotokloop
decfszj, f
gotojloop
decfszi, f
gotoiloop

return

end

---------------------------------------------------------------------


上のアセンブラをコピベだとうまくいかないことがあるので、これをダウンロードしてください。
testmidi2.asm


sendmidi関数が重要です。
ここがソフトフェア的にmidi送信する核の部分です。

もう一度書くと、
MIDIは、転送速度31.25Kbit/sec(誤差±1%)非同期シリアル転送で伝えられるデジタル信号で、各データは8ビットで構成されます。
また、スタートビット、ビット0、…ビット7、ストップビットの順番に、計10ビットで転送されます。スタートビットは論理0、ストップビットは論理1で、MIDIで1バイトを転送する際には32.0μsecぐらいが必要です。

この関数では、79サイクル毎くらいでデータを送信しています。
なので0.4μs×79=31.6μsごとにデータ送信しています。

実はmidi送信にはUART回路とかUSART回路が内蔵しているマイコンを使う場合

使わないでソフトウェア的にUART回路とかUSART回路を想定して行う場合とがあります。
マイコンでmidi送信するにはシリアル転送と同じようなものなのでUART回路とかUSART回路を使うほうが楽なんですが、実はUART回路とかUSART回路がよくわかんないので、
今回はソフトフェア的にmidi送信しています。
すこし調べて分かったら書きます。

いろいろ応用することを考えるならば、ここを理解する必要があります。

上のアセンブラプログラムを解読すれば、分かると思います。



-------test動画-------
簡単なmax/mspのパッチを作って試してみました。
pic16f84で1秒ごとにmidi信号送信

1秒ごとにmidi信号がパソコン(max/msp)送られていることがわかります。
あとは、このアセンブラをどう料理するかは、あなたしだいですよーー!

次回はスイッチに反応させます。
[PR]
by toucyy | 2006-06-25 14:21 | 自作midiデバイス
<< picマイコン Link >>


PRODUCTS


レコードでの演奏(シンセサイザー)を可能にする
"Anvs"(アンブス) - Analog Vinyl Synthesizer -

Midi信号を他出力する
"Midiv" -Midi Distributor Divider-

ターンテーブルアニメーションを可能にする
"Taf1" -Turntable Animation Flasher-

LEDを使用したトリッキーな映像制作装置
(Taf1の機能拡張版)
"Taf2" -Turntable Animation Flasher 2-



PROFILE




Toucyy

某外資系半導体メーカー勤務、その傍らDJの経験とハードウェア、ソフトウェアエンジニアリングのバックグランドを生かし活動中。自作電子楽器でLive & DJ

patlo (yamamo2 + toucyy)
picnome、picratchbox開発者yamamo2さんとユニット組み、本格的に自作電子楽器でLiveやってます。

電子楽器と音楽と人とのつながりをいろいろ考えるのが最近のはまり。

------CONTACT------
"toucyyアットgmail.com"
(メールを送信する際はアットを@に変えてください。スパム対策用です)



イベント&ライブ等


2010年5月22~23日 MTM05 出展とプレゼンテーション "anvs"
http://www.oreilly.co.jp/mtm/05/
2010年11月20~21日 MTM06 出展 "anvs modular"
http://www.oreilly.co.jp/mtm/06/
2010年11月21日 Analog Synthesizer Builders' Summit 出展 "anvs modular"
http://analog-synth.jp/summit10/e_index.html
2011年12月3~4日 MTM07  出展 "Taf"
http://www.oreilly.co.jp/mtm/07/

2012年1月14日 TMUG20 (Tokyo Max Users Group) プレゼンテーションとライブデモ
http://tokyomax.jp/?p=1670
2010年7月10日 TMUG16 (Tokyo Max Users Group)  ライブ
http://tokyomax.jp/?p=696
http://toucylab.exblog.jp/14084312/




紹介記事



もうライブで使えるレベル――DIY楽器がますます進化



10th Analog Synthesizer Builders' Summit Party



Engadget Japan



ASCII.jp 「理屈にあわない楽しさを求めて 電子楽器をつくる人の哲学」



Sampling Loveのblog



VESTAX JAPAN



メディア&SNS



twitter

YouTube

DJイベント
"Elements"

茨城を拠点にさまざまな"要素"にこだわり行っているイベント

"Ruckus
[toucylab custom ver 1.2]"



PSP用のDJソフトウェアです。 Captain Dan氏のRuckusをベースにコントロールの微調整を行いました。
Download here !
-------------------------