diff --git a/README.md b/README.md index 822a02e..cca5630 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ A brief synopsis of the LÖVE [demos is available on the oLvgui repo](https://gi ## oLvosc Data Functions -`packet = oLvosc.oscPacket (address_str, type_str, msg_table)` +`packet = oLvosc.oscPacket(address_str, type_str, msg_table)` * Encodes an address string, a type string and a table of messages into a UDP packet * packet is ready for sending ( oLvosc.sendOSC(server, packet) ) @@ -99,6 +99,34 @@ A brief synopsis of the LÖVE [demos is available on the oLvgui repo](https://gi * Decodes a MIDI sub-packet into the four original bytes +## New with 0.1.2: + +### Data tag 't' added: OSC Timetag + + * Encoding and decoding, sending and receiving of timetags 't' added to data functions. + +### Time functions + +`time_secs, time_fraction, fraction_as_float, epoch_time = oLvosc.time()` + + * Returns the current time (OSC, which is NPT time) as: + * Time in seconds since Jan 1, 1900 (32 bit integer) + * Additional fraction of second (32 bit integer) + * That fraction as a float + * The current time as Unix 'Epoch' time + +`time_packet = oLvosc.packTIME(time_seconds, time_fraction)` + + * Encodes time in seconds, fractions of seconds (both integers) + * 'OSC timetag' is the same as NTP time: time since Jan 1, 1900 + * Returns a packed 8-byte data blk of OSC (NTP) format time + +`time_secs, time_fraction = oLvosc.unpackTIME(tPack)` + + * Takes a timetag binary packet + * Returns time in seconds, fractions of seconds + + ## oLvosc Examples ### Open a client socket (sending) diff --git a/oLv/oLvosc.lua b/oLv/oLvosc.lua index 8552c59..b629e91 100644 --- a/oLv/oLvosc.lua +++ b/oLv/oLvosc.lua @@ -10,11 +10,10 @@ local oLvosc = {} local socket = require "socket" local mtab = {0, 3, 2, 1} -local function lpak(_, fmt, ttbl) - return string.pack(fmt, ttbl) +local function lpak(_, ...) + return string.pack(...) end --- function substitues so this module will work with love2d (>=11) and lua (>=5.3) local oLvpk if love ~= nil then oLvpk= {pack = love.data.pack, unpack = love.data.unpack} @@ -44,6 +43,13 @@ end function oLvosc.sleep(tm) socket.sleep(tm) end + +-- returns int secs, int fraction, float fraction, epoch time +function oLvosc.time() + local tm = socket.gettime() + local i,f = math.modf(tm + 2208988800) + return i, math.floor(f * 2147483647), f, tm +end -- ++++++++++++++++++++++++++++++++++++++++++++++++++++ -- some utility functions -- pack MIDI data for send @@ -58,6 +64,17 @@ function oLvosc.unpackMIDI(mPack) local mChan, mStatus, mByte1, mByte2 = oLvpk.unpack('BBBB', mPack) return mChan, mStatus, mByte1, mByte2 end + +function oLvosc.packTIME(tsec, tfrac) + local tpk + tpk = oLvpk.pack('string','II', tsec, tfrac) + return tpk +end + +function oLvosc.unpackTIME(tPack) + local tsec, tfrac = oLvpk.unpack('II', tPack) + return tsec, tfrac +end -- ++++++++++++++++++++++++++++++++++++++++++++++++++++ -- osc client functions START -- init Client @@ -120,6 +137,8 @@ else strl = strl..oLvpk.pack('string', '>d', msgTab[argC]) elseif types == 'm' then strl = strl..oLvpk.pack('string', 'c4', msgTab[argC]) + elseif types == 't' then + strl = strl..oLvpk.pack('string', 'c8', msgTab[argC]) elseif types == 'N' or types == 'T' or types == 'F' or types == 'I' then end end @@ -232,6 +251,10 @@ local dTbl = {} iv, nx = oLvpk.unpack("c4", oD) oD = string.sub(oD, 5) table.insert(dTbl, iv) + elseif tc == 't' then + iv, nx = oLvpk.unpack("c8", oD) + oD = string.sub(oD, 9) + table.insert(dTbl, iv) elseif tc == 'h' then iv, nx = oLvpk.unpack(">i8", oD) oD = string.sub(oD, 9) diff --git a/oLvosc_Lua_demo/oLv/oLvosc.lua b/oLvosc_Lua_demo/oLv/oLvosc.lua index 8552c59..b629e91 100644 --- a/oLvosc_Lua_demo/oLv/oLvosc.lua +++ b/oLvosc_Lua_demo/oLv/oLvosc.lua @@ -10,11 +10,10 @@ local oLvosc = {} local socket = require "socket" local mtab = {0, 3, 2, 1} -local function lpak(_, fmt, ttbl) - return string.pack(fmt, ttbl) +local function lpak(_, ...) + return string.pack(...) end --- function substitues so this module will work with love2d (>=11) and lua (>=5.3) local oLvpk if love ~= nil then oLvpk= {pack = love.data.pack, unpack = love.data.unpack} @@ -44,6 +43,13 @@ end function oLvosc.sleep(tm) socket.sleep(tm) end + +-- returns int secs, int fraction, float fraction, epoch time +function oLvosc.time() + local tm = socket.gettime() + local i,f = math.modf(tm + 2208988800) + return i, math.floor(f * 2147483647), f, tm +end -- ++++++++++++++++++++++++++++++++++++++++++++++++++++ -- some utility functions -- pack MIDI data for send @@ -58,6 +64,17 @@ function oLvosc.unpackMIDI(mPack) local mChan, mStatus, mByte1, mByte2 = oLvpk.unpack('BBBB', mPack) return mChan, mStatus, mByte1, mByte2 end + +function oLvosc.packTIME(tsec, tfrac) + local tpk + tpk = oLvpk.pack('string','II', tsec, tfrac) + return tpk +end + +function oLvosc.unpackTIME(tPack) + local tsec, tfrac = oLvpk.unpack('II', tPack) + return tsec, tfrac +end -- ++++++++++++++++++++++++++++++++++++++++++++++++++++ -- osc client functions START -- init Client @@ -120,6 +137,8 @@ else strl = strl..oLvpk.pack('string', '>d', msgTab[argC]) elseif types == 'm' then strl = strl..oLvpk.pack('string', 'c4', msgTab[argC]) + elseif types == 't' then + strl = strl..oLvpk.pack('string', 'c8', msgTab[argC]) elseif types == 'N' or types == 'T' or types == 'F' or types == 'I' then end end @@ -232,6 +251,10 @@ local dTbl = {} iv, nx = oLvpk.unpack("c4", oD) oD = string.sub(oD, 5) table.insert(dTbl, iv) + elseif tc == 't' then + iv, nx = oLvpk.unpack("c8", oD) + oD = string.sub(oD, 9) + table.insert(dTbl, iv) elseif tc == 'h' then iv, nx = oLvpk.unpack(">i8", oD) oD = string.sub(oD, 9) diff --git a/oLvosc_Lua_demo/oscping.lua b/oLvosc_Lua_demo/oscping.lua index 57d194a..c4ed853 100644 --- a/oLvosc_Lua_demo/oscping.lua +++ b/oLvosc_Lua_demo/oscping.lua @@ -14,4 +14,8 @@ while 1 do local packet = oLvosc.oscPacket('/myOSC/ping', 'i', { val } ) val = val + 1 oLvosc.sendOSC(cli, packet) + + local t1, t2, t3 = oLvosc.time() + + print('time: npt sec '..t1..' frac '..t2..' epoch '..t3) end diff --git a/oLvosc_Lua_demo/osctimeping.lua b/oLvosc_Lua_demo/osctimeping.lua new file mode 100644 index 0000000..8ac3a9f --- /dev/null +++ b/oLvosc_Lua_demo/osctimeping.lua @@ -0,0 +1,24 @@ +local oLvosc = require "oLv/oLvosc" +local cli +local val = 0 +-- +++++++++++++++++++++++++++++++++++++++++++++++++++ + +-- +++++++++++++++++++++++++++++++++++++++++++++++++++ +local port = 8000 +print('sending to port: '..port) + +cli = oLvosc.cliSetup('224.0.0.1', port) + +while 1 do + oLvosc.sleep(1) + local isec, ifrac, ffrac, epoch = oLvosc.time() + local mytime = oLvosc.packTIME(isec, ifrac) + + local packet = oLvosc.oscPacket('/myOSC/ping', 'it', { val, mytime } ) + val = val + 1 + oLvosc.sendOSC(cli, packet) +end + + +--local mytime = oLvosc.packTIME(isec, ifrac) +--print (oLvosc.unpackTIME(mytime)) \ No newline at end of file diff --git a/oLvosc_Lua_demo/osctimet.lua b/oLvosc_Lua_demo/osctimet.lua new file mode 100644 index 0000000..76ed810 --- /dev/null +++ b/oLvosc_Lua_demo/osctimet.lua @@ -0,0 +1,12 @@ +local oLvosc = require "oLv/oLvosc" +local cli +local val = 0 +-- +++++++++++++++++++++++++++++++++++++++++++++++++++ +-- timetag test +-- +++++++++++++++++++++++++++++++++++++++++++++++++++ + +local isec, ifrac, ffrac, epoch = oLvosc.time() +print(isec, ifrac, ffrac, epoch) + +local mytime = oLvosc.packTIME(isec, ifrac) +print (oLvosc.unpackTIME(mytime)) \ No newline at end of file