Max/MSP实战:从零开始搭建一个可变律动音序器
Max/MSP作为一个强大的视觉化编程环境,确实能让人脑洞大开,但很多朋友可能跟我一样,常常觉得它功能强大,却苦于没有具体的项目来上手,总是停留在看教程、理解概念的阶段。今天,我们就来一个“实战演练”,从零开始,一步步搭建一个“可变律动音序器”,让你亲手体验Max/MSP的魅力,玩出属于自己的音乐花样!
这个音序器不仅能按部就班地播放音符,还能加入随机性和可变性,让你的音乐充满惊喜,告别呆板的循环。
第一步:核心节拍与时钟
音序器的心脏是时钟。我们需要一个稳定的节拍来驱动所有事件。
新建一个Max Patch:打开Max/MSP,
File -> New Patcher。创建主时钟:
- 创建一个
metro对象(快捷键m)。metro会周期性地发出bang消息。 - 它的左输入口是时间间隔(毫秒),右输入口是开关。
- 我们希望它每125毫秒(相当于120BPM的16分音符)发送一个
bang。所以,创建number对象(快捷键i),输入125,连接到metro的左输入口。 - 创建一个
toggle对象(快捷键t)作为开关,连接到metro的右输入口。 - 为了看到
bang,再创建一个button对象(快捷键b),连接到metro的输出口。点击toggle,你会看到button闪烁。
[number 125] | [metro] ---- [button] ^ [toggle]- 创建一个
计数器:我们还需要知道当前是第几拍。
- 创建一个
counter对象。默认是0到无穷大。 - 连接
metro的输出口到counter的左输入口(每次bang让counter递增)。 - 为了限制步数,比如8步,在
counter对象后加上参数8,即counter 8。这样它会从0数到7,然后循环。 - 创建一个
number对象来显示counter的输出。
[number 125] | [metro] ---- [counter 8] ---- [number] ^ [toggle]- 创建一个
第二步:音符序列与播放
现在我们有时钟和步进,下一步是存储和播放音符。
音符序列存储:
- Max/MSP中,
coll对象非常适合存储序列数据。创建一个coll my_sequence。 coll的左输入口接收索引(即步进号),右输入口接收数据。- 将
counter的输出连接到coll的左输入口。这样,每当counter输出一个数字,coll就会查询该索引对应的数据。 - 创建一个
number对象来显示coll的输出。你会发现默认什么都没显示,因为coll里是空的。
- Max/MSP中,
填充音符:
- 双击
coll对象,会弹出一个文本编辑器。 - 我们可以手动输入音符数据,格式是
索引, MIDI音高 响度;。例如:0, 60 100; 1, 62 100; 2, 64 100; 3, 65 100; 4, 67 100; 5, 69 100; 6, 71 100; 7, 72 100; - 保存并关闭。现在再点击
toggle,你会看到coll输出的音高和响度。
- 双击
播放MIDI音符:
- 我们需要将
coll输出的音高和响度分解。使用unpack对象。coll输出的是两个数字,所以创建unpack 0 0。 - MIDI音符需要
noteout对象来发送。创建一个noteout。 - 将
unpack的第一个输出(音高)连接到noteout的左输入口。 - 将
unpack的第二个输出(响度)连接到noteout的中间输入口。 noteout的右输入口是通道号,默认即可。
[counter 8] ---- [coll my_sequence] ---- [unpack 0 0] ---- [noteout]现在,你已经有了一个基本的步进音序器了!点击
toggle试试看,你的系统应该能听到MIDI音符了。- 我们需要将
第三步:加入“新花样”——随机性和可变律动
仅仅是按部就班播放,还称不上“新花样”。我们来给音序器加点随机性,让它更有趣。
随机跳过步进:
- 我们可以在每一步播放前,增加一个“是否播放”的随机判断。
- 在
metro连接counter之前,插入一个random对象。 - 创建一个
random 100(生成0-99的随机数)。 - 创建一个
!/ 50(如果输入值小于50,则输出bang,否则不输出)。 - 将
metro的输出连接到random的输入。 - 将
random的输出连接到!/的左输入口。 - 将
!/的输出连接到counter的输入口。
[metro] ---- [random 100] ---- [!/ 50] ---- [counter 8]现在,音序器会随机跳过一些步进,创造出不规则的律动。
!/ 50中的50可以调节,数值越大,跳过概率越低。随机音高偏移:
- 我们可以让音符在原有音高基础上,进行小范围的随机偏移。
- 在
unpack和noteout之间插入一个+对象和一个random对象。 - 创建一个
random 5(生成0-4的随机数)。 - 创建一个
!- 2(将随机数减去2,得到-2到2的偏移量)。 - 将
unpack的第一个输出(原始音高)连接到+的左输入口。 - 将
!- 2的输出连接到+的右输入口。 - 将
+的输出连接到noteout的左输入口。 - 每次
metro的bang,除了驱动counter,也可以驱动这个随机音高偏移。所以,从metro的输出口引一条线到random 5的输入口。
[unpack 0 0] ---- [int] ---- [+] ---- [noteout] [metro] -------- [random 5] ---- [!- 2] ----^(注意,
unpack输出的数字默认是浮点数,int对象可以将其转换为整数,确保音高是整数。)
第四步:美化与控制
一个工具好不好用,交互性也很重要。
添加控制界面:
- 为
metro的速度添加一个slider对象,连接到metro的左输入口。这样可以实时调整BPM。 - 为随机跳过概率的
!/对象添加一个slider,控制随机性。 - 为随机音高偏移的范围(比如
random 5中的5)添加一个slider,控制音高变化的剧烈程度。 - 为
coll对象,你可以创建一个table对象(快捷键cmd+4或ctrl+4),将coll的输出连接到table的输入,可以可视化音符,甚至通过table来手动编辑音符序列。
- 为
保存你的作品:
File -> Save Patcher,保存为一个.maxpat文件。
进阶思考与拓展:
- 多层音序器:可以搭建多个类似的音序器,分别控制不同的音色或乐器,通过
makenote对象来控制音符时长,然后连接到不同的noteout或midiout对象。 - 和弦播放:
coll中可以存储多个音高,用unjoin分解后同时播放。 - 参数自动化:Max/MSP中的
line、function等对象可以对任意参数进行平滑的自动化控制。 - 外部控制:结合
midiin对象,用MIDI控制器来控制音序器的参数,实现更丰富的互动。 - 音频合成:如果你对MSP部分感兴趣,可以将MIDI信息转换为音频信号,直接在Max/MSP中搭建合成器来发声,而不是依赖外部MIDI设备。
Max/MSP的魅力就在于其无限的自由度和模块化思维。这个可变律动音序器只是一个起点,你可以根据自己的想象力,不断地添加模块、修改逻辑,最终创造出独一无二的音乐工具。希望这个实战教程能给你带来启发,让你在Max/MSP的世界里玩得开心!