diff options
author | Robin Gareus <robin@gareus.org> | 2016-12-08 12:44:36 +0100 |
---|---|---|
committer | Robin Gareus <robin@gareus.org> | 2016-12-08 12:45:44 +0100 |
commit | f05f19bdd4c376d8427f488ab9c812df4d400fbc (patch) | |
tree | 0a1f3c7c5b03b97853deb8d2d5cf4ee37f4ec71c /libs | |
parent | 3d925ef503faae520c670464653856f62c6ca56b (diff) |
add Lua bindings for Timecode conversion
Diffstat (limited to 'libs')
-rw-r--r-- | libs/ardour/ardour/lua_api.h | 29 | ||||
-rw-r--r-- | libs/ardour/lua_api.cc | 122 | ||||
-rw-r--r-- | libs/ardour/luabindings.cc | 21 |
3 files changed, 171 insertions, 1 deletions
diff --git a/libs/ardour/ardour/lua_api.h b/libs/ardour/ardour/lua_api.h index 017246cf1d..f56a640ca1 100644 --- a/libs/ardour/ardour/lua_api.h +++ b/libs/ardour/ardour/lua_api.h @@ -157,13 +157,40 @@ namespace ARDOUR { namespace LuaAPI { */ int hsla_to_rgba (lua_State *lua); - /* Creates a filename from a series of elements using the correct separator for filenames. + /** + * Creates a filename from a series of elements using the correct separator for filenames. * * No attempt is made to force the resulting filename to be an absolute path. * If the first element is a relative path, the result will be a relative path. */ int build_filename (lua_State *lua); + /** + * Generic conversion from audio sample count to timecode. + * (TimecodeType, sample-rate, sample-pos) + */ + int sample_to_timecode (lua_State *L); + + /** + * Generic conversion from timecode to audio sample count. + * (TimecodeType, sample-rate, hh, mm, ss, ff) + */ + int timecode_to_sample (lua_State *L); + + /** + * Use current session settings to convert + * audio-sample count into hh, mm, ss, ff + * timecode (this include session pull up/down). + */ + int sample_to_timecode_lua (lua_State *L); + + /** + * Use current session settings to convert + * timecode (hh, mm, ss, ff) to audio-sample + * count (this include session pull up/down). + */ + int timecode_to_sample_lua (lua_State *L); + class Vamp { /** Vamp Plugin Interface * diff --git a/libs/ardour/lua_api.cc b/libs/ardour/lua_api.cc index 6a2dbbe9f6..5af9a6c960 100644 --- a/libs/ardour/lua_api.cc +++ b/libs/ardour/lua_api.cc @@ -253,6 +253,128 @@ ARDOUR::LuaAPI::plugin_automation (lua_State *L) } int +ARDOUR::LuaAPI::sample_to_timecode (lua_State *L) +{ + int top = lua_gettop (L); + if (top < 3) { + return luaL_argerror (L, 1, "invalid number of arguments sample_to_timecode (TimecodeFormat, sample_rate, sample)"); + } + typedef Timecode::TimecodeFormat T; + T tf = luabridge::Stack<T>::get (L, 1); + double sample_rate = luabridge::Stack<double>::get (L, 2); + int64_t sample = luabridge::Stack<int64_t>::get (L, 3); + + Timecode::Time timecode; + + Timecode::sample_to_timecode ( + sample, timecode, false, false, + Timecode::timecode_to_frames_per_second (tf), + Timecode::timecode_has_drop_frames (tf), + sample_rate, + 0, false, 0); + + luabridge::Stack<uint32_t>::push (L, timecode.hours); + luabridge::Stack<uint32_t>::push (L, timecode.minutes); + luabridge::Stack<uint32_t>::push (L, timecode.seconds); + luabridge::Stack<uint32_t>::push (L, timecode.frames); + return 4; +} + +int +ARDOUR::LuaAPI::timecode_to_sample (lua_State *L) +{ + int top = lua_gettop (L); + if (top < 6) { + return luaL_argerror (L, 1, "invalid number of arguments sample_to_timecode (TimecodeFormat, sample_rate, hh, mm, ss, ff)"); + } + typedef Timecode::TimecodeFormat T; + T tf = luabridge::Stack<T>::get (L, 1); + double sample_rate = luabridge::Stack<double>::get (L, 2); + int hh = luabridge::Stack<int>::get (L, 3); + int mm = luabridge::Stack<int>::get (L, 4); + int ss = luabridge::Stack<int>::get (L, 5); + int ff = luabridge::Stack<int>::get (L, 6); + + Timecode::Time timecode; + timecode.negative = false; + timecode.hours = hh; + timecode.minutes = mm; + timecode.seconds = ss; + timecode.frames = ff; + timecode.subframes = 0; + timecode.rate = Timecode::timecode_to_frames_per_second (tf); + timecode.drop = Timecode::timecode_has_drop_frames (tf); + + int64_t sample; + + Timecode::timecode_to_sample ( + timecode, sample, false, false, + sample_rate, 0, false, 0); + + luabridge::Stack<int64_t>::push (L, sample); + return 1; +} + +int +ARDOUR::LuaAPI::sample_to_timecode_lua (lua_State *L) +{ + int top = lua_gettop (L); + if (top < 2) { + return luaL_argerror (L, 1, "invalid number of arguments sample_to_timecode (sample)"); + } + Session const* const s = luabridge::Userdata::get <Session> (L, 1, true); + int64_t sample = luabridge::Stack<int64_t>::get (L, 2); + + Timecode::Time timecode; + + Timecode::sample_to_timecode ( + sample, timecode, false, false, + s->timecode_frames_per_second (), + s->timecode_drop_frames (), + s->frame_rate (), + 0, false, 0); + + luabridge::Stack<uint32_t>::push (L, timecode.hours); + luabridge::Stack<uint32_t>::push (L, timecode.minutes); + luabridge::Stack<uint32_t>::push (L, timecode.seconds); + luabridge::Stack<uint32_t>::push (L, timecode.frames); + return 4; +} +int +ARDOUR::LuaAPI::timecode_to_sample_lua (lua_State *L) +{ + int top = lua_gettop (L); + if (top < 5) { + return luaL_argerror (L, 1, "invalid number of arguments sample_to_timecode (hh, mm, ss, ff)"); + } + Session const* const s = luabridge::Userdata::get <Session> (L, 1, true); + int hh = luabridge::Stack<int>::get (L, 2); + int mm = luabridge::Stack<int>::get (L, 3); + int ss = luabridge::Stack<int>::get (L, 4); + int ff = luabridge::Stack<int>::get (L, 5); + + Timecode::Time timecode; + timecode.negative = false; + timecode.hours = hh; + timecode.minutes = mm; + timecode.seconds = ss; + timecode.frames = ff; + timecode.subframes = 0; + timecode.rate = s->timecode_frames_per_second (); + timecode.drop = s->timecode_drop_frames (); + + int64_t sample; + + Timecode::timecode_to_sample ( + timecode, sample, false, false, + s->frame_rate (), + 0, false, 0); + + luabridge::Stack<int64_t>::push (L, sample); + return 1; +} + +int ARDOUR::LuaOSC::Address::send (lua_State *L) { Address * const luaosc = luabridge::Userdata::get <Address> (L, 1, false); diff --git a/libs/ardour/luabindings.cc b/libs/ardour/luabindings.cc index 4899757188..46e1d67551 100644 --- a/libs/ardour/luabindings.cc +++ b/libs/ardour/luabindings.cc @@ -423,6 +423,20 @@ LuaBindings::common (lua_State* L) //.addStaticData ("ticks_per_beat", &Timecode::BBT_Time::ticks_per_beat, false) .endClass () + .beginClass <Timecode::Time> ("Time") + .addConstructor <void (*) (double)> () + .addData ("negative", &Timecode::Time::negative) + .addData ("hours", &Timecode::Time::hours) + .addData ("minutes", &Timecode::Time::minutes) + .addData ("seconds", &Timecode::Time::seconds) + .addData ("frames", &Timecode::Time::frames) + .addData ("subframes", &Timecode::Time::subframes) + .addData ("rate", &Timecode::Time::rate) + .addData ("drop", &Timecode::Time::drop) + .endClass () + + // TODO add increment, decrement; push it into the class + /* libtimecode enums */ .beginNamespace ("TimecodeFormat") .addConst ("TC23976", Timecode::TimecodeFormat(Timecode::timecode_23976)) @@ -1809,6 +1823,11 @@ LuaBindings::common (lua_State* L) .addFunction ("route_groups", &Session::route_groups) .addFunction ("new_route_group", &Session::new_route_group) .addFunction ("remove_route_group", (void (Session::*)(RouteGroup*))&Session::remove_route_group) + .addExtCFunction ("timecode_to_sample_lua", ARDOUR::LuaAPI::timecode_to_sample_lua) + .addExtCFunction ("sample_to_timecode_lua", ARDOUR::LuaAPI::sample_to_timecode_lua) + .addFunction ("timecode_frames_per_hour", &Session::timecode_frames_per_hour) + .addFunction ("timecode_frames_per_second", &Session::timecode_frames_per_second) + .addFunction ("timecode_drop_frames", &Session::timecode_drop_frames) .endClass () .beginClass <RegionFactory> ("RegionFactory") @@ -1853,6 +1872,8 @@ LuaBindings::common (lua_State* L) .addFunction ("usleep", Glib::usleep) .addCFunction ("build_filename", ARDOUR::LuaAPI::build_filename) .addFunction ("new_noteptr", ARDOUR::LuaAPI::new_noteptr) + .addCFunction ("sample_to_timecode", ARDOUR::LuaAPI::sample_to_timecode) + .addCFunction ("timecode_to_sample", ARDOUR::LuaAPI::timecode_to_sample) .beginClass <ARDOUR::LuaAPI::Vamp> ("Vamp") .addConstructor <void (*) (const std::string&, float)> () |