2018年12月8日土曜日

MIDI-CV Converter MIDI_CV_CONVの構想

BSM02でシーケンサー+D/A混在シンセを作りましたが、打ち込んだデーターを外に取り出す仕組みは作っていないので、Nucleo_DCOに音階を与えるために流用するのは少しめんどうです。BSM02のハードウェア/ソフトウェアに手を入れる必要があるので、思いつきで崩してしまうのは抵抗があります。

ひとまずは、パソコン上のDAWを使ってMIDI信号を出力し、CV/GATE信号に変換する、MIDI-CVコンバーターを作ってみることにしました。

作戦


ArduinoとmbedのMIDI Libraryを簡単に試したことがありますが(https://dad8893.blogspot.com/search/label/MIDI%20Library)、サイズの小さいNucleo F303K8を使ってmbedでやってみると、どうもMIDIメッセージを読みこぼすようです。

Nucleo-F303K8は12bit DACが3系統内蔵されていて、性能もCortex-M4でそこそこ高スペックなので使ってみたかったのですが、まずはArduinoでやってみることにしました。

Arduino NANOかArduino Pro Miniを使うつもりです。

想定している使用例

ArduinoにSPI/DACのMCP4922を接続し、アナログ値を出力してCVとします。MCP4922は2ch DACなのでうまく行けば2ch分CVを出力できます。

Nucleo_DCOは3.3V系(5Vトレラント)なのでCVの信号レベルは0V~3.3Vとします。

「DASS01」(「ASS01」という名前にしようと思ってましたが、「DASS01」に変更します)はアナログ系でCV信号にもう少し振幅が欲しいので「DASS01」内の「Amp」で増幅します。増幅率は「Mod Level」POTで可変します。

GATE信号はGPIOから出力します。「Arduino_EG」のプロセッサーは5V駆動のArduino Pro Miniなので入力するGATE信号レベルは5VでOKです。「KIK01」はNucleo-F446RE、「BSM02」はNucleo-F401REでSyncIn(GATEの立ち上がりで評価)は3.3V系ですが5Vトレラントなのでこれも5VでOKです。

開発環境


ArduinoでMIDI Libraryを使うとデフォルトではハードウェアUART(D0, D1)を使うので、デバッグ用にArduinoのSerialクラスが使えません。簡単なメッセージの表示しかできませんが、I2C接続のキャラクタLCD(秋月のAE-AQM1602A)を使うことにしました。

ブレッドボード配線図

※Arduinoで書き込むときは、RXの配線を抜く。


※MCP4922はまだ接続していません。

Arduinoのスケッチ


AE-AQM1602Aのライブラリは「I2CLiquidCrystal-1.5 https://n.mtng.org/ele/arduino/i2c.html」を使いました。

<MIDI_Display_Message_I2C_LCD_Gate.ino>

#include <Wire.h>
#include <I2CLiquidCrystal.h>
#include <MIDI.h>

#define LCD_TRACE   (0)
#define PIN_CHECK   (1)
#define TITLE_STR1  ("MIDI to GATE    ")
#define TITLE_STR2  ("20181204        ")

// Pin assign
const int GateOutPin1 = 2;
const int GateOutPin2 = 3;
const int GateOutPin3 = 4;
const int GateOutPin4 = 5;
const int GateOutPin5 = 6;
const int GateOutPin6 = 7;

const int CheckPin1   = 8;

// MIDI
MIDI_CREATE_DEFAULT_INSTANCE();

// I2C LCD
#if (LCD_TRACE)
I2CLiquidCrystal lcd(32, (bool)true);
#endif

// MIDI -------------------------------------------------------------------------

#if (LCD_TRACE)
void printNoteOnOff(const char* type, byte inChannel, byte inNote, byte inVelocity)
{
  lcd.setCursor(0, 1);
  lcd.print("                ");
  lcd.setCursor(0, 1);
  lcd.print(type);
  lcd.print(' ');
  lcd.print(inChannel);
  lcd.print(' ');
  lcd.print(inNote);
  lcd.print(' ');
  lcd.print(inVelocity);
}
#endif

void handleNoteOn(byte inChannel, byte inNote, byte inVelocity)
{
  digitalWrite(GateOutPin1, HIGH);
#if (LCD_TRACE)
  printNoteOnOff("On", inChannel, inNote, inVelocity);
#endif
}

void handleNoteOff(byte inChannel, byte inNote, byte inVelocity)
{
  digitalWrite(GateOutPin1, LOW);
#if (LCD_TRACE)
  printNoteOnOff("Off", inChannel, inNote, inVelocity);
#endif
}

// -----------------------------------------------------------------------------

void setup()
{
  pinMode(GateOutPin1, OUTPUT);
  pinMode(GateOutPin2, OUTPUT);
  pinMode(GateOutPin3, OUTPUT);
  pinMode(GateOutPin4, OUTPUT);
  pinMode(GateOutPin5, OUTPUT);
  pinMode(GateOutPin6, OUTPUT);
  pinMode(CheckPin1,   OUTPUT);

  MIDI.setHandleNoteOn(handleNoteOn);
  MIDI.setHandleNoteOff(handleNoteOff);
  MIDI.begin(MIDI_CHANNEL_OMNI);

#if (LCD_TRACE)
  lcd.begin(16, 2);
  lcd.print(TITLE_STR1);
  lcd.setCursor(0, 1);
  lcd.print(TITLE_STR2);
  delay(2000);
#endif
}

void loop()
{
#if (PIN_CHECK)
  digitalWrite(CheckPin1, HIGH);
#endif

  if (MIDI.read()) {

    // Display Raw Midi Message

    byte type    = MIDI.getType();
    byte channel = MIDI.getChannel();
    byte data1   = MIDI.getData1();
    byte data2   = MIDI.getData2();

#if (LCD_TRACE)
    lcd.setCursor(0, 0);
    lcd.print("                ");
    lcd.setCursor(0, 0);
    lcd.print(type, HEX);
    lcd.print(' ');
    lcd.print(channel, HEX);
    lcd.print(' ');
    lcd.print(data1, HEX);
    lcd.print(' ');
    lcd.print(data2, HEX);
#endif
  }
#if (PIN_CHECK)
  digitalWrite(CheckPin1, LOW);
#endif
}

メモ:


LCD_TRACEを有効化(1)するとMIDIメッセージを読みこぼす。

中華製のArduino NANOはプロセッサでATMega328P(Old bootloder)を指定する必要がある場合がある。

メインループの処理時間は92kHzぐらいで変わらない?

DACからの出力にはLPFを入れる。Nucleo_DCOはADCにCV信号を入力するので注意。

厳密にするならDACやGPIOからの信号はデジタル回路でラッチをかけて同期させたいけど、そこまでは必要ないか・・・

0 件のコメント:

コメントを投稿