11 ポイント 投稿者 GN⁺ 2024-05-01 | 2件のコメント | WhatsAppで共有
  • 小さなモバイル画面でA4 PDFを拡大しながら演奏する音楽家のために、Web上で流動的かつレスポンシブな楽譜レンダリングが必要

Scribeプロトタイプ

  • 以前、JSONからSVGを出力するScribeという音楽レンダラーをプロトタイプとして制作した
  • 当初の目標はレスポンシブな音楽レンダラーを作ることだったが、複雑なマルチパスレイアウトエンジンを書く必要があり、進展が難しかった
  • その後、CSS Gridをプロジェクトに導入し、Scribeで扱っていたレイアウト問題の解決策になり得ると感じた

.staveクラス

  • 五線譜はグリッドに似ている。垂直軸は音高、水平軸は時間である
  • .staveクラスでは、垂直軸であるグリッド行を定義する
  • 標準的な音名で固定サイズのグリッド行を作り、五線譜を描く背景画像を使う
  • トレブル譜表に対する行マップの例:
    .stave {  
      display: grid;  
      row-gap: 0;  
      grid-template-rows:   
        [A5] 0.25em [G5] 0.25em [F5] 0.25em [E5] 0.25em  
        [D5] 0.25em [C5] 0.25em [B4] 0.25em [A4] 0.25em  
        [G4] 0.25em [F4] 0.25em [E4] 0.25em [D4] 0.25em  
        [C4] 0.25em ;  
      background-image: url('/path/to/stave.svg');  
      background-repeat: no-repeat;  
      background-size: 100% 2.25em;  
      background-position: 0 50%;  
    }  
    
  • 各譜線と間隔に音名のグリッド線ができる

五線譜上に音高を配置

  • 五線譜の各行には複数の音高を配置できる
  • DOM要素を正しい行に置くため、data-pitch属性に音名を入れ、CSSでdata-pitch値を五線譜の行にマッピングする
    .stave > [data-pitch^="G"][data-pitch$="4"] { grid-row-start: G4; }  
    
  • この規則は'G'で始まり'4'で終わる音高を捉え、'G♭4'、'G4'、'G♯4'などをG4行に割り当てる
  • これをすべての五線譜行について行う必要がある
  • これでいくつかの記号を五線譜上に配置できる

.barクラスと拍

  • リズムを扱うのはもう少し厄介だ
  • あらゆる種類のリズムをサポートする明確な最小リズム分割は存在しない
  • 1拍あたり24列というアプローチは、8分音符、16分音符、32分音符、および3連符を均等に配置できるため良い出発点になる
  • 4拍を4 × 24 = 96グリッド列として定義し、開始と終了に列を追加する:
    .bar {  
      column-gap: 0.03125em;  
      grid-template-columns:  
        [bar-begin]  
        max-content  
        repeat(96, minmax(max-content, auto))  
        max-content  
        [bar-end];  
    }  
    
  • ::before::afterで小節線を追加し、data-pitch="B4"で音部記号を中央に配置する

拍に記号を配置

  • 今度はdata-beat属性を使って要素に拍を割り当て、CSSルールを使って拍をグリッド列にマッピングする
  • CSSマップは1/24拍ごとに1つの規則で構成される
  • 属性の^=開始セレクターを使うと、規則に誤差許容性を持たせられる
  • .staveクラスと組み合わせることで、data-beatを1〜5の間の拍に、data-pitchを音名に設定し、拍と音高ごとに記号を配置できる

流動的でレスポンシブな楽譜

  • こうした複数の小節をflexboxコンテナに入れると、レスポンシブな楽譜を表示できる
  • まだ欠けている部分は多いが、出発点としては良い基盤だ
  • すでにオンライン音楽レンダラーよりはるかに優雅に改行される

音符間のスペース

  • より近い時間に発生する音符の符頭は、やや近く描画される
  • これは小さなcolumn-gapによって生まれる微妙で意図的な効果で、記号要素がスロットに入るための一種の時間的な「エーテル」として機能する
  • 列自体は符頭がなければ幅0だが、拍的に離れたイベントの間にはより多くの列間隔(1拍あたり24個)があるため、距離が広がる
  • 記号のマージンを調整して一定の間隔を制御できる

音部記号と拍子記号

  • 垂直方向と水平方向の間隔に別クラスを使った理由は、他方に触れずに片方だけ差し替えられるからだ
  • 同じメロディをヘ音記号で表示したい場合は、.staveクラスを、同じdata-pitch属性をヘ音譜表の行にマッピングするbass-staveクラスに置き換えればよい
  • CSSでdata-duration="5"を.barの120グリッドテンプレート列にマッピングすれば、同じ五線譜に5/4拍子記号を与えられる

コードと歌詞

  • CSS Gridを使えば、楽譜グリッド内で他の記号も整列できる
  • コードや歌詞、ダイナミクスなどを時間指定されたイベントに合わせて整列・拡張できる

符尾

  • 符尾、コード、一部の長い休符は、data-duration属性をgrid-column-endのspan値にマッピングすることで列にまたがらせる

スケーリング

  • システム全体はem単位でサイズ指定されているため、font-sizeを変更するだけで拡大縮小できる

FlexとGridの限界

  • 完璧なシステムではない。限界点:
    1. CSSは改行時に新しい音部記号や調号を自動配置できない
    2. 新しい行の新しい音符に連桁をつなげることができない
    3. 傾いた符尾はGridが配置した後でないと正確な位置が分からず、整列が難しい
  • 完全に仕上げるには多少の後処理JavaScriptが必要だが、CSSがレイアウト作業の大半を処理するため、JavaScript側で行うレイアウト作業は大幅に減る

カスタム要素

  • この新しいCSSシステムを中心にインタープリタを書き、要素にラップした
  • まだ本番向けではないが、レスポンシブなリードシートをレンダリングし、ドラム譜を記譜できるため、興味深く有用だ
  • コンテンツのデータ、src属性で取得したファイル、要素の.data属性に設定したJSオブジェクトから楽譜をレンダリングする
  • 現在の開発ビルドはWebページに取り込んで試すことができる

今後の計画

  • Scribe 0.3の改善点に加え、長期的に調査したい機能:
    • SMuFLフォント対応 - 楽譜記号に使われるフォントを変更
    • ネストされたシーケンス対応 - マルチパート曲を有効化
    • 分割譜表レンダリング - 1つの譜表に複数パートを配置
    • マルチ譜表レンダリング - 複数の整列した譜表に複数パートを配置

GN⁺の意見

  • Web上で楽譜を流動的かつレスポンシブにレンダリングすることは、音楽家と音楽愛好家の双方にとって非常に有用そうだ。小さな画面でPDF楽譜を拡大縮小しながら見る不便さを解消してくれるだろう
  • CSSのGridとFlexレイアウトを活用したアプローチが興味深い。複雑なレイアウトエンジンがなくても、CSSだけでかなり多くの部分を解決できることを示す良い例だ
  • ただし楽譜の特性上、CSSだけでは限界がある部分もある。改行時に自動で音部記号や調号を配置したり、連桁を自動接続したりするような、音楽的文脈の理解が必要な部分ではJavaScriptの助けが必要になるだろう
  • リードシートのレンダリングやドラム譜対応など、すでにかなり多くの部分を実装しているというので、近いうちに十分実用的な水準まで改善されるかもしれない。オープンソース化されて開発が継続すれば、MuseScoreのような既存の楽譜エディタの良い代替になる可能性もある
  • 今後計画しているSMuFLフォント対応、マルチパートおよびマルチ譜表レンダリング対応などの機能が実装されれば、楽譜表現の完成度は大きく高まりそうだ。期待できるプロジェクトだ

2件のコメント

 
roxie 2024-05-06

そうされる理由があるはずですよね

 
GN⁺ 2024-05-01
Hacker Newsの意見
  • 楽譜ソフトウェア開発者から、CSS Gridを使った楽譜レンダリング方式に対する称賛があった
    • Soundslice というWebベースの楽譜レンダリングサービスを10年以上開発しており、2014年に初の「レスポンシブ」なWeb楽譜レンダリングを実装した
    • 関連する技術的な詳細は発表動画のリンクを参照: https://www.youtube.com/watch?v=XH5EtQge_Bg
    • Soundslice のレスポンシブ楽譜の例: https://www.soundslice.com/slices/zzNlc/
    • Webベースのエディタ、練習機能、写真/PDFから楽譜データを抽出するスキャン機能など、さまざまなツールを提供している
    • CSS Grid方式は軽量なプロジェクトには有用かもしれないが、フルスコアの複雑で繊細な表現をすべて実装するのは難しいだろう
  • JavaScriptなしでCSSだけで実装できるよう、CSSコミュニティに提案してみるのもよさそうだ
    • 例えば改行時の音部記号の繰り返し表示は sticky table header に似ており、楽譜以外にも活用できるかもしれない
  • CSSの attribute selector([...]) 構文が印象的だった。例: .stave > [data-pitch^="A"][data-pitch$="5"] { grid-row-start: A5; }
  • 音楽組版の立場から見ると、視覚的にはかなり改善が必要に見える。CSSだけでは精度に限界があり難しそうだ
    • 符幹、スラー、タイなどの表現に問題がある
    • ほとんどのブラウザ楽譜は SVG や Canvas でベクターレンダリングし、ピンポイントの精度を実現している
    • CSS以外にも、すでに SoundsliceSibelius Cloud Publishing など、ブラウザでスケーラブルな楽譜を実現する別のツールがある
  • 最初はCSSで楽譜を表現するのはうまくいかなそうだと思ったが、シンプルな方法でタイポグラフィ品質が印象的だった。作者に賛辞を送りたい
    • ただし和音、8分/16分音符の間隔、パート間の整列など、特殊なケースでうまく機能するかは懸念がある。Lilypond はこうした複雑な表現で柔軟性が実証されている
  • CSS Gridが興味深い。以前、家具デザイナーを pure frontend JS で CSS Grid を活用して実装したことがある: https://alnvdl.github.io/2023/01/07/designing-furniture-using-the-css-grid.html
  • <scribe-music> カスタム要素にも期待している
  • Lilypond(lilypond.org) の代替が出てきたのはよいが、記譜法は非常に複雑なので、簡潔さの利点は長続きしなさそうだ
    • Asciidoc 愛好家なら、LilypondAsciidoc ツールチェーンに統合しやすい。DocBook PDF パイプラインで使っており、出力はかなり良好だ。TeXに似ている
  • https://www.musicxml.comhttps://opensheetmusicdisplay.org を思い出させる。コストはずっと大きいが完全なソリューションだ
  • Impro-Visor(https://github.com/Impro-Visor/Impro-Visor) のぎこちない楽譜機能をこれで置き換えられるか気になる
  • CSSベンチマークのような印象