電子工作

PICでMIDICV

RJBさんのPICによるMIDICVのハードウェアに新しくソフトを載せてみようという試みです。

使っているCPUはPIC16F648A。これのCCPモジュールを利用してPWMを発生し、フィルター、オペアンプを通してアナログシンセ制御用のCVの発生します。同時にGATE信号も生成。また、ADのVREFを利用してモジュレーションにも対応しています(16段階)。

CCPでのPWMの精度は8bitでなく、10bit。そこで、ピッチベンドとノート番号からCVを合成しています(ピッチベンドの解像度は1/8半音程度)。


発音の優先順位処理

単純なハードウェアとは言え、1CHのモノラルシンセの制御となるので、それなりに、複雑な問題が出てきます。MIDIでモノラルシンセを制御する場合の大きな問題は、キーの優先順位の問題。

一番簡単な処理は、単純な後着優先処理。一番最後に来た音程をそのまま常にCVに出力するもの。この場合でも、さらに、GATEの処理をどうするかを考える必要があります。「ド」を押している最中に「ミ」を押した場合、GATEを一旦オフにしてから再度GATEをオンにするリトリガー処理と、GATEはそのまま継続させるレガート処理の二通りが考えられます。

リトリガー処理の場合の問題点はGATEをオフする時間の長さ。新しい音が入ったときに、GATEをオフ、その直後にGATEをオンにすると短すぎて、シンセ側のEGが反応しない可能性があります。このため、GATEオフ後、一定時間(多分数ミリ秒)待ってから新しい音の処理をしなければなりません。この待ち時間がMIDIの1音の受信間隔(最小で0.6ミリ秒程度)より長いと、次々に音が入った場合にバッファに保持できなくなる可能性があります。

この単純な後着優先処理だとモノラルのシンセを演奏した場合に、不満が出ます。トリルなどの演奏が難しくなることです。「ド」を押して、「ミ」を押し、「ミ」を離して、最後に「ド」を離す。こうしたときに、「ド-ミ-ド」となると、トリルの演奏が簡単になるわけです。アナログシンセの鍵盤では鍵盤の回路方式によって、低音優先か高音優先となっています。これを利用してトリルなどが簡単に演奏できるわけです。高音優先の場合は、「ド−ミ−ド」はここで書いたとおりに動作しますが、低音優先の場合は音程が「ド」のままです。逆に「ミ−ド−ミ」のトリルは低音優先がうまく働きます。

そこで、せっかくソフトで処理するのだから、トリルが低音側、高音側のどちらでもうまく働くようにしたい。つまり、トリルを想定した後着優先処理が望ましい処理となります。この処理は、現在押されているキーを覚えておいて、常に現在押されているキーのうち一番新しいものの電圧を出力するという方法で実現できます。メモリが十分かつ高速なCPUならば、全部のキー(128)まで覚えるようにすればいいのですが、ここで想定しているPICでは、ちょっと荷が重そうです。そこで覚えるキーの数を例えば8個程度に制限して、それを越えて入ると、古いものから順に忘れてしまうという男性的な仕様が実用的かと思われます。

と、ここまで書きながら… RJB さんのインプリメントの高音優先処理(アナログシンセですね)は、コンパクトだし、使いやすそう。当座、こちらがいいかな。


ハードウェアの製作(その1)

ひとまずは、ブレッドボード上で回路を作成。回路は RJB さんのほぼコピー。CPUは PIC16F648A です。少しだけ、手持ち部品の関係で変更しました。

  1. 電源は±15V+5V。とりあえず、±15Vは、スイッチングACアダプタ使用のなんちゃって電源。+5vは実験用のスイッチング電源。
  2. フォトカプラは、シャープのPC910を使用。これに伴ってちょっとだけ回路が変わります。
     MIDIの入出力回路は毎回製作すると面倒なので、専用の実験ボードを作りました。
  3. RJB さんは 20MHz の水晶発信子を使っていらっしゃいますが、ここは、20MHzのセラロックで代用。PIC-PSGで動いたのだから、たぶん、大丈夫でしょう。
  4. オペアンプについているスケール調整用の 2k のトリマー。半固定抵抗で大丈夫なようです。
  5. フィルターの係数は、試行錯誤が必要かもしれません。RJB さんの図面でも、簡易版は10kΩと0.022μFの三段フィルター。Ver.2の方は、15kΩと0.01μFの三段フィルター。とりあえず、簡易版と同じにするつもりです。ここのコンデンサはフィルムを使った方がいいのかな。
  6. ポルタメントの部分。これが付くって素敵ですよね。これも、簡易版とVer.2とで定数が違いますが、とりあえず、簡易版に合わせて、0.22μF+1MΩボリューム。これもフィルムコンデンサかしら。
    takedaさんのインプリメントだと、これは、外せるようになっていますね。ポルタメントを使わないときにも、大きなコンデンサが悪さをするのかも知れません。
  7. ゲートのトランジスタのベースから、グランドへ抵抗を入れた方がいいかも。(パワーオン対策)
  8. リファレンス電圧を利用したモジュレーション機能。takedaさんがトランジスタのバッファをつけていらっしゃいます。これを付けて見るかな。

端子関係を整理してみます

RJBさん版
信号i/o用途備考
RA0oLED DRIVEGATE モニタ
RA1oLED DRIVEERROR モニタ
RA2oVREF OUTMODULATION CVOUT
RA3(io)nc
RA4(io)nc(out,od)
RA5(i)nc(input only)
RA6-xtalセラロック20MHz
RA7-xtal同上
RB0(io)nc
RB1iRXMIDI入力
RB2oTXMIDI出力
RB3oCCP1KEY-CVOUT
RB4oGATE OUTGATE SIGNAL
RB5(io)nc
RB6(io)nc
RB7(io)nc
変更案
信号i/o用途備考
RA0oLED DRIVEGATE モニタ
RA1oLED DRIVEERROR モニタ
RA2oVREF OUTMODULATION CVOUT
RA3onc予備のゲート端子
RA4onc(出力はオープンドレイン)予備のゲート端子
RA5iSW?(input only)ゲート極性指定
RA6-xtalセラロック20MHz
RA7-xtal同上
RB0iDIPSW b0受信チャンネル指定
RB1iRXMIDI入力
RB2oTXMIDI出力
RB3oCCP1KEY-CVOUT
RB4oGATE OUTGATE SIGNAL
RB5iDIPSW b1受信チャンネル指定
RB6iDIPSW b2受信チャンネル指定
RB7iDIPSW b3受信チャンネル指定

 RJBさんのピンアサインとぶつからないように割り振りました。

  1. 受信チャンネルはRB6-RB5:RB0の4ビット。電源オン時にチャンネルを確定します。DIPSWをつければ、変更が容易。

    当初はプルダウン抵抗を使用するつもりでした。スイッチはVCCとの間に入れます。たぶん、チャンネル0とか1しか使わないだろうから、ほとんどのスイッチはオフ。このときには電流がほとんど流れません。

    ところが、回路節約のために、内蔵のWeakPullupを使うことに方針転換。スイッチは端子とグランドの間に設け、オフでレベルH,オンでレベルLとなります。プログラムではビット反転してチャンネルを決めます。さて、WeakPullupがうまくいくかどうか…

    チャンネル固定の場合には、オープンがそのビットを0に、,GNDに落とせば、そのビットが1になります。

    また、RB7:RB5をオープンにして、RB0にスイッチをつければ、チャンネル1とチャンネル2の切り替えが出来ます。

  2. RA3とRA4は出力に設定して将来の GATE出力予約にします。MIDI CLOCKを出力するとか、コントロールチェンジでオン・オフする。あるいは、ポルタメントオンオフ指定などが候補ですが、現在は決めずにNC(未結線)とします。
  3. RA5は、本来はリセット端子。ポートとしては入力専用です。予備ポートも含めたゲートの極性をここで指定します。この端子はプルアップします。スイッチはグランドとの間に入れます。スイッチオフで、正極性(ローランド式)。スイッチオンで負極製。ゲート極性指定スイッチが不要ならば、スイッチを省略すれば、RJBさんの仕様に合った正極性となります。
  4. TXは使うかどうかを別にして、一応、MIDI出力配線をして端子に立てておくと良さそうですね。当面はNCでも大丈夫。
  5. 電源は迷うところです。両電源のオペアンプを使うと、±15VとPIC用に+5V。三電源があれば、それで十分です。5Vは+15Vからレギュレータで作るのも可能。

    単電源のオペアンプを使うと、+15VをスイッチングACアダプタで供給して、+5Vはレギュレータで作ればそれで間に合う。ただ、グランド近辺のリニアリティと、出力が負に引っ張られたときの破損がちょっと心配です。

    回路は大差ないので、作るときに選択できるようにしておけばいいですね(無責任)。

実はCPUをPIC16F88に変更すれば、チャンネル指定はボリュームで出来るじゃないか、とも考えもあるのですが…


ハードウェア製作(その2)

手配線で一号機を製作しました。

部品の主要部分は秋月のC基板(15x25穴)。LED、DIPSW、ゲート極性スイッチは、パネルに置くつもりなので、一応、小さなパネル基板に配置。LEDは、配線の都合上、RJBさんの基板と逆で、グランドに落とすようにしました(これは、ソフトでRJBさん版にも対応予定)。ゲートスイッチ、チャンネルスイッチは省略も可能です。全部配線しなければ、正極性ゲートで、チャンネル1固定となるようになっています。

パネル基板と主基板は、ジャンパー飛ばして繋いでしまったのが醜いところ。他はコネクタを使いました。MIDI OUTを装備しているので将来の拡張にも余裕です(???)。オペアンプの1ピンと5ピンを繋ぐジャンパーが異様に長いのは、将来、ここにハサミを入れて、ポルタメント回路を挿入するためです。

ブレッドボード版で作成したプログラムを載せてみたところ、ハードウェアはうまく動作しているようです。

必要な調整は一箇所のスケール調整ボリューム。ここは、ケチをして半固定抵抗を使いましたが、スペースを考えても、多回転トリマーにすればよかったと後から反省。シーケンサからC3(60)を出して3Vに調整。以降、C0(24)が0V、C1が1Vと順に確認して、全体にバランスよくなるようにします。

とりあえず、オペアンプはLM358Nにして、電源は+15V単独。-15V電源端子はコネクタでグランドに落としておきます。

両電源タイプのオペアンプ(TL072など)を使う場合には、電源を±15V供給すればそのまま動きます。

作り終えてみると、特に単電源のとき、保護回路入れなくちゃいけないなと思ったりします。たぶん、KeyCVに-15Vが繋がるとオペアンプを破損。-15V(単電源でのGND)とKeyCVの間にダイオードを入れればいいと思うのですが、電流のリークなどもあるので検討が必要かな。こういう危なっかしいところも、自作の楽しみで、まぁ、いいかな。


主な仕様

主な仕様は次の通り。

  1. モノラル(当たり前ですね)。16チャンネルから一つをスイッチで指定。
  2. 発音範囲:C0(24)以上。(SX-150 SW 汎用指定時)
  3. 高音優先。
  4. 出力は、KEY-CV、GATE、MODULATION-CV/VELOCITY-CV

    MODULATION-CV/VELOCITY-CVはEEPROMオプションで切り替え。デフォルトでMODULATION-CV。

  5. KEY-CVは、C0(24)が0Vで、V/Oct。C3(60)が3Vに相当(SX-150 SW 汎用指定時)。KEY-CVにはピッチベンドが加算される。ピッチベンドの加算はEEPROMオプションで無効に出来る。
  6. GATEは正極性(ローランド式)、負極製(コルグ式)のいずれかをスイッチで指定。

    端子RA5オープンで正極性、ショートで負極性。

  7. MODULATION-CV/VELOCITY-CVは,VREF機能を利用した16段階。現状の回路では0-2.7V程度の範囲で変化。
  8. ピッチベンドの分解能はPWMを10ビットで使用しているため、1/8半音。ピッチベンドレンジのデフォルトは2(全音)。
  9. ピッチベンドレンジの指定はRPNを使用する。有効なベンドレンジは 0 - 12。

    RPNを利用したメッセージ入力は次の通りです。

    Control Change番号メッセージ(16進)
    RPN LSBCC#1000Bn 64 00レジスタード・パラメータ番号は
    MSB、LSBともに0
    RPN MSBCC#1010Bn 65 00
    DATA ENTRY(MSB)CC#6ベンド幅(0-12)Bn 06 vv半音単位で指定
  10. ゲート極性スイッチ、EEPROMスイッチは電源オン時に読み取る。
  11. チャンネル指定スイッチは動作時に変更可能。
  12. ERR,GATEモニターの二つのLEDのCPUでの極性はEEPROMスイッチで切り替えることが出来る。

スイッチの動作

  1. EEPROMスイッチ

    ハードウェアとの関係で指定する通常使わない機能をEEPROMの0番地で指定する。デフォルトの値は0xFF。

    秋月のライターでは、EEPROMの内容を手で変更できるので、この機能を使用して変更すると便利です。

    ビット名称値=1値=0
    b0LED_DRIVE1:正極性ドライブ0:負極性 二つのLED(GATE、ERROR)のPICのピンでの極性。
    ここで紹介した回路では、正極性。RJBさんの回路では、負極性を選択。
    b1PITCHBEND1:使用する0:使用しない KeCVにピッチベンド電圧を加えるかどうか。この機能は、現行版、および、V1.02betaでは機能しないことが発覚しています(常にピッチベンドが有効)。
    b2VREF1:MODULATION0:VELOCITY VREF端子の用途。
    b3CHANNEL SW1:オリジナル
    RB7_RB6_RB5_RB0
    (b3b2b1b0)
    0:takeda式
    RB0_RB7_RB6_RB5
    (b3b2b1b0)
    受信チャンネル番号とDipSwの対応。
    b4SX-150 SW1:汎用0:SX-150対応 学研シンセ「SX−150」のCVレンジに合わせる場合に0を指定。内部のキーシフトが無効になる。V1.05以降でのみ指定可能。
  2. GATE極性スイッチ

    端子 RA5(外部でプルアップすること)に接続したスイッチでGATE出力の極性を指定します。

    極性
    オープン正極性。GATEON:+15V GATEOFF:0V
    クローズ(GND)負極性。GATEON:0V GATEOFF:+15V
  3. チャンネル指定スイッチ

    16のチャンネル指定に4ビットのポートが用意されています。各スイッチはオープンで値1、クローズで値0を表します。従って、16チャンネル全部を使用しない場合には必要な端子にだけスイッチを使用すればよいことになります。

    ポートのビット解釈は、EEPROMスイッチにより、標準とtakeda式の二通りを切り替えます。

    標準
    チャンネル・ビットb3b2b1b0
    CPU端子RB7RB6RB5RB0
    takeda式
    チャンネル・ビットb3b2b1b0
    CPU端子RB0RB7RB6RB5

ソフトウエア製作

仕様の拡張と、バグ対策を続けています。

  1. V1.02beta

    動作中のチャンネル切り替えに対応。ついでに、予約済みのポートに、Sustain(ダンパーペダル)とポルタメントのOn/Offを割り付けました。

  2. V1.03beta  EPROMスイッチのうち、KEYCVにBEND情報を加えるか否かを決めるものがあるのですが、これが有効に動作していませんでした。
  3. V1.04

    高音域でマイナス側のピッチベンドの処理にバグがあったので対処しました。

  4. V1.05

    CVをSX-150のレンジに合わせるオプションを追加した版。汎用版としては未検査です。

検討中の機能

  1. TX(シリアル出力)の活用

    せっかくつけたシリアル出力を生かしたいと思います。ちょっと、思いついたのはチャンネルフィルター&コンバータ。

    PIC-MIDICVでの受信チャンネルに一致したチャンネルメッセージをTXからチャンネル1に変換して出力。こうすれば、2台目以降のMIDICVは受信チャンネル固定で使えます。TX出力はMIDI出力を想定しているので、220オームの抵抗が直列に入っていますが、それを2台目のRXに入れても、多分動作するでしょう。となれば、2台目以降はフォトカプラーも省略できる。

    2台目以降を例えば、コントローラ系のCV専用とすれば、主要な部分は8ピンのPIC+オペアンプでのコンパクトなモジュールに出来そうです。コントローラ系ならば出力電圧はアバウトでよいと考えれば、調整回路も不要だし、場合によってはオペアンプを省略しても(安全ではありませんが)良いかもしれません。コントローラの出力を正負に振るとすれば、2電源でオペアンプでのレベルシフトが必要になるかも。


ハードウェア製作(その3)

ケース、作らなくちゃ。

こればかりは、夜中に作業というわけにはいかないし、ケースに入れるとCPUのプログラミングが面倒になりますね。(ソフトをいじっている間は、ケースがあっても、結局、外に出していたり…)


ハードウェア -検討事項-

ここまでは、とりあえず、動作することを目標にクローン回路を組み立てましたが、何点か検討したいこともあります。

  1. LowPass Filterの検討

    アクティブフィルタでもっと急激に処理するのも可能かもしれません。RJBさんの新しいほうのMIDICVではアクティブフィルタを使っていらっしゃいます。

  2. Key-CVのレンジを広げる

    現在の対応範囲は、C0(24)より上の音しか出ません。CPUの出力がGND-5Vで、これをストレートに増幅するために、範囲を限定しています。この範囲の限定を取り外したい。このためには、後ろのオペアンプでレベルシフトも処理して、負の電圧も出るように回路を変更する必要があります。シフト電圧を正確に計算して作り出すのが、ちょっと、面倒。

    また、他の目的でCVを作るときにもこの処理は必要です。KEY-CVとシフト量が変わるのがちょっと、悲しいです。

    それに、この場合は、単電源でオペアンプを使えなくなるので、回路を、現在のものと二通りに分ける必要がありそう。

この検討は、まだ、すこし、時間を置いて行いたいです。


ソフトウエア製作(寄り道)

PIC-MIDICVでは少ない機能とは言え、扱わなければならない、MIDIのコントロールチェンジについてまとめてみます。

まずはお決まりの一覧表から。

;
0バンクセレクト(MSB)
1モジュレーション・ホィール
2ブレス・コントローラ
3未定義・予約
4フット・コントローラ
5ポルタメント・タイム
6データ・エントリー(MSB)
7チャンネル・ボリューム
8バランス
9未定義・予約
10パンポット
11エクスプレッション・コントローラ
12エフェクト・コントロール 1
13エフェクト・コントロール 2
14未定義・予約
15未定義・予約
16汎用コントローラ 1
17汎用コントローラ 2
18汎用コントローラ 3
19汎用コントローラ 4
20未定義・予約
21未定義・予約
22未定義・予約
23未定義・予約
24未定義・予約
25未定義・予約
26未定義・予約
27未定義・予約
28未定義・予約
29未定義・予約
30未定義・予約
31未定義・予約
32バンクセレクト(LSB)
33LSB of cc 1
34LSB of cc 2
35LSB of cc 3
36LSB of cc 4
37LSB of cc 5
38LSB of cc 6
39LSB of cc 7
40LSB of cc 8
41LSB of cc 9
42LSB of cc 10
43LSB of cc 11
44LSB of cc 12
45LSB of cc 13
46LSB of cc 14
47LSB of cc 15
48LSB of cc 16
49LSB of cc 17
50LSB of cc 18
51LSB of cc 19
52LSB of cc 20
53LSB of cc 21
54LSB of cc 22
55LSB of cc 23
56LSB of cc 24
57LSB of cc 25
58LSB of cc 26
59LSB of cc 27
60LSB of cc 28
61LSB of cc 29
62LSB of cc 30
63LSB of cc 31
64ホールド
65ポルタメント オン/オフ
66ソステヌート
67ソフトペダル
68レガート・フット・スイッチ
69ホールド 2
70サウンドコントローラ 1 (サウンド・バリエーション)
71サウンドコントローラ 2 (ティンバー/ハーモニックコンテンツ)
72サウンドコントローラ 3 (リリース・タイム)
73サウンドコントローラ 4 (アタック・タイム)
74サウンドコントローラ 5 (ブライトネス)
75サウンドコントローラ 6
76サウンドコントローラ 7
77サウンドコントローラ 8
78サウンドコントローラ 9
79サウンドコントローラ 10
80汎用コントローラ 5
81汎用コントローラ 6
82汎用コントローラ 7
83汎用コントローラ 8
84ポルタメント・コントロール
85未定義・予約
86未定義・予約
87未定義・予約
88未定義・予約
89未定義・予約
90未定義・予約
91エフェクト1デプス (外部エフェクト)
92エフェクト2デプス (トレモロ)
93エフェクト3デプス (コーラス)
94エフェクト4デプス (セレステ)
95エフェクト5デプス (フェイザー)
96データ・インクリメント
97データ・デクリメント
98NRPN LSB
99NRPN MSB
100RPN LSB
101RPN MSB
102未定義・予約
103未定義・予約
104未定義・予約
105未定義・予約
106未定義・予約
107未定義・予約
108未定義・予約
109未定義・予約
110未定義・予約
111未定義・予約
112未定義・予約
113未定義・予約
114未定義・予約
115未定義・予約
116未定義・予約
117未定義・予約
118未定義・予約
119未定義・予約
120オール・サウンド・オフ
121リセット・オール・コントローラ
122ローカル・コントロール
123オール・ノート・オフ
124オムニ・オフ
125オムニ・オン
126モノ・モード・オン
127モノ・モード・オフ

まず、最初に注意しておかなければいけないのは、大きなメッセージの枠組みと違い、ゆるやかな規定であることです。歴史的な経緯を経ながら、現実に合わせて、次第にコントロール番号の用途が決まってきました。基本的にはどのコントロールで何をしようが、楽器の勝手なのですが、そこはそれで、ある程度、お互いに合わせた方がいい。そのガイドラインのようなものです。古い楽器が登場した頃には決まっていなかったものも沢山あり、時代が進むに従って、だんだん、対応するコントロール番号が増えてきたのです。また、コントロール番号での動作の詳細もそれぞれの楽器によって当然ながら異なります。

大きな枠として、0-119の本来のコントロールチェンジと120-127のチャンネルモードの区分があります。

チャンネルモードは、動作の大枠を決めるもので初期設定や、緊急停止的な特殊なメッセージです。124-127が発音モードその他を決めるのですが、現在のマルチティンバーのシンセでは、時代遅れな感じで、これらのメッセージをそのまま、インプリメントしているものはほとんど無いと思います。122は、鍵盤付き音源で鍵盤と音源の接続を決めるもの。120、121、123は緊急停止的に音を止めたりするリセットのようなものです。123で止めた場合にはゲートオフされるだけで余韻は残るが、120で止めた場合には余韻も含めて無音にするなど違いが示されていますが、現実に対応するかどうかは、楽器によって異なります。特に、120と121は、かなり、後になってから決められたので、この番号を通常のコントロールチェンジとして使用している楽器もあります。ここでは深く触れません

ここからが本来のコントロールチェンジについて。

コントロールチェンジのメッセージは、コントロール番号と、値の二つの組合せで出来ています。指定の制御番号にある値を送る。それだけですが、基本的な値の表し方について決まりがあります。例えばホールド(サスティン)つまり、ピアノのダンパーペダルのメッセージのようにオン/オフの二値しか取らない場合、送り出し側は、オンで0x7f(127)、オフで0x00(0)を送ります。受け取り側は、0x40(64)以上ならばオン、未満ならばオフとします。

連続値を扱う場合には二通りあります。コンピュータで言うところの符号無しの値は、そのまま、0x00 - 0x7f で扱います。符号付の値、つまり、正も負もとりうる場合には、0x40(64)を0にした下駄履き表現を使います。 0x7f は +63 を表し、0x00 は -64 を表します。日常の表現からコントロールチェンジの符号表現に変換する場合には、0x40(64)を加えます。コントロールチェンジの符号表現を日常の表現に戻す場合には、0x40(64)を引きます。

コントロールチェンジでは値の幅が7ビット(128段階)ですが、二つのコントロールチェンジを組み合わせて14ビット(16384段階)の精度で表す方法が決められています。コントロールチェンジ番号の0-31に対して、それに32を足した32-63が拡張部分として定義されています。もともとの0-31番のコントロールチェンジで上位バイト(MSB)を指定し、32-63で下位バイト(LSB)を指定します。

モジュレーション(CC#1)を例に挙げます。モジュレーションでは、MSBがコントロール番号1.LSBがコントロール番号33となります。二つを組み合わせて、MSB x 128 + LSB が値となります。

新しい音源が2バイト精度のモジュレーションに対応しているとき、1バイト精度しか対応しない鍵盤を繋いでも、LSBは常に0として処理するのでうまく動作するように考えられています。

実際は、二つのメッセージのタイミングによっては、不正な動作をすることが考えられるので、2バイト精度のメッセージは難しい問題をはらんでいます(論理的な動作だけなら問題は無いのですが…)。

本来はコントロールチェンジとは言えないコントロールチェンジが一つ混ざっています。バンクセレクト(CC#0)がそれです。プログラムチェンジが0-127の128通りの音色しか扱えないので、これをバンク切り替えでサポートしようという考え方です。MSB -- CC#0 -- だけを使えば、128バンク。LSB -- CC#32 -- を併用すれば、16384バンクの音色切り替えが出来るという仕掛けです。バンク切り替えのメッセージを置く場所が無かったので、ここに割り込んだ形です。

ポルタメント・コントロール(CC#84)は、シーケンサ専用ともいえるコントロールで、異色のものです。値としてはノート番号を指定し、このメッセージの後の(同一チャンネルでの)最初のノートオンで発音する音は、ここで指定したノート番号からポルタメントがかかります。音源によっては、指定した元の高さの音が発音中ならば、そこからレガートにポルタメントがかかるものもあるようです。サポートしていない音源も多いので、使いにくいコントロールの典型です。

一般的なコントローラを駆け足で書き出してみます。

モジュレーション・ホイール(CC#1)ブレス・コントローラ(CC#2)フット・コントローラ(CC#4)。初期のシンセのコントローラ・デバイスをそのまま踏襲したもの。何に使うかは、それぞれ、シンセ次第ですが、LFOの深さが普通です。

チャンネル・ボリューム(CC#7)エクスプレッション・コントロール(CC#11)。両方とも音量制御に使われることが多いです。慣習的には、ミキサーのボリュームに相当するのがCC#7、演奏者が盛り上がったりするのがCC#11といったところ。

パンポット(CC#10)はミキサーでのパンポット。つまり、音量的に左右のどこにおくかを決めます。これは、大抵、左が0で、中央が64、右が127。実は左右の段階数が等しくないので、0がランダム、1が左端…という面白いものもあります。

ポルタメント・タイム(CC#5)ポルタメント・オン/オフ(CC#64)ポルタメント・コントロール(CC#84)はいずれもポルタメント制御。ポルタメントの時間をCC#5で指定。CC#64でオン/オフするか、CC#84で細かく制御。いずれにしても、音源方式や、機種に非常に依存します。

バランス(CC#8)は、インプリメントされている割に、知られていないもの。何のバランスだと突込みがはいりますよね。二つの音色の音量バランスだそうです。ストリングスとブラスをレイヤーで割り振っておいて、バランスで両方の割合を調節する。そういうイメージで使われていました。案外、驚きの機能がインプリメントされている機種もあります(説明無しです!)。

ペダル・コントロール、つまり、ピアノのペダルを意識したメッセージは、ホールド(CC#64)ソステヌート(CC#66)ソフトペダル(CC#67)、レガート・フット・スイッチ(CC#68)、ホールド2(CC#69)。ホールド(CC#64)はピアノのダンパーペダルで、オンにするとダンプが効かなくなる。つまり、キーを離してもミュートされずにリリースが残る機能。ソステヌート(CC#66)はソステヌートをオンした瞬間にキーが押されている音だけリリースが残る。ドミソを押しているときに、ソステヌートを踏み込むと、ドミソはソステヌートを離すまで鳴り渡るけれど、この間にレファラを打鍵しても普通にミュートされる。ソフトペダル(CC#67)は踏むとピアノのメカが左右に移動して(だったかな?)、ハンマーが叩く弦の数が減り、音がソフトになるというもの。後の二つは、一般的ではありません(説明がきちんと書いていない音源もあります)。

制御するコントロールの数が128じゃ足りないだろうというときのために、RPNNRPNという仕組みがあります。どちらも、パラメータ番号をコントロールチェンジで送って、さらに、値を送るという大げさなもの。RPNが番号を共通で決めておく仕掛け。NRPNは楽器毎に適当に決めて言いという仕掛け。RPNとNRPNは番号指定のコントロールチェンジが違うけれど、値の送り方は同じ方法です。出力した値は、RPNかNRPNか、直近のどちらか一方の値と解釈されます。

RPN/NRPNともこれだけだと128種類の拡張にしかなりませんが、例のLSBを指定する仕掛けが考えられているので、都合16384種類指定できます。また、値の方も、同様に2バイト精度まで用意されています。

パラメータ番号を指定して、それから、値を送るのが使い方。番号が変わらなければ、値だけを送れます。

番号の指定は、RPNならば、RPN LSB(CC#98)RPN MSB(CC#99)。NRPNならば、NRPN LSB(CC#100)NRPN MSB(CC#101)。順番は上下問わないことになっています。

値を送るのは、RPN/NRPNともに共通で、基本的には、データ・エントリー(CC#6)。二バイト精度ならば、さらに、データ・エントリー LSB(CC#38)を併用します。このほかに、データ・インクリメント(CC#96)データ・デンクリメント(CC#97)があります。名前の通り、現在の番号のRPNなり、NRPNを増加、減少させるのですが、その単位その他についての規定はありません。(このDATAENTRY、DATAINC、DATADECってDX7の音色編集用コントローラなんですよね)

プログラムを作るとき、気をつけるのは、番号未定義状態では、データを無効にすること。知らない番号のデータも無効にすること。今回のようにNRPNを使わないときでも、NRPNが来たら、知らないものとして以降のデータを無効にしなければいけません。

番号未定義にするのは、起動時のほか、オールノートオフなどのモードメッセージのとき。細かいことは色々あるけれど、とりあえず意識しておかないと、面倒なことになります。

延々と何を書いたかというと、ピッチベンド幅をRPNで指定するためには、ここまで、インプリメントが面倒だということなのでした。


パネルインタフェース

今回作成したハードウェアのインタフェースはチャンネル指定にDIPSWを使用していましたが、チャンネル選択をロータリスイッチで行い、さらに、7セグLEDでのチャンネル表示をする準備をしています。こちらは、「PICピカピカ」の中で試作が終わっています。


8ピン版の模索

16F648A(18pin)が出来上がっていないのに、何だといわれそうですが、最小構成のハードウェアで動かしたいと思っています。1CV、1GATE(場合によってはGATEなし)でモジュール的に使えないかと考えているわけです。ソフトウェアは16F648A版でのMIDIシステムを修正して使用。

USARTがないので、ソフトウェア・シリアルで対応。外部クロックで動かすとすれば、発振器で2ピン使って、残りが4ピンです。CV出力(CCP)、GATE出力、シリアル用入力ポート(ソフトウェアシリアルですね)で、3ピン。端子がバッティングしなければ何とか足りそう。

もし、内蔵RCで出来れば、さらに、セラロックが不要になるし、ピンも余裕が出ます。速度が遅くなるので、どこまでカバーできるか。といったところ。

デバイスは、手持ちの8ピンPICから選ぶと、12F683となりそうです。これを前提に、機能を検討してみます。

  1. クロック

    ソフトウェアでMIDI入力を扱うと、1ビットが32μS。内蔵発振では最大8MHzなので、この間に処理できる命令の数が、64命令。外付けの20MHzにすれば、160命令。

    この間に処理できないと、受信こぼれが出るので、どちらを取るか、微妙なところです。とりあえずは、外付けでプログラムを書いてみて、余裕があれば、内蔵に切り替えたい。

  2. ソフトウェアシリアル処理。

    よくある、ソフトウェアシリアル処理のように、他の処理を実行中に受信できないようだと、使い物になりません。大まかには、ピンチェンジ割り込みで、シリアル処理開始のトリガーに。ピンチェンジ割り込みはここで取りやめ、1ワード受信するまでは、タイマー割り込みでポートスキャン。読み込んだデータはFIFOにセット。タイマー割り込みをやめ、再び、ピンチェンジ割り込みで次のデータを待つ。

    タイマー割り込みの時間をきちんと作れるかが、一つの問題になりそうです。

    また、ピンチェンジ割り込みも、条件面で気がかりな点があるのですが…。

    648A版と大きく異なるのは、MIDIのデータ処理自体は、割り込み中で行わなず、地面でFIFOからデータを取りながら処理する。このため、割り込み内のFIFO詰め込みと、地面でのFIFOからの取り出しの時間がペナルティになる部分。

  3. CCP、ゲート。

    CCPによるPWMとゲート出力は648Aと同様の処理で十分。ただし、割り込み処理内ではなく、地面で実行する。

  4. 648Aと同様のVREFの機能を付加するか、あるいは、AD変換でボリュームからMIDI受信チャンネルを設定するか、どちらかの選択になりそう。
pin番号pin機能用途
1VDD電源
2GP5:CLKセラロック接続
3GP4:CLKセラロック接続
4GP3:シリアル入力
5GP2:CCP1CV出力
6GP1:VREF/AN1VREF電圧出力
または、チャンネル指定ボリューム
7GP0:ゲート出力
8VSSグランド

資料ダウンロード

回路図とプログラムです。

現在の時点での推奨プログラムは、V1.04です。ソースファイルは、V1.04のものです。

回路図picmidicv684.pdf二番目の版(07/06/22)。MODULATION回路のトランジスタの電源を直しました。
試験中のプログラムmidicv648v105.hexSX−150のCVレンジに合わせるオプションを追加したもの。汎用版。
最新版プログラムmidicv648v104.hexバグを取ったもの。
最新版プログラムソースmidicv648v104.asm上記(V1.04)のソースファイル。
旧版プログラムmidicv648_v102.hexV1.02。実行時のMIDI受信チャンネル切替版(07/07/15)。EPROMオプションのPITCHBEND指定が動作しないが、実用上は問題ない。
旧版プログラムmidicv648_060726.hexV1.00。

質問苦情エントリー

議論を集約するために、質問苦情エントリーを設けました。ご意見、ご要望、苦情、ご質問等、ございましたらこちらへ書き込んでください。

書き込み済みCPUの配布などお問い合わせも、こちらでお願いいたします。

メニューへ戻る
アルゴ算法堂へ戻る