Una biblioteca pura de python3 sin dependencias destinada a facilitar la generación fuera de línea de archivos de parche Max ( .maxpat
, .maxhelp
, .rbnopat
).
Si está buscando componentes externos de python3 para Max/MSP, consulte el proyecto py-js.
Generación fuera de línea mediante script de archivos de parcheo Max utilizando objetos Python, correspondientes, uno a uno, con objetos Max/MSP almacenados en el formato de archivo basado en JSON .maxpat
.
Conversión de ida y vuelta entre archivos (JSON) .maxpat
con niveles arbitrarios de anidamiento y los correspondientes objetos Patcher
, Box
y Patchline
Python.
Potencialmente puede manejar cualquier objeto Max o clase máxima.
Muchas pruebas unitarias, ~99% de cobertura.
Análisis y modificación de scripts fuera de línea de parches Max en términos de composición, estructura (como gráficos de objetos), propiedades de objetos y diseño (usando algoritmos de dibujo de gráficos).
Permite un diseño y configuración precisos de los objetos Max.
Los objetos Patcher
tienen métodos genéricos como add_textbox
y también pueden tener métodos especializados como add_coll
. Como ejemplo, este método tiene un argumento dictionary
para facilitar el llenado previo del objeto coll
(consulte py2max/tests/test_coll.py
).
Proporciona una función maxclassdb
que recupera las configuraciones predeterminadas de Max Objects.
Creación de archivos de parche con script.
Modificación por lotes de archivos .maxpat existentes.
Utilice la rica biblioteca y el ecosistema estándar de Python para ayudar a crear objetos parametrizables con configuración desde fuentes fuera de línea. Por ejemplo, osciladores de tabla de ondas únicos configurados a partir de archivos de tabla de ondas aleatorias.
Generación de casos de prueba y archivos .maxhelp
durante el desarrollo externo.
Elimina la molestia de crear objetos con muchos parámetros
Rellene previamente objetos contenedores como coll
, dict
y table
con datos
Ayuda a ahorrar tiempo creando muchos objetos con argumentos ligeramente diferentes.
Utilice algoritmos de diseño/dibujo de gráficos en parches generados.
Generación de parches generativos (-;
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 ()
De forma predeterminada, se devuelven objetos (incluidas las líneas de parche) y las salidas y entradas de las líneas de parche se establecen en 0. Si bien los objetos devueltos son útiles para vincular, las líneas de parche devueltas no lo son. Por lo tanto, lo anterior se puede escribir de manera más concisa como:
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 ()
Con alias integrados ( .add
para métodos de tipo .add_*
y .link
para .add_line
), el ejemplo anterior se puede escribir en una forma aún más abreviada (y con un diseño vertical) como:
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 ()
Además, puede analizar archivos .maxpat
existentes, cambiarlos y luego guardar los cambios:
p = Patcher . from_file ( 'example1.maxpat' )
# ... make some change
p . save_as ( 'example1_mod.maxpat' )
Otro ejemplo con subparches:
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 ()
Tenga en cuenta que las clases de Python son básicamente simples envoltorios alrededor de las estructuras JSON en un archivo .maxpat, y casi todos los objetos Max/MSP y Jitter se pueden agregar al archivo patcher con los métodos .add_textbox
o .add
genéricos. También existen métodos especializados en el formato .add_<type>
para números, parámetros numéricos, subparches y objetos de tipo contenedor (consulte las notas de diseño a continuación para obtener más detalles).
La forma más sencilla:
git https://github.com/shakfu/py2max.git
cd py2max
pip install . # optional
Tenga en cuenta que no es necesario instalar py2max para poder utilizarlo, por lo que puede omitir la pip install .
parte si lo prefieres y simplemente cd
al directorio clonado y comienza a usarlo:
$ 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
tiene un extenso conjunto de pruebas con pruebas en la carpeta py2max/tests
.
Se pueden ejecutar todas las pruebas de la siguiente manera:
pytest
Esto generará los resultados de todas las pruebas en la carpeta de outputs
.
Tenga en cuenta que es posible que se omitan algunas pruebas si no se puede importar un paquete requerido para la prueba.
Puede comprobar qué prueba se omite mediante lo siguiente:
pytest -v
Para verificar la cobertura de la prueba:
./scripts/coverage.sh
que esencialmente hace lo siguiente
mkdir -p outputs
pytest --cov-report html:outputs/_covhtml --cov=py2max tests
Para ejecutar una prueba individual:
python3 -m pytest tests.test_basic
Tenga en cuenta que debido a que py2max
se ocupa principalmente de la generación y manipulación json
, la mayoría de las pruebas no tienen dependencias ya que json
ya está integrado en stdlib.
Sin embargo, una serie de pruebas exploran la aplicación de algoritmos de diseño de gráficos ortogonales y para ello se han utilizado una gran cantidad de paquetes, que van desde los más conocidos hasta los esotéricos.
Como se mencionó anteriormente, pytest omitirá una prueba si los paquetes requeridos no están instalados, por lo que estas son pruebas completamente opcionales.
Si insiste en sumergirse en la madriguera del conejo y desea ejecutar todas las pruebas, necesitará los siguientes paquetes (y sus dependencias):
pip install networkx
pip install matplotlib
brew install graphviz
). Luego, puede pip install pygraphviz
Los documentos API aún no están disponibles
El algoritmo de diseño predeterminado actual es extremadamente rudimentario; sin embargo, hay algunas direcciones prometedoras y también puede ver una comparación visual de qué tan bien se desempeñan los diferentes algoritmos de diseño en este contexto.
Si bien la generación no consume los objetos py2max, desafortunadamente Max no actualiza desde el archivo cuando está abierto, por lo que tendrás que seguir cerrando y volviendo a abrir Max para ver los cambios en el árbol de objetos.
Para los pocos objetos que tienen sus propios métodos, la implementación actual diferencia los objetos con tilde de los objetos sin tilde al proporcionar un método diferente con un sufijo _tilde
:
gen = p . add_gen ()
gen_tilde = p . add_gen_tilde ()
El formato .maxpat
JSON es en realidad bastante mínimo y jerárquico. Tiene un Patcher
principal y entradas Box
secundarios y también Patchlines
. Ciertos cuadros contienen otras instancias patcher
para representar subparches anidados y parches gen~
, etc.
La estructura anterior se asigna directamente a la implementación de Python, que consta de 3 clases: Patcher
, Box
y Patchline
. Estas clases se pueden ampliar a través de sus respectivas estructuras **kwds
y __dict__
internas. De hecho, así es como se implementa el método de clase del parche .from_file
.
Esta resulta ser la forma más fácil de mantener y flexible de manejar todas las diferencias entre los cientos de objetos Max, MSP y Jitter.
Se ha implementado una lista cada vez mayor de métodos de parcheo para especializar y facilitar la creación de ciertas clases de objetos que requieren configuración adicional:
.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
Esta es una lista corta, pero el método add_textbox
por sí solo puede manejar casi todos los casos. Los demás en realidad están ahí solo por conveniencia y para ahorrar escritura.
Generalmente, se recomienda comenzar a usar py2max
a través de estos métodos add_<type>
, ya que tienen la mayoría de los parámetros requeridos integrados en los métodos y puede obtener soporte de finalización IDE. Una vez que se sienta cómodo con los parámetros, utilice la forma abreviada genérica: add
, que requiere menos escritura, pero la desventaja es que pierde la compatibilidad con la finalización de parámetros IDE.
El proyecto tiene algunos scripts que pueden resultar útiles:
convert.py
: convierte maxpat
a yaml
para facilitar la lectura durante el desarrollocompare.py
: compara usando deepdiffcoverage.sh
: ejecuta la cobertura pytest y genera el informe de cobertura htmlTenga en cuenta que si desea construir py2max como una rueda:
pip install build
cd py2max
python3 -m build .
La rueda entonces debería estar en el directorio dist
.
Hay una rama experimental de este proyecto que se basa en el proyecto pydantic2.
Esta variante tiene el beneficio de lo siguiente:
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 )]
Otra dirección prometedora de esta variante es crear clases especializadas para objetos que tengan su propia maxclass
única. Entonces, en este caso, lo anterior quedaría así:
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 )]
Hubo un esfuerzo inicial para proporcionar acceso a atributos basado en propiedades y una API mejorada. Ha sido suplantada por la rama pydantic2
y no se desarrollará más.
Todos los derechos reservados a los respectivos autores originales:
Steve Kieffer, Tim Dwyer, Kim Marriott y Michael Wybrow. HOLA: Diseño de red ortogonal similar al humano. En Visualización y gráficos por computadora, IEEE Transactions on, Volumen 22, Número 1, páginas 349 - 358. IEEE, 2016. DOI
Aric A. Hagberg, Daniel A. Schult y Pieter J. Swart, “Explorando la estructura, dinámica y función de la red usando NetworkX”, en Actas de la 7ma Conferencia Python in Science (SciPy2008), Gäel Varoquaux, Travis Vaught y Jarrod Millman (Eds), (Pasadena, CA, EE. UU.), págs. 11 a 15, agosto de 2008
Una técnica para dibujar gráficos dirigidos Emden R. Gansner, Eleftherios Koutsofios, Stephen C. North, Kiem-phong Vo • IEEE TRANSACTIONS ON SOFTWARE ENGINEERING • Publicado en 1993
Gansner, ER, Koren, Y., North, S. (2005). Dibujo de gráficos por mayorización de tensiones. En: Pach, J. (eds) Dibujo gráfico. GD 2004. Lecture Notes in Computer Science, vol 3383. Springer, Berlín, Heidelberg. https://doi.org/10.1007/978-3-540-31843-9_25
Un sistema de visualización de gráficos abierto y sus aplicaciones a la ingeniería de software Emden R. Gansner, Stephen C. North • SOFTWARE - PRÁCTICA Y EXPERIENCIA • Publicado en 2000