# NLLのオーディオ機能の利用方法

## サンプルプログラム

まずはサンプルプログラムを動かしてみてください．

	nll> NEW
	nll> LOAD "samples/audio/a_brass.nll"
	nll> RUN

もしくは

	$ nll samples/audio/a_brass.nll

## 音を鳴らす

### ドレミを鳴らす

まずは以下のように，MML文法によってドレミの音を鳴らすことができます．

	nll> APLAY("CDE")

MMLでは，ドレミのドはC，レはD，ミはEです．
ドレミファソラシは以下で鳴らせます．

	nll> APLAY("CDEFGAB")

小文字でも構いません．

	nll> APLAY("cdefgab")

オクターブは>で上げて，<で下げます．
ドレミファソラシドドシラソファミレドは以下で鳴らせます．

	nll> APLAY("CDEFGAB>CC<BAGFEDC")

### シャープ／フラットを使う

シャープ(半音上げる)は#もしくは+，フラット(半音下げる)は-です．

	nll> APLAY("C#")	※ド＃の音を鳴らす
	nll> APLAY("CEG")	※ドミソのメジャー
	nll> APLAY("CE-G")	※ドミソのマイナー

### 音符の長さを指定する

標準では4分音符です．
8部音符などを使いたい場合は，以下のようにします．

	nll> APLAY("C8E8G8")	※8部音符
	nll> APLAY("C16E16G16")	※16部音符
	nll> APLAY("C32E32G32")	※32部音符
	nll> APLAY("C4E4G4")	※4部音符(デフォルト)
	nll> APLAY("C2E2G2")	※2部音符
	nll> APLAY("C1E1G1")	※全音符

.をつけると，長さが1.5倍になります．(いわゆる符点音符)

	nll> APLAY("C4.E4.G4.")	※符点4分音符

### 休符を使う

休符はRです．

	nll> APLAY("CRERG")

長さも指定できます．全休符は以下です．

	nll> APLAY("C1R1E1R1G1")

## 様々な指定

### オクターブ指定

オクターブはOで，数値で指定できます．未指定時のデフォルト値は3です．

	nll> APLAY("O3CDEO4CDE")

### デフォルトの音符の指定

デフォルトの音符はLで指定できます．未指定時のデフォルト値は4で，4分音符です．

	nll> APLAY("L8CDE")	※デフォルトを8分音符にする

### ボリュームの指定

ボリューム(音量)はVで指定できます．1024で標準値(デフォルト)となります．
(上限が1024ということではないので，1024より大きい値も指定できます)

	nll> APLAY("V200CV400CV600CV800CV1000C")	※徐々に音量を上げる

### テンポの指定

テンポ(１分間での4分音符の数)はTで指定できます．デフォルト値は120です．

	nll> APLAY("T60CDET120CDET240CDE")	※徐々に早くする

### 音色の指定

音色は@で指定できます．詳しくは後述します．

	nll> APLAY("T60@0CDE@1CDE@2CDE")	※音色を切替えながら演奏する

## 複数の音を鳴らす

### 和音

()内の音は和音として，同時に発声されます．

	nll> APLAY("(CEG)")	※ドミソの和音

### 音を連続して鳴らす

フラグとしてA_SAVEを指定することで，演奏は保存されます．
例えば以下は，ドレミとファソラとシが連結して演奏されます．

	nll> APLAY("CDE", A_SAVE)	※ドレミを保存(ここでは演奏されない)
	nll> APLAY("FGA", A_SAVE)	※ファソラを保存(ここでは演奏されない)
	nll> APLAY("B")		※ドレミファソラシを演奏

### 複数の演奏をする

フラグにA_NEWを指定することで，新たな演奏となります．
(演奏の保存先が，新たなものに切り替わります)

例えば以下は，ドミソの和音を伴奏しながらドレミファミレド
と演奏します．

	nll> APLAY("CDEFEDC", A_SAVE)	※ドレミファミレドを保存
	nll> APLAY("(CEG)(CEG)(CEG)(CEG)", A_SAVE|A_NEW)	※伴奏を保存
	nll> APLAY("(CEG)(CEG)(CEG)", A_SAVE)	※伴奏を続けて保存
	nll> APLAY()	※演奏を開始

### ファイルに出力する

フラグに続けてファイル名を指定すると，演奏結果はファイルに出力されます．
フォーマットはWAV形式で，標準のサンプリング周波数は44.1kHz，サンプル数は
16ビットです．

	nll> APLAY("CDEFEDC", A_SAVE)	※ドレミファミレドを保存
	nll> APLAY(,,, "sample.wav")	※WAVファイルに保存

## 音色を作るためのチュートリアル

ここまでは，単なる正弦波による単純な音しか出ていません．

様々な変調方式を組み合わせることで，音色を作ることができます．

まずはチュートリアル的に，音色を作ってみましょう

### サンプルの音を鳴らしてみる

まずはサンプルとなる音色が，samples/audioにあります．
これらを実行して，音を聞いてみましょう．

	$ nll -q samples/audio/a_epiano.nll

### 単純な音を鳴らす

正弦波(SIN波)の音を鳴らしてみます．

	nll> ACLEAR()		※音源ユニットの設定を全削除
	nll> OP = AUNIT()	※音源ユニットを作成
	nll> AOSC(OP)		※音源ユニットに正弦波の発信器を設定
	nll> APLAY("CDE")	※ドレミを鳴らす

音色の未設定時と同じように，「ポー」というような音で「ドレミ」が鳴ったと
思います．
これが正弦波による基本の音になります．

上の例ではAUNIT()で音源ユニットを作成しています．
音源ユニットは発信器やエンベロープ処理，フィルタなどを包含する，音の波を扱う
ための単位となります．

ただし音源ユニットを作成しただけでは音は鳴りません．
上の例では音源ユニットの作成後，AOSC()で音源ユニットに対して正弦波の発信器を
設定しています．

### 音量を変えてみる

まずは，音量を変えてみます．

	nll> ACLEAR()
	nll> OP = AUNIT(, 300)	※約30％の音量
	nll> AOSC(OP)
	nll> APLAY("CDE")

### 波形を変えてみる

正弦波以外にも，三角波や矩形波などの様々な波形を利用できます．
矩形波の音を聞いてみましょう．

	nll> ACLEAR()		※残っている設定を全削除
	nll> OP = AUNIT()
	nll> AOSC(OP,,,,A_SQUARE)	※矩形波の発信器を設定
	nll> APLAY("CDE")

今度は「ブー」というような音で「ドレミ」が鳴ったかと思います．
これが矩形波の音です．

### 周波数を変えてみる

音の高さは，周波数によって変わります．
２倍の周波数の音を鳴らしてみましょう．
周波数は，1024分率(1024で１倍となる)で指定します．1024*2とすれば2048で，
２倍の周波数という意味になります．(未指定だと1024で，つまり１倍になります)

	nll> ACLEAR()
	nll> OP = AUNIT()
	nll> AOSC(OP,, 1024*2)	※２倍の周波数
	nll> APLAY("CDE")

高い音で「ドレミ」が鳴ったと思います．
これが２倍の周波数の音です．周波数が２倍だと，１オクターブ上の音になります．

### 複数の音を並べる

複数の周波数を並べて，音を鳴らしてみます．

	nll> ACLEAR()
	nll> AOSC(AUNIT(),, 1024  )	※元の周波数
	nll> AOSC(AUNIT(),, 1024*2)	※２倍の周波数
	nll> AOSC(AUNIT(),, 1024*3)	※３倍の周波数
	nll> APLAY("CDE")

「ポー」という単純な音でなく，楽器っぽい自然な音(？)に近付いたのではないで
しょうか．実際の楽器の音は，このように複数の周波数が並んでいるため，
鳴らす周波数を増やすと楽器っぽい音に近付きます．

### 音量を調整する

それぞれの音量を調整してみましょう．
音量もやはり1024分率で指定します．
(上限が1024ということではないので，1024より大きい値も指定できます)

	nll> ACLEAR()
	nll> AOSC(AUNIT(),1024  , 1024  )	※元の周波数
	nll> AOSC(AUNIT(),1024/2, 1024*2)	※２倍の周波数(音量は1/2)
	nll> AOSC(AUNIT(),1024/3, 1024*3)	※３倍の周波数(音量は1/3)
	nll> APLAY("CDE")

音色がちょっと変わったかと思います．
このようにそれぞれの周波数の音量を調整して，音色を調整することができます．

### 変調をかける

次に「変調」をかけてみます．変調とは，ある波で別の波の周波数に変化を与える
ことだと思ってください．(周波数を「揺らす」感じです)

	nll> ACLEAR()
	nll> OP = AUNIT()
	nll> AOSC(OP)		※元の音
	nll> OP2 = AUNIT(OP)	※出力先をOPにして，元の音に変調をかける
	nll> AOSC(OP2)		※変調するための波
	nll> APLAY("CDE")

これも単純な音でなく，楽器っぽい自然な音に近付いていると思います．

変調をかけることで，様々な周波数の音が発生します．
なのでこれにも，音色を変化させる効果があります．

### エンベロープを調整する

ここまででは「ポー」というような音だけでしたが，「ポン」というような減衰する
音にもできます．

	nll> ACLEAR()
	nll> OP = AUNIT(,,A_ENVFDOUT)	※フェードアウトのエンベロープを設定
	nll> AOSC(OP)
	nll> APLAY("CDE")

「ポー」ではなく「ポン」という音になったと思います．

エンベロープとは，音量の変化のことです．
標準では，音量が一定になります．(このためここまでは「ポー」という音でした)

エンベロープが未設定の状態だと，単に鳴り続けるだけの音になるため，
「ポー」というオルガンっぽい連続した音になります．

上の例ではAUNIT()のフラグにA_ENVFDOUTを指定することで，フェードアウトの
エンベロープを設定していますが，エンベロープは値を設定して作ることもできます．

エンベロープを作ってみます．

	nll> ACLEAR()
	nll> OP = AUNIT()
	nll> AOSC(OP)
	nll> AENVPOINT(OP,,   0,   0)	※最初は音量がゼロ
	nll> AENVPOINT(OP,, 512,1024)	※途中で音量が上がる
	nll> AENVPOINT(OP,,1024,   0)	※最後に音量を下げる
	nll> APLAY("CDE")

音量がだんだん上がり，また下がるような，バイオリンや管楽器のような音になったと
思います．

エンベロープは，横軸は0から始まり1024が音符の終了位置(1024より大きい値も指定
できます)，縦軸は音量のグラフとして指定します．
上の例では，(0,0)，(512,1024)，(1024,0)という５つの点を直線で結んだグラフの
エンベロープとなるので，音量が徐々に上がり，そして下がり…といった音色になり
ます．

周波数の構成はそのままでもエンベロープを変更しただけで，別の楽器のように
聞こえます．実際に音作りをするには，周波数だけでなくエンベロープの調整に
よっても音色の感じかたは大きく変わってきます．
(エンベロープを「それっぽく」するだけでも，それなりに楽器っぽい音にできる，
ということです)
上の例でも，エンベロープを変えるだけで違う楽器のような音にできています．

変調元の波にエンベロープを設定することで，音色に時間的変化を持たせることも
できます．

### 楽器の音を作ってみる

ではここまでの手順で，楽器の音を作ってみます．

ただしここで作るのは基本的な音のみなので，ちょっと物足りないかとは思います．

実際には以下に加えて様々なチューニングや要素追加をすることで，本格的な音に
近付けていきます．

ここで紹介するのはあくまで説明用のサンプルで，音作りのベースとなる音，
基本的な作り方の説明のためのものだと思ってください．

また音色のサンプルがsamples/audioにあります．
こちらにはもう少し「それっぽい」音色がありますので，そちらも参考にしてみて
ください．

### オルガンの音を作ってみる

まずはオルガンの音を作ってみましょう．
オルガンの音は，複数の整数倍の音を並べて，エンベロープは未設定として連続的な
音にします．

	nll> ACLEAR()
	nll> AOSC(AUNIT(), 1024  , 1024)
	nll> AOSC(AUNIT(), 1024/2, 1024*2)
	nll> AOSC(AUNIT(), 1024/3, 1024*4)
	nll> APLAY("CDE")

### ギターの音を作ってみる

ギターは弦楽器なので，弦の振動によって１倍，２倍，３倍などの複数の周波数の音が
発生します．

ただし周波数が上がるにつれて音量は下がると思われるので，以下のような感じに
なるかと思います．音量は徐々に減衰するので，フェードアウトのエンベロープで
いいかと思います．

	nll> ACLEAR()
	nll> AOSC(AUNIT(,,A_ENVFDOUT),1024  , 1024  )
	nll> AOSC(AUNIT(,,A_ENVFDOUT),1024/2, 1024*2)
	nll> AOSC(AUNIT(,,A_ENVFDOUT),1024/3, 1024*3)
	nll> APLAY("CDE")

### バイオリン？のような音を作ってみる

バイオリンも弦楽器ですが，複雑な周波数構成にすることでひっかくようなノイズっ
ぽい音にするために，変調を多めにかけてみます．

ゆっくりと音量が上がるため，エンベロープは立上りが遅くなるようにすることで，
バイオリンっぽい音色に近づけられます．
ただし高音は早めに減衰するという定石があるので，変調具合を早めに少なくして
高い周波数を徐々に減らすように，変調元にもエンベロープを設定しています．

	nll> ACLEAR()
	nll> OP  = AUNIT()
	nll> OP2 = AUNIT(OP)
	nll> AOSC(OP)
	nll> AOSC(OP2, 1024*3)		※変調を多めにかける
	nll> AENVPOINT(OP ,,   0,   0)
	nll> AENVPOINT(OP ,, 256,1024)
	nll> AENVPOINT(OP ,, 512,1024)
	nll> AENVPOINT(OP ,,1024,   0)
	nll> AENVPOINT(OP2,,   0,   0)
	nll> AENVPOINT(OP2,, 128,1024)
	nll> AENVPOINT(OP2,, 256,1024)
	nll> AENVPOINT(OP2,, 512,   0)
	nll> APLAY("CDE")

…とは思ったのですが，あまりバイオリンっぽい音とは言えないですね．
何かの管楽器？のような音になっています．

実際にはこれをベースにして，ここからパラメータ調整や要素の追加などの
チューニングをしていって，目的の音に近づける(もしくは偶然的に新たな音を「発見」
できたりすることが，面白いところです)ということになるかと思います．

### 基本構成

ここまでのことから音色を作るための基本構成を考えると，まずは以下のような構成が
標準的になるかと思います．

	nll> ACLEAR()
	nll> OP1 = AUNIT()		※元の音
	nll> OP2 = AUNIT()		※元の音
	nll> OP3 = AUNIT()		※元の音
	nll> OP4 = AUNIT()		※元の音
	nll> AOSC(OP1, 1024, 1024*1)	※１倍の周波数の音
	nll> AOSC(OP2, 1024, 1024*2)	※２倍の周波数の音
	nll> AOSC(OP3, 1024, 1024*3)	※３倍の周波数の音
	nll> AOSC(OP4, 1024, 1024*4)	※４倍の周波数の音
	nll> OP1D = AUNIT(OP1)		※出力先を指定して変調する
	nll> OP2D = AUNIT(OP2)		※出力先を指定して変調する
	nll> OP3D = AUNIT(OP3)		※出力先を指定して変調する
	nll> OP4D = AUNIT(OP4)		※出力先を指定して変調する
	nll> AOSC(OP1D, 1024, 1024*1)	※１倍の音を変調
	nll> AOSC(OP2D, 1024, 1024*2)	※２倍の音を変調
	nll> AOSC(OP3D, 1024, 1024*3)	※３倍の音を変調
	nll> AOSC(OP4D, 1024, 1024*4)	※４倍の音を変調
	nll> APLAY("CDE")

上の例は実際に聞いてみると何かブザーでも鳴っているかのような音になりますが，
ここからパラメータ(上の例で1024が指定されている部分)をいろいろ変化させて，
様々な音色の音を聞いてみるといいかと思います．

## 様々な音色を作る

実際に様々な音色を作るための詳細を説明します．

### 音源ユニットの作成

音源ユニットはAUNIT()で作成できます．

AUNIT()の引数は，以下になっています．
数値は基本として1024分率で指定します．
(「1024より大きい値」も指定できます．2048とすれば倍の値ということになります)

	AUNIT(OUTPUT,AMP,FLAGS,UNITSET)
	OUTPUT	出力先．A_OUTPUTでスピーカーに出力される．A_NOOUTで出力無し
	AMP	出力の音量．1024分率で指定する(未設定時は1024)
	FLAGS	フラグ(未設定時は位相変調・標準のエンベロープ)
	UNITSET	音源ユニットのセットの指定(後述)

フラグには以下を|で接続して指定できます．

	A_ENVFDOUT	フェードアウトのエンベロープ
	A_ENVFDIN	フェードインのエンベロープ
	A_ENVCLEAR	空のエンベロープ(減衰せず，ただ鳴るだけの音)
	A_ENVFIXED	固定長のエンベロープ(4分音符を基準とする．デフォルトは音符の長さを基準とする)
	A_FILCLEAR	空のフィルタ
	A_FILFIXED	固定長のフィルタ(4分音符を基準とする．デフォルトは音符の長さを基準とする)

### 発信器の設定

発信器の設定はAOSC()で行います．

AOSC()の引数は，以下になっています．
数値が基本として1024分率で指定するのは，AUNIT()と同様です．

	AOSC(INDEX,AMP,FREQ,PHASE,TYPE,MOD,FLAGS,UNITSET)
	INDEX	設定する発信器(AUNIT()の戻り値で指定)
	AMP	発信器の音量．1024分率で指定する(未設定時は1024)
	FREQ	発信器の周波数．1024分率で指定する(未設定時は1024)
	PHASE	発信器の位相．1024分率で指定する(未設定時は0)
	TYPE	波形(未設定時は正弦波)
	MOD	変調方式(未設定時は位相変調)
	FLAGS	フラグ
	UNITSET	音源ユニットのセットの指定(後述)

パラメータの指定は，100分率や1000分率でなく「1024分率」(つまり1024で100％)と
しています．
この理由は，値を細かく指定できるようにしたい(100分率では不十分)のと，音を扱う
ときは周波数や振幅や長さなどを半分にしていけることが重要なので，何度でも２で
割れる値を基準にしたほうが扱いやすいという判断のためです．

波形は以下で指定します．

	A_SIN		正弦波(サイン波)
	A_TRIANGLE | n	三角波(n/1024)
	A_SQUARE	矩形波
	A_PULSE | n	パルス波(n/1024)
	A_SAWUP | n	ノコギリ波(徐々に増加)(n/1024)
	A_SAWDOWN | n	ノコギリ波(徐々に減少)(n/1024)
	A_RANDOM | n	乱数(サンプルごとに乱数で変化，nはゼロ付近の集中度(未指定で白色雑音)
	A_NOISE | n	ノイズ(n/1024周期ごとに乱数で変化)
	A_ZERO		ゼロ
	A_HIGH | amp	一定値(ampが未指定だと最大値(1024))
	A_INPULSE | amp	インパルス(最初のみampになる．ampが未指定だと最大値(1024)．フィルタの応答確認用)
	A_EXTIN | op	外部入力(後述)
	A_DATA | index	ファイル入力(後述)

変調方式には，以下が指定できます．実験的な変調方式も入れてみてあります．

	A_PHASE	位相変調
	A_FREQ	周波数変調
	A_NULL	入力をそのまま出力する(遅延を加えて位相をそろえるときなどに利用)
	A_REV	入力の符号を反転して出力とする(発信器の値を基準とする)
	A_ABS	入力の絶対値(発信器の値を基準とする)
	A_INV	入力を発信器の値とマイナス発信器の値を基準として反転
		(発信器にA_HIGHを指定することで，特定の値を基準にして反転できる)
	A_SIGN	入力が正の値で発信器の値，負の値でマイナス発信器の値，ゼロでゼロとなる
		(発信器にA_HIGHを指定することで，正負に応じて特定の値にできる)
	A_CLIP	入力をマイナス発信器の値〜発信器の値にクリッピングする
		(発信器にA_HIGHを指定することで，特定の値でクリッピングできる)
	A_ADD	入力と発信器の出力を加算する
	A_SUB	入力から発信器の出力を減算する
	A_MUL	入力と発信器の出力をかけ算する(オーバーフローに注意)
	A_AND	入力と発信器の出力をビットANDする
	A_OR	入力と発信器の出力をビットORする
	A_XOR	入力と発信器の出力をビットXORする
	A_AVE	入力と発信器の出力の平均値
	A_PER	入力と発信器の出力をかけ算し，最大値で割る(オーバーフローしにくい)
	A_MIN	入力と発信器の出力で，小さいほうの値
	A_MAX	入力と発信器の出力で，大きいほうの値
	A_LT	入力＜発信器の出力のときに最大値，そうでなければマイナス最大値
	A_GT	入力＞発信器の出力のときに最大値，そうでなければマイナス最大値

フラグには以下を|で接続して指定できます．

	A_FIXED		周波数を1024分率でなく固定値として設定

### 複数の音源ユニットを使う

出力先を同じにして音源ユニットを複数設定すると，複数の音源ユニットが並列に
動作し，それぞれの出力は加算されます．

周波数は1024分率で指定されるため，例えば倍音(１オクターブ上の音)を出した
ければ，周波数に2048を指定します．512とすれば１オクターブ下の音になります．

例えば以下のように正弦波の倍音を並べれば，オルガンのような音を出すことが
できます．

	nll> ACLEAR()
	nll> AOSC(AUNIT(),, 1024)	※基準音
	nll> AOSC(AUNIT(),, 1024*2)	※倍音
	nll> AOSC(AUNIT(),, 1024*3)	※3倍音
	nll> AOSC(AUNIT(),, 1024*4)	※4倍音
	nll> APLAY("CDE")

### 変調をする

発信器の出力先に別の発信器を指定することで，出力はその発信器に入力され，
変調をかけることができます．

	nll> ACLEAR()
	nll> OP = AUNIT()
	nll> AOSC(OP)
	nll> AOSC(AUNIT(OP))		※OPを正弦波で変調する
	nll> APLAY("CDE")

変調の度合は，発信器の出力(1024分率で指定)で変化させられます．

	nll> ACLEAR()
	nll> OP = AUNIT()
	nll> AOSC(OP)
	nll> AOSC(AUNIT(OP, 512))	※出力50％(これが変調度合になる)
	nll> APLAY("CDE")

デフォルトでは位相変調です．変調方式はAOSC()のMODで指定します．
以下は周波数変調をする例です．変調するための発信器の出力が変調度合となりますが
1024だと大きすぎるため，以下の例では100にしてみました．

	nll> ACLEAR()
	nll> OP = AUNIT()
	nll> AOSC(OP,,,,,A_FREQ)	※周波数変調で変調される
	nll> AOSC(AUNIT(OP, 100))	※変調度合を100とする
	nll> APLAY("CDE")

発信器を多段に接続することもできます．

	nll> ACLEAR()
	nll> OP1 = AUNIT(); AOSC(OP1)
	nll> OP2 = AUNIT(OP1); AOSC(OP2)	※変調された波で変調
	nll> AOSC(AUNIT(OP2),, 2048)		※OP2を倍音の周波数で変調
	nll> APLAY("CDE")

変調した波を複数同時に発声させることもできます．
以下は基準音を基準音の周波数で，倍音を倍音の周波数で別々に変調し，それらを
同時発声させる例です．

	nll> ACLEAR()
	nll> OP1 = AUNIT(); AOSC(OP1)		※基準音
	nll> AOSC(AUNIT(OP1))			※基準音を基準音で変調
	nll> OP2 = AUNIT(); AOSC(OP2,, 2048)	※倍音
	nll> AOSC(AUNIT(OP2),, 2048)		※倍音を倍音で変調
	nll> APLAY("CDE")

### 複数の発信器から入力する

発信器の入力には，複数の発信器の出力を接続できます．

	nll> ACLEAR()
	nll> OP = AUNIT(); AOSC(OP)	※基準音
	nll> AOSC(AUNIT(OP))		※基準音で変調
	nll> AOSC(AUNIT(OP),512,2048)	※倍音でも変調(ただし50％)
	nll> APLAY("CDE")

### 出力を複数に分ける

AADDOUT()を利用すると，発信器に出力先を追加することができます．
(出力の度合は1024分率で指定します)
これにより，ひとつの発信器の出力を枝分かれさせて，複数の発信器の入力に加える
ことができます．出力先をA_OUTPUT(もしくは未指定)にすると，スピーカーに出力
されます．

	nll> ACLEAR()
	nll> OP1 = AUNIT(); AOSC(OP1)		※基準音
	nll> OP2 = AUNIT(); AOSC(OP2,, 2048)	※倍音
	nll> OP3 = AUNIT(OP1); AOSC(OP3)	※基準音を変調
	nll> AADDOUT(OP3, OP2, 512)	※倍音も変調(ただし変調度合は50％)
	nll> APLAY("CDE")

AADDOUT()の引数は，以下のようになっています．

	AADDOUT(INDEX,OUTPUT,AMP,FLAGS,UNITSET)
	INDEX	設定する発信器(AOSC()の戻り値で指定)
	OUTPUT	出力先の発信器(AOSC()の戻り値で指定．A_OUTPUTでスピーカーに出力)
	AMP	出力の音量
	FLAGS	現状では未使用(将来的な予約)
	UNITSET	音源ユニットのセットの指定(後述)

### フィードバックをする

AADDOUT()を利用すれば，ある発信器の出力をその発信器の入力に与える
(いわゆるフィードバック)ことができます．
以下は出力の50％を入力にフィードバックする例です．

	nll> ACLEAR()
	nll> OP = AUNIT(); AOSC(OP)
	nll> AADDOUT(OP, OP, 512)	※出力を再度入力する(50％を入力)
	nll> APLAY("CDE")

複数の発信器をまたいでのフィードバックもできます．

	nll> ACLEAR()
	nll> OP1 = AUNIT(); AOSC(OP1)
	nll> OP2 = AUNIT(OP1); AOSC(OP2)	※O2でO1を変調
	nll> AADDOUT(OP1, OP2, 512)		※O1の出力をO2にフィードバック
	nll> APLAY("CDE")

### エンベロープ

音源ユニットには時間推移での出力変化(いわゆるエンベロープ)を設定できます．
以下は徐々に減衰する例です．

	nll> ACLEAR()
	nll> OP = AUNIT(); AOSC(OP)
	nll> AENVPOINT(OP,, 0, 1024)	※最初に最大出力になる
	nll> AENVPOINT(OP,, 1024, 0)	※最後に出力ゼロになるよう減衰していく
	nll> APLAY("CDE")

AENVPOINT()の引数は，以下のようになっています．

	AENVPOINT(INDEX,N,STEP,AMP,FLAGS,UNITSET)
	INDEX	設定する発信器(AOSC()の戻り値で指定)
	N	設定するエンベロープの点の番号(未指定で，先頭から順に設定)
	STEP	エンベロープの点の横軸の位置
	AMP	エンベロープの点の縦軸の位置
	FLAGS	A_ENVCLEARでエンベロープを全クリアしてから設定する
	UNITSET	音源ユニットのセットの指定(後述)

出力変化は，(0,0)〜(1024,1024)のグラフとして設定します．横軸は時間変化で
1024が音符の長さ，縦軸は出力(1024分率)です．

以下のようにすれば，徐々に大きくなり(いわゆるアタック)，その後持続し
(いわゆるサスティン)，最後に音が緩やかに切れる(いわゆるリリース)ような
出力変化を作れます．

	nll> ACLEAR()
	nll> OP = AUNIT(); AOSC(OP)
	nll> AENVPOINT(OP,, 0, 0)	※最初は音量ゼロ
	nll> AENVPOINT(OP,, 200, 1024)	※少しずつ最大出力(1024)になる
	nll> AENVPOINT(OP,, 400, 300)	※最大出力から低い出力(300)に変化
	nll> AENVPOINT(OP,, 800, 300)	※そのまま出力(300)を維持
	nll> AENVPOINT(OP,, 1024, 0)	※最後に出力ゼロになるよう減衰していく
	nll> APLAY("CDE")

以下のようにA_ENVFIXEDを指定すると，音符の長さを基準にせずに，4分音符を基準
(1024が4分音符の長さ)とした固定長のエンベロープになります．
(1024以上の値を指定することで，4分音符以上の長さのエンベロープを作成できます)

	nll> ACLEAR()
	nll> OP = AUNIT(,,A_ENVFIXED); AOSC(OP)
	nll> AENVPOINT(OP,, 0, 1024)
	nll> AENVPOINT(OP,, 1024*4, 0)	※全音符の長さで減衰していく
	nll> APLAY("CDE")	※全音符の長さで減衰するので，音が途中で切れる
	nll> APLAY("C1D1E1")

エンベロープはAENVCOPY()でコピーできます．

	nll> ACLEAR()
	nll> OP1 = AUNIT(); AOSC(OP1)
	nll> OP2 = AUNIT(); AOSC(OP2)
	nll> AENVPOINT(OP,, 0, 1024)
	nll> AENVPOINT(OP,, 1024, 0)
	nll> AENVCOPY(OP2, OP1)

AENVCOPY()の引数は，以下のようになっています．

	AENVCOPY(INDEX,SOURCE,FLAGS,UNITSET)
	INDEX	コピー先の発信器(AOSC()の戻り値で指定)
	SOURCE	コピー元の発信器(AOSC()の戻り値で指定)
	FLAGS	現状では未使用(将来的な予約)
	UNITSET	音源ユニットのセットの指定(後述)

以下のようにエンベロープの点の番号を指定することで，設定したエンベロープを修正
することができます．(点の番号が未指定だと，未設定の最後の位置を指定したこと
(つまり，最後の位置に設定する)になり，結果として始点から順に設定されていくこと
になります)
コピーしたエンベロープを修正することで，エンベロープを細かく修正して流用する
ことができます．

	nll> ACLEAR()
	nll> OP = AUNIT(); AOSC(OP)
	nll> AENVPOINT(OP,, 0, 1024)	※(0,1024)の点(0番目の点になる)
	nll> AENVPOINT(OP,, 1024, 0)	※(1024,0)の点(1番目の点になる)
	nll> AENVPOINT(OP, 0, 0, 512)	※0番目の点を(0,1024)→(0,512)に修正
	nll> AENVPOINT(OP, 1, 512, 0)	※1番目の点を(1024,0)→(512,0)に修正

### 固定周波数

フラグにA_FIXEDを指定すると，(MMLで指定したドレミの音階に関わらず)固定の
周波数で発信します．

これを利用して，ビブラートのような効果を出せます．
例えば以下は，10Hzで位相を変化させる，ビブラートの例です．

	nll> ACLEAR()
	nll> OP = AUNIT(); AOSC(OP)		※10Hzで位相が変化
	nll> AOSC(AUNIT(OP),,10,,,,A_FIXED)	※10Hzを発信
	nll> APLAY("CDE")

以下は，正弦波を4Hzという低い周波数で音量を変化させて音を震わせる
(いわゆるトレモロ)例です．

	nll> ACLEAR()
	nll> OP = AUNIT(); AOSC(OP,,,,,A_PER)	※音量を変化
	nll> AOSC(AUNIT(OP),,4,,,,A_FIXED)	※4Hzを発信
	nll> APLAY("CDE")

### 外部入力

波形にA_EXTINを指定することで，ある発信器の出力を，別の発信器の発信にすることが
できます．

これを利用すると，２つの発信器の出力に対して演算を行うことができます．

	nll> ACLEAR()
	nll> OP1 = AUNIT(A_NOOUT); AOSC(OP1,512,,,A_SIN)	※正弦波を出力
	nll> OP2 = AUNIT(); AOSC(OP2,,,,A_EXTIN|OP1,A_ADD)	※正弦波と三角波を加算
	nll> AOSC(AUNIT(OP2),512,,,A_TRIANGLE)		※三角波を出力
	nll> APLAY("CDE")

A_EXTINによる外部入力を用いれば，加工された出力に対してさらに演算を行うような
ことができます．

### ファイル入力

波形にA_DATAを指定することで，ファイルから入力したデータを発信器の出力にすることが
できます．

	nll> ACLEAR()
	nll> (INDEX,LENGTH) = AOPEN("sample.wav")
	nll> OP = AUNIT(); AOSC(OP,,,,A_DATA|INDEX)	※ファイルのデータを出力
	nll> APLAY("C1D1E1F1G1")			※O3Aでそのままの周波数で再生

これを利用して，WAVファイルの音声に対して変調をかけたりすることができます．

## 音色セット

### 複数の音色の登録

音色は発信器の組み合わせパターンで決まりますが，この組み合わせは複数セットを
定義できます．

以下の関数では，UNITSETに組み合わせのセットの番号を指定できます．
(デフォルトの番号は0)
これを切替えることで，複数の音色の設定や利用ができます．

	ACLEAR(UNITSET)
	INDEX = AUNIT(OUTPUT,AMP,FLAGS,UNITSET)
	AOSC(INDEX,AMP,FREQ,PHASE,TYPE,MOD,FLAGS,UNITSET)
	AADDOUT(INDEX,OUTPUT,AMP,FLAGS,UNITSET)
	AENVPOINT(INDEX,N,STEP,AMP,FLAGS,UNITSET)
	AENVCOPY(INDEX,SOURCE,FLAGS,UNITSET)
	AFILPOINT(INDEX,TYPE,N,AMP,FLAGS,UNITSET)
	AFILCOPY(INDEX,SOURCE,FLAGS,UNITSET)
	APLAY("CDEFGAB",FLAGS,UNITSET,FILENAME)

なおACLEAR(),APLAY()の引数は，以下のようになっています．

	ACLEAR(UNITSET)
	UNITSET	音源ユニットのセットの指定(未指定だとすべてクリア)

	APLAY("CDEFGAB",FLAGS,UNITSET,FILENAME)
	第１引数	演奏内容のMML
	FLAGS		フラグ(A_NEWで新たな演奏，A_SAVEで演奏内容の保存，A_REMAINで演奏後に演奏内容を削除しない，A_STEREOでステレオ演奏(デフォルトはモノラル)，A_TEXTでテキスト形式でファイル出力)
	UNITSET		音源ユニットのセットの指定
	FILENAME	指定時にはファイルに出力(標準ではWAVフォーマット．FLAGSにA_TEXTを指定するとテキスト形式)

例えば以下は，正弦波を音色の0番に，三角波を音色の1番に登録する例です．

	nll> ACLEAR()
	nll> AOSC(AUNIT())		※音色0(正弦波)
	nll> OP = AUNIT(,,,1)		※音色1(三角波)
	nll> AOSC(OP,,,,A_TRIANGLE,,,1)	※音色1に三角波を設定
	nll> APLAY("CDE")		※音色0でドレミ
	nll> APLAY("CDE",,1)		※音色1でドレミ

これは以下のようにA_SAVEによって演奏を保存し，同時に再生開始することで，
同時演奏させることができます．

	nll> APLAY("CDE", A_SAVE)	※音色0での演奏を保存
	nll> APLAY(">CDE<", A_SAVE|A_NEW, 1)	※音色1での演奏を保存
	nll> APLAY()	※演奏開始

### 複数の音色での演奏

これにより，複数の楽器で演奏しているような表現もできます．

以下は音色0で主旋律，音色1で伴奏として，２つの楽器を同時演奏する例です．
(演奏はA_SAVEで保存され，A_NEWで保存先が新たなものに切り替わる点に注意して
ください)

	nll> ACLEAR()
	nll> AOSC(AUNIT())
	nll> OP = AUNIT(,,,1)
	nll> AOSC(OP,,,,A_TRIANGLE,,,1)
	nll> APLAY("CDEFEDC", A_SAVE)		※音色0でドレミファミレド
	nll> APLAY("(CEG)(CEG)(CEG)(CEG)", A_SAVE|A_NEW, 1)	※音色1で伴奏
	nll> APLAY("(CEG)(CEG)(CEG)", A_SAVE, 1)	※伴奏の続き
	nll> APLAY()	※演奏開始

### 音色の変更

MMLでは@でUNITSETのセット番号を指定できます．
これにより，MML中で音色を変更できます．

	nll> APLAY("@0CDEFEDC@1CDEFEDC")	※音色0の後に音色1でドレミファミレド

これを利用すると，打鍵が強い場合の音色と弱い場合の音色を２種類作成しておいて，
音色を切替えながら演奏することで，打鍵の強弱を表現するようなことができます．

### 音色のデフォルト値

AUNITSET()で，音色のデフォルト値(未指定時の値)を設定できます．

	AUNITSET(UNITSET)
	UNITSET	音源ユニットのセットの指定(未指定だとゼロ)

## フィルタの設定

出力を遅延バッファに保存して，係数をかけて出力に加算したりフィードバックしたり
することができます．つまりディジタルフィルタを設定することができます．

これを利用して，エコーなどのエフェクトを加えたり，FIRフィルタ／IIRフィルタを
設定することができます．

### エコーの設定

フィルタはAFILPOINT()で設定します．
AFILPOINT()の引数は，以下のようになっています．

	AFILPOINT(INDEX,TYPE,N,AMP,FLAGS,UNITSET)
	INDEX	設定する発信器(AOSC()の戻り値で指定)
	TYPE	フィルタのタイプ(A_FILFW:FIRフィルタ，A_FILBW:IIRフィルタ)
	N	設定するフィルタの段の番号(未指定で，先頭から順に設定)
	AMP	フィルタの段の係数(1024分率)
	FLAGS	A_FILCLEARでフィルタを全クリアしてから設定する
	UNITSET	音源ユニットのセットの指定

フラグには以下を|で接続して指定できます．

	A_FILCLEAR	フィルタを全クリアしてから設定する
	A_FILINC	徐々に有効になる
	A_FILDEC	徐々に無効になる

例えば以下のようにすれば，一定の遅延の後に再度出力することで，エコーをかける
ことができます．(以下の例ではフィルタの段数が少ないため，実際にわかるような
エコーにはなりません．後述する発信器の直列接続で，フィルタの段数を増やすことが
できます)

	nll> ACLEAR()
	nll> OP = AUNIT(); AOSC(OP)
	nll> AFILPOINT(OP, A_FILFW,,1024)	※0段目の係数
	nll> AFILPOINT(OP, A_FILFW,15,512)	※15段目の係数

### FIRフィルタの設定

FIRフィルタで，0段目の係数を1.0, 1段目の係数を0.5，2段目の係数を0.25と
するならば，以下のように設定します．

	nll> ACLEAR()
	nll> OP = AUNIT(); AOSC(OP)
	nll> AFILPOINT(OP, A_FILFW,,1024)	※0段目の係数
	nll> AFILPOINT(OP, A_FILFW,, 512)	※1段目の係数
	nll> AFILPOINT(OP, A_FILFW,, 256)	※2段目の係数

### フィルタを徐々に有効とする．

以下のようにフラグにA_FILINCを設定すると，係数が徐々に有効になります．
(最初に無効の状態から，徐々に有効となっていきます)
これはLPF(ローパスフィルタ)などを徐々に効かせたい／無効化したいときなどに利用
できます．(A_FILDECで，最初に有効の状態から，徐々に無効とすることもできます)

	nll> ACLEAR()
	nll> OP = AUNIT(); AOSC(OP)
	nll> AFILPOINT(OP, A_FILFW,,1024, A_FILINC)	※係数が徐々に有効となる
	nll> AFILPOINT(OP, A_FILFW,, 512, A_FILINC)	※係数が徐々に有効となる
	nll> AFILPOINT(OP, A_FILFW,, 256, A_FILINC)	※係数が徐々に有効となる

デフォルトでは音符の長さで完全に有効となりますが，AOSC()でA_FILFIXEDを指定
すると4分音符の長さで完全に有効になります．

	nll> ACLEAR()
	nll> OP = AUNIT(,,,A_FILFIXED); AOSC(OP)	※4分音符の長さで有効になる
	nll> AFILPOINT(OP, A_FILFW,,1024, A_FILINC)
	nll> AFILPOINT(OP, A_FILFW,, 512, A_FILINC)
	nll> AFILPOINT(OP, A_FILFW,, 256, A_FILINC)

### IIRフィルタの設定

AFILPOINT()のTYPEにA_FILBWを指定することで，フィードバック型のフィルタの係数を
設定できます．A_FILFWと組み合わせることで，IIRフィルタを設定できます．

例えばIIRフィルタで，フィードバック側の1段目の係数を0.5，2段目の係数を0.25と
するならば，以下のように設定します．
(IIRフィルタでは，フィードバックの0段目は通常は無いので，未指定となります)

	nll> ACLEAR()
	nll> OP = AUNIT(); AOSC(OP)
	nll> AFILPOINT(OP, A_FILFW,,1024)
	nll> AFILPOINT(OP, A_FILFW,, 512)
	nll> AFILPOINT(OP, A_FILFW,, 256)
	nll> AFILPOINT(OP, A_FILBW, 1, 512)	※フィードバック側の1段目の係数
	nll> AFILPOINT(OP, A_FILBW, 2, 256)	※フィードバック側の2段目の係数

IIRフィルタは一般にFIRフィルタよりも少ない段数で実現できます．

### フィルタのコピー

フィルタの設定は，AFILCOPY()でコピーできます．
AFILCOPY()の引数は，以下のようになっています．

	AFILCOPY(INDEX,SOURCE,FLAGS,UNITSET)
	INDEX	コピー先の発信器(AOSC()の戻り値で指定)
	SOURCE	コピー元の発信器(AOSC()の戻り値で指定)
	FLAGS	現状では未使用(将来的な予約)
	UNITSET	音源ユニットのセットの指定

### フィルタの段数を増やす

標準ではフィルタの段数は16段までです．(AFILPOINT()のNに指定できる値は0〜15です)
発信器を直列に接続し，出力を次の入力に加えることで，フィルタの段数を増やすよう
なことができます．

以下はこれを利用して，エコーを深くした例です．
(ただし発信器の数が多いためリアルタイム再生は厳しく，以下の例ではWAVファイルに
出力しています)

	1 ACLEAR()
	2 OP = AUNIT(A_OUTPUT,,A_ENVFIXED)
	3 OUTOP = OP
	4 LOOP I, 500
	5 OP = AUNIT(OP,,A_ENVFIXED)
	6 AFILPOINT(OP, A_FILFW, 0, 0)
	7 AFILPOINT(OP, A_FILFW, 15, 1024)
	8 LOOPEND
	9 AADDOUT(OUTOP, OP, 512)
	10 OP = AUNIT(OUTOP,,A_ENVFIXED)
	11 AOSC(OP)
	12 AENVPOINT(OP,, 0, 1024)
	13 AENVPOINT(OP,, 180, 0)
	14 AFILPOINT(OP, A_FILFW, 0, 1024)
	15 APLAY("T60CDEC1",,, "echo.wav")

ここまで
