/

elektronik.hfbk.net

/

Blog

/

VCVRack mit OSC steuern

  • en
  • de
  • VCVRack mit OSC steuern

    written by David Huss

    2021-01-15

    Wie VSVRack Synthies mit Daten von Python aus steuern?

    Die Lösung besteht aus zwei Teilen:
    - etwas in VCVRack um OSC Nachrichten zu empfangen
    - etwas in Python um OSC Nachrichten zu senden

    Empfänger

    Das Modul cvOSCcv von trowaSoft lässt sich dazu nutzen um OSC-Nachrichten zu empfangen. Über den CONFIG-Button und einen Klick auf den ENABLE-Button lässt sich OSC anstarten. Die IP-Adresse und der Empfangende Port (in meinem Fall 7001) muss später im Python Script verwendet werden.

    Sender

    Diser Script generiert eine Textdatei gefüllt mit einem n-dimensionalen Random Walk, der dann verwendet werden kann um 8 Parameter im VCVRack zu steuern. Die so befüllte Datei wird dann in weiterer Folge ausgelesen, OSC-Nachrichten werden gebaut und an VCVRack geschickt. Das selbe Prinzip kann verwendet werden um alle möglichen Arten von Daten via OSC zu verschicken.

    Dieser Script verwendet die python-osc library, die via Command Line mit pip install python-osc oder pip3 install python-osc installiert werden kann (abhängig davon welche Python version wie installiert wurde).

    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)