Une bibliothèque python3 pure sans dépendances destinée à faciliter la génération hors ligne des fichiers Max patcher ( .maxpat
, .maxhelp
, .rbnopat
).
Si vous recherchez des externes python3 pour Max/MSP, consultez le projet py-js.
Génération hors ligne scriptée de fichiers Max Patcher à l'aide d'objets Python, correspondant, sur une base individuelle, aux objets Max/MSP stockés dans le format de fichier basé sur .maxpat
JSON.
Conversion aller-retour entre les fichiers (JSON) .maxpat
avec des niveaux arbitraires d'imbrication et les objets Python Patcher
, Box
et Patchline
correspondants.
Peut potentiellement gérer n’importe quel objet Max ou maxclass.
Beaucoup de tests unitaires, couverture d'environ 99 %.
Analyse et modification scriptée hors ligne des patchs Max en termes de composition, de structure (sous forme de graphiques d'objets), de propriétés d'objets et de disposition (à l'aide d'algorithmes de dessin de graphiques).
Permet une disposition et une configuration précises des objets Max.
Les objets Patcher
ont des méthodes génériques telles que add_textbox
et peuvent également avoir des méthodes spécialisées telles que add_coll
. À titre d'exemple, cette méthode a un argument dictionary
pour faciliter le pré-remplissement de l'objet coll
(voir py2max/tests/test_coll.py
).
Fournit une fonctionnalité maxclassdb
qui rappelle les configurations par défaut de Max Objects.
Création de fichiers de correctifs scriptés.
Modification par lots des fichiers .maxpat existants.
Utilisez la riche bibliothèque standard et l'écosystème Python pour créer des objets paramétrables avec une configuration à partir de sources hors ligne. Par exemple, des oscillateurs à table d'ondes uniques configurés à partir de fichiers de tables d'ondes aléatoires.
Génération de cas de tests et de fichiers .maxhelp
lors du développement externe
Simplifie la création d'objets avec de nombreux paramètres
Préremplir les objets conteneurs tels que les objets coll
, dict
et table
avec des données
Aide à gagner du temps en créant de nombreux objets avec des arguments légèrement différents
Utilisez des algorithmes de dessin/mise en page graphique sur les correctifs générés.
Génération de correctifs génératifs (-;
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 ()
Par défaut, les objets sont renvoyés (y compris les lignes de patch) et les sorties et entrées des lignes de patch sont définies sur 0. Bien que les objets renvoyés soient utiles pour la liaison, les lignes de patch renvoyées ne le sont pas. Par conséquent, ce qui précède peut être écrit de manière plus concise comme suit :
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 ()
Avec les alias intégrés ( .add
pour les méthodes de type .add_*
et .link
pour .add_line
), l'exemple ci-dessus peut être écrit sous une forme encore plus abrégée (et avec une disposition verticale) comme :
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 ()
De plus, vous pouvez analyser les fichiers .maxpat
existants, les modifier puis enregistrer les modifications :
p = Patcher . from_file ( 'example1.maxpat' )
# ... make some change
p . save_as ( 'example1_mod.maxpat' )
Autre exemple avec des sous-patcheurs :
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 ()
Notez que les classes Python ne sont fondamentalement que de simples wrappers autour des structures JSON dans un fichier .maxpat, et presque tous les objets Max/MSP et Jitter peuvent être ajoutés au fichier patcher avec la .add_textbox
ou les méthodes génériques .add
. Il existe également des méthodes spécialisées sous la forme .add_<type>
pour les nombres, les paramètres numériques, les sous-patcheurs et les objets de type conteneur (voir les notes de conception ci-dessous pour plus de détails).
Manière la plus simple :
git https://github.com/shakfu/py2max.git
cd py2max
pip install . # optional
Notez que py2max n'a pas besoin d'être installé pour être utilisé, vous pouvez donc ignorer le pip install .
part si vous préférez, cd
simplement le répertoire cloné et commencez à l'utiliser :
$ 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
dispose d'une suite de tests complète avec des tests dans le dossier py2max/tests
.
On peut exécuter tous les tests comme suit :
pytest
Cela affichera les résultats de tous les tests dans le dossier outputs
.
Notez que certains tests peuvent être ignorés si un package requis pour le test ne peut pas être importé.
Vous pouvez vérifier quel test est ignoré comme suit :
pytest -v
Pour vérifier la couverture du test :
./scripts/coverage.sh
qui fait essentiellement ce qui suit
mkdir -p outputs
pytest --cov-report html:outputs/_covhtml --cov=py2max tests
Pour exécuter un test individuel :
python3 -m pytest tests.test_basic
Notez que comme py2max
traite principalement de la génération et de la manipulation json
, la plupart des tests n'ont aucune dépendance puisque json
est déjà intégré à stdlib.
Cependant, de nombreux tests explorent l'application d'algorithmes de disposition de graphes orthogonaux et pour cela, tout un tas de packages ont été utilisés, qui vont du plus connu à l'ésotérique.
Comme mentionné ci-dessus, pytest ignorera un test si les packages requis ne sont pas installés, ce sont donc des tests entièrement facultatifs.
Si vous insistez pour plonger dans le terrier du lapin et souhaitez exécuter tous les tests, vous aurez besoin des packages suivants (et de leurs dépendances) :
pip install networkx
pip install matplotlib
brew install graphviz
) - vous pouvez alors pip install pygraphviz
Les documents API ne sont toujours pas disponibles
L'algorithme de mise en page par défaut actuel est extrêmement rudimentaire, mais il existe des directions prometteuses et vous pouvez également voir une comparaison visuelle de la performance des différents algorithmes de mise en page dans ce contexte.
Bien que la génération ne consomme pas les objets py2max, Max n'actualise malheureusement pas le fichier lorsqu'il est ouvert, vous devrez donc continuer à fermer et rouvrir Max pour voir les modifications apportées à l'arborescence des objets.
Pour les quelques objets qui ont leurs propres méthodes, l'implémentation actuelle différencie les objets tilde des objets non-tilde en fournissant une méthode différente avec un suffixe _tilde
:
gen = p . add_gen ()
gen_tilde = p . add_gen_tilde ()
Le format .maxpat
JSON est en fait assez minimal et hiérarchique. Il a un parent Patcher
et des entrées enfants Box
ainsi que Patchlines
. Certaines boîtes contiennent d'autres instances patcher
pour représenter les sous-patcheurs et les patchs gen~
imbriqués, etc.
La structure ci-dessus correspond directement à l'implémentation Python qui se compose de 3 classes : Patcher
, Box
et Patchline
. Ces classes sont extensibles via leurs structures **kwds
et internes __dict__
respectives. En fait, c’est ainsi que la méthode de classe .from_file
patcher est implémentée.
Cela s'avère être le moyen le plus maintenable et le plus flexible de gérer toutes les différences entre les centaines d'objets Max, MSP et Jitter.
Une liste croissante de méthodes de patcher ont été implémentées pour spécialiser et faciliter la création de certaines classes d'objets nécessitant une configuration supplémentaire :
.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
Il s'agit d'une courte liste, mais la méthode add_textbox
à elle seule peut gérer presque tous les cas. Les autres ne sont là que pour plus de commodité et pour économiser la saisie.
Généralement, il est recommandé de commencer à utiliser py2max
via ces méthodes add_<type>
, car elles intègrent la plupart des paramètres requis dans les méthodes et vous pouvez obtenir une prise en charge de l'achèvement de l'IDE. Une fois que vous êtes à l'aise avec les paramètres, utilisez la forme abrégée générique : add
, qui est moins typée mais le compromis est que vous perdez la prise en charge de la complétion des paramètres IDE.
Le projet contient quelques scripts qui peuvent être utiles :
convert.py
: convertissez maxpat
en yaml
pour faciliter la lecture pendant le développementcompare.py
: comparer en utilisant deepdiffcoverage.sh
: exécutez la couverture pytest et générez un rapport de couverture HTMLNotez que si vous souhaitez construire py2max sous forme de roue :
pip install build
cd py2max
python3 -m build .
La roue devrait alors être dans le répertoire dist
.
Il existe une branche expérimentale de ce projet qui est basée sur le projet pydantic2.
Cette variante présente les avantages suivants :
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 )]
Une autre direction prometteuse de cette variante est de créer des classes spécialisées pour les objets qui ont leur propre maxclass
unique. Donc, dans ce cas, ce qui précède se lirait :
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 )]
Il y a eu un premier effort pour fournir un accès aux attributs basé sur la propriété et une API améliorée. Elle a été supplantée par la branche pydantic2
et ne sera pas développée davantage.
Tous droits réservés aux auteurs originaux respectifs :
Steve Kieffer, Tim Dwyer, Kim Marriott et Michael Wybrow. HOLA : disposition de réseau orthogonal de type humain. Dans Visualisation et infographie, IEEE Transactions on, Volume 22, Numéro 1, pages 349 - 358. IEEE, 2016. DOI
Aric A. Hagberg, Daniel A. Schult et Pieter J. Swart, « Explorer la structure, la dynamique et la fonction du réseau à l'aide de NetworkX », dans Actes de la 7e conférence Python in Science (SciPy2008), Gäel Varoquaux, Travis Vaught et Jarrod Millman (Eds), (Pasadena, CA USA), pp. 11-15, août 2008
Une technique pour dessiner des graphiques dirigés Emden R. Gansner, Eleftherios Koutsofios, Stephen C. North, Kiem-phong Vo • TRANSACTIONS IEEE SUR LE GÉNIE LOGICIEL • Publié en 1993
Gansner, ER, Koren, Y., North, S. (2005). Dessin graphique par majoration des contraintes. Dans : Pach, J. (éd.) Graph Drawing. GD 2004. Notes de cours en informatique, vol 3383. Springer, Berlin, Heidelberg. https://doi.org/10.1007/978-3-540-31843-9_25
Un système ouvert de visualisation de graphes et ses applications au génie logiciel Emden R. Gansner, Stephen C. North • LOGICIEL - PRATIQUE ET EXPÉRIENCE • Publié en 2000