aboutsummaryrefslogtreecommitdiff
path: root/mod/timer.c
diff options
context:
space:
mode:
authorLudvig Gunne Lindström <ludviggunnelindstrom@gmail.com>2026-07-17 11:43:24 +0200
committerLudvig Gunne Lindström <ludviggunnelindstrom@gmail.com>2026-11-08 14:15:04 +0100
commit039847a29868d335c08fe0a587260dffc71ca5c4 (patch)
treee9d775090fef45ca51db576779fb373040d50e6a /mod/timer.c
downloadmelisma-modules-main.tar.gz
Diffstat (limited to 'mod/timer.c')
-rw-r--r--mod/timer.c152
1 files changed, 152 insertions, 0 deletions
diff --git a/mod/timer.c b/mod/timer.c
new file mode 100644
index 0000000..92659dd
--- /dev/null
+++ b/mod/timer.c
@@ -0,0 +1,152 @@
+/*
+ * melisma - extensible and scriptable audio engine
+ * Copyright (C) 2026 Ludvig Gunne Lindström
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <lauxlib.h>
+#include "melisma.h"
+
+#define TIMER_TYPENAME "timer"
+
+struct timer
+{
+ bool on;
+ uint64_t t;
+};
+
+static void proc(const ml_proc_args *args)
+{
+ struct timer *tmr = args->userp;
+
+ if (tmr->on)
+ {
+ tmr->t += args->nframes;
+ }
+}
+
+static int l_init(lua_State *s)
+{
+ struct timer *tmr = calloc(1,sizeof(*tmr));
+
+ tmr->on = false;
+ tmr->t = 0;
+
+ ml_node *node = ml_create_node(proc,tmr);
+ ml_channel *src = ml_add_output(node);
+ ml_channel *dst = ml_add_input(ml_get_root_node());
+ ml_connect(src,dst);
+
+ *(void**) lua_newuserdata(s,sizeof(void*)) = tmr;
+ luaL_setmetatable(s,TIMER_TYPENAME);
+
+ return 1;
+}
+
+static int l_start(lua_State *s)
+{
+ struct timer *tmr = *(void**) luaL_checkudata(s,1,TIMER_TYPENAME);
+ tmr->on = true;
+ return 0;
+}
+
+static int l_stop(lua_State *s)
+{
+ struct timer *tmr = *(void**) luaL_checkudata(s,1,TIMER_TYPENAME);
+ tmr->on = false;
+ return 0;
+}
+
+static int l_reset(lua_State *s)
+{
+ struct timer *tmr = *(void**) luaL_checkudata(s,1,TIMER_TYPENAME);
+ tmr->t = 0;
+ return 0;
+}
+
+static int l_read(lua_State *s)
+{
+ struct timer *tmr = *(void**) luaL_checkudata(s,1,TIMER_TYPENAME);
+ double t = (double) tmr->t / (double) ml_sample_rate();
+ lua_pushnumber(s,t);
+ return 1;
+}
+
+int luaopen_melisma_timer(lua_State *s)
+{
+/*** Time measurement.
+
+ local mtimer = require 'melisma.timer'
+ local mkeycallback = require 'melisma.keycallback'
+
+ local timer = mtimer.init()
+ timer:start()
+
+ mkeycallback.set(function()
+ print(timer:read())
+ timer:reset()
+ end)
+
+@classmod timer
+*/
+ lua_newtable(s);
+ int tbl = lua_gettop(s);
+
+/*** Create a new timer.
+@static
+@function init
+@treturn timer
+*/
+ lua_pushcfunction(s,l_init);
+ lua_setfield(s,tbl,"init");
+
+/*** Start timer.
+@function start
+*/
+ lua_pushcfunction(s,l_start);
+ lua_setfield(s,tbl,"start");
+
+/*** Stop timer.
+@function stop
+*/
+ lua_pushcfunction(s,l_stop);
+ lua_setfield(s,tbl,"stop");
+
+/*** Reset timer.
+@function reset
+*/
+ lua_pushcfunction(s,l_reset);
+ lua_setfield(s,tbl,"reset");
+
+
+/*** Read timer.
+@function read
+@treturn number Elapsed seconds.
+*/
+ lua_pushcfunction(s,l_read);
+ lua_setfield(s,tbl,"read");
+
+ luaL_newmetatable(s,TIMER_TYPENAME);
+ int mt = lua_gettop(s);
+
+ lua_pushvalue(s,tbl);
+ lua_setfield(s,mt,"__index");
+
+ lua_settop(s,tbl);
+ return 1;
+}