WEBVTT 1 00:00:03.166 --> 00:00:05.733 こんにちは、くいなちゃんです。 2 00:00:05.733 --> 00:00:12.733 今回は作曲ソフトを自作して、作ったそのソフトで曲を自作していきましょう。 3 00:00:12.733 --> 00:00:18.300 実は既に完成した曲がもうありますので、早速聴いてみましょう。 4 00:00:28.166 --> 00:00:32.000 はい、ゲームで敵を倒したときに流れそうな音楽ですね。 5 00:00:32.000 --> 00:00:35.299 コード進行でちょっぴり遊んでしまいました。 6 00:00:35.299 --> 00:00:38.433 では、今からこれを作りましょう。 7 00:00:42.333 --> 00:00:44.466 とりあえずログインして、 8 00:00:49.799 --> 00:00:55.733 DocumentsフォルダにMusicMakerという名前で作業用フォルダを作りました。 9 00:00:55.733 --> 00:00:59.766 今回、DebianというLinuxディストリビューションを使っていますが、 10 00:00:59.766 --> 00:01:02.000 OSは何でも大丈夫です。 11 00:01:02.000 --> 00:01:06.733 FreeBSDでもWindowsでも好きなものを使ってください。 12 00:01:06.733 --> 00:01:09.433 それでは、とりあえずターミナルを開きます。 13 00:01:09.433 --> 00:01:13.599 main.cというファイルを作って、Vimで開きます。 14 00:01:13.599 --> 00:01:16.733 テキストエディターもVimでなくて大丈夫です。 15 00:01:16.733 --> 00:01:19.599 私は普段はVSCodeを使っていますが、 16 00:01:19.599 --> 00:01:22.766 ちょっと便利すぎて自作している雰囲気が出ないので、 17 00:01:22.766 --> 00:01:24.733 今回はVimで書きます。 18 00:01:24.733 --> 00:01:29.933 プログラミング言語も、Pythonなどを使えばライブラリが豊富で便利ですが、 19 00:01:29.933 --> 00:01:33.000 中で何をやっているのかが見えなくなってしまいますので、 20 00:01:33.000 --> 00:01:36.733 今回はあえてシンプルなC言語で書こうと思います。 21 00:01:36.733 --> 00:01:37.766 全部見せます。 22 00:01:38.733 --> 00:01:43.299 まずは片っ端から#includeして、main関数を書きます。 23 00:01:43.299 --> 00:01:45.599 さて、とりあえずの流れとして、 24 00:01:45.599 --> 00:01:50.200 このプログラムでWAVファイルを生成することをゴールとします。 25 00:01:50.200 --> 00:01:52.733 WAVファイルは音声ファイルの一種で、 26 00:01:52.733 --> 00:01:56.733 波形がそのままの形で含まれているフォーマットになります。 27 00:01:56.733 --> 00:02:00.733 つまり、人間にとって読み書きしやすい形式です。 28 00:02:00.733 --> 00:02:05.733 それではとりあえず、このWAVファイルのバイナリを格納するバッファーを作ります。 29 00:02:05.733 --> 00:02:10.233 サイズはまだわからないので、適当に1024にしましょう。 30 00:02:10.933 --> 00:02:12.766 (適宜、作業は倍速再生します) 31 00:02:13.400 --> 00:02:17.500 WriteBin関数で中身を書き込む想定にして、 32 00:02:17.500 --> 00:02:22.366 output.wavのファイルに出来上がったバイナリを出力します。 33 00:02:23.133 --> 00:02:26.733 (プログラミングたのしいです…) 34 00:02:28.633 --> 00:02:33.066 で、あとは、WriteBinで中身を作れば完成です。 35 00:02:36.099 --> 00:02:41.733 バイナリにIDや数値を書き込むためのユーティリティ関数を作っておきましょう。 36 00:02:42.666 --> 00:02:46.166 (とりあえず関数名は、WriteId、WriteIntとしました。) 37 00:02:49.966 --> 00:02:54.900 ここからは、WAVファイルのフォーマットに沿ってバイナリを書き込んでいきます。 38 00:02:59.500 --> 00:03:03.533 (WAVファイルの仕様書を見ながら書きます。) 39 00:03:05.966 --> 00:03:10.066 (また、10進数から16進数には、電卓を使って変換しています。) 40 00:03:12.333 --> 00:03:16.599 (今回は、44100Hzで16bitのモノラル音声に設定しました。) 41 00:03:18.866 --> 00:03:22.300 いよいよ、波形をバイナリに書き込む処理です。 42 00:03:22.300 --> 00:03:27.166 波形は、-1.0~1.0の小数で扱いたいのですが、 43 00:03:27.166 --> 00:03:28.800 今回のWAVファイルは、 44 00:03:28.800 --> 00:03:36.333 -32768~32767の整数で書き込むフォーマットになっているため、 45 00:03:36.333 --> 00:03:38.966 変換して書き込むようにします。 46 00:03:39.900 --> 00:03:44.266 (値が範囲を超えたときにクランプする処理を書いています…) 47 00:03:47.866 --> 00:03:50.033 とりあえず、一度ビルドして、 48 00:03:50.033 --> 00:03:53.566 WAVファイルが正しく生成されるかを確認しましょうか。 49 00:03:54.733 --> 00:03:56.533 ビルドは通りました。 50 00:03:58.733 --> 00:04:00.266 実行もできました。 51 00:04:00.500 --> 00:04:03.733 output.wavが生成されていますね。 52 00:04:03.733 --> 00:04:05.266 再生してみましょう。 53 00:04:06.533 --> 00:04:09.500 うーん、短すぎてよくわかりませんね。 54 00:04:09.500 --> 00:04:12.733 エラーは出ないため、フォーマットは正しそうに思えます。 55 00:04:13.199 --> 00:04:14.699 長くしてみましょう。 56 00:04:14.699 --> 00:04:22.666 サンプリング周波数は、44100Hzなので、44100の長さにして、1秒の音声にします。 57 00:04:23.233 --> 00:04:27.066 (またビルドと実行をして…) 58 00:04:28.166 --> 00:04:33.000 波形が常に0なので音は鳴りませんが、1秒間再生されているようです。 59 00:04:37.033 --> 00:04:40.166 試しに何か波形を書き込みましょう。 60 00:04:40.166 --> 00:04:45.733 440Hzのsin波は、人間の耳にはラの音で知覚されます。 61 00:04:45.733 --> 00:04:51.033 1秒間に440回振動するように、sin波を書き込みましょう。 62 00:04:57.733 --> 00:04:59.733 再生してみると、 63 00:05:01.100 --> 00:05:03.500 あ、ラの音が鳴りましたね。 64 00:05:03.500 --> 00:05:05.166 成功です。 65 00:05:05.166 --> 00:05:08.033 記念に別名保存しておきましょう。 66 00:05:10.199 --> 00:05:13.500 次は… あ、解放し忘れていました。 67 00:05:13.500 --> 00:05:14.966 解放しておきましょう。 68 00:05:16.166 --> 00:05:19.733 では次は、音階とメロディーを作っていきましょう。 69 00:05:19.733 --> 00:05:22.500 まずは、メロディーの音を書いていきます。 70 00:05:25.133 --> 00:05:30.166 CDEFGABの音と、長さの組み合わせを書きます。 71 00:05:30.166 --> 00:05:34.166 四分音符なら4、八分音符なら8と書きます。 72 00:05:36.666 --> 00:05:39.266 はい、『きらきら星』のメロディーです。 73 00:05:39.733 --> 00:05:45.066 CreateWaveという関数に、このメロディーを渡すと波形が生成される流れとします。 74 00:05:51.933 --> 00:05:58.066 この辺りには、渡ってきたメロディーの音階を波形に変換する処理を書きます。 75 00:05:58.066 --> 00:06:03.433 音は、周波数が2倍になるごとに1オクターブ音が高くなります。 76 00:06:03.433 --> 00:06:07.733 1/2倍になるごとに1オクターブ音が低くなります。 77 00:06:07.733 --> 00:06:11.800 つまり、440Hzに2^nをかけることで、 78 00:06:11.800 --> 00:06:15.733 オクターブ違いのラの音を鳴らすことができます。 79 00:06:15.733 --> 00:06:18.133 さらに、1オクターブの間には、 80 00:06:18.133 --> 00:06:22.733 ピアノの白鍵と黒鍵を合わせて12個の音があります。 81 00:06:22.733 --> 00:06:27.699 つまり、1オクターブを12分割した、m/12を考え、 82 00:06:27.699 --> 00:06:32.466 440Hzに2^(m/12)をかけることで、 83 00:06:32.466 --> 00:06:35.733 ピアノの鍵盤にあるすべての音が表せます。 84 00:06:35.733 --> 00:06:39.833 白鍵は、半音単位で考えると等間隔でないため、 85 00:06:39.833 --> 00:06:45.533 mは0、2、3、5、7、…のように不規則な値になります。 86 00:06:49.566 --> 00:06:52.233 おっと、ビルドエラーが起きました。 87 00:06:52.233 --> 00:06:54.899 配列の書き方が逆でした…。 88 00:06:57.433 --> 00:07:01.666 (修正中…) 89 00:07:06.633 --> 00:07:08.533 はい、再生してみましょう。 90 00:07:13.933 --> 00:07:15.966 無事、きらきら星が鳴りました。 91 00:07:15.966 --> 00:07:17.966 記念に別名保存します。 92 00:07:20.866 --> 00:07:23.733 さて次は、楽器を作っていきましょう。 93 00:07:23.733 --> 00:07:27.733 sin波以外にも、色々な音を鳴らしたいですよね。 94 00:07:27.733 --> 00:07:31.733 新たに、synthe.hとsynthe.cを作ります。 95 00:07:33.699 --> 00:07:37.899 (.h、.cはC言語用のファイルです。) 96 00:07:37.899 --> 00:07:42.366 (.hに関数の定義を書き、.cに実装を書きます。) 97 00:07:44.899 --> 00:07:47.899 sin波の他に、三角波も追加しましょう。 98 00:07:47.899 --> 00:07:51.966 三角波は、sin波よりも明るく目立つ音になります。 99 00:07:53.233 --> 00:07:55.466 (sin波はなめらかな波ですが、) 100 00:07:55.466 --> 00:07:59.233 (三角波は文字通り、上下に三角形を連ねた形の波です。) 101 00:07:59.733 --> 00:08:01.933 はい、三角波が完成しました。 (たぶん) 102 00:08:10.333 --> 00:08:12.699 他にも、色々な楽器を追加しましょう。 103 00:08:13.300 --> 00:08:16.733 出来るか分かりませんが、ピアノに挑戦しましょう。 104 00:08:16.733 --> 00:08:19.733 ピアノは、倍音が多い楽器です。 105 00:08:19.733 --> 00:08:23.500 cos波の重ね合わせで、倍音を表現します。 106 00:08:23.966 --> 00:08:27.366 (倍音とは、周波数を2倍、3倍…として重なった音のことです。) 107 00:08:29.100 --> 00:08:34.733 ここで、シンセサイザーにおける基本機能のADSRの関数を実装しましょう。 108 00:08:34.733 --> 00:08:39.899 ADSRは、Attack、Decay、Sustain、Releaseの頭文字で、 109 00:08:39.899 --> 00:08:43.033 音の持続や鳴り方を制御できるものです。 110 00:08:43.033 --> 00:08:45.333 例えば、ピアノの音を鳴らすと、 111 00:08:45.333 --> 00:08:49.733 いきなり大きな音が鳴ってから、自然に小さい音になっていきます。 112 00:08:49.733 --> 00:08:51.733 一方、ヴァイオリンの音を鳴らすと、 113 00:08:51.733 --> 00:08:54.799 一番大きな音になるまで少し時間がかかりますが、 114 00:08:54.799 --> 00:08:57.500 ずっと音を鳴らし続けることができます。 115 00:08:57.500 --> 00:09:00.000 このように、楽器の音を鳴らした時の、 116 00:09:00.000 --> 00:09:03.933 音の大きさの変化を再現するものがADSRです。 117 00:09:05.799 --> 00:09:07.966 (じつは低音から高音にかけてのdecayの順序が逆になっていました。) 118 00:09:07.966 --> 00:09:10.200 (これだとピアノっぽい音になりません…) 119 00:09:12.100 --> 00:09:14.733 倍音の周波数をわずかにずらすことで、 120 00:09:14.733 --> 00:09:18.766 ピアノの弦の剛性が再現できるらしいので、試してみます。 121 00:09:29.066 --> 00:09:33.366 ピアノっぽいかは疑問ですが、とりあえずピアノの音が出来上がりました。 122 00:09:35.366 --> 00:09:37.266 次は、Leadです。 123 00:09:37.266 --> 00:09:39.833 矩形波をsin関数で表現します。 124 00:09:40.266 --> 00:09:44.233 (矩形波とは、上下に長方形が並んだような波のことです。) 125 00:09:44.899 --> 00:09:48.566 本来なら、無限に倍音を重ねる必要がありますが、 126 00:09:48.566 --> 00:09:51.100 倍音を4つ程度に制限することで、 127 00:09:51.100 --> 00:09:53.733 矩形波の音に丸みを持たせます。 128 00:09:53.733 --> 00:09:56.866 そして、2つのオクターブ違いの音を重ね、 129 00:09:56.866 --> 00:10:00.200 わずかに周波数をずらして、音に厚みを持たせます。 130 00:10:01.566 --> 00:10:05.766 (いわゆるDetuneという効果です。) 131 00:10:06.366 --> 00:10:08.733 ついでに、ビブラートもかけましょう。 132 00:10:08.733 --> 00:10:12.933 音を長く鳴らした時に、だんだん音の高さに揺れが生じることで、 133 00:10:12.933 --> 00:10:15.899 人の歌声のビブラートを模したような音になります。 134 00:10:26.366 --> 00:10:28.399 はい、Leadも完成しました。 135 00:10:30.600 --> 00:10:32.233 最後に、Padです。 136 00:10:32.233 --> 00:10:36.500 Padは、Attackを小さく、ふわっとした音にします。 137 00:10:36.500 --> 00:10:39.433 1音を鳴らすだけで、和音が鳴るようにします。 138 00:10:53.633 --> 00:10:55.299 はい、Padも完成です。 139 00:10:57.966 --> 00:11:00.833 楽器ごとに音量が変えられるようにしましょう。 140 00:11:01.233 --> 00:11:04.733 (volumeという引数を、各楽器に付けて回ります。) 141 00:11:05.133 --> 00:11:09.733 さてそれでは、楽器が揃ったので、作曲の方に取り掛かります。 142 00:11:09.733 --> 00:11:14.733 今のままだと、CDEFGABの7音しか使えませんので、 143 00:11:14.733 --> 00:11:18.100 オクターブの変更と、黒鍵の実装を行います。 144 00:11:18.100 --> 00:11:19.533 休符にも対応します。 145 00:11:23.066 --> 00:11:26.066 (「-」で半音下げ、「+」で半音上げるようにします。) 146 00:11:29.166 --> 00:11:33.066 それでは、頭の中で曲を作りながら、打ち込んでいきます。 147 00:11:33.833 --> 00:11:37.866 (脳内作曲中…) 148 00:11:38.200 --> 00:11:40.066 メロディーはこんな感じです。 149 00:11:42.166 --> 00:11:45.166 (2パート目を作成中…) 150 00:11:45.766 --> 00:11:47.933 続いて、ベースを打ち込んでいきます。 151 00:11:51.466 --> 00:11:54.000 パッドで、コードの音を補強します。 152 00:11:54.399 --> 00:11:57.000 (コードは大切…) 153 00:11:57.333 --> 00:12:00.466 高音にピコピコした音を追加しましょう。 154 00:12:00.466 --> 00:12:02.166 曲調がキラキラします。 155 00:12:03.633 --> 00:12:07.966 (基本的にはコードに則りながら、) 156 00:12:07.966 --> 00:12:12.333 (アルペジオやスケールを散りばめます。) 157 00:12:13.966 --> 00:12:17.299 最後に、空いた中低音にピアノを追加しましょう。 158 00:12:18.000 --> 00:12:19.899 (なるべく周波数の空いたところに、 159 00:12:19.899 --> 00:12:21.933 (音を配置していくと良いですね。) 160 00:12:22.833 --> 00:12:25.933 このままだと、複数の波形が組み合わさって、 161 00:12:25.933 --> 00:12:30.799 波形が-1.0~1.0の範囲から超えてしまいます。 162 00:12:30.799 --> 00:12:33.600 今は、超えた部分はクランプしているため、 163 00:12:33.600 --> 00:12:37.000 波形が大きく壊れてノイズになってしまいます。 164 00:12:37.000 --> 00:12:41.100 そこで、-1.0~1.0の範囲になるように、 165 00:12:41.100 --> 00:12:42.766 全体を正規化しましょう。 166 00:12:43.466 --> 00:12:45.233 ピークの絶対値で割ることで、 167 00:12:45.233 --> 00:12:49.666 波形は-1.0~1.0の範囲にスケールされます。 168 00:12:54.533 --> 00:12:58.233 念のため、ピークの値をコンソールに出力しておきます。 169 00:13:12.500 --> 00:13:15.533 はい、それらしい曲が出来上がりました。 170 00:13:15.533 --> 00:13:20.266 では、これにディレイをかけて、音に奥行きを待たせたいと思います。 171 00:13:20.266 --> 00:13:23.100 ディレイとは、いわゆるエコーの一種です。 172 00:13:23.100 --> 00:13:25.733 鳴らした音を時間差で再度鳴らすことで、 173 00:13:25.733 --> 00:13:28.266 反響音のような効果を持たせます。 174 00:13:29.200 --> 00:13:31.633 反響音が鳴り終わるまでの部分で、 175 00:13:31.633 --> 00:13:35.433 曲の長さが伸びるため、曲の長さを更新するようにします。 176 00:13:39.766 --> 00:13:43.866 おっと…、曲本体の部分に反響音を書き込んでしまうと、 177 00:13:43.866 --> 00:13:49.233 その反響音も曲本体とみなされて、さらに反響音が生成されてしまいます。 178 00:13:49.233 --> 00:13:52.066 これを防ぐために、先頭からではなく、 179 00:13:52.066 --> 00:13:55.566 波形の末尾から先頭に向かって逆順で処理します。 180 00:13:56.366 --> 00:13:59.200 反響音は1回である必要はないので、 181 00:13:59.200 --> 00:14:02.633 時間差と音量差をつけて複数回にします。 182 00:14:03.799 --> 00:14:06.799 (ところで、今流れているBGMも自作だったりします。) 183 00:14:07.133 --> 00:14:09.166 ついでに、いろいろ調節します。 184 00:14:25.533 --> 00:14:28.566 はい、ディレイがかかってきれいになりました。 185 00:14:29.433 --> 00:14:32.133 ちょっとピアノの音にオーバードライブをかけて、 186 00:14:32.133 --> 00:14:34.166 軽く歪ませたいと思います。 187 00:14:34.166 --> 00:14:36.733 波形のプラス部分とマイナス部分とに、 188 00:14:36.733 --> 00:14:38.866 非対称なかけ方をすることで、 189 00:14:38.866 --> 00:14:41.966 独特の豊かな効果が生まれるらしいです。 190 00:14:41.966 --> 00:14:43.066 試してみましょう。 191 00:14:44.100 --> 00:14:45.399 連続性のため、 192 00:14:45.399 --> 00:14:48.466 tanhなどがよく使われるようです。 193 00:14:49.933 --> 00:14:52.633 他にもいろいろバランスを整えたいため、 194 00:14:52.633 --> 00:14:53.700 微調整します。 195 00:14:54.899 --> 00:14:59.466 今は波形を-1.0~1.0の範囲に正規化していますが、 196 00:14:59.466 --> 00:15:02.100 それだと全体的に波形が縮小され、 197 00:15:02.100 --> 00:15:04.200 音が小さくなってしまいます。 198 00:15:04.200 --> 00:15:07.733 そこで、なるべくもともとの波形の形を保ったまま、 199 00:15:07.733 --> 00:15:11.200 -1.0~1.0の範囲に収めることを考えます。 200 00:15:11.766 --> 00:15:15.033 そこで活躍するのが、コンプレッサとリミッターです。 201 00:15:15.733 --> 00:15:18.933 コンプレッサは、波形が一定レベルを超えたときに、 202 00:15:18.933 --> 00:15:21.933 超えた部分だけを圧縮する機能を持ちます。 203 00:15:21.933 --> 00:15:25.733 つまり、正規化で全体的にスケールをかけるのではなく、 204 00:15:25.733 --> 00:15:29.733 波形がたまに飛び出した部分だけにスケールをかけるイメージです。 205 00:15:29.733 --> 00:15:32.766 こうすることで、体感的な音圧が高まります。 206 00:15:33.966 --> 00:15:37.866 (コンプレッサをかけることで、音に迫力が出て全体がまとまるので、) 207 00:15:37.866 --> 00:15:42.000 (使ったことがない人は、ぜひ使ってみてください。) 208 00:15:42.000 --> 00:15:46.500 (みんな使っています。) 209 00:15:48.100 --> 00:15:53.533 リミッターは、コンプレッサの圧縮率を非常に高めたものというイメージです。 210 00:15:53.533 --> 00:15:56.733 圧縮率を無限大にすることもあります。 211 00:15:56.733 --> 00:15:59.299 今回は、波形が一定レベルを超えたときに、 212 00:15:59.299 --> 00:16:01.833 そこで単純にクリップさせようと思います。 213 00:16:01.833 --> 00:16:04.899 やりすぎると、ノイズが乗りますので注意が必要です。 214 00:16:08.933 --> 00:16:12.600 それでは、最終形が完成しました。聴いてみましょう。 215 00:16:23.566 --> 00:16:25.233 イコライザーを使いたくなったら、 216 00:16:25.233 --> 00:16:28.166 高速フーリエ変換も実装する必要が出てきますが、 217 00:16:28.166 --> 00:16:30.733 今回はこれで完成としたいと思います。 218 00:16:32.399 --> 00:16:35.033 みなさんも、もし無人島に遭難したら、 219 00:16:35.033 --> 00:16:38.566 VSCodeやPythonなどのリッチな環境は使えません。 220 00:16:38.566 --> 00:16:41.533 ぜひ、一からWAVファイルを作ってみてくださいね。 221 00:16:42.166 --> 00:16:43.533 ばいばーい。