aike’s blog 2018-12-31T18:48:28+09:00 aike Hatena::Blog hatenablog://blog/10257846132645764894 写真から素数を文字認識するアプリ作ったよ hatenablog://entry/10257846132693484174 2018-12-31T18:48:28+09:00 2018-12-31T18:48:28+09:00 作ったもの 目にした数字が素数かどうかって気になってしょうがないですよね。そんなわけで、カメラで撮影した画像中の数字を認識して素数かどうか判定するアプリを作りました。 https://aikelab.net/primelens/ 使い方 ファイル選択ボタンを押して判定したいの数字が写っている写真を指定します。このとき「写真を撮る」を選ぶとカメラで撮影した画像を保存せずにそのまま使うこともできます。例として、未読メール数字が表示されているスマホのスクリーンショット画像を使ってみます。 画像を選択したらすぐにサーバに送信され数秒で結果が返ります。1129も83も素数でした!来年は良い年になりそう。… <h1>作ったもの</h1> <p>目にした数字が<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C1%C7%BF%F4">素数</a>かどうかって気になってしょうがないですよね。そんなわけで、カメラで撮影した画像中の数字を認識して<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C1%C7%BF%F4">素数</a>かどうか判定するアプリを作りました。</p> <p><figure class="figure-image figure-image-fotolife mceNonEditable" title="スクリーンショット"></p> <p><img class="hatena-fotolife" title="f:id:aike:20181231182513p:plain" src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20181231/20181231182513.png" alt="f:id:aike:20181231182513p:plain" width="231px" height="400px" /></p> <p></figure></p> <div style="text-align: center;"> <span style="font-size: 120%;"><a href="https://aikelab.net/primelens/">https://aikelab.net/primelens/</a></span><br> <img class="hatena-fotolife" title="f:id:aike:20181231183310p:plain" src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20181231/20181231183310.png" alt="f:id:aike:20181231183310p:plain" width="80px" height="80px" /> </div> <h1>使い方</h1> <p>ファイル選択ボタンを押して判定したいの数字が写っている写真を指定します。このとき「写真を撮る」を選ぶとカメラで撮影した画像を保存せずにそのまま使うこともできます。例として、未読メール数字が表示されている<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%DE%A5%DB">スマホ</a>の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%AF%A5%EA%A1%BC%A5%F3%A5%B7%A5%E7%A5%C3%A5%C8">スクリーンショット</a>画像を使ってみます。</p> <div style="text-align: center;"> <span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20181231/20181231180353.jpg" alt="f:id:aike:20181231180353j:plain" title="f:id:aike:20181231180353j:plain" class="hatena-fotolife" itemprop="image"></span> </div> <p> </p> <p>画像を選択したらすぐにサーバに送信され数秒で結果が返ります。1129も83も<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C1%C7%BF%F4">素数</a>でした!来年は良い年になりそう。ほかにも時計の数字や車のナンバーを撮影して、さっといつでも<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C1%C7%BF%F4">素数</a>判定することができます。便利。</p> <div style="text-align: center;"> <span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20181231/20181231183626.png" alt="f:id:aike:20181231183626p:plain" title="f:id:aike:20181231183626p:plain" class="hatena-fotolife" itemprop="image"></span> </div> <p>   <br/>  <br/>  </p> <h1>使った技術</h1> <ul> <li><a href="https://reactjs.org/">React</a></li> <li><a href="https://cloud.google.com/vision/">Google Cloud Vision API</a></li> </ul> <p>例によってReactとCloud <a class="keyword" href="http://d.hatena.ne.jp/keyword/Vision">Vision</a> <a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>です。 正しく判定できる最大値は9007199254740991 (Number.MAX_SAFE_INTEGER)、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C1%C7%BF%F4">素数</a>判定はこちらのcheck-primeを使っています。シンプルな試し割り法ですが、いくつか試した中で今回の用途にはもっとも安定していて速度も十分でした。</p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fgithub.com%2Fvikramcse%2Fcheck-prime" title="vikramcse/check-prime" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;"></iframe><cite class="hatena-citation"><a href="https://github.com/vikramcse/check-prime">github.com</a></cite></p> <p>おしまい。</p> <p>   </p> <p><a href="https://aikelab.net/primelens/">素数レンズ</a> <a href="https://github.com/aike/primelens/">Github</a>  </p> <p><a href="https://atnd.org/events/102652">大晦日ハッカソン2018</a>  </p> aike 写真から電話番号を文字認識するアプリ作ったよ hatenablog://entry/10257846132680776453 2018-12-09T00:12:59+09:00 2018-12-09T00:12:59+09:00 作ったもの カメラで撮影した電話番号画像を認識して電話がかけられるスマホ用Webアプリです。 https://aikelab.net/denwalens/ 使い方 ファイル選択ボタンを押して電話番号の数字が写っている写真を指定します。このとき「写真を撮る」を選ぶとカメラで撮影した画像を保存せずにそのまま使うこともできます。 画像を選択したらすぐにサーバに送信され数秒で結果が返ります。画像の中に電話番号と解釈できる文字列があれば画面下にリンクとして表示されます。さまざまなフォントや手書き文字もわりといい感じに認識します。 リンクをタップすると発信ダイアログが出て電話をかけられます*1。まずは無料… <h1>作ったもの</h1> <p>カメラで撮影した電話番号画像を認識して電話がかけられる<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%DE%A5%DB">スマホ</a>用Webアプリです。</p> <p><figure class="figure-image figure-image-fotolife mceNonEditable" title="スクリーンショット"></p> <p><img class="hatena-fotolife" title="f:id:aike:20181205145655p:plain" src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20181205/20181205145655.png" alt="f:id:aike:20181205145655p:plain" width="231px" height="400px" /></p> <p></figure></p> <div style="text-align: center;"> <span style="font-size: 120%;"><a href="https://aikelab.net/denwalens/">https://aikelab.net/denwalens/</a></span><br> <img class="hatena-fotolife" title="f:id:aike:20181205194555p:plain" src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20181205/20181205194555.png" alt="f:id:aike:20181205194555p:plain" width="80px" height="80px" /> </div> <h1>使い方</h1> <p>ファイル選択ボタンを押して電話番号の数字が写っている写真を指定します。このとき「写真を撮る」を選ぶとカメラで撮影した画像を保存せずにそのまま使うこともできます。</p> <div style="text-align: center;"> <span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20181205/20181205200029.png" alt="f:id:aike:20181205200029p:plain" title="f:id:aike:20181205200029p:plain" class="hatena-fotolife" itemprop="image"></span> </div> <p> </p> <p>画像を選択したらすぐにサーバに送信され数秒で結果が返ります。画像の中に電話番号と解釈できる文字列があれば画面下にリンクとして表示されます。さまざまなフォントや手書き文字もわりといい感じに認識します。</p> <div style="text-align: center;"> <span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20181205/20181205201805.png" alt="f:id:aike:20181205201805p:plain" title="f:id:aike:20181205201805p:plain" class="hatena-fotolife" itemprop="image"></span> </div> <p> </p> <p>リンクをタップすると発信ダイアログが出て電話をかけられます<a href="#f-bf1a0261" name="fn-bf1a0261" title="連続して利用すると「このWebサイトから自動的に電話をかけることは禁止されています」というダイアログが出ることがありますが、その場合は「通話を許可」すれば発信できます">*1</a>。まずは無料お試しセットから。</p> <div style="text-align: center;"> <span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20181206/20181206093046.png" alt="f:id:aike:20181206093046p:plain" title="f:id:aike:20181206093046p:plain" class="hatena-fotolife" itemprop="image"></span> </div> <p> <br/>  <br/>  <br/> 画面下の共有ボタンをタップして「ホーム画面に追加」でアイコンを作っておくとネイティブアプリのようにすぐ起動できて便利。</p> <div style="text-align: center;"> <span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20181205/20181205200012.png" alt="f:id:aike:20181205200012p:plain" title="f:id:aike:20181205200012p:plain" class="hatena-fotolife" itemprop="image"></span> </div> <p> </p> <h1><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E6%A1%BC%A5%B9%A5%B1%A1%BC%A5%B9">ユースケース</a></h1> <p>たとえばあなたの洗濯機が夜中に水漏れしたとする。しかしサポート業者の電話受付は10時-17時なのだ。そこであなたはとりあえず連絡先の電話番号をメモ代わりに写真に撮っておく。</p> <p>翌日、勤務先で空き時間に業者へ電話をかけようとして、あなたははたと困る。なんと驚くべきことに、<a class="keyword" href="http://d.hatena.ne.jp/keyword/iPhone">iPhone</a>は写真ライブラリを見ながら電話をかけることができないのだ。最近の<a class="keyword" href="http://d.hatena.ne.jp/keyword/iPad">iPad</a>のように2画面分割することもできず、どんなことをしようと電話の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AD%A1%BC%A5%D1%A5%C3%A5%C9">キーパッド</a>を表示すると写真が隠れてしまう。これが名高いヒューマンインタフェース<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AC%A5%A4%A5%C9%A5%E9%A5%A4%A5%F3">ガイドライン</a>か、これが世界の選択か。人生に疲れたあなたは天を仰ぎ、思いつく限り呪詛の言葉を叫び続けることだろう。  </p> <div style="text-align: center;"> * * * </div> <p> <br/> 写真に撮った電話番号にかけたい場面はわりとあるように思います。上記のような大型家電のサポート、自販機で商品が出てこないトラブル、移動中に気になる看板広告を見かけたとき、テレビCMの電話番号など、いずれも何かの事情でその場では電話できず、カメラでメモしておいて後で連絡するような状況です。そしてこれらは1回かけたらたぶんもう使わない、電話帳に登録するにはちょっと躊躇するような番号です。</p> <p>以前、困り果てて<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C4%A5%A4%A5%C3%A5%BF%A1%BC">ツイッター</a>で何か良い方法がないか募ってみました。</p> <blockquote class="twitter-tweet" data-lang="ja"> <p dir="ltr" lang="ja">【緩募】<a class="keyword" href="http://d.hatena.ne.jp/keyword/iPhone">iPhone</a>で、電話番号が書かれた紙の写真を見ながら電話かける方法。</p> — aike (@aike1000) <a href="https://twitter.com/aike1000/status/1050601499506536448?ref_src=twsrc%5Etfw">2018年10月12日</a></blockquote> <p> <script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> </p> <p>このとき<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B7%EB%BE%EB%B9%C0">結城浩</a>さんからいただいたア<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%C7%A5%A2">イデア</a>は、公式メモアプリに電話番号を書くと自動でリンクになることを利用して、メモに貼り付けた写真を見ながら番号をタイプする、というものでした。</p> <blockquote class="twitter-tweet" data-lang="ja"> <p dir="ltr" lang="ja">できました。写真からシェアメニューで「メモに追加」して、メモ帳に移って、写真見ながらタイプ。そして番号をタップ。</p> — <a class="keyword" href="http://d.hatena.ne.jp/keyword/%B7%EB%BE%EB%B9%C0">結城浩</a> (@hyuki) <a href="https://twitter.com/hyuki/status/1050606554741796864?ref_src=twsrc%5Etfw">2018年10月12日</a></blockquote> <p> <script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> </p> <p>この方法であれば10桁程度の数字を短期記憶する必要がないのでかなり楽になります。とはいえ、全桁打ち直すのはもう少しなんとかならないものか。  <br/>  </p> <p>最近話題の<a href="https://japanese.engadget.com/2018/10/09/pixel-3-google/">Googleレンズ</a>は、カメラ映像や写真からテキストをはじめかなり高度な各種情報の画像認識をするようです。<a class="keyword" href="http://d.hatena.ne.jp/keyword/iPhone">iPhone</a>でも<a class="keyword" href="http://d.hatena.ne.jp/keyword/Google">Google</a>フォトアプリの一機能として使えるみたいです。ただ、そのために<a class="keyword" href="http://d.hatena.ne.jp/keyword/iOS">iOS</a>標準とは異なる写真ライブラリ管理アプリを入れるのも大仰な気がします。<a href="#f-2f2cb2ca" name="fn-2f2cb2ca" title="追記:この記事を投稿した3日後にiOS向けGoogleレンズの提供を開始したと公式アナウンスがありました https://japan.cnet.com/article/35130001/ 頑張って作ったアプリが3日で役目を終える気持ちを皆さんちょっとでいいので想像してみてください">*2</a>  <br/>  <br/> つまり、ぼくらがほしいのは<strong>電話番号だけ認識する<a class="keyword" href="http://d.hatena.ne.jp/keyword/Google">Google</a>レンズの単機能版</strong>なのです。そんなわけで「電話番号専用<a class="keyword" href="http://d.hatena.ne.jp/keyword/Google">Google</a>レンズもどき(怒られそうなので仮称)」、略して「電話レンズ(仮)」を作りました。  <br/>  <br/>  </p> <h1>使った技術</h1> <ul> <li><a href="https://reactjs.org/">React</a></li> <li><a href="https://cloud.google.com/vision/">Google Cloud Vision API</a></li> </ul> <p>Reactは、まあなんというか勉強中なのでとりあえず使ってみた感じ。機能を追加するたびに複雑になっていくアプリを、DOMっぽい単位で<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%DD%A1%BC%A5%CD%A5%F3%A5%C8">コンポーネント</a>化することで考えることをシンプルに保つことができるのは慣れると快適ですね。慣れるまでに3年かかりましたが。</p> <p>Cloud <a class="keyword" href="http://d.hatena.ne.jp/keyword/Vision">Vision</a> <a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>は、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Google">Google</a>の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B5%A1%B3%A3%B3%D8%BD%AC">機械学習</a>技術で画像に何が写っているかを認識してくれるめちゃくちゃすごい<a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>。今回のアプリはCloud <a class="keyword" href="http://d.hatena.ne.jp/keyword/Vision">Vision</a> <a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>にガワをつけただけの200行くらいのシンプルなプログラムです。 <a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>に送る処理は<a href="http://otiai10.hatenablog.com/entry/2016/05/22/182826">この辺の記事</a>を参考にコピペ。ぼくの人生だいたいコピペ。  </p> <pre class="code lang-javascript" data-lang="javascript" data-unlink> <span class="synIdentifier">let</span> body = <span class="synIdentifier">{</span> requests: <span class="synIdentifier">[</span> <span class="synIdentifier">{</span>image: <span class="synIdentifier">{</span>content: base64string<span class="synIdentifier">}</span>, features: <span class="synIdentifier">[{</span>type: <span class="synConstant">'TEXT_DETECTION'</span><span class="synIdentifier">}]}</span> <span class="synIdentifier">]</span> <span class="synIdentifier">}</span>; <span class="synIdentifier">let</span> xhr = <span class="synStatement">new</span> XMLHttpRequest(); <span class="synStatement">const</span> url = <span class="synConstant">'https://vision.googleapis.com/v1/images:annotate?key='</span>+key; xhr.open(<span class="synConstant">'POST'</span>, url, <span class="synConstant">true</span>); xhr.setRequestHeader(<span class="synConstant">'Content-Type'</span>, <span class="synConstant">'application/json'</span>); <span class="synStatement">const</span> p = <span class="synStatement">new</span> Promise((resolve, reject) =&gt; <span class="synIdentifier">{</span> xhr.onreadystatechange = () =&gt; <span class="synIdentifier">{</span> <span class="synStatement">if</span> (xhr.readyState !== XMLHttpRequest.DONE) <span class="synStatement">return</span>; <span class="synStatement">if</span> (xhr.<span class="synStatement">status</span> &gt;= 400) <span class="synStatement">return</span> reject(<span class="synIdentifier">{</span>message: `Failed <span class="synStatement">with</span> $<span class="synIdentifier">{</span>xhr.<span class="synStatement">status</span><span class="synIdentifier">}</span>:$<span class="synIdentifier">{</span>xhr.statusText<span class="synIdentifier">}</span>`<span class="synIdentifier">}</span>); resolve(JSON.parse(xhr.responseText)); <span class="synIdentifier">}</span>; <span class="synIdentifier">}</span>) xhr.send(JSON.stringify(body)); </pre> <p> </p> <p>認識結果は<a class="keyword" href="http://d.hatena.ne.jp/keyword/JSON">JSON</a>で返ってきます。断片的な言葉の切れ端が多いので、そこから意味のある単語を見つけ出すのが腕の見せどころです。ここでは、最初に<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C0%B5%B5%AC%C9%BD%B8%BD">正規表現</a>を使って、数字、ハイフン、カッコ、スペースが並んでいたら電話番号っぽい文字列と判断して抽出して、次に抽出した文字列からさらに数字だけ抜き出して10〜11桁なら電話番号と最終判断しています。</p> <pre class="code lang-javascript" data-lang="javascript" data-unlink> <span class="synStatement">const</span> arr_annotations = json.responses<span class="synIdentifier">[</span>0<span class="synIdentifier">]</span>.textAnnotations; <span class="synStatement">const</span> tel_numbers = <span class="synIdentifier">[]</span>; arr_annotations.forEach((item) =&gt; <span class="synIdentifier">{</span> <span class="synComment">// 高速化のために短すぎる文字列はここで無視する</span> <span class="synStatement">if</span> (item.description.length &gt;= 10) <span class="synIdentifier">{</span> <span class="synStatement">const</span> str = item.description; <span class="synComment">// 数字、ハイフン、カッコ、スペースの連続を電話番号とみなす</span> <span class="synStatement">const</span> match_str = str.match(<span class="synConstant">/[\d\-() ]+/g</span>); <span class="synComment">// 電話番号が存在するか</span> <span class="synStatement">if</span> (match_str !== <span class="synStatement">null</span>) <span class="synIdentifier">{</span> <span class="synComment">// 電話番号が複数存在する場合を考慮してループ</span> match_str.forEach((item) =&gt; <span class="synIdentifier">{</span> <span class="synComment">// ハイフン、カッコ、スペースを削除して数字のみを得る</span> <span class="synStatement">const</span> num = item.replace(<span class="synConstant">/[-() ]/g</span>, <span class="synConstant">''</span>); <span class="synComment">// 数字のみで10〜11桁のものを電話番号として配列にする</span> <span class="synStatement">if</span> ((num.length &gt;= 10) &amp;&amp; (num.length &lt;= 11)) <span class="synIdentifier">{</span> tel_numbers.push(<span class="synIdentifier">{</span>str:item, num:num<span class="synIdentifier">}</span>); <span class="synIdentifier">}</span> <span class="synIdentifier">}</span>); <span class="synIdentifier">}</span> <span class="synIdentifier">}</span> <span class="synIdentifier">}</span>); </pre> <p> </p> <p>数字の頭に“tel:"という文字列をくっつけてリンクにすると電話をかけるリンクになります。</p> <pre class="code lang-javascript" data-lang="javascript" data-unlink> <span class="synStatement">const</span> hash = <span class="synIdentifier">{}</span>; tel_numbers.forEach(item =&gt; <span class="synIdentifier">{</span> <span class="synComment">// 重複チェック</span> <span class="synStatement">if</span> (!hash<span class="synIdentifier">[</span>item.num<span class="synIdentifier">]</span>) <span class="synIdentifier">{</span> hash<span class="synIdentifier">[</span>item.num<span class="synIdentifier">]</span> = <span class="synConstant">true</span>; <span class="synStatement">const</span> <span class="synStatement">parent</span> = <span class="synStatement">document</span>.querySelector(<span class="synConstant">'#resultarea'</span>); <span class="synStatement">const</span> li = <span class="synStatement">document</span>.createElement(<span class="synConstant">'li'</span>); <span class="synStatement">const</span> a = <span class="synStatement">document</span>.createElement(<span class="synConstant">'a'</span>); a.innerText = item.str; a.href = <span class="synConstant">'tel:'</span> + item.num; li.appendChild(a); <span class="synStatement">parent</span>.appendChild(li); <span class="synIdentifier">}</span> <span class="synIdentifier">}</span>); </pre> <p>おしまい。</p> <p>   </p> <p><a href="https://aikelab.net/denwalens/">電話レンズ</a> <a href="https://github.com/aike/denwalens/">Github</a>  </p> <p><a href="https://qiita.com/advent-calendar/2018/kuso-app">クソアプリ Advent Calendar 2018</a>  <br/>  <br/>  <br/>  </p> <div class="freezed"> <div class="hatena-asin-detail"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B0776XY6Z3/Lifehacklife-22/"><img class="hatena-asin-detail-image" title="STEINS;GATE ELITE - PS4" src="https://images-fe.ssl-images-amazon.com/images/I/61cfm89Lw0L._SL160_.jpg" alt="STEINS;GATE ELITE - PS4" /></a> <div class="hatena-asin-detail-info"> <p class="hatena-asin-detail-title"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B0776XY6Z3/Lifehacklife-22/">STEINS;GATE ELITE - PS4</a></p> <ul> <li><span class="hatena-asin-detail-label">出版社/メーカー:</span> <a class="keyword" href="http://d.hatena.ne.jp/keyword/5pb.">5pb.</a></li> <li><span class="hatena-asin-detail-label">発売日:</span> 2018/09/20</li> <li><span class="hatena-asin-detail-label">メディア:</span> Video Game</li> <li><a href="http://d.hatena.ne.jp/asin/B0776XY6Z3/" target="_blank">この商品を含むブログを見る</a></li> </ul> </div> <div class="hatena-asin-detail-foot"> </div> </div> </div> <div class="footnote"> <p class="footnote"><a href="#fn-bf1a0261" name="f-bf1a0261" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">連続して利用すると「このWebサイトから自動的に電話をかけることは禁止されています」というダイアログが出ることがありますが、その場合は「通話を許可」すれば発信できます</span></p> <p class="footnote"><a href="#fn-2f2cb2ca" name="f-2f2cb2ca" class="footnote-number">*2</a><span class="footnote-delimiter">:</span><span class="footnote-text">追記:この記事を投稿した3日後に<a class="keyword" href="http://d.hatena.ne.jp/keyword/iOS">iOS</a>向け<a class="keyword" href="http://d.hatena.ne.jp/keyword/Google">Google</a>レンズの提供を開始したと公式アナウンスがありました <a href="https://japan.cnet.com/article/35130001/">https://japan.cnet.com/article/35130001/</a> 頑張って作ったアプリが3日で役目を終える気持ちを皆さんちょっとでいいので想像してみてください</span></p> </div> aike パンはパンでも体の向きによらない3Dパンがでーきた hatenablog://entry/10257846132645780622 2016-12-19T00:00:00+09:00 2016-12-19T00:00:00+09:00 WebAudio Web MIDI API Advent Calendar 2016の19日目です。 せっかちな人のためのデモページリンク。スマホ+イヤホンで聞いてグルグル歩き回ってください。 http://aikelab.net/apan/ Web Audio APIでは、左右だけでなく3Dのパンが用意されています。つまり音の定位を三次元的に配置することができます。 さて、せっかく3Dパンなので、スマホの加速度センサーを使って、聴く人の体の向きによらず空間的に音が配置されるようにしてみましょう。つまり、たとえばイヤホンで音楽を聴きながら横を向くと、それまで左右から聞こえていた音が前後から聞こ… <p><a href="http://qiita.com/advent-calendar/2016/webaudio">WebAudio Web MIDI API Advent Calendar 2016</a>の19日目です。</p><p> </p><p>せっかちな人のためのデモページリンク。<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%DE%A5%DB">スマホ</a>+イヤホンで聞いてグルグル歩き回ってください。<br /> <a href="http://aikelab.net/apan/">http://aikelab.net/apan/</a></p><p> </p><p>Web Audio <a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>では、<a href="http://qiita.com/mohayonao/items/d9bd0f4bd20aab891568">&#x5DE6;&#x53F3;</a>だけでなく3Dのパンが用意されています。つまり音の定位を三次元的に配置することができます。<br /> さて、せっかく3Dパンなので、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%DE%A5%DB">スマホ</a>の加速度センサーを使って、聴く人の体の向きによらず空間的に音が配置されるようにしてみましょう。つまり、たとえばイヤホンで音楽を聴きながら横を向くと、それまで左右から聞こえていた音が前後から聞こえてくる、というようなことです。</p><p> </p><p><a href="https://github.com/aike/AcceleroPanner/blob/master/js/main.js">&#x30BD;&#x30FC;&#x30B9;&#x30B3;&#x30FC;&#x30C9;</a>はこんな感じになります。<br /> まず何はなくともオーディオコンテキストの作成。</p> <pre class="code lang-javascript" data-lang="javascript" data-unlink> <span class="synIdentifier">var</span> ctx = <span class="synStatement">new</span> (<span class="synStatement">window</span>.AudioContext || <span class="synStatement">window</span>.webkitAudioContext)(); </pre><p>Playerは自作のBufferSourceNodeラッパーです。詳しくは<a href="https://github.com/aike/AcceleroPanner/blob/master/js/player.js">player.js</a>を見てください。</p> <pre class="code lang-javascript" data-lang="javascript" data-unlink> <span class="synIdentifier">var</span> player = <span class="synStatement">new</span> Player(ctx, <span class="synConstant">'sound/apan.mp3'</span>); </pre><p>チャンネルスプリッターノードでステレオソースの左chと右chを別々に取り出します。</p> <pre class="code lang-javascript" data-lang="javascript" data-unlink> <span class="synIdentifier">var</span> splitter = ctx.createChannelSplitter(2); </pre><p>パンナーノードで左chの音と右chの音を三次元空間に配置します。</p> <pre class="code lang-javascript" data-lang="javascript" data-unlink> <span class="synIdentifier">var</span> panL = ctx.createPanner(); panL.panningModel = <span class="synConstant">&quot;HRTF&quot;</span>; panL.setPosition(-1, 0, 0); <span class="synIdentifier">var</span> panR = ctx.createPanner(); panR.panningModel = <span class="synConstant">&quot;HRTF&quot;</span>; panR.setPosition(1, 0, 0); </pre><p>ノード同士の接続はこんな感じ。</p> <pre class="code lang-javascript" data-lang="javascript" data-unlink> <span class="synComment">// player ----splitter</span> <span class="synComment">// ---- PanL ---- destination</span> <span class="synComment">// ---- PanR ---- destination</span> player.connect(splitter); splitter.connect(panL, 0); splitter.connect(panR, 1); panL.connect(ctx.destination); panR.connect(ctx.destination); </pre><p>パン回転用のsetAngle関数です。角度を<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E9%A5%B8%A5%A2%A5%F3">ラジアン</a>で受け取ってパンナーノードの位置をY軸を中心に回転します。</p> <pre class="code lang-javascript" data-lang="javascript" data-unlink> <span class="synIdentifier">var</span> setAngle = <span class="synIdentifier">function</span>(theta) <span class="synIdentifier">{</span> <span class="synIdentifier">var</span> sn = Math.sin(theta); <span class="synIdentifier">var</span> cs = Math.cos(theta); panL.setPosition(-cs, 0, sn); panR.setPosition(cs, 0, -sn); <span class="synIdentifier">}</span> </pre><p>加速度センサーのイベント処理。加速度センサーはalpha、beta、gammaの3つの値で表現され、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%DE%A5%DB">スマホ</a>を縦持ちしたときのY軸回転はalphaに対応します。加速度センサーの値は度なので<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E9%A5%B8%A5%A2%A5%F3">ラジアン</a>に変換してから前述のsetAngle関数に渡しています。</p> <pre class="code lang-javascript" data-lang="javascript" data-unlink> <span class="synStatement">window</span>.addEventListener(<span class="synConstant">&quot;deviceorientation&quot;</span>, <span class="synIdentifier">function</span>(e)<span class="synIdentifier">{</span> <span class="synStatement">if</span> (e.alpha) <span class="synIdentifier">{</span> setAngle(e.alpha * Math.PI / 180); <span class="synIdentifier">}</span> <span class="synIdentifier">}</span>); </pre><p> </p><p>デモページはこちらです。<br /> <span class="deco" style="font-size:x-large;"><a href="http://aikelab.net/apan/">http://aikelab.net/apan/</a></span><br /> <a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%DE%A5%DB">スマホ</a>+イヤホンで再生します。<br /> こんな姿勢で<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%DE%A5%DB">スマホ</a>を持ったままグルグル歩き回ってください。<br /> <span itemscope itemtype="http://schema.org/Photograph"><a href="http://f.hatena.ne.jp/aike/20161219022741" class="hatena-fotolife" itemprop="url"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20161219/20161219022741.png" alt="f:id:aike:20161219022741p:image" title="f:id:aike:20161219022741p:image" class="hatena-fotolife" itemprop="image"></a></span></p><br /> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%BD%A1%BC%A5%B9%A5%B3%A1%BC%A5%C9">ソースコード</a>はこちら。<br /> <a href="https://github.com/aike/AcceleroPanner">https://github.com/aike/AcceleroPanner</a></p> aike メーヴェ型飛行具のプロジェクトに参加した話 hatenablog://entry/10257846132645780650 2016-10-13T00:00:00+09:00 2016-10-13T00:00:00+09:00 メーヴェを見にいこうと思ったのは、2014年の夏、5年勤めた会社を辞めて、さてこれからどうしようかというときだった。八谷和彦さんのOpenSkyプロジェクトが北海道で初めて公開テスト飛行をおこなうということを聞いて、特急スーパーカムイに乗って、たきかわスカイパークまでいくことにした。ところが、現地に到着したくらいから天候がくずれ、その日のフライトは中止になった。運もついていない。 その代わり展示された機体を間近でつぶさに観察することができた。M-02Jという正式名称もそのとき知った。離れたところから見ると白くなめらかな機体の曲線に目を奪われるものの、細部はホームセンターにありそうな部材だったり… <p> <a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E1%A1%BC%A5%F4%A5%A7">メーヴェ</a>を見にいこうと思ったのは、2014年の夏、5年勤めた会社を辞めて、さてこれからどうしようかというときだった。<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C8%AC%C3%AB%CF%C2%C9%A7">八谷和彦</a>さんの<a class="keyword" href="http://d.hatena.ne.jp/keyword/OpenSky">OpenSky</a>プロジェクトが北海道で初めて公開テスト飛行をおこなうということを聞いて、特急<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A1%BC%A5%D1%A1%BC%A5%AB%A5%E0%A5%A4">スーパーカムイ</a>に乗って、たきかわスカイパークまでいくことにした。ところが、現地に到着したくらいから天候がくずれ、その日のフライトは中止になった。運もついていない。<br />  <br />  その代わり展示された機体を間近でつぶさに観察することができた。M-02Jという正式名称もそのとき知った。離れたところから見ると白くなめらかな機体の曲線に目を奪われるものの、細部はホームセンターにありそうな部材だったり、自転車用のパーツのようなものをベルクロや補修テープでくくりつけた無骨さ。<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%CA%A5%A6%A5%B7%A5%AB">ナウシカ</a>というより、どちらかというとこれは<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%CF%A5%A6%A5%EB">ハウル</a>だ。アクセル制御にいたっては音楽用ミキサーのフェーダーで、0dBまで上げると<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B8%A5%A7%A5%C3%A5%C8%A5%A8%A5%F3%A5%B8%A5%F3">ジェットエンジン</a>が吠える。<a class="keyword" href="http://d.hatena.ne.jp/keyword/%BB%FE%C2%E5%B9%CD%BE%DA">時代考証</a>が無茶苦茶なテク<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%CE%A5%ED">ノロ</a><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B8%A1%BC">ジー</a>の塊だった。<br />  <br /> <span itemscope itemtype="http://schema.org/Photograph"><a href="http://f.hatena.ne.jp/aike/20140727090818" class="hatena-fotolife" itemprop="url"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20140727/20140727090818.jpg" alt="f:id:aike:20140727090818j:image" title="f:id:aike:20140727090818j:image" class="hatena-fotolife" itemprop="image"></a></span><br />  <br /> <span itemscope itemtype="http://schema.org/Photograph"><a href="http://f.hatena.ne.jp/aike/20140727115750" class="hatena-fotolife" itemprop="url"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20140727/20140727115750.jpg" alt="f:id:aike:20140727115750j:image" title="f:id:aike:20140727115750j:image" class="hatena-fotolife" itemprop="image"></a></span><br />  <br />  1週間後、八谷さんからメッセージが届いた。<br /> 「先日のカメラを機体に取り付けて撮影しませんか?」<br />  公開飛行がおこなわれるはずだった日、空の端から現れて反対側の空へ消えていくM-02Jを撮影しようと、特殊な全天球動画カメラを持っていったのだ。それを地上からではなく機上から撮影できるとは。<br />  <br />  早速、次の週チームに合流した。朝7時、メンバー全員を集めてブリーフィング。驚いたことにすぐに機体の移動補助や飛行記録といった責任ある役割をまかされる。後から知ったことだが、他のメンバーも初参加や2回目などが多かったようだ。<br />  ブリーフィングが終わると次はエンジンの試動。万が一のときのために、少し離れたところから消火器を手に待機する。アニメ調の機体から獰猛な燃焼音が響く。普段はグライダーとプロペラ機しかいない、のどかな飛行場で、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B8%A5%A7%A5%C3%A5%C8%A5%A8%A5%F3%A5%B8%A5%F3">ジェットエンジン</a>は異次元の音だ。地鳴りのようなサブ<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%BD%A5%CB%A5%C3%A5%AF">ソニック</a>と高速回転する金属音。<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%E4%A1%BC%A5%DE%A5%D5">イヤーマフ</a>をしていても頭蓋骨に響きわたる音に意識がゆっくり遠のいていくような気分になる。いまだに実感のわきづらい光景もあいまって現実とSFとが少しずつ融けていくような感覚を味わっていた。<br />  <br /> <span itemscope itemtype="http://schema.org/Photograph"><a href="http://f.hatena.ne.jp/aike/20161012234533" class="hatena-fotolife" itemprop="url"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20161012/20161012234533.jpg" alt="f:id:aike:20161012234533j:image" title="f:id:aike:20161012234533j:image" class="hatena-fotolife" itemprop="image"></a></span><br />  <br />  たった2年前なのに全天球動画撮影環境は今とかなり異なる。専用のカメラなどではなく、6台のGoProカメラを<a class="keyword" href="http://d.hatena.ne.jp/keyword/3D%A5%D7%A5%EA%A5%F3%A5%BF">3Dプリンタ</a>で製作したリグで固定したものだ。これらを<a class="keyword" href="http://d.hatena.ne.jp/keyword/Wi-Fi">Wi-Fi</a>接続のリモコンから操作する。たいていひとつくらい電波が届かずリモコンに反応しないので目視確認して手動で録画開始する。数を重ねるうちに、手鏡を使って確認したり、映画用のカチンコアプリで合図を入れたり、とノウハウがたまっていく。<br />  <br />  撮影した映像はその日のうちにスティッチング。テスト飛行は朝9時には終わるので、昼の空き時間や就寝前の夜間、6本の動画を専用ソフトでひとつに合成する。作業してわかったことだが、複数カメラ映像の合成加工は、至近距離から地平線まで映り込む空撮にはあまり向いていないようだ。<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D1%A5%A4%A5%ED">パイロ</a>ットに合わせて合成すると遠い景色の輪郭がずれてしまい、かといって遠距離を合わせると今度は翼端の映像がずれる。もっともつなぎめが目立たないポイントを時間をかけて探していく。全フライト分を翌日に確認できるよう作業をするとなるとけっこう忙しい。<br />  <br />  動画の確認もノートPCで見るだけでは十分伝わらないので、あるときは<a class="keyword" href="http://d.hatena.ne.jp/keyword/Oculus%20Rift">Oculus Rift</a>を持ち込み、あるときはハコスコと自作アプリで即日確認できるようにした。<br />  <br /> <span itemscope itemtype="http://schema.org/Photograph"><a href="http://f.hatena.ne.jp/aike/20140922091152" class="hatena-fotolife" itemprop="url"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20140922/20140922091152.jpg" alt="f:id:aike:20140922091152j:image" title="f:id:aike:20140922091152j:image" class="hatena-fotolife" itemprop="image"></a></span><br />   <br />  そのシーズンの最終日、ドローンの操縦を任された。ドローン撮影はチームとしても初めてだったのであまり効率よく撮影することはできなかったが、それでもワンカット、M-02Jが飛び立つ様子を上空からとらえることができた。<a href="#f-448b0b01" name="fn-448b0b01" title="H ZETTRIOのMV「Wonderful Flight」で使われているドローン映像はこのとき撮影したものだそうです https://www.youtube.com/watch?v=-mlI_hZAS6U ">*1</a><br />  <br />  このプロジェクトに参加する中、とても興味深く見ていたのは、八谷さんのプロジェクト運営、チーム運営方法だった。ボランティアベースのコミュニティということで、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AA%A1%BC%A5%D7%A5%F3%A5%BD%A1%BC%A5%B9">オープンソース</a>プロジェクトのような、ゆるいつながりに近い。とはいえ、なにしろ航空機なので大きなお金も動くしミスがあったら人が死ぬ。そういった作業の一端を、初めて会ったばかりの大学生にもどんどん担当させていく。<br />  ボランティアベースだとスパルタ式にはいかない。丁寧な言葉で明確に指示をする。搭乗姿勢になった後は細かい指示は出せないので、メンバーそれぞれ自律的に動く必要がある。さらには700mほど離れたテイクオフ側とランディング側で2つのチームが独立して正しく機能する必要がある。八谷さんは、メンバーのスキルを見極めた上で全面的に信頼して担当を依頼する。それでも経験が浅いとミスはあるので、要所には関東から呼んだベテランスタッフを配置する。 <br />  また、利用させてもらう各種施設やコラボレーション先と付き合うときも、一方的な立場になるのではなく、相手側にもメリットのあるようにして、良い関係を長く続けられるようにする。周りの人たちとお互いにリスペクトした関係性を、わずかな期間で実にたくみに作り上げていってしまう。そのあたりの立ち回り方の秘密について何度か本人に聞いてみたのだが「偶然」とか、「出会いを大切に」とか、いつも普通の言葉でかわされてしまう。いや、それ絶対普通のスキルではないと思う。たぶん、それができれば今頃みんな、空を飛んでる。<br />  <br />  M-02Jは地面に映る影が非現実的なくらい美しい。この影を見る限り、八谷さんは完全に鳥だ。僕がこのプロジェクトに参加して撮影した全天球映像は、ハコスコアプリの「きみはテト2」で見ることができるので、ぜひ自分の目で確認してほしい。</p><p><p><br /> <img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20161013/20161013013432.png"></p><p><a href="https://itunes.apple.com/jp/app/hakosuko/id918422586" class="hatena-fotolife" target="_blank"><br /> <img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20161013/20161013013451.png" class="hatena-fotolife hatena-image-left"></a></p><p><a href="https://play.google.com/store/apps/details?id=com.hacosco.viewer" class="xhatena-fotolife" target="_blank"><br /> <img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20161013/20161013013450.png"></a><br /> </p>   <br />  そんな<a class="keyword" href="http://d.hatena.ne.jp/keyword/OpenSky">OpenSky</a>プロジェクトであるが、2015年以降は参加できていない。時間的に都合がつかなかった、というのが直接的な理由ではある。本当の理由は、八谷さんを見て、なにかひとつ自分の大きなプロジェクトを始めたくなってしまったからだ。人間とコンピュータが融け合うSFを実現するプロジェクト。そのために働きながら大学院に入りなおし、土日はすべて研究の時間にあてるようにした。なにもかも手探りの状態なので、10年以上かかるかもしれない。<br />  <br />  <a class="keyword" href="http://d.hatena.ne.jp/keyword/OpenSky">OpenSky</a>プロジェクトの方は、今年無事目標だった場周飛行を成功させていた。<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AF%A5%E9%A5%A6%A5%C9%A5%D5%A5%A1%A5%F3%A5%C7%A5%A3%A5%F3%A5%B0">クラウドファンディング</a>支援者向けのテストフライト報告会が開かれ、その会場で久しぶりに八谷さんとお会いすることができた。プロジェクトは僕が参加していたときにくらべて、さらに加速していた。エンジン出力が倍になり、ずっと鋭角に上昇していた。<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%CA%A5%A6%A5%B7%A5%AB">ナウシカ</a>のテーマ曲の生演奏に乗せて、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C0%D0%BC%ED%CA%BF%CC%EE">石狩平野</a>のはるか上空で八谷さんは自由自在に飛んでいた。<br />  <br /> <span itemscope itemtype="http://schema.org/Photograph"><a href="http://f.hatena.ne.jp/aike/20140923094451" class="hatena-fotolife" itemprop="url"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20140923/20140923094451.jpg" alt="f:id:aike:20140923094451j:image" title="f:id:aike:20140923094451j:image" class="hatena-fotolife" itemprop="image"></a></span><br />  </p><br /> <p><div class="hatena-asin-detail"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4344024508/lifehacklife-22/"><img class="hatena-asin-detail-image" title="ナウシカの飛行具、作ってみた 発想・制作・離陸---- メーヴェが飛ぶまでの10年間" src="http://ecx.images-amazon.com/images/I/51RP3lbw%2BtL._SL160_.jpg" alt="ナウシカの飛行具、作ってみた 発想・制作・離陸---- メーヴェが飛ぶまでの10年間" /></a><br /> <div class="hatena-asin-detail-info"><br /> <p class="hatena-asin-detail-title"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4344024508/lifehacklife-22/">ナウシカの飛行具、作ってみた 発想・制作・離陸---- メーヴェが飛ぶまでの10年間</a></p><ul> <li><span class="hatena-asin-detail-label">作者:</span> <a class="keyword" href="http://d.hatena.ne.jp/keyword/%C8%AC%C3%AB%CF%C2%C9%A7">八谷和彦</a>,猪谷千香,<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A4%A2%A4%B5%A4%EA%A4%E8%A4%B7%A4%C8%A4%AA">あさりよしとお</a></li> <li><span class="hatena-asin-detail-label">出版社/メーカー:</span> <a class="keyword" href="http://d.hatena.ne.jp/keyword/%B8%B8%C5%DF%BC%CB">幻冬舎</a></li> <li><span class="hatena-asin-detail-label">発売日:</span> 2013/09/12</li> <li><span class="hatena-asin-detail-label">メディア:</span> 単行本</li> <li><a href="http://d.hatena.ne.jp/asin/4344024508/lifehacklife-22" target="_blank">この商品を含むブログ (9件) を見る</a></li> </ul></div><div class="hatena-asin-detail-foot">&#160;</div></div></p> <div class="footnote"> <p class="footnote"><a href="#fn-448b0b01" name="f-448b0b01" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text"><a class="keyword" href="http://d.hatena.ne.jp/keyword/H%20ZETTRIO">H ZETTRIO</a>のMV「Wonderful Flight」で使われているドローン映像はこのとき撮影したものだそうです <a href="https://www.youtube.com/watch?v=-mlI_hZAS6U">https://www.youtube.com/watch?v=-mlI_hZAS6U</a> </span></p> </div> aike ブラウザでMMLを演奏するChrome拡張作った hatenablog://entry/10257846132645780682 2016-08-22T00:00:00+09:00 2016-08-22T00:00:00+09:00 ブラウザでMML(Music Macro Language)の文字列を選択してCtrl-Cを押すと音楽が流れるChrome拡張を作りました。 Googleウェブストアからインストールできます。 https://goo.gl/0UJQcT ソースはこちら https://github.com/aike/TSSCCjs 実行例 http://youtube.com/watch?v=o-IzrXaqIbM 今から10年くらい前、ネットの掲示板上でMMLによる音楽が盛り上がったことがありました。添付ファイルなどではなく、掲示板のテキストとして直接貼られた10行程度のMMLでも驚くほどリッチな楽曲が再現… <p>ブラウザで<a href="https://ja.wikipedia.org/wiki/Music_Macro_Language">MML(Music Macro Language)</a>の文字列を選択してCtrl-Cを押すと音楽が流れる<a class="keyword" href="http://d.hatena.ne.jp/keyword/Chrome">Chrome</a>拡張を作りました。<br /> <a class="keyword" href="http://d.hatena.ne.jp/keyword/Google">Google</a>ウェブストアからインストールできます。<br /> <a href="https://goo.gl/0UJQcT">https://goo.gl/0UJQcT</a><br /> ソースはこちら<br /> <a href="https://github.com/aike/TSSCCjs">https://github.com/aike/TSSCCjs</a><br /> 実行例<br /> <a href="http://youtube.com/watch?v=o-IzrXaqIbM">http://youtube.com/watch?v=o-IzrXaqIbM</a></p><br /> <p>今から10年くらい前、ネットの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B7%C7%BC%A8">掲示</a>板上で<a class="keyword" href="http://d.hatena.ne.jp/keyword/MML">MML</a>による音楽が盛り上がったことがありました。添付ファイルなどではなく、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B7%C7%BC%A8">掲示</a>板のテキストとして直接貼られた10行程度の<a class="keyword" href="http://d.hatena.ne.jp/keyword/MML">MML</a>でも驚くほどリッチな楽曲が再現できるため、いかに短い<a class="keyword" href="http://d.hatena.ne.jp/keyword/MML">MML</a>でリアルな音楽を表現するか、技術の競い合いのような文化が生まれていました。</p><p> </p><p>当時、再生ツールとして使われていたのが、keimさんが作られたTSS Clipboard Player(<a class="keyword" href="http://d.hatena.ne.jp/keyword/TSSCP">TSSCP</a>または<a class="keyword" href="http://d.hatena.ne.jp/keyword/TCP">TCP</a>)という<a class="keyword" href="http://d.hatena.ne.jp/keyword/Windows">Windows</a>用<a class="keyword" href="http://d.hatena.ne.jp/keyword/MML">MML</a>プレイヤーです。これは、とよしまさん制作の<a href="http://www.toyoshima-house.net/tss/index.html">T&#39;SoundSystem</a>(TSS)という、PSG、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D5%A5%A1%A5%DF%A5%B3%A5%F3">ファミコン</a>、<a class="keyword" href="http://d.hatena.ne.jp/keyword/MSX">MSX</a>、<a class="keyword" href="http://d.hatena.ne.jp/keyword/FM%B2%BB%B8%BB">FM音源</a>などの音を再現できる<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B5%A5%A6%A5%F3%A5%C9">サウンド</a>ドライバを利用したものでした。Ctrl-Cで<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AF%A5%EA%A5%C3%A5%D7%A5%DC%A1%BC%A5%C9">クリップボード</a>に<a class="keyword" href="http://d.hatena.ne.jp/keyword/MML">MML</a>をコピーするだけですぐに音楽が再生される<a class="keyword" href="http://d.hatena.ne.jp/keyword/TSSCP">TSSCP</a>のあまりの使いやすさと、TSSの音の良さに支えられて、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B7%C7%BC%A8">掲示</a>板上の<a class="keyword" href="http://d.hatena.ne.jp/keyword/MML">MML</a>は大変盛り上がったようです。(自分は後から知った口なので、当事者ではないんですが)</p><p> </p><p>その後、別の方による偽<a class="keyword" href="http://d.hatena.ne.jp/keyword/TCP">TCP</a>というツールも出たりしましたが、基本的に<a class="keyword" href="http://d.hatena.ne.jp/keyword/TSSCP">TSSCP</a>の<a class="keyword" href="http://d.hatena.ne.jp/keyword/MML">MML</a>が<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%D5%A5%A1%A5%AF%A5%C8%A5%B9%A5%BF%A5%F3%A5%C0%A1%BC%A5%C9">デファクトスタンダード</a>となって、その上に<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B3%C8%C4%A5%B5%A1%C7%BD">拡張機能</a>を追加したものになっています。</p><p> </p><p>月日は流れ2016年、<a href="http://miscfeeling.blogspot.jp/2016/08/web-music-5.html">Web Music&#x30CF;&#x30C3;&#x30AB;&#x30BD;&#x30F3;#5</a>で、いまやWeb Audio/Web <a class="keyword" href="http://d.hatena.ne.jp/keyword/MIDI">MIDI</a>のキーマンである、とよしまさんにお会いすることができたので、<br /> 「TSSのWeb Audio版ってないの?」<br /> と聞いてみたら、<br /> 「<a href="https://github.com/toyoshim/tss">&#x3042;&#x308B;&#x3088;</a>」<br /> とのこと。つまり、OSにかかわらずブラウザの<a class="keyword" href="http://d.hatena.ne.jp/keyword/JavaScript">JavaScript</a>で<a class="keyword" href="http://d.hatena.ne.jp/keyword/MML">MML</a>を再生できる!</p><p> </p><p>「じゃあ、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AF%A5%EA%A5%C3%A5%D7%A5%DC%A1%BC%A5%C9">クリップボード</a><a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>で<a class="keyword" href="http://d.hatena.ne.jp/keyword/MML">MML</a>演奏するツールもあるの?」<br /> 「<a class="keyword" href="http://d.hatena.ne.jp/keyword/MML">MML</a>の方言がいろいろ違うし、それはまだなくて……」<br /> え、そうなの? <a class="keyword" href="http://d.hatena.ne.jp/keyword/MML">MML</a>の方言くらいなんとかなるでしょ、ってことで作りはじめたのがこのツールです。つまり<a class="keyword" href="http://d.hatena.ne.jp/keyword/TSSCP">TSSCP</a>のWeb版クローンです。</p><p> </p><p>実装してみたら、意外と大変で。ブラウザの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AF%A5%EA%A5%C3%A5%D7%A5%DC%A1%BC%A5%C9">クリップボード</a><a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>はセキュリティのために、コピー操作時点での<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AF%A5%EA%A5%C3%A5%D7%A5%DC%A1%BC%A5%C9">クリップボード</a>の内容が取得できないことが判明。<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A4%B0%A4%CC%A4%CC">ぐぬぬ</a>。<br /> まあ、キー操作と選択文字は取れるので、Ctrl-Cを押されたときに選択されている文字を取得すれば同じことはできるか。<a href="#f-f46dbd2b" name="fn-f46dbd2b" title="そういうわけでClipboard Playerとは名づけてません">*1</a></p><p> </p><p><a class="keyword" href="http://d.hatena.ne.jp/keyword/MML">MML</a>も難関です。<br /> やるべきことは<a class="keyword" href="http://d.hatena.ne.jp/keyword/TSSCP">TSSCP</a>形式の<a class="keyword" href="http://d.hatena.ne.jp/keyword/MML">MML</a>をTSS形式の<a class="keyword" href="http://d.hatena.ne.jp/keyword/MML">MML</a>に変換してTSSに渡すだけだし、どうせ<a class="keyword" href="http://d.hatena.ne.jp/keyword/MML">MML</a>の方言といっても、不等号の向きとかそんな程度だろうと思ってたら全然違いました。<a class="keyword" href="http://d.hatena.ne.jp/keyword/TSSCP">TSSCP</a>の<a class="keyword" href="http://d.hatena.ne.jp/keyword/MML">MML</a>は圧縮効率を重視したさまざまな拡張がされていて、行の終端は改行ではなく<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%BB%A5%DF">セミ</a>コロン、#A&#12316;#Zまでマクロ定義、#FMマクロでFM<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%EB%A5%B4%A5%EA%A5%BA%A5%E0">アルゴリズム</a>の柔軟な定義、といったTSSにない機能を持っています。</p><p> </p><p>たとえば<a class="keyword" href="http://d.hatena.ne.jp/keyword/TSSCP">TSSCP</a>の<a class="keyword" href="http://d.hatena.ne.jp/keyword/MML">MML</a>は以下のようなものです。</p> <pre class="code" data-lang="" data-unlink>#TITLE &lt;sample&gt;;t150;#A=%3v15o5cdefg;#FMB(A);A;A;</pre><p>これを、TSSで再生できるようにするには以下のような<a class="keyword" href="http://d.hatena.ne.jp/keyword/MML">MML</a>に変換する必要があります。#FMマクロは、<a class="keyword" href="http://d.hatena.ne.jp/keyword/MML">MML</a>の中でもさらに別の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B7%A5%F3%A5%BF%A5%C3%A5%AF%A5%B9">シンタックス</a>を持った言語と考えられ、専用のパーサを別途用意する必要がありました。</p> <pre class="code" data-lang="" data-unlink>#TITLE &lt;sample&gt; #CHANNEL 3 #A t150 #B %3 @i0,0@o1,0v15o5cdefg #C %3 @i3,0@o0,0v15o5cdefg</pre><p> </p><p>また、通常のマクロも、A(7)とすると、5度(7<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%BB%A5%DF">セミ</a>トーン)上に移調してマクロ展開するなど、高度な機能があり、これらを忠実に実装しなくては当時の<a class="keyword" href="http://d.hatena.ne.jp/keyword/MML">MML</a>を同じ音で再生することができません。<br /> さらに、偽<a class="keyword" href="http://d.hatena.ne.jp/keyword/TCP">TCP</a>の拡張命令も難題です、これはTSSでは再生不可能な機能を実装していたりするので拡張コマンドを無視するしかないのですが、<a class="keyword" href="http://d.hatena.ne.jp/keyword/MML">MML</a>は命令同士がセパレータで分割されておらず、また命令の文字数も1&#12316;数文字とまちまちであるため、無視するにしても、ここからここまでが拡張コマンド、というように認識する必要があります。</p><p> </p><p>結局、簡易的な文字列処理ではなく、しっかりパースして抽象<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B9%BD%CA%B8%CC%DA">構文木</a>を生成してから変換するちょっとしたトランスパイラのプログラムになりました。</p><p> </p><p>だいたいここまでで、当時の<a class="keyword" href="http://d.hatena.ne.jp/keyword/MML">MML</a>は再生できるようになりましたが、まだ同じ音色になりません。よく調べてみると、JS版TSSのバグで発音数制限があったり、JS版ではmlコマンドがサポートされていなかったり、ということあったので、JS版TSSのソースに手を入れて調整した結果、ほぼ同じ音が出るようになりました。<a href="#f-495b28f2" name="fn-495b28f2" title="いずれも本家にプルリクエストして反映してもらいました">*2</a></p><p> </p><p>非互換部分は以下のとおりです。<br /> ・偽<a class="keyword" href="http://d.hatena.ne.jp/keyword/TCP">TCP</a>の拡張コマンドは非対応<br /> ・JS版TSSでは固定波形テーブル音源が未実装のため、%5の音源は無音になる<br /> ・oコマンドやlコマンドを未指定時の値が違うっぽい<br /> ・Panが左右逆かも<br /> ・文法エラーのある<a class="keyword" href="http://d.hatena.ne.jp/keyword/MML">MML</a>の解釈</p><p> </p><p>再生確認用のサンプル<a class="keyword" href="http://d.hatena.ne.jp/keyword/MML">MML</a>も書いてみたので、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Chrome">Chrome</a>拡張をインストールして聞いてみてください。</p> <pre class="code" data-lang="" data-unlink>#TITLE &lt;TSSCCjs&#39;s Theme by aike CC-BY&gt;; t165;#A=l4dr8d16e16f2.r8gf8e8f8e.d.ec.d.efr8f16g16a2.r8b-a8g8d8fr8fr8fgr8gr8 ;#B=d.a2r8g.c+2r8c+.d.ef2.rd.a2r8g.c2r8c+.g.df2.r;#C=l4ar8a16g16a2.r8ga&lt;d8c. &gt;a.&lt;c&gt;a.a+.&lt;c&gt;a.b-16&lt;c16d2.r8c.&gt;a+ar8ar8a;#D=a.d8&gt;a8.&lt;d8.f8er8e8e8ef8g.a8a+8 ga+8;#E=dgfdgdfd&gt;a&lt;fd&gt;a&lt;f&gt;a&lt;d&gt;a&lt;cgecgcec&gt;a&lt;ec&gt;a&lt;e&gt;a&lt;c&gt;a&lt;dgfdgdfdcgecgcec&gt;b-&lt; fd&gt;b-&lt;f&gt;b-&lt;d&gt;b-;#F=fgfde.f8g.r8efg8aa+8ac+defgfde.f8g.r8efg8aa+8d2.r;#G=l4d. &gt;a.&lt;d&gt;b-r8b-.&lt;dc.&gt;g.&lt;c&gt;ar8ar8a&lt;d.&gt;a.&lt;dcr8cr8c&gt;b-r8b-r8b-a16r16a16r16a16r16a1 6r16&lt;e&gt;a&lt;;#H=l16[dagfdfga][c+agfc+fga][eagfefga][dagfdfga];#I=[4arararar]&lt;[d rdrdrdr]frfrfrfrgrgrgrgr;#J=AeAa+BB;#K=C&lt;cr8cr8c&gt;C&lt;c+r8c+r8c+Da2.rDa.d2r8Da2 .rDa.d2r8;#L=l8Ea&lt;ec&gt;a&lt;e&gt;a&lt;c&gt;a&lt;Ea&lt;ec+&gt;a&lt;e&gt;a&lt;c+&gt;al4&lt;FF&gt;;#M=GGHHHH;#N=l8[8r1]I [16r1];#O=%3v10ml3q6s5;#P=%3v10mp1,4,1,2,0k1q6s5;#Q=%3q10s3;#FMC3(B2(A));Oo6 $J;Po6$J;Qp1o6v6$J;#FMC3(B2(A));Oo5p2$K;Po5p2$K;Qp2o5v6p2$K;#FMC3(B2(A));Oo5 $L;Po5$L;Qo5v4$L;#FMC4(B2(A));%3o4l4v15$q0s1o3M;%3o4l4v13$q0s3o3M;%3o4l4v4$q 13s1o3M;o6v4q4s4$N;o6v4q4s4k5$N;o6v2q4s4r8.$N;o6v2q4s4k5r8.$N;o8%2q0s50l16v8 $[16arararaaarararaa][16araaaraaaraaaraa];#R=[7rara]ral16s20;%2q0l4o3s12,18v 8$Rarrraaaal4s12Raaaaaaaal4s12Rarrraaaal4s12Raaaaaaaal4s12;%3o4v15s1,-15q1l1 6$[16crrrrrcrcrrrrrcr][16crccrcrccrccrcrc];</pre><div class="footnote"> <p class="footnote"><a href="#fn-f46dbd2b" name="f-f46dbd2b" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">そういうわけでClipboard Playerとは名づけてません</span></p> <p class="footnote"><a href="#fn-495b28f2" name="f-495b28f2" class="footnote-number">*2</a><span class="footnote-delimiter">:</span><span class="footnote-text">いずれも本家にプルリク<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A8%A5%B9">エス</a>トして反映してもらいました</span></p> </div> aike UnityでサイドチェーンしてSEとBGMの自動バランス調整する話 hatenablog://entry/10257846132645780698 2016-04-15T00:00:00+09:00 2016-04-15T00:00:00+09:00 最近のUnityは音楽制作用DAWのような機能が充実してて、試しにサイドチェーンできるか調べたらできたのでメモ。 サイドチェーンというのは音圧上げないと死ぬ病の人たちが発明した音楽用コンプレッサーの使い方で、キック(バスドラム)の音が鳴った瞬間、それ以外のシンセやベースなどの音量を自動的に下げる、というものです。これにより音圧をギリギリまで上げつつ、キックの音をしっかり目立たせ、バックの音にもンッアッンッアッというリズムを生み出すという一粒で三度美味しいワザです。 ゲーム制作でいうと、SEやセリフの音が鳴るときにBGMを自動的に下げるというような、よくある状況に応用できます。 早速やってみまし… <p>最近のUnityは音楽制作用<a class="keyword" href="http://d.hatena.ne.jp/keyword/DAW">DAW</a>のような機能が充実してて、試しにサイドチェーンできるか調べたらできたのでメモ。<br />  <br /> サイドチェーンというのは音圧上げないと死ぬ病の人たちが発明した音楽用コンプレッサーの使い方で、キック(<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D0%A5%B9%A5%C9%A5%E9%A5%E0">バスドラム</a>)の音が鳴った瞬間、それ以外のシンセやベースなどの音量を自動的に下げる、というものです。これにより音圧をギリギリまで上げつつ、キックの音をしっかり目立たせ、バックの音にもンッアッンッアッというリズムを生み出すという一粒で三度美味しいワザです。<br />  <br /> ゲーム制作でいうと、SEやセリフの音が鳴るときにBGMを自動的に下げるというような、よくある状況に応用できます。<br />  <br /> 早速やってみましょう。<br />  <br /> UnityのWindowメニューからAudio Mixerを選択します。大丈夫、あなたのPersonal(無償)版でもできますから。<br />  <br /> 全然ミキサーっぽくない表示が出て若干不安になりますが、勇気を出して「+」印をクリックし、ミキサー名を入力します。ぼくはこれまでの人生でミキサーに名前をつけるような経験は一度もしたことがなかったので少しとまどいましたが、無難に「mixer」としました。</p><p><span itemscope itemtype="http://schema.org/Photograph"><a href="http://f.hatena.ne.jp/aike/20160416011944" class="hatena-fotolife" itemprop="url"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20160416/20160416011944.jpg" alt="f:id:aike:20160416011944j:image" title="f:id:aike:20160416011944j:image" class="hatena-fotolife" itemprop="image"></a></span><br />  </p><p>一歩前進しました。でもまだミキサーっぽくないのでGroupsのMasterを選択した状態で「+」をクリックしてトラックを追加します。トラック名はつけたことがあるので迷いません。「SE」と「BGM」にしました。</p><p><span itemscope itemtype="http://schema.org/Photograph"><a href="http://f.hatena.ne.jp/aike/20160416011945" class="hatena-fotolife" itemprop="url"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20160416/20160416011945.jpg" alt="f:id:aike:20160416011945j:image" title="f:id:aike:20160416011945j:image" class="hatena-fotolife" itemprop="image"></a></span><br />  </p><p>Audio Sourceをふたつ作ります。AudioClipとしては数小節分のキックのサンプリングとシンセのサンプリングループを用意します。サンプリングループは自分で作ると大変なので買ってきました。お金って便利。<br />  <br /> キックの方はOutputを「SE(mixer)」に、シンセの方はOutputを「BGM(mixer)」にします。</p><p><span itemscope itemtype="http://schema.org/Photograph"><a href="http://f.hatena.ne.jp/aike/20160416011946" class="hatena-fotolife" itemprop="url"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20160416/20160416011946.jpg" alt="f:id:aike:20160416011946j:image" title="f:id:aike:20160416011946j:image" class="hatena-fotolife" itemprop="image"></a></span><br /> <span itemscope itemtype="http://schema.org/Photograph"><a href="http://f.hatena.ne.jp/aike/20160416011947" class="hatena-fotolife" itemprop="url"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20160416/20160416011947.jpg" alt="f:id:aike:20160416011947j:image" title="f:id:aike:20160416011947j:image" class="hatena-fotolife" itemprop="image"></a></span><br />  <br /> サイドチェーンをかけずにそのまま混ぜて鳴らすとこんな感じになります。ふーん。</p><p><span style="vertical-align:middle;"><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" width="220" height="25" id="mp3_3" align="middle" style="vertical-align:bottom"><param name="flashVars" value="mp3Url=http://aikelab.net/dtm/20160416/kick.mp3"><param name="allowScriptAccess" value="sameDomain"><param name="movie" value="http://g.hatena.ne.jp/tools/mp3_3.swf"><param name="quality" value="high"><param name="bgcolor" value="#ffffff"><param name="wmode" value="transparent"><embed src="http://g.hatena.ne.jp/tools/mp3_3.swf" flashvars="mp3Url=http://aikelab.net/dtm/20160416/kick.mp3" quality="high" wmode="transparent" bgcolor="#ffffff" width="220" height="25" name="mp3_3" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" style="vertical-align:bottom"></object><a href="http://aikelab.net/dtm/20160416/kick.mp3"><img src="http://g.hatena.ne.jp/images/podcasting.gif" title="Download" alt="Download" border="0" style="border:0px;vertical-align:bottom;"></a></span><br />  <br /> サイドチェーンの登場です。<br /> トラックの下の方の「Add ..」をクリックし、SEは「Send」、BGMは「Duck Volume」を選択します。ミキサーっぽくなってきた。</p><p><span itemscope itemtype="http://schema.org/Photograph"><a href="http://f.hatena.ne.jp/aike/20160416011948" class="hatena-fotolife" itemprop="url"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20160416/20160416011948.jpg" alt="f:id:aike:20160416011948j:image" title="f:id:aike:20160416011948j:image" class="hatena-fotolife" itemprop="image"></a></span><br />  <br /> SendのReceiveを「BGM\Duck Volume」、Send levelを最大の「0.00 dB」に設定します。</p><p><span itemscope itemtype="http://schema.org/Photograph"><a href="http://f.hatena.ne.jp/aike/20160416011949" class="hatena-fotolife" itemprop="url"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20160416/20160416011949.jpg" alt="f:id:aike:20160416011949j:image" title="f:id:aike:20160416011949j:image" class="hatena-fotolife" itemprop="image"></a></span><br />  <br /> Duck VolumeのThresholdやRelease Timeをこんな感じに設定します。Thresholdは左の方にするほど強くかかるので、最初は強めにして効果を耳で確かめてから丁度いいところまで上げていくと分かりやすいかもしれません。</p><p><span itemscope itemtype="http://schema.org/Photograph"><a href="http://f.hatena.ne.jp/aike/20160416011950" class="hatena-fotolife" itemprop="url"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20160416/20160416011950.jpg" alt="f:id:aike:20160416011950j:image" title="f:id:aike:20160416011950j:image" class="hatena-fotolife" itemprop="image"></a></span><br />  <br /> サイドチェーンをかけて鳴らすとこんな感じ。キックがしっかり聞こえて、シンセがンッアッンッアッですね。</p><p><span style="vertical-align:middle;"><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" width="220" height="25" id="mp3_3" align="middle" style="vertical-align:bottom"><param name="flashVars" value="mp3Url=http://aikelab.net/dtm/20160416/kick_duck.mp3"><param name="allowScriptAccess" value="sameDomain"><param name="movie" value="http://g.hatena.ne.jp/tools/mp3_3.swf"><param name="quality" value="high"><param name="bgcolor" value="#ffffff"><param name="wmode" value="transparent"><embed src="http://g.hatena.ne.jp/tools/mp3_3.swf" flashvars="mp3Url=http://aikelab.net/dtm/20160416/kick_duck.mp3" quality="high" wmode="transparent" bgcolor="#ffffff" width="220" height="25" name="mp3_3" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" style="vertical-align:bottom"></object><a href="http://aikelab.net/dtm/20160416/kick_duck.mp3"><img src="http://g.hatena.ne.jp/images/podcasting.gif" title="Download" alt="Download" border="0" style="border:0px;vertical-align:bottom;"></a></span><br />  <br /> 次に別の音をトリガーにしてみます。<br /> <a href="http://unity-chan.com/">&#x30E6;&#x30CB;&#x30C6;&#x30A3;&#x3061;&#x3083;&#x3093;</a>のボイスを公式サイトからダウンロードしてきました。<br />  <br /> 普通に混ぜるとこんな感じ。もごもご。</p><p><span style="vertical-align:middle;"><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" width="220" height="25" id="mp3_3" align="middle" style="vertical-align:bottom"><param name="flashVars" value="mp3Url=http://aikelab.net/dtm/20160416/voice.mp3"><param name="allowScriptAccess" value="sameDomain"><param name="movie" value="http://g.hatena.ne.jp/tools/mp3_3.swf"><param name="quality" value="high"><param name="bgcolor" value="#ffffff"><param name="wmode" value="transparent"><embed src="http://g.hatena.ne.jp/tools/mp3_3.swf" flashvars="mp3Url=http://aikelab.net/dtm/20160416/voice.mp3" quality="high" wmode="transparent" bgcolor="#ffffff" width="220" height="25" name="mp3_3" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" style="vertical-align:bottom"></object><a href="http://aikelab.net/dtm/20160416/voice.mp3"><img src="http://g.hatena.ne.jp/images/podcasting.gif" title="Download" alt="Download" border="0" style="border:0px;vertical-align:bottom;"></a></span><br /> <span class="deco" style="font-size:small;"><a class="keyword" href="http://d.hatena.ne.jp/keyword/%26%23169%3B">&#169;</a> Unity Technologies Japan/UCL</span><br />   <br /> これもキックと同じようにOutputを「SE(mixer)」にします。</p><p><span itemscope itemtype="http://schema.org/Photograph"><a href="http://f.hatena.ne.jp/aike/20160416011951" class="hatena-fotolife" itemprop="url"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20160416/20160416011951.jpg" alt="f:id:aike:20160416011951j:image" title="f:id:aike:20160416011951j:image" class="hatena-fotolife" itemprop="image"></a></span><br />  <br /> Duck VolumeのThresholdはさっきより強め。ユニティちゃんが一言しゃべるたびにンッアッってならないようにRelease Timeは長めにします。</p><p><span itemscope itemtype="http://schema.org/Photograph"><a href="http://f.hatena.ne.jp/aike/20160416011952" class="hatena-fotolife" itemprop="url"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20160416/20160416011952.jpg" alt="f:id:aike:20160416011952j:image" title="f:id:aike:20160416011952j:image" class="hatena-fotolife" itemprop="image"></a></span><br />  <br /> できた。</p><p><span style="vertical-align:middle;"><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" width="220" height="25" id="mp3_3" align="middle" style="vertical-align:bottom"><param name="flashVars" value="mp3Url=http://aikelab.net/dtm/20160416/voice_duck2.mp3"><param name="allowScriptAccess" value="sameDomain"><param name="movie" value="http://g.hatena.ne.jp/tools/mp3_3.swf"><param name="quality" value="high"><param name="bgcolor" value="#ffffff"><param name="wmode" value="transparent"><embed src="http://g.hatena.ne.jp/tools/mp3_3.swf" flashvars="mp3Url=http://aikelab.net/dtm/20160416/voice_duck2.mp3" quality="high" wmode="transparent" bgcolor="#ffffff" width="220" height="25" name="mp3_3" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" style="vertical-align:bottom"></object><a href="http://aikelab.net/dtm/20160416/voice_duck2.mp3"><img src="http://g.hatena.ne.jp/images/podcasting.gif" title="Download" alt="Download" border="0" style="border:0px;vertical-align:bottom;"></a></span><br /> <span class="deco" style="font-size:small;"><a class="keyword" href="http://d.hatena.ne.jp/keyword/%26%23169%3B">&#169;</a> Unity Technologies Japan/UCL</span></p><p> <br /> ね?簡単でしょ。</p> aike OSCをMacやWindowsやLinuxやRasPiから送るシンプルツール作った hatenablog://entry/10257846132645780729 2016-01-14T00:00:00+09:00 2016-01-14T00:00:00+09:00 OSC(Open Sound Control)を気軽に送りたくなることってあるじゃないですか。ラズベリーパイからPCへ簡単な通知を送ったりとか。どこのご家庭にもある雰囲気メガネを光らせたいときとか。 でもなかなかシンプルなツールが見つからなくて、開発環境入れてコンパイルする必要があったり、音楽や映像を扱う大きなソフトの一機能だったりして、ちょっと気軽な感じがしないものばかりで。そんなわけで、コンパイル不要で実行ファイルひとつだけでOSCメッセージを送れるコマンドを作りました。 http://github.com/aike/oscer 使い方は簡単。コマンド名の後にホスト名、ポート番号、OSCメ… <p><a href="https://ja.wikipedia.org/wiki/OpenSound_Control">OSC(Open Sound Control)</a>を気軽に送りたくなることってあるじゃないですか。<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E9%A5%BA%A5%D9%A5%EA%A1%BC">ラズベリー</a>パイからPCへ簡単な通知を送ったりとか。どこのご家庭にもある<a href="http://akamatsu.org/aka/2015/01/12/fun-iki-midi-osc/">&#x96F0;&#x56F2;&#x6C17;&#x30E1;&#x30AC;&#x30CD;</a>を光らせたいときとか。<br />  <br /> でもなかなかシンプルなツールが見つからなくて、開発環境入れて<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%EB">コンパイル</a>する必要があったり、音楽や映像を扱う大きなソフトの一機能だったりして、ちょっと気軽な感じがしないものばかりで。そんなわけで、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%EB">コンパイル</a>不要で実行ファイルひとつだけでOSCメッセージを送れるコマンドを作りました。<br />  <br /> <span class="deco" style="font-size:x-large;"><a href="http://github.com/aike/oscer">http://github.com/aike/oscer</a><br /> </span><br />  <br /> 使い方は簡単。コマンド名の後にホスト名、ポート番号、OSCメッセージを指定するだけ。<br />  <br /> 実行例</p> <pre class="code" data-lang="" data-unlink>oscer localhost 10000 /dummy</pre><p> <br /> 引数にはInt32、Float32、Stringが指定できます。</p> <pre class="code" data-lang="" data-unlink>oscer 192.168.1.10 12000 /hello 10 oscer 192.168.1.10 13000 /world 3.14 oscer 192.168.1.10 12000 /hello world</pre><p> <br /> <a class="keyword" href="http://d.hatena.ne.jp/keyword/IPv6">IPv6</a>も対応。たぶん。</p> <pre class="code" data-lang="" data-unlink>oscer fe80::1%lo0 11000 /foo</pre><p><br /> <a class="keyword" href="http://d.hatena.ne.jp/keyword/golang">golang</a>で書いたので、ク<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%ED%A5%B9%A5%B3%A5%F3">ロスコン</a>パイルも簡単。<br /> <a href="https://github.com/aike/oscer/tree/master/build/MacOSX">Mac</a>、<a href="https://github.com/aike/oscer/tree/master/build/Windows32">Win32</a>、<a href="https://github.com/aike/oscer/tree/master/build/Windows64">Win64</a>、<a href="https://github.com/aike/oscer/tree/master/build/Linux32">Linux32</a>、<a href="https://github.com/aike/oscer/tree/master/build/Linux64">Linux64</a>、<a href="https://github.com/aike/oscer/tree/master/build/LinuxARM">LinuxARM(Raspberry Pi)</a>用にビルドしておきました。<a class="keyword" href="http://d.hatena.ne.jp/keyword/golang">golang</a>は初めて使いましたが生ソケット通信みたいなアプリでも完璧にWrite once, run anywhereなのはびっくり。実行側は<a class="keyword" href="http://d.hatena.ne.jp/keyword/golang">golang</a>をはじめランタイムライブラリ的なものが一切不要なのも嬉しいです。<br />  <br /> そんなわけで良いOSCライフを。<br />  <br /> 2016.06.13 追記<br /> 受信側もほしくなったので受信機能もつけました。</p> <pre class="code" data-lang="" data-unlink>oscer receive 10000</pre> aike 今夜わかるFM音源 その2 hatenablog://entry/10257846132645780742 2015-11-13T00:00:00+09:00 2015-11-13T00:00:00+09:00 そんなわけで、いくつかreface DXで音色を作ってみます。お題としてはマイク・オールドフィールドのチューブラーベルズ。後半に様々な楽器が同じフレーズを順番に演奏するパートがあり、そこに出てくる楽器をひととおりFM音源で再現してみます。 できた音はこんな感じです。全楽器reface DXだけで作成し、録音時のエフェクト加工などもしていません。 Grand Piano (0:00) グランドピアノの音は、アタック付近では倍音の多いノコギリ波、サスティンに従って正弦波のような甘い音になっていきます。前回も紹介したアルゴリズム8番で実装します。アタックが鋭すぎるとピックで弾いたような音になってしま… <p>そんなわけで、いくつかreface DXで音色を作ってみます。お題としては<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DE%A5%A4%A5%AF%A1%A6%A5%AA%A1%BC%A5%EB%A5%C9%A5%D5%A5%A3%A1%BC%A5%EB%A5%C9">マイク・オールドフィールド</a>の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C1%A5%E5%A1%BC%A5%D6%A5%E9%A1%BC%A5%D9%A5%EB">チューブラーベル</a>ズ。後半に様々な楽器が同じフレーズを順番に演奏するパートがあり、そこに出てくる楽器をひととおり<a class="keyword" href="http://d.hatena.ne.jp/keyword/FM%B2%BB%B8%BB">FM音源</a>で再現してみます。<br />  <br /> できた音はこんな感じです。全楽器reface DXだけで作成し、録音時のエフェクト加工などもしていません。<br /> <span style="vertical-align:middle;"><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" width="220" height="25" id="mp3_3" align="middle" style="vertical-align:bottom"><param name="flashVars" value="mp3Url=http://aikelab.net/dtm/20151113/tublarbells.mp3"><param name="allowScriptAccess" value="sameDomain"><param name="movie" value="http://g.hatena.ne.jp/tools/mp3_3.swf"><param name="quality" value="high"><param name="bgcolor" value="#ffffff"><param name="wmode" value="transparent"><embed src="http://g.hatena.ne.jp/tools/mp3_3.swf" flashvars="mp3Url=http://aikelab.net/dtm/20151113/tublarbells.mp3" quality="high" wmode="transparent" bgcolor="#ffffff" width="220" height="25" name="mp3_3" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" style="vertical-align:bottom"></object><a href="http://aikelab.net/dtm/20151113/tublarbells.mp3"><img src="http://g.hatena.ne.jp/images/podcasting.gif" title="Download" alt="Download" border="0" style="border:0px;vertical-align:bottom;"></a></span><br />  </p><p><span class="deco" style="font-weight:bold;">Grand Piano (0:00)</span><br /> グランドピアノの音は、アタック付近では<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C7%DC%B2%BB">倍音</a>の多いノコギリ波、サスティンに従って正弦波のような甘い音になっていきます。前回も紹介した<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%EB%A5%B4%A5%EA%A5%BA%A5%E0">アルゴリズム</a>8番で実装します。アタックが鋭すぎるとピックで弾いたような音になってしまうので、すこしなだらかな立ち上がりとします。<br /> ピアノの音は、ひとつの音ならわりと簡単に作れるものの、低音から高音まで、弱い音から強い音まですべて似せるのはわりと大変です。キーボードスケーリングで低い方の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C7%DC%B2%BB">倍音</a>を多めにして力強さを加え、ベロシティセンスで強く弾いたときに<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C7%DC%B2%BB">倍音</a>が多くなるようにしています。<br /> 最後に深いリ<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D0%A1%BC%A5%D6">バーブ</a>でボディとコンサートホールの響きを表現します。<br /> <a href="http://aikelab.net/dtm/20151107/pianoqr.jpg">reface capture&#x7528;QR&#x30B3;&#x30FC;&#x30C9;</a><br />  <br /> <span class="deco" style="font-weight:bold;">Reed and Pipe Organ (0:23)</span><br /> なんだかよくわからないオルガン系の音です。<br /> 普通のパイプオルガンは<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%EB%A5%B4%A5%EA%A5%BA%A5%E0">アルゴリズム</a>12の加算合成や、フィードバックによる<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B6%EB%B7%C1%C7%C8">矩形波</a>を作ると作りやすいです。ここではもう少しリードの特徴を出すためにフィードバックでノコギリ波を加えてクセのある音にしています。<br /> <a href="http://aikelab.net/dtm/20151113/organ.jpg">QR&#x30B3;&#x30FC;&#x30C9;</a><br />  <br /> <span class="deco" style="font-weight:bold;">Glockenspiel (0:46)</span><br /> <a class="keyword" href="http://d.hatena.ne.jp/keyword/FM%B2%BB%B8%BB">FM音源</a>の得意な金属音。<br /> プリセット4-7 GlassHarpをもとに、EGを金属的なアタックにして調整します。金属音はキャリアに対して3.5倍のFREQの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E2%A5%B8%A5%E5%A5%EC">モジュレ</a>ータという定番の設定ですね。<br /> <a href="http://aikelab.net/dtm/20151113/glocken.jpg">QR&#x30B3;&#x30FC;&#x30C9;</a><br />  <br /> <span class="deco" style="font-weight:bold;">Bass Guitar (1:09)</span><br /> ベースギターはプリセット1-6 DarkBassの音をもとに調整しました。<br /> 弦のベースらしいアタック感とサスティンをEGで作るだけでそれらしくなります。<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E2%A5%B8%A5%E5%A5%EC">モジュレ</a>ータであるOP2とOP4を下げめにすると落ち着いたベース音です。今回はメロディを弾くため不自然にならない程度に上げてドライブ感を出しています。<br /> <a href="http://aikelab.net/dtm/20151113/bass.jpg">QR&#x30B3;&#x30FC;&#x30C9;</a><br />  <br /> <span class="deco" style="font-weight:bold;">Double Speed Guitar (1:32)</span><br /> ちょっと風変わりな<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A8%A5%EC%A5%AD%A5%AE%A5%BF%A1%BC">エレキギター</a>の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AF%A5%EA%A1%BC%A5%F3%A5%C8%A1%BC%A5%F3">クリーントーン</a>。<br /> コツコツしたアタックと中高域にクセのあるサスティンは、<a class="keyword" href="http://d.hatena.ne.jp/keyword/FM%B2%BB%B8%BB">FM音源</a>では意外と再現が難しいです。瞬間的な<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B6%EB%B7%C1%C7%C8">矩形波</a>でアタックを、キャリアOP3と<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E2%A5%B8%A5%E5%A5%EC">モジュレ</a>ータOP4の周波数比を 2:3 にしてサスティンのクセを表現しています。さらに<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E2%A5%B8%A5%E5%A5%EC">モジュレ</a>ータOP4の立ち上がりを少し遅くすることで、弦が共振して遅れて<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C7%DC%B2%BB">倍音</a>が増える雰囲気を出しました。また、歪んでると気づかないくらい薄く<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%A3%A5%B9%A5%C8%A1%BC%A5%B7%A5%E7%A5%F3">ディストーション</a>をかけてアナログ感を出しています。<br /> <a href="http://aikelab.net/dtm/20151113/doubleguitar.jpg">QR&#x30B3;&#x30FC;&#x30C9;</a><br />  <br /> <span class="deco" style="font-weight:bold;">Two Slightly Distorted Guitar (1:55)</span><br /> 歪んだギター。<br /> Bass Guitarをオクターブ上げてEFFECTの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%A3%A5%B9%A5%C8%A1%BC%A5%B7%A5%E7%A5%F3">ディストーション</a>をかけるとそれだけで良い感じになります。ギターの歪みは<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B6%EB%B7%C1%C7%C8">矩形波</a>に近いので、エフェクトをかける前の音もFBで<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B6%EB%B7%C1%C7%C8">矩形波</a>に近づけると雰囲気が出ます。<br /> 今回は原曲風のゴツゴツしたアタックを再現しましたが、人間の弾くギターのアタックはとても多彩なので無理にアタックを強調しない方が良い場合が多いと思います。上手いギタリストのレガート奏法のようななめらかなアタックを出すために、MONOモードにするのもおすすめです。<br /> <a href="http://aikelab.net/dtm/20151113/distortedguitar.jpg">QR&#x30B3;&#x30FC;&#x30C9;</a><br />  <br /> <span class="deco" style="font-weight:bold;">Mand...lin (2:17)</span><br /> <a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DE%A5%F3%A5%C9%A5%EA%A5%F3">マンドリン</a>の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C8%A5%EC%A5%E2%A5%ED">トレモロ</a>。<br /> 小さめのボディの共鳴を再現するため<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B6%EB%B7%C1%C7%C8">矩形波</a>に近い波形にします。<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DE%A5%F3%A5%C9%A5%EA%A5%F3">マンドリン</a>は弦が2本ずつ張ってあるためコーラスエフェクトをかけます。refaceには<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C8%A5%EC%A5%E2%A5%ED">トレモロ</a>の再現に便利なEG Loopがないので<a class="keyword" href="http://d.hatena.ne.jp/keyword/LFO">LFO</a>でがんばります。がんばったけど、あんまり似なかったので深めのリ<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D0%A1%BC%A5%D6">バーブ</a>でごまかします。<br /> <a href="http://aikelab.net/dtm/20151113/mandlin.jpg">QR&#x30B3;&#x30FC;&#x30C9;</a><br />  <br /> <span class="deco" style="font-weight:bold;">Spanish Guitar and Introducing Acoustic Guitar (2:40)</span><br /> これは原曲でも他の音に混ざってよく聞こえないので普通にアコギの単音ソロ風の音を作ってみました。定番の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%EB%A5%B4%A5%EA%A5%BA%A5%E0">アルゴリズム</a>8で、ボディが低く響くサスティンとアコギの弦特有のトレブリーな<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C7%DC%B2%BB">倍音</a>を組み合わせています。これも<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E2%A5%B8%A5%E5%A5%EC">モジュレ</a>ータの立ち上がりを少し遅くして共振の隠し味を加えています。また、ベロシティセンスを上げめにして<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C0%A5%A4%A5%CA%A5%DF%A5%AF%A5%B9">ダイナミクス</a>をつけやすくしました。<br /> <a href="http://aikelab.net/dtm/20151113/spanishguitar.jpg">QR&#x30B3;&#x30FC;&#x30C9;</a><br />  <br /> <span class="deco" style="font-weight:bold;">and Tublar Bells! (3:04)</span><br /> 最後に<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C1%A5%E5%A1%BC%A5%D6%A5%E9%A1%BC%A5%D9%A5%EB">チューブラーベル</a>ズ。<br /> プリセットにあるのであんまりすることがないです。プリセットの音は残響が長すぎるので少し調整。<br /> <a class="keyword" href="http://d.hatena.ne.jp/keyword/FM%B2%BB%B8%BB">FM音源</a>では金属音が出しやすいものの、どうしても柱時計のような音になりがちなので<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E2%A5%B8%A5%E5%A5%EC">モジュレ</a>ータを上げすぎないなど工夫が必要です。原曲のチュブラーベルズの音はローをカットしたような音なので二つのキャリアの一方をオクターブ上にしてみます。でもやっぱりreface DXだけでは再現が難しいです。<br /> 今回はやっていませんが、後から<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%B3%A5%E9%A5%A4%A5%B6%A1%BC">イコライザー</a>をかけてローカットするとそれっぽくなると思います。<br /> <a href="http://aikelab.net/dtm/20151113/tublarbells.jpg">QR&#x30B3;&#x30FC;&#x30C9;</a><br />  </p> aike 今夜わかるFM音源 hatenablog://entry/10257846132645780760 2015-11-07T00:00:00+09:00 2015-11-07T00:00:00+09:00 reface DXいいですね。あえてDX7シリーズに近い音源仕様と、現代的な使いやすい操作性とを組み合わせることで、FM音源本来の音作りの楽しさがあります。とはいえ、先日Web Music Developer Meetup@Sapporoの参加者と話して、こういったイベントに参加するような人でも、FM音源でイメージどおりの音をつくるのは難しいと感じる人が多いようでした。そんなわけで、今回はちょっと実践的な音作り方法について書いてみようと思います。 ■キャリアとモジュレータ FM音源はオペレータと呼ばれる発振モジュールを組み合わせて音をつくります。変調される側をキャリア、する側をモジュレータと呼… <p><a href="http://jp.yamaha.com/products/music-production/synthesizers/reface/">reface DX</a>いいですね。あえて<a class="keyword" href="http://d.hatena.ne.jp/keyword/DX7">DX7</a>シリーズに近い音<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B8%BB%BB%C5">源仕</a>様と、現代的な使いやすい操作性とを組み合わせることで、<a class="keyword" href="http://d.hatena.ne.jp/keyword/FM%B2%BB%B8%BB">FM音源</a>本来の音作りの楽しさがあります。とはいえ、先日<a href="http://dev.classmethod.jp/event/web-music-developer-meetup-sapporo-report/">Web Music Developer Meetup@Sapporo</a>の参加者と話して、こういったイベントに参加するような人でも、<a class="keyword" href="http://d.hatena.ne.jp/keyword/FM%B2%BB%B8%BB">FM音源</a>でイメージどおりの音をつくるのは難しいと感じる人が多いようでした。そんなわけで、今回はちょっと実践的な音作り方法について書いてみようと思います。<br />  </p><p><span class="deco" style="font-size:large;">■キャリアと<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E2%A5%B8%A5%E5%A5%EC">モジュレ</a>ータ</span><br /> <a class="keyword" href="http://d.hatena.ne.jp/keyword/FM%B2%BB%B8%BB">FM音源</a>はオペレータと呼ばれる発振モジュールを組み合わせて音をつくります。変調される側をキャリア、する側を<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E2%A5%B8%A5%E5%A5%EC">モジュレ</a>ータと呼びますが、これは相対的なもので、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%EB%A5%B4%A5%EA%A5%BA%A5%E0">アルゴリズム</a>によっては変調されたキャリアがまた別のオペレータの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E2%A5%B8%A5%E5%A5%EC">モジュレ</a>ータになることもあります。<br />  <br /> と、いうようなよくある説明を読んでもなかなか音色にむすびつかないですよね。ここでは、自分の場合の音作りのワークフローを例に説明していきます。</p><p> </p><p><span class="deco" style="font-size:large;">■ハープの作成</span><br /> 最初の例としてハープの音をつくることにします。オーケストラの後ろの方で優雅にポロロンと弾いているあれです。<br />  <br /> <span class="deco" style="font-weight:bold;">1. <a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%EB%A5%B4%A5%EA%A5%BA%A5%E0">アルゴリズム</a>の選定</span><br /> 音色の特徴はアタック時の波形とサスティン時の波形にあらわれやすいです。一般的にアタックは<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C7%DC%B2%BB">倍音</a>やノイズを多く含み、サスティンは<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C7%DC%B2%BB">倍音</a>が少ないので、アタックの音色とサスティンの音色を別々につくって最後にバランスをとる、という進め方がおすすめです。</p><p> </p><p>こういった考え方の音作りに一番便利な<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%EB%A5%B4%A5%EA%A5%BA%A5%E0">アルゴリズム</a>は8番です。アタック用とサスティン用にキャリアと<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E2%A5%B8%A5%E5%A5%EC">モジュレ</a>ータが一組ずつ使えます。実際プリセットもこれを使っているのが多くて、DXの音として名高いエレピや<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DE%A5%EA%A5%F3%A5%D0">マリンバ</a>のプリセットもこの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%EB%A5%B4%A5%EA%A5%BA%A5%E0">アルゴリズム</a>です。</p><p><span itemscope itemtype="http://schema.org/Photograph"><a href="http://f.hatena.ne.jp/aike/20151107165855" class="hatena-fotolife" itemprop="url"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20151107/20151107165855.jpg" alt="f:id:aike:20151107165855j:image" title="f:id:aike:20151107165855j:image" class="hatena-fotolife" itemprop="image"></a></span></p><br /> <p>図を見てわかるように最終出力につながるオペレータが2個あります。これが1個の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%EB%A5%B4%A5%EA%A5%BA%A5%E0">アルゴリズム</a>はエグい音用、2個は汎用的、3&#12316;4個になるとオルガンやパッドのような音、というような大まかなイメージです。</p><br /> <p><span class="deco" style="font-weight:bold;">2. <a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A8%A5%F3%A5%D9%A5%ED%A1%BC%A5%D7">エンベロープ</a>仮設定</span><br /> reface DXのEGは<a class="keyword" href="http://d.hatena.ne.jp/keyword/DX7">DX7</a>と同じくパラメーターが多くて大変です。なので、初期値としてパラメーターを以下のようにしてしまって、通常はR1(A)、 R3(D)、 L3(S)、R4(R)だけ操作するようにしてしまえれば、一般的なシンセのADSRと同じなので作業のとっかかりが楽になります。その後微調整したくなったときにはじめて他のパラメーターを触るようにします。</p><p> L1:127 L2:127 L3:64 L4:0<br />  R1:127 R2:127 R3:64 R4:64</p><p><span itemscope itemtype="http://schema.org/Photograph"><a href="http://f.hatena.ne.jp/aike/20151107165901" class="hatena-fotolife" itemprop="url"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20151107/20151107165901.jpg" alt="f:id:aike:20151107165901j:image" title="f:id:aike:20151107165901j:image" class="hatena-fotolife" itemprop="image"></a></span></p><br /> <p>今回は、減衰音ということでL3=0にして、サスティン用にオペレータ1の減衰時間R3を長めの50に、アタック用にオペレータ3の減衰時間R3を短めの100にします。あとで微調整するのでここではざっくりの設定です。</p><p><span style="vertical-align:middle;"><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" width="220" height="25" id="mp3_3" align="middle" style="vertical-align:bottom"><param name="flashVars" value="mp3Url=http://aikelab.net/dtm/20151107/kanon1.mp3"><param name="allowScriptAccess" value="sameDomain"><param name="movie" value="http://g.hatena.ne.jp/tools/mp3_3.swf"><param name="quality" value="high"><param name="bgcolor" value="#ffffff"><param name="wmode" value="transparent"><embed src="http://g.hatena.ne.jp/tools/mp3_3.swf" flashvars="mp3Url=http://aikelab.net/dtm/20151107/kanon1.mp3" quality="high" wmode="transparent" bgcolor="#ffffff" width="220" height="25" name="mp3_3" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" style="vertical-align:bottom"></object><a href="http://aikelab.net/dtm/20151107/kanon1.mp3"><img src="http://g.hatena.ne.jp/images/podcasting.gif" title="Download" alt="Download" border="0" style="border:0px;vertical-align:bottom;"></a></span></p><br /> <p><span class="deco" style="font-weight:bold;">3. サスティン音の作成</span><br /> さて、ハープのような弦をはじく楽器(<a class="keyword" href="http://d.hatena.ne.jp/keyword/%D9%FB%B8%B9%B3%DA%B4%EF">撥弦楽器</a>)の場合、弦の振動は正弦波かそれに近いノコギリ波の軌道を描きます。<br /> <a href="https://www.youtube.com/watch?v=6sgI7S_G-XI">https://www.youtube.com/watch?v=6sgI7S_G-XI</a> </p><p>これはreface DXの場合、FEEDBACKだけで再現できそうです。まずオペレータ1以外のLEVELを0にします。次にオペレータ1のFEEDBACKをそれっぽい音になるまで上げていきます。40くらいが良さそうです。またこのときEGのR1、R3、R4を微調整します。</p><p><span style="vertical-align:middle;"><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" width="220" height="25" id="mp3_3" align="middle" style="vertical-align:bottom"><param name="flashVars" value="mp3Url=http://aikelab.net/dtm/20151107/kanon2.mp3"><param name="allowScriptAccess" value="sameDomain"><param name="movie" value="http://g.hatena.ne.jp/tools/mp3_3.swf"><param name="quality" value="high"><param name="bgcolor" value="#ffffff"><param name="wmode" value="transparent"><embed src="http://g.hatena.ne.jp/tools/mp3_3.swf" flashvars="mp3Url=http://aikelab.net/dtm/20151107/kanon2.mp3" quality="high" wmode="transparent" bgcolor="#ffffff" width="220" height="25" name="mp3_3" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" style="vertical-align:bottom"></object><a href="http://aikelab.net/dtm/20151107/kanon2.mp3"><img src="http://g.hatena.ne.jp/images/podcasting.gif" title="Download" alt="Download" border="0" style="border:0px;vertical-align:bottom;"></a></span></p><p>ちなみに、キャリアと<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E2%A5%B8%A5%E5%A5%EC">モジュレ</a>ータの周波数比の定番としては以下のようなものがあります。reface DXはFEEDBACKでいろいろできてしまいますが、知識として知っておくとなにかと役立ちます。</p><p> ・ノコギリ波 1:1 ブラス、ストリングス<br />  ・<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B6%EB%B7%C1%C7%C8">矩形波</a> 1:2 <a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AF%A5%E9%A5%EA%A5%CD%A5%C3%A5%C8">クラリネット</a>、笛、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EC%A5%C8%A5%ED%A5%B2%A1%BC%A5%E0">レトロゲーム</a><br />  ・金属音 1:3.5</p><br /> <p><span class="deco" style="font-weight:bold;">4. アタック音の作成</span><br /> こんどはオペレータ1のLEVELを0にして、代わりにオペレータ3のレベルを上げてアタック音を調整します。ハープは、指で弾くためアタック時のノイ<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B8%A1%BC">ジー</a>な高周波はほぼゼロと考えてよさそうです。<br /> 次にハープの構造をググって調べます。奏者のおねえさんが抱えているあたりに、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%B3%A1%BC%A5%B9%A5%C6%A5%A3%A5%C3%A5%AF%A5%AE%A5%BF%A1%BC">アコースティックギター</a>のような共鳴胴と<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B5%A5%A6%A5%F3%A5%C9">サウンド</a>ホールがあるようです。ということは箱が共鳴するような中域が響く音だと予想できますね。中域が共鳴する音は<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B6%EB%B7%C1%C7%C8">矩形波</a>で再現しやすいのでオペレータ3のFEEDBACKをマイナス方向に下げていきます。-74にするとそれっぽくなってきました。EGのR1、R3、R4も同様に微調整します。R3は83くらいが良さそうです。</p><p><span style="vertical-align:middle;"><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" width="220" height="25" id="mp3_3" align="middle" style="vertical-align:bottom"><param name="flashVars" value="mp3Url=http://aikelab.net/dtm/20151107/kanon3.mp3"><param name="allowScriptAccess" value="sameDomain"><param name="movie" value="http://g.hatena.ne.jp/tools/mp3_3.swf"><param name="quality" value="high"><param name="bgcolor" value="#ffffff"><param name="wmode" value="transparent"><embed src="http://g.hatena.ne.jp/tools/mp3_3.swf" flashvars="mp3Url=http://aikelab.net/dtm/20151107/kanon3.mp3" quality="high" wmode="transparent" bgcolor="#ffffff" width="220" height="25" name="mp3_3" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" style="vertical-align:bottom"></object><a href="http://aikelab.net/dtm/20151107/kanon3.mp3"><img src="http://g.hatena.ne.jp/images/podcasting.gif" title="Download" alt="Download" border="0" style="border:0px;vertical-align:bottom;"></a></span></p><br /> <p><span class="deco" style="font-weight:bold;">5. エフェクトの設定</span><br />  ハープはコンサートホールのようなところで鳴っている音がなじみ深いので、深めのリ<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D0%A1%BC%A5%D6">バーブ</a>をかけます。</p><p><span style="vertical-align:middle;"><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" width="220" height="25" id="mp3_3" align="middle" style="vertical-align:bottom"><param name="flashVars" value="mp3Url=http://aikelab.net/dtm/20151107/kanon4.mp3"><param name="allowScriptAccess" value="sameDomain"><param name="movie" value="http://g.hatena.ne.jp/tools/mp3_3.swf"><param name="quality" value="high"><param name="bgcolor" value="#ffffff"><param name="wmode" value="transparent"><embed src="http://g.hatena.ne.jp/tools/mp3_3.swf" flashvars="mp3Url=http://aikelab.net/dtm/20151107/kanon4.mp3" quality="high" wmode="transparent" bgcolor="#ffffff" width="220" height="25" name="mp3_3" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" style="vertical-align:bottom"></object><a href="http://aikelab.net/dtm/20151107/kanon4.mp3"><img src="http://g.hatena.ne.jp/images/podcasting.gif" title="Download" alt="Download" border="0" style="border:0px;vertical-align:bottom;"></a></span></p><br /> <p><span class="deco" style="font-weight:bold;">6.最終調整</span><br /> サスティン(オペレータ1)とアタック(オペレータ3)とのレベルバランスをとったら完成です。今回はオペレータ2と4は使いませんでした。もう少し<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C7%DC%B2%BB">倍音</a>を加えたいときに少しずつ上げるようにして使います。</p><p><span style="vertical-align:middle;"><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" width="220" height="25" id="mp3_3" align="middle" style="vertical-align:bottom"><param name="flashVars" value="mp3Url=http://aikelab.net/dtm/20151107/kanon5.mp3"><param name="allowScriptAccess" value="sameDomain"><param name="movie" value="http://g.hatena.ne.jp/tools/mp3_3.swf"><param name="quality" value="high"><param name="bgcolor" value="#ffffff"><param name="wmode" value="transparent"><embed src="http://g.hatena.ne.jp/tools/mp3_3.swf" flashvars="mp3Url=http://aikelab.net/dtm/20151107/kanon5.mp3" quality="high" wmode="transparent" bgcolor="#ffffff" width="220" height="25" name="mp3_3" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" style="vertical-align:bottom"></object><a href="http://aikelab.net/dtm/20151107/kanon5.mp3"><img src="http://g.hatena.ne.jp/images/podcasting.gif" title="Download" alt="Download" border="0" style="border:0px;vertical-align:bottom;"></a></span><br /> <span itemscope itemtype="http://schema.org/Photograph"><a href="http://f.hatena.ne.jp/aike/20151107153540" class="hatena-fotolife" itemprop="url"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20151107/20151107153540.png" alt="f:id:aike:20151107153540p:image" title="f:id:aike:20151107153540p:image" class="hatena-fotolife" itemprop="image"></a></span><br /> <a href="http://aikelab.net/dtm/20151107/harpqr.jpg">reface capture&#x7528;QR&#x30B3;&#x30FC;&#x30C9;</a></p><br /> <p><span class="deco" style="font-size:large;">■ストリングスの作成</span><br /> 次はストリングスを作ってみます。オーケストラ風の存在感のある音を目指します。</p><br /> <p><span class="deco" style="font-weight:bold;">1.<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%EB%A5%B4%A5%EA%A5%BA%A5%E0">アルゴリズム</a>の選定</span><br /> ストリングスの音はバイオリンやチェロなどたくさんの音が一斉に鳴っているところに特徴があります。そんなわけで全部のオペレータを並列に鳴らす<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%EB%A5%B4%A5%EA%A5%BA%A5%E0">アルゴリズム</a>12を選びます。</p><p><span itemscope itemtype="http://schema.org/Photograph"><a href="http://f.hatena.ne.jp/aike/20151107165858" class="hatena-fotolife" itemprop="url"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20151107/20151107165858.jpg" alt="f:id:aike:20151107165858j:image" title="f:id:aike:20151107165858j:image" class="hatena-fotolife" itemprop="image"></a></span></p><br /> <p><span class="deco" style="font-weight:bold;">2.<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A8%A5%F3%A5%D9%A5%ED%A1%BC%A5%D7">エンベロープ</a>仮設定</span><br /> ストリングスは持続音でアタックが遅いので全部のオペレータを下のような<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A8%A5%F3%A5%D9%A5%ED%A1%BC%A5%D7">エンベロープ</a>にします。<br />  L1:127 L2:127 L3:127 L4:0<br />  R1:70 R2:127 R3:127 R4:90</p><p><span style="vertical-align:middle;"><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" width="220" height="25" id="mp3_3" align="middle" style="vertical-align:bottom"><param name="flashVars" value="mp3Url=http://aikelab.net/dtm/20151107/can0.mp3"><param name="allowScriptAccess" value="sameDomain"><param name="movie" value="http://g.hatena.ne.jp/tools/mp3_3.swf"><param name="quality" value="high"><param name="bgcolor" value="#ffffff"><param name="wmode" value="transparent"><embed src="http://g.hatena.ne.jp/tools/mp3_3.swf" flashvars="mp3Url=http://aikelab.net/dtm/20151107/can0.mp3" quality="high" wmode="transparent" bgcolor="#ffffff" width="220" height="25" name="mp3_3" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" style="vertical-align:bottom"></object><a href="http://aikelab.net/dtm/20151107/can0.mp3"><img src="http://g.hatena.ne.jp/images/podcasting.gif" title="Download" alt="Download" border="0" style="border:0px;vertical-align:bottom;"></a></span></p><br /> <p><span class="deco" style="font-weight:bold;">3.サスティン音の作成</span><br /> バイオリンのような弓で弾く<a class="keyword" href="http://d.hatena.ne.jp/keyword/%BB%A4%B8%B9%B3%DA%B4%EF">擦弦楽器</a>の弦の振動は、典型的なノコギリ波の軌道を描きます。<br /> <a href="https://www.youtube.com/watch?v=6JeyiM0YNo4">https://www.youtube.com/watch?v=6JeyiM0YNo4</a></p><p>今回も鳴らすオペレータ以外のレベルをゼロにして、すべてのオペレータひとつずつのFEEDBACKをそれっぽい音になるまで上げていきます。60くらいで良い感じになりました。</p><p><span style="vertical-align:middle;"><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" width="220" height="25" id="mp3_3" align="middle" style="vertical-align:bottom"><param name="flashVars" value="mp3Url=http://aikelab.net/dtm/20151107/can1.mp3"><param name="allowScriptAccess" value="sameDomain"><param name="movie" value="http://g.hatena.ne.jp/tools/mp3_3.swf"><param name="quality" value="high"><param name="bgcolor" value="#ffffff"><param name="wmode" value="transparent"><embed src="http://g.hatena.ne.jp/tools/mp3_3.swf" flashvars="mp3Url=http://aikelab.net/dtm/20151107/can1.mp3" quality="high" wmode="transparent" bgcolor="#ffffff" width="220" height="25" name="mp3_3" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" style="vertical-align:bottom"></object><a href="http://aikelab.net/dtm/20151107/can1.mp3"><img src="http://g.hatena.ne.jp/images/podcasting.gif" title="Download" alt="Download" border="0" style="border:0px;vertical-align:bottom;"></a></span></p><br /> <p><span class="deco" style="font-weight:bold;">4.オクターブの調整</span><br />  オーケストラの弦楽器構成を想像して、低域、中域、高域にオペレータを振り分けます。オペレータ1のFREQを0.50、オペレータ2と3のFREQを1.00、オペレータ4のFREQを2.00にします。これで2オクターブに渡るユ<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%CB%A5%BE%A5%F3">ニゾン</a>になります。</p><p><span style="vertical-align:middle;"><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" width="220" height="25" id="mp3_3" align="middle" style="vertical-align:bottom"><param name="flashVars" value="mp3Url=http://aikelab.net/dtm/20151107/can2.mp3"><param name="allowScriptAccess" value="sameDomain"><param name="movie" value="http://g.hatena.ne.jp/tools/mp3_3.swf"><param name="quality" value="high"><param name="bgcolor" value="#ffffff"><param name="wmode" value="transparent"><embed src="http://g.hatena.ne.jp/tools/mp3_3.swf" flashvars="mp3Url=http://aikelab.net/dtm/20151107/can2.mp3" quality="high" wmode="transparent" bgcolor="#ffffff" width="220" height="25" name="mp3_3" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" style="vertical-align:bottom"></object><a href="http://aikelab.net/dtm/20151107/can2.mp3"><img src="http://g.hatena.ne.jp/images/podcasting.gif" title="Download" alt="Download" border="0" style="border:0px;vertical-align:bottom;"></a></span></p><br /> <p><span class="deco" style="font-weight:bold;">5.厚み・広がりの調整</span><br /> ピッチやタイミングが正確すぎると、たくさんの音が鳴っているようには聞こえません。プラスマイナス10くらいの範囲で各オペレータのデチューンを設定することで音に広がりが出ます。また、EGのR1(アタック)、R4(リリース)を微調整して適当にばらけさせました。</p><p><span style="vertical-align:middle;"><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" width="220" height="25" id="mp3_3" align="middle" style="vertical-align:bottom"><param name="flashVars" value="mp3Url=http://aikelab.net/dtm/20151107/can3.mp3"><param name="allowScriptAccess" value="sameDomain"><param name="movie" value="http://g.hatena.ne.jp/tools/mp3_3.swf"><param name="quality" value="high"><param name="bgcolor" value="#ffffff"><param name="wmode" value="transparent"><embed src="http://g.hatena.ne.jp/tools/mp3_3.swf" flashvars="mp3Url=http://aikelab.net/dtm/20151107/can3.mp3" quality="high" wmode="transparent" bgcolor="#ffffff" width="220" height="25" name="mp3_3" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" style="vertical-align:bottom"></object><a href="http://aikelab.net/dtm/20151107/can3.mp3"><img src="http://g.hatena.ne.jp/images/podcasting.gif" title="Download" alt="Download" border="0" style="border:0px;vertical-align:bottom;"></a></span></p><br /> <p><span class="deco" style="font-weight:bold;">6.エフェクトの設定</span><br /> さらにたくさんの音で鳴っている効果をつけるため、コーラスエフェクトをかけます。ふたつめのエフェクトは、こちらもコンサートホールの響きを再現するためリ<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D0%A1%BC%A5%D6">バーブ</a>をかけます。各オペレータのレベルバランスも調整したらこんな感じ。</p><p><span style="vertical-align:middle;"><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" width="220" height="25" id="mp3_3" align="middle" style="vertical-align:bottom"><param name="flashVars" value="mp3Url=http://aikelab.net/dtm/20151107/can4.mp3"><param name="allowScriptAccess" value="sameDomain"><param name="movie" value="http://g.hatena.ne.jp/tools/mp3_3.swf"><param name="quality" value="high"><param name="bgcolor" value="#ffffff"><param name="wmode" value="transparent"><embed src="http://g.hatena.ne.jp/tools/mp3_3.swf" flashvars="mp3Url=http://aikelab.net/dtm/20151107/can4.mp3" quality="high" wmode="transparent" bgcolor="#ffffff" width="220" height="25" name="mp3_3" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" style="vertical-align:bottom"></object><a href="http://aikelab.net/dtm/20151107/can4.mp3"><img src="http://g.hatena.ne.jp/images/podcasting.gif" title="Download" alt="Download" border="0" style="border:0px;vertical-align:bottom;"></a></span></p><br /> <p><span class="deco" style="font-weight:bold;">7.最後にひと工夫</span><br /> これでもかなり良い感じのストリングスですが、アタックのときに弓が弦にこすれるザリッとしたニュアンスを加えてみます。<br /> オペレータ2のFEEDBACKを上げて<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C7%DC%B2%BB">倍音</a>を加えます。また、オペレータ2の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A8%A5%F3%A5%D9%A5%ED%A1%BC%A5%D7">エンベロープ</a>を下のようにしてアタックは大きく、サスティンは他よりも小さくなるようにします。</p><p><span itemscope itemtype="http://schema.org/Photograph"><a href="http://f.hatena.ne.jp/aike/20151107165851" class="hatena-fotolife" itemprop="url"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20151107/20151107165851.jpg" alt="f:id:aike:20151107165851j:image" title="f:id:aike:20151107165851j:image" class="hatena-fotolife" itemprop="image"></a></span></p><br /> <p>他のオペレータも気持ちR1とFBを増やしてアタック感と<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C7%DC%B2%BB">倍音</a>を加えます。全体のレベルバランスをとったらできあがり。</p><p><span style="vertical-align:middle;"><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" width="220" height="25" id="mp3_3" align="middle" style="vertical-align:bottom"><param name="flashVars" value="mp3Url=http://aikelab.net/dtm/20151107/can5.mp3"><param name="allowScriptAccess" value="sameDomain"><param name="movie" value="http://g.hatena.ne.jp/tools/mp3_3.swf"><param name="quality" value="high"><param name="bgcolor" value="#ffffff"><param name="wmode" value="transparent"><embed src="http://g.hatena.ne.jp/tools/mp3_3.swf" flashvars="mp3Url=http://aikelab.net/dtm/20151107/can5.mp3" quality="high" wmode="transparent" bgcolor="#ffffff" width="220" height="25" name="mp3_3" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" style="vertical-align:bottom"></object><a href="http://aikelab.net/dtm/20151107/can5.mp3"><img src="http://g.hatena.ne.jp/images/podcasting.gif" title="Download" alt="Download" border="0" style="border:0px;vertical-align:bottom;"></a></span><br /> <span itemscope itemtype="http://schema.org/Photograph"><a href="http://f.hatena.ne.jp/aike/20151107153541" class="hatena-fotolife" itemprop="url"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20151107/20151107153541.png" alt="f:id:aike:20151107153541p:image" title="f:id:aike:20151107153541p:image" class="hatena-fotolife" itemprop="image"></a></span><br /> <a href="http://aikelab.net/dtm/20151107/stringsqr.jpg">QR</a></p><p>ね?簡単でしょ。</p><p> </p><p>次回はピアノの音の作り方とか紹介します。こんなやつ。<br /> <span style="vertical-align:middle;"><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" width="220" height="25" id="mp3_3" align="middle" style="vertical-align:bottom"><param name="flashVars" value="mp3Url=http://aikelab.net/dtm/20151107/piano.mp3"><param name="allowScriptAccess" value="sameDomain"><param name="movie" value="http://g.hatena.ne.jp/tools/mp3_3.swf"><param name="quality" value="high"><param name="bgcolor" value="#ffffff"><param name="wmode" value="transparent"><embed src="http://g.hatena.ne.jp/tools/mp3_3.swf" flashvars="mp3Url=http://aikelab.net/dtm/20151107/piano.mp3" quality="high" wmode="transparent" bgcolor="#ffffff" width="220" height="25" name="mp3_3" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" style="vertical-align:bottom"></object><a href="http://aikelab.net/dtm/20151107/piano.mp3"><img src="http://g.hatena.ne.jp/images/podcasting.gif" title="Download" alt="Download" border="0" style="border:0px;vertical-align:bottom;"></a></span><br /> <a href="http://aikelab.net/dtm/20151107/pianoqr.jpg">QR</a></p><br /> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Faike.hatenablog.com%2Fentry%2F20151113" title="今夜わかるFM音源 その2 - aike’s blog" class="embed-card embed-blogcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 190px; max-width: 500px; margin: 10px 0px;"></iframe><cite class="hatena-citation"><a href="https://aike.hatenablog.com/entry/20151113">aike.hatenablog.com</a></cite></p> aike Processingの本の表紙がなにかおかしい hatenablog://entry/10257846132645780819 2015-08-12T00:00:00+09:00 2015-08-12T00:00:00+09:00 今度Processing言語の良さそうな翻訳本が出るらしいんですが、Amazonで見ると書影がちょっとどうかしてるということで話題になりました。 tgtr.ListWidget({id:'859300',url:'http://togetter.com/',width:'500px',height:'240px'}); はたしてこれがそのまま表紙になるのか、それともとりあえずの仮の画像なのかはよくわかっていません。一般的にこの手のクリエイティブ・コーディングとかジェネラティブ・アートとかいわれるジャンルの書籍は、その題材とする言語自身で出力されたグラフィックを表紙とするのが通例のように思います… <p>今度Processing言語の良さそうな翻訳本が出るらしいんですが、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Amazon">Amazon</a>で見ると書影がちょっとどうかしてるということで話題になりました。<br />  <br /> <script src="http://togetter.com/js/parts.js"></script><script>tgtr.ListWidget({id:'859300',url:'http://togetter.com/',width:'500px',height:'240px'});</script><br />  <br /> はたしてこれがそのまま表紙になるのか、それともとりあえずの仮の画像なのかはよくわかっていません。一般的にこの手のクリエイティブ・コーディングとかジェネラティブ・アートとかいわれるジャンルの書籍は、その題材とする言語自身で出力されたグラフィックを表紙とするのが通例のように思います。はっ、ということは、これはこの書影をProcessingでジェネレートしてみろという出版社からの挑戦状なのでは?<br />  <br /> そんなわけで描いてみました。パーリンノイズをつかっていて、リロードするたびに輪郭線などが変わります。<br /> <a href="http://aikelab.net/processingbook/">http://aikelab.net/processingbook/</a><br />  <br /> ソースはこちら。<br /> <a href="http://aikelab.net/processingbook/bookimage.pde">http://aikelab.net/processingbook/bookimage.pde</a><br />  <div class="hatena-asin-detail"><br /> <a href="http://www.amazon.co.jp/dp/4861009502/?tag=lifehacklife-22&ascsubtag=d-11lyr"><img src="http://ecx.images-amazon.com/images/I/413V54N7mJL._SL160_.jpg" class="hatena-asin-detail-image" alt="Processing ビジュアルデザイナーとアーティストのためのプログラミング入門(仮)" title="Processing ビジュアルデザイナーとアーティストのためのプログラミング入門(仮)"></a><br /> <div class="hatena-asin-detail-info"><br /> <p class="hatena-asin-detail-title"><a href="http://www.amazon.co.jp/dp/4861009502/?tag=lifehacklife-22&ascsubtag=d-11lyr">Processing ビジュアルデザイナーとアーティストのためのプログラミング入門(仮)</a></p> <ul> <li><span class="hatena-asin-detail-label">作者:</span> <a href="http://d.hatena.ne.jp/keyword/%A5%D9%A5%F3%A1%A6%A5%D5%A5%E9%A5%A4" class="keyword">ベン・フライ</a>,<a href="http://d.hatena.ne.jp/keyword/%A5%B1%A5%A4%A5%B7%A1%BC%A1%A6%A5%EA%A1%BC%A5%B9" class="keyword">ケイシー・リース</a>,<a href="http://d.hatena.ne.jp/keyword/%C3%E6%C0%BE%C2%D9%BF%CD" class="keyword">中西泰人</a>,<a href="http://d.hatena.ne.jp/keyword/%B0%C2%C6%A3%B9%AC%B1%FB" class="keyword">安藤幸央</a>,<a href="http://d.hatena.ne.jp/keyword/%DF%B7%C2%BC%C0%B5%BC%F9" class="keyword">澤村正樹</a>,<a href="http://d.hatena.ne.jp/keyword/%BF%F9%CB%DC%C3%A3%D8%E6" class="keyword">杉本達應</a></li> <li><span class="hatena-asin-detail-label">出版社/メーカー:</span> <a href="http://d.hatena.ne.jp/keyword/%A5%D3%A1%BC%A1%A6%A5%A8%A5%CC%A1%A6%A5%A8%A5%CC%BF%B7%BC%D2" class="keyword">ビー・エヌ・エヌ新社</a></li> <li><span class="hatena-asin-detail-label">発売日:</span> 2015/09/20</li> <li><span class="hatena-asin-detail-label">メディア:</span> 単行本</li> <li><a href="http://d.hatena.ne.jp/asin/4861009502" target="_blank">この商品を含むブログを見る</a></li> </ul> </div> <div class="hatena-asin-detail-foot"></div></div></p> aike Webページに丸を描く5つの方法 hatenablog://entry/10257846132645780826 2015-07-28T00:00:00+09:00 2015-07-28T00:00:00+09:00 ひまなのでWebで丸を描く方法についていろいろ考えてみました。TMTOWTDI。 http://aikelab.net/circle ▪文字 <div id="mychar">●</div> #mychar { color: #00f; font-size: 120px; } ▪CSS <div id="mydiv"></div> #mydiv { width: 100px; height: 100px; margin-left: auto; margin-right: auto; -webkit-border-radius: 50px; -moz-border-radius: 50px; b… <p>ひまなのでWebで丸を描く方法についていろいろ考えてみました。<a class="keyword" href="http://d.hatena.ne.jp/keyword/TMTOWTDI">TMTOWTDI</a>。</p><br /> <p><p><a href="http://aikelab.net/circle" class="hatena-fotolife" target="_blank"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20150729/20150729005305.png" alt="circles" title="circles" class="hatena-fotolife"></a></p><a href="http://aikelab.net/circle">http://aikelab.net/circle</a></p><p> </p><p>&#9642;文字</p> <pre class="code lang-html" data-lang="html" data-unlink><span class="synIdentifier">&lt;</span><span class="synStatement">div</span><span class="synIdentifier"> </span><span class="synType">id</span><span class="synIdentifier">=</span><span class="synConstant">&quot;mychar&quot;</span><span class="synIdentifier">&gt;</span>●<span class="synIdentifier">&lt;/</span><span class="synStatement">div</span><span class="synIdentifier">&gt;</span> </pre><pre class="code lang-css" data-lang="css" data-unlink><span class="synIdentifier">#mychar</span> <span class="synIdentifier">{</span> <span class="synType">color</span>: <span class="synConstant">#00f</span>; <span class="synType">font-size</span>: <span class="synConstant">120px</span>; <span class="synIdentifier">}</span> </pre><p> </p><p>&#9642;<a class="keyword" href="http://d.hatena.ne.jp/keyword/CSS">CSS</a></p> <pre class="code lang-html" data-lang="html" data-unlink> <span class="synIdentifier">&lt;</span><span class="synStatement">div</span><span class="synIdentifier"> </span><span class="synType">id</span><span class="synIdentifier">=</span><span class="synConstant">&quot;mydiv&quot;</span><span class="synIdentifier">&gt;&lt;/</span><span class="synStatement">div</span><span class="synIdentifier">&gt;</span> </pre><pre class="code lang-css" data-lang="css" data-unlink><span class="synIdentifier">#mydiv</span> <span class="synIdentifier">{</span> <span class="synType">width</span>: <span class="synConstant">100px</span>; <span class="synType">height</span>: <span class="synConstant">100px</span>; <span class="synType">margin-left</span>: <span class="synConstant">auto</span>; <span class="synType">margin-right</span>: <span class="synConstant">auto</span>; <span class="synComment">-webkit-</span><span class="synType">border-radius</span>: <span class="synConstant">50px</span>; <span class="synComment">-moz-</span><span class="synType">border-radius</span>: <span class="synConstant">50px</span>; <span class="synType">border-radius</span>: <span class="synConstant">50px</span>; <span class="synType">background-color</span>: <span class="synConstant">#00f</span>; <span class="synIdentifier">}</span> </pre><p> </p><p>&#9642;<a class="keyword" href="http://d.hatena.ne.jp/keyword/Canvas">Canvas</a></p> <pre class="code lang-html" data-lang="html" data-unlink> <span class="synIdentifier">&lt;</span>canvas<span class="synIdentifier"> </span><span class="synType">id</span><span class="synIdentifier">=</span><span class="synConstant">&quot;mycanvas&quot;</span><span class="synIdentifier"> </span><span class="synType">width</span><span class="synIdentifier">=</span><span class="synConstant">&quot;110&quot;</span><span class="synIdentifier"> </span><span class="synType">height</span><span class="synIdentifier">=</span><span class="synConstant">&quot;110&quot;</span><span class="synIdentifier">&gt;&lt;/</span>canvas<span class="synIdentifier">&gt;</span> </pre><pre class="code lang-javascript" data-lang="javascript" data-unlink> <span class="synIdentifier">var</span> canvas = <span class="synStatement">document</span>.querySelector(<span class="synConstant">'#mycanvas'</span>); <span class="synIdentifier">var</span> ctx = canvas.getContext(<span class="synConstant">'2d'</span>); ctx.fillStyle = <span class="synConstant">'#00f'</span>; ctx.beginPath(); ctx.arc(60, 60, 50, 0, Math.PI * 2, <span class="synConstant">true</span>); ctx.fill(); </pre><p> </p><p>&#9642;<a class="keyword" href="http://d.hatena.ne.jp/keyword/SVG">SVG</a></p> <pre class="code lang-html" data-lang="html" data-unlink> <span class="synIdentifier">&lt;</span>svg<span class="synIdentifier"> </span><span class="synType">width</span><span class="synIdentifier">=</span><span class="synConstant">&quot;110&quot;</span><span class="synIdentifier"> </span><span class="synType">height</span><span class="synIdentifier">=</span><span class="synConstant">&quot;110&quot;</span> <span class="synIdentifier"> xmlns=</span><span class="synConstant">&quot;http://www.w3.org/2000/svg&quot;</span> <span class="synIdentifier"> xmlns:xlink=</span><span class="synConstant">&quot;http://www.w3.org/1999/xlink&quot;</span><span class="synIdentifier">&gt;</span> <span class="synIdentifier">&lt;</span>circle<span class="synIdentifier"> cx=</span><span class="synConstant">&quot;50&quot;</span><span class="synIdentifier"> cy=</span><span class="synConstant">&quot;60&quot;</span><span class="synIdentifier"> r=</span><span class="synConstant">&quot;50&quot;</span><span class="synIdentifier"> fill=</span><span class="synConstant">&quot;blue&quot;</span><span class="synIdentifier"> /&gt;</span> <span class="synIdentifier">&lt;/</span>svg<span class="synIdentifier">&gt;</span> </pre><p> </p><p>&#9642;<a class="keyword" href="http://d.hatena.ne.jp/keyword/WebGL">WebGL</a>(Three.js)</p> <pre class="code lang-html" data-lang="html" data-unlink> <span class="synIdentifier">&lt;</span><span class="synStatement">script</span><span class="synIdentifier"> </span><span class="synType">src</span><span class="synIdentifier">=</span><span class="synConstant">&quot;https://cdnjs.cloudflare.com/ajax/libs/three.js/r71/three.min.js&quot;</span><span class="synIdentifier">&gt;&lt;/</span><span class="synStatement">script</span><span class="synIdentifier">&gt;</span> <span class="synIdentifier">&lt;</span><span class="synStatement">div</span><span class="synIdentifier"> </span><span class="synType">id</span><span class="synIdentifier">=</span><span class="synConstant">&quot;mywebgl&quot;</span><span class="synIdentifier">&gt;&lt;/</span><span class="synStatement">div</span><span class="synIdentifier">&gt;</span> </pre><pre class="code lang-javascript" data-lang="javascript" data-unlink> <span class="synComment">// シーンを作成</span> <span class="synIdentifier">var</span> scene = <span class="synStatement">new</span> THREE.Scene(); <span class="synComment">// サークルオブジェクトを作成</span> <span class="synIdentifier">var</span> material = <span class="synStatement">new</span> THREE.MeshBasicMaterial(<span class="synIdentifier">{</span>color:<span class="synConstant">&quot;#0000FF&quot;</span><span class="synIdentifier">}</span>); <span class="synIdentifier">var</span> geometry = <span class="synStatement">new</span> THREE.CircleGeometry(0.5, 32); <span class="synIdentifier">var</span> mesh = <span class="synStatement">new</span> THREE.Mesh(geometry, material); scene.add(mesh); <span class="synComment">//カメラを作成</span> <span class="synIdentifier">var</span> camera = <span class="synStatement">new</span> THREE.PerspectiveCamera(45, 1, 1, 100); camera.position.set(0, 0.05, 1.4); <span class="synIdentifier">var</span> renderer = <span class="synStatement">new</span> THREE.WebGLRenderer(); <span class="synComment">// レンダラを作成</span> renderer.setSize(110, 110); renderer.setClearColor(<span class="synConstant">&quot;#fff&quot;</span>, 1); <span class="synStatement">document</span>.querySelector(<span class="synConstant">'#mywebgl'</span>).appendChild(renderer.domElement); renderer.render(scene, camera); </pre> aike 超簡単に3DCGできるJavaScriptライブラリ作った hatenablog://entry/10257846132645780860 2015-01-30T00:00:00+09:00 2015-01-30T00:00:00+09:00 ブラウザでWebGLが使えるようになって3DCGプログラミングはずいぶん身近なものになりました。と書いてるそばから違和感を感じるくらい生のWebGLをJavaScriptで書くのは敷居が高かったりします。できなくはないけど前提となる知識がかなり必要な感じ。 three.jsが登場したときは、これで普通に3DCGができるということで一気にひろまりました。とはいえ、それでもまだやることは多く、画面に四角い箱を表示する場合以下のようなプログラムを書くことになります。 ・シーンを作成 ・ライトを作成、位置と向きを設定、シーンに追加 ・カメラを作成、位置と向きを設定、シーンに追加 ・マテリアルを作成、色… <p>ブラウザで<a class="keyword" href="http://d.hatena.ne.jp/keyword/WebGL">WebGL</a>が使えるようになって3DCGプログラミングはずいぶん身近なものになりました。と書いてるそばから違和感を感じるくらい生の<a class="keyword" href="http://d.hatena.ne.jp/keyword/WebGL">WebGL</a>を<a class="keyword" href="http://d.hatena.ne.jp/keyword/JavaScript">JavaScript</a>で書くのは敷居が高かったりします。できなくはないけど前提となる知識がかなり必要な感じ。<br />  <br /> <a href="http://threejs.org/">three.js</a>が登場したときは、これで普通に3DCGができるということで一気にひろまりました。とはいえ、それでもまだやることは多く、画面に四角い箱を表示する場合以下のようなプログラムを書くことになります。<br />  ・シーンを作成<br />  ・ライトを作成、位置と向きを設定、シーンに追加<br />  ・カメラを作成、位置と向きを設定、シーンに追加<br />  ・マテリアルを作成、色を指定<br />  ・BoxGeometryを作成、サイズを指定<br />  ・メッシュを作成、位置と向きを設定、シーンに追加<br />  ・レンダラーを作成<br />  ・<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EC%A5%F3%A5%C0%A5%EA%A5%F3%A5%B0">レンダリング</a>ループ処理<br /> これらのひとつでも間違えたりパラメーターが適切でないと箱は表示されません。<br />  <br /> そんなわけで、超簡単に3DCGが描けるthree.jsのラッパーライブラリを作成しました。<br /> <span class="deco" style="font-size:large;"><a href="http://aikelab.net/threepiece/">http://aikelab.net/threepiece/</a></span><br /> <span class="deco" style="font-size:large;"><a href="https://github.com/aike/ThreePiece.js">https://github.com/aike/ThreePiece.js</a></span><br />  <br /> ■ボックスを表示</p> <pre class="code lang-javascript" data-lang="javascript" data-unlink><span class="synIdentifier">var</span> t = <span class="synStatement">new</span> ThreePiece(); t.eval(<span class="synIdentifier">{</span>obj:<span class="synConstant">&quot;box&quot;</span><span class="synIdentifier">}</span>); </pre><p><span itemscope itemtype="http://schema.org/Photograph"><a href="http://f.hatena.ne.jp/aike/20150130081009" class="hatena-fotolife" itemprop="url"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20150130/20150130081009.png" alt="f:id:aike:20150130081009p:image" title="f:id:aike:20150130081009p:image" class="hatena-fotolife" itemprop="image"></a></span><br /> このライブラリの基本的な方針としては、ライトもカメラもデフォルト値を持っていて、何も指定しないとデフォルト値が使われるというものです。オブジェクトを生成すると画面の見やすい位置に見やすい色、見やすい大きさで表示されます。DOMツリー上の位置も、divのIDを指定したらdivの下に生成し、省略するとbodyの直下に生成します。<br />  <br /> ■複数オブジェクトの表示<br /> オブジェクトを追加したり、グリッドを描いたりはこんな感じ。</p> <pre class="code lang-javascript" data-lang="javascript" data-unlink><span class="synIdentifier">var</span> t = <span class="synStatement">new</span> ThreePiece(); t.eval(<span class="synIdentifier">[</span> <span class="synIdentifier">{</span>obj:<span class="synConstant">&quot;grid&quot;</span><span class="synIdentifier">}</span>, <span class="synIdentifier">{</span>obj:<span class="synConstant">&quot;box&quot;</span>, x:-1, col:0xffff00<span class="synIdentifier">}</span>, <span class="synIdentifier">{</span>obj:<span class="synConstant">&quot;sphere&quot;</span>, x:1, col:0x0000ff<span class="synIdentifier">}</span> <span class="synIdentifier">]</span>); </pre><p><span itemscope itemtype="http://schema.org/Photograph"><a href="http://f.hatena.ne.jp/aike/20150130081219" class="hatena-fotolife" itemprop="url"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20150130/20150130081219.png" alt="f:id:aike:20150130081219p:image" title="f:id:aike:20150130081219p:image" class="hatena-fotolife" itemprop="image"></a></span><br />  <br /> ■視点の回転<br /> 3DCGは、一方向から見ただけでは、各オブジェクトの位置関係がわかりづらく、またカメラの後ろ側にオブジェクトが生成されていたりということがあったりします。そういうときのパラメーター調整に便利な、視点を回転するrotate()命令を用意しました。</p> <pre class="code lang-javascript" data-lang="javascript" data-unlink><span class="synIdentifier">var</span> t = <span class="synStatement">new</span> ThreePiece(); t.eval(<span class="synIdentifier">[</span> <span class="synIdentifier">{</span>obj:<span class="synConstant">&quot;ground&quot;</span><span class="synIdentifier">}</span>, <span class="synIdentifier">{</span>obj:<span class="synConstant">&quot;box&quot;</span>, x:-2, scale:2<span class="synIdentifier">}</span>, <span class="synIdentifier">{</span>obj:<span class="synConstant">&quot;cylinder&quot;</span>, x:2, scale:2, col:0x0000FF<span class="synIdentifier">}</span>, <span class="synIdentifier">]</span>); t.rotate(); </pre><p><span itemscope itemtype="http://schema.org/Photograph"><a href="http://f.hatena.ne.jp/aike/20150130081220" class="hatena-fotolife" itemprop="url"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20150130/20150130081220.gif" alt="f:id:aike:20150130081220g:image" title="f:id:aike:20150130081220g:image" class="hatena-fotolife" itemprop="image"></a></span><br />  <br /> ■モデルに名前をつけて操作<br /> モデルに名前をつけて、後から名前で検索して操作することもできます。<br /> また、addHook()を使うことで、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EC%A5%F3%A5%C0%A5%EA%A5%F3%A5%B0">レンダリング</a>ループに独自の処理を追加できます。</p> <pre class="code lang-javascript" data-lang="javascript" data-unlink><span class="synIdentifier">var</span> t = <span class="synStatement">new</span> ThreePiece(); t.eval(<span class="synIdentifier">[</span> <span class="synIdentifier">{</span>obj:<span class="synConstant">&quot;grid&quot;</span><span class="synIdentifier">}</span>, <span class="synIdentifier">{</span>obj:<span class="synConstant">&quot;box&quot;</span>, name:<span class="synConstant">&quot;myobj&quot;</span><span class="synIdentifier">}</span> <span class="synIdentifier">]</span>); t.addHook(<span class="synIdentifier">function</span>(msec) <span class="synIdentifier">{</span> t.obj(<span class="synConstant">&quot;myobj&quot;</span>).position.x = Math.sin(msec / 1000) * 4; <span class="synIdentifier">}</span>); </pre><p><span itemscope itemtype="http://schema.org/Photograph"><a href="http://f.hatena.ne.jp/aike/20150130081641" class="hatena-fotolife" itemprop="url"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20150130/20150130081641.gif" alt="f:id:aike:20150130081641g:image" title="f:id:aike:20150130081641g:image" class="hatena-fotolife" itemprop="image"></a></span><br />  <br /> ■グループ化<br /> モデルが複雑になってくると、複数のモデルをグループ化したり、オブジェクトに変化があったときのみ再描画したり(いわゆるダーティーフラグ)といった機能がほしくなります。</p> <pre class="code lang-javascript" data-lang="javascript" data-unlink><span class="synIdentifier">var</span> t = <span class="synStatement">new</span> ThreePiece(); t.define(<span class="synConstant">&quot;face&quot;</span>, <span class="synIdentifier">{</span>obj:<span class="synConstant">&quot;group&quot;</span>, z:2, data:<span class="synIdentifier">[</span> <span class="synIdentifier">{</span>obj:<span class="synConstant">&quot;box&quot;</span>, col:0xEEEEEE<span class="synIdentifier">}</span>, <span class="synIdentifier">{</span>obj:<span class="synConstant">&quot;circle&quot;</span>, w:0.1, z:0.51, x:-0.2, y:0.2, col:0x222222<span class="synIdentifier">}</span>, <span class="synIdentifier">{</span>obj:<span class="synConstant">&quot;circle&quot;</span>, w:0.1, z:0.51, x: 0.2, y:0.2, col:0x222222<span class="synIdentifier">}</span>, <span class="synIdentifier">{</span>obj:<span class="synConstant">&quot;plane&quot;</span>, w:0.6, h:0.2, z:0.51, y:-0.2, col:0xAA2222<span class="synIdentifier">}</span> <span class="synIdentifier">]}</span>); <span class="synIdentifier">var</span> data = <span class="synIdentifier">[</span> <span class="synIdentifier">{</span>obj:<span class="synConstant">&quot;grid&quot;</span><span class="synIdentifier">}</span>, <span class="synIdentifier">{</span>obj:<span class="synConstant">&quot;face&quot;</span>, x:-3, y:0<span class="synIdentifier">}</span>, <span class="synIdentifier">{</span>obj:<span class="synConstant">&quot;face&quot;</span>, x: 0, y:0, name:<span class="synConstant">&quot;centerface&quot;</span><span class="synIdentifier">}</span>, <span class="synIdentifier">{</span>obj:<span class="synConstant">&quot;face&quot;</span>, x: 3, y:0<span class="synIdentifier">}</span> <span class="synIdentifier">]</span>; t.useDirtyFlag(); t.eval(data); <span class="synIdentifier">var</span> pos = 1; setInterval(<span class="synIdentifier">function</span>() <span class="synIdentifier">{</span> pos = 1 - pos; t.obj(<span class="synConstant">&quot;centerface&quot;</span>).position.y = pos; t.setDirty(); <span class="synIdentifier">}</span>, 500); </pre><p><span itemscope itemtype="http://schema.org/Photograph"><a href="http://f.hatena.ne.jp/aike/20150130081642" class="hatena-fotolife" itemprop="url"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20150130/20150130081642.gif" alt="f:id:aike:20150130081642g:image" title="f:id:aike:20150130081642g:image" class="hatena-fotolife" itemprop="image"></a></span><br />  <br /> ■応用例<br /> がんばればこんなこともできます。<br /> <span itemscope itemtype="http://schema.org/Photograph"><a href="http://f.hatena.ne.jp/aike/20150125064655" class="hatena-fotolife" itemprop="url"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20150125/20150125064655.png" alt="f:id:aike:20150125064655p:image" title="f:id:aike:20150125064655p:image" class="hatena-fotolife" itemprop="image"></a></span><br /> <a href="http://aikelab.net/websynthv2/">http://aikelab.net/websynthv2/</a><br />  <br /> Enjoy!<br />  </p><p><div class="hatena-asin-detail"><br /> <a href="http://www.amazon.co.jp/dp/4877833242/?tag=lifehacklife-22&ascsubtag=d-11lyr"><img src="http://ecx.images-amazon.com/images/I/51mA1hBNiFL._SL160_.jpg" class="hatena-asin-detail-image" alt="three.jsによるHTML5 3Dグラフィックス〈上〉―ブラウザで実現するOpenGL(WebGL)の世界" title="three.jsによるHTML5 3Dグラフィックス〈上〉―ブラウザで実現するOpenGL(WebGL)の世界"></a><br /> <div class="hatena-asin-detail-info"><br /> <p class="hatena-asin-detail-title"><a href="http://www.amazon.co.jp/dp/4877833242/?tag=lifehacklife-22&ascsubtag=d-11lyr">three.jsによるHTML5 3Dグラフィックス〈上〉―ブラウザで実現するOpenGL(WebGL)の世界</a></p> <ul> <li><span class="hatena-asin-detail-label">作者:</span> <a href="http://d.hatena.ne.jp/keyword/%B1%F3%C6%A3%CD%FD%CA%BF" class="keyword">遠藤理平</a></li> <li><span class="hatena-asin-detail-label">出版社/メーカー:</span> <a href="http://d.hatena.ne.jp/keyword/%A5%AB%A5%C3%A5%C8%A5%B7%A5%B9%A5%C6%A5%E0" class="keyword">カットシステム</a></li> <li><span class="hatena-asin-detail-label">発売日:</span> 2013/09/01</li> <li><span class="hatena-asin-detail-label">メディア:</span> 単行本</li> <li><a href="http://d.hatena.ne.jp/asin/4877833242" target="_blank">この商品を含むブログを見る</a></li> </ul> </div> <div class="hatena-asin-detail-foot"></div></div></p><p><div class="hatena-asin-detail"><br /> <a href="http://www.amazon.co.jp/dp/B00R2QYPB0/?tag=lifehacklife-22&ascsubtag=d-11lyr"><img src="http://ecx.images-amazon.com/images/I/51pdczOaBQL._SL160_.jpg" class="hatena-asin-detail-image" alt="MOOG モーグ / Minimoog Voyager Select Series Blue/Quarter Sawn" title="MOOG モーグ / Minimoog Voyager Select Series Blue/Quarter Sawn"></a><br /> <div class="hatena-asin-detail-info"><br /> <p class="hatena-asin-detail-title"><a href="http://www.amazon.co.jp/dp/B00R2QYPB0/?tag=lifehacklife-22&ascsubtag=d-11lyr">MOOG モーグ / Minimoog Voyager Select Series Blue/Quarter Sawn</a></p> <ul> <li><span class="hatena-asin-detail-label">出版社/メーカー:</span> <a href="http://d.hatena.ne.jp/keyword/moog" class="keyword">moog</a></li> <li><span class="hatena-asin-detail-label">メディア:</span> </li> <li><a href="http://d.hatena.ne.jp/asin/B00R2QYPB0" target="_blank">この商品を含むブログを見る</a></li> </ul> </div> <div class="hatena-asin-detail-foot"></div></div></p> aike WebGLでかっちょいいシンセできたよー hatenablog://entry/10257846132645780890 2015-01-25T00:00:00+09:00 2015-01-25T00:00:00+09:00 ちょうど3年前に当時出始めのWeb Audio APIを使ってウェブブラウザで動くシンセを作りました。その後ブラウザのAPIもいろいろと進化したので、それに合わせてバージョンアップをしてみました。 http://aikelab.net/websynthv2/ https://github.com/aike/webaudiosynthv2 ■新バージョンの特徴 ・WebGL(three.js、ThreePiece.js)を使った3Dグラフィック ・Web Audio APIに追加されたオシレーターノードを使用してエイリアスノイズを排除 ・Web Audio APIのオートメーション機能によるシン… <p>ちょうど3年前に当時出始めのWeb Audio <a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>を使って<a href="http://d.hatena.ne.jp/aike/20120129">&#x30A6;&#x30A7;&#x30D6;&#x30D6;&#x30E9;&#x30A6;&#x30B6;&#x3067;&#x52D5;&#x304F;&#x30B7;&#x30F3;&#x30BB;</a>を作りました。その後ブラウザの<a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>もいろいろと進化したので、それに合わせてバージョンアップをしてみました。<br />  <br /> <span itemscope itemtype="http://schema.org/Photograph"><a href="http://f.hatena.ne.jp/aike/20150125064655" class="hatena-fotolife" itemprop="url"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20150125/20150125064655.png" alt="f:id:aike:20150125064655p:image" title="f:id:aike:20150125064655p:image" class="hatena-fotolife" itemprop="image"></a></span><br />  <br /> <span class="deco" style="font-size:large;"><a href="http://aikelab.net/websynthv2/">http://aikelab.net/websynthv2/</a></span><br /> <span class="deco" style="font-size:large;"><a href="https://github.com/aike/webaudiosynthv2">https://github.com/aike/webaudiosynthv2</a></span><br />  <br /> ■新バージョンの特徴<br /> ・<a class="keyword" href="http://d.hatena.ne.jp/keyword/WebGL">WebGL</a>(<a href="https://github.com/mrdoob/three.js/">three.js</a>、<a href="https://github.com/aike/ThreePiece.js">ThreePiece.js</a>)を使った3Dグラフィック<br /> ・Web Audio <a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>に追加された<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AA%A5%B7%A5%EC%A1%BC%A5%BF%A1%BC">オシレーター</a>ノードを使用して<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A8%A5%A4%A5%EA%A5%A2%A5%B9">エイリアス</a>ノイズを排除<br /> ・Web Audio <a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>のオートメーション機能によるシンプルなGLIDEの実装<br /> ・Web <a class="keyword" href="http://d.hatena.ne.jp/keyword/MIDI">MIDI</a> <a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>で<a class="keyword" href="http://d.hatena.ne.jp/keyword/MIDI">MIDI</a>キーボードから演奏可能<br /> ・<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%B9%A5%AD%A1%BC">アスキー</a>キーボードによる演奏<br /> ・デモ曲のロングバージョン<br />  <br /> ■実行環境<br /> ・最新版の<a class="keyword" href="http://d.hatena.ne.jp/keyword/Chrome">Chrome</a>が推奨環境です<br /> ・<a class="keyword" href="http://d.hatena.ne.jp/keyword/Safari">Safari</a>でも動きますが少し重いかもしれません<br /> ・<a class="keyword" href="http://d.hatena.ne.jp/keyword/Firefox">Firefox</a>はWeb Audio <a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>のオートメーションが未実装のようでGLIDEが効きません<br /> ・ん、<a class="keyword" href="http://d.hatena.ne.jp/keyword/IE">IE</a>?なにそれ<br />  <br /> ■その他<br /> <a class="keyword" href="http://d.hatena.ne.jp/keyword/DTM">DTM</a>ソフトウェアの<a class="keyword" href="http://d.hatena.ne.jp/keyword/GUI">GUI</a>は、これまでのような擬似3Dのものから、3DCGソフトで描いたリアルなものが少しずつ増えてきたようです。いまは事前に<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EC%A5%F3%A5%C0%A5%EA%A5%F3%A5%B0">レンダリング</a>した画像を使っているようですが、いずれリアルタイム<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EC%A5%F3%A5%C0%A5%EA%A5%F3%A5%B0">レンダリング</a>の3D <a class="keyword" href="http://d.hatena.ne.jp/keyword/GUI">GUI</a>を使うようになると予想しています。<br />  <br /> そんなわけで、実験的にリアルタイム<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EC%A5%F3%A5%C0%A5%EA%A5%F3%A5%B0">レンダリング</a>の3DCGで<a class="keyword" href="http://d.hatena.ne.jp/keyword/GUI">GUI</a>を実装してみました。まだいろいろもっさりしていて使いにくさはあるものの、簡単に拡大縮小できたり、マウスオーバー時のエフェクトなど2Dにはない面白さも感じられると思います。<br />  </p><p><div class="hatena-asin-detail"><br /> <a href="http://www.amazon.co.jp/dp/4877833242/?tag=lifehacklife-22&ascsubtag=d-11lyr"><img src="http://ecx.images-amazon.com/images/I/51mA1hBNiFL._SL160_.jpg" class="hatena-asin-detail-image" alt="three.jsによるHTML5 3Dグラフィックス〈上〉―ブラウザで実現するOpenGL(WebGL)の世界" title="three.jsによるHTML5 3Dグラフィックス〈上〉―ブラウザで実現するOpenGL(WebGL)の世界"></a><br /> <div class="hatena-asin-detail-info"><br /> <p class="hatena-asin-detail-title"><a href="http://www.amazon.co.jp/dp/4877833242/?tag=lifehacklife-22&ascsubtag=d-11lyr">three.jsによるHTML5 3Dグラフィックス〈上〉―ブラウザで実現するOpenGL(WebGL)の世界</a></p> <ul> <li><span class="hatena-asin-detail-label">作者:</span> <a href="http://d.hatena.ne.jp/keyword/%B1%F3%C6%A3%CD%FD%CA%BF" class="keyword">遠藤理平</a></li> <li><span class="hatena-asin-detail-label">出版社/メーカー:</span> <a href="http://d.hatena.ne.jp/keyword/%A5%AB%A5%C3%A5%C8%A5%B7%A5%B9%A5%C6%A5%E0" class="keyword">カットシステム</a></li> <li><span class="hatena-asin-detail-label">発売日:</span> 2013/09/01</li> <li><span class="hatena-asin-detail-label">メディア:</span> 単行本</li> <li><a href="http://d.hatena.ne.jp/asin/4877833242" target="_blank">この商品を含むブログを見る</a></li> </ul> </div> <div class="hatena-asin-detail-foot"></div></div></p><p><div class="hatena-asin-detail"><br /> <a href="http://www.amazon.co.jp/dp/B00R2QYPB0/?tag=lifehacklife-22&ascsubtag=d-11lyr"><img src="http://ecx.images-amazon.com/images/I/51pdczOaBQL._SL160_.jpg" class="hatena-asin-detail-image" alt="MOOG モーグ / Minimoog Voyager Select Series Blue/Quarter Sawn" title="MOOG モーグ / Minimoog Voyager Select Series Blue/Quarter Sawn"></a><br /> <div class="hatena-asin-detail-info"><br /> <p class="hatena-asin-detail-title"><a href="http://www.amazon.co.jp/dp/B00R2QYPB0/?tag=lifehacklife-22&ascsubtag=d-11lyr">MOOG モーグ / Minimoog Voyager Select Series Blue/Quarter Sawn</a></p> <ul> <li><span class="hatena-asin-detail-label">出版社/メーカー:</span> <a href="http://d.hatena.ne.jp/keyword/moog" class="keyword">moog</a></li> <li><span class="hatena-asin-detail-label">メディア:</span> </li> <li><a href="http://d.hatena.ne.jp/asin/B00R2QYPB0" target="_blank">この商品を含むブログを見る</a></li> </ul> </div> <div class="hatena-asin-detail-foot"></div></div></p> aike iPhoneでワウペダルを作ったった hatenablog://entry/10257846132645780907 2014-11-03T00:00:00+09:00 2014-11-03T00:00:00+09:00 ワウペダルが好きです。ギターのカッティングにかけて遊んでいるとあっというまに時間が過ぎていきます。そんなわけでどこのご家庭にもあるiPhoneとJavaScriptでワウペダルを作ることにしました。こんなやつ。 JavaScriptでiPhoneの加速度センサーとWeb Audio APIを使ったワウペダル作った。 http://t.co/rGDHh5FaWb https://t.co/erfjy9tL80— aike (@aike1000) 2014, 10月 20 ■作り方 まず、Web Audio APIでフィルターを作ります。 Biquad Filterを作ってバンドパスフィルターに設… <p>ワウペダルが好きです。ギターのカッティングにかけて遊んでいるとあっというまに時間が過ぎていきます。そんなわけでどこのご家庭にもある<a class="keyword" href="http://d.hatena.ne.jp/keyword/iPhone">iPhone</a>と<a class="keyword" href="http://d.hatena.ne.jp/keyword/JavaScript">JavaScript</a>でワウペダルを作ることにしました。こんなやつ。<br />  <blockquote class="twitter-tweet" lang="ja"><p><a class="keyword" href="http://d.hatena.ne.jp/keyword/JavaScript">JavaScript</a>で<a class="keyword" href="http://d.hatena.ne.jp/keyword/iPhone">iPhone</a>の加速度センサーとWeb Audio <a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>を使ったワウペダル作った。 <a href="http://t.co/rGDHh5FaWb">http://t.co/rGDHh5FaWb</a> <a href="https://t.co/erfjy9tL80">https://t.co/erfjy9tL80</a></p>&mdash; aike (@aike1000) <a href="https://twitter.com/aike1000/status/524037689692000256">2014, 10月 20</a></blockquote><script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script><br />  <br /> ■作り方<br /> まず、Web Audio <a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>でフィルターを作ります。<br /> Biquad Filterを作ってバンドパスフィルターに設定するだけです。簡単。Qの値を少し大きめの4くらいにしておくとワウらしいクセが出ます。あとは0.0&#12316;1.0の引数の値に応じてフィルターの中心周波数をセットする関数setWahPos()を用意しておきます。これが、ペダルの角度が変わったときに呼ばれます。<br />  </p> <pre class="code lang-javascript" data-lang="javascript" data-unlink><span class="synIdentifier">var</span> ctx = <span class="synStatement">new</span> AudioContext(); <span class="synIdentifier">var</span> wah = ctx.createBiquadFilter(); wah.type = <span class="synConstant">&quot;bandpass&quot;</span>; wah.Q.value = 4; wah.connect(ctx.destination); <span class="synIdentifier">var</span> setWahPos = <span class="synIdentifier">function</span>(pos) <span class="synIdentifier">{</span> wah.frequency.value = 400 + 3000 * pos; <span class="synIdentifier">}</span> setWahPos(1.0); </pre><p> <br /> 次に<a class="keyword" href="http://d.hatena.ne.jp/keyword/iPhone">iPhone</a>の加速度センサーで角度を検知する処理を書きます。<br /> deviceorientationのイベントリスナーを用意すると<a class="keyword" href="http://d.hatena.ne.jp/keyword/iPhone">iPhone</a>の角度変化イベントを受け取ります。角度情報はalpha、beta、gammaの3方向あり、ペダルとして使用する前後の傾き情報はbetaが対応します。検知した角度を0.0&#12316;1.0の範囲に正規化して指定されたコールバック関数を呼ぶ処理はこんな感じ。<br />  </p> <pre class="code lang-javascript" data-lang="javascript" data-unlink><span class="synIdentifier">var</span> Pedaler = <span class="synIdentifier">function</span>(callback) <span class="synIdentifier">{</span> <span class="synIdentifier">var</span> <span class="synStatement">self</span> = <span class="synIdentifier">this</span>; <span class="synStatement">window</span>.addEventListener(<span class="synConstant">&quot;deviceorientation&quot;</span>, <span class="synIdentifier">function</span>(e)<span class="synIdentifier">{</span> <span class="synStatement">if</span> (e.alpha) <span class="synIdentifier">{</span> <span class="synStatement">self</span>.setAngle(e.alpha, e.beta, e.gamma); <span class="synIdentifier">}</span> <span class="synIdentifier">}</span>); <span class="synIdentifier">this</span>.angle = 0; <span class="synIdentifier">this</span>.callback = callback; <span class="synIdentifier">}</span> Pedaler.prototype.setAngle = <span class="synIdentifier">function</span>(alpha, beta, gamma) <span class="synIdentifier">{</span> <span class="synIdentifier">var</span> angle = (beta + 20) / 40; <span class="synStatement">if</span> (angle &lt; 0.0) angle = 0.0; <span class="synStatement">else</span> <span class="synStatement">if</span> (angle &gt; 1.0) angle = 1.0; <span class="synIdentifier">this</span>.angle = angle; <span class="synStatement">if</span> (<span class="synIdentifier">this</span>.callback) <span class="synIdentifier">this</span>.callback(<span class="synIdentifier">this</span>.angle); <span class="synIdentifier">}</span> </pre><p> <br /> 上記のPedalerオブジェクトを生成して、コールバック関数でワウのsetWahPos()を指定することで角度と音色を連動させます。<br />  </p> <pre class="code lang-javascript" data-lang="javascript" data-unlink>$(<span class="synIdentifier">function</span>() <span class="synIdentifier">{</span> <span class="synIdentifier">var</span> pedaler = <span class="synStatement">new</span> Pedaler(<span class="synIdentifier">function</span>(a) <span class="synIdentifier">{</span> setWahPos(a); <span class="synIdentifier">}</span>); <span class="synIdentifier">}</span>) </pre><p> <br /> あとはUIと音源処理を書けば完成です。音源は本当はギターを<a class="keyword" href="http://d.hatena.ne.jp/keyword/iPhone">iPhone</a>につないで鳴らしたいところですが、WebRTCがまだ<a class="keyword" href="http://d.hatena.ne.jp/keyword/iOS">iOS</a>のブラウザでは使えないのでサンプリング音源をループで鳴らすことにしています。<br />  <br /> iPhoneWah <a href="http://aikelab.net/iphonewah/">http://aikelab.net/iphonewah/</a><br /> <a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%BD%A1%BC%A5%B9%A5%B3%A1%BC%A5%C9">ソースコード</a> <a href="http://github.com/aike/iphonewah/">http://github.com/aike/iphonewah/</a><br />  <br /> Pedalerはワウに限らず汎用的なペダルとして使えるように書いてあるので、ア<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%C7%A5%A2">イデア</a>と<a class="keyword" href="http://d.hatena.ne.jp/keyword/iPhone">iPhone</a>を踏み壊す勇気があればいろいろ応用が考えられると思います。</p> aike RICOH THETAとJavaScriptでハコスコ用コンテンツを作るの巻 hatenablog://entry/10257846132645780927 2014-09-30T00:00:00+09:00 2014-09-30T00:00:00+09:00 ハコスコは、iPhoneさえあればわずか1000円で実現できてしまうヘッドマウントディスプレイです。ただまだ視聴できるコンテンツがそれほど多くありません。 そんなわけで今回はRICOH THETAを使ってハコスコ用のコンテンツを自作してしまおうという企画です。 THETA用オレオレビューアライブラリthview.jsを最近アップデートしました。iPhoneの加速度センサーの情報を見て傾きに合わせて全天球画像を表示します。HTMLとJavaScriptだけなので、本格的な開発環境は不要でテキストエディタとウェブサーバだけあれば誰でも作れます。 ※WebGLの関係上、iOSのバージョンは8にする必… <p><a href="http://hacosco.com/">&#x30CF;&#x30B3;&#x30B9;&#x30B3;</a>は、<a class="keyword" href="http://d.hatena.ne.jp/keyword/iPhone">iPhone</a>さえあればわずか1000円で実現できてしまうヘッドマウントディスプレイです。ただまだ視聴できるコンテンツがそれほど多くありません。<br />  <br /> そんなわけで今回は<a href="http://theta360.com/">RICOH THETA</a>を使ってハコスコ用のコンテンツを自作してしまおうという企画です。<br />  <br /> <span itemscope itemtype="http://schema.org/Photograph"><a href="http://f.hatena.ne.jp/aike/20140930213820" class="hatena-fotolife" itemprop="url"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20140930/20140930213820.jpg" alt="f:id:aike:20140930213820j:image" title="f:id:aike:20140930213820j:image" class="hatena-fotolife" itemprop="image"></a></span><br />  <br /> THETA用オレオレビューアライブラリ<a href="https://github.com/aike/thview.js">thview.js</a>を最近アップデートしました。<a class="keyword" href="http://d.hatena.ne.jp/keyword/iPhone">iPhone</a>の加速度センサーの情報を見て傾きに合わせて全天球画像を表示します。HTMLと<a class="keyword" href="http://d.hatena.ne.jp/keyword/JavaScript">JavaScript</a>だけなので、本格的な開発環境は不要で<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C6%A5%AD%A5%B9%A5%C8%A5%A8%A5%C7%A5%A3%A5%BF">テキストエディタ</a>とウェブサーバだけあれば誰でも作れます。<br /> <span class="deco" style="font-size:small;">※<a class="keyword" href="http://d.hatena.ne.jp/keyword/WebGL">WebGL</a>の関係上、<a class="keyword" href="http://d.hatena.ne.jp/keyword/iOS">iOS</a>のバージョンは8にする必要があります。</span><br />  <br /> <a href="http://aikelab.net/thview/hmd3.html">&#x30C7;&#x30E2;1 &#x6238;&#x68DA;&#x306E;&#x4E2D;</a><br /> <p><a href="http://aikelab.net/thview/hmd3.html" class="hatena-fotolife" target="_blank"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20140930/20140930214741.png" alt="f:id:aike:20140930214741p:image" title="f:id:aike:20140930214741p:image" class="hatena-fotolife"></a></p> <br /> HTML的にはこんな感じです。</p> <pre class="code lang-html" data-lang="html" data-unlink><span class="synComment">&lt;!DOCTYPE html&gt;</span> <span class="synIdentifier">&lt;</span><span class="synStatement">html</span><span class="synIdentifier"> </span><span class="synType">lang</span><span class="synIdentifier">=</span><span class="synConstant">&quot;ja&quot;</span><span class="synIdentifier">&gt;</span> <span class="synIdentifier">&lt;</span><span class="synStatement">head</span><span class="synIdentifier">&gt;</span> <span class="synPreProc"> </span><span class="synIdentifier">&lt;</span><span class="synStatement">meta</span><span class="synIdentifier"> </span><span class="synType">charset</span><span class="synIdentifier">=</span><span class="synConstant">&quot;UTF-8&quot;</span><span class="synIdentifier">&gt;</span> <span class="synPreProc"> </span><span class="synIdentifier">&lt;</span><span class="synStatement">title</span><span class="synIdentifier">&gt;&lt;/</span><span class="synStatement">title</span><span class="synIdentifier">&gt;</span> <span class="synPreProc"> </span><span class="synIdentifier">&lt;</span><span class="synStatement">script</span><span class="synIdentifier"> </span><span class="synType">type</span><span class="synIdentifier">=</span><span class="synConstant">&quot;text/javascript&quot;</span><span class="synIdentifier"> </span><span class="synType">src</span><span class="synIdentifier">=</span><span class="synConstant">&quot;three.min.js&quot;</span><span class="synIdentifier">&gt;&lt;/</span><span class="synStatement">script</span><span class="synIdentifier">&gt;</span> <span class="synPreProc"> </span><span class="synIdentifier">&lt;</span><span class="synStatement">script</span><span class="synIdentifier"> </span><span class="synType">type</span><span class="synIdentifier">=</span><span class="synConstant">&quot;text/javascript&quot;</span><span class="synIdentifier"> </span><span class="synType">src</span><span class="synIdentifier">=</span><span class="synConstant">&quot;thview.js&quot;</span><span class="synIdentifier">&gt;&lt;/</span><span class="synStatement">script</span><span class="synIdentifier">&gt;</span> <span class="synIdentifier">&lt;/</span><span class="synStatement">head</span><span class="synIdentifier">&gt;</span> <span class="synIdentifier">&lt;</span><span class="synStatement">body</span><span class="synIdentifier">&gt;</span> <span class="synIdentifier">&lt;</span><span class="synStatement">div</span><span class="synIdentifier"> </span><span class="synType">id</span><span class="synIdentifier">=</span><span class="synConstant">&quot;image1&quot;</span><span class="synIdentifier"> </span><span class="synType">style</span><span class="synIdentifier">=</span><span class="synConstant">&quot;position:absolute;top:0px;left:0px;&quot;</span><span class="synIdentifier">&gt;&lt;/</span><span class="synStatement">div</span><span class="synIdentifier">&gt;</span> <span class="synIdentifier">&lt;</span><span class="synStatement">script</span><span class="synIdentifier"> </span><span class="synType">type</span><span class="synIdentifier">=</span><span class="synConstant">&quot;text/javascript&quot;</span><span class="synIdentifier"> &gt;</span> <span class="synSpecial"> </span><span class="synIdentifier">var</span><span class="synSpecial"> img1 = </span><span class="synStatement">new</span><span class="synSpecial"> ThView</span>(<span class="synIdentifier">{</span> <span class="synSpecial"> id:</span><span class="synConstant">'image1'</span><span class="synSpecial">,</span> <span class="synSpecial"> file: </span><span class="synConstant">'images/photo.jpg'</span><span class="synSpecial">,</span> <span class="synSpecial"> width: </span>980<span class="synSpecial">,</span> <span class="synSpecial"> height: </span>560<span class="synSpecial">,</span> <span class="synSpecial"> zoom: </span>100<span class="synSpecial">,</span> <span class="synSpecial"> firstview: </span>90 <span class="synSpecial"> </span><span class="synIdentifier">}</span>)<span class="synSpecial">;</span> <span class="synSpecial"> </span><span class="synIdentifier">&lt;/</span><span class="synStatement">script</span><span class="synIdentifier">&gt;</span> <span class="synIdentifier">&lt;/</span><span class="synStatement">body</span><span class="synIdentifier">&gt;</span> <span class="synIdentifier">&lt;/</span><span class="synStatement">html</span><span class="synIdentifier">&gt;</span> </pre><p> <br /> また、THETAの公式アプリは最近のアップデートで、一定時間ごとに自動的にシャッターを切るインターバル撮影機能がつきました。そのためthview.jsにも連続写真をパラパラマンガ風に表示する機能をつけました。<br />  <br /> <a href="http://aikelab.net/thview/hmd4.html">&#x30C7;&#x30E2;2 &#x9023;&#x7D9A;&#x5199;&#x771F;</a><br /> <p><a href="http://aikelab.net/thview/hmd4.html" class="hatena-fotolife" target="_blank"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20140930/20140930214742.png" alt="f:id:aike:20140930214742p:image" title="f:id:aike:20140930214742p:image" class="hatena-fotolife"></a></p> </p> <pre class="code lang-html" data-lang="html" data-unlink><span class="synComment">&lt;!DOCTYPE html&gt;</span> <span class="synIdentifier">&lt;</span><span class="synStatement">html</span><span class="synIdentifier"> </span><span class="synType">lang</span><span class="synIdentifier">=</span><span class="synConstant">&quot;ja&quot;</span><span class="synIdentifier">&gt;</span> <span class="synIdentifier">&lt;</span><span class="synStatement">head</span><span class="synIdentifier">&gt;</span> <span class="synPreProc"> </span><span class="synIdentifier">&lt;</span><span class="synStatement">meta</span><span class="synIdentifier"> </span><span class="synType">charset</span><span class="synIdentifier">=</span><span class="synConstant">&quot;UTF-8&quot;</span><span class="synIdentifier">&gt;</span> <span class="synPreProc"> </span><span class="synIdentifier">&lt;</span><span class="synStatement">title</span><span class="synIdentifier">&gt;&lt;/</span><span class="synStatement">title</span><span class="synIdentifier">&gt;</span> <span class="synPreProc"> </span><span class="synIdentifier">&lt;</span><span class="synStatement">script</span><span class="synIdentifier"> </span><span class="synType">type</span><span class="synIdentifier">=</span><span class="synConstant">&quot;text/javascript&quot;</span><span class="synIdentifier"> </span><span class="synType">src</span><span class="synIdentifier">=</span><span class="synConstant">&quot;three.min.js&quot;</span><span class="synIdentifier">&gt;&lt;/</span><span class="synStatement">script</span><span class="synIdentifier">&gt;</span> <span class="synPreProc"> </span><span class="synIdentifier">&lt;</span><span class="synStatement">script</span><span class="synIdentifier"> </span><span class="synType">type</span><span class="synIdentifier">=</span><span class="synConstant">&quot;text/javascript&quot;</span><span class="synIdentifier"> </span><span class="synType">src</span><span class="synIdentifier">=</span><span class="synConstant">&quot;thview.js&quot;</span><span class="synIdentifier">&gt;&lt;/</span><span class="synStatement">script</span><span class="synIdentifier">&gt;</span> <span class="synIdentifier">&lt;/</span><span class="synStatement">head</span><span class="synIdentifier">&gt;</span> <span class="synIdentifier">&lt;</span><span class="synStatement">body</span><span class="synIdentifier">&gt;</span> <span class="synIdentifier">&lt;</span><span class="synStatement">div</span><span class="synIdentifier"> </span><span class="synType">id</span><span class="synIdentifier">=</span><span class="synConstant">&quot;image1&quot;</span><span class="synIdentifier"> </span><span class="synType">style</span><span class="synIdentifier">=</span><span class="synConstant">&quot;position:absolute;top:0px;left:0px;&quot;</span><span class="synIdentifier">&gt;&lt;/</span><span class="synStatement">div</span><span class="synIdentifier">&gt;</span> <span class="synIdentifier">&lt;</span><span class="synStatement">script</span><span class="synIdentifier"> </span><span class="synType">type</span><span class="synIdentifier">=</span><span class="synConstant">&quot;text/javascript&quot;</span><span class="synIdentifier"> &gt;</span> <span class="synSpecial"> </span><span class="synIdentifier">var</span><span class="synSpecial"> img1 = </span><span class="synStatement">new</span><span class="synSpecial"> ThView</span>(<span class="synIdentifier">{</span> <span class="synSpecial"> id:</span><span class="synConstant">'image1'</span><span class="synSpecial">,</span> <span class="synSpecial"> file: </span><span class="synIdentifier">[</span> <span class="synSpecial"> </span><span class="synConstant">'images/R0010155.JPG'</span><span class="synSpecial">,</span> <span class="synSpecial"> </span><span class="synConstant">'images/R0010156.JPG'</span><span class="synSpecial">,</span> <span class="synSpecial"> </span><span class="synConstant">'images/R0010157.JPG'</span><span class="synSpecial">,</span> <span class="synSpecial">      :</span>(<span class="synSpecial">省略</span>) <span class="synSpecial"> </span><span class="synConstant">'images/R0010175.JPG'</span> <span class="synSpecial"> </span><span class="synIdentifier">]</span><span class="synSpecial">,</span> <span class="synSpecial"> interval: </span>500<span class="synSpecial">,</span> <span class="synSpecial"> width: </span>980<span class="synSpecial">,</span> <span class="synSpecial"> height: </span>560<span class="synSpecial">,</span> <span class="synSpecial"> firstview: </span>-90 <span class="synSpecial"> </span><span class="synIdentifier">}</span>)<span class="synSpecial">;</span> <span class="synSpecial"> </span><span class="synIdentifier">&lt;/</span><span class="synStatement">script</span><span class="synIdentifier">&gt;</span> <span class="synIdentifier">&lt;/</span><span class="synStatement">body</span><span class="synIdentifier">&gt;</span> <span class="synIdentifier">&lt;/</span><span class="synStatement">html</span><span class="synIdentifier">&gt;</span> </pre><p>画像は<a class="keyword" href="http://d.hatena.ne.jp/keyword/iPhone">iPhone</a>のCPUパワー等を考慮して元画像よりも少し小さくした方が良いようです。<br />  <br /> <a class="keyword" href="http://d.hatena.ne.jp/keyword/Oculus%20Rift">Oculus Rift</a>みたいに両目で別々の画像を見る方が良いのかもと思ってthview.jsに <a class="keyword" href="http://d.hatena.ne.jp/keyword/hmd">hmd</a>: true というオプションも用意しましたが、ハコスコの場合は両目で同じ画像を見るのがよさそうでした。<br />  <br /> <a href="http://aikelab.net/thview/hmd.html">&#x30C7;&#x30E2;3 &#x4E21;&#x76EE;&#x5225;&#x753B;&#x50CF;</a><br /> <p><a href="http://aikelab.net/thview/hmd.html" class="hatena-fotolife" target="_blank"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20140930/20140930214743.png" alt="f:id:aike:20140930214743p:image" title="f:id:aike:20140930214743p:image" class="hatena-fotolife"></a></p> <br /> Enjoy!<br />  <div class="hatena-asin-detail"><br /> <a href="http://www.amazon.co.jp/dp/B00LJ2J0O0/?tag=lifehacklife-22&ascsubtag=d-11lyr"><img src="http://ecx.images-amazon.com/images/I/31nf5VbxKFL._SL160_.jpg" class="hatena-asin-detail-image" alt="ハコスコ" title="ハコスコ"></a><br /> <div class="hatena-asin-detail-info"><br /> <p class="hatena-asin-detail-title"><a href="http://www.amazon.co.jp/dp/B00LJ2J0O0/?tag=lifehacklife-22&ascsubtag=d-11lyr">ハコスコ</a></p> <ul> <li><span class="hatena-asin-detail-label">出版社/メーカー:</span> <a href="http://d.hatena.ne.jp/keyword/SR%20laboratories" class="keyword">SR laboratories</a></li> <li><span class="hatena-asin-detail-label">メディア:</span> エレクトロニクス</li> <li><a href="http://d.hatena.ne.jp/asin/B00LJ2J0O0" target="_blank">この商品を含むブログを見る</a></li> </ul> </div> <div class="hatena-asin-detail-foot"></div></div></p><p><div class="hatena-asin-detail"><br /> <a href="http://www.amazon.co.jp/dp/B00F9VSJ7Q/?tag=lifehacklife-22&ascsubtag=d-11lyr"><img src="http://ecx.images-amazon.com/images/I/21JGSKybGyL._SL160_.jpg" class="hatena-asin-detail-image" alt="RICOH デジタルカメラ RICOH THETA 360°全天球イメージ撮影デバイス 0175760" title="RICOH デジタルカメラ RICOH THETA 360°全天球イメージ撮影デバイス 0175760"></a><br /> <div class="hatena-asin-detail-info"><br /> <p class="hatena-asin-detail-title"><a href="http://www.amazon.co.jp/dp/B00F9VSJ7Q/?tag=lifehacklife-22&ascsubtag=d-11lyr">RICOH デジタルカメラ RICOH THETA 360°全天球イメージ撮影デバイス 0175760</a></p> <ul> <li><span class="hatena-asin-detail-label">出版社/メーカー:</span> <a href="http://d.hatena.ne.jp/keyword/%A5%EA%A5%B3%A1%BC" class="keyword">リコー</a></li> <li><span class="hatena-asin-detail-label">発売日:</span> 2013/11/08</li> <li><span class="hatena-asin-detail-label">メディア:</span> Camera</li> <li><a href="http://d.hatena.ne.jp/asin/B00F9VSJ7Q" target="_blank">この商品を含むブログを見る</a></li> </ul> </div> <div class="hatena-asin-detail-foot"></div></div></p> aike IR録ろうぜ!2 hatenablog://entry/10257846132645780955 2014-09-21T00:00:00+09:00 2014-09-21T00:00:00+09:00 DTMでよく使われるコンボリューションリバーブやアンプシミュレーターは、現実世界の音響的特徴をWAVファイルのかたちに記録したIR(Impulse Response、インパルス応答)を使って周波数特性や残響をシミュレートします。 最近はWeb Audio APIにもコンボルバーがあるので、気軽にIRを使える環境も広がってきたように思います。 IRファイルはDTMソフトウェアに付属するものから出自の怪しいものまでいろいろありますが、安心して自由に使えて再配布可能なものとなると意外と少なかったりします。 そんなわけで、IRファイルを自作してしまおうというのが今回の主旨です。 実はかなり前にプラグイ… <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/DTM">DTM</a>でよく使われるコンボリューションリ<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D0%A1%BC%A5%D6">バーブ</a>やアンプシミュレーターは、現実世界の音響的特徴をWAVファイルのかたちに記録したIR(Impulse Response、インパルス応答)を使って周波数特性や残響をシミュレートします。<br />  <br /> 最近はWeb Audio <a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>にもコンボルバーがあるので、気軽にIRを使える環境も広がってきたように思います。<br />  <br /> IRファイルは<a class="keyword" href="http://d.hatena.ne.jp/keyword/DTM">DTM</a>ソフトウェアに付属するものから出自の怪しいものまでいろいろありますが、安心して自由に使えて再配布可能なものとなると意外と少なかったりします。<br />  <br /> そんなわけで、IRファイルを自作してしまおうというのが今回の主旨です。<br />  <br /> 実はかなり前に<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>エフェクトからIRを録る手順について<a href="http://d.hatena.ne.jp/aike/20110428">&#x30D6;&#x30ED;&#x30B0;&#x306B;&#x66F8;&#x3044;&#x305F;</a>ことがあります。今回は実際のアンプからマイク録りしてIRを作ります。<br />  <br /> <iframe width="420" height="315" src="http://www.youtube.com/embed/ycovHmaZ77k?wmode=transparent" frameborder="0" allowfullscreen></iframe><br />  <br /> <a class="keyword" href="http://d.hatena.ne.jp/keyword/%B2%BB%B6%C1%B9%A9%B3%D8">音響工学</a>的な正確さを求めなければ、すごく簡単に作れるのがわかると思います。<br />  <br /> このとき作ったIRファイルがこちらです。<br /> <a href="http://aikelab.net/dtm/20140921/ir_impulse.wav">ir_impulse.wav</a><br /> <a href="http://aikelab.net/dtm/20140921/ir_sweep.wav">ir_sweep.wav</a><br />  <br /> これらをギターの音にかけてみます。<br />  <br /> これが元のギターの音。かなりライン録りくさい感じがします。<br /> <span style="vertical-align:middle;"><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" width="220" height="25" id="mp3_3" align="middle" style="vertical-align:bottom"><param name="flashVars" value="mp3Url=http://aikelab.net/dtm/20140921/org.mp3"><param name="allowScriptAccess" value="sameDomain"><param name="movie" value="http://g.hatena.ne.jp/tools/mp3_3.swf"><param name="quality" value="high"><param name="bgcolor" value="#ffffff"><param name="wmode" value="transparent"><embed src="http://g.hatena.ne.jp/tools/mp3_3.swf" flashvars="mp3Url=http://aikelab.net/dtm/20140921/org.mp3" quality="high" wmode="transparent" bgcolor="#ffffff" width="220" height="25" name="mp3_3" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" style="vertical-align:bottom"></object><a href="http://aikelab.net/dtm/20140921/org.mp3"><img src="http://g.hatena.ne.jp/images/podcasting.gif" title="Download" alt="Download" border="0" style="border:0px;vertical-align:bottom;"></a></span><br />  <br /> クラップ音から作ったIRをかけた音。なんだかちょっとクセのある音ですがアンプっぽくなりました。手を叩いた時の残響が混ざって少しルームリ<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D0%A1%BC%A5%D6">バーブ</a>がかかったような音になっています。<br /> <span style="vertical-align:middle;"><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" width="220" height="25" id="mp3_3" align="middle" style="vertical-align:bottom"><param name="flashVars" value="mp3Url=http://aikelab.net/dtm/20140921/impulse.mp3"><param name="allowScriptAccess" value="sameDomain"><param name="movie" value="http://g.hatena.ne.jp/tools/mp3_3.swf"><param name="quality" value="high"><param name="bgcolor" value="#ffffff"><param name="wmode" value="transparent"><embed src="http://g.hatena.ne.jp/tools/mp3_3.swf" flashvars="mp3Url=http://aikelab.net/dtm/20140921/impulse.mp3" quality="high" wmode="transparent" bgcolor="#ffffff" width="220" height="25" name="mp3_3" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" style="vertical-align:bottom"></object><a href="http://aikelab.net/dtm/20140921/impulse.mp3"><img src="http://g.hatena.ne.jp/images/podcasting.gif" title="Download" alt="Download" border="0" style="border:0px;vertical-align:bottom;"></a></span><br />  <br /> スイープ音から作ったIRをかけた音。小型アンプとはいえマーシャルの特徴がけっこう出てると思いませんか。<br /> <span style="vertical-align:middle;"><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" width="220" height="25" id="mp3_3" align="middle" style="vertical-align:bottom"><param name="flashVars" value="mp3Url=http://aikelab.net/dtm/20140921/sweep.mp3"><param name="allowScriptAccess" value="sameDomain"><param name="movie" value="http://g.hatena.ne.jp/tools/mp3_3.swf"><param name="quality" value="high"><param name="bgcolor" value="#ffffff"><param name="wmode" value="transparent"><embed src="http://g.hatena.ne.jp/tools/mp3_3.swf" flashvars="mp3Url=http://aikelab.net/dtm/20140921/sweep.mp3" quality="high" wmode="transparent" bgcolor="#ffffff" width="220" height="25" name="mp3_3" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" style="vertical-align:bottom"></object><a href="http://aikelab.net/dtm/20140921/sweep.mp3"><img src="http://g.hatena.ne.jp/images/podcasting.gif" title="Download" alt="Download" border="0" style="border:0px;vertical-align:bottom;"></a></span><br />  <br /> IRはそれ自体がWAVなのでIRの波形を加工して残響成分を増減したりEQをかけて整えたりすることもできます。<br /> また、本来IR目的ではない音のWAVファイルをIRとして使って特殊な音を作るようなクリエイティブな方法もあるので自由な発想でいろいろ試してみてください。</p> aike ブラウザでVJプログラム書くときのフレームワーク作った hatenablog://entry/10257846132645780966 2014-09-13T00:00:00+09:00 2014-09-13T00:00:00+09:00 JavaScriptでオーディオとビジュアルの扱い方をおぼえると、人類はみなVJアプリを作るようになります。ぼくの周りの5人くらいの人類はそうでした。 自分もいろいろビジュアライザーアプリを作ってイベントでブラウザVJやったりしました。ただ、ひとつひとつはそれなりに面白い視覚効果のプログラムでも、それだけでは長時間のイベントに対応できません。通常のVJのように、イベントの進行やDJの音楽の緩急に合わせて効果的な視覚効果を選択して次々と切り替えていきたいところです。 そんなわけで、複数の視覚効果をクロスフェードで切り替えられるようなブラウザVJフレームワークを作りました。それぞれの視覚効果や各種… <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/JavaScript">JavaScript</a>でオーディオとビジュアルの扱い方をおぼえると、人類はみなVJアプリを作るようになります。ぼくの周りの5人くらいの人類はそうでした。<br />  <br /> 自分もいろいろビジュアライザーアプリを作ってイベントでブラウザVJやったりしました。ただ、ひとつひとつはそれなりに面白い視覚効果のプログラムでも、それだけでは長時間のイベントに対応できません。通常のVJのように、イベントの進行やDJの音楽の緩急に合わせて効果的な視覚効果を選択して次々と切り替えていきたいところです。<br />  <br /> そんなわけで、複数の視覚効果を<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AF%A5%ED%A5%B9%A5%D5%A5%A7%A1%BC%A5%C9">クロスフェード</a>で切り替えられるようなブラウザVJ<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D5%A5%EC%A1%BC%A5%E0%A5%EF%A1%BC%A5%AF">フレームワーク</a>を作りました。それぞれの視覚効果や各種の機能を<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>として仕様化し、この仕様に合わせれば<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B3%C8%C4%A5%B5%A1%C7%BD">拡張機能</a><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>を自作できるようになっています。<br />   <br /> <span class="deco" style="font-size:large;"><a href="https://github.com/aike/jsdrome">https://github.com/aike/jsdrome</a></span><br /> <span class="deco" style="font-size:large;"><a href="http://aikelab.net/jsdrome/">http://aikelab.net/jsdrome/</a><br /> </span> <br /> <span itemscope itemtype="http://schema.org/Photograph"><a href="http://f.hatena.ne.jp/aike/20140913074551" class="hatena-fotolife" itemprop="url"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20140913/20140913074551.png" alt="f:id:aike:20140913074551p:image" title="f:id:aike:20140913074551p:image" class="hatena-fotolife" itemprop="image"></a></span><br />  <br /> ■仕様<br /> ・複数のビジュアライザーを<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>として組み込み<br /> ・ビジュアライザー同士の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AF%A5%ED%A5%B9%A5%D5%A5%A7%A1%BC%A5%C9">クロスフェード</a><br /> ・非表示状態のビジュアライザーの処理を自動停止<br /> ・<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B5%A5%A6%A5%F3%A5%C9">サウンド</a>ファイルの再生<br /> ・マイク入力または<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B5%A5%A6%A5%F3%A5%C9">サウンド</a>ファイルに反応する映像処理<br /> ・テキストロゴ表示<br /> ・ウェブカメラ入力表示<br /> ・キーボード入力による制御<br /> ・<a class="keyword" href="http://d.hatena.ne.jp/keyword/MIDI">MIDI</a>入力による制御<br /> ・<a class="keyword" href="http://d.hatena.ne.jp/keyword/Leap%20Motion">Leap Motion</a>入力による制御<br />  <br /> 現状、以下のようなビジュアライザー<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>があり、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AF%A5%ED%A5%B9%A5%D5%A5%A7%A1%BC%A5%C9">クロスフェード</a>で切り替えられます。</p> <table> <tr> <td>3d-cube.js</td> <td>キューブ</td> </tr> <tr> <td>3d-wave.js</td> <td><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%DA%A5%AF%A5%C8%A5%E9%A5%E0%A5%A2%A5%CA%A5%E9%A5%A4%A5%B6">スペクトラムアナライザ</a>ー</td> </tr> <tr> <td>3d-lissajous.js</td> <td>リサジュー図形</td> </tr> <tr> <td>3d-matrix.js</td> <td><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DE%A5%C8%A5%EA%A5%C3%A5%AF%A5%B9">マトリックス</a></td> </tr> <tr> <td>3d-stardust.js</td> <td>宇宙</td> </tr> <tr> <td>danmaku.js</td> <td><a class="keyword" href="http://d.hatena.ne.jp/keyword/%C3%C6%CB%EB">弾幕</a>ビジュアライザー</td> </tr> <tr> <td>videoplayer.js</td> <td>動画プレイヤー</td> </tr> <tr> <td>dummy.js</td> <td>表示テスト</td> </tr> </table><p> <br /> 以下の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>は<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AF%A5%ED%A5%B9%A5%D5%A5%A7%A1%BC%A5%C9">クロスフェード</a>せずに常時有効となる共通<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>です。</p> <table> <tr> <td>common/logo.js</td> <td>テキストロゴ表示</td> </tr> <tr> <td>common/musicplayer.js</td> <td>音楽プレイヤー</td> </tr> <tr> <td>common/camera.js</td> <td><a class="keyword" href="http://d.hatena.ne.jp/keyword/Web%A5%AB%A5%E1%A5%E9">Webカメラ</a>+エフェクト</td> </tr> <tr> <td>common/controlwindow.js</td> <td>操作パネル表示</td> </tr> <tr> <td>common/leap.js</td> <td><a class="keyword" href="http://d.hatena.ne.jp/keyword/Leap%20Motion">Leap Motion</a>インタフェース</td> </tr> </table><p> <br /> <a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>は以下の各イベントに対応するメソッドを実装します。イベント処理が不要の場合は空のメソッドとしておきます。</p> <table> <tr> <td>onStart()</td> <td>表示開始</td> </tr> <tr> <td>onStop()</td> <td>表示終了</td> </tr> <tr> <td>onFade(opacity)</td> <td>フェードイン/アウト処理 opacityは0〜1</td> </tr> <tr> <td>onAudio(moment, period)</td> <td>マイク入力またはオーディオファイルの音量が定期的に通知される</td> </tr> <tr> <td>onKeydown(keycode)</td> <td>キー押下イベント。フォアグラウンドの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>にのみ通知される</td> </tr> <tr> <td>onResize(x, y, width, height)</td> <td>ウィンドウリサイズ処理</td> </tr> <tr> <td>onTimer()</td> <td>描画用タイマーイベント</td> </tr> <tr> <td>onMidi(arg1, arg2, arg3)</td> <td><a class="keyword" href="http://d.hatena.ne.jp/keyword/MIDI">MIDI</a>入力イベント</td> </tr> </table><p> <br /> わりと多機能なので、いずれもう少し詳しく書く予定です。</p> aike Webでポリシンセ作るときのテンプレ作った hatenablog://entry/10257846132645780978 2014-09-09T00:00:00+09:00 2014-09-09T00:00:00+09:00 もう半年以上前に作ったやつですけどせっかくなので解説。 JavaScriptでプログラミングをやっていると人は誰しもシンセを作りたくなるかと思います。僕も3年くらい前にWeb Audio Synthというのを作りました。 いまはウェブブラウザもオーディオやMIDIのAPIが充実してきてシンプルな単音のシンセを作るのは簡単になりました。でもちょっと和音を弾きたくなってポリシンセに拡張しようと思うとこれがけっこう大変だったりします。 同時発音数6ボイスのポリシンセを作るとなったら、ほんとうにモノシンセを6個分実装する必要があります。さらに、和音を弾いている最中に追加で音を重ねるときなど空いているボ… <p>もう半年以上前に作ったやつですけどせっかくなので解説。<br />  <br /> <a class="keyword" href="http://d.hatena.ne.jp/keyword/JavaScript">JavaScript</a>でプログラミングをやっていると人は誰しもシンセを作りたくなるかと思います。僕も3年くらい前に<a href="http://aikelab.net/websynth/">Web Audio Synth</a>というのを作りました。<br />  <br /> いまはウェブブラウザもオーディオや<a class="keyword" href="http://d.hatena.ne.jp/keyword/MIDI">MIDI</a>の<a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>が充実してきてシンプルな単音のシンセを作るのは簡単になりました。でもちょっと和音を弾きたくなってポリシンセに拡張しようと思うとこれがけっこう大変だったりします。<br /> 同時発音数6ボイスのポリシンセを作るとなったら、ほんとうにモノシンセを6個分実装する必要があります。さらに、和音を弾いている最中に追加で音を重ねるときなど空いているボイスをさがして割り当てるといったオブジェクトプーリングの仕組みが必要になります。<br /> また、いくつかシンセを作っていると、鍵盤のUIや<a class="keyword" href="http://d.hatena.ne.jp/keyword/MIDI">MIDI</a>入力の対応など定型的で毎回同じ作業があることに気づいてきます。<br />  <br /> そんなわけで、そういった部分をテンプレ的に用意しました。つまり、ボイス(ノートナンバーに応じて単音を生成する処理)の中身を自作すれば、それ以外の和音の処理、鍵盤のUI、ASCIIキーボードイベント処理、<a class="keyword" href="http://d.hatena.ne.jp/keyword/MIDI">MIDI</a>イベント処理、WebMidiLinkイベント処理などはテンプレにまかせてしまえるというものです。</p><p><span class="deco" style="font-size:large;"><a href="https://github.com/aike/TemplateSynth">https://github.com/aike/TemplateSynth</a></span><br /> <span itemscope itemtype="http://schema.org/Photograph"><a href="http://f.hatena.ne.jp/aike/20140910001405" class="hatena-fotolife" itemprop="url"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20140910/20140910001405.png" alt="f:id:aike:20140910001405p:image" title="f:id:aike:20140910001405p:image" class="hatena-fotolife" itemprop="image"></a></span><br />  <br /> ■シンセの作成例<br /> 自分のシンセを作りたい時は js/voice.js を拡張するようにしてください。</p> <table> <tr> <th>メソッド名</th> <th>処理内容</th> </tr> <tr> <td>Voice#noteOn(note, velocity)</td> <td>発音開始</td> </tr> <tr> <td>Voice#changeNote(note)</td> <td>発音中に音程変更</td> </tr> <tr> <td>Voice#noteOff()</td> <td>発音終了</td> </tr> <tr> <td>Voice#setParam(param_id, val)</td> <td>パラメータ設定(空でも可)</td> </tr> </table><p> <br /> デフォルトではサイン波を鳴らすシンセになっています。</p> <pre class="code lang-javascript" data-lang="javascript" data-unlink><span class="synIdentifier">var</span> Voice = <span class="synIdentifier">function</span>(ctx) <span class="synIdentifier">{</span> <span class="synIdentifier">this</span>.ctx = ctx; <span class="synIdentifier">this</span>.next_node = <span class="synStatement">null</span>; <span class="synIdentifier">this</span>.noteNoToFrequency = <span class="synIdentifier">function</span>(noteno) <span class="synIdentifier">{</span> <span class="synStatement">return</span> 440.0 * Math.pow(2.0, (noteno - 69.0) / 12.0); <span class="synIdentifier">}</span> <span class="synIdentifier">}</span> Voice.prototype.noteOn = <span class="synIdentifier">function</span>(note, velocity) <span class="synIdentifier">{</span> <span class="synIdentifier">this</span>.osc = <span class="synIdentifier">this</span>.ctx.createOscillator(); <span class="synIdentifier">this</span>.osc.frequency.value = <span class="synIdentifier">this</span>.noteNoToFrequency(note); <span class="synIdentifier">this</span>.osc.connect(<span class="synIdentifier">this</span>.next_node); <span class="synIdentifier">this</span>.osc.start(0); <span class="synIdentifier">}</span> </pre><p> <br /> こんな風に変えるとプレイバック<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B5%A5%F3%A5%D7%A5%E9%A1%BC">サンプラー</a>になります。</p> <pre class="code lang-javascript" data-lang="javascript" data-unlink><span class="synIdentifier">var</span> Voice = <span class="synIdentifier">function</span>(ctx) <span class="synIdentifier">{</span> <span class="synIdentifier">this</span>.ctx = ctx; <span class="synIdentifier">this</span>.next_node = <span class="synStatement">null</span>; <span class="synIdentifier">this</span>.noteNoToSpeed = <span class="synIdentifier">function</span>(noteno) <span class="synIdentifier">{</span> <span class="synStatement">return</span> Math.pow(2.0, (noteno - 69.0) / 12.0); <span class="synIdentifier">}</span> <span class="synIdentifier">var</span> <span class="synStatement">self</span> = <span class="synIdentifier">this</span>; <span class="synIdentifier">this</span>.loadwav(<span class="synConstant">'sampler.wav'</span>, <span class="synIdentifier">function</span>(buf) <span class="synIdentifier">{</span> <span class="synStatement">self</span>.buf = buf; <span class="synIdentifier">}</span>); <span class="synIdentifier">}</span> Voice.prototype.loadwav = <span class="synIdentifier">function</span>(file, callback) <span class="synIdentifier">{</span> <span class="synIdentifier">var</span> xhr = <span class="synStatement">new</span> XMLHttpRequest(); xhr.open(<span class="synConstant">&quot;GET&quot;</span>, file, <span class="synConstant">true</span>); xhr.responseType = <span class="synConstant">&quot;arraybuffer&quot;</span>; <span class="synIdentifier">var</span> <span class="synStatement">self</span> = <span class="synIdentifier">this</span>; xhr.onload = <span class="synIdentifier">function</span>() <span class="synIdentifier">{</span> <span class="synStatement">self</span>.ctx.decodeAudioData(xhr.response,<span class="synIdentifier">function</span>(buf)<span class="synIdentifier">{</span> callback(buf); <span class="synIdentifier">}</span>, <span class="synIdentifier">function</span>()<span class="synIdentifier">{}</span>); <span class="synIdentifier">}</span>; xhr.send(); <span class="synIdentifier">}</span> Voice.prototype.noteOn = <span class="synIdentifier">function</span>(note, velocity) <span class="synIdentifier">{</span> <span class="synIdentifier">this</span>.sample = <span class="synIdentifier">this</span>.ctx.createBufferSource(); <span class="synIdentifier">this</span>.sample.buffer = <span class="synIdentifier">this</span>.buf; <span class="synIdentifier">this</span>.sample.playbackRate.value = <span class="synIdentifier">this</span>.noteNoToSpeed(note); <span class="synIdentifier">this</span>.sample.connect(<span class="synIdentifier">this</span>.next_node); <span class="synIdentifier">this</span>.sample.start(0); <span class="synIdentifier">}</span> </pre><p> <br /> 1ボイスにつきデチューンした5個のノコギリ波を鳴らすSuper Saw的なシンセならこんな感じ。</p> <pre class="code lang-javascript" data-lang="javascript" data-unlink><span class="synIdentifier">var</span> Voice = <span class="synIdentifier">function</span>(ctx) <span class="synIdentifier">{</span> <span class="synIdentifier">this</span>.ctx = ctx; <span class="synIdentifier">this</span>.next_node = <span class="synStatement">null</span>; <span class="synIdentifier">this</span>.noteNoToFrequency = <span class="synIdentifier">function</span>(noteno) <span class="synIdentifier">{</span> <span class="synStatement">return</span> 440.0 * Math.pow(2.0, (noteno - 69.0) / 12.0); <span class="synIdentifier">}</span> <span class="synIdentifier">this</span>.osc = <span class="synStatement">new</span> <span class="synType">Array</span>(5); <span class="synIdentifier">this</span>.gain = <span class="synStatement">new</span> <span class="synType">Array</span>(5); <span class="synStatement">for</span> (<span class="synIdentifier">var</span> i = 0; i &lt; 5; i++) <span class="synIdentifier">{</span> <span class="synIdentifier">this</span>.gain<span class="synIdentifier">[</span>i<span class="synIdentifier">]</span> = <span class="synIdentifier">this</span>.ctx.createGain(); <span class="synIdentifier">this</span>.gain<span class="synIdentifier">[</span>i<span class="synIdentifier">]</span>.gain.value = 0.3; <span class="synIdentifier">}</span> <span class="synIdentifier">}</span> Voice.prototype.noteOn = <span class="synIdentifier">function</span>(note, velocity) <span class="synIdentifier">{</span> <span class="synStatement">for</span> (<span class="synIdentifier">var</span> i = 0; i &lt; 5; i++) <span class="synIdentifier">{</span> <span class="synIdentifier">this</span>.osc<span class="synIdentifier">[</span>i<span class="synIdentifier">]</span> = <span class="synIdentifier">this</span>.ctx.createOscillator(); <span class="synIdentifier">this</span>.osc<span class="synIdentifier">[</span>i<span class="synIdentifier">]</span>.type = <span class="synConstant">'sawtooth'</span>; <span class="synIdentifier">this</span>.osc<span class="synIdentifier">[</span>i<span class="synIdentifier">]</span>.detune.value = 10 * i - 20; <span class="synIdentifier">this</span>.osc<span class="synIdentifier">[</span>i<span class="synIdentifier">]</span>.frequency.value = <span class="synIdentifier">this</span>.noteNoToFrequency(note); <span class="synIdentifier">this</span>.osc<span class="synIdentifier">[</span>i<span class="synIdentifier">]</span>.connect(<span class="synIdentifier">this</span>.gain<span class="synIdentifier">[</span>i<span class="synIdentifier">]</span>); <span class="synIdentifier">this</span>.osc<span class="synIdentifier">[</span>i<span class="synIdentifier">]</span>.start(0); <span class="synIdentifier">}</span> <span class="synIdentifier">}</span> </pre><p> <br /> 最大同時発音数は synth.js で以下のように指定しています。</p> <pre class="code lang-javascript" data-lang="javascript" data-unlink>synth = <span class="synStatement">new</span> Synth(8); </pre><p> <br /> <a class="keyword" href="http://d.hatena.ne.jp/keyword/MIDI">MIDI</a>鍵盤から演奏したり、ASCIIキーボードを鍵盤代わりに弾くこともできます。<br /> シンセの発音<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%EB%A5%B4%A5%EA%A5%BA%A5%E0">アルゴリズム</a>を試したりするのに便利なので使ってみてください。<br /> Web Componentsとか使ってるので動作環境は現状<a class="keyword" href="http://d.hatena.ne.jp/keyword/Chrome">Chrome</a>のみだと思います。</p> aike 全天球ビューワーPaView.jsの動作環境とパノラマ飛行動画 hatenablog://entry/10257846132645780999 2014-08-24T00:00:00+09:00 2014-08-24T00:00:00+09:00 先日作った全天球ビューワーPaView.jsですが、できるだけ多くのブラウザで表示できるよう調べてみました。 クロスブラウザで問題になるところは、マウスイベント、WebGLで動画のテクスチャマッピングしているところ、対応動画フォーマットあたりです。 ■Windows Windows PCのブラウザは素直なものが多いようで、マウスイベントの処理をブラウザごとに書くくらいで、わりとそのまま動きました。Windows7上のChrome、Firefox、IEで正常に動くことを確認しました。 ■Mac OS Macの場合、Safari用のマウスイベント処理を書いたら正常に動きました。Firefoxは.m… <p>先日作った<a href="http://d.hatena.ne.jp/aike/20140726">&#x5168;&#x5929;&#x7403;&#x30D3;&#x30E5;&#x30FC;&#x30EF;&#x30FC;PaView.js</a>ですが、できるだけ多くのブラウザで表示できるよう調べてみました。<br /> <a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AF%A5%ED%A5%B9%A5%D6%A5%E9%A5%A6%A5%B6">クロスブラウザ</a>で問題になるところは、マウスイベント、<a class="keyword" href="http://d.hatena.ne.jp/keyword/WebGL">WebGL</a>で動画の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C6%A5%AF%A5%B9%A5%C1%A5%E3%A5%DE%A5%C3%A5%D4%A5%F3%A5%B0">テクスチャマッピング</a>しているところ、対応動画フォーマットあたりです。<br />  <br /> ■<a class="keyword" href="http://d.hatena.ne.jp/keyword/Windows">Windows</a><br /> <a class="keyword" href="http://d.hatena.ne.jp/keyword/Windows">Windows</a> PCのブラウザは素直なものが多いようで、マウスイベントの処理をブラウザごとに書くくらいで、わりとそのまま動きました。<a class="keyword" href="http://d.hatena.ne.jp/keyword/Windows7">Windows7</a>上の<a class="keyword" href="http://d.hatena.ne.jp/keyword/Chrome">Chrome</a>、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Firefox">Firefox</a>、<a class="keyword" href="http://d.hatena.ne.jp/keyword/IE">IE</a>で正常に動くことを確認しました。<br />  <br /> ■<a class="keyword" href="http://d.hatena.ne.jp/keyword/Mac%20OS">Mac OS</a><br /> <a class="keyword" href="http://d.hatena.ne.jp/keyword/Mac">Mac</a>の場合、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Safari">Safari</a>用のマウスイベント処理を書いたら正常に動きました。<a class="keyword" href="http://d.hatena.ne.jp/keyword/Firefox">Firefox</a>は.mp4の動画に対応しておらず(特許関係らしいです)、WebMで表示するようにしてみました。サーバ上に.mp4と同名の.webmのファイルを用意しておけば、.mp4を.webmとJSが読み替えて無理矢理表示します。サーバ側も AddType video/webm .webm する必要があるかもしれません。<br /> <a class="keyword" href="http://d.hatena.ne.jp/keyword/OS%20X">OS X</a> <a class="keyword" href="http://d.hatena.ne.jp/keyword/Mavericks">Mavericks</a>上の<a class="keyword" href="http://d.hatena.ne.jp/keyword/Chrome">Chrome</a>、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Firefox">Firefox</a>、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Safari">Safari</a>で正常に動くことを確認しました。<br />  <br /> ■<a class="keyword" href="http://d.hatena.ne.jp/keyword/iOS">iOS</a><br /> <a class="keyword" href="http://d.hatena.ne.jp/keyword/iOS">iOS</a>はWebGLRendererが使えないっぽいので<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C6%A5%AF%A5%B9%A5%C1%A5%E3%A5%DE%A5%C3%A5%D4%A5%F3%A5%B0">テクスチャマッピング</a>がうまくいかず非対応です。<br />  <br /> ■<a class="keyword" href="http://d.hatena.ne.jp/keyword/Android">Android</a><br /> <a class="keyword" href="http://d.hatena.ne.jp/keyword/Android">Android</a>は持っていないので未確認です。たぶん<a class="keyword" href="http://d.hatena.ne.jp/keyword/iOS">iOS</a>と同じような状況だと思います。<br />  <br /> 先日、メディアアーティストの八谷さんの超小型飛行機にカメラを搭載して撮影した動画をアップしました。空中を飛んでいる風景は全天球パノラマ動画の大きな可能性を感じることができると思います。見てみてください。<br />  <br /> <span class="deco" style="font-size:large;"><a href="http://sound.jp/aike/m02j/">http://sound.jp/aike/m02j/</a></span><br /> <p><a href="http://sound.jp/aike/m02j/" class="hatena-fotolife" target="_blank"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20140824/20140824184126.png" alt="f:id:aike:20140824184126p:image:w640" title="f:id:aike:20140824184126p:image:w640" class="hatena-fotolife" width="640"></a></p></p><p>※音が出ます。<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EC%A5%F3%A5%BF%A5%EB%A5%B5%A1%BC%A5%D0">レンタルサーバ</a>の仕様上<a class="keyword" href="http://d.hatena.ne.jp/keyword/Mac">Mac</a>の<a class="keyword" href="http://d.hatena.ne.jp/keyword/Firefox">Firefox</a>には対応していません。</p> aike MMDの全天球パノラマ動画を作ってみた hatenablog://entry/10257846132645781011 2014-08-07T00:00:00+09:00 2014-08-07T00:00:00+09:00 THETAからはじまって最近は動画にいたるまで、このところ全天球パノラマに興味を持っていたところ、先日こんなツイートを見かけました。 GoPro 6台からの映像を合成することで全球映像ができるのであれば、MMDのカメラを6パターンで出力すれば、できるのかな?— なヲタ級flagship - SKB06 (@nawota1105) 2014, 7月 20 通常、全天球パノラマ動画は6台のGoProで実写撮影した動画を、専用のスティッチングソフトを使って手作業で合成していきます。MMDの場合最初から仮想空間のCGなので、わざわざ6本のムービーとして出力して再合成する意味はあんまりないのですが、ステ… <p>THETAからはじまって最近は動画にいたるまで、このところ全天球パノラマに興味を持っていたところ、先日こんなツイートを見かけました。<br />  <blockquote class="twitter-tweet" lang="ja"><p>GoPro 6台からの映像を合成することで全球映像ができるのであれば、<a class="keyword" href="http://d.hatena.ne.jp/keyword/MMD">MMD</a>のカメラを6パターンで出力すれば、できるのかな?</p>&mdash; なヲタ級flagship - SKB06 (@nawota1105) <a href="https://twitter.com/nawota1105/statuses/490693353223122945">2014, 7月 20</a></blockquote></p></p> <p> <br /> 通常、全天球パノラマ動画は6台のGoProで実写撮影した動画を、専用のスティッチングソフトを使って手作業で合成していきます。<a class="keyword" href="http://d.hatena.ne.jp/keyword/MMD">MMD</a>の場合最初から仮想空間のCGなので、わざわざ6本のムービーとして出力して再合成する意味はあんまりないのですが、スティッチングの練習になりそうだし面白そうなのでやってみました。<br />  <br /> <a href="http://sound.jp/aike/paview/index6.html">http://sound.jp/aike/paview/index6.html</a><br /> <p><a href="http://sound.jp/aike/paview/index6.html" class="hatena-fotolife" target="_blank"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20140807/20140807183650.gif" alt="f:id:aike:20140807183650g:image" title="f:id:aike:20140807183650g:image" class="hatena-fotolife"></a></p><span class="deco" style="font-size:xx-small;"><a href="http://www6.atwiki.jp/vpvpwiki/pages/138.html" target="_blank">FL-chan−TYPEアノマロ モデル</a> by アノマロ<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A4%AB%A4%EA%A4%F3%A4%C8%A4%A6">かりんとう</a> / <a href="http://www6.atwiki.jp/vpvpwiki/pages/236.html#id_3f4fc9b5" target="_blank">金剛八式 モーション</a> by hino / <a href="http://www6.atwiki.jp/vpvpwiki/pages/406.html#id_3c1632f7" target="_blank">鷲宮神社 ステージ</a> by リボン犬</span><br />  <br /> 上のリンク先へ行くと、マウスでカメラを好きな方向に向けられる全天球パノラマ動画が表示されます(上記はキャプチャしたGIFアニメ)。一見リアルタイム<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EC%A5%F3%A5%C0%A5%EA%A5%F3%A5%B0">レンダリング</a>の3DCGのようにも見えますが、実際はムービーなのでFLちゃんの向こう側を見たりはできません。<br />  <br /> <a class="keyword" href="http://d.hatena.ne.jp/keyword/MMD">MMD</a>の出力パラメータはこんな感じです。<br /> 出力サイズ:<br />  640 x 480 px<br /> 視野角:<br />  100<br /> カメラ角度:<br />  cam1 0, 0, 0<br />  cam2 0, 180, 0<br />  cam3 0, 90, -90<br />  cam4 0, -90, 90<br />  cam5 90, 180, 90<br />  cam6 -90, 180, 90</p> aike ブラウザで波紋エフェクト出すやつ作った hatenablog://entry/10257846132645781026 2014-08-06T00:00:00+09:00 2014-08-06T00:00:00+09:00 最近プレゼンとかでウェブベースのアプリを実演する機会がわりとあったりします。そのときちょっと不便なのは、マウスをどのように操作して、どこでどういう風にクリックしたのかがいまいち伝わりにくいということで。まあしょうがないかと思ってたんですが。 そうしたら次期Androidのマテリアルデザインでは波紋エフェクトが使われるようになるとか。あー、その手があったか。そういえば、スマホじゃなくてPCの世界ではそういうのときどき見たことあるな、と思ってJavaScriptで作ってみました。 http://aikelab.net/visibletouch/ https://github.com/aike/Vi… <p>最近プレゼンとかでウェブベースのアプリを実演する機会がわりとあったりします。そのときちょっと不便なのは、マウスをどのように操作して、どこでどういう風にクリックしたのかがいまいち伝わりにくいということで。まあしょうがないかと思ってたんですが。<br />  <br /> そうしたら次期<a class="keyword" href="http://d.hatena.ne.jp/keyword/Android">Android</a>の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DE%A5%C6%A5%EA%A5%A2%A5%EB%A5%C7%A5%B6%A5%A4%A5%F3">マテリアルデザイン</a>では波紋エフェクトが使われるようになるとか。あー、その手があったか。そういえば、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%DE%A5%DB">スマホ</a>じゃなくてPCの世界ではそういうのときどき見たことあるな、と思って<a class="keyword" href="http://d.hatena.ne.jp/keyword/JavaScript">JavaScript</a>で作ってみました。<br />  <br /> <a href="http://aikelab.net/visibletouch/">http://aikelab.net/visibletouch/</a><br /> <a href="https://github.com/aike/VisibleTouch.js">https://github.com/aike/VisibleTouch.js</a><br />  <br /> <p><a href="http://f.hatena.ne.jp/aike/20140806180238" class="hatena-fotolife" target="_blank"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20140806/20140806180238.gif" alt="f:id:aike:20140806180238g:image" title="f:id:aike:20140806180238g:image" style="border: solid 1px #888888;" class="hatena-fotolife"></a></p> <br /> 発想の元は<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DE%A5%C6%A5%EA%A5%A2%A5%EB%A5%C7%A5%B6%A5%A4%A5%F3">マテリアルデザイン</a>の波紋エフェクトですが、プレゼン用ということで最終的にいろいろ違った感じになりました。たぶん探せば同じようなツールはすでにたくさんあって101回目くらいの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%BC%D6%CE%D8%A4%CE%BA%C6%C8%AF%CC%C0">車輪の再発明</a>だとは思うけど、自分用にぴったりのがほしかったので自作しました。<br />  <br /> ライブラリのJSファイルは共通部と固有部にわかれていて、読み込む固有ライブラリによってビジュアライズが変わります。<br />  <br /> visibletouch.js 共通ライブラリ<br /> visibletouchripple.js 固有ライブラリ:波紋エフェクト<br /> visibletouchmouse.js 固有ライブラリ:マウスイラスト表示<br /> visibletouchano.js 固有ライブラリ:「<a href="http://dic.nicovideo.jp/a/%E3%81%82%E3%81%AE%E6%A5%BD%E5%99%A8">&#x3042;&#x306E;&#x697D;&#x5668;</a>」風 波紋エフェクト<br />  <br /> <p><a href="http://f.hatena.ne.jp/aike/20140806180607" class="hatena-fotolife" target="_blank"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20140806/20140806180607.gif" alt="f:id:aike:20140806180607g:image" title="f:id:aike:20140806180607g:image" class="hatena-fotolife" style="border: solid 1px #888888;" ></a></p> <br /> 波紋エフェクトの仕組みとしては、ウィンドウと同じサイズの透明なキャンバスをあらかじめ最下位レイヤーに置いておいて、クリックされたらキャンバスを最上位レイヤーに移動して波紋アニメーションを描画。波紋が完全にフェードアウトしたら再びキャンバスを最下位レイヤーに戻す、という無理矢理なことをしています。そのため波紋描画中に連続してクリックしたりドラッグしたりすると、いろいろ悲しい思いをすることがあると思います。<br />  <div class="section"><br /> <div class="hatena-asin-detail"><br /> <a href="http://www.amazon.co.jp/dp/B0045S6NMC/?tag=lifehacklife-22&ascsubtag=d-11lyr"><img src="http://ecx.images-amazon.com/images/I/51PVnIog5eL._SL160_.jpg" class="hatena-asin-detail-image" alt="Invisible Touch" title="Invisible Touch"></a><br /> <div class="hatena-asin-detail-info"><br /> <p class="hatena-asin-detail-title"><a href="http://www.amazon.co.jp/dp/B0045S6NMC/?tag=lifehacklife-22&ascsubtag=d-11lyr">Invisible Touch</a></p> <ul> <li><span class="hatena-asin-detail-label">アーティスト:</span> <a href="http://d.hatena.ne.jp/keyword/Genesis" class="keyword">Genesis</a></li> <li><span class="hatena-asin-detail-label">出版社/メーカー:</span> <a href="http://d.hatena.ne.jp/keyword/Virgin%20Catalogue" class="keyword">Virgin Catalogue</a></li> <li><span class="hatena-asin-detail-label">発売日:</span> 2007/10/01</li> <li><span class="hatena-asin-detail-label">メディア:</span> MP3 ダウンロード</li> <li><a href="http://d.hatena.ne.jp/asin/B0045S6NMC" target="_blank">この商品を含むブログを見る</a></li> </ul> </div> <div class="hatena-asin-detail-foot"></div> </div></div></p> aike 片手間のJavaScriptでもテストがしたい! hatenablog://entry/10257846132645781041 2014-08-01T00:00:00+09:00 2014-08-01T00:00:00+09:00 テストしたくないでござる。テストしたくないでござる。 いやまあきちんと環境が整ってたらテスト書くのもわりと楽だし、プログラム本体書いているときの安心感が全然違うので、それなりの規模のプログラムを書く時は良いんだけど。でも、2〜3日で書くようなちょっとしたブラウザ側だけのJavaScriptプログラムとか、開発環境がインストールされていないPCでも気軽にテストできないかなあというのが今回のテーマ。 これだけメジャーなJavaScriptなんだからテストも簡単だろうと思って調べると、ブログとかのサンプルを見てもNode.js前提だったり、Mochaが良さそうだと使おうとしたらアサーションライブラリ… <p>テストしたくないでござる。テストしたくないでござる。<br /> いやまあきちんと環境が整ってたらテスト書くのもわりと楽だし、プログラム本体書いているときの安心感が全然違うので、それなりの規模のプログラムを書く時は良いんだけど。でも、2〜3日で書くようなちょっとしたブラウザ側だけの<a class="keyword" href="http://d.hatena.ne.jp/keyword/JavaScript">JavaScript</a>プログラムとか、開発環境がインストールされていないPCでも気軽にテストできないかなあというのが今回のテーマ。<br />  <br /> これだけメジャーな<a class="keyword" href="http://d.hatena.ne.jp/keyword/JavaScript">JavaScript</a>なんだからテストも簡単だろうと思って調べると、ブログとかのサンプルを見てもNode.js前提だったり、Mochaが良さそうだと使おうとしたら<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%B5%A1%BC%A5%B7%A5%E7%A5%F3">アサーション</a>ライブラリは別だとか、UIはbrowserifyいるの?いらないの?とか、もじゃもじゃしたヤクの毛にからまって必死で刈り進める感じ。テスト初心者の人にテストコードの書き方を説明するときなんか、たどりつくまでがすごく遠い。<br />  <br /> そんなわけで、インストール不要でconsole.logのすごい版みたいな感じにプリント<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%D0%A5%C3%A5%B0">デバッグ</a>おじさんでも気軽に使える、シンプルな<a class="keyword" href="http://d.hatena.ne.jp/keyword/JavaScript">JavaScript</a>テストのサンプルを作ってみました。<br />  <br /> <a href="https://github.com/aike/MinimumJsTest">https://github.com/aike/MinimumJsTest</a><br />  <br /> 仕様はこんな感じ。<br /> ・ウェブブラウザ上でテストを実施<br /> ・Mocha + <a class="keyword" href="http://d.hatena.ne.jp/keyword/Chai">Chai</a> を使用<br /> ・Node.js、npm、Webサーバ、その他ツールのインストール不要<br /> ・Node.jsに依存する機能・ライブラリは使えません<br />  <br /> 調べてみると、とりあえず最低限 mocha.js、mocha.<a class="keyword" href="http://d.hatena.ne.jp/keyword/css">css</a>、<a class="keyword" href="http://d.hatena.ne.jp/keyword/chai">chai</a>.js の3ファイルだけあればブラウザを使ってテストができそうです。なので、外部ライブラリで使うのはそれらと<a class="keyword" href="http://d.hatena.ne.jp/keyword/jQuery">jQuery</a>のみとします。<br />  </p> <pre class="code lang-html" data-lang="html" data-unlink><span class="synComment">&lt;!DOCTYPE html&gt;</span> <span class="synIdentifier">&lt;</span><span class="synStatement">html</span><span class="synIdentifier">&gt;</span> <span class="synIdentifier">&lt;</span><span class="synStatement">head</span><span class="synIdentifier">&gt;</span> <span class="synPreProc"> </span><span class="synIdentifier">&lt;</span><span class="synStatement">meta</span><span class="synIdentifier"> </span><span class="synType">charset</span><span class="synIdentifier">=</span><span class="synConstant">&quot;utf-8&quot;</span><span class="synIdentifier"> /&gt;</span> <span class="synPreProc"> </span><span class="synIdentifier">&lt;</span><span class="synStatement">title</span><span class="synIdentifier">&gt;</span>minimum javascript test example<span class="synIdentifier">&lt;/</span><span class="synStatement">title</span><span class="synIdentifier">&gt;</span> <span class="synPreProc"> </span><span class="synComment">&lt;!-- 汎用ライブラリ --&gt;</span> <span class="synPreProc"> </span><span class="synIdentifier">&lt;</span><span class="synStatement">script</span><span class="synIdentifier"> </span><span class="synType">src</span><span class="synIdentifier">=</span><span class="synConstant">&quot;jquery-2.0.3.min.js&quot;</span><span class="synIdentifier">&gt;&lt;/</span><span class="synStatement">script</span><span class="synIdentifier">&gt;</span> <span class="synPreProc"> </span><span class="synComment">&lt;!-- テストフレームワーク --&gt;</span> <span class="synPreProc"> </span><span class="synIdentifier">&lt;</span><span class="synStatement">link</span><span class="synIdentifier"> </span><span class="synType">rel</span><span class="synIdentifier">=</span><span class="synConstant">&quot;stylesheet&quot;</span><span class="synIdentifier"> </span><span class="synType">href</span><span class="synIdentifier">=</span><span class="synConstant">&quot;test/mocha.css&quot;</span><span class="synIdentifier"> /&gt;</span> <span class="synPreProc"> </span><span class="synIdentifier">&lt;</span><span class="synStatement">script</span><span class="synIdentifier"> </span><span class="synType">src</span><span class="synIdentifier">=</span><span class="synConstant">&quot;test/mocha.js&quot;</span><span class="synIdentifier">&gt;&lt;/</span><span class="synStatement">script</span><span class="synIdentifier">&gt;</span> <span class="synPreProc"> </span><span class="synIdentifier">&lt;</span><span class="synStatement">script</span><span class="synIdentifier"> </span><span class="synType">src</span><span class="synIdentifier">=</span><span class="synConstant">&quot;test/chai.js&quot;</span><span class="synIdentifier">&gt;&lt;/</span><span class="synStatement">script</span><span class="synIdentifier">&gt;</span> <span class="synPreProc"> </span><span class="synComment">&lt;!-- テスト対象プログラム --&gt;</span> <span class="synPreProc"> </span><span class="synIdentifier">&lt;</span><span class="synStatement">script</span><span class="synIdentifier"> </span><span class="synType">src</span><span class="synIdentifier">=</span><span class="synConstant">&quot;main.js&quot;</span><span class="synIdentifier">&gt;&lt;/</span><span class="synStatement">script</span><span class="synIdentifier">&gt;</span> <span class="synPreProc"> </span><span class="synComment">&lt;!-- テスト本体 --&gt;</span> <span class="synPreProc"> </span><span class="synIdentifier">&lt;</span><span class="synStatement">script</span><span class="synIdentifier"> </span><span class="synType">src</span><span class="synIdentifier">=</span><span class="synConstant">&quot;test/test.js&quot;</span><span class="synIdentifier">&gt;&lt;/</span><span class="synStatement">script</span><span class="synIdentifier">&gt;</span> <span class="synIdentifier">&lt;/</span><span class="synStatement">head</span><span class="synIdentifier">&gt;</span> <span class="synIdentifier">&lt;</span><span class="synStatement">body</span><span class="synIdentifier">&gt;</span> <span class="synComment">&lt;!-- テスト結果出力用エレメント --&gt;</span> <span class="synIdentifier">&lt;</span><span class="synStatement">div</span><span class="synIdentifier"> </span><span class="synType">id</span><span class="synIdentifier">=</span><span class="synConstant">&quot;mocha&quot;</span><span class="synIdentifier">&gt;&lt;/</span><span class="synStatement">div</span><span class="synIdentifier">&gt;</span> <span class="synComment">&lt;!-- アプリ本体のエレメント --&gt;</span> <span class="synIdentifier">&lt;</span><span class="synStatement">div</span><span class="synIdentifier"> </span><span class="synType">id</span><span class="synIdentifier">=</span><span class="synConstant">&quot;message&quot;</span><span class="synIdentifier">&gt;&lt;/</span><span class="synStatement">div</span><span class="synIdentifier">&gt;</span> <span class="synIdentifier">&lt;/</span><span class="synStatement">body</span><span class="synIdentifier">&gt;</span> <span class="synIdentifier">&lt;/</span><span class="synStatement">html</span><span class="synIdentifier">&gt;</span> </pre><p> <br /> テスト対象の関数はたとえばこんな感じ。</p> <pre class="code lang-javascript" data-lang="javascript" data-unlink><span class="synComment">// main.js</span> <span class="synComment">//// 引数で受け取った文字列をid=&quot;message&quot;のエレメントに挿入する関数</span> <span class="synIdentifier">function</span> say(s) <span class="synIdentifier">{</span> $(<span class="synConstant">'#message'</span>).text(s); <span class="synIdentifier">}</span> </pre><p> <br /> それに対するテストコードはこんな感じ。</p> <pre class="code lang-javascript" data-lang="javascript" data-unlink><span class="synComment">// test.js</span> $(<span class="synIdentifier">function</span>() <span class="synIdentifier">{</span> <span class="synComment">//// テストの設定</span> chai.should(); mocha.setup(<span class="synConstant">'bdd'</span>); <span class="synComment">///// テスト本体</span> describe(<span class="synConstant">'メッセージ出力のテスト'</span>, <span class="synIdentifier">function</span>() <span class="synIdentifier">{</span> it (<span class="synConstant">'引数で指定したメッセージが出力されること'</span>, <span class="synIdentifier">function</span>() <span class="synIdentifier">{</span> say(<span class="synConstant">'Hello, world!'</span>); $(<span class="synConstant">'#message'</span>).text().should.equal(<span class="synConstant">'Hello, world!'</span>); <span class="synIdentifier">}</span>); it (<span class="synConstant">'非同期でもメッセージが出力されること'</span>, <span class="synIdentifier">function</span>(done) <span class="synIdentifier">{</span> setTimeout(<span class="synIdentifier">function</span>() <span class="synIdentifier">{</span> say(<span class="synConstant">'こんにちはこんにちは!!'</span>); $(<span class="synConstant">'#message'</span>).text().should.equal(<span class="synConstant">'こんにちはこんにちは!!'</span>); done(); <span class="synIdentifier">}</span>, 100); <span class="synIdentifier">}</span>); <span class="synIdentifier">}</span>); <span class="synComment">//// テスト実行</span> mocha.run(); <span class="synIdentifier">}</span>); </pre><p> <br /> 実行結果<p><a href="http://f.hatena.ne.jp/aike/20140801195755" class="hatena-fotolife" target="_blank"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20140801/20140801195755.png" alt="f:id:aike:20140801195755p:image" title="f:id:aike:20140801195755p:image" class="hatena-fotolife" style="border: solid 1px #888888;"></a></p> <br /> テスト実行用アプリは必要に応じて後からちゃんと作ったりするとして、とりあえずざっくり書いたターゲットアプリのindex.htmlでテストを読み込んで実行するような利用イメージです。<br />  <br /> ターゲットアプリのレイアウトが崩れて問題があるなら、こんなコードを追加するとテスト結果のウィンドウがオーバーラップしてるみたいな表示になります。</p> <pre class="code lang-javascript" data-lang="javascript" data-unlink><span class="synComment">//// テストの出力をウィンドウっぽく表示 </span> $(<span class="synConstant">'#mocha'</span>) .css(<span class="synIdentifier">{</span> position: <span class="synConstant">'absolute'</span>, <span class="synStatement">top</span>: 10, right: 20, width: 400, bottom: 20, margin: 0, paddingTop: 50, overflow: <span class="synConstant">'scroll'</span>, backgroundColor: <span class="synConstant">'#ddd'</span>, boxShadow: <span class="synConstant">'8px 8px 8px rgba(0,0,0,0.3)'</span>, zIndex: 1000 <span class="synIdentifier">}</span>) setTimeout(<span class="synIdentifier">function</span>() <span class="synIdentifier">{</span> $(<span class="synConstant">'#mocha-stats'</span>) .css(<span class="synIdentifier">{</span> position: <span class="synConstant">'absolute'</span>, <span class="synStatement">top</span>: 5, left: 2, width: 400, height: 40, backgroundColor: <span class="synConstant">'#ddd'</span>, zIndex: 1000 <span class="synIdentifier">}</span>); <span class="synIdentifier">}</span>, 100); </pre><p> <br /> 実行結果<p><a href="http://f.hatena.ne.jp/aike/20140801195756" class="hatena-fotolife" target="_blank"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20140801/20140801195756.png" alt="f:id:aike:20140801195756p:image" title="f:id:aike:20140801195756p:image" class="hatena-fotolife" style="border: solid 1px #888888;"></a></p> <br /> おしまい</p> aike 全天球パノラマ動画を表示するJavaScriptライブラリ作った hatenablog://entry/10257846132645781087 2014-07-26T00:00:00+09:00 2014-07-26T00:00:00+09:00 複数台のGoProを組み合わせて360度上も下も撮影できる動画カメラが一部で流行りつつあるようです。 こんなやつ。 http://home360.co.jp/freedom360.html http://freedom360.us/ 要はRICOH THETAの動画版なんですが、動画ということで機材の価格もだいぶ違うし、複数の動画を合成する作業もまだまだけっこう手間も時間もかかります。 そこまで頑張って動画を作っても、公開がまた大変です。フリーのスタンドアロンプレイヤーはありますが(これとか)、見る人にインストールさせるのはちょっと面倒だし、Flashで作られた全天球動画プレイヤーも良いものが… <p>複数台のGoProを組み合わせて360度上も下も撮影できる動画カメラが一部で流行りつつあるようです。<br /> こんなやつ。<br /> <a href="http://home360.co.jp/freedom360.html">http://home360.co.jp/freedom360.html</a><br /> <a href="http://freedom360.us/">http://freedom360.us/</a><br />  <br /> 要は<a class="keyword" href="http://d.hatena.ne.jp/keyword/RICOH%20THETA">RICOH THETA</a>の動画版なんですが、動画ということで機材の価格もだいぶ違うし、複数の動画を合成する作業もまだまだけっこう手間も時間もかかります。<br />  <br /> そこまで頑張って動画を作っても、公開がまた大変です。フリーの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%BF%A5%F3%A5%C9%A5%A2%A5%ED%A5%F3">スタンドアロン</a>プレイヤーはありますが(<a href="http://www.kolor.com/360-video/kolor-eyes-desktop-free-360-video-player.html">&#x3053;&#x308C;&#x3068;&#x304B;</a>)、見る人にインストールさせるのはちょっと面倒だし、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Flash">Flash</a>で作られた全天球動画プレイヤーも良いものがいろいろあるものの、自由にダウンロードできて自分のサイトで手軽に使えるものは今はちょっとなさそうです。<br />  <br /> そんなわけで<a class="keyword" href="http://d.hatena.ne.jp/keyword/JavaScript">JavaScript</a>のThree.jsを使ってさくっと全天球動画プレイヤーを作ってみました。<br />  <br /> <span class="deco" style="font-size:x-large;"><a href="http://sound.jp/aike/paview/">http://sound.jp/aike/paview/</a></span><br /> <span class="deco" style="font-size:x-large;"><a href="https://github.com/aike/paview.js">https://github.com/aike/paview.js</a></span></p><p><p><a href="http://sound.jp/aike/paview/" class="hatena-fotolife" target="_blank"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20140726/20140726233151.png" alt="クリックでデモページへ移動" title="クリックでデモページへ移動" class="hatena-fotolife"></a></p>音が出ます。<a class="keyword" href="http://d.hatena.ne.jp/keyword/Chrome">Chrome</a>推奨、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Firefox">Firefox</a>不可、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Safari">Safari</a>は<a class="keyword" href="http://d.hatena.ne.jp/keyword/WebGL">WebGL</a>を有効にする必要があるかも。<br />  <br /> ドラッグしてカメラの向きを変えたり、ホイールでズームしたりできます。水平の調整やファーストビューの指定もできます。シンプルな作りだし、MITライセンスなので自由に改変して使ってください。<br />  <br /> ※ついでに前回つくった<a href="http://d.hatena.ne.jp/aike/20140102">RICOH THETA&#x753B;&#x50CF;&#x8868;&#x793A;&#x7528;JavaScript&#x30E9;&#x30A4;&#x30D6;&#x30E9;&#x30EA;</a>の方もドラッグでカメラ向きを変えられるようにしました。</p> aike RICOH THETA画像を表示するJavaScriptライブラリ作った hatenablog://entry/10257846132645781096 2014-01-02T00:00:00+09:00 2014-01-02T00:00:00+09:00 絶賛通常営業中。 普段からいろいろプログラムは作っているもののこのところ仕事が立て込んでいてブログが全然書けなかったので休み中に棚卸し的に書いていきます。 RICOH THETAの画像を公開するとなると公式サイトに上げるのが普通なんですがやっぱりそれなりに不満点もあって、全公開になってしまうとか、ファーストビューが指定できないとか、顔や見せたくないところを加工してから公開したいとかそういうことがやりにくくてアップに躊躇したりということもあったり。 そんなわけで、とりあえず自サイトに上げて表示できるようなライブラリをThree.jsを使って作ってみました。まだまだ機能は少ないですが徐々に改善する… <p>絶賛通常営業中。<br /> 普段からいろいろプログラムは作っているもののこのところ仕事が立て込んでいてブログが全然書けなかったので休み中に棚卸し的に書いていきます。<br />  <br /> <a class="keyword" href="http://d.hatena.ne.jp/keyword/RICOH%20THETA">RICOH THETA</a>の画像を公開するとなると公式サイトに上げるのが普通なんですがやっぱりそれなりに不満点もあって、全公開になってしまうとか、ファーストビューが指定できないとか、顔や見せたくないところを加工してから公開したいとかそういうことがやりにくくてアップに躊躇したりということもあったり。<br />  <br /> そんなわけで、とりあえず自サイトに上げて表示できるようなライブラリをThree.jsを使って作ってみました。まだまだ機能は少ないですが徐々に改善する予定です。<br />  <br /> 本当は<a class="keyword" href="http://d.hatena.ne.jp/keyword/JavaScript">JavaScript</a>で書けばPCでも<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%DE%A5%DB">スマホ</a>でも同じように見せられるかと思って作ったんですが<a class="keyword" href="http://d.hatena.ne.jp/keyword/iOS">iOS</a>のブラウザは<a class="keyword" href="http://d.hatena.ne.jp/keyword/WebGL">WebGL</a>をフルサポートしてないみたいでだめでした。あと、PCでも現行の<a class="keyword" href="http://d.hatena.ne.jp/keyword/Safari">Safari</a>はなぜかデフォルトで<a class="keyword" href="http://d.hatena.ne.jp/keyword/WebGL">WebGL</a>が無効になっているようでなんだかいろいろがっかりです。このライブラリは人類にはまだ早すぎたのかもしれません。<br />  <br /> ■デモサイト<br /> <a href="http://aikelab.net/thview/">http://aikelab.net/thview/</a><br />  </p><p>■機能と制限<br /> 自サイトにアップした全天球画像を表示します。<br /> 転送速度やプライバシーなどの理由で元画像を縮小しても表示できます。<br /> 元画像サイズに関わらず表示エリアの縦横サイズを指定できます。<br /> ファーストビュー、ズーム、自動回転の有無、回転速度などを細かく指定できます。<br /> <del datetime="2014-07-26T22:01:08+09:00">ドラッグして向きを変えることはできません(今のところ)。</del><br /> <del datetime="2014-07-26T22:01:08+09:00">カメラを上下に動かして空や地面を見ることはできません(今のところ)。逆に自分が見えなくて良いかも。</del><br /> 自動で水平を補正することはできません。手動で補正することは可能です。<br /> 画像は同じサーバ(Same Origin)にある必要があります。そんなわけで<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A4%CF%A4%C6%A4%CA%A5%C0%A5%A4%A5%A2%A5%EA%A1%BC">はてなダイアリー</a>には埋め込めないです。<br /> PCの<a class="keyword" href="http://d.hatena.ne.jp/keyword/Chrome">Chrome</a>や<a class="keyword" href="http://d.hatena.ne.jp/keyword/Firefox">Firefox</a>だと良い感じに見えます。それ以外の環境だといろいろアレな感じ。<br />  <br /> まあ見ての通り実質50行くらいのライブラリなので気になるところがあれば好きに改造してください。<br />  <br /> ■埋め込み方<br /> シンプルな例</p> <pre class="code lang-html" data-lang="html" data-unlink><span class="synIdentifier">&lt;</span><span class="synStatement">div</span><span class="synIdentifier"> </span><span class="synType">id</span><span class="synIdentifier">=</span><span class="synConstant">&quot;ph1&quot;</span><span class="synIdentifier">&gt;&lt;/</span><span class="synStatement">div</span><span class="synIdentifier">&gt;</span> <span class="synIdentifier">&lt;</span><span class="synStatement">script</span><span class="synIdentifier"> </span><span class="synType">type</span><span class="synIdentifier">=</span><span class="synConstant">&quot;text/javascript&quot;</span><span class="synIdentifier"> &gt;</span> <span class="synSpecial"> </span><span class="synIdentifier">var</span><span class="synSpecial"> img1 = </span><span class="synStatement">new</span><span class="synSpecial"> ThView</span>(<span class="synIdentifier">{</span><span class="synSpecial">id:</span><span class="synConstant">'ph1'</span><span class="synSpecial">, file:</span><span class="synConstant">'photo.jpg'</span><span class="synIdentifier">}</span>)<span class="synSpecial">;</span> <span class="synIdentifier">&lt;/</span><span class="synStatement">script</span><span class="synIdentifier">&gt;</span> </pre><p>オプション指定付きの埋め込み例</p> <pre class="code lang-html" data-lang="html" data-unlink><span class="synIdentifier">&lt;</span><span class="synStatement">div</span><span class="synIdentifier"> </span><span class="synType">id</span><span class="synIdentifier">=</span><span class="synConstant">&quot;ph2&quot;</span><span class="synIdentifier">&gt;&lt;/</span><span class="synStatement">div</span><span class="synIdentifier">&gt;</span> <span class="synIdentifier">&lt;</span><span class="synStatement">script</span><span class="synIdentifier"> </span><span class="synType">type</span><span class="synIdentifier">=</span><span class="synConstant">&quot;text/javascript&quot;</span><span class="synIdentifier"> &gt;</span> <span class="synSpecial"> </span><span class="synIdentifier">var</span><span class="synSpecial"> img2 = </span><span class="synStatement">new</span><span class="synSpecial"> ThView</span>(<span class="synIdentifier">{</span> <span class="synSpecial"> id:</span><span class="synConstant">'ph2'</span><span class="synSpecial">,</span> <span class="synSpecial"> file:</span><span class="synConstant">'photo2.jpg'</span><span class="synSpecial">,</span> <span class="synSpecial"> firstview:</span>180<span class="synSpecial">,</span> <span class="synSpecial"> zoom:</span>100<span class="synSpecial">,</span> <span class="synSpecial"> width:</span>300<span class="synSpecial">,</span> <span class="synSpecial"> height:</span>200<span class="synSpecial">,</span> <span class="synSpecial"> rotation:</span><span class="synConstant">true</span><span class="synSpecial">,</span> <span class="synSpecial"> speed:</span>-30<span class="synIdentifier">}</span>)<span class="synSpecial">;</span> <span class="synIdentifier">&lt;/</span><span class="synStatement">script</span><span class="synIdentifier">&gt;</span> </pre><p> <br /> ■オプション一覧</p> <table> <tr> <th>キーワード</th> <th>意味</th> </tr> <tr> <td>id</td> <td>親エレメント(DIV)のID (必須)</td> </tr> <tr> <td>file</td> <td>画像ファイル名 (必須)</td> </tr> <tr> <td>width</td> <td>幅の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D4%A5%AF%A5%BB%A5%EB">ピクセル</a>数</td> </tr> <tr> <td>height</td> <td>縦の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D4%A5%AF%A5%BB%A5%EB">ピクセル</a>数</td> </tr> <tr> <td>rotation</td> <td>自動回転の有無</td> </tr> <tr> <td>speed</td> <td>回転速度(負の値で反対方向へ回転)</td> </tr> <tr> <td>zoom</td> <td>ズーム</td> </tr> <tr> <td>firstview</td> <td>初期表示位置</td> </tr> <tr> <td>degree</td> <td>軸の角度調整 [x, y, z]</td> </tr> </table><p> <br /> ■<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%BD%A1%BC%A5%B9%A5%B3%A1%BC%A5%C9">ソースコード</a><br /> <a href="https://github.com/aike/thview.js">https://github.com/aike/thview.js</a><br />  <br /> 2014.07.26 追記<br /> ドラッグして上下左右好きな方向を向けるようにしました</p> aike Web Audio APIとWeb MIDI APIでパターンシーケンサー風楽器作った hatenablog://entry/10257846132645781145 2013-11-18T00:00:00+09:00 2013-11-18T00:00:00+09:00 Web Audio APIとWeb MIDI APIの応用例として楽器を作ってみました。 適当にボタンを押すだけでもそれっぽい曲になるので遊んでみてください。 http://aikelab.net/webrhy/ http://github.com/aike/webrhy 僕はYouTubeのDenkitribeさんやBakaOscillatorさんのパフォーマンスが大好きなんですが、あの域に達するにはそれなりの技術とアレンジ能力が必要でなかなか真似できるものではありません。 でも、このアプリをつかうと、わりとそれっぽい演奏が楽しめます。 それぞれのボタンにはパターンがわりあてられています。適… <p>Web Audio <a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>とWeb <a class="keyword" href="http://d.hatena.ne.jp/keyword/MIDI">MIDI</a> <a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>の応用例として楽器を作ってみました。<br /> 適当にボタンを押すだけでもそれっぽい曲になるので遊んでみてください。<br />  <br /> <a href="http://aikelab.net/webrhy/">http://aikelab.net/webrhy/</a><br /> <a href="http://github.com/aike/webrhy">http://github.com/aike/webrhy</a><br /> <p><a href="http://aikelab.net/webrhy/" class="hatena-fotolife" target="_blank"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20131118/20131118235822.png" alt="Webrhy" title="Webrhy" class="hatena-fotolife"></a></p> <br /> 僕は<a class="keyword" href="http://d.hatena.ne.jp/keyword/YouTube">YouTube</a>の<a href="http://www.youtube.com/user/Denkitribe/videos">Denkitribe&#x3055;&#x3093;</a>や<a href="http://www.youtube.com/user/BakaOscillator/videos">BakaOscillator&#x3055;&#x3093;</a>のパフォーマンスが大好きなんですが、あの域に達するにはそれなりの技術とアレンジ能力が必要でなかなか真似できるものではありません。<br />  <br /> でも、このアプリをつかうと、わりとそれっぽい演奏が楽しめます。<br />  <br /> <iframe width="420" height="315" src="http://www.youtube.com/embed/MDdGhQRNrxc?wmode=transparent" frameborder="0" allowfullscreen></iframe><br />  <br /> それぞれのボタンにはパターンがわりあてられています。適当でかまわないのでリアルタイムにどんどん選んでいってください。なんとなく曲っぽくなるかと思います。慣れてきたら曲の展開や盛り上がりをつくったりもできます。ライブ演奏指向のアプリのため、パターンの並びをソングとしてあらかじめ組むことはできません(いまのところ)。<br />  <br /> パターンは自作するのではなく、完全にランダムに生成されます。とはいえ、変な音にならないよういろいろ工夫しています。<br /> シンセとベースは主和音や関連和音から音を選んだ単音フレーズにして、音がぶつからずに聞けるようにしています。シンセの方は、アクセント的にスケール音から生成したパターンをおりまぜています。<br /> 左端のパターン0はミュートです。その隣のパターン1はかならず主和音であるAmになるようにしたので、ちょっとカオスな感じになってきたらこのボタンを押すと落ち着いた感じに戻ります。<br />  <br /> ドラムは、表拍の四分音符は必ずキックを鳴らして四つ打ちはくずさないようにしています。その上で右側に行くほど手数が増えて盛り上がるようなフレーズにしています。一番右端のパターンはスネアを連打する<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D5%A5%A3%A5%EB%A5%A4%A5%F3">フィルイン</a>になっています。<br />  <br /> その他、ショートカットキーとして[ESC]と[RETURN]は全ミュートになります。さんざん盛り上げて、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D5%A5%A3%A5%EB%A5%A4%A5%F3">フィルイン</a>→全ミュートみたいにするとエンディングっぽくなります。<br />  <br /> 音源としては、あらかじめ内蔵されているWeb Audio <a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>を使ったシンセ音源の他、Web <a class="keyword" href="http://d.hatena.ne.jp/keyword/MIDI">MIDI</a> <a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>で<a class="keyword" href="http://d.hatena.ne.jp/keyword/MIDI">MIDI</a>接続した外部音源も使用できます。<br />  <br /> <iframe width="420" height="315" src="http://www.youtube.com/embed/AvNThR9h5tY?wmode=transparent" frameborder="0" allowfullscreen></iframe><br />  <br /> ウェブオーディオ/<a class="keyword" href="http://d.hatena.ne.jp/keyword/MIDI">MIDI</a>の大きな可能性として、ライブパフォーマンスへの応用があると思っています。おそらく本格的なレコーディング品質のアプリが出そろうにはまだ少し時間がかかり、その前に<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ableton%20Live">Ableton Live</a>や<a class="keyword" href="http://d.hatena.ne.jp/keyword/KORG">KORG</a> <a class="keyword" href="http://d.hatena.ne.jp/keyword/ELECTRIBE">ELECTRIBE</a>、volcaのような楽器と打ち込みの中間的な存在や、VJとの連携といったあたりにWebアプリが得意な分野があるような気がしています。</p> aike Web MIDI APIを使ってMIDI鍵盤からブラウザコントロール hatenablog://entry/10257846132645781157 2013-11-09T00:00:00+09:00 2013-11-09T00:00:00+09:00 ウェブブラウザにWeb MIDI APIが少しずつ実装されてきて、Mac OS XのChrome Canary版だとプラグインなしで普通に使えるくらいになってきました。 Web MIDI APIを使うとJavaScriptでさまざまなハードウェア音源を鳴らすことができます。ただそれは一側面に過ぎず、重要なのはウェブブラウザ(JavaScript)がついにリアルワールドとつながったということです。WebRTCもウェブと現実世界をつなげる技術ではありますが、MIDIはなにしろ30年も歴史があって、そのシンプルなプロトコル仕様ゆえに当初の演奏情報以外のコントロールにもいろいろ汎用的に使われてたりもし… <p>ウェブブラウザにWeb <a class="keyword" href="http://d.hatena.ne.jp/keyword/MIDI">MIDI</a> <a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>が少しずつ実装されてきて、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Mac%20OS%20X">Mac OS X</a>の<a class="keyword" href="http://d.hatena.ne.jp/keyword/Chrome">Chrome</a> Canary版だと<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>なしで普通に使えるくらいになってきました。<br />  <br /> Web <a class="keyword" href="http://d.hatena.ne.jp/keyword/MIDI">MIDI</a> <a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>を使うと<a class="keyword" href="http://d.hatena.ne.jp/keyword/JavaScript">JavaScript</a>でさまざまなハードウェア音源を鳴らすことができます。ただそれは一側面に過ぎず、重要なのはウェブブラウザ(<a class="keyword" href="http://d.hatena.ne.jp/keyword/JavaScript">JavaScript</a>)がついにリアルワールドとつながったということです。WebRTCもウェブと現実世界をつなげる技術ではありますが、<a class="keyword" href="http://d.hatena.ne.jp/keyword/MIDI">MIDI</a>はなにしろ30年も歴史があって、そのシンプルな<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%ED%A5%C8%A5%B3%A5%EB">プロトコル</a>仕様ゆえに当初の演奏情報以外のコン<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C8%A5%ED%A1%BC%A5%EB">トロール</a>にもいろいろ汎用的に使われてたりもします。<br />  <br /> また、Web <a class="keyword" href="http://d.hatena.ne.jp/keyword/MIDI">MIDI</a> <a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>は電子楽器を制御して音を鳴らすだけでなく、<a class="keyword" href="http://d.hatena.ne.jp/keyword/MIDI">MIDI</a>鍵盤や<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%BF%A1%BC%A5%F3%A5%C6%A1%BC%A5%D6%A5%EB">ターンテーブル</a>型のDJコントローラーのようなハードウェアからの入力を受け付けることができます。ということは、ウェブブラウザを操作することができる膨大なフィジカルコントローラーを手に入れたことになります。しかもそれらは何百年もの人間工学的な蓄積によって操作性が洗練されていて、またライブツアーのようなタフな使われ方にも対応できるだけの耐久性を持っています。<br />  <br /> そんな可能性の一端を示すウェブページを作ってみました。<br />  <br /> <span class="deco" style="font-size:large;"><a href="http://aikelab.net/midizap/">http://aikelab.net/midizap/</a></span></p><p><p><a href="http://aikelab.net/midizap/" class="hatena-fotolife" target="_blank"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20131110/20131110012619.png" alt="http://aikelab.net/midizap/" title="http://aikelab.net/midizap/" class="hatena-fotolife"></a></p> <br /> Web <a class="keyword" href="http://d.hatena.ne.jp/keyword/MIDI">MIDI</a> <a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>が使用できる環境で、<a class="keyword" href="http://d.hatena.ne.jp/keyword/MIDI">MIDI</a>鍵盤をつないで弾いてみてください。「ド」の鍵盤を押すとドーナツのページが開き、「レ」の場合はレモンのページが開き、「ミ」はみんなのページが開き……、という風にブラウザをコン<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C8%A5%ED%A1%BC%A5%EB">トロール</a>します。<br />  <br /> <span class="deco" style="font-size:x-small;">※Web <a class="keyword" href="http://d.hatena.ne.jp/keyword/MIDI">MIDI</a> <a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>が使えない場合、画面上の白鍵をクリックしても一応動くようにはしてあります。</span><br />  <br /> まだまだテスト的なページですが、この先に何か多くの可能性があるような気がして楽しみです。</p> aike ツクツクホーシにギターとベースとドラムを重ねてみた hatenablog://entry/10257846132645781169 2013-09-21T00:00:00+09:00 2013-09-21T00:00:00+09:00 もう夏も終わりな感じであれですが。少し前にツクツクホーシのサビの部分がどうのとか鳴き声が「おじいちゃん!」に聞こえるとかちょっと話題になって、じっくり聞いてみたもののよくわかりませんでした。 僕からしてみればあれはどうみてもメロスピのギターリフに聞こえるんですが、言葉で言っても伝わらないと思うのでバッキングを重ねてみました。聞いてください。 メンバー紹介 リードギター ツクツクホーシ(テンポ、ピッチ、エフェクト等加工なし) バックギター KONTAKT5 + PG01 ベース KONTAKT5 + SCARBEE MM BASS ドラム EZ Drummer + dfh <p>もう夏も終わりな感じであれですが。少し前に<a href="http://blog.livedoor.jp/nanjnan/archives/32076752.html">&#x30C4;&#x30AF;&#x30C4;&#x30AF;&#x30DB;&#x30FC;&#x30B7;&#x306E;&#x30B5;&#x30D3;&#x306E;&#x90E8;&#x5206;&#x304C;&#x3069;&#x3046;&#x306E;</a>とか<a href="https://twitter.com/narupon/status/378682578447790081">&#x9CF4;&#x304D;&#x58F0;&#x304C;&#x300C;&#x304A;&#x3058;&#x3044;&#x3061;&#x3083;&#x3093;&#xFF01;&#x300D;&#x306B;&#x805E;&#x3053;&#x3048;&#x308B;</a>とかちょっと話題になって、じっくり聞いてみたもののよくわかりませんでした。<br />  <br /> 僕<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A4%AB%A4%E9%A4%B7">からし</a>てみればあれはどうみても<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E1%A5%ED%A5%B9%A5%D4">メロスピ</a>のギターリフに聞こえるんですが、言葉で言っても伝わらないと思うのでバッキングを重ねてみました。聞いてください。</p><br /> <p>メンバー紹介<br />  <a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EA%A1%BC%A5%C9%A5%AE%A5%BF%A1%BC">リードギター</a> ツクツクホーシ(テンポ、ピッチ、エフェクト等加工なし)<br />  バックギター KONTAKT5 + <a href="http://www.dlmarket.jp/product_info.php/products_id/139440/language/ja">PG01</a><br />  ベース KONTAKT5 + SCARBEE MM BASS<br />  ドラム EZ Drummer + dfh</p><br /> <p><script type="text/javascript" src="https://embed.nicovideo.jp/watch/sm21876367/script"></script></p> aike 明日また来てください、本物のExcel方眼紙をお見せしますよ hatenablog://entry/10257846132645781180 2013-09-19T00:00:00+09:00 2013-09-19T00:00:00+09:00 「俺はェスァイ」 「SIって?」 「お客様のビジネスに最適なソリューションをインテグレートするんだ」 「でたっ、富士通っぽいことば!!」 「標準機能を組み合わせたパッケージは使いにくいからだよっ!!」 ドス、ドス、ドス、バッ 「この仕様書を作ったのは誰だあっ!!」 「Excelの文書がなにかございましたか」 「なぜセルをこんなに細かくした!!計算など必要のない連中がスプレッドシートを使うからだ。馬鹿どもにExcelを与えるな」 「ははっ」 「そんなことを言うからには、文字やフォームを任意のグリッドにレイアウトできて、顧客も当然のように文書ファイルを開けるソフトウェアがいろいろあるんだろうな」 … <p>「俺はェスァイ」<br /> 「SIって?」<br /> 「お客様のビジネスに最適なソリューションをインテグレートするんだ」<br /> 「でたっ、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C9%D9%BB%CE%C4%CC">富士通</a>っぽいことば!!」<br /> 「標準機能を組み合わせたパッケージは使いにくいからだよっ!!」</p><br /> <p>ドス、ドス、ドス、バッ<br /> 「この仕様書を作ったのは誰だあっ!!」<br /> 「<a class="keyword" href="http://d.hatena.ne.jp/keyword/Excel">Excel</a>の文書がなにかございましたか」<br /> 「なぜセルをこんなに細かくした!!計算など必要のない連中が<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%D7%A5%EC%A5%C3%A5%C9%A5%B7%A1%BC%A5%C8">スプレッドシート</a>を使うからだ。馬鹿どもに<a class="keyword" href="http://d.hatena.ne.jp/keyword/Excel">Excel</a>を与えるな」<br /> 「ははっ」</p><br /> <p>「そんなことを言うからには、文字やフォームを任意のグリッドにレイアウトできて、顧客も当然のように文書ファイルを開けるソフトウェアがいろいろあるんだろうな」<br /> 「ぐぬう」<br /> 「<a class="keyword" href="http://d.hatena.ne.jp/keyword/Excel">Excel</a>方眼紙は帳票デザインが大きな割合を占める日本の業態に即したものなんだ」<br /> 「とはいえ俺も一般的な<a class="keyword" href="http://d.hatena.ne.jp/keyword/Excel">Excel</a>方眼紙が最良とは思わない」<br /> 「みなさん、明日またここに来てください、本物の<a class="keyword" href="http://d.hatena.ne.jp/keyword/Excel">Excel</a>方眼紙をお見せしますよ」</p><br /> <br /> <p><span itemscope itemtype="http://schema.org/Photograph"><a href="http://f.hatena.ne.jp/aike/20130919204419" class="hatena-fotolife" itemprop="url"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20130919/20130919204419.png" alt="f:id:aike:20130919204419p:image" title="f:id:aike:20130919204419p:image" class="hatena-fotolife" itemprop="image"></a></span></p><br /> <p><a href="http://aikelab.net/dtm/20130919/hoganshi.xlsx">&#x30C0;&#x30A6;&#x30F3;&#x30ED;&#x30FC;&#x30C9;(hoganshi.xlsx)</a></p><br /> <br /> <p> </p><p><div class="hatena-asin-detail"><br /> <a href="http://www.amazon.co.jp/dp/4091877710/?tag=lifehacklife-22&amp;ascsubtag=d-11lyr"><img src="http://ecx.images-amazon.com/images/I/51PMDSD9Y3L._SL160_.jpg" class="hatena-asin-detail-image" alt="美味(おい)しんぼの料理本 (ビッグコミックス スペシャル)" title="美味(おい)しんぼの料理本 (ビッグコミックス スペシャル)"></a><br /> <div class="hatena-asin-detail-info"><br /> <p class="hatena-asin-detail-title"><a href="http://www.amazon.co.jp/dp/4091877710/?tag=lifehacklife-22&amp;ascsubtag=d-11lyr">美味(おい)しんぼの料理本 (ビッグコミックス スペシャル)</a></p> <ul> <li><span class="hatena-asin-detail-label">作者:</span> <a href="http://d.hatena.ne.jp/keyword/%B4%E7%B2%B0%C5%AF" class="keyword">雁屋哲</a>,<a href="http://d.hatena.ne.jp/keyword/%B2%D6%BA%E9%A5%A2%A5%AD%A5%E9" class="keyword">花咲アキラ</a></li> <li><span class="hatena-asin-detail-label">出版社/メーカー:</span> <a href="http://d.hatena.ne.jp/keyword/%BE%AE%B3%D8%B4%DB" class="keyword">小学館</a></li> <li><span class="hatena-asin-detail-label">発売日:</span> 2004/03/30</li> <li><span class="hatena-asin-detail-label">メディア:</span> コミック</li> <li><a href="http://d.hatena.ne.jp/asin/4091877710" target="_blank">この商品を含むブログを見る</a></li> </ul> </div> <div class="hatena-asin-detail-foot"></div></div></p><p><div class="hatena-asin-detail"><br /> <a href="http://www.amazon.co.jp/dp/4091925014/?tag=lifehacklife-22&amp;ascsubtag=d-11lyr"><img src="http://ecx.images-amazon.com/images/I/51QAKqGyaKL._SL160_.jpg" class="hatena-asin-detail-image" alt="美味しんぼ (1) (小学館文庫)" title="美味しんぼ (1) (小学館文庫)"></a><br /> <div class="hatena-asin-detail-info"><br /> <p class="hatena-asin-detail-title"><a href="http://www.amazon.co.jp/dp/4091925014/?tag=lifehacklife-22&amp;ascsubtag=d-11lyr">美味しんぼ (1) (小学館文庫)</a></p> <ul> <li><span class="hatena-asin-detail-label">作者:</span> <a href="http://d.hatena.ne.jp/keyword/%B4%E7%B2%B0%C5%AF" class="keyword">雁屋哲</a>,<a href="http://d.hatena.ne.jp/keyword/%B2%D6%BA%E9%A5%A2%A5%AD%A5%E9" class="keyword">花咲アキラ</a></li> <li><span class="hatena-asin-detail-label">出版社/メーカー:</span> <a href="http://d.hatena.ne.jp/keyword/%BE%AE%B3%D8%B4%DB" class="keyword">小学館</a></li> <li><span class="hatena-asin-detail-label">発売日:</span> 2000/08</li> <li><span class="hatena-asin-detail-label">メディア:</span> 文庫</li> <li><a href="http://d.hatena.ne.jp/asin/4091925014" target="_blank">この商品を含むブログを見る</a></li> </ul> </div> <div class="hatena-asin-detail-foot"></div></div></p> aike HTML5でワードアートするJSライブラリ作った hatenablog://entry/10257846132645781196 2013-09-08T00:00:00+09:00 2013-09-08T00:00:00+09:00 以前は商店街のチラシや自治会のお知らせなんかでよくワードアートが使われていました。もう最近は目にすることも少なくなりましたが、ワードアートのレトロで独特の雰囲気は見る人をなごませるように思います。 そんなわけで、最新のウェブ技術の粋を集めてワードアートを再現するライブラリwordart.jsを作りました。 http://aikelab.net/wordart/ こんな文字列にするといかにもな雰囲気が出ます。 最先端のインフォメーションもワードアートにするとまるで90年代のようです。 世界的な大イベントもほらこのとおり、なんだか町内会っぽい。 <p>以前は商店街のチラシや<a class="keyword" href="http://d.hatena.ne.jp/keyword/%BC%AB%BC%A3">自治</a>会のお知らせなんかでよくワードアートが使われていました。もう最近は目にすることも少なくなりましたが、ワードアートのレトロで独特の雰囲気は見る人をなごませるように思います。<br /> そんなわけで、最新のウェブ技術の粋を集めてワードアートを再現するライブラリwordart.jsを作りました。<br /> <span class="deco" style="font-size:x-large;"><a href="http://aikelab.net/wordart/">http://aikelab.net/wordart/</a></span></p><p> <br /> <span itemscope itemtype="http://schema.org/Photograph"><a href="http://f.hatena.ne.jp/aike/20130908172341" class="hatena-fotolife" itemprop="url"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20130908/20130908172341.jpg" alt="f:id:aike:20130908172341j:image" title="f:id:aike:20130908172341j:image" class="hatena-fotolife" itemprop="image"></a></span><br />  <br />  <br /> こんな文字列にするといかにもな雰囲気が出ます。</p><p><span itemscope itemtype="http://schema.org/Photograph"><a href="http://f.hatena.ne.jp/aike/20130908172342" class="hatena-fotolife" itemprop="url"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20130908/20130908172342.jpg" alt="f:id:aike:20130908172342j:image" title="f:id:aike:20130908172342j:image" class="hatena-fotolife" itemprop="image"></a></span><br />  <br />  <br /> 最先端のインフォメーションもワードアートにするとまるで90年代のようです。</p><p><span itemscope itemtype="http://schema.org/Photograph"><a href="http://f.hatena.ne.jp/aike/20130908172343" class="hatena-fotolife" itemprop="url"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20130908/20130908172343.jpg" alt="f:id:aike:20130908172343j:image" title="f:id:aike:20130908172343j:image" class="hatena-fotolife" itemprop="image"></a></span><br />  <br />  <br /> 世界的な大イベントもほらこのとおり、なんだか町内会っぽい。</p><p><span itemscope itemtype="http://schema.org/Photograph"><a href="http://f.hatena.ne.jp/aike/20130908210543" class="hatena-fotolife" itemprop="url"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20130908/20130908210543.jpg" alt="f:id:aike:20130908210543j:image" title="f:id:aike:20130908210543j:image" class="hatena-fotolife" itemprop="image"></a></span><br />  <br />  </p> aike 不思議な円グラフを描くウェブサービス作ったよ hatenablog://entry/10257846132645781208 2013-07-18T00:00:00+09:00 2013-07-18T00:00:00+09:00 最近ツイッター界隈で不思議な円グラフを見かけました。 こんなやつです。ちょっと調べてみると昨年の報道番組からキャプチャした映像のようです。 このグラフを見て、その手があったか!という新鮮な驚きを感じました。これまでの円グラフの常識にとらわれず、円の中心からあえてずらした位置から分割することで飛躍的に表現の幅を向上させています。無味乾燥で機械的なグラフにくらべて製作者の強い思いがぐっと伝わってきます。なんとイノベーティブでなんとワンダーなグラフなのでしょう。 でも、このグラフ、実際に描こうと思うとけっこう面倒です。Excelのグラフ機能をみても中心点の位置をずらす方法はなさそうです。 そんなわけ… <p>最近<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C4%A5%A4%A5%C3%A5%BF%A1%BC">ツイッター</a>界隈で不思議な円グラフを見かけました。<br /> こんなやつです。</p><p><span itemscope itemtype="http://schema.org/Photograph"><a href="http://f.hatena.ne.jp/aike/20130718190133" class="hatena-fotolife" itemprop="url"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20130718/20130718190133.jpg" alt="f:id:aike:20130718190133j:image" title="f:id:aike:20130718190133j:image" class="hatena-fotolife" itemprop="image"></a></span></p><p>ちょっと調べてみると昨年の報道番組からキャプチャした映像のようです。<br />  <br /> このグラフを見て、その手があったか!という新鮮な驚きを感じました。これまでの円グラフの常識にとらわれず、円の中心からあえてずらした位置から分割することで飛躍的に表現の幅を向上させています。無味乾燥で<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B5%A1%B3%A3%C5%AA">機械的</a>なグラフにくらべて製作者の強い思いがぐっと伝わってきます。なんとイノベーティブでなんとワンダーなグラフなのでしょう。<br />  <br /> でも、このグラフ、実際に描こうと思うとけっこう面倒です。<a class="keyword" href="http://d.hatena.ne.jp/keyword/Excel">Excel</a>のグラフ機能をみても中心点の位置をずらす方法はなさそうです。<br />  <br /> そんなわけでゆがんだ円グラフを描く<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A6%A5%A7%A5%D6%A5%B5%A1%BC%A5%D3%A5%B9">ウェブサービス</a>を作りました。<p><span style="font-size:x-large;" class="deco"><a href="http://aikelab.net/wdgg/" target="_blank">ワンダー・グラフ・ジェネレイター</a></span><br /> </p></p><p><p><a href="http://aikelab.net/wdgg/" class="hatena-fotolife" target="_blank"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/aike/20130718/20130718185842.jpg" alt="f:id:aike:20130718185842j:image" title="f:id:aike:20130718185842j:image" class="hatena-fotolife"></a></p> </p><p>項目の追加変更はもちろん、中心をずらしたり、楕円形にして項目を強調したりできます。円グラフの秘められた表現力を感じてみてください。<br /> それからレポートで使うとたぶん怒られます。<br />  <div class="hatena-asin-detail"><br /> <a href="http://www.amazon.co.jp/dp/B004MLGOJ4/?tag=lifehacklife-22&amp;ascsubtag=d-11lyr"><img src="http://ecx.images-amazon.com/images/I/61KfFyzIbmL._SL160_.jpg" class="hatena-asin-detail-image" alt="Still Life" title="Still Life"></a><br /> <div class="hatena-asin-detail-info"><br /> <p class="hatena-asin-detail-title"><a href="http://www.amazon.co.jp/dp/B004MLGOJ4/?tag=lifehacklife-22&amp;ascsubtag=d-11lyr">Still Life</a></p> <ul> <li><span class="hatena-asin-detail-label">アーティスト:</span> <a href="http://d.hatena.ne.jp/keyword/Van%20Der%20Graaf%20Generator" class="keyword">Van Der Graaf Generator</a></li> <li><span class="hatena-asin-detail-label">出版社/メーカー:</span> <a href="http://d.hatena.ne.jp/keyword/Virgin%20UK" class="keyword">Virgin UK</a></li> <li><span class="hatena-asin-detail-label">発売日:</span> 2005/06/27</li> <li><span class="hatena-asin-detail-label">メディア:</span> MP3 ダウンロード</li> <li><a href="http://d.hatena.ne.jp/asin/B004MLGOJ4" target="_blank">この商品を含むブログを見る</a></li> </ul> </div> <div class="hatena-asin-detail-foot"></div></div></p> aike