shithub: sox

Download patch

ref: ef2fd8381da0e925e63afd25cafa78c2f83b2474
parent: cbd2f99d69a5bac3f84a75959d21ce36d60496c4
author: rrt <rrt>
date: Mon Jan 15 09:31:58 EST 2007

First cut of working Lua file formats.

--- a/src/luaeff.c
+++ b/src/luaeff.c
@@ -111,8 +111,8 @@
   outarr.size = *osamp;
   outarr.data = obuf;
 
-  st_lua_newarr(lua->L, inarr);
-  st_lua_newarr(lua->L, outarr);
+  st_lua_pusharray(lua->L, inarr);
+  st_lua_pusharray(lua->L, outarr);
   if ((ret = lua_pcall(lua->L, 2, 0, 0)) != 0)
     st_fail("error in Lua script: %d", ret);
 
--- a/src/luaform.c
+++ b/src/luaform.c
@@ -61,11 +61,29 @@
     st_fail("cannot load Lua script %s: error %d", ft->signal.lua_script, ret);
     return ST_EOF;
   }
+  /* FIXME: Store script function for reuse! */
 
   return ST_SUCCESS;
 }
 
 /*
+ * Call Lua script with (action, fp, array), and return return value
+ * (an st_size_t) to the caller.
+ */
+static st_size_t lua_callscript(lua_State *L)
+{
+  st_size_t done;
+  int ret;
+
+  if ((ret = lua_pcall(L, 3, 1, 0)) != 0)
+    st_fail("error in Lua script: %d", ret);
+  done = lua_tointeger(L, -1);
+  lua_pop(L, 1);
+
+  return done;
+}
+
+/*
  * Read up to len samples of type st_sample_t from file into buf[].
  * Return number of samples read.
  */
@@ -72,8 +90,6 @@
 static st_size_t lua_read(ft_t ft, st_sample_t *buf, st_size_t len)
 {
   lua_t lua = (lua_t)ft->priv;
-  st_size_t done;
-  int ret;
   st_sample_t_array_t inarr;
 
   inarr.size = len;
@@ -80,13 +96,10 @@
   inarr.data = buf;
 
   lua_pushstring(lua->L, "read");
-  st_lua_newarr(lua->L, inarr);
-  if ((ret = lua_pcall(lua->L, 2, 1, 0)) != 0)
-    st_fail("error in Lua script: %d", ret);
-  done = lua_tointeger(lua->L, -1);
-  lua_pop(lua->L, 1);
+  st_lua_pushfile(lua->L, ft->fp);
+  st_lua_pusharray(lua->L, inarr);
 
-  return done;
+  return lua_callscript(lua->L);
 }
 
 /*
@@ -96,7 +109,6 @@
 static st_size_t lua_write(ft_t ft, const st_sample_t *buf, st_size_t len)
 {
   lua_t lua = (lua_t)ft->priv;
-  int ret;
   st_sample_t_array_t outarr;
 
   outarr.size = len;
@@ -103,11 +115,10 @@
   outarr.data = (st_sample_t *)buf;
 
   lua_pushstring(lua->L, "write");
-  st_lua_newarr(lua->L, outarr);
-  if ((ret = lua_pcall(lua->L, 2, 1, 0)) != 0)
-    st_fail("error in Lua script: %d", ret);
+  st_lua_pushfile(lua->L, ft->fp);
+  st_lua_pusharray(lua->L, outarr);
 
-  return len;
+  return lua_callscript(lua->L);
 }
 
 /*
@@ -122,18 +133,16 @@
   return ST_SUCCESS;
 }
 
+/* Seek relative to current position. */
 static int lua_seek(ft_t ft, st_size_t offset)
 {
   lua_t lua = (lua_t)ft->priv;
-  int ret;
 
   lua_pushstring(lua->L, "seek");
+  st_lua_pushfile(lua->L, ft->fp);
   lua_pushinteger(lua->L, offset);
-  if ((ret = lua_pcall(lua->L, 2, 1, 0)) != 0)
-    st_fail("error in Lua script: %d", ret);
-  /* Seek relative to current position. */
 
-  return ret;
+  return lua_callscript(lua->L);
 }
 
 /* Format file suffixes */
--- a/src/st_i.h
+++ b/src/st_i.h
@@ -265,8 +265,9 @@
   st_size_t size;
   st_sample_t *data;
 } st_sample_t_array_t;
-int st_lua_newarr(lua_State *L, st_sample_t_array_t arr);
-void *st_lua_new(void);
+int st_lua_pusharray(lua_State *L, st_sample_t_array_t arr);
+lua_State *st_lua_new(void);
+void st_lua_pushfile(lua_State *L, FILE *fp);
 
 
 /*=============================================================================
--- a/src/stlua.c
+++ b/src/stlua.c
@@ -25,11 +25,12 @@
 #include <lualib.h>
 #include <lauxlib.h>
 
+
 /* st_sample_t arrays */
 
 static const char *handle = "st_sample_t array";
 
-int st_lua_newarr(lua_State *L, st_sample_t_array_t arr)
+int st_lua_pusharray(lua_State *L, st_sample_t_array_t arr)
 {
   lua_newuserdata(L, sizeof(st_sample_t_array_t));
   *(st_sample_t_array_t *)lua_touserdata(L, -1) = arr;
@@ -109,7 +110,8 @@
     return xrealloc(ptr, nsize);
 }
 
-void *st_lua_new(void)
+/* Create a Lua state and set it up for libst use */
+lua_State *st_lua_new(void)
 {
   lua_State *L;
 
@@ -126,5 +128,19 @@
   createmeta(L, handle);
   luaL_register(L, NULL, meta);
 
+  /* Stop file handles being GCed */
+  luaL_getmetatable(L, LUA_FILEHANDLE);
+  lua_pushnil(L);
+  lua_setfield(L, -2, "__gc");
+
   return L;
+}
+
+/* Push a FILE * as a Lua file handle */
+void st_lua_pushfile(lua_State *L, FILE *fp)
+{
+  FILE **pf = lua_newuserdata(L, sizeof *pf);
+  *pf = fp;
+  luaL_getmetatable(L, LUA_FILEHANDLE);
+  lua_setmetatable(L, -2);
 }