Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Receive OSC messages inside lua script #12

Closed
igoumeninja opened this issue Feb 4, 2014 · 9 comments
Closed

Receive OSC messages inside lua script #12

igoumeninja opened this issue Feb 4, 2014 · 9 comments

Comments

@igoumeninja
Copy link

Good evening,

I am trying to receive arguments from OSC messages inside lua script, for live coding use. I extend wrapper and is working very well, but something strange happen.
Here is a float function that I want to return the amplitude which I receive from an OSC msg.

float ofApp::amp() {
    return amplitude;
}

It's returning a 0 while amplitude is changing.
If I substitute amplitude with ofGetFrameNum() is working fine!

float ofApp::amp() {
    return ofGetFrameNum();
}

Any help?
Thanks in advance

@abigpotostew
Copy link
Contributor

Hi Aris. I can't tell you exactly what is wrong without more code. I suspect it's because your amp() function is a member function and you're not calling the correct instance of your myApp in the lua code so it's returning 0 (null).

On Tue, Feb 4, 2014 at 3:02 PM, Aris Bezas notifications@github.com
wrote:

Good evening,
I am trying to receive arguments from OSC messages inside lua script, for live coding use. I extend wrapper and is working very well, but something rare happen.
Here is a float function that I want to return the amplitude which I receive from an OSC msg.
float ofApp::amp() {
return amplitude;
}
It's returning a 0 while amplitude is changing.
If I substitute amplitude with ofGetFrameNum() is working fine!
float ofApp::amp() {
return ofGetFrameNum();
}
Any help?

Thanks in advance

Reply to this email directly or view it on GitHub:
#12

@igoumeninja
Copy link
Author

Hi Stewart, my amp() function is part of ofApp class and the wrapper is the following

            class_<ofApp>("app")
                .def(constructor<>())
                .def("test", (void(ofApp::*)()) &ofApp::test)
                .def("amp", (float(ofApp::*)()) &ofApp::amp)

and the lua script:

gea = of.app()
function setup()
   of.setWindowTitle("adf")
   of.background(0)
end
----------------------------------------------------
function update()
   print(gea:amp())
end
----------------------------------------------------
function draw()
   of.fill()
   of.setColor(100,0,0,10)
   of.rect(100,0,of.getWidth(), of.getHeight())
end
----------------------------------------------------
function keyPressed(key)
   if key == string.byte("s") then
      print(gea:amp())
   end
end

Thanks in advance for your help

@danomatika
Copy link
Owner

You're creating a new instance in Lua as it's calling the constructor of.app(). It dosent refer to the existjf object in c++ but to a new, empty one, which is whynit dosent work. You need a global function binding which returns the already existing app pointer to lua.

@danomatika
Copy link
Owner

aka you need something like:

// get global app pointer and cast type to your custom ofApp
 ofApp* getApp() {return (ofApp*) ofGetAppPtr();}

.def("getApp", &getApp), // returns the global instance of the ofApp to Lua

Then simply change this:

gea = of.app()

to this

gea = of.getApp()

@igoumeninja
Copy link
Author

First of all thanks for your reply!
So I am adding the pointer in ofApp.cpp file like that:

#include "ofApp.h"
ofApp* getApp() {return (ofApp*) ofGetAppPtr();}
//--------------------------------------------------------------
void ofApp::setup() {...}

but when I am trying to create the binding:

class_<ofApp>("app")
    .def(constructor<>())
    .def("getApp", &getApp)

I am taking an error

error: use of undeclared identifier 'getApp'; did you mean 'getopt'?

deep waters for me...

@danomatika
Copy link
Owner

Long answer:

You need to read up on how C++ compiles source files. Header files (.h) are used to tell the compiler about what classes and functions exist and the .cpp files are where those functions are implemented. Whenever you want to use one of those functions, the compiler needs to know about it which is why at the top of many source files you will see #include lines which are telling it to look at that header. This way, the classes and functions declared in the included header will be recognized in the rest of the file.

Short answer:

You need to put the getApp() function in a place where the compiler can find it in the bindings files. The error is telling you that it doesn't know what "getApp", mainly because it is only written in the ofApp.cpp file.

The simplest answer is to put this function in your bindings file, aka at the top of the file where you have the lua bindings (I was trying to imply this in my last answer).

@igoumeninja
Copy link
Author

You have right, I confused with the place that the pointer must be defined. Now my lua bindings file is like that:

 */
#include "ofApp.h"
#include "ofxGea.h"
#include "ofxMidiLua.h"
#include "ofxLua.h"

// get global app pointer and cast type to your custom ofApp
ofApp* getApp() {return (ofApp*) ofGetAppPtr();}

namespace bindings {
luabind::scope registerGea() {
    using namespace luabind;
    return
            class_<ofxMidiLua>("midi")
                .def(constructor<>())
                .def("setup", (void(ofxMidiLua::*)()) &ofxMidiLua::setup)
                .def("update", (void(ofxMidiLua::*)()) &ofxMidiLua::update)
                .def("init", (void(ofxMidiLua::*)(int, float)) &ofxMidiLua::init)
                .def("map", (float(ofxMidiLua::*)(int, float, float)) &ofxMidiLua::map),

            class_<ofApp>("app")
                .def(constructor<>())
                .def("getApp", &getApp)
    ;
}
} // namespace

And I have to compile errors, but when I run the script:

gea = of.getApp()

function setup()
   of.setWindowTitle("adf")
   of.background(0)
end
----------------------------------------------------
function update()
   --print(gea:amp())
end
----------------------------------------------------
function draw()
   of.fill()
   of.setColor(100,0,0,10)
   of.rect(100,0,of.getWidth(), of.getHeight())
end

I taking a console message:

[notice ] got a script error: Runtime error: ...cripts/my-lua-scripts/lua-scripts/00-receive-amp.lua:1: attempt to call field 'getApp' (a nil value)

Please help me to close this issue.

@danomatika
Copy link
Owner

You're almost there, but you didn't update the bindings to reflect how the new function needs to work.

"getApp" should be a global function and not a member of your "app" class aka you should be able to use it without having to make a new "app" instance since what we want is to get a reference to the existing "app".

Your bindings should look like this:

return
        class_<ofxMidiLua>("midi")
            .def(constructor<>())
            .def("setup", (void(ofxMidiLua::*)()) &ofxMidiLua::setup)
            .def("update", (void(ofxMidiLua::*)()) &ofxMidiLua::update)
            .def("init", (void(ofxMidiLua::*)(int, float)) &ofxMidiLua::init)
            .def("map", (float(ofxMidiLua::*)(int, float, float)) &ofxMidiLua::map),

        // get global app instance
        def("getApp", &getApp),

        class_<ofApp>("app")
            .def(constructor<>())
            .def("amp", &App::getAmp)
            .property("amp", &App::getAmp) // readonly property
    ;

Then you can use them like:

-- get a reference to the global app
app = gea.getApp()

-- get data from the app
amp = app:getAmp()
amp = app.amp -- this works too as I added a property in the bindings

Make sense? Also, it's very important to note the colon : with app:getAmp(). The colon is used when calling a member function on a class instance while the period . is used when accessing a property (app.amp) or calling a global function in a module (gea.getApp(), where "gea" is the module name). Coming from C++, that still trips me up now and then :D

As this is more of a general question about using Luabind with ofxLua and not a problem with the ofxLua source code, in the future can you ask us on the OF forums? Just make sure to include my twitter handle @danomatika in the post so I'll get the notification.

@igoumeninja
Copy link
Author

I didn't manage to receive the amplitude that SuperCollider detecting in my sketch. I' ve create a post in OF forum from scratch. I hope to see you there!
http://forum.openframeworks.cc/t/oxflua-ofxosc-receive-osc-msg-content-in-a-lua-script/14713

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants