Serum公式解析器基础教程2 - 语法
1、 表达式允许包含的变量或常量
1.1 x参数
x参数是一个重要的时域参数,指代波形界面中当前绘制的值,取值 [-1.0,1.0] ,可以理解为“横坐标”的值。而此时不同x取值下表达式的值 f(x) ,则可以理解为“纵坐标”的值。得到的波形即为点(x, f(x))在x取值[-1.0, 1.0]时得到的点所连成的曲线。
一般来说,如果我们希望直接绘制波形,就会写一个关于x的表达式。如上一章中所演示的,我们需要得到一个方波图像时,便可以绘制一个[-1.0, 0)范围函数值为-1、(0.0, 1.0]范围函数值为1的函数的图像,而符号函数sgn(x) (Formula Parser中应写作sign())符合这一要求。因此我们输入sign(x)后按下回车,便可以得到一帧方波。

一些细节:表达式的值一旦大于1,则该点的取值会被设为1;若小于-1,则该点的取值会被设为-1;若表达式在该点处没有定义(比如log(x)在[-1.0, 0.0]范围内均无定义),则该点的取值会被设为0。
1.2 w参数
完全等价于 (x+1)/2 ,取值 [0.0, 1.0] 。

我们输入w,会发现得到的图像与输入(x+1)/2后得到的图像完全一致。当然,如果把一个表达式中所有的x均替换为(2*w-1)话,得到的图像将与原表达式完全一致。
1.3 q参数
q参数是一个非常重要的一个频域参数,指代谐波次数,取值 1, 2, ..., 512 ,即1至512中的自然数,公式中出现q参数时,表达式的值将表示上方FFT区中的振幅栏中各谐波的振幅。
我们输入1/q,便可以得到一个谐波振幅与谐波次数成反比的波形。

而输入1/q^0.5,便会获得一个FFT的锯齿波。

值得注意的是,若表达式在生成任何一个谐波的振幅时出现未定义的情况,则该帧波表的所有谐波振幅都会被清除,图像也将变成输入0后获得的图像。
1.4 p参数
p参数与q参数的取值一样,也指代谐波次数,取值范围 1, 2, ..., 512 。与q参数不同的时,公式中出现p参数时,表达式的值将表示上方FFT区中的相位栏中各谐波的相位。

我们输入p*0.1,会发现基频到9次谐波的相位符合表达式的预期效果,以0.1为公差递增,但10次谐波以后的相位均为0。这说明一旦包含p的表达式值超过1了,相位就会被设为0。同样的,一旦包含p的表达式值小于0了,相位也会被设为0。与q参数一样,若表达式在生成任何一个谐波的相位时出现未定义的情况,则该帧波表的所有谐波振幅也都会被清除,图像也将变成输入0后获得的图像。
1.5 z参数
与指代帧的编号线性相关,取值 [0.0, 1.0] 。表达式应用于第一帧时,z参数的取值为0.0;应用于第256帧时,z参数的取值为1.0。公式中出现z参数时,表达式将被应用于所有帧。若表达式中不含in参数且波表帧数不足256帧时,将依据公式生成256帧。(不足256帧时与p参数联合使用的效果非常蛋疼,因为你不能对着一个不存在的帧指定相位)
因此我们输入z*x,便会得到一个振幅随波表帧数增加的锯齿波波表。

1.6 y参数
完全等价于 z*2-1 ,取值 [-1.0, 1.0] 。公式中出现y参数时,表达式也将被应用于所有帧。若表达式中不含in参数且波表帧数不足256帧时,也将依据公式生成256帧。
1.7 in参数
指代当前帧的值。若原始波形为 f(x) ,则in参数在 x=x0 时的值为 f(x0) 。若表达式中含有q参数,则q取值为 q0 时,in指代 q0 次谐波的振幅。若表达式中含有p参数,则p取值为 p0 时,in指代 p0 次谐波的相位。若表达式中含有z参数,则in参数指代的均为z参数所指波表的相关参数:如若第k帧波形为fk(x),则z取0时,in在 x=x0 时的取值为 f1(x0) ;z取1时,in在 x=x0 时的取值为 f256(x0) 。
因此如果我们输入in*0.5,便会将原始波形振幅缩小一半。

1.8 sel参数
指代用户选中帧的值。与in参数不同的时,sel参数指代的帧的参数与z参数的取值无关,始终指代用户选中帧的值。
所以如果我们需要将一帧的波形克隆到256帧,我们只需选中那一帧,然后输入z=sel即可。(这里表达式前缀的“z=”是一种特殊写法,下文中会提到。)

1.9 rand参数
随机数。在表达式中x、p或q取不同值时会有不同的随机取值,但该取值与z参数无关:不论z指代哪张波表,rand都会在x、p或q参数取相同值时取相同的值(这个特性有时候非常的蛋疼)。
输入rand后是这个效果。

但如果我们输入z=rand,我们会得到256帧一模一样的随机波形。
1.10 常数
e:自然对数的底,值为2.71828182845904523536。(不知为何,Serum手册中标注的e的值为2.718281828182818281828,数学家欧拉先生认为这并不是真正的e)
pi:圆周率,值为3.141592653589793238462643。
1.11 表达式作用范围的判断原则
原则上,x(及w)、p、q参数不应该出现同一个表达式中,试图在时域表达式中使用频域参数是没有意义的。若表达式中不含p、q参数,则表达式默认被应用于波形界面,in、sel参数指代的值为波形取值。若含有q参数,表达式则被应用于FFT区中的振幅栏,in、sel参数指代的值也将为谐波振幅。若含有q参数,表达式则被应用于FFT区中的相位栏,in、sel参数指代的值也将为谐波相位。
2、 表达式允许包含的函数
函数 参数数量 说明
sin 1 正弦函数
cos 1 余弦函数
tan 1 正切函数
asin 1 反正弦函数
acos 1 反余弦函数
atan 1 反正切函数
sinh 1 双曲正弦函数
cosh 1 双曲余弦函数
tanh 1 双曲正切函数
asinh 1 双曲反正弦函数
acosh 1 双曲反余弦函数
atanh 1 双曲反正切函数
log2 1 以2为底的对数函数
log10 1 以10为底的对数函数
log 1 以10为底的对数函数
ln 1 以e (2.71828...)为底的对数函数
exp 1 e为底数的指数函数
sqrt 1 平方根函数
sign 1 符号函数(x<0值为-1;x>0值为1 )
rint 1 四舍五入法取整
abs 1 绝对值函数
min var. 取多个值的最小值
max var. 取多个值的最大值
sum var. 取多个值的和
avg var. 取多个值的平均值
3、 表达式允许包含的运算符
运算符 解释 优先级
&& 逻辑与 1
|| 逻辑或 2
<= 小于等于 4
>= 大于等于 4
!= 不等于 4
== 等于 4
> 大于 4
< 小于 4
+ 加 5
- 减 5
* 乘 6
/ 除 6
% 取余 6
^ 幂 7
其中优先级越大的运算符越优先进行运算。
4、 特殊语法:
4.1 三目运算符
写法为 (条件)?(条件为真时的取值):(条件为假时的取值) 。如表达式 (1>0)?1:2 的值为1,因为1>0这个条件为真,所以取冒号之前的值作为表达式的最终值。以方波为例,如果我们要用三目运算符来绘制一个1/4方波,我们可以这么做。
(1) 明确表达式的逻辑
我们要求波形在[-1.0, 0.5]范围内值为-1,在[0.5, 1.0]范围内值为1,为此我们需要写一个分段函数:
(2) 写成三目运算符的形式
分界的依据为x与0.5的大小关系,于是我们可以将条件设为x<0.5,若成立则取-1,若不成立则取1。写成表达式就是: x<0.5?-1:1

4.2 表达式前缀
写法为z=;q=;p=,置于表达式的开头。判断表达式作用范围时,前缀中出现的参数也视为在“表达式中出现”。若表达式前缀z=,则视为z在表达式中出现,表达式将被应用于256帧波表;同理,表达式前缀q=,表达式的值将表示上方FFT条中的振幅栏中各谐波的振幅;表达式前缀p=,表达式的值将表示上方FFT条中的相位栏中各谐波的相位。