GB音源での打ち込み

令和のこの時代ですが、GB音源での打ち込みをやる準備をやってみます。ざっと書くと、以下の様な流れになります。

  1. MML (Music Macro Language)を書く
  2. GBMCでGBSファイルを作成する
  3. gbsplayで再生、またはwavファイルを作成する

MML (Music Macro Language)とは

MMLは音楽演奏情報の記述に特化したDSLの総称で、ざっくり言うとMIDIファイル (より正確にはSMF) で書くことのできる様なことを記述することができます。 つまり、WAVやMP3等の音声データとは異なり、楽譜に書いてある様な情報を記述することができます。 また「DSLの総称」と書いた通り、MMLは標準化された単一のファイルフォーマットがある訳ではなく、ある程度の類似性はあるものの処理系毎に異なる言語が用いられます。 例えば今回GB音源の打ち込みに用いるGBMCのMMLでは、どの音をどのタイミングで鳴らすのかという楽譜に書いてある様な情報に加えて、どの様な音源を使うのかの情報も記述することができます。

GBMC (GameBoy Music Compiler)

GBMCはMMLをコンパイルしてGBSファイルを生成するためのコンパイラです。今回は使いませんが、GBSファイル以外にもGBエミュレータ用のファイルなども生成することができます。

GBMCはソースコードは配布されていない様ですが、Windows用の実行ファイルが無料で配布されています。残念ながらWindows環境が手許にないのでwineを使います。また、LinuxだけではなくmacOSでも動かしたいのでDocker上でwineを動かします。今回使った Dockerfile は以下の様になります。

FROM archlinux

ENV container docker

RUN pacman -Sy archlinux-keyring  --noconfirm
RUN pacman -Syu --ignore ca-certificates --noconfirm
RUN pacman-db-upgrade
RUN pacman -S ca-certificates --noconfirm
RUN trust extract-compat
COPY pacman.conf /etc/pacman.conf
RUN pacman -Syy wine-mono --noconfirm

RUN mkdir -p /opt/gbmc/
RUN pacman -S unzip --noconfirm && cd /root && curl -o GBMC_20191003.zip http://mydocuments.g2.xrea.com/files/gb/gbmc/GBMC_20191003.zip && unzip GBMC_20191003.zip -d /opt/gbmc/
RUN wine /opt/gbmc/GBMC.exe
ENTRYPOINT ["wine", "/opt/gbmc/GBMC.exe"]
WORKDIR /root/

この Dockerfile から作ったdockerイメージの使い方は以下の様になります。

docker run -v$PWD:/root gbmc gbmc/sample/SampleEASY.txt

gbsplayによるWAVファイル生成

gbsplayはゲームボーイ用の音声周りのハードウェアのエミュレータで、GBSファイルなどの音源ファイルを再生することができます。普通に再生することもできますが、標準出力に音声データを出力することもできるので、それを使ってWAVファイルを生成することもできます。

gbsplayはソースコードがGPLで公開されており、LinuxやmacOSで使うことができます。Linuxでは多くのディストリビューションでパッケージが用意されていますが、macOS用のパッケージはない様なので、今回はHomebrewのFormulaを作成します。gbsplayのFormulaである gbsplay.rb は以下の様になります。

# typed: true
# frozen_string_literal: true

class Gbsplay < Formula
  #
  desc "Gameboy sound player"
  homepage "https://mmitch.github.io/gbsplay/"
  url "https://github.com/mmitch/gbsplay/archive/refs/tags/0.0.94.tar.gz"
  sha256 "8a4c66d97914ac8597c79d98f819874d516769542f36c98cf9daa5d463f435d5"
  license "GPL-1.0-or-later"
  head "https://github.com/mmitch/gbsplay.git"

  depends_on "sdl2" => :build

  def install
    conf_args = std_configure_args
    conf_args.delete("--disable-debug")
    conf_args.delete("--disable-dependency-tracking")
    conf_args.delete("--disable-dependency-tracking")
    conf_args = conf_args.reject { |opt| /libdir/.match(opt) }
    conf_args.push("LDFLAGS=-lintl")
    conf_args.push("CFLAGS=-I/usr/local/include/SDL2")
    system "./configure", *conf_args
    system "make"
    system "make", "install"
  end

  test do
    system "gbsplay", "-V"
  end
end

どうやらgbsplayの最新のリリース版である 0.0.94 は音声出力周りに問題がある様なので、開発版をインストールします。gbsplayのインストールは以下の様に行ないます。

brew install --HEAD ./gbsplay.rb

gbsplayとffmpegを使うことで、以下の様にWAVファイルを生成することができます。

gbsplay -o stdout -E l -r 48000 SampleEASY.gbs  | ffmpeg -ac 2 -f s16le -ar 48000 -i - -c:a pcm_s16le SampleEASY.wav