Table Of Contents
Open Table Of Contents
Chuck 简介
ChucK是一个音乐编程语言,支持Linux,Windows和MacOS X。 可以在官网主页下载安装包或自己编译。
语法
Chuck的语法格式与C++类似,如条件,控制,循环,函数,类等都非常类是于C++。 但也有一些细微区别,最大的区别在于”=>“符号,这是在ChucK中用得特别多的符号。比如
0=>int i;
相当于C++中的
int i =0;
除此之外“=>”还有很多其他的用法,下面会讲到。
一个简单例子:
SinOsc s=> dac;
1::second=>now;
把以上内容存储为 first.ck,运行$ chuck first.ck
,你会听到一秒钟的正弦波声音。
以上程序的第一行做了三件事
- 创建了一个 “SinOSC”(正弦振荡器) 类型的实例 s
- dac 指数模转换器, 是ChucK内置的实例,实际上可以形象的认为是喇叭。
- 把 s 与 dac 连起来, 这里是”=>“的另一个用法。
这样相当于信号从正弦振荡器中产生,然后输入到喇叭发声。 若程序到此为止,是没有声音的,这里只是将s连向了dac, 第二行的作用是使时间往前1秒。因此正弦波的声音会持续一秒。(这里是”=>“的又一个用法。) 这是ChucK很有意思的地方,若深入了解会发现它的时间机制使得在做实时处理时非常强大。
如果需要声音一直持续,可以通过循环实现
SinOsc s=> dac;
while(true)
{
1::second=>now;
}
太单调了,需要更有趣一点?
SinOsc s => dac;
while( true ) {
100::ms => now;
Math.random2f(400.0, 1000.0) => s.freq;
}
Chuck 的运行方式
Chuck有2种运行方式,第一种方式和其他语言的编译或解释方式一样,$chuck foo.ck
会解释运行foo.ck中的内容.也可同时输入多个文件$chuck foo.ck bar.ck
.
`
第二种方式是带有Chuck独有的”on-the-fly”方式
$chuck --loop&
$chuck + foo.ck
$chuck + bar.ck
chuck --loop
会建立一个host/listener,通过$chuck + foo.ck
可以向host发送一个程序,即所谓的”on-the-fly”.
—>
实时控制
Chuck语言的一个很大的特点是其强大的实时控制机制.接下来我会实现一个带有如下功能的程序:
- 正弦波声音输出
- 随机采样一个大调音阶,每300ms改变一次正弦波的频率(SinOsc.freq),
- 每180ms改变一次正弦波的左右声道位置,
在(1)中已实现了如下功能.
-
正弦波声音输出
-
每隔100ms随机改变正弦波的频率
SinOsc s => dac; while( true ) { 100::ms => now; Math.random2f(400.0, 1000.0) => s.freq; }
在这个程序的基础上,做一些修改:
-
为了能够控制左右声道位置,需要增加一个模块Pan2,连在SinOsc和dac中间.
SinOsc s => Pan2 p => dac;
-
定义一个数组,包含大调音阶:
[60,62,64,65,67,69,71] @=> int scale[];
数组中的数字是MIDI音符值,通过
Std.mtof()
可以转换为频率值.随机采样scale数组:
scale[Math.random2(0,6)] => Std.mtof => s.freq;
-
定义一个函数,实时改变左右声道位置
fun void bar() { while(true) { 180::ms=>now; Math.random2f(-1.0,1.0)=>p.pan; } }
-
新开一个进程,运行bar()函数
spork ~bar(); // spork和fork名字很相似~
完整的代码:
foo_1.ck:
SinOsc s => Pan2 p => dac;
[60,62,64,65,67,69,71] @=> int scale[];
spork ~bar();
while( true ) {
300::ms => now;
scale[Math.random2(0,6)] => Std.mtof => s.freq;
}
fun void bar()
{
while(true)
{
180::ms=>now;
Math.random2f(-1.0,1.0)=>p.pan;
}
}
运行$chuck foo_1.ck
!