Search code examples
pythonoscsupercollider

python script to send OSC to SuperCollider using Neuroskys mindwave and NeuroPy module


I'm trying to send multiple OSC messages to Supercollider using the variables (1-13) from neuroPy. It works fine with only one variable. How can I utilize more variables.

from NeuroPy import NeuroPy
import time
import OSC

port = 57120
sc = OSC.OSCClient()
sc.connect(('192.168.1.4', port)) #send locally to laptop
object1 = NeuroPy("/dev/rfcomm0")
zero = 0
variable1 = object1.attention
variable2 = object1.meditation
variable3 = object1.rawValue
variable4 = object1.delta
variable5 = object1.theta
variable6 = object1.lowAlpha
variable7 = object1.highAlpha
variable8 = object1.lowBeta
variable9 = object1.highBeta
variable10 = object1.lowGamma
variable11 = object1.midGamma
variable12 = object1.poorSignal
variable13 = object1.blinkStrength


time.sleep(5)

object1.start()

def sendOSC(name, val):
    msg = OSC.OSCMessage()
    msg.setAddress(name)
    msg.append(val)
    try:
        sc.send(msg)
    except:
        pass
    print msg #debug



while True:
    val = variable1
    if val!=zero:
        time.sleep(2)
        sendOSC("/att", val)

This works fine and I get the message in Supercollider as expected.

What can I do to add more variables and get more messages?

I figured it should be something with setCallBack.


Solution

  • You do not need to send multiple OSC messages, you can send one OSC message with all the values in. In fact, this will be a much better way to do it, because all the updated values will arrive synchronously, and less network traffic will be needed.

    Your code currently does the equivalent of

    msg = OSC.OSCMessage()
    msg.setAddress("/att")
    msg.append(object1.attention)
    sc.send(msg)
    

    which is fine for one value. For multiple values you could do the following which is almost the same:

    msg = OSC.OSCMessage()
    msg.setAddress("/neurovals")
    msg.append(object1.attention)
    msg.append(object1.meditation)
    msg.append(object1.rawValue)
    msg.append(object1.delta)
    # ...
    sc.send(msg)
    

    It should be fine, you'll get an OSC message with multiple data in. You can also write the above as

    msg = OSC.OSCMessage()
    msg.setAddress("/neurovals")
    msg.extend([object1.attention, object1.meditation, object1.rawValue, object1.delta])  # plus more vals...
    sc.send(msg)
    

    Look at the documentation for the OSCMessage class to see more examples of how you can construct your message.