Loading

S.F. Info.

S.F.@SFPGMR

2019/6/30 6:05:47

今さらクォータニオンを学習中。。

クォータニオン (Quaternion) を総整理! ~ 三次元物体の回転と姿勢を鮮やかに扱う ~ - Qiita
# 0. はじめに: クォータニオンについて思うこと
はじめまして!
[NTTデータ数理システム](http://www.msi.co.jp/)で[機械学習](https://ja.wikipedia.org/wiki/%E6%A9%...

2019/6/30 6:37:45

あかん。難しい。今まで3次元空間での回転は軸固定でx,y,zのオイラー角で表してたのだが、回転軸ベクトルとラジアンを使って3次元の回転を表す方法をいまさら理解してさらにクォータニオンに行き着いたわけだが、朝一でこれはきつい。

2019/6/30 6:43:08

回転のアニメーションをオイラー角でしていると妙な違和感があって。x,y,zを同じ角速度で回してるのになんかこう回転速度が変化するような感じになってしまうのはなんでかな。。と昔から思ってた。

No Image
8x8x8Voxelの表示 - YouTube


voxファイルの表示
voxファイルの表示

2019/6/30 6:49:06

x,y,z軸固定でオイラー角でx,y,zをx,z,yの順番に回転行列を掛け合わせるのだが。各軸周りの回転が等速になってるように見えんところが気になるところだ。

Youtube - 8x8x8Voxelの表示

2019/6/30 6:49:06

これはひょっとして「ジンバル・ロック」によるものなのかと考えたりとかしてたり。わからんけどね。
そこでまあ「ジンバル・ロック」のない回転とやらはどんな感じなのかと思ったわけだ。そこで思い出したのが「クォータニオン(四元数)」である。

2019/6/30 6:54:14

しかし、「ジンバル・ロック」とやらはいくら頭の中で考えても全くイメージできんわけだ。これが。。

ジンバル - Wikipedia

2019/6/30 6:54:15

x,y,zの各軸は互いに直交してるわけで、なんで軸が重なるねん??となって頭が混乱するわけだ。

2019/6/30 6:55:22

でまあこれを読んでみたわけだが。理解しとらんが「いいね」をつけとこう。。

クォータニオン (Quaternion) を総整理! ~ 三次元物体の回転と姿勢を鮮やかに扱う ~ - Qiita
# 0. はじめに: クォータニオンについて思うこと
はじめまして!
[NTTデータ数理システム](http://www.msi.co.jp/)で[機械学習](https://ja.wikipedia.org/wiki/%E6%A9%...

2019/6/30 6:57:53

こっちはクォータニオンを使うに必要な知識が書いてある。

No Image
その10 クォータニオンを学んでみよう!

2019/6/30 6:57:53

クォータニオンはさておいて、軸ベクトルとラジアン1個で任意の回転をあらわすことができることは理解したのである。。

2019/6/30 7:04:28

軸ベクトルをつかうと例えばx軸周りの回転は
(1,0,0)になるわなあ。そしてx軸かつy軸周りの回転は
(1,1,0)となるのだろうなと思う。でまあy軸だけ逆回転させたくば(1,-1,0)とすればよいのかなと。たしかに考えやすい気がするねえ。。考え方が間違って理解してなければの話だけど。。

2019/6/30 7:07:15

複数のボクセルデータを表示するために今改造してるところなんだけど、これを機会にオイラー角での指定をやめて、軸ベクトル+ラジアンで回転を表すようにしてみるつもりである。

2019/6/30 7:08:39

複数のボクセルデータを表示するのはサクっと作ってしまうつもりだったんだけど、WebGL2.0の理解が深まるにつれいろいろ盛り込みたいことが増えてきてる。盛り込みたいというか変更したいというか。。

2019/6/30 8:43:20

ここまでの記録をまとめた。

自作WASMプリプロセッサとWeb要素技術を使ってレトロ・シューティングを作る - Togetter
自作WASMプリプロセッサとWeb要素技術を使ってPSGエミュレータを軽く作ってみた。そしていまレトロ・シューティングを作っている(進行中)。

2019/6/30 18:22:05

160x100pxへのこだわりはやはり「N-TYPE」を見てからですな。これはほんとにすごい。

Youtube - 【PC-8001】N-TYPE2【AABM2】

2019/7/3 20:28:22

ようやく複数オブジェクトの表示ができるようになった。。

2019/7/3 20:30:06

これがそう。なんの変哲もないポリゴンの立方体のように見えるが実はポイントスプライトで表示しているという。

No Image
YouTube

2019/7/3 20:32:41

ここでUBO使おうと思ったんだけど、現時点の実装では思ったほどUniformバッファの恩恵を受けられないことが分かったのでやめた。。

2019/7/4 4:09:45

続いて複数キャラを同時に表示する部分を作らんといかんな。。

2019/7/4 4:10:07

違うわ。複数の異なるオブジェクトだった。。

2019/7/4 6:29:37

ようやく所望のものができた感じですな。。
3Dスプライトといったところか。
この粗々なピクセルの感じがレトロっぽくて好みなんだよね。。

Youtube - MagicaVoxelのデータをポイント・スプライトで表示する

2019/7/4 7:51:52

オブジェクトの描画は登場キャラの頂点情報を1つのArrayBufferにまとめて、drawArraysにオフセットをあたえることでキャラの切り替えをするわけですな。

gl.drawArrays(gl.POINTS, objInfo.vindex,objInfo.count);

2019/7/4 7:54:04

こうすればバッファ切り替えしなくても良くなる。でもバッファの切り替えなんてポインタの切り替えコストくらいじゃないかと思うからメリットはそんなにないかな。。

2019/7/4 8:00:00

オブジェクトの情報も1つの大きなArrayBufferの1区画で管理するようにして、それをwasmから見えるようにする。wasmからそのメモリに書き込むことでキャラクターをコントロールするのですな。

2019/7/5 4:37:53

512個ほどキャラを表示。混沌として何が何だか。。

Youtube - MagicaVoxelのデータ表示

2019/7/5 4:37:53

現在の成果物。。Z座標に応じて輝度を暗くしてみている。フォグのかわり。。

voxファイルの表示
voxファイルの表示

2019/7/5 4:45:10

次は入力とサウンド関係のめどをつけるか。。

2019/7/6 5:30:53

DataView,ArrayBuffe,TypedArrayを使うとJSか?と思うほど型やメモリアドレスを意識したメモリアクセスができるのがすごいなあ。

2019/7/6 5:37:16

仮想テキストVRAMとボクセルデータ用のスプライトバッファを1つのArrayBufferにまとめることができた。更に同じArrayBufferに入力やサウンドのI/OをマッピングすればwasmモジュールからメモリマップドI/Oで操作できるようになる。

2019/7/6 5:37:17

ここまでは想定通り実装できているわけですな。

2019/7/6 5:37:18

しかしWebGL2.0のシェーダーも整数値のビット演算ができるようになったから、頂点情報にフラグ情報をビット単位で詰めて渡せるようになったので頂点あたりのバイト数も節約できたわ。

2019/7/7 9:32:55

ここまでをnoteにまとめた。

MagicaVoxelデータをWebGLのポイント・リスト(ポイント・スプライト)で疑似表示する|sfpgmr|note
mwasmのプリプロセッサをある程度完成させたところで、それ使ってゲームを作ろうとしている。wasmでゲームを作ろうと思ったら、リソースをメモリにマップしてアクセスできるようにしてやるか、JS側でリソースアクセスのための関数を作ってwasmにエクスポートする必要がある。JS側の関数を呼び出すのは安直でよいが、呼び出しのオーバーヘッドが気になるのでメモリにマップしてそこにwasmに書き込ませ、JS側でメモリをデコードして各種リソースにアクセスするようにすることにした。 内容はレトロ風の横スクロールシューティングである。パワーアップ可能な自機が敵をなぎ倒して進めるようなタイプのやつで

2019/7/8 7:47:42

入力部分は過去作ったコードを若干手直しして利用することにした。自分が作ったコードにしては割とよくできてる方でよかった。。次はサウンド部分ですな。。これはJSで作った波形メモリ音源をwasm
で書き直すつもりだがさてどうなるか。

2019/7/8 19:01:07

ただタッチパネルには対応してないんだな。これが。。

2019/7/9 5:48:04

これが一応入力クラスのテスト画面。ふつうはキーボードでゲームパッドを刺すとそっちに切り替わる。ボタンカスタマイズもできるようにしてるけどUIでは割愛。。

No Image
ゲーム用入力クラスの作成
https://t.co/HMQLUKpBPZ

2019/7/9 5:56:58

さて、サウンド機能を実装するか。。以前JSで作った波形メモリ音源をwasm化しようかなと思ったが、PSGエミュレーション+SCCエミュレーション+αにしようかなと思ってる。YM2203相当のFM音源もいれてみたいと思うけどねえ。AudioWorklet+wasmでそこまでできるだろうか。。

2019/7/9 5:56:58

とりあえずPSGエミュレータにSCC相当の音源を載せることからはじめるか。シーケンサー機能も併せて作ろう。これはMIDIシーケンスデータを再生する仕様にしようかね。。

2019/7/9 6:06:15

以前作った波形メモリ音源はWebAudioベッタリの仕様で、ゲインノードでエンベロープ・ジェネレータを作ってたりしてた。今回はなるたけAudioworklet内で処理を完結しようと思ってるので、ほぼ作り直しになる。作り直すならSCCに近いものを...と思ったわけ。

2019/7/9 6:07:28

できる限り整数(固定少数)を使ってチマチマ作るつもり。よって作業時間が相当かかりそうな気がする。

2019/7/9 6:09:19

FM音源もあの出音の割には簡素なしくみだし、C/C++のソースならゴロゴロ転がってるのでそれを移植するだけで済みそうだよな。。

2019/7/9 7:52:36

SCCの情報

No Image

2019/7/9 8:01:48

PSG3音、SCC5音、4オペFM3音、SID3音、8ビットDA2音くらいのスペックにできれば申し分ないんだけどなあ。。私にできるだろうか。言うても先人の遺産が大量にあるので、できんことはないだろうけどね。。ほぼ全部C/C++ のソースコードあるしなあ。私はチマチマwasm
に書き換えるだけなんだけどね。。

2019/7/9 8:02:54

MAMEのコードがすごいんだよなあ。

2019/7/9 8:06:05

しかしなんでこんなに音源を豊富にしたいかというと、単なる趣味ですが。SPC700なんかも興味あるんだよなあ。。ゲームコンソールの中で唯一興味のある音源ですわ。。

2019/7/9 8:08:59

SPC700も調べて過去にブログ記事にしてみたんだけど、なぜかAD-PCMの解説みたいになっちゃった。。

No Image

2019/7/10 4:14:25

完全なエミュレーションをするのではなく、オシレータをFMか波形メモリかSIDの波形選択としてあとはフィルタとEGを作ればいいだけのような気もするな。。

2019/7/10 4:16:27

結局チップに足りない機能はソフトウェアで補完して、最終的にはそのような形になるもんね。。

2019/7/10 4:31:47

MAMEのソースコード久しぶりに読もうと思ってリポジトリクローンしたら結構大きいな。。

2019/7/10 5:18:01

mame/src/devices/sound のソースがもう宝の山というか。「サウンドチップ・エミュレータの聖地」といっても過言ではない。。ありがたく拝読させていただこう。

2019/7/10 5:18:02

やっぱりあれだよな。オシレータをPSG/SCC/SID/FMとすればいけるよなあ。コントロールI/Fはオリジナルでいこう。といってもEGのかかり方はそれぞれ(
SID/FM)だからそこをどう考えるかだな。「まんま」の音を出すつもりではなくて、いちおうオリジナル音源にするつもりだからな。

2019/7/10 5:23:14

MAMEの6581(SID)ソースのオシレータ部分を見るとやっぱり波形テーブルから読みだしてピッチ変える感じになってるんだよなあ。なのでこれも波形メモリがROMの音源の一種とみることができるな。

2019/7/10 5:23:15

いやしかし、SIDの設計はPSGチップとしては秀逸だと思うなあ。。

2019/7/10 5:26:17

結局波形メモリにするとSCC/PSG/SIDのオシレータはカバーできるということになるな。だけどSCC/PSGとSIDはピッチの狂い方がそれぞれ異なるようだから、そこをどうするかだよなあ。ピッチは合わすようにするか。オリジナル音源だということをすぐ忘れそうになるなあ。。

2019/7/10 5:29:58

自分で調べたドキュメントも見直すか。。

No Image

2019/7/10 5:30:21

ほとんど内容忘れとるわ。。

2019/7/10 5:32:49

SIDはほんと「シンセ」の落としてるわ。フィルタがあるのが大きいんだよな。やっぱり。

No Image

2019/7/10 5:35:31

このSIDチップの存在は当時雑誌で知った。なのでC64が欲しくて仕方なかった。しかし結構高かったんだよな。日本でのC64は。

2019/7/10 5:41:53

コモドール64miniを買ってしまった。。以外に安かったので。。

No Image
Amazon.co.jp: コモドール64 mini

2019/7/10 5:41:53

ということで間接的だが長年の夢がかなったわ。。

2019/7/10 6:11:08

波形メモリのオシレータ+PSGオシレータ、FM変調、リング変調、オシレータシンク、フィルタ、アンプ・フィルタEGで構成すればまあ所望のものになるよなあ。普通のシンセの構成ですがな。。

2019/7/10 6:12:08

波形メモリの内容を6581のにすればSIDっぽい音も鳴るだろうし。問題はフィルタ特性かあ。。

2019/7/10 19:21:09

まあとりあえずはSCCのまがい物を作るところから始めるとするか。

2019/7/11 7:30:09

実装をし始めた。SCCの音源をBGMにとスペースマンボウの動画を流しながらやってたら、聴いてるうちにやっぱりEG必要だよなあ、LFO
必要だよなあ、フィルタも最初からあったほうがいいよなあ。。とかなってきて、結局普通の波形メモリ音源を実装する感じになってる。。

2019/7/11 7:30:10

SCC自体波形再生とピッチ、ボリュームだけなので、EGやLFOはソフトウェアで補ってる。そこも作らんといかんので音源の仕様として入れこんでしまおう思ったわけ。全部ソフトウェアになるからね。結局。。

2019/7/11 7:32:45

オシレータは差し替え可能にしようかなと思う。そうすれば大半の音源はサポートできるんではないかなと。。

2019/7/13 5:58:27

ちょっとwasm用のプリプロセッサに手を加えようと思ってる。最低やらないといかんのは

・リニアメモリの利用開始オフセット指定
・構造体による相対オフセット・アドレス指定

ほんとはマクロ機能も付けたい&記法も見直したいところだが、それはできればということで。。

2019/7/13 7:38:17

プリプロセッサの機能追加は思いのほか簡単だった。とりあえずこれでいこうか。マクロ機能はどうするかなあ。久しぶりにいじってみると独自記法の部分がなんだかなあ。。って感じになっている。

2019/7/13 7:41:55

メモリのオフセット定義もJSでもなくかといってS式でもなく、C風の表記になってるんだよね。ここはS式にしておけばよかったかなあと今は思ってる。

2019/7/15 18:28:50

ようやく波形テーブルを指定のピッチ・ボリュームで再生するWASMを書き終えたところ。これからUIとAudioWorkletとのつなぎコードを書いて、そのあとデバッグしようと思う。EG・LFO・フィルタはそのあとだなあ。

2019/7/15 18:32:02

波形テーブルはSCCに倣って8ビット×32サンプルの波形を5CH持たせている。でまあこれを指定ピッチ(Hz)で鳴らすのをどうしようかと高校野球観戦(千葉県大会)の合間に考えていた。

2019/7/15 18:34:48

画面はPSGエミュレータのを少し改造して、これに波形エディットするUIを加えればいいかなあと思っている。 https://t.co/gjQ79kx24X

2019/7/15 18:39:16

今週はUIを作って音を鳴らすところまでを目標とするか。。そのあとEG・LFO・フィルタを作ればまあなんとかなるだろう。

2019/7/16 5:40:15

テスト用のUIを構築中。。 https://t.co/QdnXNaRgYX

2019/7/17 5:21:58

ここまで作りかけてあれなのだが、設計を見直すことにした。というか昔書いた古いコードの改良で済ますことにしたといったほうがいいだろうか。古いコードというのはこれなんだけど。

2dshooting2/audio.js at master · sfpgmr/2dshooting2 · GitHub
HTML5,WebGL,WebAudioで縦スクロールシューティングゲームを作る. Contribute to sfpgmr/2dshooting2 development by creating an account on GitHub.

2019/7/17 5:21:58

いろいろ考えると、AudioWorkletの中でいろいろやるのはパフォーマンス的にもまたWeb Audio APIを生かすという面でもあまり意味はないなあ。。と考えた。

2019/7/17 5:21:58

オシレータ部分のみをAudioWorkletにして、そこをwasmで書く感じに変えようかなと思ったんだよね。考えはまた変わるかもしれんけどもね。。

2019/7/17 5:41:02

例えばPSGのオシレータ部分だけとかね。

2019/7/17 5:46:54

今得られた知見(wasmとかAudioWorklet)を使って書き直すとどうなるのかといったところ。。

2019/7/17 5:48:20

とはいえ昔書いたコードもすっかり忘れているのでソースコード読んで理解しなくてはならんのだが(笑)。シーケンサ部分はモハヨナオさんのmml-parser使ってるんだよね。確か。

2019/7/18 4:38:47

私が持ってるchuwiのandroid tabでPSGエミュレータを動かしてみたんだけど、やっぱりもたつく。もたつくと音がとぎれとぎれになる。何が原因かなと考えた。私のコードの書き方が悪いのかはそれは置いといて。

2019/7/18 4:38:48

ひとつ思ったのはJSからwasmへのコールがやっぱり言語境界を超えるので遅いのかなと。この記事を過去に読んだからなんだけど。

Calls between JavaScript and WebAssembly are finally fast 🎉 - Mozilla Hacks - the Web developer blog
At Mozilla, we want WebAssembly to be as fast as it can be. This started with its design, which gives it great throughput. Then we improved load times with a ...

2019/7/18 4:39:42

ちなみにPSGエミュレータというのはこれなんだけどね。

No Image
WASMでPSG Emulatorを作る

2019/7/18 5:07:19

この記事によるとJS->wasmへの呼び出しは1億回で5500msだと書いてある。とすると1回あたり約0.055μsということになりますな。

2019/7/18 5:07:20

サンプリングレートが48khzのとき、AudioWorkletが呼び出される周期は

1/48000 * 1000 * 1000 * 128 = 2666μs

となる。1サンプルあたりだと約20.8μsか。a-rateのパラメータを考えると1サンプルごとに処理しなくてはならないから0.055*128=7.04μsか。。そんなに大きな影響はないのかな。

2019/7/18 5:10:18

あ、ここで自分の環境での計測ができるのか。。

No Image

2019/7/18 5:13:10

あら、JStoJSとJStoWasmと関数呼び出し比較するとJsTowasm関数呼び出しのほうが2倍以上遅いみたいだな。まあ言語境界におけるオーバーヘッドがあるのはしょうがないわな。 https://t.co/Ye8j8vAqvV

2019/7/18 5:16:32

ちなみにさっきのはchromeでの話で、firefoxだとJsToWasmのほうが速くなるんだな。。 https://t.co/KWBIaXfgKa

2019/7/18 5:19:56

これはなんでかというと先ほどの記事に書いてあるんだな。トランポリン関数を介さずネイティブ同士で呼び出すようにして、呼び出しコストを削減してるんだよな。簡単にいうと。。

Calls between JavaScript and WebAssembly are finally fast 🎉 - Mozilla Hacks - the Web developer blog
At Mozilla, we want WebAssembly to be as fast as it can be. This started with its design, which gives it great throughput. Then we improved load times with a ...

2019/7/18 5:21:28

ようし、これからはFirefoxでいこう!と言いたいところだが、AudioWorkletはFirefoxではサポートしてないんだな。これが。。

2019/7/18 5:27:32

ただ96KHzのサンプリングレート、2.6ms以内で音声処理すべてをこなそうとするのはJS/WASMでは難しいかもしれんね。別スレッドで先行処理してバッファリングしておいて、AudioWorklet内ではバッファコピー位に留めておくくらいが現実的なのかもね。。

2019/7/18 5:30:43

このようなことは別の手段でもできるから、このアイデアもあまりAudioWorkletをうまく使っているとは言えんねぇ。。

2019/7/18 6:54:45

違うな。96khzだと1.3msか。。128サンプル単位だと。。

2019/7/18 13:27:35

もしWASMを使うなら、AudioWorklet使うならJSでバッファコピーだけするようにして、別にタイマーかワーカーかで50ms単位くらいの大きい括りで処理するのがよいかもね。

2019/7/19 4:05:31

これもちょっと試してみるか。。

2019/7/19 5:13:06

メインスレッドのタイマー処理でオーディオをレンダリングしてバッファ(おそらくリングバッファ)に溜め込んでおいて、AudioWorkletがそのバッファを128byteずつ読み込んで処理することを考えている。

2019/7/19 5:17:27

気になっているのが不要なメモリコピー。ワーカー間のデータのやり取りはpostMessageでやるんだけどその時にメモリのコピーが発生するんだよな。なのでAudioWorklet側とメモリを共有したいという欲求が出てくるんだよね。

2019/7/19 5:17:28

こういう時のためにどうもSharedMemoryBufferちゅうのが用意されとるらしいのだが、ただMDNを見ると「Spectre対応のために無効化した」と書いてあるんだな。。 https://t.co/vivLDeTdf4

2019/7/19 5:19:25

別の情報では復活したようなことも書いてあるんだけどもね。。

The Return of SharedArrayBuffers and Atomics - Blog | SitePen
A common complaint of modern web apps is the concept of jank; web pages being unresponsive to user input and frame rates being low. Left unmitigated, this problem leads to a poor quality experience for end users of our web applications.

2019/7/19 5:23:42

現状のブラウザサポート状況は惨憺たるものですな。Chromeだけのようだ。今は。。

No Image
Can I use... Support tables for HTML5, CSS3, etc
https://t.co/DOrFhsodDa

2019/7/19 5:27:22

まあしかし、AudioWorklet使ってる時点でChromeしか動かんのだが(笑)。近々にはEdgeでも動くようになると思うけどね。Chromeとべースは同じになるからね。。

2019/7/19 6:05:36

SharedArrayBuffer使ってやってみますか。一度。

2019/7/19 6:12:19

「所有権の譲渡 (Transferable Objects) によるデータの引き渡し」ちゅうのもあるのかな?

Web Worker の使用 - Web API | MDN
Web Worker は、ウェブコンテンツがスクリプトをバックグラウンドのスレッドで実行するためのシンプルな手段です。 Worker スレッドは、ユーザーインターフェイスを妨げることなくタスクを実行できます。加えて、それらは (responseXML 属性や channel 属性は常に null ですが) XMLHttpRequest を使用して入出力を行うこともできます。生成された Worker は、生成元が指定したイベントハンドラーへメッセージを送ることにより JavaScript コードへメッセージを送ることができます (その逆も可能です)。本記事では、 Web Workers の使い方を詳しく紹介します。

2019/7/19 6:20:30

しかしこれ使うと、所有権がワーカーに移るんだな。ということはオーディオをバッファにレンダリングするたびにnew ArrayBuffer()しなければならなくなるちゅうことですわ。そのコストも結構高い気がする。やっぱりSharedArrayBufferだよなあ。。

2019/7/19 7:44:32

No Image
ES proposal: Shared memory and atomics

2019/7/19 7:57:19

そういえば、WebAudioってオフラインレンダリングできるんじゃなかったっけ?

2019/7/20 3:58:51

GPUでオフライン処理するっちゅう手もあるわなあ。。だんだんWASMから離れていってるけど。

2019/7/20 4:05:24

具体的にいうとtransform feedbackを使うということだけどね。

サンプルで理解するWebGL 2.0 - Transform Feedbackによるパーティクル表現 - ICS MEDIA

2019/7/20 4:05:24

しかしこれもGPU <-> CPU間のデータの受け渡しで時間がかかるのではないかなということ。あとはコールのコストがあるのでできれば大きいまとまりで処理すべきかなと。

2019/7/20 4:05:24

WebAudioのAudioWorkletでは128サンプル単位の処理となるから、サンプリングレートを考慮しながらバッファサイズを求めてそれを共有することになるだろうね。

2019/7/20 4:07:57

wasmでやるならFixed Width SIMDが使えるようになるとうれしいのだが。

No Image
WebAssembly SIMD - Chrome Platform Status

主要ブラウザは「実装中」のステータスですな。

2019/7/20 4:55:43

ちなみにこれはWebAudio + JSの波形メモリ音源。昔作ったやつに手をちょっとだけ加えた。

Youtube - WebAudioで波形メモリ音源を作る

2019/7/20 5:26:35

ちなみにこれだとAndroid Tabでも再生にモタリはほぼない。

2019/7/20 5:27:29

フィルタはないし、音量のEGだけでピッチEGもないからそりゃまあそうかなあ。。といった感じだ。

2019/7/20 6:38:13

AudioWorkletってhttpsで配信されんと動かんのね。localhostは例外的にhttpが利用可能とのこと。wsl -> wsl2に移行して気づいた。wsl2だと仮想マシンのIPがつくのでlocalhost(127.0.0.1)ではテストできんのよね。

2019/7/20 6:38:13

それでAudioContext.audioWorklet.addModuleでエラー。httpだとAudioContext.audioWorkletプロパティ自体が存在しなくなるんだな。

2019/7/21 7:51:17

一つのアプローチとして、

1. web workerの中でwasmを動かして、メモリにレンダリング
2. メインスレッドがメモリをAudioWorkletに渡す
3. AudioWorkletがメモリを128サンプルずつ処理

を試そうとしてる。この間を取り持つのをSharedArrayBufferに担ってもらおうと思った。

2019/7/21 7:56:10

メモリ転送コストというか、コピーのコストは極力減らした形で処理したいと思ったんだな。しかし考えるとWebAssembly.Memoryで作るメモリはSharedArrayBufferにはなれないんですな。現状。

2019/7/21 7:59:08

だからWASMのメモリからSharedArrayBufferへのメモリコピーが発生するんですな。それで過去こんなproposalがあったのですな。。

allow Memory.buffer to be a SharedArrayBuffer · Issue #950 · WebAssembly/design · GitHub
Some background: I'm working on Browsix, a tool for running multiple C, C++, Go and node.js programs as processes in the browser. We do this for C programs by compiling with a (fork) of Emscrip...

2019/7/21 8:04:50

この話はその後wasmのthreadsで議論されて、最終的には

let memory = new WebAssembly.Memory({initial: 1, maximum: 1, shared: true});

「shared」を「true」とすることでSharedArrayBufferになることができるようだ。

2019/7/21 8:05:49

threads/Overview.md at master · WebAssembly/threads · GitHub
Threads and Atomics in WebAssembly. Contribute to WebAssembly/threads development by creating an account on GitHub.

2019/7/21 8:07:10

threadsの仕様も読んどこう。

design/FutureFeatures.md at master · WebAssembly/design · GitHub
WebAssembly Design Documents. Contribute to WebAssembly/design development by creating an account on GitHub.

2019/7/21 8:14:18

threads/SharedArrayBufferはchromeではflagで使えるようにはできるみたいだな。 https://t.co/ruu1Rp4Z0s

2019/7/21 8:19:36

ちょっと試してみようか。SharedArrayBufferはspectre問題で一度すべてのブラウザでdisableにされ、chrome以外のブラウザはまだ使えるようにはなってないようだが、そこの理由も知りたいところだが。

2019/7/21 8:26:15

なかなか重い議論っぽいね。。このあたり。

SharedArrayBuffer and timing attacks (Meltdown and Spectre) · Issue #3 · tc39/security · GitHub
I think everyone was aware that ShareArrayBuffer allows for creating accurate timers. With the recent release of Meltdown and Spectre, SharedArrayBuffer was disabled in all browsers.

2019/7/21 8:27:58

そもそもspectreとかの話って何が問題なのかよくわかってないよなあ。私は。。過去記事をちゃんと読んどくか。そして現状その問題はどうなっているのかだよな。。

2019/7/21 9:43:37

chromeがSharedArrayBufferを再度有効化したのはSite Isorationしたからなのか。。

Spectre/Meltdownとその派生
SCAIS 2019 (Small-workshop on Communications between Academia and Industry for Security) https://researchmap.jp/sug/SCAIS2019/ の発表資料

2019/7/21 16:09:24

CPUのアーキテクチャを追っかけてたのはスーパースケーラとかというワードが目新しいころ。Penitum登場のころくらいまで。分岐予測とかね。今は3次キャッシュ、投機的実行、マルチコア、SIMDとかまあてんこ盛りでまったくついていけてないわ。。

2019/7/21 16:25:54

キャッシュにのると実行時間が短縮されるから、それを高精度タイマーで計測して値を特定するということなのかね?なんかすごい話だな。

2019/7/21 17:27:29

いやそういう話でもないのか。これ読んだけど全く理解できん。なんでこれで任意のメモリを読むことができるのか。。

図解でわかるSpectreとMeltdown - Speaker Deck
A brief explanation of spectre(variant 1) and Meltdown(variant 3)

2019/7/21 17:44:14

まあこれくらいの理解でいいか。。

ブラウザベンダーのSpectre and Meltdown対応 - abcdefGets
Spectre and Meltdownについては前回書いたが、 各ブラウザベンダーがとっている対応について今回は書く。 といっても大したことではないのだが。 対応一覧 Google Chrome SharedArrayBufferのデフォルト無効化とPerformance.nowの解像度を下げる(どこまでかは不明) Per Site Isolationを有効化 Firefox SharedArrayBufferのデフォルト無効化とPerformance.nowの解像度を20μsまで下げる Safari SharedArrayBufferのデフォルト無効化とPerformance.nowの解像…

2019/7/22 5:49:35

いろいろ調べて、ここに行き着いている。

No Image
WebAssembly Worker Based Threads - Chrome Platform Status

2019/7/22 5:49:36

Chrome 74以降、WebAssemblyのスレッドサポートが既定で有効化されているんだな。ということはMemoryのオプションsharedが使えるということだよね。

2019/7/22 5:49:36

ということはWebAssemblyのメモリをshared=trueで作成すると、そのベースとなるbufferは共有利用できる状態になる。つまりSharedArrayBufferになるというわけですわな。

2019/7/22 5:49:36

threadサポートと言っても、別にwasmにスレッドコントロールができるわけではなくて、スレッドで問題となるメモリアクセス競合を回避するための命令が追加されるだけなんだよな。

2019/7/22 5:58:52

つまり、WebAssembly.Memoryをshared=trueで作成すれば、メインスレッド、worker、AudioWorklet間でメモリコピーが発生することなくデータのやり取りができるようになるということなんだな。

2019/7/22 6:03:52

スレッドにおけるメモリアクセス競合の回避手法についてはそりゃもうC/C++の世界では語りつくされた感があるよね。そのあたりを多少知ってると理解しやすいよね。

2019/7/22 6:07:18

ちょっとそれるけど、chrome 75だとメモリのバルク・コピー命令も実装されたようだね。

No Image
WebAssembly Bulk Memory Operations - Chrome Platform Status

2019/7/22 6:11:30

メモリ共有の恩恵を受けるのは大きいサイズの場合であって、小さい場合はコピーとそう変わらないんじゃないかという気もする。メモリ共有自体コストがかかる処理だもんね。。

2019/7/22 21:01:51

さて高校野球チェックの合間にちょこちょこ実装してくとするか。。

2019/7/24 4:31:04

ちょっと前に作ったPSGエミュレータのコードを少し改造してメインスレッドで作成したWebAssembly.MemoryをAudioWorklet上のwasmモジュールと共有できるか試してみた。

2019/7/24 4:41:00

見た目は何も変わらないけどね。chromeはもうすでにwasmのthreadsサポートが既定で動くようになっていた。wasm側はメモリをimportして共有するように修正した。

No Image
WASMでPSG Emulatorを作る
https://t.co/tIhrsb3bYM

2019/7/24 4:45:16

(export "memory" (memory $memory))

(import "env" "memory" (memory $memory 1 1 shared))

wasm側は「shared」を入れ、wat2wasmで--enable-threadsをつけてwasm化する。私はwabt.js使ってるけどね。気を付けなればいけないのはメモリについては最大サイズ指定がsharedの時はmustだってこと。

2019/7/24 4:48:14

メインスレッド側のメモリは「shared」オプションをつけて作成する。

const memory = new WebAssembly.Memory({initial:1,shared:true,maximum:1});

maximum指定をしないとエラーになる。SharedArrayBufferが内部で使われるようだね。
#webassembly

2019/7/24 4:50:30

このメモリはpostMessageで送っても参照のみのコピーとなって、メインスレッドとオーディオ・ワークレットでインスタンス化したwasmと共有できるようになる。

#WebAssembly

2019/7/24 4:52:18

とりあえずできることが分かったので、psgエミュレータを別のワーカーで動かすようにして、メインスレッド・AudioWorklet・ワーカー間で協調動作するようにコードを変えてみる。

2019/7/24 4:55:34

wabt.jsはドキュメント上には書いていないけれど、3つ目の引数としてfeaturesオプションがあって、ここで--enable-xxxxxを設定することができる。

wabt.parseWat(path,watText,features);

例えば--enable-threadsをしたくば
features.threads = true
みたくする。

2019/7/24 4:57:25

wabt.jsのこの辺りのコードを読んで知った。

wabt/demo.js at master · WebAssembly/wabt · GitHub
The WebAssembly Binary Toolkit. Contribute to WebAssembly/wabt development by creating an account on GitHub.

2019/7/24 4:59:07

今回はリングバッファにして、できる限りメモリをロックせず動かそうかなと思う。。

2019/7/24 5:51:20

昔と違ってマルチコアになってるので、それなりにスレッド使わないともったいないよね。。スレッドがコア別に分けられるかはよくわからんけどね。。

2019/7/24 5:53:04

1980年代後半のアーケード基板はオーディオ用にサブCPUを載せてたりしたから、それに倣う感じ。

2019/7/30 6:13:33

実装スピードは夏バテもありものすごく落ちている。超絶ノロノロ状態だが、一日数行でもコードを書いてるのでいつかはできるだろう。。

2019/7/30 6:14:36

仕事から帰るとヘトヘトで何もしたくなくなるんだよなあ。。この時期。

2019/8/3 7:43:41

ようやく実装を終え、デバッグのステータスに入った。

2019/8/3 9:11:27

まだまともに動いてないのでなんなのだが、SharedArrayBufferは、webAssembly,web-worker,AudioWorklet,webgl,メインスレッド間で共有できることを理解した。

2019/8/3 9:15:54

メインスレッドでWebAssembly.Memoryをshared=trueで作ると、そのメモリはコピーコストを伴わずwasm/webgl/worker/audioWorklet間で共有できる。これができるのは今のところchromeだけのようだけど。

2019/8/3 9:19:29

共有メモリにはオペレーションの原子性を保証するメソッド群がAtomicsに定義されている。

2019/8/3 9:20:44

このようなことがJSでできるようになってることはすごいことだね。今更だけど。

2019/8/3 15:30:57

webAssemblyのステップトレースができるchromeもすごい。これがあるのでwatでコーディングするモチベーションを保つことができる。 https://t.co/YiEnMvTfSn

2019/8/3 18:42:03

ウーム。問題発生。今やろうとしてるのは、

1.worker中のwasmでオーディオをレンダリング
2.AudioWorkletでレンダリングしたオーディオデータを再生

で、このデータを受け渡しをSharedArrayBufferでやろうとしてる。

2019/8/3 18:42:03

もう少し細かくいうと

1.メインスレッドでWebAssembly.Memoryを共有モードで作成
2.そのメモリをpostMessageでworkerとAudioWorkletに渡す

ことでメモリを共有して、そのメモリにデータをロード・ストアしてスレッド間のデータ受け渡しをしようとしてる。

2019/8/3 18:49:44

私はWebAssembly.Memoryを共有モード(shared :true)で作れば、postMessageで送っても内部的に作成されるSharedArrayBufferはクローンされずポインタのみ渡されると期待していたがそうではなかった。。クローンされてるようだ。どうもSharedArrayBufferそのものをpostMessageせんといかんようだ。

2019/8/3 18:51:37

WebAssembly.Memoryを生成するときにShareArrayBufferを指定できればよいのだけれど、それはないので、ちょっと工夫しなければならないね。

2019/8/3 19:17:03

WebAsssembly.MemoryにはbufferプロパティがあるのでこれをpostMessageすればよさそうだけど、そうするとworker側のwasmでメモリをインポートすることができんようになってしまうんだな。これが。

2019/8/3 19:17:03

となると、

1.メインスレッド側は必要なメモリページ数を計算
2.workerへ必要メモリページ数をpostMessage
3.worker側でWebAssembly.Memoryを作成。メインスレッドへ内部SharedArrayBufferへの参照を返す。
4.メインスレッドはその参照をAudioWorkletにpostMessage

みたいにすればいいかな?

2019/8/3 19:18:12

しかし現状のレベルではWebAssembly.Memory自体をスレッド間(worker/メインスレッド)で共有できんのですな。これはちと痛いですな。。

2019/8/3 21:02:16

しかしこのサンプルを見ると、WebAssembly.Memoryはスレッド間で共有できてる風なんだけどなあ。ひょっとして何か凡ミスしてるかもしれん。。

threads/Overview.md at master · WebAssembly/threads · GitHub
Threads and Atomics in WebAssembly. Contribute to WebAssembly/threads development by creating an account on GitHub.
https://t.co/WxuGvcjpGS

2019/8/3 21:02:46

まあこのコード見たから「いける!」と思ったんだった。そういえば。。

2019/8/4 11:43:09

どうも私の凡ミスっぽい。WebAssembly.Memoryはshared=trueにすればスレッド間で共有できるのは間違いないようだ。そりゃそうか。。

2019/8/4 11:43:55

私のwasm関数がおかしな動きしてるだけというオチ。

2019/8/5 6:23:00

とりあえずメモリが共有できてることだけは確認できた。が、まだ動いてない。。しょうもないバグだった。しかしまあ、サンドボックス環境(安全性がそこそこ担保された環境)でリニアメモリを各スレッド間で共有して自由にアクセスできるのはちょっとうれしいね。

2019/8/5 6:24:52

PSGエミュレータのworker改造版が動けば、いよいよオリジナル?の波形メモリ音源をWebAssemblyベースで作って先に進めるとしよう。。

2019/8/6 7:44:38

うーむ。音が鳴らんなあ。。

2019/8/9 4:58:28

Bugを追い込んでるが、凡ミス部分がなかなか発見できん。。いうても1日1時間もいじってないけど。。モチベーション低下中。。

2019/8/9 4:59:12

なんかこう、workerのデバッグってやりにくいなあ。。

2019/8/10 16:54:33

いやぁ。ようやく音が鳴るようになったなあ。workerの中で25msのsetTimeoutだとタイマーの間隔が短すぎるようだ。100msくらいにしないとまともに音が鳴らないわ。。

2019/8/11 5:15:47

と思ったけどBugを見つけた。25msくらいでも行けるようになったなあ。。

2019/8/11 5:48:20

現状の成果物はこんな感じ。

Youtube - WebWorker+AudioWorklet+WebAssemblyでPSGをエミュレーションする

2019/8/11 5:49:11

これが一応私の環境で動いてるやつ。。
Chromeしか動きませんが。。

No Image
WASMでPSG Emulatorを作る

2019/8/11 5:55:49

えらい時間がかかってしまったなあ。。
しかしこれで技術的なめどはついたので、いよいよ波形メモリ音源をwasmで作るとするか。。バグを潰してる間もどうしようかいろいろ考えたんだよねえ。。

2019/8/11 5:59:04

波形メモリ+EG+フィルタだよな。やっぱり。ちゅうことでSCC+SIDみたいなやつでいこうかなと。とりあえずそれで設計しつつ実装すると。

2019/8/11 6:00:18

あとはシーケンサかあ。MML書けるようにするかそれともStandard MIDIをそのまま再生できるようにするか。。。

2019/8/11 6:02:56

私REAPERというDAWを使ってるので、JS Pluginで同じ仕様の音源を作って、REAPERで作曲してそのデータを再生するようにしようかなとも思ってる。

2019/8/11 6:12:06

そういえば思い出したのが、WebAudio APIを使ってモジュラータイプのやつを途中までつくってたんだっけ。。ステップシーケンサー作ってる途中でやる気なくしたんだよな。

No Image
https://t.co/0qxAPewFLs

2019/8/11 6:12:07

レコポっぽいシーケンス・エディタを志向しててそれなりにできてた気もするけどなあ。。 https://t.co/kxJeodX2IX

2019/8/11 6:12:57

これ改造してエディタ+シーケンサを作れんかな。。

2019/8/11 8:30:19

まあでもあれかあ、REAPERでやってみるかあ。。

2019/8/12 5:42:19

前作って放置したWebAudioのやつを動画にしてみた。エディタはレコポのコマンドのまんまにしようとしてたみたいね。。

Youtube - Web Audio Moduler

2019/8/12 6:49:28

これはなかなかいいね。。

No Image
Playing Fasttracker 2 .XM files in Javascript – a1k0n.net

2019/8/12 6:49:40

GitHub - a1k0n/jsxm: FastTracker 2 .xm module player in Javascript
FastTracker 2 .xm module player in Javascript. Contribute to a1k0n/jsxm development by creating an account on GitHub.

2019/8/12 7:07:28

おぉ。これはFastTracker IIのクローンか。。

No Image
16-bits.org - home of 8bitbubsy

2019/8/12 7:35:45

うーむ。。。いいね。。

WebSid - the first HTML5/JavaScript C64 music player

2019/8/12 7:57:03

SID界隈のソースをじっくり読もうかのう。。

2019/8/17 8:26:19

帰省中も少し音源のことを考えた結果、音源作る前にシーケンサーのコードをwasmで書こうかなと思った。それでPSGを演奏してみようかなと。MMLっぽい言語のパーサもついでにpegで書いて、それをメモリに落とすコンパイラを作り、シーケンサーに渡して演奏させるようにするつもり。

2019/8/18 8:24:42

と思ったがやっぱりまずは波形メモリ音源を先に作ろうと思う。。どっちやねん。。

2019/8/19 20:28:48

そういうわけで先ずはEGから作り始めている。。

2019/8/21 6:14:06

コツコツmwasm(自作プリプロセッサ)でEQを実装中。もうちょっとでできる。
だいぶwatでの実装も慣れてきた感じ。S式ってシンプルでいいなあ。。 https://t.co/JbmXjRRuul

2019/8/21 6:14:38

EQじゃなくてEGだった。。

2019/8/21 6:16:56

EGを作る

WaveTable部分を作る

一度音を鳴らしてみる

LFOを作る

フィルタを作る

の順番で作っていくつもり。AudioWorklet+Workerで処理が間に合うかはよくわからんね。。

2019/8/23 6:56:06

とりあえずEG出来た。。

sandbox/wpsg.mwat at master · sfpgmr/sandbox · GitHub
JS,WebGL,three.jsをいじるためのレポジトリ. Contribute to sfpgmr/sandbox development by creating an account on GitHub.

2019/8/24 5:40:47

さて次は波形テーブル部分を作るとしますかな。

2019/8/24 5:53:13

実のところEnvelope Genetator(EG)もADSRのそれぞれのフェーズへの移行を直線的、つまり一次関数で実装する分には楽なのだが、アナログ・シンセのEGをまねるとなると結構面倒くさくてですな。。

VSTiの作り方 - 7.おまけ (ADSRの実装) | g200kg Music & Software

2019/8/24 5:53:13

私のEGはもれなくいい加減なやつなんですな。つまり直線的なやつですわ。

2019/8/24 6:02:59

波形メモリもなんちゅうか、エイリアシングノイズが発生するという問題があるので、それをできるだけ抑えてきれいな波形を出すとなると周波数帯域に応じた複数の波形データを用意する必要があったりして、凝りだすと止まらんわけですな。マルチ・サンプルとか言ったりもしますわな。。

2019/8/24 6:02:59

しかしそれは楽器としての話で、例えば古いサウンド・チップなんかはコストがかかる話なので、エイリアシング・ノイズは承知の上で割り切ったりしてるんですな。例えばSCCなんかは8ビット×32サンプルで発声可能なすべての音域をカバーするもんね。

2019/8/24 6:06:55

ということで我々はシステムに起因するノイズが含まれた音を聞くことになるのだけど、そのノイズが聴感上耳障りなのかどうかというのはまた別の話なんですな。そこに独特の味や良さを感じるひとたちもいるわけで。

2019/8/24 6:06:55

SCC・PSGはさらにピッチ・コントロールに制約があるのでちょっと音痴になったりするんだけど、それに違和感を感じる人もいれば、感じない人もいるわけで。

2019/8/24 6:10:29

波形メモリというのはオシレータの一種なわけで。オシレータもいろいろな作り方があるんだよな。例えば計算によってサイン波・矩形波・のこぎり波などの周期波形を出力する方法もある。

2019/8/24 6:16:25

リアルタイムに計算によって波形出力するのは昔はコストが高かったので、あらかじめメモリに波形情報を保存しておいて、それを読み出すことによって波形合成する方式がまず普及したんですな。

2019/8/24 6:20:56

BLITなんかも昔調べたよなあ。。

VSTiの作り方 - 8.おまけ (BLITのお話) | g200kg Music & Software

2019/8/24 6:23:55

サンプリング周波数変換なんかも結構奥が深くてですな。やっぱりノイズを含む問題があって、それを抑えるためのテクニックがあるんですわ。

No Image
サンプリング周波数変換 - Wikipedia

2019/8/24 6:25:11

サンプリング周波数変換だけで一冊の本になってしまうくらいですからな。。

No Image
マルチレート信号処理―レート変換とマルチレートフィルタ | 高橋 宣明, 武部 幹 |本 | 通販 | Amazon

2019/8/24 6:31:39

ちょっと内部的なサンプリングレートを24KHz固定にしようかなぁと考えててね。いまどきのPCはオーディオのサンプリングレートは可変で、それに合わせて内部処理してもいいんだけど、高周波数になるとちょっと処理的にきつそうだし、Lo-Fiな音で十分だという気持ちもある。

2019/8/24 6:31:39

そうはいってもPCの方は再生サンプリング周波数は可変だから、もし内部の周波数を固定にするとレート変換をやらなくてはいけなくなるんだな。でも私のPCだと96KHzくらいでも処理できたりできてるけどね。。さて、どうするか。。

2019/8/28 6:11:58

WaveTableの実装はとりあえず終わり。これからテストに入る。。

2019/8/28 6:12:59

テスト用の音源&UIを作って鳴らしてみる。

2019/8/30 5:22:52

このwasmのデバッガはありがたい。スタックやメモリの内容、ローカル変数の値が見れるしね。S式でソースを書いてるのでフラットモードを追うのはちと面倒だけど。。 https://t.co/QNW2PlC26Y

2019/8/30 5:25:13

wasmで書いた波形メモリのオシレータはようやく動くようになった。

2019/8/31 9:12:20

波形メモリ音源の体裁を整える作業を実施中。コンピュータはメモリへのロード・ストアがいかに多いかがwasmを直接書いてみると実感できる。しかもS式で書きなれてきて、スタックが今どんな状態か頭で想像できるようになってきたわ。

2019/8/31 9:12:20

平行してデジタル・フィルタのコードを物色中。とりあえずはMAMEのSIDのコードを参考にwasmで書こうかなと思っているけど、やっぱりフィルタは重い処理だね。。

2019/8/31 9:13:59

Worker自体で処理するよりは、コードをGLSLで書いてGPUにさせたほうがいいかもしれんな。まあ書いてみんとわからんけど。

2019/8/31 9:16:31

RolandのVSCも最初はフィルタなしだったもんなあ。。

2019/9/4 6:52:08

波形メモリシンセとして動くコードをwasmで書いてるが、call_indiectの書き方でハマり中。。wabt.jsからよくわからないエラーが出てコンパイルできんのですわ。。

2019/9/4 6:54:50

仕様だけで書き方がわからない時は、wasmのテストコードを読んだりしてる。。

spec/call_indirect.wast at master · WebAssembly/spec · GitHub
WebAssembly specification, reference interpreter, and test suite. - WebAssembly/spec

2019/9/4 7:18:18

(table funcref
...
ん、funcref ? なんだこれ。

spec/call_indirect.wast at master · WebAssembly/spec · GitHub
WebAssembly specification, reference interpreter, and test suite. - WebAssembly/spec

2019/9/4 7:22:42

これか。。

reference-types/Overview.md at master · WebAssembly/reference-types · GitHub
Proposal for adding basic reference types (anyref) - WebAssembly/reference-types

2019/9/4 7:28:18

anyfunc から funcrefに変わっとるのね。。

2019/9/4 7:29:23

仕様もそうなっとるな。。

No Image
WebAssembly Core Specification

2019/9/5 5:32:56

それはそれとして、元々の問題は凡ミスだった。。

2019/9/5 5:57:35

波形メモリ音源の実装のめどがつきそうな感じになってきたな。。音が鳴ったらフィルタを作って終わりにしよう。演奏部分(シーケンサ)も作らんといかんしな。。年内にゲームシステムが完成するか微妙になってきたね。もう9月だもんね。。

2019/9/5 5:58:23

ゲーム・システムが完成したらようやくゲームつくりに入れるからなあ。。

2019/9/5 6:02:13

プログラミングにかける時間は平日は多くて1時間、休日は2-3時間くらいだからなかなか進まんよなあ。。それくらいしか集中力が続かんのよねぇ。。

2019/9/5 6:02:59

もちろん趣味のプログラミングに割く時間だけだけどね。。

2019/9/8 6:51:58

ぼちぼちテスト&バグつぶしをやってる。あれれ、memory.grow でエラー出るなあ。。 https://t.co/rFhbOcuVBc

2019/9/8 8:01:55

うーむ。JS側でgrowしてもアウトですな。。 https://t.co/b98pbNl8Cr

2019/9/8 8:02:56

shared arraybufferだとダメなのかな。。。

2019/9/8 8:07:03

普通のmemoryだといけるな。。やっぱりsharedだとmemory.growできん仕様なのかな。。 https://t.co/F5xHT3nT1g

2019/9/8 8:12:08

これはちょっと行き詰った感ありですな。。

2019/9/8 9:17:11

しかしまあ特別shared memoryだからといってmemory.growがfailするとは書いてないからなあ。。

threads/Overview.md at master · WebAssembly/threads · GitHub
Threads and Atomics in WebAssembly. Contribute to WebAssembly/threads development by creating an account on GitHub.

2019/9/8 9:18:22

「grow_memory of a shared linear memory is allowed.」だもんねぇ・・。

threads/Overview.md at master · WebAssembly/threads · GitHub
Threads and Atomics in WebAssembly. Contribute to WebAssembly/threads development by creating an account on GitHub.

2019/9/8 20:19:47

どうもこのBugっぽいねぇ。。

No Image
8564 - Loading issue... - Monorail

2019/9/8 20:29:09

このBugはまだ解消されてない模様。というかIssue9380のためにブロックされているようだ。

No Image
9380 - Loading issue... - Monorail

2019/9/8 20:30:20

ちょっと待ちかあ。初期アロケートメモリを大きくしてテストを続けるかな。。

2019/9/8 20:42:30

そういえばガベコレも動かせるようになったんだよな。。 https://t.co/KIowNFTnbx

2019/9/10 13:18:19

おっと、自作プリプロセッサのバグを発見。修正せねばいかんな。。

2019/9/11 6:12:22

プリプロセッサのバグを取り終え、波形メモリ音源プロトタイプのテスト&バグつぶしを再開。まだちゃんと動いてはいない。。

2019/9/11 6:13:21

プリプロセッサもS式を崩さないように構文設計すればよかったかなあと思ったりするな。。

2019/9/11 6:52:15

今のところ、フィルタなし、波形メモリによるオシレータ、ピッチLFO/EG、アンプLFO/EGという構成になってる。

2019/9/11 6:54:15

WSGやSCCの時代はチップとソフトウェアでこれくらいのスペックを実現してると思う。。

2019/9/11 7:06:49

MOD界隈でもなかなかデジタルフィルタをソフトウェアかつリアルタイムで動かすことはできなかった。そこは長い間DSPが担う部分だったんだよな。。

2019/9/12 5:52:01

とりあえず実行すると何らかの波形出力が得られるようになった。これからUIと簡易シーケンサを作って実際に鳴らしてみるとするか。。

2019/9/12 6:01:22

PSGエミュレータに比べてパラメータが圧倒的に増えたんでちょっと面倒なんだよねえ。。

2019/9/13 6:17:51

先にフィルタを実装してみることにした。。

2019/9/13 6:18:15

このコードを参考にして。。

簡単なデジタルフィルタのサンプルコード | C++でVST作り
簡単なデジタルフィルタの実装についてで説明したフィルタのサンプルコードです。 「Z変換」や「伝達関数」といった高度な数学を極力使わずに実装するフィルタのサンプルコードです。 「簡単なデジタルフィルタの実装について」も合わせてお読みください。

2019/9/13 19:50:01

フィルタ実装は今半分くらい進んでいる。サンプルコードがすごくわかりやすくてbiquadフィルタの理解も少しは高まった気がしないでもない。しかし原理の理解は浅い。。

2019/9/13 19:50:02

離散数値で構成されるデジタルの音の世界では、ある「一定期間の音声データの平均をとること」≒「ローパスフィルタをかける」ことということは感覚的に理解している。

2019/9/13 19:52:06

がそれ以上はよくわからない。よくわからないがしかしフィルタのコード自体はいたって簡単である。がしかしなぜこれでLPFやHPFになったりするのかがよくわからんのであった。。

2019/9/13 21:22:33

2019年のWebAssembly事情 - Qiita
2年前に、[「(Learn the Hard Way)nodejs-8でのWebAssembly自体を調べてみた」](https://qiita.com/bellbind/items/a6435b0c8f10306128b8)として、...

2019/9/13 21:25:57

v8では--wasm-math-intrinsicsが使えるのであった。。これでsin/cosの呼び出しコストが抑えられるのでjsのMathを利用することにした。新たにsin/cosを作るのはとりあえずやめておこう。

2019/9/14 14:17:01

下のサンプルコードをwasmに書き換えた。このフィルタを使えるように波形メモリシンセの修正にこれから入ろうと思う。その前に耳鼻科に行かんとね。。

簡単なデジタルフィルタのサンプルコード | C++でVST作り
簡単なデジタルフィルタの実装についてで説明したフィルタのサンプルコードです。 「Z変換」や「伝達関数」といった高度な数学を極力使わずに実装するフィルタのサンプルコードです。 「簡単なデジタルフィルタの実装について」も合わせてお読みください。

2019/9/16 21:06:00

うーむ。思ったほど進捗できず。。

2019/9/16 21:07:01

まあしかし少しずつでも進めればいつかはできるからね。。

2019/9/18 5:35:57

ようやく音が鳴り、UI作りに入る。UIができたら各パラメータをいじって所望の動きになっているかテストする。 https://t.co/6EARekLIJd

2019/9/18 5:35:58

まだしかし音源としては機能が足りてないので、そこは追加実装しなくてはならない。さて、この音源使い物にはたしてなるのか。。

2019/9/18 7:06:40

まず、波形テーブルの編集部分から作り始めるとするか。。

2019/9/19 6:22:47

そういうことで作成中。数式で波形を生成する機能+ハンド・ドローイングで波形をエディットすることにしてみた。 https://t.co/qHxEAfX5h3

2019/9/19 6:23:59

波形メモリのサンプル数が512だとやっぱり綺麗だな。。 https://t.co/38VKWy2ChD

2019/9/19 6:24:53

サンプル数が16だとレトロな感じ。。 https://t.co/85BrpIejqi

2019/9/19 11:56:14

これを波形メモリに直接反映して結果をすぐ確認できるようにするつもり。波形メモリは共有メモリに格納してるのでこの辺は簡単かと。。

2019/9/19 11:58:28

式で波形生成できるようにしてみたがこれが結構面白くてちょっとハマってる。。

2019/9/19 20:25:57

FM変調風 https://t.co/O1EwWWh3ni

2019/9/19 20:34:03

フーリエ級数による矩形波。ギブス現象が出とる。。 https://t.co/I6lfmzOsen

2019/9/19 20:36:25

級数の数を増やすとほほほぼ矩形波になるな。。 https://t.co/8BhpQJeG9p

2019/9/19 20:38:31

矩形波はこんな式でもいけるけどね。。 https://t.co/DbBAkxdWzu

2019/9/19 20:40:00

鋸波 https://t.co/saMexy7ELA

2019/9/19 20:43:02

三角波 https://t.co/zqRhaIphHW

2019/9/19 21:02:04

フーリエ級数による鋸波
やはり項が有限だとギブス現象が出ますな。。 https://t.co/nHI34guVx6

2019/9/19 21:04:01

多分正弦波の和ですべての波形は表現できるんだろうなあ。フーリエさんちゅうのはすごいですなあ。。

2019/9/19 21:09:28

FMは簡単な実装で複雑な波形を作ることができる。しかもEGだけでフィルタを使わずに含まれる周波数の成分を変えることができるという。

2019/9/19 21:11:58

原理は簡単なんでチップも安価に作ることができるし、PSGに比べてその音色の豊かさは比較にならない。しかも従来のシンセでは出ない音も出すことができたという。。

2019/9/19 21:13:20

FM音源を開発したヤマハ社にはリスペクトしかないですな。おかげでゲーム音楽がリッチになったもんな。。

2019/9/21 5:49:30

波形エディタがようやく動くようになったので動画にしてみた。

Youtube - 波形メモリ音源の制作ー波形メモリエディタ

2019/9/21 6:13:08

WebAssembly.MemoryのbufferがSharedArrayBufferのときgrowできんというBugどうやらFixした模様ですな。。

No Image
8564 - Loading issue... - Monorail

2019/9/21 6:15:05

これがいつChromeに反映されるかだが。

2019/9/21 6:23:15

波形メモリの編集部分がそこそこできたので、音色(Timbre)エディタ部分を作ろうかなと思う。EGやフィルタ・パラメータをいじる部分。

2019/9/23 10:43:55

音色エディタを作成中。ようやく音量のEGとLFOがエディットできるようになった。

Youtube - 波形メモリ音源の制作ー音色エディタ

2019/9/23 10:46:46

年内に所望のゲーム・システムはできるだろうか。やばくなってきたな。。その上に載るゲームのアイデアもモヤっとしとるがな。。

2019/9/23 18:01:51

フィルタのUI作成中。ああ、面倒くさい。。 https://t.co/nzhIOhNolg

2019/9/24 7:19:34

とりあえずフィルタのパラメータいじるとこまでUIコードを書いたがうんともすんともいわない状態。。

2019/9/25 6:05:56

ようやくフィルタが動くようになった。まだなおさないといけないところはある。。

Youtube - 波形メモリ音源の制作ーフィルタの実装

2019/9/25 6:10:35

これが終わったらピッチのテストか。。これでようやく波形メモリシンセとしては完成か。。次は演奏部分(シーケンサ)を作らなくてはいけないな。過去何度も演奏エンジンだけで作ってエディタで挫折してるので、なんとか乗り越えたいところ。。今回はpegで演奏用の言語(MMLではない)を作ろうかなと。

2019/9/25 6:15:05

今回作ってて面白いなと思ったのは、式からの波形生成。以下のような式を作って波形を作ると、鋸波と正弦波が半分ずつミックスされて聞こえるところ。式から聞こえる音がなんとなく想像できるのが楽しいなと。当たり前の話だけどね。。

Math.sin(t * Math.PI) * 0.5 + t * 0.5

2019/9/25 6:15:36

ちなみにtは0-1の間で変化する。。

2019/9/25 6:18:44

まだ単音でしか鳴らせてないので、これが8音ポリくらいになったときに処理負荷がどれくらいになるのか想像がつかんので、やってみるしかないんだけど、そこがちょっと不安かなと。あ、そういえばマルチ・ティンバーで鳴るようにするコードも書かんといかん。

2019/9/25 6:18:44

あとサンプラ機能もな。。

2019/9/26 6:07:04

ピッチ部分のUIも作ったが、見事にBugっている。ピッチEGいじってるうちにパックマンがやられた時のような音が出た。。

Youtube - 波形メモリシンセの作成 - Pitch UIの作成

2019/9/26 6:17:10

波形はこんな感じで、正弦波を加算合成して作ったのですわ。。
(Math.sin(t * Math.PI) + Math.sin(2 * t * Math.PI) + Math.sin(4 * t * Math.PI)) / 3 https://t.co/aZi53CdbtE

2019/9/26 6:52:39

ピッチの算出式はそもそも間違ってるようなので見直さんといかんな。。

2019/9/27 6:27:11

算出式は間違ってなかったけど、アルゴリズムが間違っていたな。。ピッチの計算は誤差の蓄積やら桁あふれやらデノーマルやらを考えるとf32ではなくu64の固定小数点で計算したほうがよさそうだな。。それでやってみるか。。

2019/9/27 6:30:35

f32のままでやってもいいけど小数点以下の桁数を抑えてデノーマルを防ぐようにするという手もあるかなぁ。でも結局波形テーブル引きするときに整数化するからなあ。。

2019/10/4 5:26:07

64bit幅、小数部16bitの固定小数点で波形メモリのピッチを計算しなおすことにして実装中。固定小数点の乗算・除算のコツをすっかり忘れてしまってた。オーバーフローとか乗算後のシフトとか、除算前のシフトとかをね。。

2019/10/4 6:04:35

これまでの成果。LFOとかピッチがちょっとおかしい。。

Youtube - 波形メモリ音源の作成-20191004

2019/10/4 6:06:28

フィルタ使えると管楽器的な音がリアルになるよなあ。やっぱり。時間的な周波数成分の変化は音色にとって重要だなということがわかる。

2019/10/4 6:10:29

chromeでWASMのSIMDが試験的に実装されたので、それをいつどこで使うかだよなあ。まあもうちょっとちゃんと動くようになってから考えるか。

2019/10/4 6:12:28

いちおうオシレータの部分は他の波形生成方式に差し替えできるように作ってるので、音源として完成したらFM方式のオシレータも作ってみたいんだよな。。AFM音源みたいなやつ。。

2019/10/4 7:01:20

それよりもゲーム作りを進める方が先か。。

2019/10/4 7:02:58

あ、それとフィルタのQが全然効いてないのだった。。

2019/10/4 7:17:44

まあしかし、この部分はほんとはAudioWorkletでなく、oscillator nodeやgain node、filter nodeを使用すればもっと簡単に実装できるのだが。

2019/10/5 5:41:50

フィルタのQが効くようになった。またしても凡ミス。LPFはいい感じだけど、HPFの動作がおかしいね。。

Youtube - 波形メモリシンセを作る-20191005

2019/10/5 5:42:33

やっぱりレゾナンス効かせるとシンセっぽくていいなあ。。

2019/10/6 17:12:05

LFO当たりの修正を加える。さらにシンセっぽい音が鳴るようになったな。。

Youtube - 自作ゲーム用の波形メモリ音源を作るー20191006

2019/10/8 7:13:39

シーケンサに手をつけ始めた。シーケンサの構造を考えながら音源のポリ化を進めようかなと。パン二ングも実装せんとなあ。爆発音に必要なノイズジェネレータも実装せんといかんなあ。。

2019/10/14 7:01:06

シーケンサの仕様が固まったので実装しつつ、仮想メモリ音源のマルチティンバー化も並行して進めている。8音か16音ポリのマルチティンバーとなる予定だが果たしてどうか。処理が追いつくのだろうか。。

2019/10/14 7:01:07

多分音を鳴らすだけなら問題ないんだろうけど、ゲームのBGM用だからなあ。。フィルタの処理がやっぱり重いんで気になるところですわ。

2019/10/14 7:04:11

シーケンサの動作確認用も兼ねてMMLみたいな簡易言語を作るつもりである。書いたらバイナリ・データにコンパイルするやつである。

2019/10/14 7:06:34

SIMD使うと2音~4音くらい同時に処理できてパフォーマンスアップできそうだけどね。。

simd/SIMD.md at master · WebAssembly/simd · GitHub
Branch of the spec repo scoped to discussion of SIMD in WebAssembly - WebAssembly/simd

2019/10/14 7:07:01

まあとりあえず全部組み上げてから考えよう。最適化は。。

悠斗@yu_to_0511

2019/10/13 20:38:01

閃光福岡~! #ラグビー日本代表 #ラグビー https://t.co/0weOYnwQSF

S.F.@SFPGMR

2019/10/13 19:53:50

自作のwasmテキストフォーマット(S式)用のプリプロセッサのドキュメントを更新した。

GitHub - sfpgmr/mwasm: wasmテキストフォーマットのプリプロセッサ拡張
wasmテキストフォーマットのプリプロセッサ拡張. Contribute to sfpgmr/mwasm development by creating an account on GitHub.


#WebAssembly

S.F.@SFPGMR

2019/10/12 8:14:36

いきなり停電。
#台風19号

2019/10/12 8:14:59

この段階で停電するとは。。

2019/10/12 8:21:36

とりあえずラジオをつける。手回し付きの充電器付き。
#停電
#台風19号

2019/10/12 8:22:42

おお、復旧した。
#台風19号

2019/10/12 8:59:33

冷蔵庫も停電時の保冷に備えて水を凍らしとかんといかんな。。

2019/10/12 9:00:11

ちなみにスマフォの充電器は20000mのやつを2台確保ずみ。

2019/10/12 9:01:43

さっき編集してたソースコードは吹っ飛びましたな。。

2019/10/12 10:24:38

雨がすごいな。。

2019/10/12 16:58:35

風が強くなってきたな。。

2019/10/12 20:17:55

風は15号の時のほうがすごかった気がするな。。まだ油断は禁物だが。。

2019/10/12 21:26:58

いやいやそんなことはないな。やっぱり怖いや。。

2019/10/12 23:52:20

もう過ぎたか。。

2019/10/13 6:10:22

風は強かったけど、15号の時のほうがヤバかったな。雨はあまり降らずに通過。まああくまでうちの地域はだけど。しかし他県は雨がすごくて氾濫・決壊か。。

S.F.@SFPGMR

2019/10/12 8:45:46

@syntaxerrors72 この間の台風で玄関の門柱が破壊されたので、今回はどうなることやら。。地デジのアンテナが飛んでかないか心配ですが。。

S.F.@SFPGMR

2019/10/12 8:42:27

@syntaxerrors72 マジでした。でも今は復旧してます。水道の水圧もなぜかおかしいです。。

S.F.@SFPGMR

2019/10/10 20:37:53

関東大会の組み合わせが確定したか。。
chbf.or.jp/wp-content/upl…

2019/10/10 20:40:18

習志野は前橋育英、もし勝ったら次はおそらく東海大相模、そして拓大紅陵は花咲徳栄かあ。。厳しいなあ。。センバツも狭き門だ。。

2019/10/10 20:42:05

桐生第一は1勝すればほぼセンバツ当確かあ。やはり地元開催は地の利があるなあ。。

S.F.@SFPGMR

2019/10/10 4:32:05

週末の台風大丈夫だろうか。。

S.F.@SFPGMR

2019/10/6 9:52:07

習志野と拓大紅陵の決勝。やはり竹内くん、山内くんは投げないわな。堀井くんと加藤くん。加藤くんは一年生か。。山内くんはセンターか。。

2019/10/6 9:52:36

打撃力もあるからね。。

2019/10/6 10:19:00

堀井くんの投球フォームってなんか古谷くんに似てる気がするなあ。。

2019/10/6 10:25:50

拓大紅陵の佐藤くん2回表3Kか。すごいな。。

2019/10/6 10:54:47

と思ったら3回で8-1か。。こりゃ一方的な展開。

2019/10/6 10:57:37

何より和田くんが長打したのが良いね。

2019/10/6 10:59:54

ピッチャー山根くんに交代か。もうちょっと堀井くん投げて欲しかったけどなあ。。

2019/10/6 15:02:58

結果は習志野14-3拓大紅陵か。竹内くんのリリーフはなかったのね。まあ序盤であれじゃ投げる場面はふつうないなあ。。関東大会での活躍に期待といったところか。

2019/10/6 15:02:58

習志野はこれで関東大会の1回戦は他地区の2位と戦うことになって多少有利になる。その次が結構高い壁なんだよな。。クジ運も大事。でも今の習志野のチーム力だといける確率はかなり高い。和田くんもこれで勢いがついて関東大会でも活躍してほしいね。

2019/10/6 15:07:38

堀井くんー山根くんの継投で3点に抑えたのもよかったよな。ただ堀井くんちょっとコントロールに課題ありそうだね。。

2019/10/6 17:53:56

関東大会各県代表

【群馬】
1桐生第一
2前橋育英
3健大高崎

【茨城】
1常総学院
2霞ヶ浦

【栃木】
1青藍泰斗
2文星芸大附

【埼玉】
1花咲徳栄
2西武台

【山梨】
1山梨学院
2駿台甲府

【神奈川】
1東海大相模
2桐光学園

【千葉】
1習志野
2拓大紅陵

2019/10/6 17:55:59

うーむ。やはりそうそうたるメンツですな。浦和学院や横浜、作新学院の名がないのがちとさみしいが。。

2019/10/6 17:57:33

さて、習志野は昨年に続いてセンバツ出場なるか。そして拓大紅陵は久々のセンバツ出場を果たすのか。

S.F.@SFPGMR

2019/10/6 17:21:36

ナムコの波形メモリ音源の存在に最初気付いたのはやっぱり「ディグダグ」かなあと思うな。なんかあきらかに他のゲームと音の質が違ってたし、目立ってたもんなあ。。当時波形メモリ音源なんていうのは当然知らんけど、音の違いだけは分かってた感じですな。

Youtube - 1982 [60fps] Dig Dug 4452990pts Hardest Round256

2019/10/6 17:24:55

マッピーなんちゅうのはデモ音で十分ゲーセンで目立ってて、さらにゲーム始めるとBGMが響き渡ってすごく目立ってましたな。

Youtube - 1983 [60fps] Mappy 1075810pts Nomiss Round50

2019/10/6 17:27:44

「リブル・ラブル」もそこそこ面白くて結構お金使ったけど、BGM聴きたさもちょっとあったと思うな。。なんか今聞いてもいい音してると思ってしまうなあ。。

Youtube - 1983 [60fps] Libble Rabble 1775070pts 20miracles

2019/10/6 17:30:34

ギャプラスも今聞き返すと結構リッチな音鳴ってますなあ。PSGとは明らかに違う。

Youtube - 1984 [60fps] Gaplus 10000000pts (Loop1 st1-256)

2019/10/6 17:33:07

ギャラガもそうなんだよな。ゲーム・スタートとかネーム・エントリとかもね。これを当時PSG装備のPCで真似てもその音には決してならんかったもんな。なんで違うんだ?と当時思った。波形が違うと知ったのはかなり後の話。

No Image
YouTube

2019/10/6 17:34:50

よく聞いたらパックマンもそうですな。。なんか鋸波っぽい音もしてるもんな。。

Youtube - 1980 [60fps] PuckMan 300000pts Nomiss

2019/10/6 17:40:29

パックマンは私自身下手過ぎて洒落にならんかった。だけどうまい人のプレイを見てるのは楽しかったなあ。。