めろたんのアレ

色々書いてくやつ

Web Audio でシンセを作った話

どうもー

最近は暑くて死にそうです。

高山に行ったんですけど、22℃とかでくそ涼しかったです。

www.instagram.com www.instagram.com www.instagram.com www.instagram.com www.instagram.com

小京都だぞ!という感じがありノスタルジーに浸れたり、山の方に行けば綺麗で景色も見れて最高に涼しくて、最高に最高でした。

奥飛騨に別荘を建てて夏は奥飛騨に住みたい…。

そんな気持ちになりました。

はい。

高山には海の日あたりに学生時代の後輩氏達と行ったのですが、ただ遊びに行ったわけじゃなくて、開発合宿しようぜ〜とのことだったので、前々からちょっとやりたかった、 WebAudioをつかってシンセをつくるぞ〜⤴という気持ちを強く持ちながら、結構な時間を観光を楽しんだのでその進捗のNASAを書きます!!!!

Web Audio?

Web Audio API が正しいかな。

詳しくはこちらをどうぞ Web Audio API

まぁざっくりウェッブで音を扱うAPIですね。

音をだすだけじゃなくて、入力とかも扱うことができます。

でまぁもうこれをつかってシンセとかいくらでも作られているんですけど、まぁ作りたかったんです。

ロマンです。ロマン。

成果物〜

github.com

ネーミングセンスがないので、「FXで有り金全部溶かす人の顔」みたいな顔をしながら 「synse」という名前のパッケージをつくりました。

READMEはまだ無い。

でこれを使ったexampleがこちら

github.com

GitHub Pageで見れるようにしてるので良い感じにアクセスするか、 下のiframe内をご確認くだされ〜。

キーボードのa w s e d f t g y h j kをおすことで音がなります。

一応鍵盤通り?な配置で1オクターブが良い感じになるようになってるはずです。

同時に押してもオシレーターが一個しか無いので、単音しかなりません。

和音を鳴らしたいときは、後述するけどがんばれ。

他のいろいろな input は色々いじってもらうとアナログシンセみたいな感じに音が変わるかと思います。

設計思想とか?

そんなたいそれたものではないけど…

一応、あくまで一応、アナログシンセをイメージして作りました。

vco vcf vca とかをモジュールとして提供する感じにしています。
なので、vcoをそのままspeakerにつなぐこともできるし、vco -> vcf -> speakerのようにvcaを飛ばしたりとかもできるようになってる。

今は無いけど、もうちょっとしたらmixer?というか

vco ->  mixer -> vcf ....
vco ->

まぁmixerかな…。なんだろ…。
みたいに感じにn個の音源を混ぜるみたいなのも作ろうと思ってる。

実装的な話

Flow type とか Type Scriptとかを使って型がほしかったけど、開発合宿で2日くらいしかないし、まぁ後にしよーと思って結構ツライなぁとなってた。素直に入れればよかったけど、webpackとかで苦しんでいたので、そんな余裕はなかった。

そのうち Flow typeをいれたいなぁと思っている。

で、vcoとかはAudioNodeっていうクラスを継承させて作っていて、そこで他のAudioNodeとつなげるところは共通化させている。

vcaだけはちょっと特殊で、時間が経過するに連れて音を大きくしたり、小さくしたりみたいなのがあったので、どうしようか迷いに迷って、setTimeOutを使うようになっている。

よくないなぁ…と思いつつ、web上でのkeydownとかのイベントの発火が押しっぱなしだとワンテンポ遅れたりして、音が急にでかくなったり、いきなり消えたりしてわけわからんくなってしまったので、ダサいけどそうなっている。

今でも微妙なときがあるのでカイゼンの余地がある。

またsynseで提供している、keyboardは単音?1音?しか出せないようになってます。和音は出せません。

なぜならアナログシンセを設計思想においているからです。

和音を出したいときは、ナウいシンセのように複数個オシレーターを準備してやればいいかなと思ってます。*1

まぁvcoをn個用意してやればいいですね。

そのうちmixerができるから良い感じにつなげれば完成ですよ〜和音でますよ〜。

ちょっと話がそれましたね。

またkeyboardの実装もだいぶ汚いものになっています。 こちらもvcaと同様にsetTimeOutがあります。理由はvcaと同様です。辛かったし今もツライ。

そんな感じかなー。

色々もやっとしてるところはあるので、良い感じにしていきたいにゃーって思ってます。

あーあとテストとかも一切ないのでうーんってなってるけど、 これどうやってテストするんだ…ってなってる。 音が鳴るとか、ね。*2

まとめ

  • 高山はめっちゃ良いところだった。
  • web audio api 奥が深い。
  • つらいこともありますが、たのしかったです。

はいー

まぁそんなに使うタイミング無いかもしれないですけど、こういうのやっぱりおもしろいなぁーと思いましたまる。

そんなかんじで、ここまで。

またねー。じゃあねー。

*1:本当にそういう実装というか作りになっているかは知らないけど、多分そう。

*2:なんかでweb audio apiをモックして良い感じの値が来てるかどうか。みたいな感じのテストにすればいいのかな?

PostHTMLのプラグインつくったぞーって話

どうも。

いろんなことに夢見て、そのたびに期待をアレされて悲しくなってるめろたんです。

最近はクリエイターズマーケットっていうイベントで購入したテラリウムを見て心を癒やしています。

はい。

今回はPostHTMLプラグインつくったぞーって話を書こうと思います。

PostHTMLって?

と本題に入る前にPostHTMLってなんぞって話なんですが、

github.com

PostHTMLとは、JSHTML/XMLを変換するツールで、HTMLをパースして、ノードツリーを操作するAPIを提供しています。

PostCSS*1HTML版ですね。

これ単体だと、特になにも起きません。

で、色々公開されている、プラグインを使うことで、HTMLを良い感じに変換したりできます。

そのままのっけるけど、

import posthtml from 'posthtml'

const html = `
  <component>
    <title>Super Title</title>
    <text>Awesome Text</text>
  </component>
`

const result = posthtml()
  .use(require('posthtml-custom-elements')())
  .process(html, { sync: true })
  .html

console.log(result)

みたいにすると、

<div class="component">
  <div class="title">Super Title</div>
  <div class="text">Awesome Text</div>
</div>

と変換されてHTMLが返ってくるっていうやつです。 (このposthtml-custom-elementsっていうプラグイン筋悪くね…ってちょっとおもったゾ…)

静的なページを作るんだけど、複数ページつくらないといけなくて、headerとかは共通につくっておきたいなー みたいなのにすごく便利では?って思ったり崎哲夫してました。

今回作ったの

で、今回作ったのはこちらですー

github.com

英語が苦手なフレンズなのでアレ。

それはさておき、何を作ったかというと、

<!DOCTYPE html>
<html>
  <head>    
    <link rel="stylesheet" href="~~~~" >
  </head>
</html>

みたいに書いたときにstylesheetを中に良い感じに展開してほしい、っていうのを作りました。

なんでいるの?とは思うかもしれませんが、HTMLメールとか?あと、AMPで中に書く必要があったりするじゃん?みたいなので、どうしても中に書きたい場合があるんすよ。

っていうので作りました。

実装はどうなってる?

非常に簡単な作りになっているのでぎっよはっぶでみてくれ、みたいなところはあるけど、まぁ軽く。

github.com これを参考にしてつくりました。

const parser = require('posthtml-parser');
const fs = require('fs');
const path = require('path');

module.exports = function(options) {
  const root = options.root || './';
  const encoding = options.encoding || 'utf-8';
  return function posthtmlInclude(tree) {
    tree.match({ tag: 'link', attrs: { expand: 'true', rel: 'stylesheet' } }, function(node) { // ①
      const href = node.attrs.href;
      let content;
      if (href) {
        const src = path.resolve(root, href);
        content = parser(fs.readFileSync(src, encoding)); // ②
      }
      return { // ③
        tag: 'style',
        content: content
      };
    });
    return tree;
  };
};

これが全コードですね。簡単な作りです。

① ノードのマッチ

ここでlinkタグかつrelstylesheetで、expandtrueのときだけ展開する処理を行うようにしています。 全部展開されると困ることもあるでしょうし、任意のやつだけ展開したいことが多くあると思うので、専用の属性を設けました。 本当はdata-~~とかにすべきなのかなぁとかも思ったけど、まぁ変換された後のHTMLが正しければいいと思うし、まぁいいやってなりました。

②選択したファイルのよみこみ

まぁとくに説明することはないですね。hrefで指定されているファイルを読み込むようにしています。 それを展開するためにcontentに保持しています。

③styleで書き出す

で、その①でマッチした所をstyleタグに変換します。 中身は②で取ってきたやつですね。

テッテレ~

完成。

まとめ

もともとはすでにこういうのあるっしょ〜とか思ってたんだけど、無くて*2、期待をアレされて悲しくなってましたが、意外と簡単な作りだったので、自分でできて良かったです(小並感)。

後々になってposthtml-include使えばよかったのでは?とか思ったけど、なんか気持ち悪いし作ってよかったなと思ってます。

今後、これも盛り上がっていくといいなぁとおもいつつ、無いだろうなぁとおもっためろたんでした。

あ、今回作ったやつnpmで公開しているので、興味がある人は使ってみてくだされ〜

www.npmjs.com

チラ裏

ここからは、愚痴等。

で今、AMPのサイトつくろ〜っと思ってこれ無いやんってなったので作ったのですが、そこまでに至る経緯がクソだったので書いとく。

まず最初 Webpack3出たし、Webpackでやろ〜とおもってposthtml-loaderっていうの使おうと思ったんだけど、

github.com

これね

f:id:renyamizuno:20170702001855p:plain

f:id:renyamizuno:20170702001907p:plain

リリースに載ってないバージョンがリリースされてるんすよwwwwww

しかも壊れてるんすよwwwwwwwwwwww*3*4*5

これ特定するのにまじで精神と時間をすり減らしたから訴訟したい(暴挙)。

で諦めて、cliをつかってみようと思ったら、そっちもうまく動かなくて、精神と時間を溶かした人の顔になってた。

結局posthtmlを叩くjsを書いた。

この時の僕の気持ちは最高にアレだった。

頼むから壊れたままにするのはやめてほしい。

そんなアレでした。

とりあえずnpm界隈はこれだから〜みたいな感じになった。

*1:CSSをパースしてASTを吐いてそれを操作するAPIを提供しているJSのやつ。めっちゃ好き。ロゴがイカしてる。 github.com

*2:ちゃんと探せていないだけかもしれない

*3:もしかしたら使い方が違うかもしれないとかそういうやつかもしれないけど、4時間近く色々試したし、loaderのコードに色々差し込んで確認したりしたから確固たる意志をもって書く。僕は間違っていない。

*4:parserを指定できるので、pug(jadeって言われてたやつ)をつかってみよーと思ったら、

だけ出力されてキレてた。

*5:どうも、parserにoptionを渡す前提で作られていないので、optionを受け取る前提で作られているparserにはoptionを受け取るところで、html(というかpug)の文字列が入ってきちゃって、処理すること無く空を返すみたいな感じになってたっぽい。深くは見ていない。

第1回 React.js 導入事例で話してきた

どうも。

ちゃんとしたブログを作ろうと思ってずっと何も書いていなかっためろたんです。

ちゃんとしたこと書こうと思います。

第1回 React.js 導入事例で話してきました。

第1回 React.js 導入事例で話してきました。

frontend-temple.connpass.com

これです。

大体僕のぐちみたいになってしまっていたけど、まぁよかったかなって思ってる。

speakerdeck.com

発表資料は上のやつ。

僕のメールアドレスが隠れてなかったりしてちょっと焦ったりしてた。

準備不足ですね。

はい。

発表したってことはここまでにして、内容とかを書いていきたい。

よかったこと

まぁこの辺はホント色んな所に書いてあるとおりでそれ以上のことはないかなと思います。

DOMの操作がなくなる?

基本的にはなくなると思う。

実際やってると厳しいところが出てきて直接触らないといけないところが出てきたりするしね。

github.com

例えばこれの、

document.addEventListener('click', this.handleClickOutside, true);

これとか。

どうなん?

DOM操作では無いけどなんか怖くない?

まぁはい。

どのJSからどこを触ってるかわかる

JSXでかけば基本的にはそのJSX内で触るところが限定される(はず)だから色々わかりやすくはなるなぁという感じ。

なういJS

ES2015+ で書かないとどう書くのか全くわからん。強制的に今時な(?)JSを書かざるをえないのかなと思っている。classが本当に良いかどうかはおいておいて。

まぁ変にprototypeを書いて大変な目に(継承とか)あうよりかは良いんじゃないかな。

と言うか各ブラウザ氏class構文サポートしてたの今知ったわ。

Can I use... Support tables for HTML5, CSS3, etc

コンポーネント

なるね。 JSXだしね。

良いところはまあよくよくあるこんな感じだなぁーって思ってた。

はい。

やだなー

依存パッケージ

まぁこれはReactには直接的には関係ないんだけど、色々大変だよね。 react-routerの件とかね。

あと npm とか yarn のパッケージの持ち方がわからん。

調べろよ。って話なんだけどね。

Redux

ReactやるならReduxだよね〜SPAだよね〜〜〜〜〜 みたいなの多すぎませんかね。

そもそもFluxレスでReactやってもいいんじゃない? 何かの編集フォームだけReactとか。何かの一覧ページだけReactみたいにやっていいんじゃないかなぁっておもってる。

あと、Redux以外になんかあっても良いんじゃないかなって思う。

僕の後の えるきちさん の発表でFlux自体は割りと簡単にできる。っていうのもあったし、 一家に一台Flux実装みたいなのがあっても良いんじゃないかな〜っておもってる。 極論だから別に良いんだけど。

あとReduxだとAsyncFunctionがうまく扱えないみたいなのがクソ辛くないですかね。 なんかそんな気持ちがもやもやするけど、Reduxだけが育っていく現状。自分もReduxを使ってしまうというアレ。

ReactとかRiotとかVueとかがかつて色々マウント取り合っていたのに、Reduxは何もなかった印象。あくまで印象ですがね。なんかもうちょっと戦いがあっても良いんじゃないかなって。

SPAつらい

つらい。 なにが必要なのかわからんし、どこまでハンドリングというか面倒みないといけないんだろうって考え始めるとキリがない。

というかブラウザというアプリケーションの上でアプリケーションを作るのって辛くない? みたいな気持ちが最近は大きい。 素人がやるもんじゃねえって思った。

個人的につらいなぁ嫌だなって思ってたのがこの辺ですね。

最近思っていること

そもそもReactでやる意味

なんでReactでやりたいのか、やるのか。 というのを最近振り返ってみたところ、全くといっていいほどなんもねえなぁと思った。

ReactでやればReactNativeがあるゾ。ってあるけどそこまで魅力に感じないんですよね。個人的なアレだけど。 そうじゃなくてWebしかやらないんだよなって人はちょっと考えてみるといいのかなぁって思う。

仮想DOMがほしいなら、VueでもAngularでもあるわけで。 コンポーネント指向で〜とかでも上の2つもそうだし。みたいなね。

ReactをやるならJSXを書かないといけなくて、JSXってFacebookが考えたものでES2015+の構文とかでもなんでもないんだし、なんかどうなの?みたいな感じ。

それよか、WebComponentsっていうのがくる(ぞーってずっと言ってる気がするけど…)し、そっちに夢見たほうがいいんじゃないかなぁって思う。

Babelで最新のナウいJSを書こうぜ!ってなってるのに、次世代のWebComponents書こうぜ!みたいなのが全然無い気がするなぁって思うのが、なんだかなぁという気持ち。

僕の視野が狭いって話もある。

まとめ

完全にただの愚痴のブログみたいになってしまった。。。

ちゃんとしたブログとは。。。

とにかく、僕が言いたいのは選択肢はReactだけじゃないと思うし、SPAにしないといけないってことは無いはず。だからちょっとずつやっていけば良いんじゃないかな。

あと、もっと次世代に生きても良いんじゃないかな?って思うよ。

はい。

ここまで。

じゃあね。