● 実験テーマ18
「PICによる、MIDI音源コントロールの簡単な実験」
■ 2012.08.09〜 2012.08.10
<実験テーマ17の次のテーマは何にする?>
・PIC_MIDIにしようと思う。
・市販の音源(SC-88Pro)の、MIDI_IN(DSUBコネクタ側) と、PICを、RS232Cで接続し、PICより、
MIDIメッセージを送信し 音源を鳴らす実験をやってみたい。
・目的は、MIDIデータの仕様を理解することに始まり
最終的には、SDに記録した、MIDIデータ(SMF)を、
音源に転送し 音源を鳴らすことを考えている。
また、TEMPOを、PICの指令で変えられるように出来たらと思う。
・今までは、シーケンス・ソフトにてそれらを実行していたが、
これを、PICシーケンサに置き換えようと思う。
・実験段階も、PIC24Fトレーニング基板を使う予定
・C言語のみで記述
<計画案>
STEP 1: ・MIDIの初期化と、発音までのメッセージ仕様を理解する。
STEP 2: ・ピアノの中央Cの音を1つだけ鳴らす、メッセージを考える。
STEP 3: ・メッセージが解れば、そのテーブルを、RS232C送信するだけでよいのでは?
ここで、以前作った、232Cテーブル送信器にてそれを送信してみれば・・・・
・暫くは、電子工作の出費を抑えるため、調べごとに時間をかけようと思う。
気長にやりましょう。
→ 「詳細MIDI規格」というタイトルの、WEBページは現在無いようである。
当該WEBページには接続できるが、ページを表示するアクセス許可がないらしい?
→ 音を鳴らす簡単な例が、WEBページに載っているが、ASMで書かれている。
→ データビットの送り順は、通常通リ、B0から
→ MIDI音源の受信ポートに、PICから送信するので、RS232Cクロスケーブルが必要
■ 2012.08.29
・チャイム音発生実験の時、使用した「任意コード発生治具」を使って、MIDIメッセージを送信してみる。
治具のハードはそのままで、ソフトのみMIDIメッセージ対応に変更すればよいはず。
・その前に、RS232Cボーレートを、MIDIのボーレート:31250bpsに変更する
必要がある。
前回は、9600bpsにしてあるので、これを以下の通りに変更した。
///
Initialize UART1: 31250bps, 8Bit, Non Parity, Non Control Flow
//U1BRG = 103; // 9600bps@Fcy=16MHz:Value of U1BRG= (16M/16x9600)-1
U1BRG = 31; // 31250bps@Fcy=16MHz:Value of U1BRG= (16M/16x31250)-1
U1MODE = 0b1000100000000000; // UART1 Mode Set: UARTEN,RTSMD= '1' Other
Bit= '0'
U1STA = 0b0000010000000000; // UART1 Status Set:UTXEN= '1' Other Bit=
'0'
・また、MIDIメッセージのデータテーブルとして次の、5つのメッセージを用意した。
メッセージ送信前に、ディプSWを目的のメッセージ番号にセットし、送信ボタンを押すとそのメッセージが送信
されるようにした。
そうすれば、各メッセージ毎の機能確認が可能になる。
以下に、その部分の、Cソースを示す。
///MIDI
MESSAGE Table
const char midi_msg1[] =
{0xF0,0x41,0x10,0x42,0x12,0x00,0x00,0x7F,0x00,0x01,0xF7}; // System Mode Set for
SC-88
//const char midi_msg2[] = {0x08,0x03,0x00}; // Instrument Set: Piano 1w(最初のmidi_msg2の設定は誤りで修正した)
const char midi_msg2[] = {0xB0,0x00,0x08, // Bank Select MSB= 8
0x00,
// Delta Time
0xB0,0x20,0x00, // Bank Select LSB= 0
0x00,
// Delta Time
0xC0,0x00}; // Program Change = 1
const char midi_msg3[] = {0xB0,0x00,0x01, // Bank Select MSB=
1
0x00,
// Delta Time
0xB0,0x20,0x00, // Bank Select LSB= 0
0x00,
// Delta Time
0xC0,0x049}; // Program Change = 74(Flute2:)
const char midi_msg4[] = {0x90,0x3C,0x64}; // Note ON: CH1,
C4, VOL=100
const char midi_msg5[] = {0x90,0x3C,0x00}; // Note OFF: CH1,
C4, VOL=0
■ 2012.08.30
・Cソース作成済
コンパイルOK
・音源との、RS232C接続確認
・音源の、COMPUTER端子仕様の切替SWを、PC-1(31.25Kbps)にする必要がある。
尚、PC-2にすると対応転送速度が、38.4Kbpsになる。
・動作確認
まずはダメ
midi_msg2を送信しても、Piano 1wに変わらない。(音源のLCD表示で確認できる)
・しかし、midi_msg1のシステムモードセットは上手くいっているようで、送信すると
音色が、piano1に設定される。
(その他の、VOL等のパラメータも初期化される。)
・3番目のメッセージ:NOTE ONで、音源LCDのトラック1の音量レベル・バー表示しているが、NOTE
ONなので、NOTE OFF
まで鳴りっぱなしになるのかなと思いきや、約2秒位で鳴り止んだ。(バー表示消えた)
よって4番目の、NOTE OFFの確認が出来ない。
・2番目のメッセージ(バンク切替+プログラムチェンジによる音色切替)の送り方に問題があると思い、WEB検索してみた。
→ まず基本的に、各コマンドに相当するMIDIでは、ステータスバイトと呼ばれる、BYTE列が抜けていた。
(今までは、データを並べていただけ)
つまり、データの前に
バンクセレクトMSBのステータス_2BYTE= 0xB0, 0x00
バンクセレクトLSBのステータス_2BYTE= 0xB0, 0x20
プログラムチェンジのステータス_1BYTE=0xC0
を追加した。
→ それから、各ステータス+データ送信の間には、デルタ・タイムと呼ばれるインターバルのための、0x00送信が必要
なことも判明、それを追加した。
■ 2012.08.31
・昨日の変更で、見事に音色切替(Piano
1→ Piano 1w)に成功した。
・もう一つの疑問として、3番目のメッセージ:NOTE
ONで音を鳴らした場合
NOTE OFFまで鳴りっぱなしになろと思いきや、約2秒位で鳴り止んでいることが挙げられる。
→ 今はピアノ音を指定しているので、NOTE ONするとピアノは減衰音としてサンプルされているので、それを再生すると、
次第に鳴り止むのかもしれない。
→ 試しにフルート音のするメッセージも追加して試すことにした。
(持続音をサンプルしたデータが音源ROMに入ってると仮定すれば、NOTE
ONで鳴りっぱなしになるはずである。)
※ 何時も、MIDI制作で使っているフルート音(Flute2:)にするにはプログラムチェンジのデータを
0X49(音色番号:74(実際にデータセットする時は、74-1=73=0x40をセットする必要あり)
にするだけで良いはず。
■ 2012.09.01
・昨日のメッセージ追加で、見事に音色が、「Flute2:」に切替わった。
→ NOTE ONすると鳴りっぱなしになることを確認した。
→ ここで、NOTE OFFすると鳴り止むことも確認できた。
・これで、STEP1〜3の目標は達成できたので、本件はクローズすることにする。
<最終ソース>
・こちらから、どうぞ→ midi_message_generator.c