Cap*_*rog 6 matlab udp osc max-msp-jitter puredata
我正在尝试接收通过OSC从Pure Data(或Max/MSP)发送到MATLAB的消息.
这是我从MATLAB发送消息的代码(我使用的是oscmex协议):
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);
Run Code Online (Sandbox Code Playgroud)
如果我使用主机'localhost'发送,一切正常,使用上面的代码从 MATLAB 发送到 MATLAB.如果我将其设置为'127.0.0.1',MATLAB将发送到Pure Data,但MATLAB无法接收自己的消息.
现在为了事情的另一端.这是我的Pure Data补丁:

同样,单独运行上述补丁会成功通过Pure Data发送和接收消息.
问题在于我试图从一个程序谈到另一个程序.如果我设置东西以便MATLAB在端口3333上发送并且Pure Data在3333上接收,并且Pure Data在2222发送并且MATLAB在2222 接收,那么如果MATLAB的主机是'127.0.0.1' ,我可以接收 Pure Data .但是,使用'127.0.0.1',MATLAB无法发送给自己.
在任何情况下,无论我尝试什么,我都无法将纯数据发送到MATLAB,尽管能够将其发送给自己.我怀疑它与"主机"地址有关.
我的实际IPv4地址(使用MS命令提示符的'ipconfig'找到)与127.0.0.1完全不同,并且使用此处指定的值似乎不会使事情更好.
我知道我不能在同一时间打开同一个端口的多个OSC服务器,因此我目前尝试解决方案涉及从一个端口上的MATLAB发送,另一个端口上的Pure Data发送在任一端口上一次打开一台服务器.
注意我也知道我/foo用于来自MATLAB和/testPure Data的消息.但是,我的MATLAB代码不加选择地接收通过OSC发送的所有内容,因此这没有区别.
任何帮助PD与MATLAB交谈的帮助将不胜感激.
更新:我解决了'localhost'问题,这似乎没有解决问题(我必须将localhost添加到我的Windows'主机'文件).所以,我可能因为担心本地主机事而咆哮错误的树.但是,我仍然无法让PD与MATLAB交谈.
更新#2:Amro在下面发布了一个优雅的解决方案,我仍然无法让MATLAB接收来自Pure Data的消息.我已经安装了CloseTheDoor来监控我的UDP连接,并注意到当MATLAB设置服务器时,它使用'Interface' [::0],而PD集使用'Interface' 0.0.0.0.由于PureData是成功接收消息的那个,也许我需要让MATLAB监听0.0.0.0?
首先让我说我以前从未使用过PureData或OSC,我只是复制了你创建服务器/客户端所显示的图形/补丁.
首先让我们在PureData中创建服务器:

现在这里是一个在MATLAB中作为GUI实现的简单客户端:
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
Run Code Online (Sandbox Code Playgroud)

移动滑块时,会将消息发送到服务器(使用OSC-MEX界面),并且值将显示在PureData模型中.
在测试时,我注意到double不支持该类型,因为我在PD日志窗口中看到以下消息:
unpackOSC:PrintTypeTaggedArgs:[64位浮点]未实现
因此,有必要手动将值转换为single或在传递给osc_sendOSC-MEX函数的结构中显式指定提示类型:
val = single(1);
m = struct('path','/test', 'tt','f', 'data',{{val}});
osc_send(osc, m);
Run Code Online (Sandbox Code Playgroud)
同样我们在PureData中创建客户端:

同样,这里是作为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
Run Code Online (Sandbox Code Playgroud)

服务器部分在MATLAB中有点棘手.我们的想法是,我们不希望MATLAB无限期地阻止等待消息.所以我创建了一个每0.11秒执行一次的计时器.在计时器功能内部,我们尝试以阻塞方式接收消息,但超时为0.1秒.这样,GUI和MATLAB IDE都能保持响应.
使用上述解决方案,您还可以在PureData中打开客户端和服务器,或在MATLAB中打开客户端和服务器.它应该以任何方式工作.
最后,我应该说,无论是使用主机名localhost还是直接指定IP地址,都没有区别127.0.0.1.
HTH
我自己设法编译了OSC-MEX包,这里是步骤.首先下载osc-mex 源及其依赖项.这包括:liblo 源代码,pthreads-win32 二进制文件,premake4可执行文件.
1)我们从构建liblo库开始:
premake4 --platform=x32 vs2010include在"其他包含目录"字段中添加包含pthreads头文件的文件夹.同样,添加lib链接器的文件夹,并指定pthreadVC2.lib为附加依赖项.lib\ReleaseLib\liblo.lib请注意,默认情况下,在liblo中禁用IPv6支持,因为像Pd这样的OSC应用程序存在IPv6问题.如果您仍想启用它,请将以下行添加到config.h文件中:
#define ENABLE_IPV6 1
Run Code Online (Sandbox Code Playgroud)
2)接下来我们在MATLAB中编译MEX函数:
liblo.lib从上一步复制到此目录中.也可以pthreadVC2.lib从pthreads库中复制.编译每个函数使用:
mex -largeArrayDims -I../path/to/liblo-0.27 xxxxxx.c pthreadVC2.lib liblo.lib -lwsock32 -lws2_32 -liphlpapi
Run Code Online (Sandbox Code Playgroud)*.mexw32每个xxxxxx.c源文件最终应该有六个文件
pthreadVC2.dll为了省去一些麻烦,这里是使用VS2010 在WinXP 32位和Win8 64位上构建的已编译MEX文件.下面是源代码,如果你想自己编译(简单地构建VS2010解决方案,然后运行osc_make.m在MATLAB)
localhost127.0.0.1是;的别名 它们确实是相同的 IP 地址。因此,如果 matlab 仅在发送至 时收到某些内容localhost,但在发送至 时则不接收某些内容127.0.0.1,则他们可能存在 OSC 的错误实现。
只要你[udpreceive 2222]的补丁中有,Pd就会阻塞端口UDP/2222,并且matlab将无法在该端口上接收任何内容。
所以简单的解决方案是:[udpreceive 2222]在创建 matlab 服务器之前删除使用osc_new_server(2222);