• Products
    • Isadora
    • Get It
    • ADD-ONS
    • IzzyCast
    • Get It
  • Forum
  • Help
  • Werkstatt
  • Newsletter
  • Impressum
  • Dsgvo
  • Press
  • Isadora
  • Get It
  • ADD-ONS
  • IzzyCast
  • Get It
  • Press
  • Dsgvo
  • Impressum

Navigation

    • Register
    • Login
    • Search
    • Categories
    • Recent
    • Popular
    • Tags

    Listening OSC over different ports on ISADORA 4 possible?

    How To... ?
    3
    10
    1043
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • G
      Gaspar last edited by

      Congrats for the release and the hard work!!!

      I've not yet downloaded v4 but have this question

      Is it possible to listen to several ports receiving OSC commands over the network. I'm using more than 1 identical sensors. I can't change their OSC addresses, but the port number. Is this solvable in Isadora 4. Afaik in V3 I can only define one port in preferences and that's it.

      Could this be something to do with the pythoner actor? I have no python knowledge so far, but if @DusX keeps uploading examples maybe this could be a good one.

      In puredata, or max I can just specify several ports and listen to them. The workaround could be listening to several ports in PD and send the variables prepending sensor number over to ISADORA through another port. But this will introduce more lag which is not very desirable.

      If this is not possible I might log it as feature request.

      Cheers

      Windows 10 64bit version 2004, i7 9700, M.2 SSD for system and SSD 2xRaid for data, 32Gb Ram, nVidia RTX 2070 (mobile) | located in Majorca / Spain

      Woland 2 Replies Last reply Reply Quote 0
      • Woland
        Woland Tech Staff @Gaspar last edited by Woland

        @gaspar

        Isadora 4 can still only listen to one OSC port (set in Isadora Preferences), but I don't see a reason that you can't set all the devices to send to port 1234. Isadora will hear them all. It would be the same if you had six computers on a network and you wanted all of them to send data to one Isadora computer. You'd have them all send OSC with whatever address they have to the IP address of the Isadora computer on port 1234.

        Do you have a link to the documentation for the sensors? (It's a strange design decision that there'd be no way other than the port to tell them apart if you're using more than one simultaneously.)

        TroikaTronix Technical Support
        New Support Ticket: https://support.troikatronix.com/support/tickets/new
        Support Policy: https://support.troikatronix.com/support/solutions/articles/13000064762
        Add-Ons: https://troikatronix.com/add-ons/ & https://troikatronix.com/add-ons/?u=woland
        Professional Services: https://support.troikatronix.com/support/solutions/articles/13000109444

        | Isadora Version: all of them | Mac Pro (Late 2013), macOS 10.14.6, 3.5GHz 6-core, 1TB SSD, 64GB RAM, Dual AMD FirePro D700s |

        G 1 Reply Last reply Reply Quote 0
        • Woland
          Woland Tech Staff @Gaspar last edited by

          @gaspar said:

          Could this be something to do with the pythoner actor?

          I went through my emails and dug this up from a past project using Python and OSC (this predates Pythoner)

          important-osc-links.pdf

          As a starting point, I asked ChatGPT:

          Can you write me Python code that lets me listen on a variable number of ports, collects all OSC messages sent from those ports, and then, in real-time, forwards the same OSC messages to the local host on port 1234 with the original port number appended to the original OSC address? I want there to be as little lag as possible.
          Example:
          Sensor 1 sends data to the OSC address "/sensor/data" on port 1111
          Sensor 2 sends data to the OSC address "/sensor/data" on port 2222
          Data collected by Python and forwarded to local host on port 1234 with the OSC addresses "/1111/sensor/data" and "/2222/sensor/data"

          ChatGPT responded: 

          Below is the Python code to achieve this functionality. You'll need the python-osc library, which can be installed using pip install python-osc.
          The code listens on a variable number of ports, collects all OSC messages sent to those ports, and then forwards them to the localhost on port 1234 with the original port number appended to the OSC address.
          from pythonosc import dispatcher
          from pythonosc import osc_server
          from pythonosc import udp_client
          import threading
          # Function to handle incoming OSC messages and forward them
          def forward_message(client, port, address, *args):
              new_address = f"/{port}{address}"
              client.send_message(new_address, args)
              print(f"Forwarded {address} from port {port} to {new_address} with args {args}")
          # Function to create a server for each port
          def create_server(port, client):
              disp = dispatcher.Dispatcher()
              disp.set_default_handler(lambda addr, *args: forward_message(client, port, addr, *args))
              server = osc_server.ThreadingOSCUDPServer(("0.0.0.0", port), disp)
              print(f"Serving on {server.server_address}")
              server.serve_forever()
          # Main function to start servers on multiple ports
          def start_servers(ports):
              client = udp_client.SimpleUDPClient("127.0.0.1", 1234)
              for port in ports:
                  threading.Thread(target=create_server, args=(port, client)).start()
          # List of ports to listen on
          ports_to_listen = [1111, 2222]  # Add more ports as needed
          start_servers(ports_to_listen)
          
          Explanation
          1. forward_message: This function is called whenever an OSC message is received. It modifies the address to include the original port number and sends the message to localhost on port 1234 using the udp_client.
          2. create_server: This function creates an OSC server on the specified port. It uses a dispatcher to handle all incoming messages with forward_message.
          3. start_servers: This function starts servers on all specified ports. It creates a new thread for each server to ensure they can run concurrently.
          4. ports_to_listen: This is the list of ports you want to listen on. You can add or remove ports from this list as needed.
          How to Run
          1. Ensure you have Python installed and python-osc library.
          2. Save the code in a Python file, for example, osc_forwarder.py.
          3. Run the script using python osc_forwarder.py.
          This code will set up listeners on the specified ports, forward incoming OSC messages to port 1234 on localhost, and modify the address to include the original port number. This setup ensures minimal lag by using threading for concurrent processing.

          ChatGPT code isn't always functional right out of the gate, but it's generally a good place to start.

          You could start out just running it in the free, community version of PyCharm and then adapt it for Isadora's Pythoner actor once you have it working.

          TroikaTronix Technical Support
          New Support Ticket: https://support.troikatronix.com/support/tickets/new
          Support Policy: https://support.troikatronix.com/support/solutions/articles/13000064762
          Add-Ons: https://troikatronix.com/add-ons/ & https://troikatronix.com/add-ons/?u=woland
          Professional Services: https://support.troikatronix.com/support/solutions/articles/13000109444

          | Isadora Version: all of them | Mac Pro (Late 2013), macOS 10.14.6, 3.5GHz 6-core, 1TB SSD, 64GB RAM, Dual AMD FirePro D700s |

          1 Reply Last reply Reply Quote 0
          • G
            Gaspar @Woland last edited by

            @woland

            Thanks for replying.

            The sensor is the NGIMU SENSOR. I've got two of them right now. Still playing around, although not in ISADORA but in Ableton over M4L, both new to me.

            This is the link to the manual. 

            https://x-io.co.uk/downloads/N...

            So far I like the sensors.

            Windows 10 64bit version 2004, i7 9700, M.2 SSD for system and SSD 2xRaid for data, 32Gb Ram, nVidia RTX 2070 (mobile) | located in Majorca / Spain

            DusX Woland 2 Replies Last reply Reply Quote 0
            • DusX
              DusX Tech Staff @Gaspar last edited by

              @gaspar

              I spent sometime and put together what appears to be a pretty solid approach to this script.

              We launch a server in a thread to capture incoming OSC, and grab the values from a que (only works with FLOATS right now).
              I may refine this for other data types and add it to the example file. But for now, this should work for you.

              from pythonosc import dispatcher, osc_server
              import threading
              import queue
              import time
              # iz_input 1 "OSC Port"
              # iz_input 2 "OSC Address"
              # iz_input 3 "UDP Address"
              # iz_input 4 "Trigger"
              # iz_output 1 "Received Value"
              osc_values = queue.Queue()  # Use a queue to store received values
              osc_server_thread = None  # To keep track of the server thread
              osc_server_instance = None  # To keep track of the server instance
              last_value = 0.0  # Store the last value to always return a consistent type
              lock = threading.Lock()  # Lock for thread-safe operations
              def osc_handler(address, *args):
                  global osc_values
                  if args and len(args) > 0:
                      with lock:
                          osc_values.put(float(args[0]))  # Ensure the value is always a float
              def start_osc_server(udp_address, port, osc_address):
                  global osc_server_instance
                  try:
                      disp = dispatcher.Dispatcher()
                      disp.map(osc_address, osc_handler)
                      osc_server_instance = osc_server.ThreadingOSCUDPServer((udp_address, int(port)), disp)
                      osc_server_instance.serve_forever()
                  except Exception as e:
                      print(f"Exception in OSC server: {e}")
              def stop_osc_server():
                  global osc_server_thread, osc_server_instance
                  if osc_server_instance:
                      osc_server_instance.shutdown()
                      osc_server_instance.server_close()
                      osc_server_instance = None
                  if osc_server_thread:
                      osc_server_thread.join()
                      osc_server_thread = None
              # python_init is called when the actor is first activated.
              # It requires the same number of parameters input as python_main()
              def python_init(osc_port, osc_address, udp_address, trigger):
                  global osc_server_thread
                  stop_osc_server()  # Ensure any existing server is stopped
                  if osc_server_thread is None:  # Start server only if it isn't already running
                      osc_server_thread = threading.Thread(target=start_osc_server, args=(udp_address, osc_port, osc_address))
                      osc_server_thread.daemon = True
                      osc_server_thread.start()
                  return last_value  # Ensure it returns a consistent type
              # python_main is called whenever an input value changes
              def python_main(osc_port, osc_address, udp_address, trigger):
                  global last_value
                  if trigger:
                      with lock:
                          if not osc_values.empty():
                              last_value = osc_values.get()
                  return last_value  # Always return the last value to ensure consistent output type
              # python_finalize is called just before the actor is deactivated
              def python_finalize():
                  stop_osc_server()
              if __name__ == "__main__":
                  """
                  This section is used to call the python_main() function from an IDE in the same way it would be called
                  once entered into the Pythoner actor. This allows external development of code more easily, because it can be setup
                  to run in your IDE (assuming you link the same VENV)
              
              Generally once the setup matches in both environment you can simply cut and paste the code from your IDE into the
              Pythoner code editor. Your IDE will provide powerful debugging tools that the Pythoner code editor does not.
              This script is a good starting point. If you can run this in your IDE and in Isadora you are off to a good start.
              """
              python_init(123, "/ryan", "127.0.0.1", True)
              try:
                  while True:
                      value = python_main(123, "/ryan", "127.0.0.1", True)
                      if value is not None:
                          print(f"Received value in IDE: {value}")
                      time.sleep(0.1)  # Add a small delay to ensure proper synchronization
              finally:
                  python_finalize()  # Ensure cleanup happens on exit</pre><p><strong>NOTE</strong>: you may need to set this up carefully, since problem occur is ports are closed correctly or you try to open the same port more than once.<br />I have Isadora sending to port 123 and 321 (via OSC Transmit), and I am receiving on both of these (all on localhost) with Pythoner.<br />Use the Trigger to get the last value (I linked a pulse generator to this at 30hz).</p>

              Troikatronix Technical Support

              • New Support Ticket Link: https://support.troikatronix.com/support/tickets/new
              • My Add-ons: https://troikatronix.com/add-ons/?u=dusx
              • Profession Services: https://support.troikatronix.com/support/solutions/articles/13000109444-professional-services

              Running: Win 11 64bit, i7, M.2 PCIe SSD's, 32gb DDR4, nVidia GTX 4070 | located in Ontario Canada.

              G 1 Reply Last reply Reply Quote 1
              • G
                Gaspar @DusX last edited by

                @dusx @Woland

                Thank you both. Looks good I'll give it a try as soon as I get some time to tinker.
                By the way, I stated I could not change the address names of the sensor. Whereas I'm still thinking there's no straight forward way of doing that (can't find a command to do so over the terminal), the GUI and API are open source, so probably it can be done, if you know more than me. I'll ask them directly and report here.


                 

                Windows 10 64bit version 2004, i7 9700, M.2 SSD for system and SSD 2xRaid for data, 32Gb Ram, nVidia RTX 2070 (mobile) | located in Majorca / Spain

                1 Reply Last reply Reply Quote 0
                • Woland
                  Woland Tech Staff @Gaspar last edited by

                  @gaspar said:

                  The sensor is the NGIMU SENSOR.

                  I've just gone to their website and asked them if it's possible to easily change the OSC addresses a sensor uses. I'll let you know as soon as I hear back.

                  Best wishes,

                  L Wilson-Spiro 

                  TroikaTronix Technical Support
                  New Support Ticket: https://support.troikatronix.com/support/tickets/new
                  Support Policy: https://support.troikatronix.com/support/solutions/articles/13000064762
                  Add-Ons: https://troikatronix.com/add-ons/ & https://troikatronix.com/add-ons/?u=woland
                  Professional Services: https://support.troikatronix.com/support/solutions/articles/13000109444

                  | Isadora Version: all of them | Mac Pro (Late 2013), macOS 10.14.6, 3.5GHz 6-core, 1TB SSD, 64GB RAM, Dual AMD FirePro D700s |

                  G 1 Reply Last reply Reply Quote 0
                  • G
                    Gaspar @Woland last edited by

                    @woland

                    The NGIMU guys answered the following:


                    "It is not possible to change the OSC addresses used by the NGIMU.  Multiple NGIMUs are intended to be used by configuring each NGIMU to send to a different UDP port.  For example, 8001 and 8002.  You can change the OSC address using the NGIMU GUI as shown below."

                    Now we're in production and I have no time to test Izzy4. Once I test @DusX approach with the Pythoner I'll report back.

                    Tks.

                    Windows 10 64bit version 2004, i7 9700, M.2 SSD for system and SSD 2xRaid for data, 32Gb Ram, nVidia RTX 2070 (mobile) | located in Majorca / Spain

                    Woland 1 Reply Last reply Reply Quote 0
                    • Woland
                      Woland Tech Staff @Gaspar last edited by Woland

                      I got a similar answer to my email.


                      @gaspar said:

                      You can change the OSC address using the NGIMU GUI as shown below.

                      Did they mean to say "UDP port" instead of "OSC address" here, or can you actually use the NGIMU GUI to change the OSC address?

                      TroikaTronix Technical Support
                      New Support Ticket: https://support.troikatronix.com/support/tickets/new
                      Support Policy: https://support.troikatronix.com/support/solutions/articles/13000064762
                      Add-Ons: https://troikatronix.com/add-ons/ & https://troikatronix.com/add-ons/?u=woland
                      Professional Services: https://support.troikatronix.com/support/solutions/articles/13000109444

                      | Isadora Version: all of them | Mac Pro (Late 2013), macOS 10.14.6, 3.5GHz 6-core, 1TB SSD, 64GB RAM, Dual AMD FirePro D700s |

                      G 1 Reply Last reply Reply Quote 0
                      • G
                        Gaspar @Woland last edited by

                        @woland

                        In the GUI I can change IPs ,  SSIDs + password, and port numbers, but not OSC Adresses. That's surely a unwanted lapsus on their site.

                        As they say, the system is meant to be used by assigning a different port to each sensor.

                        Cheers

                        Windows 10 64bit version 2004, i7 9700, M.2 SSD for system and SSD 2xRaid for data, 32Gb Ram, nVidia RTX 2070 (mobile) | located in Majorca / Spain

                        1 Reply Last reply Reply Quote 1
                        • First post
                          Last post