/

elektronik.hfbk.net

/

Blog

/

Control VCVRack via OSC

  • en
  • de
  • Control VCVRack via OSC

    written by David Huss

    2021-01-15

    Ever wondered how control VCVRack (a great open source modular synth software) with arbitrary data from a python script?

    There are two parts to this:
    - something in VCVRack to receive OSC Messages
    - something in Python to send OSC Messages

    Receiving side

    Use cvOSCcv by trowaSoft to receive OSC messages. Click the CONFIG-Button and there click the ENABLE Button. Note down the IP and the Receiving Port (in my case 7001) for later use Python.

    Sending side

    This script generates a file filed with data of an n-dimensional random walk (in this case 8-dimensional) which can be used to control 8 parameters in VCVRack and then uses that file to send OSC Messages to VCVRack. The same principle can be used to send any kind of data via OSC (e.g. real time generated data, other data).

    This script uses the python-osc library, which you can install by running pip install python-osc or pip3 install python-osc (depending on your python installation).

    import random
    import time
    from pythonosc import udp_client
    
    
    # Generate random data?
    GENERATE = False
    
    # Where to store/reade the data from?
    DATAPATH = "data.txt"
    
    
    # Only execute the Block below if GENERATE is set to True
    # WARNING: this will overwrite the file at DATAPATH!
    if GENERATE:
        # Number of dimensions of parameters
        n_dimensions = 8
    
        # Fill a dimensions list with n start values of 0.0
        dimensions = [0.0 for d in range(n_dimensions)]
        speed = 0.1
    
        # Open a new file
        with open(DATAPATH, "w") as f:
            # Write this many lines
            for i in range(50000):
                # Change each dimension value by a tiny random amount (a n-dimensional random walk)
                for index, dimension in enumerate(dimensions):
                    dimensions[index] += (random.random()-0.5) * speed
    
                # Convert list of floats to list of str
                str_dimensions = [str(d) for d in dimensions]
    
                # Write the resulting dimensions to a line in file
                f.write(", ".join(str_dimensions)+"\n")
    
        exit()
    
    # Create a UDP Connection.
    client = udp_client.SimpleUDPClient("127.0.0.1", 7001)
    
    # Read data from File
    # So multiple values seperated by commas
    with open(DATAPATH, "r") as f:
        lines = f.readlines()
    
        # Convert list of variables to list of floats
        lines = [[float(x.strip()) for x in line.split(",")] for line in lines]
    
        # For each pair of values on each line
        for values in lines:
            print(values)
            # For each value in that line
            for i, value in enumerate(values):
                # Create a target adress (8 max)
                target_adress = "/ch/{}".format(i+1)
                print("Sending {} to {}".format(value, target_adress))
                client.send_message(target_adress, value)
    
            # Sleep for 0.1 seconds after all channels have been sent
            time.sleep(0.1)