The relationship between pure data and MATLAB using OSC

I am trying to get a message sent through OSC from Pure Data (or Max / MSP) in MATLAB.

  • I can send OSC messages from Pure Data to Pure Data li>
  • I can send messages from MATLAB to MATLAB
  • I can even send messages from MATLAB to Pure Data li>
  • ... I'm really trying to get Pure Data to talk with MATLAB

Here is my code that sends messages from MATLAB (I use the oscmex protocol):

host = 'localhost'; % local host UDP address sendPort = 3333; % UDP port number to send over receivePort = 3333; % UDP port number to receive from oscAddress = osc_new_address(host, sendPort); % open send address oscServer = osc_new_server(receivePort); % open server dataPacket = struct('path','/foo','tt','f','data',{num2cell([1.0])}); % create packet osc_send(oscAddress, dataPacket); % write packet to OSC oscMessage = osc_recv(oscServer, 0.1); % listen for packet on OSC % check to see if anything is there... if length(oscMessage) > 0 fprintf('Found something!') else fprintf('Failed to find anything') end osc_free_address(oscAddress); osc_free_server(oscServer); 

If I send using localhost, everything will go fine from MATLAB to MATLAB using the code above. If I set it to "127.0.0.1", MATLAB will send Pure Data, but MATLAB will not be able to receive its own messages.

Now for the other end of things. Here is my Pure Data patch:

Pure data patch image

Again, running the above patch successfully sends and receives messages through Pure Data.

The problem is that I am trying to speak from one program to another. If I set things up so that MATLAB will send to port 3333 and Pure Data will get to 3333 and that Pure Data will send to 2222 and MATLAB will receive 2222, I can do Pure Data if the MATLAB host is "127.0.0.1", But , with '127.0.0.1', MATLAB cannot send to itself.

In any case, no matter what I try, I cannot make Pure Data send to MATLAB, despite the fact that you can send it to yourself. I suspect this has something to do with the host address.

My actual IPv4 address (found using the "ipconfig" MS command line) is completely different from 127.0.0.1, and using the value provided here does not seem to improve performance.

I know that I cannot have more than one OSC server with the same port open at any given time, and therefore my current attempt at a solution involves sending from MATLAB to one port and sending from Pure Data to another, while on one only one server opens from the ports at a time.

Note. I also know that I use /foo for messages from MATLAB and /test from Pure Data. However, my MATLAB code indiscriminately gets everything sent over OSC, so that doesn't make any difference.

Any help in getting a PD to communicate with MATLAB would be appreciated.

Update: Ive solved the "localhost" problem and it doesn't seem to fix the situation (I had to add localhost to the Windows "hosts" file). Thus, I may have barked the wrong tree, worrying about the subject area. But I still can't get PD to talk to MATLAB.

Update # 2 : Amro posted an elegant solution below, and I still can't get MATLAB to receive messages from Pure Data. I installed CloseTheDoor to monitor my UDP connections and noticed that when MATLAB installs the server, it uses the 't23> interface, while PD sets use "Interface" 0.0.0.0 . Since PureData is the one that successfully receives messages, maybe I need to also listen to MATLAB at 0.0.0.0 ?

+6
source share
2 answers

Let me say that I have never used PureData or OSC before, and I just duplicated the schedule / patch shown to create the server / client.

1) server in PureData, client in MATLAB:

First, create a server in PureData:

server_PD: pastebin.com/hwJzxri2

Now here is a simple client implemented as a GUI in MATLAB:

 function example_osc_client() handles = createGUI(); osc = []; function h = createGUI() h.fig = figure('Menubar','none', 'Resize','off', ... 'CloseRequestFcn',@onClose, ... 'Name','OSC Client', 'Position',[100 100 220 140]); movegui(h.fig, 'center') h.conn = uicontrol('Style','pushbutton', 'String','Connect', ... 'Callback',{@onClick,'connect'}, ... 'Parent',h.fig, 'Position',[20 20 80 20]); h.disconn = uicontrol('Style','pushbutton', 'String','Disconnect', ... 'Callback',{@onClick,'disconnect'}, ... 'Parent',h.fig, 'Position',[120 20 80 20]); h.slid = uicontrol('Style','slider', 'Callback',@onSlide, ... 'Min',-10, 'Max',10, 'Value',0, ... 'Parent',h.fig, 'Position',[30 60 160 20]); h.txt = uicontrol('Style','text', 'String','0.0', ... 'Parent',h.fig, 'Position',[80 100 60 20]); set([h.slid;h.disconn], 'Enable','off'); drawnow end function onClick(~,~,action) switch lower(action) case 'connect' osc = osc_new_address('127.0.0.1', 2222); set(handles.conn, 'Enable','off') set(handles.disconn, 'Enable','on') set(handles.slid, 'Enable','on') case 'disconnect' osc_free_address(osc); osc = []; set(handles.conn, 'Enable','on') set(handles.disconn, 'Enable','off') set(handles.slid, 'Enable','off') end drawnow end function onSlide(~,~) if isempty(osc), return; end val = single(get(handles.slid,'Value')); m = struct('path','/test', 'tt','f', 'data',{{val}}); osc_send(osc, m); set(handles.txt, 'String',num2str(val)) drawnow end function onClose(~,~) if ~isempty(osc) osc_free_address(osc); end delete(handles.fig); end end 

client_MATLAB

When moving the slider, messages are sent to the server (using osc-mex ), and the values ​​are displayed in the PureData Model.

During testing, I noticed that the double type is not supported, because in the PD log window I saw the following message:

unpackOSC: PrintTypeTaggedArgs: [64-bit float] not implemented

Thus, it was necessary either to manually distinguish the values ​​as single , or to explicitly indicate the type of tooltip in the structure passed to osc_send OSC-MEX:

 val = single(1); m = struct('path','/test', 'tt','f', 'data',{{val}}); osc_send(osc, m); 

2) server in MATLAB, client in PureData:

Similarly, we create a client in PureData:

client_PD: pastebin.com/P1KcM00m

Again, here the server is implemented as a MATLAB GUI:

 function example_osc_server() handles = createGUI(); osc = []; function h = createGUI() h.fig = figure('Menubar','none', 'Resize','off', ... 'CloseRequestFcn',@onClose, ... 'Name','OSC Server', 'Position',[100 100 220 140]); movegui(h.fig, 'center') h.start = uicontrol('Style','pushbutton', 'String','Start', ... 'Callback',{@onClick,'start'}, ... 'Parent',h.fig, 'Position',[20 20 80 20]); h.stop = uicontrol('Style','pushbutton', 'String','Stop', ... 'Callback',{@onClick,'stop'}, ... 'Parent',h.fig, 'Position',[120 20 80 20]); h.txt = uicontrol('Style','text', 'String','', ... 'Parent',h.fig, 'Position',[60 80 100 20]); set(h.stop, 'Enable','off'); drawnow expose h.timer = timer('TimerFcn',@receive, 'BusyMode','drop', ... 'ExecutionMode','fixedRate', 'Period',0.11); end function onClick(~,~,action) switch lower(action) case 'start' set(handles.start, 'Enable','off') set(handles.stop, 'Enable','on') osc = osc_new_server(2222); start(handles.timer); case 'stop' set(handles.start, 'Enable','on') set(handles.stop, 'Enable','off') osc_free_server(osc); osc = []; stop(handles.timer); end drawnow expose end function receive(~,~) if isempty(osc), return; end m = osc_recv(osc, 0.1); if isempty(m), return; end set(handles.txt, 'String',num2str(m{1}.data{1})) drawnow expose end function onClose(~,~) if ~isempty(osc) osc_free_server(osc); end stop(handles.timer); delete(handles.timer); delete(handles.fig); clear handles osc end end 

server_MATLAB

The server side was a bit more complicated in MATLAB. The idea is that we do not want MATLAB to block endless waiting for messages. So I created a timer that runs every 0.11 seconds. Inside the timer function, we are trying to get the message in a blocking way, but with a timeout of 0.1 s. In this way, both the GUI and the MATLAB IDE remain responsive.


3) other combinations:

Using the solutions above, you can also open both the client and server in PureData or both the client and server in MATLAB. It should work anyway.

Finally, I have to say that it doesn’t matter if I use the host name as localhost or directly specify the IP address 127.0.0.1 .

NTN


EDIT:

I managed to build the OSC-MEX package myself, here are the steps. First download the osc-mex sources and its dependencies. This includes: liblo sources , pthreads-win32 binaries , premake4 executable.

1) Let's start by creating the liblo library:

  • Copy "premake4.exe" to the "build" directory and run: premake4 --platform=x32 vs2010
  • open the generated liblo.sln solution file in VS2010. Select the "liblo" project and go to "Project> Properties". Add an include folder containing the pthreads header files in the "Include Additional Directories" box. Similarly, add the lib folder for the linker and specify pthreadVC2.lib as an additional dependency.
  • Select the target "ReleaseLib" Win32 and create a project. This should create the final goal: lib\ReleaseLib\liblo.lib

Note that by default , IPv6 support is disabled in liblo because OSC applications like Pd have problems with IPv6. If you still want to enable it, add the following line to the config.h file:

 #define ENABLE_IPV6 1 

2) Next, we compile MEX functions in MATLAB:

  • Go to the folder containing the C-sources of the MEX functions
  • copy liblo.lib from the previous step to this directory. Also copy pthreadVC2.lib from the pthreads library.
  • compile each function using:

     mex -largeArrayDims -I../path/to/liblo-0.27 xxxxxx.c pthreadVC2.lib liblo.lib -lwsock32 -lws2_32 -liphlpapi 
  • You should get six *.mexw32 files for each of the xxxxxx.c source files

  • Finally copy the pthreads dll into the same folder: pthreadVC2.dll

To save you trouble, here are the compiled MEX files created on WinXP 32-bit and Win8 64-bit using VS2010. Here are the sources if you want to compile it yourself (just create a solution in VS2010, then run osc_make.m in MATLAB)

+5
source

localhost is an alias for 127.0.0.1 ; they really are the same IP address. therefore, if Matlab only gets something, if it sends to localhost , but not when it sends to 127.0.0.1 , they probably have an incorrect OSC implementation.

as long as you have [udpreceive 2222] in your patch, Pd will block the UDP / 2222 port and Matlab will not be able to get anything on this port.

therefore a simple solution: remove [udpreceive 2222] before creating the matlab server using osc_new_server(2222);

0
source

Source: https://habr.com/ru/post/947172/


All Articles