ブラウザで楽譜を書けるライブラリ abcjs のご紹介

この記事は <a href="https://adventar.org/calendars/3342">CyberAgent 19新卒 エンジニア Advent Calendar 2018</a> 14日目の記事です。

# この記事について
ブラウザで簡単に楽譜を書ける便利なライブラリ **abcjs** を紹介します。ニッチな話題ですが、

 - 自身の<a href="https://scrapbox.io/satakebox/hyperscorebox">修士研究</a>で利用しており、細かく触る機会が多い
 - 有用なライブラリなのに、Qiita記事がほとんど無い

という理由で紹介記事を書くことにしました。

# 対象読者
- 楽譜を使う人
- abcjsを使ったことがない人
- ABC記譜法を知らない人

# abcjsについて
 abcjsは<a href="https://ja.wikipedia.org/wiki/ABC%E8%A8%98%E8%AD%9C%E6%B3%95">ABC記譜法</a>(以下ABC)を使ってWeb上に楽譜を書けるJavaScriptライブラリです。 <a href="https://github.com/paulrosen">@paulrosen</a>氏によるオープンソースプロジェクトで、MITライセンスのため様々な場所で使うことができます。また現在もアクティブに開発されており、頻繁に新機能の追加やアップデートが行われています。

ABCは「C」と書くと「ド」になるシンプル記法で、複雑なレイアウトや大規模なスコアの記述は苦手ですが、だいたいの楽譜はABCで十分書けます。

### できること
- HTMLに楽譜を埋め込む
<img width="500px" src="https://gyazo.com/5ad69b4d19a3d6679e6b892ffcd9a620.png">

- テキストベースでサクサク楽譜を書く
<img width="500px" src="https://gyazo.com/b4c08eba935dff8bd4611bf79f9d292d.gif">

- 楽譜のMIDIを再生する
<img width="500px" src="https://gyazo.com/05878925b07e50325124140a42005ad0.gif">

### インストール

```
$ npm i abcjs
```
### 読み込み
```
import abcjs from "abcjs";
```
<a href="https://github.com/paulrosen/abcjs#old-style-minimized-download">scriptタグで読み込めるURL</a>も用意されています

# 基本的な使い方
 「ドレミ」の楽譜を描画してみます。「ドレミ」はABCで「cde」と書きます。
<img width="500px" src="https://gyazo.com/b7eb53047c09985db15eed4c901cda9d.png">

###使用API
```
abcjs.renderAbc(${楽譜描画先要素のID}, ${ABC});
```

###サンプルコード
<a href="https://codesandbox.io/s/5379j4jowp">Codesandbox</a>

# もう少し真剣に楽譜を書いてみる
### Information Fieldの書き方
ABC本文の前に、タイトルや作曲者といったメタデータ (**Information Field**) を記述できます。

#### タイトル:T
```
T:My Song
```
<img width="500px" src="https://gyazo.com/d535f49dfba61d6dbd428afee52623c1.png">

#### 作曲者:C
```
T:My Song
C:stkay
```
<img width="500px" src="https://gyazo.com/c327c0acdbde65be903d8d208c1102f8.png">


#### 基準の音価を変える:L
ABCでは何も指定しない限り、音符は8分音符(1/8)を基準として入力されます。この基準となる音価を変更する場合は、`L`フィールドを設定します。

```
T:My Song
C:stkay
L:1/4
CCCC
```
<img width="500px" src="https://gyazo.com/a1d9af41a3af71de35934be99dda9154.png">

#### 調号を変える:K
```
T:My Song
C:stkay
L:1/4
K:G
CCCC
```
<img width="500px" src="https://gyazo.com/e77cda60d976f46f47157bf8e502dcb3.png">

#### 拍子記号を変える:M
```
T:My Song
C:stkay
L:1/4
K:G
M:1/2
CC
```
<img width="500px" src="https://gyazo.com/e5c933dfc87b887d44294bd56d04d4d3.png">

### いろいろなABCの書き方
#### 音価を変える
音価を変更する場合は、基準音価の倍数で指定します。

```
T:My Song
C:stkay
L:1/4
C1/4 C1/2 C C2 C3 C4
```
<img width="500px" src="https://gyazo.com/174b7fdc99c9954ec5d67d062bb9fca0.png">

#### 小節線を書く
`|`が小節線になります。

```
T:My Song
C:stkay
L:1/4
M:4/4
CCCC | CCCC |
```
<img width="500px" src="https://gyazo.com/490a020e4672fb98dd06126975a51a42.png">

#### はたを区切る
テキストにスペースを入れると音符のはたを区切ることができます。

```
T:My Song
Cstkay
M:4/4
C C CC CCCC
```
<img width="500px" src="https://gyazo.com/f061e367e1e968f0ba6d88c85e05f7e6.png">

その他詳細な記法については<a href="http://abcnotation.com/wiki/abc:standard:v2.2">ABC記譜法公式wiki</a>をご覧ください。

# リアルタイム楽譜編集

**abcjs editor** を利用すると、ブラウザ上でリアルタイムに楽譜入力できます。
<img width="500px" src="https://gyazo.com/b4c08eba935dff8bd4611bf79f9d292d.gif">

### 使用API

```
new abcjs.Editor(${テキストエリアのID}, {paper_id: ${楽譜描画先要素のID})
```

### サンプルコード

<a href="https://codesandbox.io/s/8lwow11kp0">Codesandbox</a>

# 楽譜のMIDIを再生する
abcjsでは作成した楽譜をMIDIとして再生することができます。
<img width="500px" src="https://gyazo.com/05878925b07e50325124140a42005ad0.gif">

### 使用API

```
abcjs.renderMidi(${シークバー描画先要素のID}, ${ABC})
```

### サンプルコード
<a href="https://codesandbox.io/s/x3xjjj9vk4">Codesandbox</a>

### 準備
#### ライブラリのインポート元を変更

```
import abcjs from "abcjs/midi";
```
MIDI機能を利用する場合はインポート元が変わるので注意！

#### シークバーが利用するfont-awesome / CSSのロード
MIDI再生時にabcjsがシークバーを描画してくれますが、そこで使われているfont-awesome / CSSを別途読み込む必要があります。

- `<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">`をHTMLに追加
- https://raw.github.com/paulrosen/abcjs/master/abcjs-midi.css をリポジトリ内のCSSファイルにコピーする

# もう少し凝った使い方
### 楽譜の見栄えを調整する

`renderAbc`に渡す`params`で指定する方法と、描画されるSVGにCSSで直接スタイルを適用する2つの方法があります。
#### paramsで指定する
`abcjs.renderAbc(${楽譜描画先要素のID}, ${ABC}, ${params});`
第3引数に渡すオブジェクト`params`で楽譜の見栄えやレイアウト等に関するパラメータを指定できます。

##### スケールを変更してみる例 (<a href="https://codesandbox.io/s/w6mj3mkm9l">Codesandbox</a>)
<img width="500px" src="https://gyazo.com/fb27119d6a269241cf80da1aa4009262.png">

#### CSSでスタイルを適用する
`params`内で`add_classes`を有効にしていると、特定のパスにスタイルを適用できます。
##### 五線を赤くする例 (<a href="https://codesandbox.io/s/pkl6vmkqnj">Codesandbox</a>)
<img width="500px" src="https://gyazo.com/705f74539f44a740def459b41a438085.png">

### 音符にクリックリスナを登録する
`params`の`clickListener`に、音符に対するクリックリスナを登録することができます。

##### 音符をクリックするとalertする例 (<a href="https://codesandbox.io/s/z6nvqnz3ql">Codesandbox</a>)
<img width="500px" src="https://gyazo.com/aed7e259c378de0e46f53985fa8b696b.gif">

# まとめ
　以上がabcjsの基本的な使い方になります。質問があれば本記事のコメント欄や、筆者の<a href="https://twitter.com/dorayaki0">twitter</a>にお気軽にドゾー。

# 関連情報
### abcjsに関する情報
- <a href="https://github.com/paulrosen/abcjs/blob/master/docs/api.md">公式APIドキュメント</a>	
- <a href="https://configurator.abcjs.net/">abcjs Configurator</a>
 - APIで設定できる各種パラメータをインタラクティブにプレビューできるサイト
- <a href="https://abcjs.net/abcjs-editor.html">abcjs demo page</a>
 - abcjs Editorを試せるサイト

### ABCに関する情報
- <a href="http://abcnotation.com/wiki/abc:standard:v2.2">公式マニュアル (v2.2)</a>
 - ページ内検索して記法を調べるのに利用します。(例えば臨時記号の記法を調べたい場合は「accidental」で検索)
 - 音楽用語の英訳が分からないと使いづらいかもしれません。
- <a href="http://www.ne.jp/asahi/music/marinkyo/ml/abc-regulo.html.ja">まりんきょ氏の日本語訳マニュアル (v2.1)</a>
 - ↑の公式マニュアルの日本語訳です(最新ではありません)
- <a href="https://groups.yahoo.com/neo/groups/abcusers/info">Yahoo Groups</a>
 - ABCのメーリングリスト
 - ABCの文法や、ソフトウェアの使い方に関する質問が日々投稿されています
- <a href="http://abcnotation.com/software">abc software packages</a>
 - ABCを扱える各プラットフォーム上のソフトウェアのリスト

### ABC譜例
- <a href="http://abcnotation.com/searchTunes">tune search</a>
 - ABC譜を検索できます。IMSLP等に比べるとレパートリーは少ないかもしれません。 　　


# 宣伝
<a href="https://scrapbox.io">scrapbox.io</a>上で楽譜をサクサク書けるChrome拡張<a href="https://scrapbox.io/satakebox/hyperscorebox"> **hyperscorebox** </a>を修士研究の一環として開発しています。Scrapboxのリンク機能とABCによるテキストベース楽譜を融合した強力な拡張機能ですので、ぜひ利用してみてください。