https://github.com/cansik/duit-osc
Adds OSC communication to duit datafields.
https://github.com/cansik/duit-osc
api duit open-sound-control osc
Last synced: 2 months ago
JSON representation
Adds OSC communication to duit datafields.
- Host: GitHub
- URL: https://github.com/cansik/duit-osc
- Owner: cansik
- License: mit
- Created: 2023-11-23T13:18:33.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2024-11-01T13:43:25.000Z (8 months ago)
- Last Synced: 2025-04-14T08:07:43.233Z (2 months ago)
- Topics: api, duit, open-sound-control, osc
- Language: Python
- Homepage:
- Size: 21.5 KB
- Stars: 1
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# OSC for Duit
[](https://pypi.org/project/duit-osc/)
[
](https://github.com/cansik/duit-osc)Open Sound Control communication for duit datafields.
This is an addon module for the data ui toolkit ([duit](https://github.com/cansik/duit)) which adds OSC in and output support for [DataFields](https://cansik.github.io/duit/duit.html#data-field).
## Installation
The package can ben installed directly from [PyPI](https://pypi.org/project/duit-osc/).```
pip install duit-osc
```## Documentation
Duit-osc uses [python-osc](https://pypi.org/project/python-osc/) (`~=1.8`) as OSC backend to receive and send message. The main class is the `OscService` which handles the incoming and outgoing OSC server and client. It also maps the annotated `DataFields` to the corresponding route.### OscEndpoint
It is possible to annotate existing `DataFields` with the `OscEndpoint` annotation. This annotation later tell the `OscService` if the field has to be exposed over OSC. It is recommended to gather all DataFields in a single object:```python
from duit_osc.OscEndpoint import OscEndpointclass Config:
def __init__(self):
self.name = DataField("Cat") | OscEndpoint()
```By default, the name of the variable (e.g. `name`) is used as OSC address identifier. It is possible to change the name through the `OscEndpoint` annotation.
```python
self.name = DataField("Cat") | OscEndpoint(name="the-cats-name")
```#### Direction
By default, an annotated `DataField` sends out an OSC message on change and is changed by incoming OSC messages. This behaviour can be controlled by the `OscDirection` option of the `OscEndpoint` annotation.```python
from duit_osc.OscDirection import OscDirection# ...
self.name = DataField("Cat") | OscEndpoint(direction=OscDirection.Send)
```- `OscDirection`
- Send - *Does only send the datafield value on change.*
- Receive - *Does only receive the datafield value.*
- Bidirectional (Default) - *Sends and receives the value over OSC*### OscService
As already mentioned, the OscService handles the OSC server and mapping with the `DataFields`. Here is a simple example on how to create an `OscService`, add the previous defined config and start the service.```python
# create an actual instance of the config
config = Config()# create an osc service
osc_service = OscService()# add the config object (create mapping) under the route "/config"
osc_service.add_route("/config", config)# print the api description of the service (experimental)
print(osc_service.api_description())# run the service
osc_service.run()
```#### Settings
The `OscService` has several default arguments, like the `host`, `in_port`, `out_port` and so on. These can be changed before the service is started:
```python
# OscService parameters and the default values
host: str = "0.0.0.0", # on which interface the service is running
in_port: Optional[int] = 8000, # on which port the OscServer is started
out_port: Optional[int] = 9000, # on which port the OscClient is sending
allow_broadcast: bool = True, # if broadcasting is allowed
send_on_receive: bool = False # Indicated if a message that has been received should be also sent out again (reply the change back)
```#### Routes
It is possible to add various objects to the OscService, each with a unique route (address).```python
osc_service.add_route("/config", config)
```Each `DataField` is added under this route, so for example the `name` field would get the OSC address `/config/name`.
#### Receiving Data and Events
On receiving an address that corresponds to a DataField, the arguments of the message are passed as the value to DataField. If no arguments are passed, the `on_change` event of the DataField is fired, or if it's value is a `method`, the method is called.#### Start
To start the service, it is necessary to call `run()`. This is a blocking method, which does not return until the service is shutdown. If it should run as a background thread, use the `run_async()` method:```python
# run blocking
osc_service.run()# run in seperate thread
osc_service.run_async()
```#### API Description
It is possible to print an API description. This is highly experimental and will change in the future:```python
print(osc_service.api_description())
```
## About
Copyright (c) 2024 Florian Bruggisser