注釈: ここでのCDはCompact DiscのほうではなくてContinuous Deploymentのほうを指します。
趣味で楽曲制作をしています。
普段は電子音メインなんですが、たまに生楽器の小編成な曲も書くことがあって、そのついでとして譜面化することもあります。
本職はエンジニアだし、せっかくならテキストフォーマットで書いてGitで管理したいなということで、そのあたりの話をします。
リポジトリ: https://github.com/Pctg-x8/farewell_for_reunion_score
楽譜をGitで管理する技術
楽曲のデータ形式としてよく知られているものにWAV, MP3, MIDIといったものがありますが、これらはいずれもバイナリフォーマットなのでGitで取り扱うには向きません。これは各種DAWのプロジェクトファイルも同様です1。
テキストデータで楽曲を表現できるものの一つにMMLといったものもありますが、こちらはテンポや発音や音色指定といった、どちらかというと演奏のために必要な情報しか記述できないため楽譜化するには情報がたりません。
というわけで、テキストで記述でき、かつ楽譜として必要な情報を記述できるようなフォーマットが新たに必要になります。その一つがLilyPondです。GNUのオープンソースプロジェクトの一つで、様々な種類の楽譜をテキストデータで記述し、PDFなどのファイルとして生成することができます。
LilyPondに読み込ませるフォーマットは基本的な音の配置を表すMML風の表記にいくつかの拡張情報を添付できるようにし、さらにそれらをいくつかのブロックにまとめて構造化したような形をしています。MML「風」としたのは、単一の音階以外にもコード名も記述できるためです。以下のbes:m7
がそれで、この場合はBbm7を表します。
\version "2.18"
\header {
title = "aaa"
composer = "SisterCat"
}
<<
\new ChordNames \chordmode {
bes:m7
}
\new Staff \relative c' {
\tempo 4 = 96
\time 4/4
c4
}
\new Staff {
\clef bass
\relative { c4 }
}
>>
これをプログラムに通して変換すると以下のような出力を得ることができます(変換方法は後述します)。
かなり幅広いタイプの楽譜の出力に対応しており、全部を紹介することは難しいので詳しい表記法については公式ドキュメントを参照してください。
とりあえず、これで楽譜をテキストデータとして表すことができるようになり、つまりGitで管理するのに適した形にすることができました。
楽譜をCDする技術
さて、楽譜ソースをGitで管理できるようになったということは他のプログラミング言語と同様にCI/CDを走らせたりすることができるようになったということでもあります。
今回はGitHubでホスティングしていますので、せっかくなのでGitHub Actionsを使って、mainに変更がpushされたら自動でアーティファクトとして楽譜のPDFファイルを生成してくれるようにしてみます。
GitHub Actionsについて詳しくは記載しませんが、特定のディレクトリに置いたyamlファイルでいい感じにジョブ/ステップを構成することでGitHub上のイベントに連動して、または手動で一連のジョブ(プログラム)を実行してくれるものです。
GitHub Actions最大の特徴はここでの「ステップ」にあたるプログラムを自由に共有して使い回すことができる点にあります。けっこういろんなものがすでに作られていて、実際今回登場したLilyPondのプログラムを実行するだけのAction2もあります。が、自分が試した当時だと本体のバージョンが低くエラーが出てしまったので今回はActionを自作します。
今回作るワークフローは以下の単純な構成になっています。このうち2番目のステップを自作します。
- mainをcheckout
- lilypondでPDFを作る
- アーティファクトとしてupload
LilyPondで変換を実行するだけのActionを作る
今回は用途が限定的なので、ソースファイル名と出力ファイル名だけを受け取る単純なDockerアクションにします。
FROM ubuntu:bionic
ADD entrypoint.sh /entrypoint.sh
RUN apt-get update && apt-get install -y lilypond && chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
LilyPond自体は普通にパッケージがありますので、インストール作業はapt-getでOKです。
entrypoint.sh
は以下のように単にlilypondを呼び出すだけとなっています。
#!/bin/bash
set -xe
lilypond -o $OUTPUT_FILE $SCORE_FILE
lilypondはデフォルトではPDFファイルを生成するようなのでこの引数だけでOKです。これ以外にSVG, PNG, PostScriptといった出力フォーマットに対応しており、-f
でそれぞれ指定することが可能です3。
また、拡張子は省略しなければなりません。引数側でつけると二重に拡張子が付きます。
このActionを使って、環境変数でOUTPUT_FILE
とSCORE_FILE
を指定することでLilyPondを使って変換を行うことができるようになります。
Workflow全体を作る
変換Actionが作れましたので、これでワークフロー自体を構成できるようになりました。以下が全体です。
name: Score PDF Autobuild
on:
push:
branches:
- main
jobs:
build:
name: Build PDF
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@v2
- name: build
uses: ./.github/actions/lilypond_generator
env:
SCORE_FILE: score.ly
OUTPUT_FILE: score
- name: publish
uses: actions/upload-artifact@v2
with:
name: Score PDF
path: score.pdf
if-no-files-found: error
mainへのpushを起点にcheckout, build, publishを行う至ってシンプルなワークフローです。これは特に説明するところはないかなと思います。
おわり
以上が楽譜を自動デプロイするためにやったこととなります。
本来はウェブサイトまで用意してS3にアップロードしてPDF本体をDLできるようにする、とかもやりたかった4んですが時間が......