原文 http://www.reaper.fm/sdk/js/basiccode.php
基本的なコードリファレンス
JSFXのコアになるのはEEL2と呼ばれる単純なプログラミング言語で書かれたコードで、C言語に似ています。コードは一つまたは複数のコードセクションに書かれます。この言語のいくつかの基本的な機能は以下のとおりです:
- 変数は宣言される必要がありません。デフォルトでエフェクト内でグローバルにアクセスできます。そして全ては倍精度浮動小数点数です。
- 加算(+)、減算(-)、乗算(*)、除算(/)指数(^)の基本的な演算ができます。
- 和集合(|)、積集合(&)、排他的論理和(~)、左シフト(<<)、符号拡張右シフト(>>)のビット演算ができます。これらは計算時に整数に変換されます。
- "(" と ")" のかっこは計算順を指定したり、関数の引数を指定したり、複数のステートメントを一つのステートメントとしてまとめたりするのに使われます。
- セミコロン
;
はステートメントを分けるために使われます。 - 仮想ローカル変数空間は約800万ワード存在し、これは "[" と "]"のかっこでアクセスできます。
- 共有グローバル変数空間は約100万ワード存在し、
gmem[]
でアクセスできます。これは全てのJSFXプラグインインスタンスで共有されます。 - 名前付き共有グローバル変数は"_global."プリフィックスを付けることでアクセスできます。これは全てのJSFXプラグインインスタンスで共有されます。
- ユーザー定義関数はプライベート変数、パラメーターを定義することができ、名前空間付きインスタンス変数にアクセスすることも可能です。
- 数値は通常10進数ですが、
$x
でプリフィックスすると16進数になります。($x90
,$xDEADBEEF
, 等). -- (REAPER v4.25以上ではC言語風の0x90
のような指定も可能です) - ASCII文字列は
$'c'
で指定可能です。 - 整数のビットマスクを指定したい場合は
$~X
を使います。たとえば$~7
は127、$~8
は255、$~16
は65535を表します。-- REAPER 4.25以上 - コメントはこれらを使います:
// 行末までコメント
/* 複数行にまたがることのできるコメント */
演算子リファレンス
最も高い優先度から低い優先度の順に並べます。(しかしかっこを使う場合はこの限りではありません!):
[ ]
z=x[y];
x[y]=z;
かっこはエフェクト内のローカルメモリのインデックスとして使われます。エフェクト内には約800万(8,388,608)スロットのメモリがあり、固定のオフセット(i.e. 16811[0])もしくは変数名(myBuffer[5])でアクセスできます。かっこの左側にある値とかっこの中にある値の和がメモリのインデックスになります。かっこの中の値が省略された場合は、かっこの左側にある値が使われます。
z=gmem[y];
gmem[y]=z;
gmem
がかっこの左側に指定された場合、グローバル共有メモリが使用されます。これは約100万(1,048,576)スロットのメモリがあり、全てのJSFXエフェクトのインスタンスで共有されます。
プラグインは次のようにすることもできます。(コードセクションの前で):
options:gmem=someUniquelyNamedSpace
これはgmem[]
より大きな共有バッファで、options:gmem=<the same name>
を使うことで他のプラグインからアクセスできるようになります。もしいくつかのプラグインが同時に動作する場合、共有メモリを使うことで他のプラグインを気にすることなくコミュニケーションすることができます。このオプションはgmem[]
の大きさを800万エントリーに拡大させます。(デフォルトは約100万) -- REAPER 4.6以上
!value
論理的NOT演算の結果を返します。(もし元の値が0.0なら、1.0を返します。そうでなければ0.0を返します。)
-value
符号反転させた値を返します。(-1 * value)
+value
変更されていない値を返します。
a ^ b
a
のb
乗の結果を返します。pow(a,b)
関数を使うのと同じです。
numerator % denominator
整数として除算を行い、その余りを返します。
value << shift_amt
双方の値を32ビット整数に変換し、2番目のパラメーターの分だけ左方向へのビットシフト演算をします。32より大きな数や0より小さい数でビットシフトすると不定の結果を返します。-- REAPER 4.111以上
value >> shift_amt
双方の値を32ビット整数に変換し、2番目のパラメーターの分だけ右方向へのビットシフト演算をします。符号ビットは元の値のものを引き継ぎます(y
が負の数なら、結果は正にならない)。32より大きな数や0より小さい数でビットシフトすると不定の結果を返します。-- REAPER 4.111以上
value / divisor
二つの値の除算の結果を返します。
value * another_value
二つの値の乗算の結果を返します。
value - another_value
二つの値の差を返します。
value + another_value
二つの値の和を返します。
a | b -- 二つの値を32ビット整数に変換し、ビットごとの論理和を計算して返します。
a & b -- 二つの値を32ビット整数に変換し、ビットごとの論理積を計算して返します。
a ~ b -- 二つの値を32ビット整数に変換し、ビットごとの排他的論理和を計算して返します。-- REAPER 4.25以上
value1 == value2 -- 二つの値を比べて、差が0.00001未満なら1を、そうでなければ0を返します。
value1 === value2 -- 二つの値を比べて、確実に等しいなら1を、そうでなければ0を返します。-- REAPER 4.53以上
value1 != value2 -- 二つの値を比べて、差が0.00001未満なら0を、そうでなければ1を返します。
value1 !== value2 -- 二つの値を比べて、確実に等しいなら0を、そうでなければ1を返します。-- REAPER 4.53以上
value1 < value2 -- 二つの値を比べて、最初のパラメーターが次のパラメーターより小さいなら1を返します。
value1 > value2 -- 二つの値を比べて、最初のパラメーターが次のパラメーターより大きいなら1を返します。
value1 <= value2 -- 二つの値を比べて、最初のパラメーターが次のパラメーター以下なら1を返します。
value1 >= value2 -- 二つの値を比べて、最初のパラメーターが次のパラメーター以上なら1を返します。
y || z -- 二つの値の論理和を返します。もしy
が0でないなら、z
は評価されません。
y && z -- 二つの値の論理積を返します。もしy
が0なら、z
は評価されません。
y ? z
y
が0でなければ、z
を評価します。C言語のif (y) { z }
のようなものです。
y ? z : x
y
が0でなければz
を評価し、そうでなければx
を評価します。C言語のif (y) { z } else { x }
のようなものです。
z
,x
にあたる部分はかっこを使うことで複数のステートメントを含むことができます。
x % 5 ? (
f += 1;
x *= 1.5;
) : (
f = max(3, f);
x = 0;
);
y = z
z
の値をy
に代入します。z
は変数か、式です。
y *= z
二つの乗算を行い、結果をy
に格納します。
y /= divisor
除算を行い、結果をy
に格納します。
y %= divisor
整数として除算を行い、余りをy
に格納します。
a ^= b
a
のb
乗を計算して、結果をa
に格納します。
y += z
二つの結果を加算して、結果をy
に格納します。
y -= z
y-z
の減算を行い、結果をy
に格納します。
y |= z
双方を整数に変換して、ビットごとの論理和を計算して、結果をy
に格納します。
y &= z
双方を整数に変換して、ビットごとの論理積を計算して、結果をy
に格納します。
y ~= z
双方を整数に変換して、ビットごとの排他的論理和を計算して、結果をy
に格納します。-- REAPER 4.25以上
特にC言語のプログラマーは以下の点に気をつけましょう。
( )
(
,)
は複数のステートメントを囲み、最後の式の値が評価されます。
z = (
a = 5;
b = 3;
a + b;
); // z は8になる。
条件分岐
条件分岐はif() else
ではなく?
または? :
を使って作ります。
a < 5 ? b = 6; // aが5未満なら、bに6を代入する
a < 5 ? b = 6 : c = 7; // aが5未満なら、bに6を代入、そうでなければcに7を代入する。
a < 5 ? ( // aが5未満なら、bに6を代入して、cに7を代入する。
b = 6;
c = 7;
);
?
,?:
のオペレーターは、式の左辺にも使うことができます。
(a < 5 ? b : c) = 8; // もしaが5未満なら、bに8を代入、そうでなければcに8を代入する。
単純な数学関数
- sin(angle) -- 指定した角度のサインを返します。指定する角度の単位はラジアンです。度からラジアンに変換するためには、
$pi/180
もしくは0.017453
をかけてください。 - cos(angle) -- コサインを返します。指定する角度の単位はラジアンです。
- tan(angle) -- タンジェントを返します。指定する角度の単位はラジアンです。
- asin(x) -- アークサインを返します。単位はラジアンです。
- acos(x) -- アークコサインを返します。単位はラジアンです。
- atan(x) -- アークタンジェントを返します。単位はラジアンです。
- atan2(x,y) -- $atan(\frac{x}{y})$を返します。単位はラジアンです。
- sqr(x) -- 二乗を返します(
x * x
と似ていますが、x
は一度しか評価されません)。 - sqrt(x) -- 平方根を返します。
- pow(x,y) --
x
のy
乗を返します。動作とパフォーマンスは^
演算子と同じです。 - exp(x) -- $e$ (約2.718)の
x
乗を返します。この関数はpow()
や^
演算子を使うよりもとても高速です。 - log(x) -- $e$を底とする自然対数を返します。
- log10(x) -- 10を底とする自然対数を返します。
- abs(x) -- 絶対値を返します。
- min(x,y) -- 二つの引数の最小値を返します。
- max(x,y) -- 二つの引数の最大値を返します。
- sign(x) -- 引数の符号を返します(-1, 0, 1のいずれか)。
- rand(x) -- 0以上x未満の擬似乱数を返します。
- floor(x) -- x以下で最も大きい整数を返します (floor(3.9)==3, floor(-3.1)==-4)。
- ceil(x) -- x以上で最も小さい整数を返します (ceil(3.1)==4, ceil(-3.9)==-3)。
- invsqrt(x) -- 平方根の逆数($\frac{1}{\sqrt{x}}$)を高速に計算します
ループ
JSFXでのループは以下の関数で作成します。
loop( 回数, コード)
loop(32,
r += b;
b = var * 1.5;
);
最初の引数がループの回数を決定します。この引数が1未満なら、第二引数は評価されません。
最初の引数に大きすぎる値を指定しないように気をつけましょう。もしそうするとエフェクトが長時間のフリーズを引き起こします。実行時のフリーズを避けるため、繰り返し回数は約1,000,000回に制限されています。もしもっとたくさんのループが必要だとしたら、設計を考え直した方が良いでしょう(もしくは最後の手段としてループをネストしてください)。
最初の引数は一度しか評価されません(なのでループの中で変数を変更しても、ループ回数は変わりません)。回数の不明なループを作りたい場合は、次のwhile()
を見てください。
while( コード )
while(
a += b;
b *= 1.5;
a < 1000; // aが1000未満の間繰り返し
);
最初のパラメーターの最後のステートメントが0と評価されるまで繰り返します。
実行時のフリーズを避けるため、繰り返し回数は約1,000,000回に制限されています。もしもっとたくさんのループが必要だとしたら、設計を考え直した方が良いでしょう(もしくは最後の手段としてループをネストしてください)。
while( 条件 ) ( コード ) -- REAPER 4.59以上
while ( a < 1000 ) (
a += b;
b *= 1.5;
);
引数を評価して、0でなければ後続するコードブロックを実行し、繰り返します。これはC言語のwhile()
と似ています。
実行時のフリーズを避けるため、繰り返し回数は約1,000,000回に制限されています。もしもっとたくさんのループが必要だとしたら、設計を考え直した方が良いでしょう(もしくは最後の手段としてループをネストしてください)。
時間の関数
time([v]) -- REAPER 4.60+
現在時刻を1970年1月1日からの秒数で返します。引数が与えられると、その引数にタイムスタンプが設定されます。
time_precise([v]) -- REAPER 4.60+
システム固有のタイムスタンプを返します。精度はシステムにより異なりますが、大抵は1ミリ秒未満です。ベンチマークに便利です。引数が指定された場合は、その引数にタイムスタンプが設定されます。