Slide 1

Slide 1 text

ドット絵シーケンサ 技術的うらばなし Web Music ハッカソン #4 @京都 Jul 25, 2015

Slide 2

Slide 2 text

• armorik83 • 京都市 • Webエンジニア • 元音楽屋、MIDI講師

Slide 3

Slide 3 text

Web Music ハッカソン?

Slide 4

Slide 4 text

• Web MIDI API (Chrome 43) • Web Audio API (Chrome 35) • これらのAPIを活用するハッカソン • 第四回は西日本初の大会で、京都市で開催

Slide 5

Slide 5 text

• MIDI検定1級所持 • MIDI検定認定講師資格も所持
 (専門学校で講師をしていました) • 今はWebの仕事をしている • 出場するしかない • 今回は初ハッカソン

Slide 6

Slide 6 text

チーム編成

Slide 7

Slide 7 text

• armorik83 • _likr • pastelinc • ussy9

Slide 8

Slide 8 text

• armorik83 from ng-kyoto • _likr from ng-kyoto • pastelinc from ng-kyoto • ussy9 (内輪感あるチームに快く参加していただきありがとうございました)

Slide 9

Slide 9 text

3人もng-kyoto 宣伝 [ng-kyoto Angular Meetup #2] [検索]

Slide 10

Slide 10 text

何をつくろう

Slide 11

Slide 11 text

DAWでこういう遊びをした人、居るはず

Slide 12

Slide 12 text

音符をドットに見立てて絵が描けるやつ作るか!

Slide 13

Slide 13 text

で、こんなん作りました

Slide 14

Slide 14 text

設計

Slide 15

Slide 15 text

• ドット絵が描ける • ドットは鍵盤(MIDIキーボード)にて入力 • 現在のカーソルにドットが置かれたら
 カーソルは右に動く(DAWのステップ入力的) • 領域外の低音を弾くとカーソルは左右に自由に動かせる

Slide 16

Slide 16 text

• ドットは2値ではなくベロシティによる濃淡表現が可能 • MIDIは16チャンネルまであるので
 チャンネルごとの色分けで最大16色使用可 • 1ドットは16分音符1個に対応 • 縦1ドットが半音単位だと不協和音が頻発するので
 スケール(旋律:長調、短調、Blues風など…)を選択し
 シーケンサ上のドット絵でありながら調性が整う

Slide 17

Slide 17 text

• ドットは2値ではなくベロシティによる濃淡表現が可能 • MIDIは16チャンネルまであるので
 チャンネルごとの色分けで最大16色使用可 • 1ドットは16分音符1個に対応 • 縦1ドットが半音単位だと不協和音が頻発するので
 スケール(旋律:長調、短調、Blues風など…)を選択し
 シーケンサ上のドット絵でありながら調性が整う 元音楽屋として、ここかなりこだわらせてもらった

Slide 18

Slide 18 text

• Firebaseによる複数人同時編集 • WebGLによる3D表現 • DAWではない、Webっぽさを意識

Slide 19

Slide 19 text

技術選定

Slide 20

Slide 20 text

• Web MIDI API • AngularJS • Firebase • SVG • WebGL • 独自ライブラリ

Slide 21

Slide 21 text

• ハッカソンにおいて最重要APIなのだが
 4人の作業時間を合わせると、扱った時間は一番短い • InputもOutputも取り扱う • Web Audio APIは使用していない Web MIDI API

Slide 22

Slide 22 text

• UIとアプリケーションの中枢はAngularJS 1.4.3を採用 • 経験者が75%という強み • 改めてモックアップを作るのに最適な
 フレームワークだと実感 AngularJS

Slide 23

Slide 23 text

• 永続化 • 複数人同時編集の同期 • Web Music ハッカソンがGDG主催なので(?) Firebase

Slide 24

Slide 24 text

• UIの描画はすべてSVG • D3.jsを使用 • 配列の可視化に強い SVG

Slide 25

Slide 25 text

• ussy9さんのアイデア • three.jsで利用 • 音の再生にあわせてイイ感じに3D演出が動く! WebGL

Slide 26

Slide 26 text

• MIDI入力をグリッドの座標に変換
 座標をMIDI出力に変換するためのロジック • 入った数値を内部の関数によって変換する
 単純なコンバータ • 前例が無いのでライブラリ的に実装 独自ライブラリ

Slide 27

Slide 27 text

担当者

Slide 28

Slide 28 text

• Web MIDI API: pastelinc, armorik83 • AngularJS: _likr • Firebase: _likr • SVG: _likr • WebGL: ussy9 • 独自ライブラリ: armorik83

Slide 29

Slide 29 text

ぱんだ無双!!

Slide 30

Slide 30 text

作業開始

Slide 31

Slide 31 text

• GitHubにリポジトリ立ち上げて作業 • 全員Gitの知識があったのでPRベースのチーム開発 • Slackもすぐに立ち上げ、進捗や口で伝えにくい部分 (ソース周りなど)をチャットで相談 • 口頭で話しつつ、参考サイトのURLなどを貼っていく • GitHubと連携させてPR情報がドンドン入ってくるの
 めちゃ便利だった

Slide 32

Slide 32 text

• AngularJS周りは_likrが整備(AngularJSのベテラン強い) • 当たり前のようにES2015 Babel + Browserify • `npm run watch` によるwatchifyベースの開発 • CSSなし、gulpなし、ESLintなし、テストなしの
 ハッカソンらしい軽量装備(少ないほどチーム内に広めやすい) • AngularJS周りの設計については
 ng-kyoto Angular Meetup #2で詳しく話す

Slide 33

Slide 33 text

• 仕様の詳細を決める • ドットは縦40, 横64とする • 縦は、スケールの周期が5音〜7音のため
 6〜8オクターブ必要となることから限界の40 • 横は、4分の4拍子4小節分の16分音符数から算出
 将来的にはいくらでも可能(なはず)

Slide 34

Slide 34 text

• データ構造的には[[0..39], [0..39]..[0..39]]
 length 40の配列を格納するlength 64の配列 • 音符(Note)は3プロパティを持つ • NoteNumber • Velocity • Channel • 意図的にMIDI仕様と同じ構造にした

Slide 35

Slide 35 text

• ハッカソン時間内で全てのプロパティが有効に
 活用されなかったとしても、VelocityやChannel値は
 今後の表現に活用できるため省略せず含ませた • 絶対時間情報も持たせない • Note OnとNote Offの送出時間差で
 音符の長さを表現 • これもMIDI仕様に従っている

Slide 36

Slide 36 text

• AngularJSのアプリケーション中枢が
 非MIDIのNote onやNote offイベントをpubする • イベントを受けたMIDIプレイヤーと3Dレンダラーが
 それぞれ作用する • MIDIプレイヤーはイベントに合わせて
 生のMIDI Note on/offを送信 • 3DレンダラーはVelocity値などを活用し
 three.js APIを叩いて表現(この辺担当してなくて詳しくない)

Slide 37

Slide 37 text

• MIDIインタフェース(受信側)は鍵盤から入力された NoteNumber(ドレミに番号を振ったもの)を
 変換ライブラリを通して座標のY値に変換する • 変換ライブラリは2時間足らずで作成
 テスト駆動でやりたかったので、別リポジトリを立ち上げ
 gulpのwatchとMochaでガンガン回しながら開発 • gulpは定番構成を使ったので3分で開発開始できた • 普段からハッカソン用スケルトンみたいなのがあると強い

Slide 38

Slide 38 text

アーキテクチャ

Slide 39

Slide 39 text

8FC.*%*"1* .BJO$POUSPMMFS 锃侭䕵 WJTVBMJ[FS 8FC(-䬐䔲%JSFDUJWF HSJE ء٦؛ٝ؟邌爙䬐䔲%JSFDUJWF BOHVMBSNPEVMF 'JSFCBTF 宕竲⻉ծ醱侧،ؙإأ儗ךⰟ剣 .*%**OQVU .*%*Ⰵ⸂Ⳣ椚4FSWJDF .*%*1MBZFS .*%*⳿⸂4FSWJDF $POWFSUFS .*%*/PUF/VNCFS׾䏟垥ח 䏟垥׾.*%*/PUF/VNCFSח バックエンド フロントエンド ブラウザAPI層

Slide 40

Slide 40 text

結果と反省点など

Slide 41

Slide 41 text

で、こんなんできました

Slide 42

Slide 42 text

• 受賞して景品を頂きました! (Thanks!)

Slide 43

Slide 43 text

• WebGL全般 • 旋律に応じてMIDIを座標に変換するコンバータ • 旋律選択(長調とBluesのみ) • MIDI入力に合わせて画面にドットが点灯 • MIDIを出力してソフトシンセ(Cubase使用)で発音 • Firebaseでの編集同期 できたところ

Slide 44

Slide 44 text

• ChannelやVelocityに応じた色の変化(今は黒一色) • カーソルを自由に動かせる機能
 今はドットを入力しないと隣にカーソルが移動しない やってないところ

Slide 45

Slide 45 text

• 40*64の配列の編集はかなり重いのか
 同期がとにかく遅い • 開発中にスクリーンを真っ白にする機能をまるで
 忘れていて、デモ中に1から点を打っていく演出が
 できなかった • 開発中の大量の点があったためデモ再生で一斉に
 音が鳴り、旋律選択があまり伝わっていなかった 惜しかったところ

Slide 46

Slide 46 text

• MIDI入力部分のフォローが足りていなかった
 (最重要機能で完成も一番ギリギリ) • Web MIDI APIの予習はもうちょっとしておくべきだった • デバイスポート周り、端末依存しそうなコードを
 いかに抽象化できるか • けっこう低レイヤーで直接叩くと使いにくいという学び • 今回はDAWのソフトシンセ依存だったので可搬性・再現性が悪い
 Web Audio APIのシンセと組み合わせたらブラウザ内で完結できそう 個人的な反省点

Slide 47

Slide 47 text

• 反省点はありつつも、6時間でここまで作れたことは自分でも驚いた • ES2015はチーム内のコーディングを
 ある程度整えるポテンシャルがある(他言語のclass構文経験者なら余裕) • AngularJSのイベント駆動でインタフェースや内部APIを実装より
 先に定めたおかげで、双方ブロッキングせずに開発が進んだ • 細かいところは詰まってないがシーケンサは
 ブラウザのみでも十分作れる(要パフォーマンス・チューニング) 感想

Slide 48

Slide 48 text

• この人数・納期規模の開発だと
 とにかく設計力 & 実装力(あと地味に命名力) • ここが高ければ高いほど初速が良く、全体が進みだす • 配列処理周りのアルゴリズム・API暗記は必須と痛感 • 今後、だいたい開始時に出たアイデアの7割が
 達成ギリギリラインだと見積もっていく 今後の課題

Slide 49

Slide 49 text

• 今回のハッカソンで制作した『ドット絵シーケンサ』は
 オープンソースカンファレンス2015 Kansai@Kyoto
 のng-kyotoブースにて展示します • 8月7-8日 京都リサーチパークで開催
 http://www.ospn.jp/osc2015-kyoto/ • ぜひ遊びにきてね 宣伝

Slide 50

Slide 50 text

お疲れさまでした!