Python-OSC: A Pure Python Library for Implementing the OSC Protocol to Interact with Music Devices and Control Applications

Python-OSC is a pure Python library for implementing the Open Sound Control (OSC) protocol. It allows developers to easily interact with various music devices and control applications. This article will detail the features, installation methods, and example code for Python-OSC to help you get started quickly.

Core Features of Python-OSC

Python-OSC provides multiple server and client implementations, including blocking, threaded, forking, and asynchronous servers for both UDP and TCP. Its main features include:

  • Multiple Server Implementations: Supports UDP and TCP protocols, suitable for different application scenarios.

  • Protocol Format Support: Supports OSC 1.0 and 1.1 protocol formats for TCP clients.

  • Rich Data Types: Supports various OSC parameter types, including integers, floats, strings, MIDI, timestamps, etc.

  • Simple Address and Callback Matching System: Users can easily match OSC addresses with handling functions.

  • Response Support: Both servers and clients can send responses from callback handlers.

  • Comprehensive Unit Test Coverage: Ensures the stability and reliability of the library.

Installing Python-OSC

Python-OSC is a pure Python library with no external dependencies. It can be easily installed using the following command:

$ pip install python-osc

Simple Client Example

Below is a simple OSC client example that sends 10 random values to the <span>/filter</span> address, sending one value per second:

import argparse
import random
import time
from pythonosc import udp_client

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("--ip", default="127.0.0.1",help="The ip of the OSC server")
    parser.add_argument("--port",type=int, default=5005,help="The port the OSC server is listening on")
    args = parser.parse_args()

    client = udp_client.SimpleUDPClient(args.ip, args.port)

    for x in range(10):
        client.send_message("/filter", random.random())
        time.sleep(1)

In this example, the client connects to the specified OSC server and sends random values.

Simple Server Example

Below is a simple OSC server example that listens on multiple addresses and prints the received data:

import argparse
import math
from pythonosc.dispatcher import Dispatcher
from pythonosc import osc_server

def print_volume_handler(unused_addr, args, volume):
    print("[{0}] ~ {1}".format(args[0], volume))

def print_compute_handler(unused_addr, args, volume):
    try:
        print("[{0}] ~ {1}".format(args[0], args[1](volume)))
    except ValueError: pass

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("--ip", default="127.0.0.1",help="The ip to listen on")
    parser.add_argument("--port",type=int, default=5005,help="The port to listen on")
    args = parser.parse_args()

    dispatcher = Dispatcher()
    dispatcher.map("/filter", print)
    dispatcher.map("/volume", print_volume_handler, "Volume")
    dispatcher.map("/logvolume", print_compute_handler, "Log volume", math.log)

    server = osc_server.ThreadingOSCUDPServer((args.ip, args.port), dispatcher)
    print("Serving on {}".format(server.server_address))
    server.serve_forever()

This server will listen for messages from clients and output the corresponding values.

Building OSC Bundles

Python-OSC also supports building OSC Bundles, allowing multiple messages to be combined and sent together. Here is an example of building a Bundle:

from pythonosc import osc_bundle_builder
from pythonosc import osc_message_builder

bundle = osc_bundle_builder.OscBundleBuilder(osc_bundle_builder.IMMEDIATELY)
msg = osc_message_builder.OscMessageBuilder(address="/SYNC")
msg.add_arg(4.0)

# Add multiple messages to the Bundle
bundle.add_content(msg.build())
msg.add_arg(2)
bundle.add_content(msg.build())
msg.add_arg("value")
bundle.add_content(msg.build())
msg.add_arg(b"\x01\x02\x03")
bundle.add_content(msg.build())

sub_bundle = bundle.build()
bundle.add_content(sub_bundle)

bundle = bundle.build()

# Send Bundle through client
client.send(bundle)

This example demonstrates how to create and send an OSC Bundle containing multiple messages.

Conclusion

Python-OSC is a powerful and easy-to-use library suitable for any developer looking to interact using the OSC protocol. Whether for simple clients, servers, or more complex message handling, it meets the needs. Through this article’s introduction, we hope you can quickly get started and apply Python-OSC in your projects.

Project address: https://github.com/attwad/python-osc

Leave a Comment