ソフトシンセ(の基本)

注意:ここではある程度デモの話,C言語の基礎,WinAPIがわかるという前提で話を進めていきます。
その辺の話からよくわからない方はそういうサイトを回ってからの方が良いと思われます。
あと、VisualC++(以下VC)限定なので他の方にはあまり有効でないかもしれません。



前回は単にバッファに作成した単純波形を再生するだけでした。
しかし、コレでは"音"はなっても、"音楽"にはなりませんね。
とりあえず、音楽として必要な基本を紹介していきます。
(コレをかいてる私(kioku)は音楽についてはさっぱりなのでかなりアバウトです。
もしかしたらかなりおかしいことをいってるかもしれないので鵜呑みにしないほうがいいかもしれません。(ぉ
まぁそういうのがあるんだ・・・程度で・・。)


●音階
音階というと「ドレミファソラシド」のことですね。
まぁ、音楽関係をやってる方には非常に当たり前のことと思われますが、まぁ基本的なことですし
かなりキーですからね。

まず、440Hzの音が『ラ』の音の高さとなっています。
そして、220Hzの音を1オクターブ低い、880Hzの音を1オクターブ高い『ラ』の音とします。
このオクターブの周波数の間を2の指数乗の感覚で12分割します。
12分割の理由は「ドレミファソラシド」の間にシャープとかフラットとかの、半音があるからですね
まぁ数を数えると鍵盤が12個あるわけです。(どっちの決まりが先かは知りませんが・・・)
音階 周波数(Hz)
・・・ ・・・
220*2^( 0/12)
220*2^( 2/12)
220*2^( 3/12)
220*2^( 5/12)
220*2^( 7/12)
ファ 220*2^( 8/12)
220*2^(10/12)
440*2^( 0/12)
440*2^( 2/12)
440*2^( 3/12)
440*2^( 5/12)
440*2^( 7/12)
ファ 440*2^( 8/12)
440*2^(10/12)
880*2^( 0/12)
・・・ ・・・
こんな感じですかね。 (^は階乗記号です。)
指数乗の数字が飛んでいるところが半音です。

実際にどのようにコードで使うかは
前回の波形生成のところで
 long t;
 float f = (鳴らしたい周波数);
 short* wave_data=(short*)GlobalAlloc(GPTR,sizeof(short)*44100);
 for(t=0; t<44100; t++){
     if( (t%(44100/f))<100 ) wave_data[t] =  32767;  
     else                    wave_data[t] = -32767;  
 }
としてやればいいわけです。



●和音
まぁコレは読んで字のごとく、音と音を合わせたものです。音と音の合成ですね。
まぁ、音楽的にどれとどれを組み合わせるかは、作曲の問題なので触れません。
コード的には音の波を加算したものを作るだけです。
> wave_data[t] = wave_dataA[t] + wave_dataB[t];
特に問題はないですね・・・。



●波形の種類
今までは矩形波だけを扱ってきました。波形についていくらか知っている方は
すでに、sin波や三角波、のこぎり波などが思い浮かぶでしょう。
これらが良くわからない方は、ちょっと検索してもらえればすぐに、すばらしい図解で
詳しく図解されたサイトが出てくるでしょうし、シンセサイザーなどで作曲される方などは
良くご存知のことでしょうから、とくには触れません。
(私の中では作曲の範疇だと思ってますんで・・・)
まぁ使うときは、はやり矩形波とおなじく、バッファに書き込んでそれを使います。

 long t;
 float f = (鳴らしたい周波数);
 short* wave_data=(short*)GlobalAlloc(GPTR,sizeof(short)*44100);
 for(t=0; t<44100; t++){
     wave_data[t] = (long)(32767*sin(2*PI*f*t));
 }

まぁ特には難しくないでしょう・・・。
ただし、sin関数など標準関数のものは使えないので(サイズを減らすときにライブラリをリンクしてません)
自前で作成する必要があります。テイラー展開などのコードを書いてください・・・。
他にも高速に生成する手法などもありますが、とりあえずテイラー展開がわかりやすいかと・・・
あと、浮動小数点を整数に変換するのにも、ちょっと追加コードが必要になります。
デフォルトでコンパイルしてしまうと_ftolがない・・・とかいわれてしまいます。
(VC6だといわれないと思いますが・・・) 回避策はサンプルにかいときました。



●楽器データ構造
さて、ここまでで、いくつかの波形を紹介したわけですが、
これらの波形をただ単に合成するだけでは、なかなか良い音が作れるわけではありません。
というか、無理です。基本波しかないのでどうがんばってもファ●コンが限界です。
そこで、やっぱり、かっこいい音を鳴らしたい!ソフトシンセといえばシンセサイズ!
ということで、音(波形)をシンセサイズして、その音を楽譜データをもとに鳴らすと
いうわけです。
このシンセサイズの方法はいろいろあり、ここで全部書いているとキリがないので
簡単にだけ触れておきます。

まず、基本波をいくつか加算してさまざまな音をだす加算式と呼ばれる方法があります。
また、基本波を1つきめて、その波形にハイパスフィルターやローパスフィルターなどの
フィルターと呼ばれるものを通し、波形を変形(?)させる減算式。というものもあります。
また、FM音源とかいわれるものを聞いたことがあるかもしれませんが、FM変調というものがあり
波形を変調させて、さまざまな音を出す方式もあります。
この辺の話は、音楽に詳しい人なら良く知っていることだと思うので、
そういう人たちに任せることにしましょう。(コードの話がないし・・・。)

まぁ、それらの方式を選んだら、波形をつくるために必要なパラメータを決め、
そのパラメータを楽器データとして保存するようにします。
バッファに作るときに、sinなどの基本波ではなく、それらのパラメータによる波形で
曲をつくると、カッコイイ(?)音がなるといいうわけです。



●楽譜データ構造
まぁ一番ソフトシンセで問題となるのがファイルデータ構造でしょう
なぜ、あの小さなサイズで音楽がなるのか?という疑問に一番答えられるものでしょう。
サイズが小さい理由は、曲データが小さいからです。
その小さい曲データをもとに、先ほどまでの周波数を生成するコードを対応させて
長いバッファの波形が詰まったものをつくり、それを再生してやることで曲を鳴らします。

簡単に言うと
「ドレミファソラシド」
という楽譜があって、それを元にドレミファソラシドの波形を作り出し、
バッファ内に構築してやればよいわけです。
まぁさすがに音階だけでは、どういう曲かは特定できませんので
演奏の早さ(BPMや音符の種類)などを同時に記録するようにしておけばよいでしょう
これらの、データでどれを必要として、どれを必要としないかはシンセを設計する段階で
決めておかねばならないでしょう。パラメータをたくさん増やせば増やすほど、
さまざまな音楽を再生することができますが、その分データ量がふえて重くなります。
楽譜データは長い曲になればなるほどデータが増えますから、なるべく小さいほうがいいでしょう。
かのfarbrauschのソフトシンセをつくったkb氏によれば、SMF(standard midi file)形式が
非常に64kbのファイル形式に有効らしいです。たしかに小さいようですね。
参考ページ:kb氏のシンセ解説
私がやっている方法は、もっと原始的で
『ドレミファソラシド』の音階を、ピアノの鍵盤であらわすとみたて
キーボードの『asdfghjk』に対応させました。
まぁコレはtoolのKSynthを見てもらえばわかると思いますが
まぁ、そのままですね・・・(w
これだと、ぱっとみ何の音階なのかわかりませんが、sinclいわく
「なれたらどってことない。」だそうです。(私は楽譜以前がわかりません(汗
まぁやっぱり見にくいという人は、楽譜に置き換えるインターフェースの作曲ツールをつくるか
C-7とかのコードで表示するかにするのが良いと思います。

まぁ、この辺の曲データ構成が一番オリジナリティを発揮するところでもあるので
ここであまりとやかく書いてしまうと、ちょっとアレなので、この程度にしておきます。
(私のやっている方法が最善ではないですし・・・。)



●まとめ
さて、ここまでがソフトシンセの基本的な枠組みです。
え?中身がさっぱり書いてないって?ええそのとおりです。
だって、それを書いてしまうと、グラフィックでいうと
どうやってこのエフェクト書くんですか?とかという質問と同じになってしまいます。
このTIPSでの目的はあくまで、64KBデモの作り方であって、作成ではありません。
それに、上でも書きましたが、オリジナリティを発揮する場所です。
人の考えたコードをまねても面白くありませんし、ゼロから自分で構築するのが面白いと思っています。
64KB用のソフトシンセのヒントとしては十分に出したつもりです。
あとはひたすら良い曲データ構造を考えだして、それを実装するのみです。
みなさんも、ぜひ自分だけのシンセシステムを構築して64KBデモをつくってみてください。
・・・
と、なげやりに放置しても、なんだかなぁといわれるので
チョー簡単な曲システムのサンプルソースをおいときます。




感想・質問・間違い指摘はBBSまで・・・