doubledepth

Codeを書くまでが遠い

“オートメーション工場”の分岐の巨大な入れ子が再描画されてもweb browsersが応答不能状態に陥らないようにしたい。分岐構造の描画領域を複数頁に分割すれば解決できそうな気がするが、その場合は分岐の入れ子構造を素朴にHTMLに転写できなくなる。それは私に扱える複雑さを超えるので可能なら避けたいが、代案を思いつかないまま数日が過ぎた。しんどいのはいやだ、諦めたくない。

これに限らずクソデカBMS問題への対処法がわからない。54.8 GiBのBMSON file(演奏時間2年)を圧縮中にCPU使用率100 %のままcomputerが応答不能状態に陥り、私の作業中のdataが吹っ飛んだ。たった今の出来事だ。寝よう!

ビーエム・エスパーザ(必殺技)

BMX2WAV v2の#RANDOM#ENDRANDOMは、たぶん変数のblock scopeとして理解できる。
#title flow test
#bpm 60
#wav11 01.wav
#wav22 02.wav
#wav44 04.wav
#wav66 06.wav
#wav88 08.wav
#wav99 09.wav
#wavbb 11.wav

#00111:1100000000000000

#random 2

#00112:0022000000000000

#if 1
#wav33 03.wav
#00113:0000330000000000
#endif

#00114:0000004400000000

#random 2
#if 1
#wavcc 12.wav
#00213:000000cc00000000
#endif
#if 2
#wavdd 13.wav
#00214:00000000dd000000
#endif
#endrandom

#if 2
#wav55 05.wav
#00115:0000000055000000
#endif

#00122:0000000000660000

#if 1
#wav77 07.wav
#00123:0000000000007700
#endif

#00124:0000000000000088

#endrandom

#00225:9900000000000000

#if 2
#wavaa 10.wav
#00211:00aa000000000000
#endif

#00212:0000bb0000000000
title = "flow test";
bpm = 60;
wav["11"] = "01.wav";
wav["22"] = "02.wav";
wav["44"] = "04.wav";
wav["66"] = "06.wav";
wav["88"] = "08.wav";
wav["99"] = "09.wav";
wav["BB"] = "11.wav";

data["001"]["11"] = ["11",,,,,,,];
{
    let value = getRandomInteger(1, 2);

    data["001"]["12"] = [,"22",,,,,,];

    if (value === 1) {
        wav["33"] = "03.wav";
        data["001"]["13"] = [,,"33",,,,,];
    }

    data["001"]["14"] = [,,,"44",,,,];
    {
        let value = getRandomInteger(1, 2);
        if (value === 1) {
            wav["CC"] = "12.wav";
            data["002"]["13"] = [,,,"CC",,,,];
        }
        if (value === 2) {
            wav["DD"] = "13.wav";
            data["002"]["14"] = [,,,,"DD",,,];
        }
    } // end of inner let scope

    if (value === 2) {
        wav["55"] = "05.wav";
        data["001"]["15"] = [,,,,"55",,,];
    }

    data["001"]["22"] = [,,,,,"66",,];

    if (value === 1) {
        wav["77"] = "07.wav";
        data["001"]["23"] = [,,,,,,"77",];
    }

    data["001"]["24"] = [,,,,,,,"88"];

} // end of outer let scope

data["002"]["25"] = ["99",,,,,,,];

if (value === 2) { // undefined global value
    wav["AA"] = "10.wav";
    data["002"]["11"] = [,"AA",,,,,,];
}

data["002"]["12"] = [,,"BB",,,,,];

Scopeの外のcode blockは、少なくともBMX2WAV上では(分岐指定時に明示的にcheckしない限り)演奏されない。この日記を書いているうちに書式違反に寛容になれそうな方法を思いついた! 寝る。

括弧英数字keysその野良邦訳

Notesの個別化はBMSON形式でなければ難しそうだが、Sonorousの括弧英数字拡張を導入すればBMS形式でも記述はできそう。Data文が関数型言語かbrainfxxkみたいになりそうだが。

#(1204)11:01(+)(23+)(24+ -25])02()00(+])

(うわあ……。)(+)はTick Objects、(23+)は発音されるTick Objects、(24+ -25])は発音されるTick Objectsと同時にChargeNotes終端keyup発音、(+])は終端発音無しのHellChargeNotes終端、()00、みたいな感じ? 実際は正負符号のような重要な記号を無造作に扱うわけにもいかないだろうから、いまはとりあえず「囲まれたASCII印字可能文字keysを受理しうる」くらいのゆるい雰囲気でparserを書き進めている。何も考えずに書いた前述の例を眺めていて突然気がついたが、括弧英数字拡張ならBMSONのLayered Notesも普通に表現できそうだし、Sonorous仕様から外れるが4桁以上の小節番号も読み書きできそう。#(3724800)01:UXとか。


最初の壁が鉄壁すぎる。不完全な入れ子構造への対処法を求めるあまり、私はとうとうHTML parser仕様を眺め始めた。う〜ん、わからん。100層の入れ子分岐から#ENDIF#ENDRANDOMを全部消し去ってもuBMplayは100層の入れ子分岐として解釈してくれる。つまり事前に数え上げているわけではない。


なんか、BMSのLAYER画像を「BMSON layer_events仕様を満たす透過画像」に一括変換するところまで含めて、Web browser上でJavaScriptだけで完結できそうな気がしてきた。でもこのFileSystemDirectoryEntry.getFile()とか、使えるのだろうか。この機能は標準ではなく、標準化の予定もありません。公開されているウェブサイトには使用しないでください。」とあるけど。まあいいか。

JSON.parse(BMSON) vs 初手で分岐を構文解析しないとぐちゃぐちゃになるBMS形式

Programmingの素養がない私にとってBMSはあまりにも高すぎる壁だった。uBMplayやmBMplayのように「#ENDIFが省略された入れ子無しの#RANDOM」と「入れ子の#RANDOM」を区別したいが、私にはそのalgorithmがわからない。事前に#IF#ENDIFの個数を数えるとか糞みたいな方法しか思いつかない。


beatoraja 0.8.1、Java 15環境だとversion checkが走った際も“An illegal reflective access operation”が警告される。beatorajaのversion checkは起動するつど走るわけではなく、体感では週に一回くらいの頻度だと思う。この機能を無効化する提案をどこかで見かけて、へえ〜そういうのが気になる人もいるのか〜と新鮮に思った。

Une Nuit sur le Mont ChauveBemuseで遊ぶ

そのままではBemuseでは遊べないので、以下の手順を踏む。

  1. BMSをたくさん作るぜ'20/bald folderをどこか別の場所にcopyして、適当に名前を変更する。
  2. Copyされたfolder内の、sub folders配下のfilesをすべてBMSON filesと同じ場所に移す。
  3. Copyされたfolder内のBMSON filesを削除し、代わりに参照先を平坦化した差分図表を置く。
  4. Chromeの場合は、Copyされたfolderそのものを、Bemuseの選曲画面にdrag-and-dropする。
  5. Firefoxの場合は、copyされたfolderの中身を全選択してまるごと選曲画面にdropする

Bemuseのpitch changing機構と管弦楽曲の相性は最高だった。しっかり作られた管弦楽器のKEY音が、演奏を誤ると狂った音階に化けるのが、たまらなくthrillingで楽しい。決めの密着LongNotesがふにゃふにゃになった時など絶頂すら覚える。

Bemuseのこの仕組みは音階notesに対しては「演奏している実感」を絶大にboostする一方で、rhythm系の打楽器に対する影響は小さい(「そんなこともあるだろう」みたいな感じ)。たとえば大雑把な塊に分けられたbreakbeatsなどであれば、「Notesを演奏するtimingがずれたら、そのKEY音だけ再生速度が加速または減速する」のようにできれば、聴覚上のfeedbackが直撃して楽しそう。こういった演奏失敗時の音声処理も、各notesごとに指定できたりすると面白そう。

BMSChecker v1.0.1v1.1.0

昨年末にreleaseされていた。BMSから参照されるresourcesの構成まで検証してくれるところが強み。今回の更新では無音notesの含有率とかまで出してくれるようになった。いつかどこかのBMS eventが無音notesを60 %くらいまで許容していたような記憶がある。今でもそうなのかは知らないが、無音含有率をこのように定量化できるなら、省力化したいBMS作家にとっては有益かもしれない。

Anzu BMS Diff ToolはBMS filesの比較に特化している。どちらも比較だけでなく図表の単純な誤りも検出してくれるので、これらの支援toolsがBMS作家に広く知られると良いと思う。「叩かなくてもBGMで勝手に鳴る重複notes」とか絶滅してほしいし、従来は全notes見逃しplayくらいしか確認する術がなかった(のでたかしクンみたいな長尺大量譜面構成はほぼありえなかった)。検証器、最高。

Radio buttonは一般的には排他選択肢として用いられるので、この場合はcheckbox一個だけにするか、 のほうが良いのでは。と思うけど、将来的な機能拡張の準備だろうか。

可視notesを#000に置いている図表は警告されるが、teletroitのような例もあるので鵜呑みにはできない。“teletroit”のn譜面#049以降は明らかに誤りだが、重複定義によるnuanceはおそらく意図されたものだろう。無視できない警告だけを取捨選択する判断が検証者には求められる。

間違ってUne Nuit sur le Mont Chauveをcheckしてしまったところ、ものすごく待たされた。Abort buttonが欲しい。と一瞬思ったけど、Windowを閉じればよかったのか。Throbberが回っている最中に閉じるのって怖くない?

Last Resort Font

この書体はCategoryを示し、Firefoxは“豆腐”にCodepointを直接示す。


Commentで「Unicode関連の検証に役立つかもしれないやつ」としてご紹介いただいた書体。WOFF 2.0形式に変換すると204 KiBに収まる軽量さから、Webpage側がFallback fontとして用いる際に有用かも。FileFormat.infoなどは相当昔からこの書体を使っていた。私見ではこの書体の最も重要な点は「そこに文字がある」という情報が絶対に欠落しないところ。“豆腐”に徹する職人魂。

Tsubasa Mai Kaze#TITLE“翼舞狂に、#ARTIST“烈 ]|光|[ ~神圣之翼~”に変更した例。

beatoraja用ModernChic skinが用いるMgen+書体に含まれない文字は単に描画されないが、

Last Resort書体は文字数が合致する。

まあWindowsでBemuseを使えば普通に文字が描画されるんですけどね。

ア……aエイsync

NTTのwebpageでIアイPピーvブイ6ろくと読み仮名が振ってあって、それでこそ日本だよね、せっかく表音文字を使っているのだから私もがんがん読み仮名を振っていこうと思った。モ……mogrify(読めない)

beatoraja 0.8.1の判定幅

(beatoraja 0.8.1のTiming Graph標本:)
#DEFEXRANK 2
基準判定幅の2 %、BMS形式における最も狭い判定幅。
#DEFEXRANK 3
基準判定幅の3 %。
#DEFEXRANK 4, #DEFEXRANK 5
基準判定幅の4 %から5 %。同一の判定幅として描画されている。実際のところは不明。
"judge_rank": 5
基準判定幅の5 %、BMSON形式における最も狭い判定幅。
#RANK 0, #DEFEXRANK 0, #DEFEXRANK 34, "judge_rank": 0, "judge_rank": 25
VERY HARD判定。
#RANK 1, #DEFEXRANK 67, "judge_rank": 1, "judge_rank": 50
HARD判定。
#RANK 2, #DEFEXRANK 100, "judge_rank": 2, "judge_rank": 75
NORMAL判定。
#RANK 3, #DEFEXRANK 1, #DEFEXRANK 134, "judge_rank": 3, "judge_rank": 100
EASY判定。
#RANK 4, #DEFEXRANK 167, "judge_rank": 4, "judge_rank": 125
VERY EASY判定。

  • [beatoraja固有] BMSONの"judge_rank": 0–4は、BMSの#RANK 0–4と一致する
  • [beatoraja固有] BMSの#DEFEXRANK 0は、BMSの#RANK 0と一致する
  • [beatoraja固有] BMSの#DEFEXRANK 1は、BMSの#RANK 3と一致する
  • [書式仕様に沿った目安]
    Label #RANK #DEFEXRANK "judge_rank"
    VERY HARD03425
    HARD16750
    NORMAL210075
    EASY3134100
    VERY EASY4167125

    註: 判定幅の実装は、各clientによって異なる

Une Nuit sur le Mont Chauve"judge_rank": 3は、既定の判定幅を値100とするBMSON書式仕様に照らし合わせると異常に厳しい判定となるはずだが、beatorajaではEASY判定として遊べるNothing But Sevenの24k/48k図表も"judge_rank": 2だったりして、書式仕様の誤解例が案外多いようでもあり、こうなるとbeatorajaの解釈が事実上の標準として今後も支持されそう。

math: 22201222012^{2^{20}-1}
sup: 2220−1
img: 2^{2^{20}-1}

数式を画像で賄えば、縦書きHTMLの始祖さえsupportできる。画像の代替textとしてTeXを書けば、screen readersの一部はうまいこと読んでくれそう。数式画像はTeXclipなどで生成できる。TeX codeは数式の画像からも得られる。ならもう最初から数式画像だけでよくない? と思ったけど平文を画像化しているTweetとか個人的に不便に感じているので、やっぱり私はもうちょっと機械をいたわる方向に進みたい。Content MathMLとPresentation MathMLの相互変換器とか、楽しい。

先日HTML内のMathML内にHTMLのmark要素がうっかり混ざったが、仕様上問題なかった。ヨシ!


WSL2からbeatorajaを起動しようとしたが、応答はあっても起動はしなかった。ならばと「WSL2 + Ubuntu 20.04でGUIアプリを動かす」と「WSL2でGUIアプリを起動」を試し、どちらの方法もxeyesを起動するところまではいけたが、肝心のbeatorajaは起動せず。特に何もしなくても2021年内にはWSL2でGUI表示が可能になりそうという噂もあり、私はVcXsrvとMobaXtermをuninstallした。

10³¹⁵⁶⁵² ←ただのUnicode上付き数字

JavaScriptってどうやって書くんだったかしら、と脳霧brain-fogを振り払っていたら、もう普通にBigIntとかが使えるようになっていて隔世の感があった。WebKitにBigInt型が実装されたのは公開のSafari 14かららしいので、今すぐ使うのはややためらわれる。最大値が環境に依存するらしいことも気になる(64-bit Blinkは22301M<223022301M2230{2^{2^{30}-1}\leq M}<2^{2^{30}}64-bit Geckoは22201M<222022201M2220{2^{2^{20}-1}\leq M}<2^{2^{20}}WebKitは私には確認不能)。しかし64-bit Gecko基準でも少なくとも3.37057×103156523.37057103156523.37057\times 10^{315632}あたりまでは精度を保ったまま整数演算ができるはずだから、私の用途ならまったく問題なさそう、とてもありがたい。

日記ついでにMathMLを使い始めた。Blinkには簡易CSSを拝借して対処した。問題は非視覚系browsersで、たとえばw3mだと意味不明になるFirefoxならContent MathMLも使っていけるが…… [追記] 使えません。いつもの勘違いでした。すみません。ついでなのでMDNの例のようにContent MathMLも混ぜ書きしたところ、w3mがさらに混沌としてきた

beatoraja日記

PowerShell v7.1.1をキメた。Ubuntu + PowerShellでDrag-and-Dropとかapplication実行(&構文みたいなexec奴)とかどうやるのかな〜と検索している。

beatorajaをUbuntuで最速で動かす」を実行済みの環境で、そういえばJava 15にできるのかな、と思い立って以下を実行した。できたっぽい。

sudo apt remove bellsoft-java11-runtime-full
sudo apt autoremove
sudo apt install bellsoft-java15-runtime-full
sudo apt update
sudo apt upgrade

勘でcommandを打った後で、このJavaがLibericaという名前でv15が出ていたことを知る。このJavaは「JavaFX(OpenJFX)をbundleしているJava」であるらしく、--module-path--add-modulesを指定する必要がない(というか指定すると駄目だった)。以下の指定でbeatorajaはとりあえず起動した。DelimitorがSEMICOLONでないことに気が付かず10分ほど悩んだ。

exec java -XX:+UseShenandoahGC -Xms4g -Xmx4g -cp /home/username/Desktop/beatoraja0.8.1/beatoraja.jar:ir/* bms.player.beatoraja.MainLoader

[VMware Workstation 16 Player + Ubuntu 20.04 + Liberica JDK 15 + beatoraja 0.8.1] かつ“MUSIC SELECT” skinがModernChicSelect-2のとき、異常終了した

INFO: 描画されないことが確定しているSkinObject削除 : 17 / 761
Jan 18, 2021 4:51:10 AM bms.player.beatoraja.MainController create
INFO: 初期化時間(ms) : 49188
VMware: vmw_ioctl_command error Cannot allocate memory.
Aborted (core dumped)

beatoraja-configからPLAY buttonを押下すると選曲画面の音楽が流れ始めるが、画面が真っ黒のまま延々待たされbeatorajaが突然終了する。その後“Sorry, the application java has stopped unexpectedly. Send problem report to the developers?”と尋ねられる。開発者とは、beatorajaの? Javaの? Ubuntuの? わからないのでmessageboxを閉じる。詳細はこんな感じだった

“MUSIC SELECT” skinをbeatoraja defaultに変更すると、ModernChicの選曲BGMが演奏されたままBMSも同時に演奏された。これは一度も選択していないスキン種類が変なresourcesを参照する現象に関係があるかもしれない(ないかもしれない)。あとJava 11 + beatoraja 0.7.6では以下のerrorは出ていなかったような気がする…… が、どちらもuninstallしてしまったため確認不能。[翌日追記] Java11 + beatoraja 0.7.6の頃も以下の警告は出ていた。たまたまlogが残っていた。

(java:1894): Gdk-WARNING **: 04:47:36.957: XSetErrorHandler() called with a GDK error trap pushed. Don't do that.

ModernChicSelect-2の設定項目「画像フォントの使用」から「使用しない」を選択したところ、無事に選曲画面に辿り着けた。画像フォントはUnicode時代には好ましからざる手段なのかもしれない。

私へ: WSL1 + Ubuntu 18.04をuninstallするべからず

2020年4月から今日までの当日記logが、古いSafariやAndroid/iOS環境で私の期待通りには描画されていなかった。CSS Logical Propertiesのvendor接頭辞を復活させて解決した。Internet Explorer 8以前、Presto Opera、Firefox 40以前の各browsersには、現在の当日記用CSSは反映されない。

先日の<U+1F441 U+200D U+1F5E8>の件、実装者側が仕様に“No”を突き付けていけるのは良いことだろう、と考え直した。MathMLもJavaScriptに委ねるべきなのかな〜私べつにapplicationを作りたいわけじゃなくて普通に日記の中で分数を書きたいだけなんだけどな〜

はっちゃけあやよさん(49)

iOSからWeb拍手を経由して、絵文字忍者の肌色多様性を示してくださった匿名さん、ありがとうございました。しかしWeb拍手はあらゆる絵文字をcommentから消し去ってしまった。まあShift_JIS時代のserviceだから仕方ないのだけど…… 申し訳ないのでこの場で肌色忍者について言及してみる。

🥷🥷🏻🥷🏼🥷🏽🥷🏾🥷🏿

画像はTwemojiから。これらの絵文字そのものをBMSON上でescapeすると、以下のような感じ。

{
"version":"1.0.0",
"info":{
"title":"\uD83E\uDD77\uD83E\uDD77\uD83C\uDFFB\uD83E\uDD77\uD83C\uDFFC\uD83E\uDD77\uD83C\uDFFD\uD83E\uDD77\uD83C\uDFFE\uD83E\uDD77\uD83C\uDFFF",
"artist":"131",
"init_bpm":140,
"judge_rank":84,
"total":32,
"level":1,
"mode_hint":"beat-5k",
"resolution":2
},
"lines":[{"y":0},{"y":8}],
"sound_channels":[{
"name":"v_foon.wav",
"notes":[{"x":1,"y":8}]}
]}

\uD83E\uDD77は無添加のU+1F977 NINJAを示す。忍者にU+1F3FB..1F3FFを後置すると、(肌色の異体字selectorsをsupportする環境、かつ肌色の異体字selectorsをsupportする書体なら)肌の色が変わる。

前述のBMSONをBemuseにDrag-and-Dropした結果。

Windows 10 20H2 + Bemuse 48.3の場合、Firefoxでは豆腐忍者と肌色成分が別個に描画される。Vivaldiでは忍者も肌色成分もすべて豆腐になる。おそらく2021年のFeature Updateを経れば、多様な肌色の忍者たちが描画されるようになるだろう。


もちろん書体によって絵柄が異なるうえ、絵文字の異体字の解釈も機種に依存する場合がある。ちょうど目玉の絵文字にEye in Speech Bubbleという好例があったので紹介すると、

👁️‍🗨️
Twemoji画像
👁‍🗨
Twitter型
👁️‍🗨️
Facebook型

Firefox 84はTwitter型の<U+1F441 U+200D U+1F5E8>“Eye in Speech Bubble”とは解釈しない(目と吹き出しを別個の絵文字として解釈する)。Vivaldiはどちらも“Eye in Speech Bubble”とみなす。Unicode仕様に準拠しているのはFirefoxのほうだが、Blinkは仕様を後からどうにでも変更できるようなので最初からBlinkに合わせるのが合理的という結論になり、多様性という語のmetamessageにげんなりさせられる。閑話休題、この差異はもちろんBemuseにも反映される

#TITLE 𠄔U+20114とか#GENRE 👁U+1F441とか

環境と実装を限定すれば、Unicodeの文字列値を用いたBMSは現時点でも成立する。しかし可能なら非ASCII文字列値はOADX+型#BACKBMP"title_image"などで補完するのが無難と思われる。

(Bemuse, mBMplay, Qwilight, ruv-itに関する退屈な詳細)

Bemuse

BOMつきUTF-8符号化BMS形式BMSON形式で図表を作成したうえで、Unicodeの文字列値を普通に記述すれば、Unicode文字はBemuse上で描画されうる。(BMSON形式の場合、"title": "\uD840\uDD14\u8A00""genre": "\uD83D\uDC41"のように非ASCII文字をescapeしておくほうが、いくつかの準拠度がいまひとつな実装にも図表著者の期待通りに文字列が解釈される可能性が高まる)

Web browsersが描画できない文字はBemuseも描画できない。たとえば指先忍者 かえる変化の術なんですけろ幼女氏のimpressionで感嘆符の代役を務めた🥷は、iOSやAndroid以外のOS上では現時点では文字化けを示す矩形(俗称は豆腐)として描画される。Twitterは独自の絵文字描画libraryを持つため、Twitter上では既に忍者の絵文字が飛び交っているが、この文字をBemuseに描画させることはiOSやAndroid以外のOS上では現時点ではできない。

Windows 10 Version 20H2 (日本語環境) + Firefox 84.0.2 + Bemuse 48.3の場合、U+20114細明體MingLiU書体で描画され、U+1F441はSegoe UI Symbol書体(白黒)またはSegoe UI Emoji書体(色付き)で描画される。Windows 10がUnicode 13.0をsupportすれば、🥷も描画されうる。

Ubuntu 20.04 + Firefox 84.0.2 + Bemuse 48.3の場合、U+20114は文字化けを示す矩形として描画され、U+1F441Firefoxに組み込まれたEmojiOne書体描画されるEmojiOne Mozilla書体がUnicode 13.0をsupportすれば、🥷も描画されうる。UbuntuにおけるFontLink相当の設定を変更すればU+20114も描画される可能性がありそうだが、私は元に戻せそうにないので試していない。

Qwilight

BOMつきUTF-8符号化BMS形式BMSON形式で図表を作成したうえで、Unicodeの文字列値を普通に記述すれば、Unicode文字はQwilight上で描画されうる。Windows 10が描画できない文字はQwilightも描画できない。たとえば🥷は現時点では文字化けを示す矩形として描画される。U+20114はおそらく細明體MingLiU書体で描画され、U+1F441はSegoe UI Symbol書体で描画される。

mBMplay

BOMつきUTF-8符号化BMS形式で図表を作成したうえで、Unicodeの文字列値を普通に記述すれば、Unicode文字はmBMplay上で描画されうる。Windowsが描画できない文字はmBMplayのtitlebarにも描画されない。たとえば#GENRE 👁。この文字列値が指定された図表をWindows 7やWindows 8.1やWindows 10 Version 1511以前の環境で演奏すると、mBMplayのtitlebarには文字化けを示す矩形が描画される。Unicode 7.0がsupportされたWindows 10 Anniversary Update以降では、U+1F441はSegoe UI Symbol書体で描画される。

演奏画面下部の#GENRE, #TITLE, #ARTIST表示枠には、mBMplayに組み込まれた画像書体が使われる。mBMplayの画像書体に収録されていない文字は描画されない

ruv-it!

BOMつきUTF-8符号化BMS形式で図表を作成したうえで、Unicodeの文字列値を普通に記述すれば、Unicode文字はruv-it上で描画されうる。Windowsが描画できない文字はruv-itも描画できない。

これら以外にも絵文字などを描画できるBMS実装は存在するかもしれないが、私は確認しきれていない。


BMS実装がUnicodeをsupportしていることと、環境がUnicodeをsupportしていることと、文字を描画できる書体が存在することと、代替書体にfallbackする仕組みが存在することと、図表fileのtext encodingは、それぞれ話が異なる。書きながら私もわからなくなってきた。

トムはさらにトム

Windows 10 Version 1909に20H2への自動更新が降って来ていたので更新した。3時間かかった。

Windows 10のメモ帳の既定のText EncodingがBOM無しUTF-8になってから二年が経とうとしている(Version 1903でUTF-8に変更されたらしい)。この変更に気付いておられない感じのBMS作品をそこそこ見かけるが、Text Encodingを図表ごとに手動で変更できる実装なら問題なさそう。

実装に合わせるしかない

BmsONEは常に小節線を省略せず書き出すが、これは以下のBMSON小節線仕様に準拠する実装がBmsONEとraindropしか存在しないがゆえに仕方なしにそうしたものと思われる。

  • If this is not specified (null or undefined), then a 4/4 time signature is assumed, and a bar line will be generated every 4 quarter notes.

そういえば納期のテーマ (なんでもあり Any% Remix)の小節線がずれていた。

readme.txtによると仕様らしいが、意図不明。普通に合わせるのでは駄目なんだろうか。
    "lines": [
{"y":0},{"y":960},{"y":1920},{"y":2880},{"y":3840},{"y":4800},{"y":5760},{"y":6720},{"y":7680},
{"y":8640},{"y":9600},{"y":10560},{"y":11520},{"y":12480},{"y":13440},{"y":14400},{"y":15360},
{"y":16320},{"y":17280},{"y":18240},{"y":19200},{"y":20160},{"y":21120},{"y":22080},{"y":23040},
{"y":24000},{"y":24960},{"y":25920},{"y":26880},{"y":27840},{"y":28800},{"y":29760},{"y":30720},
{"y":31680},{"y":32640},{"y":33600},{"y":34560},{"y":35520},{"y":36480},{"y":37440},{"y":38400},
{"y":39240},{"y":40200},{"y":41160},{"y":42120},{"y":43080},{"y":44040},{"y":45000},{"y":45960},
{"y":46920},{"y":47880},{"y":48840},{"y":49800},{"y":50760},{"y":51720},{"y":52680},{"y":53640},
{"y":54720},{"y":55680},{"y":56640},{"y":57600},{"y":58560},{"y":59520},{"y":60480},{"y":61440},
{"y":62400},{"y":63360},{"y":64320},{"y":65280},{"y":66240},{"y":67200},{"y":68160},{"y":69120}
    ],

東京をお食べ

frozen summitの5h図表をPERFECTに演奏できて、最高の気分で画面変遷したらAUTOPLAYだった。WAV版はBM98でも遊べる(rhythmはややずれる)。簡易版BMP filesを#xxx04に配置したうえで、#xxx07に動画を配置すれば、Compile error一個分を代償にfallbackもできる。

徹夜で見張れば雪が積もらないのでは?

CROSSPEEDflash10011_result.pngが最高の不透明度を持つので、LR2は下地を透過しない。

Une Nuit sur le Mont ChauveのNORMAL譜面、大好きだけど、#158には違和感があった。ここではTrumpetの高音部と低音部がKEY音としてまとめられている。この場面で連打が現れることによって、演奏者の聴覚は高音部にfocusする。Trumpetの高音部はLongNoteにできる鳴り方をしていない。

HYPER譜面が最高に好き

Mescalineをbeatorajaで演奏すると謎の例外が出る。
java.io.IOException: D:\bms\Nancyatte A-1 Climax\Mescaline_ogg\Kick_Filter_011.ogg : 0 samples
        at bms.player.beatoraja.audio.PCM$PCMLoader.loadPCM(Unknown Source)
        at bms.player.beatoraja.audio.PCM.load(Unknown Source)
        at bms.player.beatoraja.audio.PCM.load(Unknown Source)
        at bms.player.beatoraja.audio.PortAudioDriver.getKeySound(Unknown Source)
        at bms.player.beatoraja.audio.PortAudioDriver.getKeySound(Unknown Source)
        at bms.player.beatoraja.audio.AbstractAudioDriver$AudioCache.load(Unknown Source)
        at bms.player.beatoraja.audio.AbstractAudioDriver$AudioCache.load(Unknown Source)
        at bms.player.beatoraja.ResourcePool.get(Unknown Source)
        at bms.player.beatoraja.audio.AbstractAudioDriver.lambda$setModel$1(Unknown Source)
        at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
        at java.base/java.util.HashMap$EntrySpliterator.forEachRemaining(HashMap.java:1837)
        at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
        at java.base/java.util.stream.ForEachOps$ForEachTask.compute(ForEachOps.java:290)
        at java.base/java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:746)
        at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
        at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1016)
        at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1665)
        at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1598)
        at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:183)
1月 09, 2021 7:58:17 午後 bms.player.beatoraja.audio.AbstractAudioDriver setModel
情報: 音源ファイル読み込み完了。音源数:968
  • Kick_Filter_011.oggは、音量がとても小さいが、無音ではない。
  • beatoraja 0.8.1 [PortAudio] + Amazon Corretto version 15.0.1.9.1でこのerrorが発生する。
  • OpenAL (LibGDX Sound)だと、このerrorは発生しない。
  • Oracle Java Version 8 Update 271だと、このerrorは発生しない。
  • 全音声filesをWAVにdecodeすると、このerrorは発生しない。

小指120 %(霜焼け太り)

Microsoft DefenderがQwilight installerをTrojan:Win32/Wacatac.D4!mlと判定して隔離するようになった。[追記] 版のinstallerはいまのところ大丈夫っぽい。Qwilightの最近版には自動更新機能が備わっているので、既に導入済みのusersにとっては特に問題はない。BMSON Layered Notesが正しく演奏されるようになるとありがたい。

以下のような構造のBMSがあるとき、LR2とPulsusはあたかも問題がないかのようにBMSを演奏する。
a/
b/
c.bms
#BPM 120
#TITLE invalid path
#WAV01 d.wav
#BMP01 e.bmp
#00104:01
#00111:01
d.wav
e.bmp

微笑みの地雷

bmsonでの地雷は比較的実装しやすそうな印象もあるのですが、そこまでに必要な手続きをわからないでいます。

  • 手続き的に正当なのは……と書こうとした私は既にIssueが立っていることに気付きました。
  • GitHubや実装における手続きは、私には一切わかりません。
  • BMSON自体はBMSの上位互換を意図していないように見えます。不可視notesや地雷notesなどのOneShotSpecial要素は、sound slicingを主軸とするBMSONの設計思想と噛み合わないように見えます。それはそれとしてBMSONに不可視notesや地雷notesが実装されるなら私にとっては喜ばしいです。
  • 地雷をsupportしないBMSON実装が地雷を適切に無視できるよう、"bomb_channels"を仮定する。

    • 基本的にSoundChannelsと同じ構造。なので爆発音を途中変更可能。
    • 地雷の"name"値が空なら既定の爆発音を参照する。
    • 地雷は"d"に小数値を持ちうる。百分率でdamageを指定する。
    • 地雷の"d"の値がFalsyなら即死……否、damage: 0も可能であるべきか?
    • 地雷一個一個に"d"を指定するのはアホくさい。大域的なdamage指定もできるといい。
    • 地雷は"l"で長さを持っても良い、と個人的には思う。Pixel Artsのshorthandとかでも。
    • 地雷が可視notesと同一座標上に競合した場合、その地雷は破棄されなければならない。
    • 地雷がBGMにある場合、その地雷は破棄されなければならない。
    • 地雷における特定のsound sliceの同時押し配置は許容されなければならない。
    • 地雷の"d"に負数値を指定するとgaugeが回復する?

    非開発者によるたたき台としてはこんな感じでしょうか。とはいえ私自身は地雷に何の思い入れもないので案の持ち合わせがありません、gimmick系の図表著者氏らのご意見を伺いたいところです。

[寝て起きて追記] 地雷に定義された音の一部だけを切り出して使う場合、かつ当該波形の切り出されない部分が地雷として使用されない場合、"c": falseの先頭部分は単純に破棄できないような気がするな……。あ〜、BGMにある地雷は、図表が演奏される際は音量0のsound notesとして処理される」とかになるんだろうか。この形にできるなら地雷のLayered Notesとかも可能かも。Layered Notesがどうやって実装されているのか知らないけど。いろいろ考えると地雷の実装は微妙に面倒くさそう。

自分用に整理してみる

思いつき次第追記していく。

BMS形式の利点

  • #RANDOM分岐を使える。
  • 不可視notesや地雷notesを使える。
  • Scrolling tricksを組みやすい。
  • BMSON型の大域分解能方式では困難な、複雑なrhythmを組みやすい。
  • 気をつけて組めば20年以上昔のsoftwareでも遊べる。
  • 作成支援softwaresやdocumentsが充実している。
  • 図表著者が柔軟に曲や映像を組み替えやすい。曲変更差分などを作りやすい。

BMSON形式の利点

  • 音声を実際に裁断しなくても構わない。
  • 1296種類以上の音声filesや映像filesを使える。
  • #999以上の小節を使える。
  • 複数のKEY音を図表上で合成できる(Layered Notes)。
  • LN/CN/HCNを図表内に混在でき、BSSも完全に再現できる(beatoraja拡張)。
  • Text層では絶対に文字化けしない(書体やFileSystem層での文字化けはありうる)。
  • GrooveGauge上昇量を無駄に計算する必要がない。
  • 図表著者が曲や映像を組み替えづらい。編集上の単純な誤りはほぼ抑制される。
  • JSON.parse(file)だけで構文解析が完了する。

ベリハVERY HARD差分企画 第一回

  • 呼無のカミサマの「S乱クリア許さないギミック」が面白い。
  • “Progressive?”の本体と差分だけでは音声が足りないように見える。2018年春のソフラン差分祭り 第2回vs_yūdachi” folderがいつのまにかvs_yudachiに修正されていたように(非UTF-8文化圏でyurusitekudachi)、今回もいつのまにか直っていますように……
  • Pastel Colorful Freshableは分かりやすいpatternを延々繰り返すのがとても気持ち良い。
  • “キラーパラパラドラえもん”の簡単なやつだけclearできた。地味にBPMが合わせてあり良い。

ちょっとだけ先日の続き。

  • Noteの個別化は、Space InvadersXeviousになる程度の質的変化はあるんじゃないかなあ〜。
  • Groove Gaugeが動かない状況だと、HCNの視覚的feedbackは物足りない。
  • 地雷も目的に応じて適した外観が変わりそう。誤爆誘発(階段とかの間に挟まる)、KEYUP強制(LN終端とかの直後に後続する)、Animation、Karaoke等々。もともとpresentation特化な感じ。
  • 長さを持つnotesの終端を判定する場合、判定線の見映えは現状のままで良いのだろうか? 後発のsmartphone用rhythm-action gamesにはUIの改善提案もあったような気がするが、title失念。

手足が凍瘡に罹りBMS休止中

けもびーつ」収録作品“sttra ry ffarp”のHamal図表は、LongNotesで疑似的に#ExtChrを行う。Hamal図表を終端判定ありで遊ぶとstaccatissimo感が味わえる。KEY音がそうしたarticurationを有する状況であれば、演奏時のkeyup操作が音にmatchして気持ち良さそう。

先端判定の有無終端判定の有無押下中にCOMBOが増加するか否か、それぞれについて見映えや操作にmatchするKEY音がある。こうした観点からすると、CNHCNの違いはそれほど明白ではない。判定の有無のほうが演奏感への影響は大きいし、判定の有無を制御できる仕組みが重要。そしてそれを演奏者に示す適切な外観も重要。図表側からnoteの外観を個別にcustomizeできれば最高。せっかく個別化するなら判定幅・gauge上昇量・scrolling速度などもいじりたいところ。そこまで個別化するならBMSON形式が必須になりそう。既にbeatorajaは独自拡張によってLN/CN/HCNを図表内に混在できる。私が知る作例はCovenantくらいだが、この仕組みはnoteの個別化のきざはしとなりうる。

[追記] “HARDTEK DJMIXもLN/CN/HCNを派手に使い分けている。


beatorajaのOpenAL (LibGDX Sound)は、Java 9以降の環境では警告される(らしい):
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.lwjgl.LWJGLUtil$3 (file:/D:/beatoraja0.8.1/beatoraja.jar) to method java.lang.ClassLoader.findLibrary(java.lang.String)
WARNING: Please consider reporting this to the maintainers of org.lwjgl.LWJGLUtil$3
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
  • beatoraja 0.8.1 [OpenAL] + Oracle Java Version 8 Update 271: 警告なし。
  • beatoraja 0.8.1 [OpenAL] + Amazon Corretto version 15.0.1.9.1: 警告あり。
  • beatoraja 0.8.1 [OpenAL] + Liberica JRE同梱版: java.exeから起動すると警告あり。

ほとんどの場合PortAudioが有利だが、beatorajaの動画を撮る場合やBmsONEと連携する場合はOpenALを使うほうが面倒がない。実況動画なども同様かもしれない。

日記

BMS関連

拙作BMS
bubble / hitkey
二次配布BMS
ノイズの海と鯨 / moka
PARTY TIME IN MY DREAM / HAIJI
BMSE非公式ヘルプ
Lite
Lite-online
Full
Full-online
buglist
iBMSC
Web (Japanese version)
issues
BMS差分
a­nal­gam
boléro
Ketch­up
quovadis
SELF
yellows
Do not use non-ascii filenames
Brilliant Techno Square
雑多なメモ
bmsplayer data
bms benchmark
Secrets - Feeling Pomu 2nd
grid2sec
bmx2xxx
BMx Outliner
BMS command memo
BMS command memo (Japanese version)
BMS EVENT LITE
#RANDOM BMS list
BMS #OPTION command
BMS Bitmap test
Extended BPM
STOP Sequence
BMS Edge Cases
BMS extensions proposed by Sonorous (unofficial Japanese version)
BMS 2.0 (unofficial Japanese version)
BMS Editors
Do not use non-ascii filenames
BM98 Kikuchan Version 3.30 Revision #4.2
BMSON Checker
_wsh_bms2bmson.js

その他

HTML関連メモ
Dakuten on HTML
nest1000
EVS
Nervous Cascading
Source Han Sans test
User-Agent String
CSS Logical Properties