绝对值 vs. 比例值,节奏反向
[本章绝大多数偏向创作,并无太多SC的东西]
做序列化的一个选择是选择绝对或比例值。绝对值将一成不变,一个绝对的C4将永远是C4。比例值基于一个公式或上一个值计算。使用同样的比例,却返回不同的值。五度(fifth)音程是比例值一个很好的例子。较弱这样,实际返回的值可能是C4或D-flat3(不懂如何翻译..D降3?),但它将永远比上一个值大1/5。比例值对音高、下一事件、持续时间和振幅起作用。它在振幅方面尤为有用,允许序列化在音量间渐变。
比例事件之于音乐非常有意义,因为它让我们从关系的角度认知音乐:这一事件与上一事件相关。旋律的逻辑依靠每两个音符间的比率(ratio)决定。节奏基于一拍的比率:这一拍的事件是上一拍事件的两倍。
当选择绝对音高时,你也可基于另一个音高控制一个音高的概率。例如,你可以偏重选择C和G,感觉就很主音(tonic)。但使用比例值,你可以在和谐音程(consonant interval)上偏重选择,或更多不和谐音程(dissonant intervals),从而控制不谐和的水平。
在使用比例值时,超越边界的危险性更大。因为你无法在一个范围内指定绝对音高,因此你将受系统支配,并会定期走出范围。解决方式是使用一个缓冲(buffer),或像之前例子中那样折回(wrap around)。
对绝大多数参数来说,一个比例值通常是一个浮点数字。在0.0~1.0间的比例选择将产生一个比当前值小的新值。(比如说,持续时间为2,比例值为0.75,那最终的下一个值将是1.5)如果比例值大于1.0,那结果值将更大。(持续时间为2,比例值为1.25,那最终的下一个值将是2.5)
音高
在使用比例音高体系时,有两件重要的事需要考虑。如果你使用频率工作,你可以将音程描述为当前值的一部分。比如说,如果你正演奏A 440并想为下一事件一个八度的比例值,那么比率是2:1(值*2)。注意音程比率比如2.0(八度音阶),1.5(五度),1.333(四度),1.25(三度)等等,仅仅是音程。我们在绝大多数现代音乐中使用等程音阶(平均律音阶)。
如果,另一方面,你要平均律,然后使用MIDI数字。每个MIDI数字代表钢琴上的一个键,音色由合成器决定。为使用MIDI音色的比例系统运用的数学也不一样。除非你想增减值,否则无需乘法。给一个从C4(MIDI数字60)开始的起点,C4上五度是G4(MIDI数字67)。为得到音程,你为五度加7,四度加5,三度加4,三度以下-4,等等。一系列MIDI音程的反向很简单:midiArray.neg。它取得值并反向全部正负号,比如将5变成-5,-10变成10。
27.1. 比例的MIDI反向
// 如果使用MIDI音程,这是同度的,4th上, M3rd上, // 5th上, M2下, M6th下, 2nd上, ttone down o = [0, 5, 4, 7, -2, -9, 2, -6]; o.neg; // 结果一致, 4th下, M3rd下, 等等 [ 0, -5, -4, -7, 2, 9, -2, 6 ]
持续时间和下一事件
你可能会认为由于我们的系统基于比例值(一拍的商或积)标记,那么比例持续时间将非常有意义。实际上,它很快就变得非常复杂。对持续时间来说,一系列附加到比例的分数在传统标记法下很难表述。这是一串令人迷惑的简单比例值:1, 1.5, 1.5, 1.5, 0.5, 0.5。以1秒作为起点,或四分音符的一拍 = 60bpm:1×1=1(四分音符)×1.5=1.5(附点四分音符)×1.5=2.25(half tied to a sixteenth,ok,我又不知道该怎么翻了)×1.5=3.375(dotted half tied to sixteenth tied to thirty-second,还能再麻烦一点吗?)×0.5=1.6875(??)×0.5=0.84375(??)。这么一堆如何可能用传统标记法表述?这是计算机依人类体系思考的失败例证,或我们应该思考的另一问题?
测量音乐的细分没有固有的错误。我们喜欢它,因为这是一个易于上手的简单模式。比例策划(proportioanl scheme)仍可被每拍使用:这拍比上拍有更多分部(division)。这拍有上拍1/2的事件。
比例持续时间计划的另一问题是值0。在SC中,为下一事件使用0是合法的,代表一个和弦或一个同时事件。但一旦你日到0便无法逃亡,因为0乘任何数皆为0。解决方式是测试值、为下一事件提供非0值(但之后你将不再能在一个和弦拥有超过两个音符),或更佳的,将和弦想做一个单独事件,然后决定这个事件是否是一个和弦,以及和弦里有多少个元素,与下一事件区分。比如说,判定每个事件是否是休息的(rest),单独的音符,或者一个和弦。如果是和弦,判定和弦里有多少个音。将它们全部作为当前持续时间,然后判定下一事件仍未一个和弦,一个休止,或一个单独音高。
另一个可能是永远不允许将0作为一个选择,但设想同时事件(simultaneous events)为一个对位法(conuterpoint)函数:设计两或三行有时会同时出现为一个和弦的代码。这个表述的难点在于持续捕捉来自两个独立系统的音程结果。
下一事件
另一个调节休息(rest)和同时事件的方法是分别计算持续时间和下一事件。若这样的话,即使当前事件设置为4秒下一事件也可是1秒。或下一事件可以是0,生成同时事件,同时每个同时事件的持续时间可以不同。当然下一事件长于当前事件的持续时间时,休息便会发生。
非时序事件
并不需要循序(sequentially)计算事件。我们太频繁的假设那个事件应该是线性和连续的。(一个很好的理由:我们循序的认知音乐,像一系列关系。)另一途径是选取一个音发声的时间点,而不是选取下一个音。比如说,如果你首选决定一个作品的时间(比如四分钟),你将在这个连续统一体的时间线的某些地方放置项目。音1可能别放置在2分23秒,持续3秒,音2可能被放置在1分13秒。这在连续性上出现了问题。像在之前指出的,我们循序的认知央视,因此如果事件不是循序计算的,那么维持主旋律一致性将变得困难。一个解决之道是包含一个音序和非音序事件的混合体。主题和动机可能被循序的充实,但向上边描述的那样被植入时空。然而,我认为时序与非时序的方法更多属于学术范畴。
振幅
在振幅的情况下,比例系统也可以很好的工作,因为振幅常是之前值(渐强或渐弱)的一个函数。
节奏反向
最后一点关于序列化节奏:反向。原始以及反向版本的节奏系列(series)是明显不同的,但要如何反向它呢?绝大多数我在其他地方阅读到的解决方式并未抓到节奏反向的要义。状态应被转化到反面,慢到快,长到短,等等。我常使用两种办法来做这个。但两种方法都是有问题的。
首先是密度的反向,这是对行的二进制观测角度。要求你首先决定最小的结合(articulation)。以这为例,让我们使用一个八分音符。这意味着密度测量将由八分音符填满,最少的密度将是一个单独的全音符。你可以使用多个持续时间0和1描述一个测量,于是每个可能的结合点(每个八分音符)便是0或1,0意味着没有链接,1意味着一个单独的链接。使用这个方法,四个四分音符将是1, 0, 1, 0, 1, 0, 1, 0。两个二分音符将是1, 0, 0, 0, 1, 0, 0, 0。逻辑的反向然后将变为简单的0和1的交换。四分音符测量将转换到0, 1, 0, 1, 0, 1, 0, 1,或一个切分八分音符通路(passage)。两个二分音符将转化为0, 1, 1, 1, 0, 1, 1, 1,或一个八分休止符,接着三个八分音符,然后另一个八分休止符,接着三个八分音符。
这种方法的第一个问题是你被限制于仅可用申明了的合法值的小盒子里。第二个问题是,倒置可能生成一个结合不等的数字,并将因此要求音高或动态系列的不同大小。(例如,设想你正在使用一个8个音的序列,和一个由两个二分音符、四个四分音符以及两个全音符组成的节奏序列。初始的节奏序列使用8个结合点,但反向将产生24个结合点。你打算如何处理这些多出来的音符?)一个解决方式是确保仅使用全部结合点的一半,这样反向便将是另外一半。值的总量将始终如一。但这看起来像是一个有限的约束。
另一办法,是将每个持续表述为一个给定脉动的比例。四分音符是1.0,二分音符是2.0,八分音符是0.5,等等。这是节奏反向将是倒数:2转化为1/2,1/2转化为2。这个计划(scheme)维持了一个系列内结合的数量并满足了一个反向的逻辑(快到慢,慢到快,密到稀薄:一个活跃的密度线,比如说,全部是十六分音符,将转化为一条松散的长线,全部为全音符)。这个系统唯一的毛病是,反向的时间总合可能会与初始的行(row)完全不同。如果你与若干声音协同工作,这将会使行内其他元素失去同步。
你可以使用normalizeSum消息强制比例适应规定期限(prescribed time)。打个比方,数组[1, 1.5, 0.25, 4, 0.25],总共持续6秒。“倒数”反向将是[1, 0.67, 4, 0.25, 4 ],总共持续9.92秒。使用normalizeSum,减小数组中的每个值,使其总合为1.0。([1, 0.67, 4, 0.25, 4 ].normalizeSum.round(0.01))的结果是[ 0.1, 0.07, 0.4, 0.03, 0.4 ]。那些值总合为1.0,如果我们希望它们持续6秒,那很简单,乘以6就可以了:[ 0.1, 0.07, 0.4, 0.03, 0.4 ]*6 = [ 0.6, 0.42, 2.4, 0.18, 2.4 ]。
结果常是非常复杂的,并再次迅速从绝对多数创作者关于节奏可能性的狭窄概念中走出来,也许是件好事。
Ex. 21.1
var rhythmArray, orLength, inversion; rhythmArray = [1, 1.5, 2, 1.25, 0.25, 0.25, 1.5, 0.333]; orLength = rhythmArray.sum; inversion = rhythmArray.reciprocal.normalizeSum*orLength; inversion.postln; rhythmArray.sum.postln; inversion.sum.postln;
Terry Lee,之前的一个学生,相信我对于保存总持续时间的常是一个卷积(convolution),并且当你反向时间的时候你应当得到一个不同的总持续时间。我才如果你持有这样的观点话,你需要确保你一次性反转了全部声音。那样,或不在意其他声音输出的不匹配。