悦楽舎 © 2002 hoshi
2024/05/31 (2024/06/01加筆)

効果音制作と「ひみつのアセンブリ」裏話

悦楽舎15周年記念!最近開発したものの裏話、二本立て。GBA用の効果音制作と例大祭頒布「ひみつのアセンブリ」の話です

(6/1 ちょっと追記)


悦楽舎は今日で15周年

GBA用の効果音制作を手伝った話と、例大祭で頒布した「ひみつのアセンブリ」の話を、なるべく噛み砕いてお届けする「開発の裏話」……みたいな感じのを二本立てでお届けします(謎


全体的に技術系の記事です。噛み砕いたけどもしかしたら食用に適してないかもしれません(

(相変わらず独学で突っ走ってるので間違ったこと書いてたらすまん)


合わせて「ひみつのアセンブリ」を v1.0.1 に更新しました!

目次

  1. PC98用ゲームをGBAに移植するプロジェクトで、効果音移植/アレンジ制作を手伝った話
  1. GB用自作ソフトで256タイル制限を突破して、背景に300タイル使った反則(?)技の話

サウンドとアセンブリ(と新フォーマット)

GBA開発wikiの中の人ことakkera102さん開発の「カナン ~約束の地~ for GBA」「夢幻夜想曲 for GBA」用の効果音制作をお手伝いしました!

カナン ~約束の地~ for GBA 夢幻夜想曲 for GBA

↑ 左がカナン(アニメでゎない)、右が夢幻夜想曲(東方アレンジでゎない)


これらは「PC98のノベルゲーを勝手に携帯機に移植する」というロマン溢れる素敵なジャンルです!

「スマホ移植は?スマホでプレイ動画でいい」とか……今の常識が絶対ムリな当時(写メの表示に数秒かかるガラケーの時代)にPCゲームが手に収まるゲーム機で“どこでも”遊べる……!?どう考えても不可能としか思えないことを実現しながら“携帯ゲーム機”のコンセプトを十二分に活かしていて、しかも同人、ついでに成人向け。これは“ロマン”がすぎるでしょ!!です(超早口オタク)


というわけで、ロマンを追い求めた先人たちの軌跡に続くチャンス!面白そう!やるしかない!!でした!


……ちなみに、公開されているのは「PC98用ソフトを展開してGBA用ROMに変換するツール」で本編を遊ぶにはゲームソフトが必要です。

が、効果音関連のファイルが埋もれるのは「勿体なくね?」ってことで、音確認のやりとりに実際に使っていたテストROMも公開中。効果音だけ聴けます、ソースや効果音の生データ付。123って良い番号もらったなぁ


0. 効果音、作れるだろうか?

最初に思ったのがこれ↑でした。如何せん

  • 曲はたくさん作ったけど……効果音は一度もない(

  • VGM(音楽フォーマット)って、……何?

  • LSDj/MusicROMはTimer&STATで再生、今回はVBlank……まぁいけるか?

  • GBAをGBAモードで起動した上でGB音源を鳴らす……仕様は同じだけど、試したことない

  • てか、GBAでGBソフトを起動した時(GBCモード)すら音が違って困ってる(MusicROMで)


と、“それ”用の仕様やツールがある分野じゃないので未知/要確認だらけ。まず調査する時間をもらって最初はちまちま確認してました(経験から行けそうでもハードがハードだけに“無理”にブチ当たると詰む可能性がある)

1. LSDjを使う方針(=MusicROMと同じ)

どう作っていくかの方針が決まったのはピポッ(PC98の起動音)を作った時で、

ピポッは音階ではなく2kHz→1kHzの周波数(CPUが10MHzの場合)の音らしく、まずGBは2kHzが出ません!(

(出せないことはないけどハード仕様上近いのは1985.9Hzか2016.5Hz。このズレまで気にしているのは単に頭がおかしいからです)

で、試行錯誤してchiptusionで使った蓬莱人形風の周波数セット(A=449Hz)がいい感じなので今回も採用。


最終的にピポッは B7(3971.8Hz) → B6(1985.9Hz)波形メモリに半分の周波数の波形を書いてます波形メモリは矩形波の半分の周波数の音が出ます。

ちょうど2kHzが出ないように、高い音は苦手(音痴)なので避けるべきですが、この二音は奇跡的に音の外し方が一致して綺麗に鳴ります、……数式のミラクル(

ピポッの音階 ピポッの波形

↑ そういや今更LSDjのフォントを描いて判別しやすくした


こういう作業は改造LSDjでするのが早いので、MusicROMと同じように作って最後に(未知の)VGMに変換しようと決め、仮で効果音を全部作り1つ目の壁突破でした。

(MusicROM開発で使っている改造lsdpackは改造LSDjの音関係の処理を記録して“APUログ”を出力できます。APUログの内容はもう知ってるのでMusicROM用の曲データに変換したり改変もできます。つまりここで“GB用の”全効果音データ(仮)が完成、一安心)


2. 作った効果音をGBAで再生する、データ変換の話

VGMは……APUログの行頭に$B3があるだけ?改造lsdpackで出力したAPUログと大差ない、身構えて損した

そして、GBAに備わったGB音源(以下、GB-PSG)を扱うサウンドドライバはakkeraさんが既に作ってます。

116_vgm2gba_vblank

↑ “VBlank割込のVGM(=60fps再生用)”をGBAで再生するROMです。(画面の通り音制作にhUGETracker 1.01を使う前提)


GBAでGB-PSGを再生するドライバはある、APUログとVGMはほぼ同じ仕様(周波数が違う程度)……色々揃ってる


まず、ツール付属の「“VGM”をGBAドライバ用に変換するvgm2gba.c」は“VBlank割込のVGM(60fps)”のみ対応なので、なんとなくこのドライバで“VGM(44.1kHz)”も再生できるようにサンプリング周波数変換する機能を追加したsongraw_to_gpsg.pyを作りました(注: 割と大雑把に変換します)


更にVBlank割込(60fps)と同じようなHBlank割込(360,720)の再生も検討して2つ目の壁突破が見えてきました。

同じフォーマット、バラバラなサンプリング周波数

急に出てきたHBlank割込はLSDj/MusicROMの仕様(360Tick)です。(1フレーム中に6回処理するので6*60fps=360Tick、6倍細かく音を制御できます)。これの再生も確認したかったのでドライバに対応させました。


途中、GBミクロ(GBエミュではなくGBAモード)でクラウディパーク(カービィ2)を流すとか寄り道して遊んでましたサンプリング周波数の変換とHBlank割込が両方とも正常に動作するか確認している重要なテストです!(

test2.gba

↑ 欲張ってHBlank12回割込(12*60=720Tick)で再生中。でもカービィ2の曲は元がVBlank割込(60fps)なので(いみがない)


で、本命のLSDjで作った効果音(のAPUログをsongraw_to_gpsg.pyでGBAドライバ用に変換したバイナリ)も再生……

散々遊んだテストしたお陰でLSDjで作ったデータ(360Tick)も、HBlank6回割込(360Tick)問題なしでした!


で、最初「効果音はVBlank割込で」って話だったのでここからダウンサンプリング(効果音を60fpsに変換)を考えてたけど、HBlank割込でも大丈夫ということでこのまま(360Hzで)使えることになりました!2つ目の壁も突破!

ちなみにドライバにHBlank割込の追加はGBA開発wikiを参考にして爆速でした、ダブル感謝

ついでにサンプリング周波数系のアレのメモ
  • 44.1kHz VGM仕様(?) - CDでお馴染み、なんで44.1kかは知らない
  • 約1Mhz GBソフト(M-Cycle) - 処理の最小単位(CGBは倍速も可能)。4194304 / 4
  • 約60fps GBソフト(VBlank) - だいたいこれ。画面更新と同じ。4194304 / 456 / 154 = 59.727500569606
  • 約360Tick LSDj/MusicROM(STAT) - Vコマンドとかで使うSTAT割込。1回の画面更新中に6回処理
  • 4096Hz LSDj/MusicROM(Timer) - 曲のBPMを決めるTimer割込。4194304 / 1024

という感じなので下手に変換するとjpgで保存されたドット絵ほどではないにせよ、非整数倍で拡大縮小したpng並には細部がズレます。作業用の便利なフォーマットとかは作らないとないです(

改造lsdpackのAPUログは360Tickなのでとりあえず1Mhz出力にしたいけどGBエミュ改造が避けられないのでまだ(ry

新フォーマット「gPSG」

ちょくちょく出てきた「VGMやAPUログから変換したGBAドライバ用バイナリ」というファイル。中身はほぼVGMのまま周波数を変更して使ってるけど、VGMは44.1kHz固定みたいなのでb3VGM(仮称)は違うなと思って「gPSG (GAMEBOY PSG Sound)」として区別するようにしました。

それに44.1kHzでイメージしがちな普通の(波の高さの)サンプリング周波数とも違いVBlank割込(60fps)やLSDj(360Tick)は処理の周波数です。MusicROMへの変換作業は1Tick内に2つの異なるデータが入ってきてハチャメチャになること普通にあります(死)

123_nisfx_gpsg

↑ これが公開中のテストROMです。効果音を再生(A)、停止(B)、loop切替(Select)。波形edit(Start)は確認のみ、編集は未実装


今のgPSGは、VBlank割込/HBlank何回割込で再生するデータかの情報がバイナリ内に無く、再生するドライバの実装で決定……とあくまで今回(360Tick)用の状態のままです。……ヘッダを付けて作業用のフォーマットに、はちょっと考えてます。


3. GBAから出る音がやっぱ違う!

  • DMG(初代GB)実機で聞きながら作った音をGBA実機で聞くとけっこう違う!!

  • GBAエミュはGB-PSGに力入れてないのか再現度がまぁまぁ低い

  • 波形メモリにけっこう気になるバグ(?)がある!もちろん実機で!!

まぁ想定通りで最後は耳で調整、そして死ぬ気でバグ取り。お決まりのパターンですね(白目


音が安定しないバグ(?)は原因不明、一部は波形メモリから矩形波に変えて作り直し。DMG実機、bgb、mGBA、NanoBoyAdvance(再現度は頭2つ抜けてるが鳴らない音がある)、SP実機をひたすら往復して調整。

元がFM音源の効果音でGBでアレンジするにしても微妙にLSDjで作れないとか、GBA特有のプチノイズが出るとかはAPUログを直編集(しかなかった)


で、akkeraさんにも音の感想をもらって、微調整してもっと良くなって無事完成!!でした。


4. 効果音聴き比べコーナー

比較しやすいよう最低限のマスタリング済。実機録音にノイズが乗ってるのは仕様です(

カナン SSG 21 (セレクト音)

たぶん一番聞く効果音

元がPSGで一音だと録音して波形を見れば答えが書いてあるに等しくサクサク再現できて面白かったです。

DMGで再現してもGBAで変わってしまったは結構あったけど(

夢幻夜想曲 FMX 1 (嵐の音)

FMXって名前だけど普通にノイズじゃない? 有識者にFM音源で鳴る仕組みと利点を教えてもらいました。すごい(小並感)

オリジナルはABCBCBCでループだけどAとCは大差ないのでCから開始。テストROMのループ機能はこれ用

カナン FMX 1 (落ちていく効果音)

元がFM音源の効果音は色々工夫してアレンジ。落ちる時の音なので落ちてる感を大事に

カナン FMX 4 (咆哮)

これの「ぐるる」感を出すのが無理だったけど「ぐわおうっ」とは言ってるので「ガオー」って感じ(?)

夢幻夜想曲 FMX 4 (特殊なセリフ音)

「館に閉じ込められた」世界観で、暗転して「偉人の名言が表示される」時の真面目なセリフ音、重要です。

連打して使われること、エミュの再現度、波形メモリの問題、木琴ような丸み広がりなど色々が色々で、あらゆることを試して最後は2音版と3音版の2つをakkeraさんに渡して判断を委ねました(逃げ


3音+ノイズの4つ全部使うことも可能でド派手な音も作れたけど、ほぼ2つあれば充分で3つはポケモンのなきごえレベル(=鳴りまくるとうるさい)で、効果音がゲームの邪魔することもあるよなって再発見もありました。

(おまけ) PC98起動音の仮完成版(DMG実機+LSDj再生)と、GBA版(SP実機)の比較

波形メモリで作った音はGBAで結構変わってしまったけどピポッは機種によって違うみたいだしいいかなと(

仮完成の時、どの機種に寄せるべきか悩んで某アニメの次回サブタイが出るところも参考にしてます(裏話)


不可能グラフィックには反則を

不可能グラフィック」とは! 背景(以下、BG)に257タイル以上使った一枚絵を表示すること!

不可能グラフィック

……いや、出来てるし不可能じゃないのでは?(クソリプ)


まぁ不可能弾幕(実は回避不可能ではない)を反則アイテム(弾幕ゲー的に)を使って攻略する「弾幕アマノジャク」の原曲「不可能弾幕には反則を」がCDに入ってるからどっちでも正しいけど(


というわけで、天邪鬼だか何だかわからない始め方だけど300タイル前後の一枚絵を出す方法を解説します!もちろんカラー専用(普通に512タイル使える)で作り直すとかじゃないです(

1. 256タイルまでは“可能”グラフィック(謎)

タイルは8bitで指定する仕様だから$00-$FFに対応する256種類しか使えない、故に256タイル制限

……これが一番分かりやすいと思います(


299タイル 245タイル

↑ 両方とも一枚絵のタイル指定マップ。GBの解像度を埋めるには8x8のタイルが20*18=360枚必要(=0x168)で

 左は実機の画像で見せた299種類のマップ、右は以前の245種類。どちらも8bitで360個です(ズルしてません)


ちなみに、キャラに使われるスプライト(以下、OBJ)も8bitなので同じ制限があります。

2. DMGで使用“可能”な機能は?

BG、OBJに256タイル制限がある一方、VRAMには384タイル分ロード出来る領域があります。

誰しも一度は「おっ?これは?」って思うけど、指定が8bitなので256制限は覆りません!絶対に


でも384(=128x3)タイルの内、使う256タイルの開始位置変える機能があって、上2つか、下2つかです。

よくあるのは上の256タイルがOBJ用、(128タイル重複で)下の256タイルがBG用として使う設定。これは自由に切り替えられます。

VRAMには384タイル

↑ 以前の199タイルを表示している時のVRAM。上128タイルがメニュー用、下256タイルが背景用の“よくある”設定です。


……今までは大人しく(?)VRAMを使ってましたが、

反則(言いたいだけ)「画面の描画が半分くらい終わったタイミングで、タイル開始位置を切り替え」ます!

299タイル 299タイル 245タイル

↑ 左から、299タイル使うために整頓したVRAM、タイル開始位置を下2つで固定した時の表示、上2つで固定した時の表示


毎フレームこの技を使って上手く切り替え続けたら制限がないように見せられる!という実にシンプルな技です。説明も楽。

3. “不可能”かもしれない

(STAT割込さえ知っていれば)画面描画中を狙って切り替える処理はそんなに難しくないです、たぶん。


でも、プリズムデモ(V2)の時からあったアイデアをずっと先送りしてきたのは、

  1. MusicROMはSTAT割込とTimer割込を両方同時に使っている(LSDjがそうだから仕方ない)

  2. STAT割込でVコマンドやkit再生の再現、オプションメニュー表示と既にたくさんの処理がある

  3. 変換で257タイルを超える160x144のpngは、既存のあらゆるもの相性が悪い


特に3で「VRAMの使い方を再考、使い方に合わせた画像変換ツールを開発、アセンブリで使い方を実装」とグラフィック関連は素材から全部見直しになりました(

1,2はHBlank割込が時々遅延する(例: n+5行目に処理される)ことがある状態で動いていて、ほぼ負荷を増やせない所に処理を追加する必要がありました。本当にこのままでいいのか?(


というわけで、開発が想定の三倍くらい大変で必死こいて例大祭に間に合わせました(

苦労したけど、力技で“作った”、死ぬ気で“直した”くらいでここに書けるような中身はないです(

弾幕ゲーの「気合で避けろ」や、音ゲーの「体力で喰らいつけ」と一緒。出来ないから攻略見たのに!(


4. ひみつのアセンブリ v1.0.1 更新

本当にギリギリで一旦削った機能の復活と「一日足りない」を悟って残してしまったバグ修正パッチです。


ひみつのアセンブリ v1.0.0用のv1.0.1更新データ。BPSパッチでの更新の方法はMusicROMの解説記事で。


機能追加、更新、復活

  • オプションメニューのinfoテキスト復活
  • UI非表示モード追加(Selectボタン)
  • ボタンアイコンのデザイン微調整、リジュームアイコン追加
  • 再生状態表示の現代化(※)
  • (仕様上最大9曲から99曲まで選択可能になった、2曲しか入ってないけど)
  • (仕様上最大317タイルから332タイルまで使用可能になった、301タイルで足りてるけど)
  • Select+Dpadに隠されていたデバッグ用機能の削除

(※ 再生中に[▶]再生ボタンを表示して“再生している”ことを示すのではなく、[||]一時停止ボタンを表示してユーザーの入力で“一時停止できる”ことを示すように変更。前者がCDプレイヤーとかの液晶、後者がスマホやYouTubeだったりするので“現代化”)


バグ修正

  • 画面上部がチラつくことがある(※)のを暫定修正
  • 不要になっていた初期化処理を削除、VRAMにゴミを転送していた処理を修正

(※ 「描画“中”にタイル開始位置を切り替え」の遅延は対策済だが「描画“後”にタイル開始位置を“戻す”」が遅延すると発生)


infoテキスト復活 リジュームアイコン

↑ 左、infoテキストも曲名と同じようにタイル書き換えにした。右、一時停止中なのでリジュームアイコン(止めたとこから再開)

5. 曲の話

効果音でいつもと違う音を色々作ったから曲でも使ってみよう!って感じで作りました。申し訳程度の音屋要素


「ひみつのアセンブリ」収録曲

  1. 反則の〇〇(仮 (原曲: 不可能弾幕には反則を / 弾幕アマノジャク 〜 Impossible Spell Card.)
  2. 真夜中でもダンス (原曲: 真夜中のフェアリーダンス / 妖精大戦争 〜 東方三月精)


効果音に使った低音の響きを補強する半分の周波数の波形ですが、GBAや各種エミュでは音が小さめです、無改造GBCに至ってはほとんど聞こえません(

……CDと比べながらハードウェアの性能チェックとかに使ってね(ぉぃ

半分の波形 普通の波形

↑ 半分の周波数の波形はこういうの、(だいたい)半分


ゲームだと本体のスピーカーで聞く人多いだろうし、DMGとGBAで同じ音が出せないことも分かったしで、効果音の確認でやったように環境を往復して落とし所を探すのがいいのかな、と(今回はアマノジャク)


あと、ゲームに使うことを少し意識して作ったけど……やっぱCDで続けて聞くのとゲームでループするBGMは違うかも……?、ゲーム完成あとは曲を付けるだけ、って状態になるまで正解がわからないまである。


6. このロゴ、どこかで……たしか、ひみつのアイp(ry

今週(5/26)放送された8話、推しに推し活(ナマモノ百合グッズ二次創作)を補足されたネット弁慶ぼっち陰キャ女オタクが推している推しの前で推しの話をする圧しの強いアイドル女と出会い著作権無視の応酬でお友達になる話で笑ったし良かったんスよねぇ(

二人が一緒に映るカットがやたら多いのは多分絵コンテが有能もしくはただの百合ヲタクだと拙者は思うのでござるがやは(以下略)


(左、音声なし動画。電柱が似合いそう) (右、教室で死ぬほどイチャついてるくせに百合イラストを見て照れるな!!捗る!!)

チュッピだからこういうの好きー!!

女児アニメだけど面白いよ✨(💗媚びを売る💗)、ニコニコで最新話見ようね🎵(💕追い媚び💕) 🧟3DCGライブ…🧟


15周年記事のあとがき

2024年前半をまとめた日記やん( その時好きだったものを記しておくのは重要だと思う(言い訳)


それはそうと「アセンブリは簡単だよ~みんなやろう~」って簡単そうな場所だけ見せて人を騙そうとしたのに(妖怪ムーブ)簡単そうな場所、全然ない(

まぁタイル数を考えずに描いた絵が300タイル前後だったんで自由に一枚絵を出したい人は参考にどうぞ(


あと、アセンブリからC(GBA用サウンドドライバ編集中)天国でした。こんなのみんなGBAに行ってしまうのでは?って手応えしか残ってません、なんか充実したwikiあるし(


15周年ってことは、……ココちゃんGBからもう5年(遠い目

毎回、次はゲーム……とか言ってる気がするので、もうエンジンを作ってからのゲームより、片っ端からテストゲームを作って使えそうなパーツを剥ぎ取ってキメラなエンジンにしたほうが良いのかも(

次の技術系の記事は、なにか見せときたくなる気持ちになる感じのが出来たら出します(雑


……あ、“ひみつ”とは一体何なのか!?(何も考えてない) 乞うご期待!!