Package: py-pyper
pyperpyperis a python package for constructing REAPER session with native python constructs. The majority of the interface is a reflection of the.rppfile structure which itself is very similar to.xmlwith tags and elements (except each element is called a 'chunk'). As such, you may need to know a bit about the underlying structure of REAPER's file format before using something like this. A good way to do this is to make a REAPER project and open the project in a text editor. You might also refer tothis documentwhich is fairly exhaustive.installationYou cangit clonethis repo,cdto it and then install viapip install -e pyper. You need to pointpipto the folder containing setup.py, not the parent folder with examples and README.md etc.You can alsopip install py-pyper.usagepyperexposes objects for each type of 'chunk' or as I've called itnodein the graph of objects in a session. A very simple example of a REAPER project with a single track would go as follows.frompyper.nodesimport*# import all of the pyper nodesproject=Project(# create an instance of a projectTrack()# and pass a Track() object to the constructor)project.write("basic.rpp")# write the project out to the pathWe can construct such graphs in a variety of ways which lendspypertowards programmatic constructions of projects.# Using Loopsfrompyper.nodesimport*project=Project()# create an instance of a projectforxinrange(1024):project.add(Track())# use the add method of the project to add a Track()project.write("loops.rpp")# write the project out to the path# Comprehensionsfrompyper.nodesimport*tracks=[Track()forxinrange(100)]project=Project(*tracks)project.write("comprehensions.rpp")# write the project out to the pathA more complex example might be to arrange a series of sound files randomly along a single track, similar to a granular synthesiser. This example presents newpypernodes you won't have seen beforefrompyper.nodesimportProject,Track,Item,Source# note new nodes Item() and Source()frompathlibimportPathimportrandomsources=[]# create a source object for each of the .wav files in a directory (can you tell I love comprehensions)sources=[Source(file=f'{str(x)}')forxinPath('my-sounds').rglob("*.wav")# you would point it to an actual folder of sounds, not just 'my-sounds']track=Track()# create a blank Track()pos=0.0# set our initial position to 0forxinrange(1000):# 1000 grainsgrain=random.choice(sources)# random file from our sourceslength=random.uniform(0.1,0.5)# random length of the itemtrack.add(Item(grain,# Item()'s have a child Source() node, which is randomly selected aboveposition=pos,# and we set the positionlength=length# and we set the length))pos+=length# increment the position by the length to create contiguous blocksproject=Project(track)# create the project with our composed trackproject.write("granular.rpp")# write it outpropsIn the.rppstructure each 'chunk' can have various properties. For example, theITEMchunk will have length and position properties that determine where in the timeline the item is positioned and the duration of the item. I don't want to implement functions for each of these so there are ways to insert arbitrary properties for each 'chunk', or what you are now familiar with as apyper'node'.# modifiying properties with function argumentsfrompyper.nodesimport*item=Item(length=10,position=0.5)# create a blank item 10 seconds in length a 0.5 seconds in the timeline# the convention is you match the word of the property as lower case.# if the property in the file is LENGTH, then the function argument is 'length'track=Track(item)project=Project(track)project.write("properties1.rpp")# write the project out to the path# modifiying properties by directly modifying the .props of the objectfrompyper.nodesimport*item=Item()# create a blank item 10 seconds in length a 0.5 seconds in the timelineitem.props={"LENGTH":10,"POSITION":0.5}track=Track(item)project=Project(track)project.write("properties1.rpp")# write the project out to the path