Erik Sven Broberg
Erik Sven Broberg

Reputation: 125

OSC proper fader control algorithm

I am coding in python 2.7 to accommodate OSC communication from my ipad to my rasp pi using the 'touchOSC' app from the app store. (this is not for music or midi, but simply to access values to control stepper motors etc..) I am using windows to code and then I transfer the .py to my rasp pi (not the issue here). I set up the fader in touch OSC's layout software with the name, IP address that is in the code below. Also, I set the range value of the fader in the software that touchOSC has provided from 0 to 1.

The issue is that I am receiving only zeros when I invoke the fader on my ipad. What I wish to see is the values incrementing from 0 to 1 by floating values. I believe I would need to use some sort range function? This is the issue, How can specify that I want the fader to increment in the code below?

Right now the code is:

from OSC import OSCServer,OSCClient, OSCMessage

server = OSCServer( ("192.168.0.8", 8000) ) 
client = OSCClient()

def handle_timeout(self):
    print ("I'm IDLE")
#This here is just to do something while the script recieves no information....
server.handle_timeout = types.MethodType(handle_timeout, server)

def fader_0(path, tags, args, source): 
    value=int(args[0]) # Value is the variable that will transform the input from the faders into whole numbers(easier to deal with)
    print "Fader Value:", value

server.addMsgHandler("/1/fader1", fader)

My question regards the Def fader_0(path, tags, args, source) When I input: value = int(args[0]), I receive a zero when I adjust the fader on my ipad via touch OSC. this is obvious; however, I wish to access the floating points in between 0 and 1 as the fader is incremented.

I assume the code would be: value = float(args[someLoop]) maybe something like value = float(args[range(0,1,.125)])

Thank you in advance.

Upvotes: 0

Views: 490

Answers (2)

sfscs
sfscs

Reputation: 535

I think you might be looking for a linear interpolation function. You can have TouchOSC translate the float value to discrete values before sending.

To do this use a function that maps a value from 0 to 1 to a range that you want like this:

function lerp(min, max, percent)
  return math.floor(min + (max - min) * percent)
end

Where

  • min is smallest value you want sent
  • max is the largest value you want sent
  • percent is a value between 0 and 1

For example lerp(1, 128, someFloat)

Coding it in TouchOSC

Since we want to modify the value before sending, we will need to define the controller's onValueChanged callback, which is called whenever the controller is moved.

Keep in mind that TouchOSC doesn't automatically distinguish number types when it sends over OSC so to send an integer you must use the argument type tags format.

Putting that all together, this is what the script for your control could look like. In this example you would send values from 1 to 256, though you can use whatever range you want:

function lerp(min, max, percent)
  return math.floor(min + (max - min) * percent)
end

function onValueChanged(key)
    if key == 'x' then
      local scaled = lerp(1, 256, self.values['x'])
      sendOSC({
        '/1/fader1', 
        {
            { tag = 'i', value = scaled }
        }
      });
    end
end

Upvotes: 0

Charles Martin
Charles Martin

Reputation: 358

The values coming from TouchOSC are floats between 0 and 1. In the fader_0 function, you currently transform the float from TouchOSC, args[0] to an int which rounds any number less than 1 down to 0, thus your program prints out zero every time.

You can easy see how this happens in the python interpreter:

In [2]: int(0.7)
Out[2]: 0

The solution is just to remove the int function from fader_0 like so:

def fader_0(path, tags, args, source): 
    value=args[0]
    print "Fader Value:", value

Upvotes: 0

Related Questions