以下の内容はhttps://relativelayout.hatenablog.com/entry/2023/03/17/084325より取得しました。


【DJへの道】ArduinoでMIDIデバイスを作ってRaspberry Pi上のMixxxと連携させる

まずはボタンから。

ポキオ Arduino MIDI Raspberry Pi Mixxx

前回はMixxxをRaspberry Piにインストールしました

非力なRaspberry Pi 2Bでディスプレイも小さいですが、動作自体は問題なさそうです。

relativelayout.hatenablog.com

今回は、Mixxxを操作するハードウェアを作っていきます。

以前作ったデバイスを再利用

ハードウェアを作ると言っても、モノ自体は以前作ったデバイスを再利用していきます。

ポキオ Arduino MIDI Raspberry Pi Mixxx

こんな感じで、5つのボタンをGNDとデジタルIOピンにつないだものです。

ポキオ Arduino MIDI Raspberry Pi Mixxx

マイコン部分はArduino Leonardo互換機のSeeeduino Liteです。Atmega32U4が搭載されているのでUSBネイティブサポートも使えて、USBデバイスとしてエミュレーションも可能です。よって以て、USB接続できるMIDIバイスとしてもエミュレーション可能なはず…。

いざプログラミング

ハードウェアは再利用するので、それを制御するロジックを書き換えていきます。コーディングはArduino IDEで。 久しぶりのダウンロード・起動だったので、UIがガラッと変わっていたのでびっくりしました。

www.arduino.cc

さて、プログラミング自体は下記のArduinoのドキュメントを参考にコーディングしていきます。

docs.arduino.cc

ポイントは…

  • Native USB Port対応をしているボードを使う
  • MIDIを扱うためにMIDIUSBライブラリを使う

こんな感じ。MIDI系のライブラリは複数あってカオスですが、今回はArduinoドキュメントに従っていきます。

コードは最後の方に貼っておきますが、MIDIのやり取りとしてはノートオン・ノートオフを使っていきます。

void noteOn(byte channel, byte pitch, byte velocity) {
  Serial.println("noteOn");
  midiEventPacket_t noteOn = { 0x09, 0x90 | channel, pitch, velocity };
  MidiUSB.sendMIDI(noteOn);
}

void noteOff(byte channel, byte pitch, byte velocity) {
  Serial.println("noteOff");
  midiEventPacket_t noteOff = { 0x08, 0x80 | channel, pitch, velocity };
  MidiUSB.sendMIDI(noteOff);
}

こんな感じで、ノート(鍵盤)を押す・離すという情報をプログラム的に送信します。鍵盤なので、どの音階をどのくらいの速さ(強さ)で押すか、などの情報も送ります。今回は中央のド(C3)からソ(G3)までを5つのボタンに割り当てて、ノートオン・ノートオフで送信します。チャネルと速度は固定のものを使いました。

ドレミファソをMixxxのコントロールに割り当てる

今回ド〜ソまでの5つの音階が表現できるMIDIバイスが出来たので、それぞれDeck1/2のPlay・Cueに割り当てていきます。(5つのボタンのうち4つだけアサインしてみます)

ポキオ Arduino MIDI Raspberry Pi Mixxx

理想としてはこんな割り当て。実際にMixxxでマッピングしていきます。

ポキオ Arduino MIDI Raspberry Pi Mixxx

自作MIDIバイスRaspberry Piに接続してからMixxxを起動して、設定画面を開くとコントローラーというタブでデバイスが認識されているようです。

一応、プリセットという項目を覗いてみると、主要なDJコントローラーのマッピングには対応してそうですが、今回はプリセットは使わず、ラーニングウィザードを使って自力でマッピングしていきます。

ポキオ Arduino MIDI Raspberry Pi Mixxx

ラーニングウィザードを開くと、Mixxx上の要素が一覧で並んでいて、それぞれに信号のアサインが出来ます。

ポキオ Arduino MIDI Raspberry Pi Mixxx

とりあえず、Deck1/2のPlayとCueを探しては、実際にデバイスのボタンを押して、ボタンと制御の紐付けを行いました。

ポキオ Arduino MIDI Raspberry Pi Mixxx

こんな感じ。

いざDJ

4ボタンだけなので、凝ったことは出来ませんが、ちゃんとボタンと演奏がリンクしていました。

ポキオ Arduino MIDI Raspberry Pi Mixxx

雑感として

  • 理論的にはボタンやスライダーを追加していけばDJコントローラーは自作できる
  • ボタンがチャタるので、何かしらの制御が必要そう
  • ハードウェアボタンを同時に押したり操作したりすると、処理が追いつくか(他の処理をブロッキングしないか)が心配
  • ボタンが増えるとマッピングが面倒

こんな感じですねぇ。自作あるあるですが、やっぱり製品ってすげぇ…ってなりますね(笑)

とりあえず、横フェーダー・縦フェーダー、イコライザ、できればジョグあたりも追加してみたいところ・・・。

コードはこちら

#include <MIDIUSB.h>
#include <MIDIUSB_Defs.h>
#include <frequencyToNote.h>
#include <pitchToFrequency.h>
#include <pitchToNote.h>

#define BUTTON1 3
#define BUTTON2 5
#define BUTTON3 7
#define BUTTON4 8
#define BUTTON5 10

#define C3 48
#define D3 50
#define E3 52
#define F3 53
#define G3 55

#define DELAY 100

void setup() {
  pinMode(BUTTON1, INPUT_PULLUP);
  pinMode(BUTTON2, INPUT_PULLUP);
  pinMode(BUTTON3, INPUT_PULLUP);
  pinMode(BUTTON4, INPUT_PULLUP);
  pinMode(BUTTON5, INPUT_PULLUP);

  Serial.begin(9600);
}

void loop() {
  if (digitalRead(BUTTON1) == 0) {
    Serial.println("BUTTON1");
    noteOn(5, C3, 64);
    MidiUSB.flush();
    delay(DELAY);
    noteOff(5, C3, 64);
    MidiUSB.flush();
  }

  if (digitalRead(BUTTON2) == 0) {
    Serial.println("BUTTON2");
    noteOn(5, D3, 64);
    MidiUSB.flush();
    delay(DELAY);
    noteOff(5, D3, 64);
    MidiUSB.flush();
  }

  if (digitalRead(BUTTON3) == 0) {
    Serial.println("BUTTON3");
    noteOn(5, E3, 64);
    MidiUSB.flush();
    delay(DELAY);
    noteOff(5, E3, 64);
    MidiUSB.flush();
  }

  if (digitalRead(BUTTON4) == 0) {
    Serial.println("BUTTON4");
    noteOn(5, F3, 64);
    MidiUSB.flush();
    delay(DELAY);
    noteOff(5, F3, 64);
    MidiUSB.flush();
  }

  if (digitalRead(BUTTON5) == 0) {
    Serial.println("BUTTON5");
    noteOn(5, G3, 64);
    MidiUSB.flush();
    delay(DELAY);
    noteOff(5, G3, 64);
    MidiUSB.flush();
  }
}

void noteOn(byte channel, byte pitch, byte velocity) {
  Serial.println("noteOn");
  midiEventPacket_t noteOn = { 0x09, 0x90 | channel, pitch, velocity };
  MidiUSB.sendMIDI(noteOn);
}

void noteOff(byte channel, byte pitch, byte velocity) {
  Serial.println("noteOff");
  midiEventPacket_t noteOff = { 0x08, 0x80 | channel, pitch, velocity };
  MidiUSB.sendMIDI(noteOff);
}

void controlChange(byte channel, byte control, byte value) {
  Serial.println("controlChange");
  midiEventPacket_t event = { 0x0B, 0xB0 | channel, control, value };
  MidiUSB.sendMIDI(event);
}

最後に…

誰かPCDJを私に恵んでください…。

  • Pioneer DJ

www.amazon.jp




以上の内容はhttps://relativelayout.hatenablog.com/entry/2023/03/17/084325より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14