shithub: sox

Download patch

ref: f31b93dfccbc215a427c75c73b03128815e179cb
parent: 2630befd3bf9a80ed565927988b6598cde40cea4
author: rrt <rrt>
date: Tue Jan 9 21:42:24 EST 2007

luaeff.c

--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -23,7 +23,7 @@
 effects = avg.c band.c bandpass.c biquad.c biquad.h breject.c btrworth.c \
 	  btrworth.h chorus.c compand.c dcshift.c deemphas.c earwax.c \
 	  echo.c echos.c equalizer.c fade.c FFT.c FFT.h filter.c flanger.c \
-	  highp.c highpass.c lowp.c lowpass.c lua.c lintlib.c mask.c \
+	  highp.c highpass.c lowp.c lowpass.c luaeff.c lintlib.c mask.c \
 	  mcompand.c noiseprof.c noisered.c noisered.h pad.c pan.c \
 	  phaser.c pitch.c polyphas.c rabbit.c rate.c repeat.c resample.c \
 	  reverb.c reverse.c silence.c speed.c stat.c \
--- a/src/lua.c
+++ /dev/null
@@ -1,284 +1,0 @@
-/*
- * Lua - write filters in Lua.
- *
- * Copyright 2006 Reuben Thomas
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, write to the Free Software
- * Foundation, Fifth Floor, 51 Franklin Street, Boston, MA 02111-1301,
- * USA.  */
-
- 
-/* TODO: If efficiency is a problem, move the call of the Lua script
-   into the flow phase. Instrument the Lua environment so that scripts
-   can still be written naively: reading beyond the end of the input
-   array yields to read more data, and writing output similarly. In
-   order not to need nonetheless to buffer all input and output until
-   finished, need low-water-marks that the script can update to signal
-   that it has finished reading and writing respectively.
-   Alternatively, assume that each location can only be read/written
-   once. */
-
- 
-#include "st_i.h"
-
-#include <assert.h>
-#include <string.h>
-#include <lua.h>
-#include <lualib.h>
-#include <lauxlib.h>
-
-/* Private data for effect */
-typedef struct lua {
-  char *file;                   /* Script file */
-  lua_State *L;                 /* Lua state */
-  st_size_t nsamp;              /* Number of samples in input */
-  st_sample_t *data;            /* Input data */
-} *lua_t;
-
-assert_static(sizeof(struct lua) <= ST_MAX_EFFECT_PRIVSIZE, 
-              /* else */ lua_PRIVSIZE_too_big);
-
-
-static void *lua_alloc(void *ud UNUSED, void *ptr, size_t osize UNUSED, size_t nsize)
-{
-  if (nsize == 0) {
-    free(ptr);
-    return NULL;
-  } else
-    return xrealloc(ptr, nsize);
-}
-
-/*
- * Process command-line options
- */
-static int lua_getopts(eff_t effp, int n, char **argv) 
-{
-  lua_t lua = (lua_t)effp->priv;
-  int i;
-
-  if (n < 1) {
-    st_fail(effp->h->usage);
-    return ST_EOF;
-  }
-
-  /* Since the allocator quits if it fails, this should always
-     succeed if it returns. */
-  assert((lua->L = lua_newstate(lua_alloc, NULL)));
-
-  /* Collect options into global arg table */
-  lua_createtable(lua->L, n - 1, 0);
-  for (i = 1; i < n; i++) {
-    lua_pushstring(lua->L, argv[i]);
-    lua_rawseti(lua->L, -2, i);
-  }
-  lua_setglobal(lua->L, "arg");
-
-  lua->file = xstrdup(argv[0]);
-  return ST_SUCCESS;
-}
-
-
-/* st_sample_t arrays */
-
-typedef struct {
-  st_size_t size;
-  st_sample_t *data;
-} st_sample_t_array_t;
-
-static const char *handle = "st_sample_t array";
-
-static int newarr(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;
-  luaL_getmetatable(L, handle);
-  lua_setmetatable(L, -2);
-  return 1;
-}
-
-static int arr_index(lua_State *L)
-  /* array, key -> value */
-{
-  st_sample_t_array_t *p = luaL_checkudata(L, 1, handle);
-  lua_Integer k = luaL_checkinteger(L, 2);
-
-  if ((st_size_t)k >= p->size)
-    lua_pushnil(L);
-  else
-    lua_pushinteger(L, (lua_Integer)p->data[k]);
-    
-  return 1;
-}
-
-static int arr_newindex(lua_State *L)
-  /* array, key, value -> */
-{
-  st_sample_t_array_t *p = luaL_checkudata(L, 1, handle);
-  lua_Integer k = luaL_checkinteger(L, 2);
-  lua_Integer v = luaL_checkinteger(L, 3);
-
-  /* FIXME: Have some indication for out of range */
-  if ((st_size_t)k < p->size)
-    p->data[k] = v;
-    
-  return 0;
-}
-
-static int arr_len(lua_State *L)
-  /* array -> #array */
-{
-  st_sample_t_array_t *p;
-  p = luaL_checkudata(L, 1, handle);
-  lua_pushinteger(L, (lua_Integer)p->size);
-  return 1;
-}
-
-static int arr_tostring(lua_State *L)
-{
-  char buf[256];
-  void *udata = luaL_checkudata(L, 1, handle);
-  if(udata) {
-    sprintf(buf, "%s (%p)", handle, udata);
-    lua_pushstring(L, buf);
-  }
-  else {
-    sprintf(buf, "must be userdata of type '%s'", handle);
-    luaL_argerror(L, 1, buf);
-  }
-  return 1;
-}
-
-/* Metatable */
-static const luaL_reg meta[] = {
-  {"__index", arr_index},
-  {"__newindex", arr_newindex},
-  {"__len", arr_len},
-  {"__tostring", arr_tostring},
-  {NULL, NULL}
-};
-
-
-/*
- * Prepare processing.
- * Do all initializations.
- */
-static int lua_start(eff_t effp)
-{
-  lua_t lua = (lua_t)effp->priv;
-  int ret;
-
-  lua->data = NULL;
-
-  /* TODO: If concerned about security, lock down here: in particular,
-     don't open the io library. */
-  luaL_openlibs(lua->L);
-
-  luaopen_int(lua->L);
-
-  /* Create st_sample_t array userdata type */
-  createmeta(lua->L, handle);
-  luaL_register(lua->L, NULL, meta);
-
-  if ((ret = luaL_loadfile(lua->L, lua->file)) != 0) {
-    st_fail("cannot load Lua script %s: error %d", lua->file, ret);
-    return ST_EOF;
-  }
-
-  return ST_SUCCESS;
-}
-
-/*
- * Processed signed long samples from ibuf to obuf.
- * Return number of samples processed.
- */
-static int lua_flow(eff_t effp, const st_sample_t *ibuf, st_sample_t *obuf UNUSED, 
-                       st_size_t *isamp, st_size_t *osamp)
-{
-  lua_t lua = (lua_t)effp->priv;
-
-  lua->data = (st_sample_t *)xrealloc(lua->data, (lua->nsamp + *isamp) * sizeof(st_sample_t));
-  memcpy(lua->data + lua->nsamp, ibuf, *isamp * sizeof(st_sample_t));
-  lua->nsamp += *isamp;
-
-  *osamp = 0;           /* Signal that we didn't produce any output */
-
-  return ST_SUCCESS;
-}
-
-/*
- * Drain out remaining samples if the effect generates any.
- * If there's nothing to do, use st_effect_nothing_drain instead.
- */
-static int lua_drain(eff_t effp, st_sample_t *obuf, st_size_t *osamp)
-{
-  lua_t lua = (lua_t)effp->priv;
-  int ret;
-  st_sample_t_array_t inarr, outarr;
-
-  inarr.size = lua->nsamp;
-  inarr.data = lua->data;
-  outarr.size = *osamp;
-  outarr.data = obuf;
-
-  newarr(lua->L, inarr);
-  newarr(lua->L, outarr);
-  if ((ret = lua_pcall(lua->L, 2, LUA_MULTRET, 0)) != 0)
-    st_fail("error in Lua script: %d", ret);
-
-  *osamp = 0;
-  /* Help out application and return ST_EOF when drain
-   * will not return any mre information.  *osamp == 0
-   * also indicates that.
-   */
-  return ST_EOF;
-}
-
-/*
- * Clean up state.
- */
-static int lua_delete(eff_t effp)
-{
-  lua_t lua = (lua_t)effp->priv;
-
-  lua_close(lua->L);
-
-  return ST_SUCCESS;
-}
-
-
-/*
- * Effect descriptor.
- * If one of the methods does nothing, use the relevant
- * st_effect_nothing* method.
- */
-static st_effect_t st_lua_effect = {
-  "lua",
-  "Usage: lua script [options]",
-  ST_EFF_MCHAN,
-  lua_getopts,
-  lua_start,
-  lua_flow,
-  lua_drain,
-  st_effect_nothing,
-  lua_delete
-};
-
-/*
- * Function returning effect descriptor. This should be the only
- * externally visible object.
- */
-const st_effect_t *st_lua_effect_fn(void)
-{
-  return &st_lua_effect;
-}