進捗

QMK薙刀式の新しいロジックは、おおよそ実用的な実装ができた。

github.com

評価関数としては、キーごとに「他のキーとラップしている時間/キーを押している時間」を計算して、平均値を取っている。これで、今のところ調子良く打てている。

https://github.com/eswai/qmk_firmware/blob/a9f730ae3c9b96fcae48fb3d6e5a19ea10da370e/users/naginata_v15x/naginata_v15x.c#L1057

おもしろいのは前置シフトのみか、後置シフトも認めるかも、評価関数で処理できたことかな。2キー目がシフトだったら0点を返すとするだけで、後置シフトしない設定にできた。

https://github.com/eswai/qmk_firmware/blob/a9f730ae3c9b96fcae48fb3d6e5a19ea10da370e/users/naginata_v15x/naginata_v15x.c#L1039

今のところ4キーまでの組み合わせを評価している。5キー目を押すと変換を開始するが、例えば「もみもみ」みたいにシフトを押しながら5キー目に入る場合は、バッファを完全にクリアせず、シフトキーはバッファに残さないといけない。 5キーにバッファを拡張したいが、バッファをあふれた時の処理を先に煮詰めないといけないのかな。

QMK薙刀式の進化

これまでの薙刀式キーマップは、入力したキーをバッファに保管し、キーを離し始めたタイミングでバッファの先頭から辞書にしたがって変換していくものでした。

しかし、少しでもキープレスが重なっていたら同時押しと判定していたので、高速打鍵での意図しない変換が多かったり、長い連続シフトの判定を誤ったりしていました。

今でも日常使いでそれほど問題はないのですが、Mac用の薙刀式変換ソフトBenkeiはもっと高度な判定をしたいと考えていたので、一旦まずはrubyで新しいロジックを書いてみて、うまくいけばBenkeiやQMKに書き換えようと思っていました。

なかなか手がつかなかったのですが、かな漢字変換のロジックを読んだ時に、薙刀式変換でも同じことだと思い、rubyで書いて試してみたところ、いくつかの例でうまく動作し、また先に挙げた問題点も解決できそうなので、QMKでの実装を開始しました。

基本的なロジックは
1. キー入力をバッファにためていく
2. 全てのキーを離したら変換開始する。それまでは何も出力しない。
3. バッファの中のキーがとりえる組み合わせ(各キーが単独押しか、同時押しか、連続シフトなのかなど)を全部列挙する。この組み合わせは事前に定義されたテーブルに従っている。
4. まず、この組み合わせから辞書にない同時押しを含む組み合わせは削除する。
5. 次に残った組み合わせを評価関数に通して点数付けし、一番点が高い組み合わせを採用する。

評価関数として、キーを押してる時間に対する、他のキーとの重なり時間の割合、としてみた。評価関数はいろいろ考えられるし、キーの組み合わせごとに変えるとかもできるはず。

これまで考慮していなかった時間を導入したので、ちょっとくらい重なっていても、2つの単独押しとするなどができる。

また、最初に全部の組み合わせを列挙するので、考慮しないパターンというのはないはず。現時点で4キーまでの組み合わせテーブルを持っている。5キーになると組み合わせが爆発してくるので、まだ作っていないが、5キーまでは実用的に必要だと思っている。

反面、全てのキーを離すまで何も表示されないというのはデメリットである。
全ての組み合わせを網羅したいというコンセプトとの背反である。

とりあえず編集モードなしのQMK実装を書いてみて、変換できることを確認した。2キー同士押しはいい感じだが、3キー同時だと2+1や1+2キーの同時押しになりやすい。これは評価関数によるもので、チューニングが必要である。
また、かなり実行時にメモリをつかうらしく(ファームウェアは小さい)、AVRではハングアップした。RP2040なら動作する。これは配列をPROGMEMでファームウェア上に確保することで解決できるだろう。

書き殴ったコードなので整理が必要だし、編集モードは実装してないし、実用的に動作するレベルではないが、今後の進化余地はありそう。評価関数で挙動が変えられるので、いろいろ試せるだろう。

汎用キーマップ変換ソフトの、DvorakJや紅皿とは違うアプローチであるのも面白い。

薙刀式の進化に合わせて、こちらも進化を見せることができそうです。

QMKのOS DETECTION

QMKにはキーボードをつないだ先のOSが何かを推定して返す機能がある。

QMK Firmware

WindowsMacでキーマップを変えたい時などに非常に有用な機能で、OSによってControlキーとCommandキーを入れ替えるなどに使える。 起動時に実行されるkeyboard_post_init_user関数で、OSを判別してレイヤーを変えるわけだが、ドキュメントにも書いてあるようにこれが機能するまでには少し時間がかかる。 RP2040で試してみた結果、400msほど待ってからdetected_host_os()をコールすれば、レイヤー変更が実行された。

void keyboard_post_init_user(void) {
  wait_ms(400);
  switch (detected_host_os()) {
    case OS_WINDOWS:
      layer_move(_WIN);
      break;
    case OS_MACOS:
    case OS_IOS:
      layer_move(_MAC);
      break;
    case OS_LINUX:
      layer_move(_WIN);
      break;
    default:
      layer_move(_WIN);
  }

M1 Macでffmpegエンコード

H265でハードウェアエンコードをするメモ。 古い画像なので、ノイズ除去とdeinterlace付き。

ffmpeg -i input.mov -c:v hevc_videotoolbox -q:v 65 \
       -vf yadif,format=yuv420p,hqdn3d=1:1:9:9 \
       -c:a aac_at -b:a 192k output.mp4

ソフトエンコードの場合は

ffmpeg -i input.mov -c:v libx265 -preset medium -crf 19 \
       -vf yadif,format=yuv420p,hqdn3d=1:1:9:9 \
       -c:a aac_at -b:a 192k output.mp4

ソフトウェアエンコードの方がきれいらしいが、 速度はハードウェアエンコードの方が圧倒的に速い。