MIDI OX を使って MIDI メッセージを記録する方法

MIDI メッセージの解析をするのに MIDI-OX は非常に強力なソフトウェアです。MIDI 信号を再現するために、受けた信号を記録することもできるのですが、やり方が少しわかりにくいのでこの記事に書き留めておきます。以下の手順で .mid ファイルを作ることができます。

1. Input Monitor を開く

開かなくても記録はできるんですがモニタを開いておくと受けたメッセージが見られるので作業が楽です。メニューの

View-> Input Monitor…

から開けます。

2. モニタを開始する

Actions -> Start Display

で開始します。ついでに SysEx も受け付けるようにしておくと解析にはよいかもしれません。

Options -> Pass SysEx

3. 試しに MIDI メッセージを入れてみる

以下のような画面になるはずです。右下の REC と SYX というボックスが紺色に反転していることが重要です。

4. 記録を開始する

モニタ画面を右クリックして “Clear Input” を選ぶと画面がクリアされます。クリアしたら記録を開始します。

File -> Log

を選んで、ログファイルダイアログを呼び出し、以下のように内容を変更します。

  • Enable Logging を入れる
  • Log Format を “MIDI to Text” にする
  • Log File の拡張子を .mtx に変える

OK ボタンを押すと記録が開始されます。再度何か入力を入れると、以下のような画面になります。右下の LOG ボックスが紺色に反転していることが重要です。

5. 記録を終了する

画面右下の LOG ボックスをクリックするか、File -> Log… ダイアログで Enable Logging を外して OK ボタンを押すと記録が終了します。記録開始時に指定した .mtx ファイルが生成されます。

6. .mtx ファイルを .mid ファイルに変換する

Mtx2Midi というツールを使います。MIDI-OX のページ

http://www.midiox.com/

に行って、Mtx2Midi-Installer.zip というリンクを探してインストールします。インストール後、生成した .mtx ファイルを右クリックして “Convert to MIDI file” を選ぶと変換した .mid ファイルが同じフォルダに作られます。

PSoC CY8CKIT-049-42xx キットの USB-UART ブリッジを使う

これをプログラムするには miniprog3 が必要です。

1. SCB UART コンポーネントを置く。ボーレートを 9600 に変更する。
uart_config

2. ピンの割り当ては以下の通り

UART RX : P4[0]
UART TX : P4[1]

pin_connection

3. これがソースコード

int main()
{
    CyGlobalIntEnable; /* Enable global interrupts. */

    /* Place your initialization/startup code here (e.g. MyInst_Start()) */
    UART_1_Start();
    
    UART_1_UartPutString("Hello world from CY8CKIT-049-42xx\r\n");

    for(;;)
    {
        /* Place your application code here. */
    }
}

4. ビルドしてプログラムして CY8CKIT-049-42xx キットを PC につなぎます
terminal_screenshot

はいこれだけ

PSoC 42xx を使って MCP2515 の命令フレームを生成する

PSoC 42xx は SPI コンポーネントが提供されていて、クロックは 4MHz まで設定できます。しかしながら、これを使って可能な限り速く MCP2515 と通信することはそれほど単純ではありません。

問題は、MCP2515 の命令は複数のバイトでできていることです。一つの命令は CS 信号で束ねられていて、命令を送っている最中はずっと L (イネーブル)にしておかないといけません。しかしながら、PSoC の SPI は CS 信号を直接制御できません。コンポーネントとの通信は FIFO を通じて行われており、FIFO がデータを受け取ると、内部で自動的に CS をイネーブルに変え、データの送信が終わって FIFO が空になると自動的に CS をディスエイブルに戻します。自動生成される API 関数はあまり効率が良くなくて、SPI のクロック周波数が高いとスピードに追い付けず、送信の間が空いてしまいます。そのためクロック周波数が高いと API 関数を使って MCP2515 の命令フレームを作ることができません。

datasheet_read_instruction

この問題を解決するために、API 関数を使わずに SPI を制御する関数を書きました。方針は

  • より低レベルのインタフェースを使って SPI とやり取りを行う
  • いったん送信が始まったら可能な限り速く Tx FIFO にデータを送り込み、送信が途絶えないようにする
  • データを送るのと並行して可能な限り早く Rx FIFO からデータを取り出す

いくつか制限事項があります

  • SPI 設定の Rx および Tx バッファサイズは 4 でないといけない。これより大きいと、PSoC Creator がソフトウェアバッファを生成してしまいソースコードの管理が難しくなる
  • 取り出したデータの最初の2バイトはダミーで意味をなさない。実際のデータは3バイト目から始まる。
  • まだ実装していないがたぶんこの関数を実行中は割り込みを停止しておかないといけない

以下がソースコードです。SPI コンポーネント名は SPIM_CAN で種類は SPI マスタ (SCB を使わない) です。

#define CAN_CTL_READ 0x03

void mcp2515_read(uint8_t address, uint8_t data[], uint8_t length)
{
    /* initialization */
    uint8_t to_write = length;
    length += 2;

    /* flush rx buffer */
    while (SPIM_CAN_GetRxBufferSize())
        SPIM_CAN_ReadRxData();

    /* wait until Tx FIFO becomes empty */    
    while (0u == (SPIM_CAN_TX_STATUS_REG & SPIM_CAN_STS_TX_FIFO_EMPTY)) {}

    CY_SET_REG8(SPIM_CAN_TXDATA_PTR, CAN_CTL_READ); // push instruction
    CY_SET_REG8(SPIM_CAN_TXDATA_PTR, address);      // push address

    // loop until all bytes are retrieved
    while (length > 0) {
        // transmit 0 to receive a byte
        if (to_write > 0 && (SPIM_CAN_TX_STATUS_REG & SPIM_CAN_STS_TX_FIFO_NOT_FULL)) {
            CY_SET_REG8(SPIM_CAN_TXDATA_PTR, 0);
            --to_write;
        }
        // retrieve a byte if there is any in Rx FIFO
        if (SPIM_CAN_RX_STATUS_REG & SPIM_CAN_STS_RX_FIFO_NOT_EMPTY) {
            *data++ = CY_GET_REG8(SPIM_CAN_RXDATA_PTR);
            --length;
        }
    }
}

MCP2515 から 16 バイト取り出してみました。4MHz のクロックで想定通りに動いています。

read_instruction

read_instruction2

Emacs のひっくり返った ctrl-M と ctrl-J を元に戻す

Emacs 24 のどこかのバージョンで突然 ctrl-M (改行) と ctrl-J (改行+インデント) の役割が逆転したようです。Emacs 開発のこういう無神経な変更にはイライラさせられますがとにかく何でもカスタマイズできる emacs のことです。以下の一行を .emacs に入れれば元に戻ります。

(when (fboundp 'electric-indent-mode) (electric-indent-mode -1))

以下の投稿に感謝。
http://emacs.stackexchange.com/questions/5939/how-to-disable-auto-indentation-of-new-lines

USB Serial Communication with PSoC Pioneer Kit

Exchanging data with PSoC Pioneer Kit over serial communication is often useful. The kit CY8CKIT-042 has a built in USB-to-UART utility programmed in the PSoC 6LP device which is used for onboard debugger for the target PSoC 4. It is easy to use. See below.

https://www.element14.com/community/thread/23868/l/psoc-4-pioneer-kit-community-project04-usb-uart-utility?displayFullThread=true

MIDI 受信くん

schematic

DSC02703

PSoC Creator が突如不安定になってしまいソフトウェアが書けなくなりました。

修復中ですがその間に 「MIDI 受信くん」を作りました。悲しいぐらい手順を忘れていてこんなもんにもえらい時間がかかりました。これで MIDI 受けの開発がちょっと楽になるといいです。

動作確認はまだ。

Analog3: 最初の設計例

DSC02688

Analog 3 の開発を休止してから1年が経ってしまいました。そろそろ再開しようと考えて、最初の設計例として作りたいシンセのパネルの粗案をかいてみました。パラメータ数は多いし、VCF のパラメータの例のように、伝統的なパラメータと考え方の違うものも多々あります。作って行くうちに更新や調整が必要になってくる可能性があります。ハードウェアの作り直しを避けるために、以下のような道筋で開発を進めようと考えています。

  • 最初に動くことがわかっているシンセから出発する。
  • このシンセを改造してゆくことで開発を進める。
  • 改造は、モジュールを1個ずつ Analog 3 のものに置き換えることで行う。
  • 新しいモジュールはソフトウェアパネルを使う。
  • 古いモジュールはハードウェアパネルを使い続ける

このようにして、常に完全なセットで音が出る状態で開発を進めようと考えています。

ということで、最初にする作業は、Analog2.0 の基本セットを組み立てることです。

 

今何を作っているのか

analog3もうここ数年ろくに新しい製作の記事を書いてないのですが、作るのをやめてしまったわけではなく、単に手こずっているのであります。あと、自分でも何を作っているのかよくわかっていなかったためなんとなく記事にしづらかったのであります。

作っては失敗し、やり方を変えてまた作り、を繰り返しはや数年、ここ一ヶ月ぐらいでやっと動く様が見られるようになってきました。動くものを見たら自分が何を作っているのかやっと少しずつわかるようになってきました。

今やっているのは、Analog3 というアナログシンセサイザー作りの新しいプロジェクトです。でも今の所アナログ回路はほとんど組んでいません。大半がソフトウェアです。まだもうしばらくソフトウェアばかり組むことになりそうです。

ソフトウェアの進捗はブログにまとめづらいのですがソースコードは GitHub で管理していてそちらから見られます。

https://github.com/naokiiwakami/analog3

何でアナログシンセなのにソフトウェアばっかりになっているかというと、以前していた Analog2.0 プロジェクトは一旦開発終了として(サポートは現在も続けてます!)、次のシンセを作ろうと思った時にこんな葛藤があったからです。

  • アナログシンセ、細かい所に不満が多すぎる。もっと細かいところをしっかりたくさん作り込みたい。
  • でも、こまこまと作り込むと、設定パラメータが増えてしまう。
  • アナログシンセには操作パネルが付いていて、パラメータ一個につきツマミが一個必要。
  • パラメータが増えたら、ツマミの数が大変なことになるよ。ツマミ100個とかになったら作るのは大変な手間だし、作ったとしてもごちゃごちゃしてて操作できないよ。
  • しかも、回路をちょっと変えただけでパネルの作り直しが必要になったらいつまでたっても完成しないよ。
  • こまった…

しばらく色々考えて、こんな風に考えるようになってきました。

  • パネルがなければ回路を変えてもあんまり困らないんじゃね?
  • パネルはソフトウェアで作っちゃう?
  • パネルがソフトなら、律儀にパラメータ一個にツマミ一個つけなくてもいいんじゃね?減らしたりまとめたりできるよね?操作楽だよね?
  • いいかも
  • でもツマミをくりくり回せないアナログシンセなんてアナログシンセじゃないよ。作る意味ないじゃん?

そんなわけで、色々試行錯誤してゆくうちに、Analog3 はこんな風なシンセになってきました。

  • あくまでもアナログシンセサイザー
  • でもパネルを作らなくてもいい
  • でもパネルを作りたくなったら作ってもいい

冒頭の写真の試作では、LFO モジュールを PSoC で実装して、アナログシンセを揺らしています。LFO のパネルはなくて、そのかわりにパネル情報が PSoC のモジュールに入っています。これを Raspberry Pi を経由して Mac から読んで、Mac の画面に描いています。ただ描くだけじゃなくてちゃんと操作もできます。まだ実装中ですけれども。ツマミを回すぐらいのことはできるようになってきました。

組み込み向け exp() 関数の実装方法

楽器系の作り物をマイクロプロセッサでするときには、指数関数が必要になる場合が頻繁にあります。汎用の実装は遅くてでかいので、組み込みには向きません。正確さが必要な場合は少ないですが、スピードと小ささは重要です。

組み込み向けの実装をいくつか探したので忘れないようにここにリンクをはっておきます。

http://www.convict.lu/Jeunes/ultimate_stuff/exp_ln_2.htm

http://www.quinapalus.com/efunc.html

今の所、過去に試作したエンベロープジェネレータの指数関数計算部分を流用していて、まだでかくて遅いですがとりあえず今やっているプロジェクトで使っている PSoC 4200 に収まってちゃんと走っているので困るまでこのままにしておくのではあります。