首先让我说我以前从未使用过PureData或 OSC,我只是复制了您展示的图形/补丁来创建服务器/客户端。
1) PureData 中的服务器,MATLAB 中的客户端:
首先让我们在 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
当您移动滑块时,消息会发送到服务器(使用OSC-MEX界面),并且值会显示在 PureData 模型中。
在对此进行测试时,我注意到double
不支持该类型,因为我在 PD 日志窗口中看到以下消息:
unpackOSC: PrintTypeTaggedArgs: [A 64-bit float] 未实现
因此,有必要手动将值转换为single
或明确指定传递给osc_send
OSC-MEX 函数的结构中的提示类型:
val = single(1);
m = struct('path','/test', 'tt','f', 'data',{{val}});
osc_send(osc, m);
2) MATLAB 中的服务器,PureData 中的客户端:
同样,我们在 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
服务器部分在 MATLAB 中有点棘手。这个想法是我们不希望 MATLAB 无限期地阻塞等待消息。所以我创建了一个每 0.11 秒执行一次的计时器。在定时器函数内部,我们尝试以阻塞方式接收消息,但超时为 0.1 秒。这样,GUI 和 MATLAB IDE 都可以保持响应。
3) 其他组合:
使用上述解决方案,您还可以在 PureData 中打开客户端和服务器,或者在 MATLAB 中同时打开客户端和服务器。它应该以任何一种方式工作。
最后我应该说,无论我使用主机名localhost
还是直接指定 IP 地址都没有区别127.0.0.1
。
高温高压
编辑:
我设法自己编译了 OSC-MEX 包,步骤如下。首先下载osc-mex 源及其依赖项。这包括:liblo 源、pthreads-win32 二进制文件、premake4可执行文件。
1) 我们从构建 liblo 库开始:
- 将“premake4.exe”复制到“build”目录中,然后运行:
premake4 --platform=x32 vs2010
- 在VS2010中打开生成的“liblo.sln”解决方案文件。选择“liblo”项目并转到“项目 > 属性”。
include
在“其他包含目录”字段中添加包含 pthreads 头文件的文件夹。同样添加lib
链接器的文件夹,并指定pthreadVC2.lib
为附加依赖项。
- 选择“ReleaseLib”Win32 目标并构建项目。这应该创建最终目标:
lib\ReleaseLib\liblo.lib
请注意,默认情况下,liblo 中禁用 IPv6 支持,因为像 Pd 这样的 OSC 应用程序存在 IPv6 问题。如果您仍想启用它,请将以下行添加到config.h
文件中:
#define ENABLE_IPV6 1
2) 接下来我们在 MATLAB 中编译 MEX 函数:
为了给您省点麻烦,这里是编译的 MEX 文件,在 WinXP 32 位和 Win8 64 位都使用 VS2010 构建。如果您想自己编译,这里是源代码osc_make.m
(只需在 VS2010 中构建解决方案,然后在 MATLAB 中运行)