Timidity++ っぽい MIDI プレイヤーを作りました。
前回に引き続き、Midy の機能確認やバグ潰しが目的で作ったアプリですが、
割と人気の UI ではあるので使い道もあるかも知れません。
本当は紹介のためにスクリーンレコーダーで録画してみたのですが、
Web Audio API がうまく録音できなかったです。音なしだと面白くないので動画は特になし。
私も割と好きな UI ですが Velocity は鍵盤の色で表現するほうが良いと思っていたので、
64〜191 の間で色を調整して表示しました。これだけでだいぶコンパクトにできます。
それ以外は Timidity++ とだいたい同じですが、簡易的なミキサーアプリとしても使えるようにしています。
スライダーがありきたり過ぎるので改良しようかとも思ったのですが…、
面倒すぎてデフォになりました。スライダーは弄ろうとするとなかなか大変です。
実装では鍵盤をどう光らせるかで多少悩みました。
Web Audio API でやろうとすると、ended event はありますが、started event がないので、意外と難しいです。
AudioBufferSource.start() と同じタイミングで動くようにタイマーを設定すると、
タイマーの数が 2倍になってしまって速度の問題が出てきてしまいます。
Web Audio API を使ったタイマーだと負荷が大きくなってしまうので、
requestAnimationFrame() で描画タイミングと同期しながら、
noteOn などの時間を監視して光らせるのがおそらく一番効率が良いです。
鍵盤を光らせるには Midy 内部で処理するイベントのタイムラインを見ながら処理します。
Midy の再生開始判定と、@marmooo/midi-player の判定は微妙に違っています。
@marmooo/midi-player は再生ボタンを押したときにサウンドフォントの読み込みもします。
このへんの処理をどうすれば楽にできるかを考えていて少しだけハマったので、
再生ボタンを押したときから isPlaying = true な変数を持つように実装を加えたところ、
割と簡単に GUI 拡張を作れるようになりました。
GUI 側でも isPlaying の状態を持つことで、再生の終了判定も容易になりました。
最近の Chrome は AudioContext をつけっぱなしにすると
CPU をかなり消費するようになったので、こまめに AudioContext を ON/OFF しています。
Chrome の AudioContext の CPU 負荷はバグとしか思えないので、
そのうち直っているかも知れませんが。
最後に鍵盤を鳴らす実装をしていると、グリッサンドに耐えられない問題が発生しました。
事前にすべてをキャッシュするのも手と思ったのですが、
keyRange/velRange と 2つパラメーターがあるのでちょっとメモリが心配です。
そこで await で音声波形をデコードする前にスケジューリング配列に追加してしまうことで、
問題なく再生できるとわかりました。
ただこれだけだと処理時間が少ないことで運良く実行できているだけだと思うので、
スケジューリング配列に登録するとき note に pending 状態を付けて、
pending 中に noteOff が発生したときは、noteOn の処理内で noteOff も実行するようにしました。
これならリアルタイムな割り込みが発生しても問題なく処理できるはずです。
ここまでの実装で Timidy は動くようになったので公開としましたが、色々と余地はあります。
例えば midy 0.4.0 の noteOn は、SF2 modulation に渡す状態配列や noteOff と整合性を保つために
await を付けて処理していますが、波形のデコードが 〜50ms で、
状態配列 (256 x 32bit = 1KB) のコピーが 〜0.02ms であることから、
noteOn から noteOff までの間に状態配列と SF2 modulation に変化がなければ、
await せず状態をコピーしながら処理でき、Worker で並列処理で高速化可能のはずです。
面倒そうだけど並列処理すればグリッサンドに対してより頑強になるはずです。
これもそのうち検証しようとは思いますが、まずはイベント数を減らすほうが確実とは思います。
marmooo's blog
2025年12月14日日曜日
2025年11月25日火曜日
GM2 MIDIミキサー Humidy を作った
MIDI Player/Synthesizer ライブラリ Midy の実装がだいぶ進んできて、
GM2 の再生も安定してできるようになってきました。
まだ細かい実装不足やバグ、再生負荷の課題はあると思うのですが、そろそろ実用段階に入ってきています。
そこでバグ潰しも兼ねて、GM2 の機能をすべて使える MIDI Mixer アプリ Humidy を作ってみました。
GM2 は仕様がかなり大きいので、機能をすべて使ったアプリとか見たことないんですが、実際のところどうなんでしょう。 ちなみにすべての機能を本気で使おうとすると UI が複雑になり過ぎるので省略している箇所はありますが、ライブラリからはもちろんすべて使えます。 なるべくシンプルに作ったつもりですが、複雑な機能は簡単な UI にはしにくいので、 普段は表示しないように押し込み、設定項目も無理やり減らしています。
名前は Timidity++ のもとになった英単語で timidity があって、 同じように midi が出現するもう一つの英単語として humidity があるので、 humidity と Midy をもじって Humidy としました。
Midy は自分に合わせて作っているので作りやすいのは当たり前とはいえ、 かなり短いコードで音楽ミキサーアプリを作ることができました。なかなかいい感じ。 動的サウンドフォント、動的 fetch プログラムチェンジ、GM2 なども動くようになったので、いよいよライブラリとしても完成度が高まってきました。 もう少し高速化したらすべての MIDI ライブラリは Midy に移行できそう。 速度も激ヤバ MIDI 以外なら問題になることはないので、もう実用レベルと思います。 激ヤバ MIDI は瞬間的なイベント数の負荷がブラウザの限界に達して死ぬので、イベント数を減らす処理をこれから入れていきます。
MIDI はサウンドフォント周りをもっと設定できたら面白そうなので、 もう少し色々改良したいなと思っています。個人的に気になるのはリバーブです。 MIDI はサウンドフォントで Reverb Effects Send を決め打ちしますが、 そこで決め打ちすると楽器によってはリバーブ効果がわからなくなります。 現実のリバーブは Reverb Effects Send のように楽器によって効果が決まるのではなく、 周波数に応じてリバーブの効果が変わる (低音ほど消える) はずなので、 音響理論で考えると微妙な気もして、設定できたほうが嬉しい機会もあると思いました。 開発者以外でこれに悩む人はいるのかという疑問はありますが、 MIDI プレイヤーをゼロから実装していると、こういう細かいところが気になってきます。
バグ潰しのために、さらに何種類かアプリを作ってみる予定です。
GM2 は仕様がかなり大きいので、機能をすべて使ったアプリとか見たことないんですが、実際のところどうなんでしょう。 ちなみにすべての機能を本気で使おうとすると UI が複雑になり過ぎるので省略している箇所はありますが、ライブラリからはもちろんすべて使えます。 なるべくシンプルに作ったつもりですが、複雑な機能は簡単な UI にはしにくいので、 普段は表示しないように押し込み、設定項目も無理やり減らしています。
名前は Timidity++ のもとになった英単語で timidity があって、 同じように midi が出現するもう一つの英単語として humidity があるので、 humidity と Midy をもじって Humidy としました。
Midy は自分に合わせて作っているので作りやすいのは当たり前とはいえ、 かなり短いコードで音楽ミキサーアプリを作ることができました。なかなかいい感じ。 動的サウンドフォント、動的 fetch プログラムチェンジ、GM2 なども動くようになったので、いよいよライブラリとしても完成度が高まってきました。 もう少し高速化したらすべての MIDI ライブラリは Midy に移行できそう。 速度も激ヤバ MIDI 以外なら問題になることはないので、もう実用レベルと思います。 激ヤバ MIDI は瞬間的なイベント数の負荷がブラウザの限界に達して死ぬので、イベント数を減らす処理をこれから入れていきます。
MIDI はサウンドフォント周りをもっと設定できたら面白そうなので、 もう少し色々改良したいなと思っています。個人的に気になるのはリバーブです。 MIDI はサウンドフォントで Reverb Effects Send を決め打ちしますが、 そこで決め打ちすると楽器によってはリバーブ効果がわからなくなります。 現実のリバーブは Reverb Effects Send のように楽器によって効果が決まるのではなく、 周波数に応じてリバーブの効果が変わる (低音ほど消える) はずなので、 音響理論で考えると微妙な気もして、設定できたほうが嬉しい機会もあると思いました。 開発者以外でこれに悩む人はいるのかという疑問はありますが、 MIDI プレイヤーをゼロから実装していると、こういう細かいところが気になってきます。
バグ潰しのために、さらに何種類かアプリを作ってみる予定です。
2025年10月2日木曜日
中学理科一問一答・中学社会一問一答を作った
中学理科一問一答と中学社会一問一答を作りました。
きちんと教科書を使って作っているので、教科書準拠の重要語句を手軽にチェックできます。
苦手分析もしっかりできるので、学校・塾・家庭でも使いやすいんじゃないかな。
中学理科は計算問題を含めていないので語句・公式の確認に使えるくらいですが、それだけでも多くの人に使い道があると思います。
四択問題で簡単なので、正答率は8割以上が目安なんじゃないかな。
間違った問題は復習が必要です。
重要語句の意味や事実は静的なので、AI 生成することで作ってみました。 穴埋め問題は AI が最も得意とする分野なので、精度も非常に高いことが期待できます。 とはいえ融通が効かず 10分前に話した内容をすぐ忘れる AI さんに作ってもらうのは大変でした。 それでも人間が作るより 100倍くらいはコストが低いと思いますし、 100倍楽なのだから頑張ろうと思って作りました。 いかに安定して生成させるか、いかに質を安定させるか、 いかに選択問題として使えるようにするか、いかにメンテできるようにするかが重要になります。 AI さんの知識量は凄いですが、行動は物忘れが激しいため細かい指定をしても守ってくれません。 テストをきちんと書くことが大切だなと思いました。 結構色々なチェックをしているので、問題がクソなケース以外はかなり除外できていると思います。 問題がクソかどうかはたくさんプレイしてみてわかることなので完璧は難しいですが、 ある程度は自分でもプレイしてみて確認はしています。 このへんの開発の手間具合は、1年経ったらまた状況は違うんでしょうが、現状は AI があってもやはり大変です。
アプリとして公開できるようにするためには、かなりチェックが必要でしたが、 それでも一度作ってしまえば、メンテコストは低いし、生成コストも、チェックのコストも低いのが良いところです。 違う問題を作ってと言えば、他の問題も作れます。 人間にこれをやらせると、個人開発では絶対無理だし、集団でもとんでもなく時間が掛かります。 人間や過去問をベースとして作るよりAI で作ったほうが、一般性も網羅性も高くなる利点はあるので、結構良い AI の利用例かなと思います。 ただ社会はかなり安定して問題を作れる一方で、 理科は AI さんも知識不足な気がするので、問題はだいぶ自作しました。 社会は割と安定して出力できるものの、やはり致命的なミスがたまにあったりするので、日頃の確認が必要です。
近年は高校受験や大学受験の問題を見ても、一問一答そのものが問題として出てくる機会はなくなっていますが、 知識確認には依然として有用です。 問題を解いた後に、どれくらい他のことを言えるか考えてみたり、使い道はたくさんあります。 人気の問題集とかを見ても、結局は一問一答の延長線である問題のほうが多いので、 実質的にはみんな今も使っている状態と思います。
そういえば AI で作れるよなー、くらいの気持ちで作ってみましたが、なかなか良いんじゃないかと思います。 他のアプリもまったく確認せず作り始めたのですが、いくつかはあるみたいですね。 まあ AI 生成ドリルとか、塾用のとか色々あるもんな。 でもなんというかすぐに使えるものはなかなかないし、実際欲しいのはすぐ使えるものなので、まあ良いかなという気持ちです。 今のところ中学社会一問一答・中学理科一問一答という名前にしていますが、 今後の実装レベルによっては名前を変えるかも知れません。
重要語句の意味や事実は静的なので、AI 生成することで作ってみました。 穴埋め問題は AI が最も得意とする分野なので、精度も非常に高いことが期待できます。 とはいえ融通が効かず 10分前に話した内容をすぐ忘れる AI さんに作ってもらうのは大変でした。 それでも人間が作るより 100倍くらいはコストが低いと思いますし、 100倍楽なのだから頑張ろうと思って作りました。 いかに安定して生成させるか、いかに質を安定させるか、 いかに選択問題として使えるようにするか、いかにメンテできるようにするかが重要になります。 AI さんの知識量は凄いですが、行動は物忘れが激しいため細かい指定をしても守ってくれません。 テストをきちんと書くことが大切だなと思いました。 結構色々なチェックをしているので、問題がクソなケース以外はかなり除外できていると思います。 問題がクソかどうかはたくさんプレイしてみてわかることなので完璧は難しいですが、 ある程度は自分でもプレイしてみて確認はしています。 このへんの開発の手間具合は、1年経ったらまた状況は違うんでしょうが、現状は AI があってもやはり大変です。
アプリとして公開できるようにするためには、かなりチェックが必要でしたが、 それでも一度作ってしまえば、メンテコストは低いし、生成コストも、チェックのコストも低いのが良いところです。 違う問題を作ってと言えば、他の問題も作れます。 人間にこれをやらせると、個人開発では絶対無理だし、集団でもとんでもなく時間が掛かります。 人間や過去問をベースとして作るよりAI で作ったほうが、一般性も網羅性も高くなる利点はあるので、結構良い AI の利用例かなと思います。 ただ社会はかなり安定して問題を作れる一方で、 理科は AI さんも知識不足な気がするので、問題はだいぶ自作しました。 社会は割と安定して出力できるものの、やはり致命的なミスがたまにあったりするので、日頃の確認が必要です。
近年は高校受験や大学受験の問題を見ても、一問一答そのものが問題として出てくる機会はなくなっていますが、 知識確認には依然として有用です。 問題を解いた後に、どれくらい他のことを言えるか考えてみたり、使い道はたくさんあります。 人気の問題集とかを見ても、結局は一問一答の延長線である問題のほうが多いので、 実質的にはみんな今も使っている状態と思います。
そういえば AI で作れるよなー、くらいの気持ちで作ってみましたが、なかなか良いんじゃないかと思います。 他のアプリもまったく確認せず作り始めたのですが、いくつかはあるみたいですね。 まあ AI 生成ドリルとか、塾用のとか色々あるもんな。 でもなんというかすぐに使えるものはなかなかないし、実際欲しいのはすぐ使えるものなので、まあ良いかなという気持ちです。 今のところ中学社会一問一答・中学理科一問一答という名前にしていますが、 今後の実装レベルによっては名前を変えるかも知れません。
2025年9月7日日曜日
謎のエフェクトライブラリ emoji-particle を作った
謎のエフェクトライブラリ emoji-particle を作りました。
イメージ図のように、絵文字で花火を打ち上げたり、ポップコーンっぽいエフェクトを表示できるライブラリです。
柔軟なエフェクト設定ができるため様々な用途に応用できます。
Demo でおおまかな動作を確認できますし、 marmooo/emoji-particle から MIT ライセンスでコードを利用できます。
前からずっと似たようなものは欲しかったのですが、 真面目に実装すると大変で放置していたのですが、 既存アプリが増えてきていよいよ欲しくなってきたので作りました。 Web Worker + OffscreenCanvas + 効率的な更新処理で実装しているので、 無駄に高速・高機能なライブラリとなっています。 内部の実装もかなり色々な最適化をしているので、大量に絵文字を飛ばしても重いと感じることはほぼないでしょう。
Worker を使ったライブラリを何も考えずに公開すると同一ドメインの制約があって使いにくいので、 インライン化することで簡単に使えるようにしています。
こういったエフェクトは、良いものを作ろうとすると画像が必要ですが、 たくさん画像を使い始めると取り扱いが急に面倒になります。 RPG ツクールのホコグラっぽく管理すれば多少は…とは思うのですが、そういうことを考えるのも嫌です。 画像を扱い出すとと、ファイルサイズも大きくなるし、画像ファイルの管理も面倒だし、 ライブラリのロードも面倒になります。 絵文字はどんな環境でも使えるカラフルな画像集なので、 このようなときに最も扱いやすいです。
シンプルな割にはあらゆる場面で使えて便利なライブラリだと思っています。 これまで作ったアプリたちにもこれから組み込んでいきます。 それっぽいエフェクトを付けたい時には最も重宝するライブラリになりそう。
Demo でおおまかな動作を確認できますし、 marmooo/emoji-particle から MIT ライセンスでコードを利用できます。
前からずっと似たようなものは欲しかったのですが、 真面目に実装すると大変で放置していたのですが、 既存アプリが増えてきていよいよ欲しくなってきたので作りました。 Web Worker + OffscreenCanvas + 効率的な更新処理で実装しているので、 無駄に高速・高機能なライブラリとなっています。 内部の実装もかなり色々な最適化をしているので、大量に絵文字を飛ばしても重いと感じることはほぼないでしょう。
Worker を使ったライブラリを何も考えずに公開すると同一ドメインの制約があって使いにくいので、 インライン化することで簡単に使えるようにしています。
import { createWorker } from "emoji-particle"; するだけで使えるようになっています。
Worker 系のライブラリだとあるあるなんでしょうが、ビルドはみんなどうしてるんでしょう。
私はもちろん esbuild でオレオレビルドです。
こういったエフェクトは、良いものを作ろうとすると画像が必要ですが、 たくさん画像を使い始めると取り扱いが急に面倒になります。 RPG ツクールのホコグラっぽく管理すれば多少は…とは思うのですが、そういうことを考えるのも嫌です。 画像を扱い出すとと、ファイルサイズも大きくなるし、画像ファイルの管理も面倒だし、 ライブラリのロードも面倒になります。 絵文字はどんな環境でも使えるカラフルな画像集なので、 このようなときに最も扱いやすいです。
シンプルな割にはあらゆる場面で使えて便利なライブラリだと思っています。 これまで作ったアプリたちにもこれから組み込んでいきます。 それっぽいエフェクトを付けたい時には最も重宝するライブラリになりそう。
2025年8月26日火曜日
頻出順の英和辞書 mGSL を更新した
頻出順の英和辞書 mGSL を更新しました。
以前開発した mGSL は頻出順データ自体は最強でしたが、
既存の辞書を利用しているため和訳の粒度にバラツキがあり、英和辞書としては不安定でした。
そこで生成 AI を活用して簡易的な和訳を作り、最強の和英辞書に作り変えました。 生成 AI を使って詳細な辞書を作るのはかなり苦しいと思いますが、 英単語学習では典型的な意味表現のみを知っていれば十分です。 なるべく覚える言葉自体が少なくなるように和訳の粒度を調整した辞書として mGSL を更新しました。 このような用途では生成 AI による文章生成が極めて有効です。 とはいえ既存の辞書データでさえ 3万語あったので、すぐにはできません。 AI の生成は頻繁に壊れるので完全には自動化できないため、 サボれる時間を見つけてちまちまと文章生成を繰り返すことで構築しました。
まずは既存の辞書に登録されていた 3万語まで和訳を付けました。 しかし既存の辞書のデータは頻度データをきちんと考慮していないので、 実際には頻度7000語くらいまでしか安定して登録されていません。 それ以降は歯抜けが多いので、ちまちまと翻訳を作っていく必要があります。 lemmatization されたデータは 6万件あります。 厳密な頻度で 3万語に到達する頃には、3万5000語くらいになってそうです。 これはさすがに果てしない…ということで、頻度 1万語までは完璧なものにしてこの記事を書きました。 それ以上はニーズの低さからやる気があまり出ないですが、ぼちぼちやりたいところ。 1万語あれば海外の大学生くらいの語彙数になるので、たいていのニーズは満たせるでしょう…。
生成された訳は目視で気になる点はチェックしており、 機械的に処理できるようにフォーマットを整えたりしています。 訳が不安定なところも微修正しています。 ドイツ語やイタリア語など、英語以外の語彙も含まれているので、英語学習には不向きなものも多々あります。 これらは機械的に除外できるようにしました。 AI さんに頼んでもすぐ崩壊するのでこのへんは手動で直すしかありません。 手動は手間ですが、和訳を作る部分が一番時間が掛かるので、90% は時間を削減できているでしょう。 それでも結構な時間は掛かりました。単調すぎて眠いのが地味に厳しかった。 ただその甲斐もあってか、以前は見つからなかったアラも多少修正できました。 依存ライブラリをがっつり減らすことができて、だいぶ気楽になりました。
英単語学習の辞書データとしては、より詳細なものを作る以外だと、 これ以上のものを作るのは難しいんじゃないかな。 あるとしたら lemmatization をちょっと改良できるくらい。これはいずれ検証したい。 あとはいよいよ接尾辞や現在分詞、過去分詞をもっと考慮して語彙数を減らしていくほうが、辞書としては質が高くなるのかもなあ。
Vocabee など既存の英単語アプリ、 graded-enja-corpus などの派生ライブラリには反映済みですが、 新規アプリも今後作っていきます。 やはり和訳の粒度を調整できているのはあまりにも大きい。 以前と変わらず CC-BY-SA で使えるので、使いたい人はどうぞ。
そこで生成 AI を活用して簡易的な和訳を作り、最強の和英辞書に作り変えました。 生成 AI を使って詳細な辞書を作るのはかなり苦しいと思いますが、 英単語学習では典型的な意味表現のみを知っていれば十分です。 なるべく覚える言葉自体が少なくなるように和訳の粒度を調整した辞書として mGSL を更新しました。 このような用途では生成 AI による文章生成が極めて有効です。 とはいえ既存の辞書データでさえ 3万語あったので、すぐにはできません。 AI の生成は頻繁に壊れるので完全には自動化できないため、 サボれる時間を見つけてちまちまと文章生成を繰り返すことで構築しました。
まずは既存の辞書に登録されていた 3万語まで和訳を付けました。 しかし既存の辞書のデータは頻度データをきちんと考慮していないので、 実際には頻度7000語くらいまでしか安定して登録されていません。 それ以降は歯抜けが多いので、ちまちまと翻訳を作っていく必要があります。 lemmatization されたデータは 6万件あります。 厳密な頻度で 3万語に到達する頃には、3万5000語くらいになってそうです。 これはさすがに果てしない…ということで、頻度 1万語までは完璧なものにしてこの記事を書きました。 それ以上はニーズの低さからやる気があまり出ないですが、ぼちぼちやりたいところ。 1万語あれば海外の大学生くらいの語彙数になるので、たいていのニーズは満たせるでしょう…。
生成された訳は目視で気になる点はチェックしており、 機械的に処理できるようにフォーマットを整えたりしています。 訳が不安定なところも微修正しています。 ドイツ語やイタリア語など、英語以外の語彙も含まれているので、英語学習には不向きなものも多々あります。 これらは機械的に除外できるようにしました。 AI さんに頼んでもすぐ崩壊するのでこのへんは手動で直すしかありません。 手動は手間ですが、和訳を作る部分が一番時間が掛かるので、90% は時間を削減できているでしょう。 それでも結構な時間は掛かりました。単調すぎて眠いのが地味に厳しかった。 ただその甲斐もあってか、以前は見つからなかったアラも多少修正できました。 依存ライブラリをがっつり減らすことができて、だいぶ気楽になりました。
英単語学習の辞書データとしては、より詳細なものを作る以外だと、 これ以上のものを作るのは難しいんじゃないかな。 あるとしたら lemmatization をちょっと改良できるくらい。これはいずれ検証したい。 あとはいよいよ接尾辞や現在分詞、過去分詞をもっと考慮して語彙数を減らしていくほうが、辞書としては質が高くなるのかもなあ。
Vocabee など既存の英単語アプリ、 graded-enja-corpus などの派生ライブラリには反映済みですが、 新規アプリも今後作っていきます。 やはり和訳の粒度を調整できているのはあまりにも大きい。 以前と変わらず CC-BY-SA で使えるので、使いたい人はどうぞ。
2025年7月6日日曜日
圧倒的インフレゲームの億千万タイピングを作った
圧倒的インフレゲームの億千万タイピングを作りました。
タイピングは色々なものを作っていますが、タイピングを最も学ぶのは小3〜小4なので、
その年代でより面白いものが作れればと前々から思っていました。
という訳で作ったのがこれで、学習指導要領に合わせて万・億・兆などの桁を学びながらタイピングができます。
さらに京・垓・秭・穣・・・無量大数まで対応しているので、圧倒的インフレのタイピングを楽しめます。
タイピングとしてはすこし難しいけど、面白いかもなという感じです。 私は小さな頃、家に転がっていた参考書を読んでいたら無量大数まで桁があることを知ったのですが、 今の子はどうやって覚えるんでしょう。兆の先を知る機会ってあんまりないんじゃないかな。 こんな感じの神ゲー(笑) で遊んでみるとすぐに覚えられます。
いわゆるインフレゲーはたくさんありますが、無量大数がすぐに出てくるゲームはなかったと思う。 ゲームの終盤になってやっと出てくるのが限度でしょう。学習用途で使うのはなかなか難しい。 その点、億千万タイピングはスタート時点から無量大数に親しめるので、効率的に勉強できます。
億の桁を超えると、ローマ字を表示しきれなくなるのでどうするかで悩みましたが、 表示しきれないものは見えないようにしてしまって、 桁が変わるごとにテキストを削減することで対応しました。 何回か遊べば、その後は違和感なくプレイできると思います。
神ゲーというかネタゲーですが、たまにはこういうのも良いと思う。 無量大数の得点をゲットできるので、友達と争うのにいいかも。 打鍵速度が十分に早くなってくると引き運ゲー感があるけど、そこはまあ仕方ない。
タイピングとしてはすこし難しいけど、面白いかもなという感じです。 私は小さな頃、家に転がっていた参考書を読んでいたら無量大数まで桁があることを知ったのですが、 今の子はどうやって覚えるんでしょう。兆の先を知る機会ってあんまりないんじゃないかな。 こんな感じの神ゲー(笑) で遊んでみるとすぐに覚えられます。
いわゆるインフレゲーはたくさんありますが、無量大数がすぐに出てくるゲームはなかったと思う。 ゲームの終盤になってやっと出てくるのが限度でしょう。学習用途で使うのはなかなか難しい。 その点、億千万タイピングはスタート時点から無量大数に親しめるので、効率的に勉強できます。
億の桁を超えると、ローマ字を表示しきれなくなるのでどうするかで悩みましたが、 表示しきれないものは見えないようにしてしまって、 桁が変わるごとにテキストを削減することで対応しました。 何回か遊べば、その後は違和感なくプレイできると思います。
神ゲーというかネタゲーですが、たまにはこういうのも良いと思う。 無量大数の得点をゲットできるので、友達と争うのにいいかも。 打鍵速度が十分に早くなってくると引き運ゲー感があるけど、そこはまあ仕方ない。
2025年6月15日日曜日
シームレスなエフェクトを適用するアプリ CV-Masker を作った
シームレスなエフェクトを適用するアプリ CV-Masker を作りました。
マスクを手書きで設定して、そのマスクに対してグラデーションをかけつつシームレスなエフェクトを適用できます。
色々なエフェクトを用意しているので画像はあくまでイメージですが、こんな感じの画像をサクッと作れます。
最初は cv.colorChange, cv.illuminationChange, textureFlattening などの シームレスなエフェクトを与える関数の確認のために作っていたのですが、 いくつかボツ案があったので、マスクにエフェクトを掛けて遊ぶアプリに変えました。
当初の目的のシームレスなエフェクトの関数は、良い感じの画像を作れるのですが、 へぼい CPU だと処理速度がちょっと遅かったです。 コードを見ると SIMD + Threads の最適化は甘そうなので、将来の改善に期待です。 やはり OpenCV と言えども、コア部分以外は遅い時もあるとわかりました。 あと textureFlattening は実行するたびに結果が異なるので元の実装がバグってると思う。
OpenCV の cv.colorChange などの関数は高度なシームレス処理を行っていますが、 たいていそこまで精度は必要ありません。 そこで自作の軽量な汎用局所シームレス関数を作って遊べるアプリにしました。 0/255 で書いたマスクを boxFilter でグラデーション化して、 グラデーション化したマスクに任意のエフェクトを掛け合わせます。 処理は非常に軽いですが、十分なシームレス感があります。 どんなエフェクトでもシームレスに適用できますが、 一般的かつシンプルなエフェクトをいくつか利用できるようにしておきました。 局所モザイク、局所シャープ化、局所色調補正などが利用できます。 いざ作り始めたら追加したいエフェクトが多すぎて困ってきましたが、 応用的なエフェクトは別のアプリで作ります。 アルゴリズム多すぎのものはすぐに組み込むのが難しいです。
シームレスなエフェクトを加える関数は、メモリリークが直らず苦労しました。 やはり C++ は行数が増えてくると、ハマったときになかなか厳しい。 結局少し前のバージョンでは直らず、すべて書き直したら直りました。 メモリリークそのものは input event で大量に処理させるとすぐに見つかります。 たぶん MatVector の扱いが一番難しいのですが、 push_back() はコピーらしいので、すぐに delete() するのが綺麗だと思う。 参照がどうなってるか熟知してないとできないのが厳しい。
色々なエフェクトを用意しているので画像はあくまでイメージですが、こんな感じの画像をサクッと作れます。
最初は cv.colorChange, cv.illuminationChange, textureFlattening などの シームレスなエフェクトを与える関数の確認のために作っていたのですが、 いくつかボツ案があったので、マスクにエフェクトを掛けて遊ぶアプリに変えました。
当初の目的のシームレスなエフェクトの関数は、良い感じの画像を作れるのですが、 へぼい CPU だと処理速度がちょっと遅かったです。 コードを見ると SIMD + Threads の最適化は甘そうなので、将来の改善に期待です。 やはり OpenCV と言えども、コア部分以外は遅い時もあるとわかりました。 あと textureFlattening は実行するたびに結果が異なるので元の実装がバグってると思う。
OpenCV の cv.colorChange などの関数は高度なシームレス処理を行っていますが、 たいていそこまで精度は必要ありません。 そこで自作の軽量な汎用局所シームレス関数を作って遊べるアプリにしました。 0/255 で書いたマスクを boxFilter でグラデーション化して、 グラデーション化したマスクに任意のエフェクトを掛け合わせます。 処理は非常に軽いですが、十分なシームレス感があります。 どんなエフェクトでもシームレスに適用できますが、 一般的かつシンプルなエフェクトをいくつか利用できるようにしておきました。 局所モザイク、局所シャープ化、局所色調補正などが利用できます。 いざ作り始めたら追加したいエフェクトが多すぎて困ってきましたが、 応用的なエフェクトは別のアプリで作ります。 アルゴリズム多すぎのものはすぐに組み込むのが難しいです。
シームレスなエフェクトを加える関数は、メモリリークが直らず苦労しました。 やはり C++ は行数が増えてくると、ハマったときになかなか厳しい。 結局少し前のバージョンでは直らず、すべて書き直したら直りました。 メモリリークそのものは input event で大量に処理させるとすぐに見つかります。 たぶん MatVector の扱いが一番難しいのですが、 push_back() はコピーらしいので、すぐに delete() するのが綺麗だと思う。 参照がどうなってるか熟知してないとできないのが厳しい。
const resultVec = new cv.MatVector();
for (let i = 0; i < 4; i++) {
const ch = srcChannels.get(i);
resultVec.push_back(ch);
ch.delete();
}
手軽にいい感じのエフェクトが作れるので、結構使いやすい気がします。
登録:
コメント (Atom)







