SC编程提示
SuperCollider是一门完整的编程语言,学习如何写一些标准的编程操作代码是大有裨益的。
SuperCollider语法
SuperCollider是一门基于Smalltalk的面向对象的编程语言。他具备一门计算机语言标准的工具,我将在此为你概述。
注释
// 这是一条注释
/* 这同样是一条注释 */
括号
我们通常会将一组相关的代码组合在一起,并尽量使其整洁和井井有条。你的整个patch一般都会被置于圆括号内。
( // 我的patch在这里边 )
但我们也将括号用于其它原因
( ) // 组合表达式或分析方法的引数, 例如 SinOsc.ar(440)
{ } // 函数,例如 {arg a; a*a}
[ ] // 数组 (一串数据) 例如 [1,2,3,4]
SuperCollider代码是完全嵌套的表达式——你通过查看在各对括号间被选中的内容来区分代码块嵌套的层级。
如果你稍一走神,将立马迷失在代码嵌套的海洋里。。。
尝试在SC环境下双击任意左括号:
(
// 第一个代码块
(
// 第一层嵌套块开始
(
// 第二层嵌套块
)
)
)
变量和赋值
在编程中,我们需要在某处储存我们的数据,甚至仅仅是告诉我们计算初始环境的数据。对做音乐来说,因为我们的程序始终处于运行,我们需要储存记录当前事件状态的信息。
( var a,b,c; // 变量总是首先被定义 a=1; // 赋值变量 b=a; c= b*5; [a,b,c].postln; a=4; // 为变量赋新值 b=a+9; c= c*5; // 这没问题,因为c目前为止已被赋值 [a,b,c].postln; )
post窗口显示:
[ 1, 1, 5 ]
[ 4, 13, 25 ]
[ 4, 13, 25 ]
这是对的:
( var dave; dave= 5; dave.postln; )
这是错的,SuperCollider将无视你:
( dave=5; dave.postln; )
封装
另一标准编程语言工具是自定义函数的能力,这一过程被称为封装。
证明:
(
var myfunction;
// 定义我自己的平方函数
myfunction= {arg a; a*a};
// 以输入8来运行我的函数并输出结果
myfunction.value(8).postln;
)
这避免了总是重复同样代码的繁琐。
用整洁的代码表现变化
(
var scale, current; // 做一个随机范围的代码
current=60;
scale= Array.fill(8, {var old; old=current; current=current+rrand(1,3); old}); //构建一个数组
scale.postln;
current=60;
scale= Array.fill(8, {var old; old=current; current=current+rrand(1,3); old});
scale.postln;
current=60;
scale= Array.fill(8, {var old; old=current; current=current+rrand(1,3); old});
scale.postln;
)
(
var makescale;
makescale= {var current;
current=60;
Array.fill(8, {var old; old=current; current=current+rrand(1,3); old;});
};
3.do({makescale.value.postln;});
)
循环
计算机可以为我们做一些对于人类来说非常单调无聊的事请,他们能快速的重复完成任务是因为它们有循环的能力。
(
20.do({"over and over".postln;}) // 输出20个"over and over"
)
(
var n;
n=0;
while({n<5}, {n=n+1; "keep going".postln;})
)
(
for(1, 5, {arg i; i.postln; }); // 从1开始, 满5之前每次递进1
)
//////////
(
forBy(1, 5, 2, {arg i; i.postln; }); // 从1开始, 满5之前每次递进2
)
主要不要设置死循环,那将使程序无限循环下去,并最终使你的电脑崩溃。
条件执行
SuperCollider中的控制流是自上而下的:
( "me first!".postln; "now me!".postln; "don't forget me!".postln; )
有时,我们想将某些事情的发生基于其它事情的发生。为了应对这种情况,编程语言具备条件执行——如果某些逻辑条件符合,则做某件事。
(
"me first!".postln;
"now me!".postln;
if(0.5.coin, {"don't forget me!".postln;},{"you forgot me!".postln});
// 摇一个骰子——如果是头我们做第一件事, 如果是尾则做第二件
)
if指令如此使用,一次一组顺序运行以下代码:
if(true, "true!", "false!").postln;
/////////
if(false, "true!", "false!").postln;
( var a,b; a=5; b= if(a==6, 11, 7); b.postln; )
类
最后,在SuperCollider中,你可以将你自己的函数写为类——这意味着它们在你的代码中总是可用的。你可以通过使用类将你的代码打散为很多文件。
类还是一个很好的封装函数和数据的概念性工具。这是优秀的面向对象编程的一部分。
目前为止我们已经见识过的一些类:
SinOsc
SCWindow
MouseX
一则SuperCollider中面向对象编程的笔记
大写字母开头的是类的名字。
一个点然后一个函数是一个对象的方法(method)
LFSaw.ar // ar是方法
选中方法然后Cmd+Y可以看到对应这个方法的类。
你可以使用 .dumpClassSubtree 方法来查看一个超类的起源类
UGen.dumpClassSubtree
所有玩意都源自对象类,所以运行 Object.dumpClassSubtree 看看整个层级吧~
你可以写你自己的类来为SuperCollider添加你自己的扩展。
当你想添加新类的时候,你可以将它们的代码写出来并保存为.sc文件,并把这个文件放入SCClassLibrary文件夹(我们将在这份教程的末期讲解这点)
然后使用Cmd+K重新编译类库:如果你的代码有语法错误,则库将不会被编译,但幸运的是你将看到能够你发现问题所在的错误提示。
