ไลบรารี่ python3 ล้วนๆ ที่ไม่มีการขึ้นต่อกันที่มีจุดประสงค์เพื่ออำนวยความสะดวกในการสร้างไฟล์ Max patcher แบบออฟไลน์ ( .maxpat
, .maxhelp
, .rbnopat
)
หากคุณกำลังมองหา python3 ภายนอกสำหรับ Max/MSP ลองดูโปรเจ็กต์ py-js
การสร้างไฟล์ Max patcher แบบออฟไลน์ โดยใช้สคริปต์โดยใช้อ็อบเจ็กต์ Python ที่สอดคล้องกันแบบหนึ่งต่อหนึ่ง โดยมีอ็อบเจ็กต์ Max/MSP จัดเก็บในรูปแบบไฟล์ที่ใช้ . .maxpat
JSON
การแปลงไปกลับ ระหว่างไฟล์ (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
ด้วยข้อมูล
ช่วยประหยัดเวลาในการสร้างวัตถุจำนวนมากที่มีข้อโต้แย้งที่แตกต่างกันเล็กน้อย
ใช้อัลกอริธึมการวาดกราฟ / เค้าโครงบนแพตช์ที่สร้างขึ้น
การสร้างแพทช์ทั่วไป (-;
ฯลฯ
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' )
อีกตัวอย่างหนึ่งที่มี subpatchers:
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 นั้นโดยพื้นฐานแล้วเป็นเพียงการห่อหุ้มอย่างง่าย ๆ รอบ ๆ โครงสร้าง JSON ในไฟล์ .maxpat และคุณสามารถเพิ่มอ็อบเจ็กต์ Max/MSP และ Jitter เกือบทั้งหมดลงในไฟล์ patcher ได้โดยใช้เมธอด .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
อื่น ๆ เพื่อแสดง subpatchers ที่ซ้อนกันและ gen~
patch ฯลฯ
โครงสร้างด้านบนแมปโดยตรงกับการใช้งาน Python ซึ่งประกอบด้วย 3 คลาส: Patcher
, Box
และ Patchline
คลาสเหล่านี้สามารถขยายได้ผ่าน **kwds
และโครงสร้าง __dict__
ภายในตามลำดับ อันที่จริง นี่คือวิธีการใช้คลาสเมธอด . .from_file
patcher
นี่กลายเป็นวิธีที่บำรุงรักษาได้และยืดหยุ่นที่สุดในการจัดการความแตกต่างทั้งหมดระหว่างออบเจ็กต์ Max, MSP และ Jitter นับร้อยรายการ
รายการวิธี patcher ที่เพิ่มขึ้นได้ถูกนำมาใช้เพื่อเชี่ยวชาญและอำนวยความสะดวกในการสร้างคลาสของอ็อบเจ็กต์บางประเภทที่ต้องมีการกำหนดค่าเพิ่มเติม:
.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
เพียงอย่างเดียวสามารถรองรับได้เกือบทุกกรณี ส่วนอื่นๆ ก็มีไว้เพื่อความสะดวกและประหยัดการพิมพ์เท่านั้น
โดยทั่วไป ขอแนะนำให้เริ่มใช้ py2max
ผ่านเมธอด add_<type>
เหล่านี้ เนื่องจากมีพารามิเตอร์ที่จำเป็นส่วนใหญ่อยู่ในเมธอด และคุณสามารถรับการสนับสนุน IDE ที่สมบูรณ์ได้ เมื่อคุณพอใจกับพารามิเตอร์แล้ว ใช้รูปแบบย่อทั่วไป: add
ซึ่งพิมพ์ได้น้อยกว่า แต่การแลกเปลี่ยนคือคุณจะสูญเสียการสนับสนุนพารามิเตอร์ IDE ให้สมบูรณ์
โครงการนี้มีสคริปต์บางส่วนที่อาจมีประโยชน์:
convert.py
: แปลง maxpat
เป็น yaml
เพื่อความสะดวกในการอ่านระหว่างการพัฒนาcompare.py
: เปรียบเทียบโดยใช้ deepdiffcoverage.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 บน เล่มที่ 22 ฉบับที่ 1 หน้า 349 - 358 IEEE, 2016 DOI
Aric A. Hagberg, Daniel A. Schult และ Pieter J. Swart, “การสำรวจโครงสร้างเครือข่าย ไดนามิก และฟังก์ชันโดยใช้ NetworkX” ใน Proceedings of the 7th Python in Science Conference (SciPy2008), Gäel Varoquaux, Travis Vaught และ Jarrod Millman (บรรณาธิการ), (Pasadena, CA USA), หน้า 11–15, ส.ค. 2551
เทคนิคการวาดกราฟกำกับ Emden R. Gansner, Eleftherios Koutsofios, Stephen C. North, Kiem-phong Vo • ธุรกรรม IEEE เกี่ยวกับวิศวกรรมซอฟต์แวร์ • ตีพิมพ์ 1993
Gansner, ER, Koren, Y., North, S. (2005) การวาดกราฟโดยเน้นความเครียด ใน: Pach, J. (eds) การวาดกราฟ. GD 2004. Lecture Notes in Computer Science, vol 3383. สปริงเกอร์, เบอร์ลิน, ไฮเดลเบิร์ก https://doi.org/10.1007/978-3-540-31843-9_25
ระบบแสดงภาพกราฟแบบเปิดและการประยุกต์ใช้กับวิศวกรรมซอฟต์แวร์ Emden R. Gansner, Stephen C. North • ซอฟต์แวร์ - การปฏิบัติและประสบการณ์ • เผยแพร่ในปี 2000