一个没有依赖项的纯 python3 库,旨在促进离线生成 Max patcher 文件( .maxpat
、 .maxhelp
、 .rbnopat
)。
如果您正在寻找 Max/MSP 的 python3 外部组件,请查看 py-js 项目。
使用 Python 对象以脚本方式离线生成 Max 修补程序文件,与以.maxpat
JSON 文件格式存储的 Max/MSP 对象一一对应。
具有任意嵌套级别的 (JSON) .maxpat
文件与相应的Patcher
、 Box
和Patchline
Python 对象之间的往返转换。
可以处理任何 Max 对象或 maxclass。
大量单元测试,覆盖率约 99%。
根据组成、结构(作为对象的图形)、对象属性和布局(使用图形绘制算法)对 Max 补丁进行分析和离线脚本修改。
允许精确布局和配置 Max 对象。
Patcher
对象具有通用方法(例如add_textbox
,也可以具有专用方法(例如add_coll
。例如,此方法有一个dictionary
参数,可以轻松预填充coll
对象(请参阅py2max/tests/test_coll.py
)。
提供maxclassdb
功能,可调用 Max Objects 的默认配置。
脚本化修补程序文件创建。
批量修改现有.maxpat 文件。
使用丰富的 python 标准库和生态系统来帮助创建可参数化的对象,并通过离线源进行配置。例如,从随机波表文件配置的独一无二的波表振荡器。
在外部开发期间生成测试用例和.maxhelp
文件
消除创建具有大量参数的对象的痛苦
使用数据预填充容器对象,例如coll
、 dict
和table
对象
有助于节省创建参数略有不同的多个对象的时间
在生成的补丁上使用图形绘制/布局算法。
生成补丁生成(-;
ETC..
p = Patcher ( 'my-patch.maxpat' )
osc1 = p . add_textbox ( 'cycle~ 440' )
gain = p . add_textbox ( 'gain~' )
dac = p . add_textbox ( 'ezdac~' )
osc1_gain = p . add_line ( osc1 , gain ) # osc1 outlet 0 -> gain inlet 0
gain_dac0 = p . add_line ( gain , dac , outlet = 0 , inlet = 0 )
gain_dac1 = p . add_line ( gain , dac , outlet = 0 , inlet = 1 )
p . save ()
默认情况下,返回对象(包括修补线),并且修补线出口和入口设置为 0。虽然返回的对象对于链接很有用,但返回的修补线却没有。因此,上式可以更简洁地写为:
p = Patcher ( 'my-patch.maxpat' )
osc1 = p . add_textbox ( 'cycle~ 440' )
gain = p . add_textbox ( 'gain~' )
dac = p . add_textbox ( 'ezdac~' )
p . add_line ( osc1 , gain )
p . add_line ( gain , dac )
p . add_line ( gain , dac , inlet = 1 )
p . save ()
使用内置别名( .add
表示.add_*
类型方法, .link
表示.add_line
),上面的示例可以用更缩写的形式(并使用垂直布局)编写为:
p = Patcher ( 'out_vertical.maxpat' , layout = 'vertical' )
osc = p . add ( 'cycle~ 440' )
gain = p . add ( 'gain~' )
dac = p . add ( 'ezdac~' )
p . link ( osc , gain )
p . link ( gain , dac )
p . link ( gain , dac , 1 )
p . save ()
此外,您可以解析现有的.maxpat
文件,更改它们,然后保存更改:
p = Patcher . from_file ( 'example1.maxpat' )
# ... make some change
p . save_as ( 'example1_mod.maxpat' )
另一个带有子补丁的例子:
p = Patcher ( 'out.maxpat' )
sbox = p . add_subpatcher ( 'p mysub' )
sp = sbox . subpatcher
in1 = sp . add ( 'inlet' )
gain = sp . add ( 'gain~' )
out1 = sp . add ( 'outlet' )
osc = p . add ( 'cycle~ 440' )
dac = p . add ( 'ezdac~' )
sp . link ( in1 , gain )
sp . link ( gain , out1 )
p . link ( osc , sbox )
p . link ( sbox , dac )
p . save ()
请注意,Python 类基本上只是 .maxpat 文件中 JSON 结构的简单包装器,几乎所有 Max/MSP 和 Jitter 对象都可以使用.add_textbox
或通用.add
方法添加到修补程序文件中。还有.add_<type>
形式的专门方法,用于数字、数字参数、子补丁程序和容器类型对象(有关更多详细信息,请参阅下面的设计说明)。
最简单的方法:
git https://github.com/shakfu/py2max.git
cd py2max
pip install . # optional
请注意,py2max 不需要安装即可使用,因此您可以跳过pip install .
如果您愿意,只需cd
进入克隆目录并开始使用它即可:
$ cd py2max
$ ipython
In [1]: from py2max import Patcher
In [2]: p = Patcher.from_file( " tests/data/simple.maxpat " )
In [3]: p._boxes
Out[3]: [Box(id= ' obj-2 ' , maxclass= ' ezdac~ ' ), Box(id= ' obj-1 ' , maxclass= ' newobj ' )]
py2max
有一个广泛的测试套件,测试位于py2max/tests
文件夹中。
可以按如下方式运行所有测试:
pytest
这会将所有测试的结果输出到outputs
夹中。
请注意,如果无法导入测试所需的包,则可能会跳过某些测试。
您可以通过以下方式检查跳过哪个测试:
pytest -v
要检查测试覆盖率:
./scripts/coverage.sh
其本质上是执行以下操作
mkdir -p outputs
pytest --cov-report html:outputs/_covhtml --cov=py2max tests
要运行单独的测试:
python3 -m pytest tests.test_basic
请注意,由于py2max
主要处理json
生成和操作,因此大多数测试没有依赖项,因为json
已内置到 stdlib 中。
然而,大量测试探索了正交图布局算法的应用,为此,使用了一大堆包,从众所周知的到深奥的。
如上所述,如果未安装所需的包,pytest 将跳过测试,因此这些完全是可选测试。
如果您坚持深入研究,并想要运行所有测试,您将需要以下包(及其依赖项):
pip install networkx
pip install matplotlib
brew install graphviz
来完成)——然后你可以pip install pygraphviz
API 文档仍然不可用
当前的默认布局算法非常初级,但是有一些有希望的方向,您还可以看到不同布局算法在此上下文中执行情况的视觉比较。
虽然生成不会消耗 py2max 对象,但遗憾的是 Max 在打开时不会从文件刷新,因此您必须不断关闭并重新打开 Max 才能看到对象树的更改。
对于少数拥有自己方法的对象,当前实现通过提供带有_tilde
后缀的不同方法来区分波浪线对象和非波浪线对象:
gen = p . add_gen ()
gen_tilde = p . add_gen_tilde ()
.maxpat
JSON 格式实际上非常简单且具有层次结构。它有一个父Patcher
和子Box
条目以及Patchlines
。某些盒子包含其他patcher
实例来表示嵌套子补丁程序和gen~
补丁程序等。
上面的结构直接映射到 Python 实现,它由 3 个类组成: Patcher
、 Box
和Patchline
。这些类可以通过它们各自的**kwds
和内部__dict__
结构进行扩展。事实上,这就是.from_file
patcher 类方法的实现方式。
事实证明,这是处理数百个 Max、MSP 和 Jitter 对象之间所有差异的最可维护和最灵活的方法。
已经实现了越来越多的修补程序方法来专门化和促进某些需要额外配置的对象类的创建:
.add_attr
.add_beap
.add_bpatcher
.add_codebox
.add_coll
.add_comment
.add_dict
.add_floatbox
.add_floatparam
.add_gen
.add_intbox
.add_intparam
.add_itable
.add_message
.add_rnbo
.add_subpatcher
.add_table
.add_textbox
.add_umenu
这是一个简短的列表,但仅add_textbox
方法就可以处理几乎所有情况。其他的实际上只是为了方便和节省打字。
一般来说,建议通过这些add_<type>
方法开始使用py2max
,因为它们在方法中内置了大部分必需的参数,并且您可以获得 IDE 补全支持。一旦您对这些参数感到满意,就可以使用通用缩写形式: add
,这样可以减少输入次数,但代价是您会失去 IDE 参数完成支持。
该项目有一些可能有用的脚本:
convert.py
:将maxpat
转换为yaml
以便于开发期间阅读compare.py
:使用 deepdiff 进行比较coverage.sh
:运行 pytest 覆盖率并生成 html 覆盖率报告请注意,如果您想将 py2max 构建为轮子:
pip install build
cd py2max
python3 -m build .
轮子应该位于dist
目录中。
该项目有一个基于 pydantic2 项目的实验分支。
该变体具有以下优点:
In [ 1 ]: from py2max import Patcher
In [ 2 ]: p = Patcher ( path = 'outputs/demo.maxpat' )
In [ 3 ]: msg = p . add_message ( 'set' )
In [ 4 ]: p . boxes
Out [ 4 ]: [ Box ( id = 'obj-1' , text = 'set' , maxclass = 'message' , numinlets = 2 , numoutlets = 1 , outlettype = [ '' ], patching_rect = Rect ( x = 48.0 , y = 48.0 , w = 66.0 , h = 22.0 ), patcher = None )]
该变体的另一个有希望的方向是为具有自己独特的maxclass
的对象创建专门的类。所以在这种情况下,上面的内容将是:
In [ 4 ]: p . boxes
Out [ 4 ]: [ Message ( id = 'obj-1' , text = 'set' , maxclass = 'message' , numinlets = 2 , numoutlets = 1 , outlettype = [ '' ], patching_rect = Rect ( x = 48.0 , y = 48.0 , w = 66.0 , h = 22.0 ), patcher = None )]
早期的努力是提供基于属性的属性访问和改进的 API。它已被pydantic2
分支取代,并且不会进一步开发。
版权归原作者所有:
史蒂夫·基弗、蒂姆·德怀尔、金·马里奥特和迈克尔·怀布罗。 HOLA:类人正交网络布局。可视化和计算机图形学,IEEE Transactions on,第 22 卷,第 1 期,第 349 - 358 页。IEEE,2016。DOI
Aric A. Hagberg、Daniel A. Schult 和 Pieter J. Swart,“使用 NetworkX 探索网络结构、动力学和功能”,第七届 Python 科学会议论文集 (SciPy2008),Gäel Varoquaux、Travis Vaught 和 Jarrod Millman (编辑),(美国加利福尼亚州帕萨迪纳),第 11-15 页,2008 年 8 月
绘制有向图的技术 Emden R. Gansner、Eleftherios Koutsofios、Stephen C. North、Kiem-phong Vo • IEEE 软件工程交易 • 1993 年出版
Gansner, ER、Koren, Y.、North, S. (2005)。通过应力主要化绘制图形。见:Pach, J.(编辑)图形绘制。 GD 2004。计算机科学讲义,第 3383 卷。施普林格,柏林,海德堡。 https://doi.org/10.1007/978-3-540-31843-9_25
开放图形可视化系统及其在软件工程中的应用 Emden R. Gansner、Stephen C. North • 软件 - 实践和经验 • 2000 年出版