可視光通信…菓子交通神?お菓子と交通の神じゃないって

可視光通信とか眼や光にまつわるもろもろ

レーザー可視光通信で歌を歌ったアルディーノ

※タイトルは、大原まり子著「銀河ネットワークで歌を歌ったクジラ」より。


前回の可視光通信キットに、さらにAruduinoを送信に使ってもう少し遊ぶとします。
LEDだと距離が苦しかったので、今回レーザーを使います。
(何しろPerfume の新譜「レーザービーム」が発売間近(2011/5/18)ですからね。なので後半ではArduionoにPerfumeを歌わせる?こともやります。)


可視光通信の送信部は、以前のはやぶさがらみ記事で、Arduionoに赤色レーザポインタをつなげたやつがあるのでOK。
受信部とA/D (アナログ−デジタル変換)は前回の光通信キットの受信部をそのまま使えばOK。
写真の白いやつは単なる乾電池のUSB給電器です。

あとはArduinoでアナログ音声変調させるスケッチ(Arduinoのプログラム)ですが、・・・とりあえず、PWM(パルス幅変調)でオーディオ出すのをググりましてこれをで遊ぶこととしました。すごい人がいるもんです。
Cantarino, the Arduino speech synthesiser
(BoxHeadRoomさんの記事 『Cantarino』唄うArduino という紹介記事がわかりやすいです。後述する「2001年・・」のHALの歌うシーンへのリンクもあります。)


これ、「唄う」と言う名に恥じず、録音済音声のPCMデータを出すんじゃなくて、フォルマントシンセサイザーです。つまり、初音ミクみたいなもんです。(正確には、初音ミクは録音済音素片を使う連結的合成方式で、今回紹介するスケッチは計算で音声波形をつくるフォルマント合成方式です)

上記動画の工作例では、このPWMの3ピンの出力をアンプ・スピーカーにつないで音を出してますが、今回は、このPWMパルスでレーザー駆動して光変調パルスとして送って、光通信キットで受信とします。
このレーザポインタの駆動は3V 17mA、Arduinoのデジタルピンは5V40mAまでひっぱれます。ですので、間に合わせですし一番安易な方法、抵抗で電圧ドロップさせて、3Vくらいに落としてやっつでやってます。

ということで、スケッチをボードにUploadしてさくっと動作確認できたら、せっかくレーザーなんで相当届くはず!いい絵が取れるぞ! と、近所の公園で、息子に動員かけて手伝わせて実験してみました。


5mくらいから順次長くしていこうと思ったら、実験してみて驚愕のヘタレ事実!工作に使ったレーザーポインタが安物で「ビームが甘すぎ」だったのです。_| ̄|〇… ほんの20mくらいで、ごらんのようにビームがだだ広がりこのあたりが限界のようです。100mは軽いと思ったのですが・・・

このように数mくらいならちゃんとビームなんですが・・・・

本当は公園いっぱい使って、鏡でグラウンドひとまわりの反射衛星砲いっちゃう?とか妄想広がってたのですが・・・安もんですからレンズの歪みか焦点調整の工作精度なのか。まあ、とりあえずこれでご愛嬌とさせてください。


この、実験をやってるときですね、下を向いて腰の高さくらいのビームの位置を確認しながら後ろずさりで「うわ〜だめだ、ダダ広がりじゃん!」とかやってたら、公園でおしゃべりしてるおばさん達がこちらをチラチラ、「あの人何やってるのかしらね?何か落としたのかしらねぇ、なんか変ねぇ」とヒソヒソが聞こえて、そのうち「何落としたの?大丈夫?」と声をかけて下さいました。おばちゃん達ありがとう。不審者でごめんなさい。





●この実験で使った楽曲「デイジー・ベル」について
wikipedia:デイジー・ベル
デイジー・ベルという曲は、1961年に世界で初めてコンピュータが唄った歌。なんですが、むしろ有名なのは、映画「2001年宇宙の旅」のシーンでしょうね。ボーマン船長が、暴走した(高度すぎるゆえに精神障害を起こした)AIコンピュータHAL9000を破壊する過程で幼児がえりしていき?HALが幼少期?に覚えた、このデイジー・ベルを歌いだすという、怖〜いシーンです。このHALがデイジー・ベル歌うというのは、作者のA・C・クラークが実際にIBM7094のデモを見ていたく感銘したからだそうです。

この動画がその解説。(この動画ではなぜキューブリックが?となっていますが、クラークのアイディアと思います)
なお、「2001年・・」で素晴らしいと思うのは、上記動画にあるようにボーマンが壊していくHALの中枢がなにかクリスタル状のモジュールからなっている事です。
光演算回路?フォトンを扱う量子コンピューティング素子?って感じで。へたに現代の回路基板にしてないために時代普遍性を出してるのが本当にハイセンスです。
ボード間ばかりでなくチップ内の信号光化も研究されてたと思うので、2001年には間に合わなかったけどホントに近未来はこういうモジュールになったりして・・・
そういえば、HALの壊れ方も、ゲシュタルトを維持しつつ壊れる感じで、ホロニックな構造を伺わせるなど、未来の人工知能としてリアリティありました。
そういえば、確か手塚治虫も「2001年・・」のアドバイザーで声かかってたのですよね。当時虫プロ立ち上げたばかりという事情で辞退なさったという事ですが・・・ちと残念。


●ちょっとプログラムの解説
上記リンクからArduionoのスケッチはダウンロードできます。依存ライブラリもないしスケッチには歌唱データつきなので、落としてボードにUploadしてPWM3ピンの出力を音声化すればどなたも、すぐに歌わせられると思います。

◯音声のPWM変調について(初心者向け)
PWM自体については、
http://www.musashinodenpa.com/arduino/ref/index.php?f=2&pos=152
とか、前回のエントリー中にもデジタルのPWMがアナログ的にはどう感じるかの理屈をごらんください。

ArduionoのPWM端子って、analogWrite()で値を設定すると、PWM(Pulse Width Modulation)を自動的に制御してくれて、ONとOFFのいい塩梅の比率になったパルスを設定してくれるんですが、
応答速度は、デフォルト(多分プレスケール1/64 490Hz)だと遅過ぎです。(まあ、基本このPWMってデフォルトの意識はモータとか制御用ですからね。音声帯域は考えてない)
8パルスで1つのアナログ値ですから、490Hzのパルス周期だと、アナログ平滑して表現できる値の変化の周波数は、490/8=61Hz つまり、61Hzサイン波ならなら表現できると。しかし、ラの音が440Hzですから、ただの正弦波のメロディレベルでも表現できません。 歌うとかしゃべるとかのレベルはありません。(たとえば人の声としっかり分かる程度の音色表現には、少なくとも4KHz(fsでいうと8KHz)くらいまでの周波数を表現できることが最低レベルといわれています。ちなみにCDでは、fs=44.1KHzだから、22KHzという高い音の成分による複雑な波形=音色を表現できるということになります)

なので、このプログラムでは、

TCCR2A = _BV(COM2B1) | _BV(WGM20);
TCCR2B = _BV(CS20);
TIMSK2 = _BV(TOIE2);

とやって、PWMの周波数を 31.5kHzにします。これ実際には、fsとして31.5/8 =3.9KHz なので、表現できる音は最高で1.9KHzで、かつPWMの相当ノイジーであることはしょうがありません。(あと、この光通信キットの受信機にせめて、2kHzのローパスがあるとよかったですが)

◯歌唱データテーブルについて
で、このプログラムの凄いところは、前述したようにPCM波形を出すのでなく、音素片と変調とピッチをテーブルに従って処理して、その場の歌声を合成するわけです。
私も正直、プログラムを全部追ってないですが、解説文によれば、二つの正弦波と一つの矩形波を合成して また位相変調を調整することで無声音もだせるとのことです。

uint8_t frameList[] PROGMEM = {
_Da,3,0,39,_Db,1,0,39,_Dc,1,3,39,_EY,8,6,39,_YX,20,3,39, // Dai..
_Z,10,0,36,_IY,35,3,36, // ..sy

(PROGMEMというのは、この配列をRAMでなくROM領域に配置しろという命令です。なにせデータがでかいので、RAMにおくとあふれちゃうので。)
上述のように、基本的に、『音素データ、長さ、変調?、ピッチ』という4バイト組でフレームと呼ぶ一つの単位です。ピッチは27がC4(ド)のようです。半音で1つ上がるごとに+1です。なので31だとミです。
時間長さは15msが1単位っぽいですが、まあ適当に。
http://code.google.com/p/tinkerit/wiki/Cantarino のテーブルも参考にしました。基本的にあまりわかりやすいドキュメントがダウンロードページにはない感じです。
母音と子音で一つの音が多いですが、複数の子音を複雑に組み合わせる必要があるようですが、そのあたりはぜんぜん理解しておりません。


Perfumeの『レーザービーム』を歌わせよう!
さてそれじゃ、曲を変えてみましょう。ターゲットはもちろん、発売が待ちどおしい、Pefumeの新譜、「レーザービーム」で。

曲を変える場合には、前述のように

uint8_t frameList[] PROGMEM = {…..}

のテーブルデータだけ変えれば良いようです。

で、さすがにやっつけなんでフルコーラスはやめといて、決めのフレーズ 「にっじっい~ろの、ラブビーム」のくだりだけやってみました。
とりあえず、formantTable[]を参照するIndexとするためenum された、_AHとか_UHとかが
一応音と対応しているらしいので、それでそれでさぐりさぐりやりました。

でまあ、10−20分くらい格闘して、ギリ聞こえるようになったかな?ってのが以下です。

//Perfume "Laser beam"
uint8_t frameList[] PROGMEM = {
_N,3,0,32, _IH,16,10,32, //Ni
_ZH,3,0,39,_IH,24,10,39, //Ji
_IH,8,10,37, //I
_ER,4,10,34, //Ro
_OH,4,0,30, //No
_L,2,0,32,_AA,4,10,32, //Ra
_V,3,5,39,_UH,3,5,39, //Bu
_Ba,1,0,33,_Bb,2,0,33,_IH,8,10,33, //Bi
_IH,8,10,30, //I
_M,3,3,27,_UH,8,5,27, //Mu
};

そういえば、ご存じ無い方のために元曲の「レーザービーム」について。
上記フレーズは、以下のPV動画 0:35あたりです。

(※公式PV動画公開に伴い、以前のCMの動画リンクから変更しました 5/21)