Package: elkpy
Sushi - gRPC controller wrapperA simple wrapper for controlling sushi over gRPC via a python script.PrerequisitesTo use this wrapper,python3.7or greater needs to be installed, together with thegrpcio-toolsPython package. Both are installed by default in the development releases of Elk for the various supported architectures.InstallationIf you are running your Python program on a device running Elk Audio OS, the latestelkpyshould already be installed.But, if you use elkpy on another system, e.g. macOS, you can either copy the module folder to the directory where it will be used, or install it locally withpip3 install -e elkpyor similar.elkpyis also available on Pypi:pip install elkpy.UsageFirst import the sushicontroller package, e.g.:fromelkpyimportsushicontrollerasscThen create an instance of theSushiControllerobject:controller=sc.SushiController()The default gRPC address islocalhost:51051.
To connect to another address, pass it as an argument to the constructor of the controller with the formatip-address:port.The second argument to the constructor of SushiController is a path to thesushi_rpc.protofile, which contains Sushi's Protobuf protocol definition.
If the argument is empty, the class will look for it atusr/share/sushi/sushi_rpc.proto, the default installation path for Sushi.To use the controller simply use the methods of the controller objects different sections. For example:# To make sure all the sub-controllers of SushiController close properly, you can wrap them in a try except block:try:# Get a list of the tracks available in sushilist_of_tracks=controller.audio_graph.get_tracks()# Get the parameters of the track with the id passed to the methodtrack_id=0list_of_processors=controller.parameters.get_track_parameters(track_id)# Send a note on message to a track in sushitrack_id=0channel=0note=65velocity=0.8controller.keyboard.send_note_on(track_id,channel,note,velocity)# To ensure proper closing of SushiController, close() should be called on your instance when you're done using itexceptKeyboardInterrupt:controller.close()For full documentation on all available methods, use:$pydoc3elkpy.sushicontroller.SushiControllerOn the terminal where the elkpy folder is located.Important notes on return valuesTo maintain proper management of the audio thread, Sushi uses an internal queue for commands passed to it via gRPC. This means that it can not return anything else than a standard -but of limited use- response.It is assumed that the user will use Sushi's notification system (seenotificationcontroller.py) to confirm that their commands have been carried out correctly!Convenience for asyncio programs - EXPERIMENTALTo alleviate this burden forsimpleuse-cases,elkpyadopts the following behavior, available to asyncio users:Commands that edit the audio graph:create_trackdelete_trackcreate_processor_on_trackdelete_processor_from_trackreturn anElkpyEvent: an asyncio.Event that will besetbyelkpywhenever the corresponding notification is emitted by Sushi.An asyncio user can elect toawait ElkpyEvent.wait()to ensure that the command has been properly carried out.
Ignoring the event is also a valid option for cases where absolute confirmation is not critical.Purely synchronous programs have to implement their own systems to confirm that Sushi is indeed in the state they are expecting.For more information aboutasyncio.Event: [https://docs.python.org/3/library/asyncio-sync.html]ExamplesTheexamplessubdirectory contains examples of how elkpy can be used.Sushi Control ExampleThis demonstrates instantiating 3 processors onto Sushi started with an “empty” config, subscribing to notifications to wait for their instantiation, and then setting their parameters once they're available.To run:Ensure you have a Python environment set up where the packages described in requirements.txt are available, globally or in avenv.Start Sushi with the provided "sushi_control_example_config.json", and the '--base-plugin-path' set to point to wheremda-vst.vst3plugins are available:$ ./sushi --portaudio \
          --config-file /path/to/elkpy/examples/sushi_control_example_config.json \
          --base-plugin-path=/path/to/sushi/build/debug/VST3/Debug/If you've built Sushi from source, the plugins are built and accessible in the above path relative to the sushi binary.Startsushi_control_example.py:$ python3 ./sushi_control_example.py --protofile "/path/to/sushi/rpc_interface/protos/sushi_rpc.proto"The--protofileargument points elkpy to the protocol buffer file used by Sushi.You should hear Sushi play a familiar theme tune.Sushi MonitorAn example passive monitor app using elkpy.
It connects to a sushi instance, subscribes to notifications and displays all the parameter, transport and audio graph changes that Sushi broadcasts.UsageEnsure there is a Sushi instance running on the same computer.Then run:$ export SUSHI_GRPC_ELKPY_PROTO=./sushi_rpc.proto
$ python3 examples/sushi_monitor.pyRunning Unit TestsBefore running unit tests with the unittest command-line interface, you need to export the environment variableSUSHI_GRPC_ELKPY_PROTO, pointing to the Sushi's.protodefinition file.Example:$ export SUSHI_GRPC_ELKPY_PROTO=./sushi_rpc.proto
$ python3 -m unittest discover -s tests -p '*_test.py'