話題の記事

エンジニアに捧ぐDJのススメ、あるいはDJコントローラの簡単なハック

2019.01.21

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

サーバーレス開発部の平田です。

実はつい先日、何を思ったかDJコントローラー(DDJ-400)を購入いたしまして、DJの世界へと足を踏み入れました。

この前の三連休では、生粋のゲーマーである私がなんと一度もゲームを立ち上げずに、ずっと音源探しとMIXに明け暮れていました。どれほど楽しいのか、少しでも伝わりますでしょうか?

さてこの記事では、そういったDJの楽しさと、DDJ-400の簡単なハックについてご紹介したいと思います。

PCDJとは?

DJというと、図のようにアナログレコードでキュッキュしている姿を思い浮かべる方も多いかと思われますが、今日日そのようなDJは少なくなりつつあると思います。

というのもPCで音源を流し、DJコントローラーでそれを操作して音をミックスしたりするほうが、圧倒的に楽で様々な機能を使えるようになるからです。このPCを利用してDJを行うことを、「PCDJ」と呼称します。

もちろんアナログレコードでDJを行うのにも非常に大きな楽しみがあるのでしょうが、この記事は怠惰・短気・傲慢を美徳とするエンジニア向けなので、PCDJのお話をしたいと思います。

先程圧倒的に楽で様々な機能を使えるとお伝えいたしましたが、実際に楽できる機能についてご紹介したいと思います。「はじめに」で私が購入したと書いたDDJ-400には、「rekordbox dj」と呼ばれるDJソフトウェアが付属しているので、この記事では基本的にDDJ−400とrekordbox djの機能についての話をメインとさせていただきます。

さて、DJというのは様々な曲をつなげていく必要があります。曲を繋げるには、BPM(曲のテンポ)と、四つ打ちの曲であればドンドンドンドンといったビートを合わせて繋げるのが基本となるかと思います。

これがアナログレコードでのDJであれば、BPMをターンテーブルの速さを微調節しながら合わせ、さらに2曲のビートも合わせるという高度なテクニックが必要になってくるかと思います。

一方PCDJでは、なんとビートシンクボタンを押すだけで上記の合わせが済んでしまいます。これはどういうわけかというと、rekordbox側で最初に曲を読み込むとBPMとグリッド(ビート・拍位置)の解析を自動で行ってくれるので、それを利用してBPMとグリッドを1曲目に合わせた上で2曲目を再生できるのです!リズム感も複雑・緻密な操作も必要ありません。

鋭いエンジニアの方であれば、「そういった自動解析がそうそううまくいくはずがない」とお考えかもしれません。私も当初そう考えていましたが、現時点でのrekordboxの解析機能は非常に頼りになると判断していいかと思います。図の波形表示を見てもらうとわかるように、「ドン」とキックが鳴るところにグリッド(縦線)がちゃんと合っています。

解析が失敗していたのは、BPMが徐々に変わっていく曲(残念ながら現時点でのrekordboxでは、このような曲にBPM/グリッドを設定することができません。曲中でパッとBPMが変更される曲であれば対応できます。)だけで、他の曲はすべてBPM/グリッドが正しく設定されていました。エンジニアの皆さんであれば、こういった本質的でない、ちまちまBPMとグリッドを設定するなんていう作業には労力をかけたくありませんよね?

DJの喜び

それでは一体、DJのどこが俺達の魂を震えさせるのでしょうか?何が本質的で、何が楽しくてやるのでしょうか?

これには様々な答えがあるかと思います。上では軽く否定してしまいましたが、アナログレコードの操作に楽しみを覚える人もいるでしょうし、ちまちま曲を手動解析するのが楽しいという方もいるでしょう。様々な答えがあることは、もちろん良い事です。

私の答えとしては、「曲の繋ぎのトライアンドエラーの楽しさ」と、「自分の大好き曲を聴く、あるいは新たな曲を聴く中での、新たな発見の喜び」ということを挙げたいと思います。

曲の繋ぎのトライアンドエラーの楽しさ

2つの曲を繋ぐ際には、様々なパラメータが関与します。例えばまずはどの曲とどの曲とを繋げるのか、2曲同士どこで区切って繋げるのか、ループをどこでどのくらいの長さにするのか、BPMが違う場合はどちらにどうやって合わせるのか、イコライザはどのようにかけるのか、音量をどう移行していくのか・・・、など数多くのパラメータがあるかと思います。それらを少しずつ変えていきながら、自分の考える「イイ感じ」にしていくというのが楽しいです。

自分の大好き曲を聴く、あるいは新たな曲を聴く中での、新たな発見の喜び

自分の大好きな曲を聴く時でも、あるいはSpotifyやBeatportなどで新たな曲を探しているときでも、DJをするという新たな観点が生まれることにより、様々な発見があります。例えば、頑張れば耳コピ出来るくらい聴き込んだ曲でも、DJをするというのを考えながら聴くと、「ここらへんをループさせればイイ感じに繋げられそう」とか、「この曲とこの曲がイイ感じに繋がりそう」という新たな発見があるものです。それを探す楽しみと、発見したときの喜びが、更に曲を探すときの推進力となっていきます。

DJのススメ

私は音楽学部卒ではありませんし、小中学校以外で音楽の授業やレッスンを受けたこともありません。何かの楽器が出来たりすることもなく、DTMもしたことがなく、単に音楽好きなパンピーです。またDJを始めるにあたって誰かに教わったりということもありませんでした。しかしながら、どういうわけか楽しめています。

何が言いたいのかというと、あなたにももちろん出来て楽しめるということをお伝えしたいです。

なんだか難しそうと思うかもしれませんが、音楽の基礎も、音感も、リズム感も、複雑な手さばきも必要ありません。あなたの好きな音楽と、DJコントローラーさえあれば始めることができ、楽しめるのです。おそらく上記の教養やセンスやテクニックのない私のDJは、めちゃくちゃで、とてもひどく、下手くそなんでしょうが、そういうことは関係なしに楽しいのです。

あなたもDJを始めてみませんか?

DDJ-400の簡単なハック

さて、単にDJのススメでは技術ブログとしては怒られてしまいそうなので、ここではDDJ-400の簡単なハックについて記載させていただきます。

DDJ-400を技術的に見ると、単なるMIDIデバイスとなります。MIDIの仕様書もPioneerは公開してくれており、以下のリンクからPDFをダウンロード出来ます。

https://www.pioneerdj.com/ja-jp/support/software-information/controller/ddj-400/#midi-compatible-software

仕様書さえ手に入ればあとはこっちのものですね、MIDIメッセージを利用して、ボタンを光らせたりすることなどが簡単に出来ます。

しかし、rekordboxでDJをしながらボタンをピカピカさせようとしたら、問題にぶち当たりました。DDJ-400(おそらくMIDIデバイス全般)では、1つのアプリケーションがデバイスを専有してしまい、他のアプリケーションからは操作出来ないのです。例えばrekordboxをDDJ-400と接続してしまうと、別のアプリケーションからはDDJ-400にMIDIメッセージを送ることが出来ません。WindowsでもMacでも同じでした。

さて困った、rekordboxは非常に便利なので使いつつイジりたいです。しかしrekordboxを解析するのはマズそうだし、rekordboxのようなものを作るのなんてもっての他だし・・・となったのですが、「仮想MIDIケーブル」というのを利用すると、どうにかできそうというのがわかりました。

仮想MIDIケーブルはアプリケーションからはMIDIデバイスに見え、受け取ったMIDIメッセージをオウム返ししてくれる仮想デバイスになります。Macだと標準で作れるようなのですが、Windowsでは別途LoopBe1loopMIDIといったものをインストールする必要があります。私は個人用ではメインでWindowsを利用しているので、今回はLoopBe1をインストールしました。以下の記事でもLoopBe1で紹介しますが、loopMIDIでもデバイス名が違うだけで動作は同じかと思います。

仮想MIDIケーブルを利用して、rekordboxを利用しつつ、プログラマブルにDDJ-400を操作する図は次のとおりです。

DDJ-400とrekordboxの間に、仮想MIDIケーブルをかませ、自作プログラム内で双方のメッセージを仲介しつつ独自処理をねじ込むという感じです。仮想MIDIケーブルは複数のアプリケーションから操作可能なので、上記の図でうまくいきました。

仮想MIDIケーブルを利用する上で1つ注意点があります。DDJ-400のMIDI仕様では、押したときのメッセージと光らせるときのメッセージが同じとなっています。これの何が問題かといいますと、例えばDDJ-400+rekordboxでは、再生時には再生/一時停止ボタンが点灯し、一時停止時にはボタンは点滅します。一時停止させようと再生ボタンを押すと、rekordboxから再生/一時停止ボタンを光らせる信号が仮想MIDIケーブルに出力されます。仮想MIDIケーブルはオウム返しをするデバイスなので、rekordboxへ再生/一時停止ボタンを光らせる信号が出力、つまりボタンを押されたという信号がrekordbox側に送られてきてしまいます。rekordboxはボタンが押されたのでまた光らせる信号を送り、それがまた押された信号となって返ってきて・・・となり、結果としてボタンが連打されてしまう挙動になってしまうのです。

これを回避するため、rekordboxのMIDI設定で、出力(OUTPUT)の信号を9XXXから、使われていなかった8XXXへと変更しました。自作プログラム内で、これを8XXXから9XXXへ戻してDDJ-400へ送るようにします。変更する際は、ポチポチ設定するのではなくCSVからインポートが出来るので、rekordboxがインストールされたフォルダ内に置いてあるDDJ-400.midi.csvをコピーして、output列をがーっと置換してからインポートすれば楽ちんです。

今回は手っ取り早く作るため、自作プログラムをWeb MIDI APIを用いたWebアプリケーションとして実装しました。また、開発を高速に行うためにWebMidi.jsというWeb MIDI APIのラッパーライブラリを利用しました。非常に簡単にMIDIデバイスを扱えたので、オススメです。

HTMLでは次のとおりにしてCDNからWebMidi.jsを読み込み、

<script src="https://cdn.jsdelivr.net/npm/webmidi@2.3.1"></script>

JavaScriptでは次のようなコードを書きました。

const midiEventNames = [
  'noteoff',
  'noteon',
  'controlchange'
]
const midiOutputDiff = 16

let blinkFlag = true
const firstBlinkButtons = [48, 50, 53, 55]
const secondBlinkButtons = [49, 51, 52, 54]

WebMidi.enable(err => {
  const inputFromPhysical = WebMidi.getInputByName("DDJ-400")
  const outputToRekordbox = WebMidi.getOutputByName("LoopBe Internal MIDI")
  const inputFromRekordbox = WebMidi.getInputByName("LoopBe Internal MIDI")
  const outputToPhysical = WebMidi.getOutputByName("DDJ-400")
  
  midiEventNames.forEach(eventName => {
    inputFromPhysical.addListener(eventName, "all", event => {
      const data = Array.from(event.data)
      outputToRekordbox.send(data.shift(), data)
    })
    inputFromRekordbox.addListener(eventName, "all", event => {
      const data = Array.from(event.data)
      outputToPhysical.send(data.shift() + midiOutputDiff, data)
    })
  })
  
  const blink = () => {
    if (blinkFlag) {
      firstBlinkButtons.forEach(button => outputToPhysical.send(151, [button, 127]))
      secondBlinkButtons.forEach(button => outputToPhysical.send(151, [button, 0]))
    } else {
      firstBlinkButtons.forEach(button => outputToPhysical.send(151, [button, 0]))
      secondBlinkButtons.forEach(button => outputToPhysical.send(151, [button, 127]))
    }
    blinkFlag = !blinkFlag
  }
  
  setInterval(blink, 250)
})

自作プログラムでは、DDJ-400と仮想MIDIケーブルとの仲介を行いつつ、独自の点滅処理を入れました。上記のプログラムを実際に走らせ、rekordboxも起動させると、下記の動画の通りになります。

via GIPHY

再生/一時停止ボタンの入力がプログラムを介してrekordboxに伝わって一時停止になり、またrekordboxからの一時停止時のボタン点滅の出力もプログラムを介してDDJ-400側へと伝わっており、その上で一番右上のサンプラーボタンを押したときには、自作プログラム内で書いた独自の点滅処理が走っているのがわかるかと思います。

うまく動いているようですが、2点問題点があります。

  • 2つの大きな円形のパーツで、曲のサーチなどに使う「ジョグ」が機能しない。
    • これは、DDJ-400からジョグを操作すると、ランニングステータスと呼ばれる形式のMIDIメッセージが飛んでくるのですが、Web MIDI APIの仕様で、ランニングステータスの送信が許されていないので、rekordbox側に送れず操作が効かないという現象が起こります。
    • Web MIDI APIを使わずに、別のAPI経由で普通にデスクトップアプリケーションとして作成すれば、この問題は回避出来るかと思います。
  • 各チャンネルの音量を表す「チャンネルレベルインジケーター」が点灯しない。
    • すみません、これは原因を突き止めきれていません。
    • DDJ-400を直接rekordboxに接続するとちゃんと光りますし、DDJ-400にMIDIメッセージとして投げてもちゃんと光ります。しかし仮想MIDIケーブルを通すと、どうもrekordbox側からインジケーターに関するMIDIメッセージが飛んできていないようです。もしかすると何かしらの方法で機種を識別し、対応している機種のみにインジケーター情報を送るなどの処理がrekordbox側でされているのかもしれません。

おわりに

DJの楽しさと、MIDIデバイスの簡単ないじり方が少しでも伝われば幸いです。