/* * 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 . */ #include #include #include #include #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; }