调试与自定义:完成脚本
本章节已经进入尾声,我们要对现有脚本进行拓展:
on init declare ui_knob $Interval (-12,12,1) declare ui_knob $Velocity (-64,64,1) $Interval := 7 $Velocity := 20 end on on note play_note($EVENT_NOTE+$Interval,$EVENT_VELOCITY+$VELOCITY,0,-1) end on
通过调节标签为Velocity(力度)的旋钮,用户可以自定义生成音符的力度。譬如设置为-10,以力度100演奏的音符,伴奏音力度就为90。
关于此代码的学习尚未结束。请把Velocity拉倒最大值64,然后尽全力地在键盘上按键,请注意界面左下角的状态栏:
程序出错了。
刚才演奏的音符力度可能达到或超过了100,由于Velocity被设置为了64,生成音符的力度已经远超最大力度127,故KSP输出了一条错误信息。出现力度溢出时,KSP会以127为力度输出音符,同时输出错误信息。
这样的错误无伤大雅,并不会影响到程序工作。但是我们应该以不犯错误为工作追求,时刻警惕程序输出的错误信息,力争无错代码。
请读者阅读下面的代码:
on init declare ui_knob $Interval (-12,12,1) declare ui_knob $Velocity (-64,64,1) $Interval := 7 $Velocity := 20 message ("") end on on note if ($EVENT_VELOCITY+$VELOCITY > 127) play_note($EVENT_NOTE+$Interval,127,0,-1) else play_note($EVENT_NOTE+$Interval,$EVENT_VELOCITY+$VELOCITY,0,-1) end if end on
这次再用力演奏,即便Velocity设置为64也不会产生错误信息了。我们来分析这段代码,其中包含了两个新概念:message()函数与if…else…end if控制语句。
message函数向Kontakt状态栏中输出消息。完整定义如下:
message()函数在检索错误时极为有用,Kontakt状态栏只能显示一条消息,所以展示出来的消息是message()函数生成的最后一条。
本例中的初始化回调函数中出现了一个message(“”)(即输出空文本),它可以清除先前的错误信息。
下面我们来学习if…else…end if控制语句。
如果条件$EVENT_VELOCITY + $Velocity > 127为真(True),程序就会输出:
play_note($EVENT_NOTE+$Interval,127,0,-1)
如果为假(Flase),程序就会输出:
play_note($EVENT_NOTE + $Interval, $EVENT_VELOCITY+$VELOCITY,0,-1)
end if标记if语句的结束。
有了这些语句后,play_note()函数就能处理所有力度值(1~127)了。
但这些处理依然不完善,因为还存在力度小于1的情况。我们将Velocity调制-40,轻轻演奏一个音符,仍然会有错误消息输出,因为play_note()函数的力度值小于1了。
来看以下代码:
on init declare ui_knob $Interval (-12,12,1) {transposition amount} declare ui_knob $Velocity (-64,64,1) {Vel amount for new note} $Interval := 7 {initialize to a perfect fifth} $Velocity := 20 {initialize to 20: all generated notes are louder} message (" ") {clear Kontakt status line} end on on note {check if Vel is higher than 127} if ($EVENT_VELOCITY+$VELOCITY > 127) play_note($EVENT_NOTE+$Interval,127,0,-1) else {check if Velocity is lower than 1} if ($EVENT_VELOCITY+$VELOCITY < 1) play_note($EVENT_NOTE+$Interval,1,0,-1) else play_note($EVENT_NOTE+$Interval,$EVENT_VELOCITY+$VELOCITY,0,-1) end if end if end on
这段代码才是真正完美无缺,但其中出现了许多绿色文字:
这些绿色文字即注释(comments),使用大括号括住。注释会以高亮色展示,不被KSP解析。注释可以为代码划分层次,使代码清爽易读。
读者保存代码后,如果再打开,可能会发现自己对脚本模块做的修改全部丢失了。这是因为KSP在解析代码时,初始化回调函数一旦执行,所有的变量都会变回缺省值。为了保存我们对模块做的修改,似乎唯一的办法就是每次都进入代码修改参数值,然后保存。但这显然是事倍功半的做法。
因此KSP支持变量固化(persistent),请读者试用以下代码:
on init {----- GUI elements -----} declare ui_knob $Interval (-12,12,1) {transposition amount} declare ui_knob $Velocity (-64,64,1) {Vel amount for new note} {----- Inits -----} $Interval := 7 {initialize to a perfect fifth} $Velocity := 20 {initialize to 20: all generated notes are louder} {----- Recall -----} make_persistent ($Interval) {save the state of the knob Interval} make_persistent ($Velocity) {save the state of the knob Velocity} message ("") {clear Kontakt status line} end on on note {check if Vel is higher than 127} if ($EVENT_VELOCITY+$VELOCITY > 127) play_note($EVENT_NOTE+$Interval,127,0,-1) else {check if Velocity is lower than 1} if ($EVENT_VELOCITY+$VELOCITY < 1) play_note($EVENT_NOTE+$Interval,1,0,-1) else play_note($EVENT_NOTE+$Interval,$EVENT_VELOCITY+$VELOCITY,0,-1) end if end if end on
代码加载后,随意操作控件,然后保存,重新加载,你会发现改动依然存在。这都是make_persistent()函数的功劳,此函数只能在初始化回调函数中编写,必须包含变量名:
make_persistent(<变量名>) |
加载文件后记住变量值。 |
所有类型的变量(例如阵列、用户定义变量)都可以固化,并非只有UI控件变量可以。
总结
if…else…end if的作用是在不同条件下运行不同指令。message()函数在Kontakt状态栏输出消息,可以显示数字、变量值和文本。make_persistent()函数将变量值保存进文件中。
大括号括住的文本被称为注释,在提升代码的易读性上功不可没。
以上便是编程基础章节的全部内容了。之后的章节展开速度会更快,定义也将更加详细。读者在学习之后,一定要亲手实践代码,只有这样才能快速掌握Kontakt脚本语言。错误是在所难免也不足为奇的,失败乃成功之母。脚本中的错误不会影响到Kontakt程序本身。