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)