Max/MSP/Jitter 官方教程翻译13 - 列表和矩阵

00 翻译自 Cycling74 的 Max/MSP/Jitter 官方文档:Tutorial 11: Lists and Matrices

本教程讲解如何用 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.filloffset 属性将列表指定到矩阵中的任何位置。这里演示如何使用 offset。


首先指定偏移量,后跟列表

上面的例子随机选择单元格索引作为 jit.fill offset 消息的参数,然后向 randbox 矩阵中的该索引处,发送要存储的 16 个元素的列表。

点击开关启动 metro。每隔半秒,16 个元素的列表被写入 randbox 矩阵中的新位置。

clear 消息清除 randbox 矩阵的内容,然后观察 metro 将列表写入新的随机位置。metro 也正在触发 jit.matrix randbox 将其内容发送到 jit.pwindow 显示。

使用 multislider

打开 draw_list 子 patch。

现在我们知道如何将预先定义的值列表存到矩阵中。如果要在 Max 中交互式生成列表并实时放置在矩阵中,需要用构建列表的对象比如 multisliderzl

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 发送 setcellgetcell 消息,也可以将消息收集到列表中,然后用 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.pwindowinterp 属性,相邻频段之间的差值会被插值平滑。

单击 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.spilljit.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.movi​​e 对象的 2D 矩阵有四个平面,jit.iter 的中间(单元索引)出口输出双元素列表,左出口的值列表是四元素列表。

对于一维或小的 2D 矩阵,或者在较大矩阵中搜索特定值或模式, 用 jit.iter 扫描整个矩阵是很方便的。

小结

发送 setcellgetcell 消息给 jit.matrix,可以存储或检索矩阵中的单个值(如教程 4 所示)。如果要存储或检索列表,就要用 jit.filljit.spill它们可以检索 1D 或 2D 矩阵的任何平面,在任意起始单元位置存储任何长度的列表。

multisliderzl 对象用于实时生成列表消息。用鼠标拖动 multislider 可以绘制列表。使用 zl group 收集多个单独的数值到一个列表中,然后一次性发送到 jit.fill

可以设置 jit.fill(或 jit.spill)的 offset 属性来指定矩阵中的起始单元格位置。jit.fill 对象要设置名称属性(或者发送name 消息或输入[name]参数),指定它将填补的矩阵名称。它用这个名称访问矩阵,并且在列表写入矩阵完成时发出 bang。可以用它来触发其他操作。

发送矩阵给 jit.iter,可以输出整个矩阵中所有值。



友情提示:独自折腾 Max 易患上癔症……不妨入群互助

👇👇👇

kidult00 wechat
扫码关注 00 的公众号
如果文章帮您节省时间或者解答疑问,不妨打个赏 :)