xor

二兎を得るか、一兎をも得ざるか

歌うテルミン "Vocaleaper"

www.youtube.com

(2016/7/17,18) NT金沢2016にて展示いたしました。

(12/6) 伊勢ギークフェア2015にて展示いたしました。

(9/11) 追記しました。マイペースでごめんなさいです。

(8/1,2) Maker Faire Tokyo 2015にて展示いたしました。

色々なサイトから紹介していただきました!

Vocaleaperとは?

Leap MotionとeVocaloidを組み合わせた、テルミンのような動きでVocaloidを歌わせることのできるインターフェースです。両手の位置と指の動き(握る動作)で歌い方を制御することができます。
Leap Motionは、赤外線カメラで手の動きを検出できるデバイスです。
eVocaloidはヤマハの組み込み音源のひとつで、ここでは大人の科学ポケットミクの内部にあるものを利用しています。
以上のように音源・インターフェースともに既成品を利用しているため、開発をしたのはハードとソフト両面のUI部分のみとなります。

プロトタイプ

大学進学で上京した次の年あたりにMaker Faireというモノ作りの祭典があるのを初めて知りました。
それをしばらく忘れていて翌年、何かのネット記事で「出展者募集開始!」みたいなのを見て、軽い気持ちで応募してみようと適当にアイデアをひねりだし4日ぐらいで試作機を作成しました。締め切り一週間ぐらい前にAmazonでポケミク(eVY1シールドより安かったため)とLeap Motionを注文し、届いてからせこせこコーディングして作ったものが以下のビデオになります。

なぜこれを作りたいと思ったのかは自分でもよくわかりませんが、念のため似たようなものがないか調べたところ、Leap Motionをインターフェースとして音程を動かすという考え方はすでにあったようですが、ボーカル音源と組み合わせるというものは見つからなかったのでこのまま作っても大丈夫そうかなと。

ちなみに"vocaloid"と"leap motion"の組み合わせで検索するとARスカートめくりみたいな何かがヒットします。それはそれでとてもよい。また制作後に調べものをしてて知ったのですが、チップを作った本家がこんな技術情報を公開されていました。

patents.google.com

インターフェースに関しては、Vocaleaperとカブる部分はほとんどないはずです。おそらく。

インターフェース構想

キーボード

最初の試作機は、左手の位置で子音、左手の指の本数(グーなら0、チョキなら2、のような)で母音を指定して右手で音階とノートオンオフの操作をするものでした。しかも左手の位置は、3×3×3のルービックキューブ状に区分けされた空間領域上に手をもっていくというもので、位置のイメージできず操作が非常に難解でした。
手話の指文字で発音を指定するというアイデアもありましたが、Leap Motionがそこまで精度よく指と手のカタチをとれず、Macbookのビルトインカメラ利用アイデアも画像のリアルタイム認識を実装する技術がなかったので断念しました。

そこで、ふだん誰もがキーボードで文字を入力しているように、ローマ字入力と同時に音量や音階をとれればいいのではないかと思って作り直したものがここで紹介する完成版のVocaleaperです。

日本語は「モーラ言語」に分類される言語であり、日本語の楽曲は、基本的には音程をもった1回の発声は1モーラを成します。この1モーラの内訳は「母音のみ」「子音と母音」「子音と半母音と母音(=拗音)」「促音」「撥音」「長音」のいずれかになります。この原理より、「日本語ボーカル用キーボード」のアイデアを書き出しました。

参考: 音素の最前線

基本的には、例えば「か」と発音したければ"K"と"A"を指定します。しかし「きゃ」のような拗音を発音したければ"K"と"Y"と"A"の三つを指定する必要があります。そのため、このような半母音の入った音素は"jA"のように分離することによって、"K"と"jA"の指定という両手で間に合うような組み合わせにすることができます。あとは本来の日本語に存在しない例外的な組み合わせである「つぃ」のような音を表現するTwという子音+半母音の組み合わせを追加し、それぞれボードの一番外側に配置しました。
さらに日本語で出現する音素の頻度が高い順番にキーボードの反応面積を大きくしています。特に母音となる文字は使用頻度が最も高いため、比較的大きな面積をキーボード上で占めることになりました。

外装 - ハードウェア

市販のコルクボードにLeap Motionを埋め込んだあと、上述のキーボードの文字配置アイデアを書き込みました。次にそれぞれの文字領域の図形のおおよその重心だと思われる位置にLEDを設置します。子音は白色LED、半母音は青色LED、母音は赤青の2色のLEDにして、母音は赤を常時点灯させておいて選択状態になると青へ切り替わるようにしました。

次にコルクボードをフタとした薄い直方体の箱を作成します。奥側の側面となる木材にはUSBと標準ラインアウトの左右とフットスイッチ用ジャックの計四つの穴を設置しました。この内部USBにLeap MotionArduino MEGAの2つを接続します。Leap Motionは手指の動きを捉えてPCに送り、Arduino MEGAはPCからの信号を受けてLEDを制御します。
またこのUSBにはポケットミク基板も接続されており、外部MIDI音源として動作します。

LED接続については、子音LEDと半母音LEDはそれぞれ抵抗を通して共通GNDにし、アノードをひとつずつArduinoのピンに接続します。母音LEDはカソードコモンなので、とりあえず共通GNDに落としてからアノード側にひとつずつ抵抗を取り付けます。特に赤青で電流量と発光度合いが変わりますし、赤色はずっと点灯させておく仕様なので、ここは贅沢に抵抗をひとつずつ使ってあげます。

最後にフットペダルジャックをプルアップしたピンに入力として接続します。さらにジャックが挿さっているかいないかで切り替わる端子もつなげて、フットペダルの利用可能の有無をソフトウェア側から判断できるようにしておきます。

操作画面 - ソフトウェア

ハードウェアはLeap Motionさえあれば入力インターフェースとして完結しており、作った黒い木箱は「二画面あるうちの下側」とでも言えるべきものです。つまりディスプレイである「上画面」がメインとなります。
基本操作のアイデアとしては、音高を手の高さ、音量を手の握り具合、その他パラメータを手の向きや角度(ピッチ・ロール・ヨー)で制御できればというものでした。これをもとに、木箱を底面とした直方体の内部で手を動かすようなイメージでGUIを作成しました。
開発期間短縮の観点からProcessing(一部Javaのネイティブコード)を開発言語として作成しています。

手指の検出

手の位置で文字を判定するやりかたですが、まず四角いハードウェアの4つのカドの上あたりに手をかざし、実際に得られる位置のfloat値の範囲をメモします。次にあらかじめ作っておいた1500×1000px(ハードウェアと同じ縦横比3:2です)の以下のような色分けビットマップ画像を、メモリ上の仮想画面に描画しておきます。

あとはこの仮想画面の範囲内に実際の手のfloat値範囲をマッピングしなおし、その変換されたあとの位置上にあるピクセルの色と一対一対応させた文字種を取り出します。逆ジオコーディングにちょっと似ているのか、もしかしたら方法としては同じなのかもしれませんが、実際こんな手法が使われているのかどうかは調べていないのでわかりません。Postgresとかの地理情報が扱えるDBを用いることもできるかもですが、反応速度が気になります。
ここではこのやり方でとりあえずは誤認識もエラーもなかったのでよしとします。

両手それぞれの操作の割り当て

前述したように、両手を用いて発音したい文字の母音字と子音字の上方にそれぞれの手を持って行くことで発音を指定してやります。さらにそれぞれの手の動きで別の操作をするのですが、常に右手が母音をーなどというようには定まらないので、「母音字スロット」「子音字スロット」を設定し、両スロットにそれぞれ右手もしくは左手が最大各1つ入ることでうまく発音させたい字を重複させずに指定できるようにしました。

例えば、最初に右手が"P"を指していれば子音字スロットには右手が入るため、必ず左手が母音字スロットに入り「ぱぴぷぺ…」のいずれかを発音するものだとすることができます。また逆に、最初に左手が"A"を指していれば母音字スロットには左手が入るため、右手を使わなければ子音字スロットに何も入らず「あ」を発音しますが、右手で何らかの子音字を指定した場合は「あかさたな…」のいずれかの発音をするものだとすることができます。

…つまるところ、片手が母音を指しているならもう片手は必ず子音の指定もしくは何も指定しない、といった割り当てに限定されるようになっているわけです。しかしこれで、どちらの手が母音字なのか子音字なのかはすぐにわかります。

このとき、母音側を指した手を開くことでノートオン、閉じることでノートオフ、開き具合で音の大小(ベロシティ)、上下移動で音階の調節ができようにしました。手の握り具合は1(握り)〜0(解放)のfloat値で得られるので、1からこの値を引いたものに127を掛けてやればベロシティになります。このあたりの変化を対数関数などにすればAカーブとか実現できそうですが、プログラム上では単純な線形変化(Bカーブ)を利用しています。

母音を指していないほうの手、つまり子音を指しているもしくは別の有効でない位置の上にある手は、上下移動でピッチベンドをし手の開き具合でビブラートをかけられるようにしました。

ピッチベンドは、ノートオンと同時に現在の手(ピッチベンド操作するほうの手)の位置を基準のゼロにリセットしたうえ、発音後に多少上下動しても反応しないように±100pxほどは変化させないように工夫しています。

ビブラートは簡単にするため標準的なmidiモジュレーション命令をそのまま使っていますが、ポケミク独自のSysExのビブラート命令のほうがリアルなのかもしれません。時間あったらやってみます。

音源

音源であるポケミクは、パソコンにつなぐとそのまま"NSX-39 "(なぜか最後に半角スペースが入る)というMIDIバイスとして認識されます。これをMidibusというProcessingライブラリを用いてI/Oするオブジェクトを立ち上げます。

さらに同時にjavamidiメッセージを扱うライブラリlibmmjもインクルードします。Mac限定みたいですね。
このlibmmjのSysExメッセージ関数で発音する文字情報・ビブラート・ピッチベンドを送出したのち、MidibusのNoteOn関数にベロシティ、ノートナンバーを含めて送出します。もうmidi系統どっちかひとつにまとめてくれ!って感じですがjavaとかライブラリとか全然詳しくなかったんで情報の寄せ集めでこうなってしまったのです…。libmmjはmidiメッセージのバイナリを直接的に触れて、MidibusはsendNoteOn関数などもう少し音楽的にmidiを制御するといった使い分けですね。

歌詞情報がやはり標準的に使用される命令群を用いることができないのでバイナリをちまちまと送ってあげねばならないということです。Processingからポケミクを操る基本的なライブラリとその扱いに関してとても参考にさせていただいたのはこちら。

karaage.hatenadiary.jp

出展後、子供達の反応を通して

実際に演奏をするには高度な技術が必要であり、製作者である本人もマトモに演奏させることが非常に難しいです。しかし、適当に手を動かすだけでバーチャルな画面が動き、よくわからない言葉になるもののVocaloidが歌いだす、という動作が子供達にはとても面白かったようです。
理論的なモノだけにこだわらず、意味はあまり無くても直感的なモノのほうが楽しくさせることができる可能性を感じました。

その他の出展したイベントなど

→ 冒頭に記載しました。