JavaScript でファミコン風の音楽を奏でる 〜ファミコン音楽と実践編〜

# 0. 目次

1. [はじめに](#1-はじめに)
1. [ファミコンの音楽](#2-ファミコンの音楽)
1. [実践](#3-実践)
1. [まとめ](#4-まとめ)
1. [おわりに](#5-おわりに)

# 1. はじめに

こんにちは、@linked34ceです。
[MYJLab Advent Calender](https://qiita.com/advent-calendar/2022/myjlab) の企画に参加しています。
今回は[超入門・音楽理論編](https://qiita.com/linked34ce/items/22539fd81206daa8df35)に続き、ファミコンの音楽の特徴について解説した後、実際に JavaScript でファミコン風の音楽を演奏するところまでやってみましょう。
なお、今回は音楽を奏でてみることが目的なので、プログラムについて詳しく解説することはしません。
気になる人はソースコードを見てください。

# 2. ファミコンの音楽

## 2.1. ピコピコ音

ファミリーコンピュータ、通称ファミコンの音楽と聞いて、どのようなものを思い浮かべますか。
多くの人は『スーパーマリオブラザーズ』の地上 BGM を想像するでしょう。
少しゲームに詳しい人なら、『ロックマン』シリーズの音楽を思い浮かべる人もいるでしょう。
そのどれもが、「ピコピコ音」から成り立っています。
「ピコピコ音」は一歩間違えれば耳障りとも言えそうですが、この独特なレトロな感じを好む人も一定数いて、投稿主もその一人だったりします。

ファミコンでは、一部例外もありますが、同時に4つの音しか鳴らすことができません。
つまり5つ以上の音が同時に鳴っているファミコン風アレンジ曲などは、正しくファミコンの音が再現できていないのです。

例えば『ロックマン2』の『DR.WILY STAGE 1』という曲は名曲として名高いですが、たった4つの音から構成されているとは思えないほどのクオリティです。
それでも。同時に4音までという制約をきちんと守っています。
正確には、ファミコンのの能力としてそれより多くの音を出すことが不可能だったため、守らざるを得なかったというわけです。

このように、厳しい制約を持つ音源チップで作られる音楽を **チップチューン** といいます。
ファミコンに限っては、CPU が 8bit であったため、8bit サウンド、あるいは単に **8bit** と呼ばれることもあります。
スーパーファミコンの音楽は、同様に **16bit** と呼ばれます。

## 2.2. ファミコン音楽の音色

ファミコンは同時に4つの音しか出せませんが、その音色にも制限があります。
それが **矩形波**、**擬似三角波**、**ノイズ** の3種類です。
しかも同時に出せるのは矩形波2つ、擬似三角波1つ、ノイズ1つと決まっています。
それぞれの特徴を見ていきましょう。

### 矩形波

矩形波の「矩形」とは、長方形という意味です。
その名の通り、四角い波形を持ちます。
無理やり記号で表すとこんな感じです。

＿＿|￣￣|＿＿|￣￣|＿＿|￣￣|＿＿|￣￣|＿＿

この波形では、|￣￣|＿＿ という1周期における  ￣￣ の部分と ＿＿ の部分の長さが同じですね。
言い換えると、￣￣ の部分が1周期の50%を占めています。
そのため、これは50%の矩形波といいます。
この矩形波の音は「ブー、ブー」というビープ音に近いです。

ファミコンでは、50%以外にも、25%、12.5%の矩形波を出力できます。

25%の矩形波は、以下のようになります。

＿＿|￣|＿＿|￣|＿＿|￣|＿＿|￣|＿＿

50%に比べて、ポワッとしたような音がして、少しやわらかい印象を持ちます。

また12.5%の矩形波は以下のようになります。

＿＿|‾|＿＿|‾|＿＿|‾|＿＿|‾|＿＿

25%よりもさらに鼻にかかったような音がします。

ファミコンは正確には75%の矩形波も出せるようですが、実質的に波形が25%と同じなので、50%、25%、12.5%の3種類のみとして扱われます。

実際の楽曲においては、メロディやハーモニーを担当することが多いです。
矩形波に限っては、音量を調節したり、波形を変えてビブラートを効かせたりするなど、応用を効かせることができます。

### 擬似三角波

三角波は、以下のような三角形の波形を持ちます。

／＼／＼／＼／＼／＼／＼／＼／＼／＼

しかしファミコンの性能では完全な三角形を作ることができません。
そのため、実際には ／ や ＼ の部分はギザギザの階段状になっています。
このように完全な三角波ではないため、擬似三角波と呼ばれるわけです。

擬似三角波の音色は矩形波よりさらに柔らかく、極めて独特なモヤッとした感じです。
この音が楽曲にファミコンらしさを与えてくれると言ってもいいでしょう。

楽曲においてはベースとして扱われることがほとんどです。
擬似三角波は音量を変えることができないため、矩形波の音量を相対的に調整する必要があります。

### ノイズ

ノイズはその名の通り雑音のような音です。
しかし、ホワイトノイズと呼ばれる完全にランダムに波形が生成される雑音とは異なります。
ファミコンのノイズは擬似乱数によって生成されるため、一定の周期性を持ちます。

低い音では「ガッ、ガッ」、高い音では「サーッ、サーッ」というように聞こえます。

楽曲ではドラムやパーカッションを担当します。
効果音として使用されることも多いです。

# 3. 実践

# 3.1. Web Audio API

ファミコンの音楽について軽く学んだところで、いよいよ JavaScript で「ファミコン風」の音楽を演奏してみましょう。
すべてを具体的に説明すると、これだけでアドベントカレンダーが埋まってしまうので、大まかな手順だけ説明します。

JavaScript で音を鳴らすためには、**Web Audio API** を使用します。

このAPIを使用すると、50%の矩形波と三角波を生成できます。
また、波形を強引に作ることでノイズも流せます。

お気づきの通り、矩形波は50%のみしか出せず、三角波は擬似三角波ではありません。
さらにノイズは、ファミコンの仕様を完全に理解すれば再現できるかもしれませんが、投稿主の力量ではファミコンのノイズと同等なものは作れませんでした。

そのため、あくまで「ファミコン風」というわけです。

## 3.2. 作曲

作曲の具体的な説明は省きますが、以下のようにしてレトロゲームの戦闘曲のようなオリジナル曲を作っていきます。

### ① DAW を立ち上げる

**DAW** とは、簡単にいえば作曲用のソフトウェアです。
投稿主は MacBook Pro に最初から入っていた GarageBand を使用しました。
そしてファミコン音楽が再現できる **Magical 8bit Plug 2** というプラグインを導入します。

### ② スケールを決める

ゲームの戦闘曲では、暗いけれど勇ましい雰囲気のある **短調** を使用するとかっこいい感じになります。
逆に **長調** にすると明るいけれど穏やかな雰囲気になり、「バトルするぞ！」という感じが失われます。
今回はできる限り簡単に作りたいため、Aマイナースケールを使用します。

### ③ コード進行を決める

前回学んだ知識を活かして、コード進行を決めます。
Aマイナースケールを用いるため、主和音である Am を基準として考えます。
定番のコード進行を使ってもいいですし、好きな楽曲のコード進行を借りてもいいでしょう。
思いつかない場合は、

Am → Bm → C → Dm → Em → Dm → C → Bm

というように、階段状に移行する簡単な進行を使ってみましょう。
意外とそれっぽくなります。
投稿主も大部分でこの進行を使用しました。

### ④ ベースを打ち込む

普通の楽曲であればコード進行に対応するストリングス (弦楽器) などを打ち込みますが、ファミコンではそんな大層なものは使えません。
そのため、まずは擬似三角波を用いて単音でベースを打ち込みます。
コードのルート音を8分音符で連続して打ち込むだけでひとまずOKです。

ただし、絶対に単音です。
それ以上の音を使うとレギュレーション違反です。

### ⑤ ドラムを打ち込む

音楽において、リズムはメロディやコードと同じくらい重要です。
戦闘曲なので、**BPM** を170くらいのハイテンポにして、ノイズを用いてドラムを打ち込みます。

BPM とは、Beats Per Minute の略で、1分間における拍数を表します。
今回は4分の4拍子で作曲します。
つまり、BPM = 170 とは、1分間に4分音符が170個分入るテンポである、ということです。

ドラムを打ち込んだ時点で、ファミコンの4音のうち、2つが消費されてしまいましたね。

### ⑥ メロディを打ち込む

ベースとドラムがきちんと打ち込まれていれば、メロディは何となくでも大丈夫です。
鼻歌を歌いながら思いついたメロディを矩形波で打ち込んでみましょう。

ただし、基本的にはスケール内の音を使います。
今回はAマイナースケールですから、半音記号なしの「A B C D E F G」を主に使います。

また、ピッチよりもリズムを意識してみると、いい感じになります。
特に、休符を意識的に入れてみましょう。
楽曲にメリハリがついて聴き心地が良くなります。

なお、Web Audio API で曲を流す前提として、矩形波は50%のみを使用し、ピッチベンドやビブラートなどのオプションは使わないようにします。
ハーモニーについても同じです。
実際は Web Audio API をフルに活用すればビブラートなどのエフェクトも掛けられますが、難しいので諦めます。

### ⑦ ハーモニーを打ち込む

メロディーに対するハーモニーを矩形波で打ち込みます。
コードの考えから、3度または5度離れた音を使うとハモらせることができます。

またメロディーのピッチをほんの少し (1Hz) だけ上げて、わずかにタイミングを遅らせたものを配置する、というテクニックがあります。
すると **ディレイ** のような効果が得られ、たった2音ではありながらも、音楽に空間的な広がりが加わります。

また、コードの構成音を分解して短い間隔で階段状に配置するという手法もあります。
これは **アルペジオ (分散和音)** と呼ばれ、実際には1音なのに複数の音を使っているように聴こえ、華やかな感じがします。

### ⑧ 編曲する

必死に打ち込んでも、実際に聴いてみるとダサい感じがすることがあります。
そんな時はピッチやリズムを調整して、かっこよく聴こえるまで粘りましょう。

ある音の前に一瞬だけ半音下または半音上の音を置くとオシャレに聴こえる、というテクニックもあります。

他にも、ベースに **経過音** を導入するのもよい手法です。
経過音とは、離れた音を滑らかにつなぐために入れる音のことです。

## 3.3. JavaScriptで再生する

作曲した音楽をファミコンの4音に対応する4トラックに分け、連想配列の配列として打ち込んでいきます。
地道な作業ですね。

そして完成したものが [こちら](https://linked34ce.github.io/famicom-music/) です。
「再生」ボタンを押すと投稿主のオリジナル曲が流れます。

※どうやら、PC版の Google Chrome でないとノイズの音が意図した通りに鳴らないようです。


残念ながら、ページの見た目や UI などにこだわる時間はありませんでした。
具体的なソースコードなどは、ブラウザの検証ツールや [GitHub](https://github.com/linked34ce/famicom-music/) から見てください。

# 4. まとめ

- 音源チップの厳しい制約の中で創作する音楽のジャンルを **チップチューン** という。
- ファミコンの音楽は、**矩形波** 2つ、**擬似三角波** 1つ、**ノイズ** 1つの4音のみで構成されている。
- JavaScript で任意の音を鳴らすには、**Web Audio API** を活用する。
- 作曲においては、**スケール** や **コード進行**、**BPM** などの要素をあらかじめ決めておくとよい。
- **長調** は明るく穏やかな楽曲に向いていて、**短調** は暗いけれど勇ましい感じの楽曲に適している。
- 音数の少ないファミコン音楽では、**アルペジオ** は効果的である。

# 5. おわりに

前回の音楽に関する知識を活かしつつ、今回は JavaScript でファミコン風のオリジナル楽曲を演奏してみました。
実際のところ、作曲だけは数ヶ月前から少しずつ進めていたため、一番時間がかかっています。
拙い音楽ではありますが、ぜひ聴いてみてください。

なお、今回は GitHub Pages で公開したため、[GitHub](https://github.com/linked34ce/famicom-music/) からソースコードをダウンロードし、楽譜を改変して任意の音楽を鳴らすことも可能です。
自分だけのオリジナル曲や、お気に入りのゲームの BGM 、好きな歌手やバンドの楽曲など、自由に楽しんでみてください。

@linked34ce でした。
それでは。