Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/EmptyTag/142.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用OSC实现纯数据与MATLAB的通信_Matlab_Udp_Osc_Puredata_Max Msp Jitter - Fatal编程技术网

用OSC实现纯数据与MATLAB的通信

用OSC实现纯数据与MATLAB的通信,matlab,udp,osc,puredata,max-msp-jitter,Matlab,Udp,Osc,Puredata,Max Msp Jitter,我正在尝试接收通过OSC从纯数据(或Max/MSP)发送到MATLAB的消息 我能够将OSC消息从纯数据发送到纯数据 我可以从MATLAB发送消息到MATLAB 我甚至可以从MATLAB向纯数据发送消息 …我真的很难得到纯数据来与MATLAB对话 下面是我从MATLAB发送消息的代码(我使用的是oscmex协议): 如果我使用主机“localhost”发送,那么使用上面的代码从MATLAB发送到MATLAB,一切都可以正常工作。如果我将其设置为“127.0.0.1”,MATLAB将发送纯数据

我正在尝试接收通过OSC从纯数据(或Max/MSP)发送到MATLAB的消息

  • 我能够将OSC消息从纯数据发送到纯数据
  • 我可以从MATLAB发送消息到MATLAB
  • 我甚至可以从MATLAB向纯数据发送消息
  • …我真的很难得到纯数据来与MATLAB对话
下面是我从MATLAB发送消息的代码(我使用的是oscmex协议):

如果我使用主机“localhost”发送,那么使用上面的代码从MATLAB发送到MATLAB,一切都可以正常工作。如果我将其设置为“127.0.0.1”,MATLAB将发送纯数据,但MATLAB无法接收自己的消息

现在是事情的另一端。以下是我的纯数据补丁:

同样,仅运行上述修补程序就可以通过纯数据成功地发送和接收消息

问题在于当我试着从一个程序到另一个程序说话时。如果我设置MATLAB在3333端口发送,纯数据在3333端口接收,纯数据在2222端口发送,MATLAB在2222端口接收,那么如果MATLAB的主机是“127.0.0.1”,我可以让纯数据接收。但是,有了“127.0.0.1”,MATLAB无法自行发送

在任何情况下,无论我尝试什么,我都无法将纯数据发送到MATLAB,尽管我能够将其发送到自身。我怀疑这与“主机”地址有关

我的实际IPv4地址(使用MS命令提示符的“ipconfig”找到)与127.0.0.1完全不同,使用此处指定的值似乎并不能使事情变得更好

我知道在任何时候都不能有多个OSC服务器同时打开同一个端口,因此我目前尝试的解决方案包括在一个端口上从MATLAB发送数据,在另一个端口上从纯数据发送数据,在任何一个端口上一次只打开一个服务器

注意,我还知道,我使用
/foo
表示来自MATLAB的消息,使用
/test
表示来自纯数据的消息。然而,我的MATLAB代码不分青红皂白地接收通过OSC发送的所有内容,所以这没有什么区别

如果您能帮助PD与MATLAB交流,我们将不胜感激

更新:我解决了“localhost”问题,但似乎无法解决问题(我不得不将localhost添加到我的Windows“hosts”文件中)。所以,我担心localhost的事情可能是找错了方向。但是,我仍然无法让PD与MATLAB对话


更新#2:Amro在下面发布了一个优雅的解决方案,我仍然无法让MATLAB接收来自纯数据的消息。我已经安装了监控我的UDP连接,并注意到当MATLAB设置服务器时,它使用“接口”
[::0]
,而PD设置使用“接口”
0.0.0
。由于PureData是成功接收消息的一个,也许我还需要让MATLAB监听
0.0.0

localhost
127.0.0.1
的别名;它们实际上是相同的IP地址。因此,如果matlab只在发送到
localhost
时接收到某些内容,而在发送到
127.0.0.1
时没有接收到这些内容,那么它们可能有一个错误的OSC实现

只要补丁中有
[udprective 2222]
,Pd就会阻塞端口UDP/2222,matlab将无法在该端口上接收任何内容


因此,简单的解决方案是:在使用
osc\u new\u服务器(2222)创建matlab服务器之前删除
[udprective 2222]

首先让我说,我以前从未使用过OSC或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

当您移动滑块时,消息被发送到服务器(使用接口),值显示在PureData模型中

在测试时,我注意到不支持
double
类型,因为我在PD日志窗口中看到了以下消息:

解包OSC:PrintTypeTaggedArgs:[64位浮点]未实现

因此,有必要手动将值转换为
single
,或者在传递给
osc\u 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和MatlabIDE都能保持响应速度


3) 其他组合: 使用上述解决方案,您还可以在PureData中同时打开客户机和服务器,或者在MATLAB中同时打开客户机和服务器。这两种方式都应该有效

最后,我应该说,无论是将主机名用作
localhost
,还是直接指定IP地址
127.0.0.1
,都没有区别


编辑: 我自己设法编译了OSC-MEX包,下面是步骤。第一次下载及其依赖项。这包括:、可执行文件

1) 我们首先构建liblo库:

  • 将“premake4.exe”复制到“build”目录中,然后运行:
    premake4--platform=x32 vs2010
  • 在VS2010中打开生成的“liblo.sln”解决方案文件。选择“liblo”项目并转到“项目>属性”。在“附加包含目录”字段中添加包含pthreads头文件的
    include
    文件夹。类似地,为链接器添加
    lib
    文件夹,并指定
    pthreadVC2.lib
    作为附加依赖项
  • 选择“ReleaseLib”Win32 t
    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
    
    #define ENABLE_IPV6 1
    
    mex -largeArrayDims -I../path/to/liblo-0.27 xxxxxx.c pthreadVC2.lib liblo.lib -lwsock32 -lws2_32 -liphlpapi