CAL教程13(实例讲解:高级二)
本篇我们就来了解最著名的精典CAL——扫弦处理!在这个CAL没有诞生之前,编写吉他扫弦如恶梦般令人心生畏惧,单单一轨的扫弦音符就有数千上万个,
如果是多个扫弦轨,那将是不可思议的工作量,我以及我所知道的很多老手们,在初接触MIDI制作时,
就是一个个音符处理的!
虽然也掌握了许多利用复制粘贴来完成操作的高效手段,但那又怎么能与CAL相提并论呢!
这个CAL的编写难度近乎是所有CAL中最高的,所以只要我们能看懂这个CAL的编写思路,
那么几乎所有的CAL,我们也能从容分析了。
我之前以在高级篇中首先讲了“音符粘合”这个CAL,主要原因就是,扫弦CAL在思路上与前者相当类似,
只是在插入时有所不同,且因为是和弦的处理,所以需要多编写一段分析和弦音高的语句。
下面,我们就走进这个CAL的编写思路,掌握了它,相信任何功能,我们只要能想得出来,就能实现它。
—————————————————————————————————————————————————
首先,我们依然是分析功能与音乐元素之间的关系:
我们处理的事件只有一种,就是音符事件,所以要涉及的元素,也就只有四个:起点;音高;力度;时值。
但因为我们需要记录的是一个柱式和弦中所有的音符,那么在设计自定义变量时,就要考虑充分,
我们需要估计吉他在扫弦时,出现最多和弦数的情况,即——6根弦同时演奏。
那么我们的变量设定,就要有6组:
音高1;力度1;时值1;
音高2;力度2;时值2;
…… …… ……
音高6;力度6;时值6;
起点变量,与音符粘合的设定差不多,因为只涉及到前一个和弦与后一个和弦两个起点,
所以不用像另外三个变量那样设定6组。
另外,因为我们要判断一个柱式和弦有多少个和弦内音,并且要在判断的同时,将它们的属性记录到变量中去,
所以一个取值为1-6的开关变量必不可少。
其它还有什么变量,其实并不用在一开始就去设定,我们可以在中途碰上需要的时候,再在开始设定它们。
下面,来分析这个扫弦CAL的结构,它主要由4大块组成:
1、自定义变量设定。
2、和弦内音记录。
3、重置已经记录了音符属性的自定义变量,使其从大到小,或从小到大排列。
总之就是要使用户明确,哪个变量记录的是第几根弦。
4、插入用户希望得到的目标音符。
其中,第3步是一串相当庞大的语句段,之所以需要重置,是因为我们的程序在扫描每一个事件时,
虽然是从左向右逐一扫描的,但对于同时出现的事件,程序是依照写入的先后顺序来取得优先扫描权的,
也就是说,对于柱式和弦,程序并不一定是从高向低扫描,也不一定是从低向高扫描,
这意味着扫描的顺序,是类似随机乱序的,因为我们不可能记得成千上万的音符中,我们写入的先后顺序,
就算在小范围内记得,这也无法被CAL利用,因为CAL词句编写出来是死的,而我们写入音符时的顺序,
在每首曲子,或是每一段,甚至是每一小节都是有所不同的!一个死的操作顺序,是无法应对乱序操作的。
下面是这个CAL在进程上的逻辑:
首先使程序记录下前一组柱式和弦,并删除之,
然后对记录了音符属性的变量进行重置,使变量从大到小,或从小到大的排列起来,
我们不用知道具体每个变量所记录的具体值,但必须知道哪个变量记录的是第几根弦的属性,特别是音高!
当程序扫描到后一组柱式和弦时,插入前一组和弦,
在插入时,我们不用修改插入音高,就照记录下来的变量进行插入即可,
但是我们可以控制插入的起点位置与时值长度,这是产生扫弦效果的关键,
因为已经知道了哪个变量记录的是最高或最低弦,所以我们就可以从高到低,或从低到高的插入音符,
并将起点依次向后移动所需要的位置,时值作相应减短即可。
然后这个CAL程序会对每一组柱式和弦都使用上诉逻辑进行操作。
这就是扫弦CAL的进程思路。
总结:
当扫描后一组和弦时,插入前一组和弦,并记录下后一组和弦,且删除之。
—————————————————————————————————————————————————
大家都看出来了,是不是与之前那个音符粘合的概念很像!
这种记录下当前扫描对象属性的同时,插入前一个扫描对象的方式,
在高级的CAL的中是相当常见的,逻辑思维强一些的人甚至会编写出扫描后两个对象时才插入第一个对象的操作,
当然,不管这种编写思路再复杂,本质上都是同一种处理概念:
就是先记录前一个对象,当扫描并记录后一个对象时再触发对前一个对象的处理。
[ 本帖最后由 溺水鱼 于 15-3-14 15:08 编辑 ]