Max/MSP/Jitter 教程13 - 列表和矩阵
Max/MSP/Jitter 教程 11 - 矩阵混合
Max/MSP/Jitter 教程12 - 视频去背景合成
00 翻译自 Cycling74 的 Max/MSP/Jitter 官方文档:Tutorial 11: Lists and Matrices
https://docs.cycling74.com/max7/tutorials/jitterchapter11
本教程讲解如何用 Max 列表和 jit.fill
对象来填充(部分)矩阵,以及如何用 jit.spill
检索(部分)矩阵内容作为列表。还将演示通过矩阵名称远程访问矩阵内容。
矩阵名称
patch 左侧有一个蓝色的 jit.matrix
。第一个参数是矩阵的名称 smallbox。其他参数表示矩阵有 1 个 char 平面,包含一维 12 个单元格。
矩阵唯一名称:smallbox
教程 4 介绍过,每个矩阵都有一个名称。如果没有另外指定,Jitter 将自动命名(类似 “u040000114” 奇怪的唯一名称)。名称表示存储矩阵的内存位置。为什么要另外给矩阵命名呢?这样可以告诉其他对象如何找到矩阵的内容。引用矩阵的名称,对象之间可以共享数据,无需接收 jit_matrix 消息就可以远程访问矩阵的内容。
Jitter 使用矩阵名称来指代内存位置,这跟 Max 的
value
对象类似。名称相同的对象可以有多个,只在其中一个中存储数值,其他对象就可以检索这个值。该名称实际上只有一个内存位置,它们共享相同的数据。同样,可以有多个名称相同的jit.matrix
对象,它们共享相同的数据。其他对象(例如jit.fill
)只需知道名称即可访问矩阵内容。
jit.fill
教程 4 展示了在矩阵特定位置指定数值的 setcell
消息,以及检索位置内容的 getcell
消息。现在来看看如何使用 jit.fill
对象将一个值列表存入矩阵中。(本章后面还将展示如何从矩阵中一次检索多个值)
在 patch 的左上角有一个包含 12 个数值列表的消息框。它连接到 jit.fill smallbox
对象。矩阵名字是 smallBox。
jit.fill 在命名矩阵中存储一个值列表
单击消息框将列表发送到 jit.fill smallbox
。对象在名为 “smallBox” 的矩阵存储这些值。单击 jit.matrix smallbox
上方的按钮显示 smallbox 矩阵的内容来验证。这些值由 jit.print
打印在 Max Console 中,并在狭长的 jit.pwindow
中显示为灰阶。
这个例子的列表长度恰好可以填充整个矩阵。这不是必须的。可以在 1D 或 2D 矩阵的任意连续部分中放置任何长度的列表。
偏移属性
双击打开 random_lists
子 patch。
默认情况下,jit.fill
将值列表放在矩阵最开头。也可以设置 jit.fill
的 offset
属性将列表指定到矩阵中的任何位置。这里演示如何使用 offset。
首先指定偏移量,后跟列表
上面的例子随机选择单元格索引作为 jit.fill
offset 消息的参数,然后向 randbox 矩阵中的该索引处,发送要存储的 16 个元素的列表。
点击开关启动 metro
。每隔半秒,16 个元素的列表被写入 randbox 矩阵中的新位置。
用 clear
消息清除 randbox 矩阵的内容,然后观察 metro
将列表写入新的随机位置。metro
也正在触发 jit.matrix randbox
将其内容发送到 jit.pwindow
显示。
使用 multislider
打开 draw_list 子 patch。
现在我们知道如何将预先定义的值列表存到矩阵中。如果要在 Max 中交互式生成列表并实时放置在矩阵中,需要用构建列表的对象比如 multislider
和 zl
。
multislider
对象包含一组 slider
,并一次发送所有 slider 的值作为列表(slider 可以小到一个像素宽,这样它看起来更像一个图形而不是一组单独的控件)。在窗口中移动任何 slider 时会发送整个列表,释放鼠标按钮时再次发送列表。在 draw_list 子 patch,有一个包含 256 个滑块的 multislider
,可发送从 0~255 的值,它恰好将 256 个 char 值发送给 jit.fill graybox
对象。
拖动鼠标在 multislider
中设置 256 个滑块。释放鼠标按钮时,256 个值的列表将发送到 jit.fill graybox
。注意矩阵单元的亮度如何与滑块的高度相对应。
一旦 jit.fill
在入口处收到列表,就会写入指定的矩阵(offset 属性指定的)位置。完成时 jit.fill
会发出 bang。可以用它来触发另一个动作,例如显示矩阵。
前两个例子故意不使用
jit.fill
左侧出口的 bang,以便清楚看到,jit.fill
远程写入到指定命名的矩阵,而不是通过物理连接。当然jit.fill
左侧出口的 bang 很方便,只要填充完就会触发矩阵的输出。
使用 zl
打开 collect_values 子 patch
某些情况下你可能想用矩阵来存储 patch 某处的数字消息:MIDI消息、来自 UI 对象的数字等。可以向 jit.matrix
发送 setcell
和 getcell
消息,也可以将消息收集到列表中,然后用 jit.fill
将它们一次性存到矩阵中。
zl
是多功能的列表处理对象,由第一个参数指定模式和行为。当第一个参数是 group 时,它会收集左入口的消息直到一定数量,然后将这些数字作为单个列表发送出去(这些值按接收顺序分组)。在 collect_values 子 patch 中有一个 zl group 256
对象,每当它从左入口收集够 256 个值,就把这个列表发送到左出口(并清除内存)。
向上和向下移动 slider 为 zl
对象生成 256 个输入值。当 zl
收到 256 个数字时,它把这个列表发送到 jit.fill midibox
,由它写入 midibox 矩阵,然后 bang jit.matrix midibox 1 char 256
对象以显示矩阵。
zl 将包含 256 个元素的列表发送到 midibox 矩阵,然后 bang jit.matrix 来显示结果
如果电脑连接了 MIDI 键盘,可以使用 MIDI 键盘的 modulation wheel 移动 slider。(MIDI 和 Jitter 的交互将在后面的教程中详细探讨)
值*2 获得 0~254 范围
可以用list length
数字框向右入口发送新的值来更改 zl
数据集的列表长度。用 loacation
数字框发送 offset
消息给 jit.fill
告诉它想要存储列表的位置。改变列表长度和位置,可以将任意数量的值放入矩阵的任何连续区域。
更改 zl
的 list length (如 100),设置 jit.fill
的 offset 属性(如 50),然后移动 slider 把值的列表存到矩阵中的指定位置。
jit.fill 和多平面矩阵
打开 fill_separate_panes
子 patch
jit.fill
可用于多平面矩阵,但它一次只能填充一个平面。jit.fill
要处理哪个平面由 @plane
属性指定。在fill_separate_panes
子 patch 中创建了另一个名为 colorbox 的矩阵,这次有四个char 数据平面。设置了三个 multislider
和三个 jit.fill
对象,每个对象都对应 colorbox 框矩阵的不同颜色平面。
各自填充每个平面
拖动三个彩色 multislider
填充三个颜色平面。
这样可以快捷生成矩阵中 RGB 平面不同强度的曲线。显示矩阵的 jit.pwindow
宽为 256 像素,所以矩阵 64 个单元格都显示为 4 像素宽的条带。如果打开 jit.pwindow
的 interp
属性,相邻频段之间的差值会被插值平滑。
单击 interp $1
消息框上方的开关,将消息发送到 jit.pwindow
。(注意,这也会发送 bang 到 jit.matrix
重新显示内容)
与前一个示例相同,但打开了 jit.pwindow 的插值
jit.fill 和二维矩阵
目前为止所有的例子都是一维矩阵。用列表(一维数组)通过 jit.fill
填充二维矩阵时会发生什么?jit.fill
对象在第一个维度里尽可能排列列表(尽量排满指定的行)然后绕到下一行继续排列。下面演示排列的过程。
单击标有 2D 的按钮,把 jit.matrix colorbox
对象变成 8x8 二维矩阵,jit.pwindow
也会调整为更合适的形状。无论何时更改矩阵尺寸,它都会清除之前的数据,所以需要再次单击三个 multislider 重新填充矩阵。仍向每个 jit.fill
对象发送 64 个元素的列表,并用 8 个元素填充矩阵的 8 行。
要点:这里没有演示如何使用带有 offset 属性的 2D 矩阵,当
jit.fill
的 name 属性命名 2D 矩阵时,offset 属性需要两个参数: x 偏移量和 y 偏移量。
jit.fill
仅适用于 1D 和 2D 矩阵。
相同的例子,列表填充 8x8 矩阵(未插值)
开启插值
jit.spill
jit.spill
是 jit.fill
的补充。它在入口处接收 jit_matrix
消息,将矩阵值作为列表发送到左出口。当使用红色 multislider
,下面的 jit.spill
发送平面 1(红色)的值到左出口并在消息框显示内容。
用列表显示 colorbox 矩阵的平面 1 的内容
jit.spill
也有 list length 和 offset 属性
如果需要发送一系列单个数字消息而不是单个列表消息,iter
对象了解一下。
从矩阵中获取一些值并分成不同的消息
jit.iter
打开 individual_values 子 patch。
jit.iter
对象可以检索矩阵中的每个值。当它收到 jit_matrix
消息时,会按矩阵中单元格的顺序发出消息序列:单元格索引(中间出口),然后是该单元格的值(左出口)。如果是一个大矩阵,会有一大堆消息试图在(Max’s scheduler)单个 tick 中发送出去,所以当它完成所有发送后,jit.iter
会向右出口发送一条完成的消息。
在 individual_values 子 patch 中有一个 jit.iter
对象,它接收来自 jit.matrix readbox 1 char 256
的矩阵信息。我们使用 swap
对象切换单元格索引的顺序(来自 jit.iter
中间出口)和单元格值(来自 jit.iter
左出口)。然后用该单元格的值作为想要存储在表对象中的 y 值,用单元格索引作为 x 轴索引。
点击 multislider
发送内容给 jit.fill
(然后 bang jit.matrix
并传达其内容给 jit.iter
)。双击 tabel
对象打开图形窗口,看到它包含与 readbox 矩阵相同的值。
请注意,使用 jit.iter
填充表格的技巧适用于中等大小的一维单平面矩阵,因为表格是一维数组。但是像jit.movie
对象的 2D 矩阵有四个平面,jit.iter
的中间(单元索引)出口输出双元素列表,左出口的值列表是四元素列表。
对于一维或小的 2D 矩阵,或者在较大矩阵中搜索特定值或模式, 用 jit.iter
扫描整个矩阵是很方便的。
小结
发送 setcell
和 getcell
消息给 jit.matrix
,可以存储或检索矩阵中的单个值(如教程 4 所示)。如果要存储或检索列表,就要用 jit.fill
和 jit.spill
。它们可以检索 1D 或 2D 矩阵的任何平面,在任意起始单元位置存储任何长度的列表。
multislider
和 zl
对象用于实时生成列表消息。用鼠标拖动 multislider
可以绘制列表。使用 zl group
收集多个单独的数值到一个列表中,然后一次性发送到 jit.fill
。
可以设置 jit.fill
(或 jit.spill
)的 offset 属性来指定矩阵中的起始单元格位置。jit.fill
对象要设置名称属性(或者发送name
消息或输入[name]参数),指定它将填补的矩阵名称。它用这个名称访问矩阵,并且在列表写入矩阵完成时发出 bang。可以用它来触发其他操作。
发送矩阵给 jit.iter
,可以输出整个矩阵中所有值。
Max/MSP/Jitter 教程系列
Max/MSP/Jitter 教程 01 - 什么是矩阵?
Max/MSP/Jitter 教程 02 - Jitter 对象的属性
Max/MSP/Jitter 教程 03 - 播放 QuickTime 视频
Max/MSP/Jitter 教程 04 - 创建矩阵
Max/MSP/Jitter 教程 05 - 矩阵的数学运算
Max/MSP/Jitter 教程 06 - 控制视频播放
Max/MSP/Jitter 教程 07 - ARGB 颜色
Max/MSP/Jitter 教程 08 - 调整颜色
Max/MSP/Jitter 教程 09 - 调整图像颜色
Max/MSP/Jitter 教程 10 - 交叉渐变
友情提示:独自折腾 Max 易患上癔症……不妨入群互助
👇👇👇