bjorn преди 6 години
родител
ревизия
ff6495111f
променени са 4 файла, в които са добавени 55 реда и са изтрити 14 реда
  1. 4 0
      .gitignore
  2. 18 13
      Tupfile
  3. 30 1
      lua_deepspeech.c
  4. 3 0
      tup.config.sample

+ 4 - 0
.gitignore

@@ -1,3 +1,7 @@
 .tup
+tup.config
 *.o
 *.so
+*.dll
+*.lib
+*.exp

+ 18 - 13
Tupfile

@@ -1,18 +1,23 @@
-# Lua flags
-# Replace the pkg-config invocation with custom -I flags if you need them
-CFLAGS += `pkg-config --cflags lua5.1`
+CFLAGS += @(LUA_CFLAGS)
+LFLAGS += @(LUA_LFLAGS)
 
-# DeepSpeech flags
-# You can set the $DEEPSPEECH env var or just change the variable to point at a DeepSpeech release
-# The 'undefined dynamic_lookup' stuff lets us link against Lua and DeepSpeech at runtime, so make
-# sure your executable includes Lua and is otherwise able to find the DeepSpeech shared library.
-DEEPSPEECH = $DEEPSPEECH
-CFLAGS += -I$(DEEPSPEECH)
-LDFLAGS += -undefined dynamic_lookup -L$(DEEPSPEECH) -ldeepspeech
-export DEEPSPEECH
+CFLAGS += -I@(NATIVE_CLIENT_PATH)
+LFLAGS += -L@(NATIVE_CLIENT_PATH)
+
+ifeq (@(TUP_PLATFORM),win32)
+  LFLAGS += -llibdeepspeech.so.if
+  EXT = dll
+  OTHERS = lua-deepspeech.lib lua-deepspeech.exp
+else
+  # The 'undefined dynamic_lookup' stuff lets us link against Lua and DeepSpeech at runtime, so make
+  # sure your executable includes Lua and is otherwise able to find the DeepSpeech shared library.
+  # On windows, you just need to put the dlls next to the executable
+  LFLAGS += -undefined dynamic_lookup -ldeepspeech
+  EXT = so
+endif
 
 !compile = |> ^ CC %f^ clang $(CFLAGS) -c %f -o %o |>
-!link = |> ^ LN %o^ clang -shared -o %o $(LDFLAGS) %f |>
+!link = |> ^ LN %o^ clang -shared -o %o $(LFLAGS) %f |>
 
 : lua_deepspeech.c |> !compile |> lua_deepspeech.o
-: lua_deepspeech.o |> !link |> lua-deepspeech.so
+: lua_deepspeech.o |> !link |> lua-deepspeech.$(EXT) | $(OTHERS)

+ 30 - 1
lua_deepspeech.c

@@ -13,6 +13,12 @@
 
 #define CHECK(c, ...) if (!(c)) { return luaL_error(L, __VA_ARGS__); }
 
+#ifdef _WIN32
+#define LDS_EXPORT __declspec(dllexport)
+#else
+#define LDS_EXPORT
+#endif
+
 static struct {
   ModelState* modelState;
   size_t bufferSize;
@@ -101,6 +107,14 @@ static int lds_init(lua_State* L) {
   return 1;
 }
 
+static int lds_destroy(lua_State* L) {
+  if (state.modelState) {
+    DS_DestroyModel(state.modelState);
+    state.modelState = NULL;
+  }
+  return 0;
+}
+
 static int lds_decode(lua_State* L) {
   size_t sampleCount;
   CHECK(state.modelState != NULL, "DeepSpeech is not initialized");
@@ -154,6 +168,12 @@ static int lds_stream_clear(lua_State* L) {
   return 0;
 }
 
+static int lds_stream_destroy(lua_State* L) {
+  lds_Stream* stream = (lds_Stream*) luaL_checkudata(L, 1, "lds_Stream");
+  DS_DiscardStream(stream->handle);
+  return 0;
+}
+
 static const luaL_Reg lds_api[] = {
   { "init", lds_init },
   { "decode", lds_decode },
@@ -166,13 +186,22 @@ static const luaL_Reg lds_stream_api[] = {
   { "decode", lds_stream_decode },
   { "finish", lds_stream_finish },
   { "clear", lds_stream_clear },
+  { "__gc", lds_stream_destroy },
   { NULL, NULL }
 };
 
-int luaopen_deepspeech(lua_State* L) {
+LDS_EXPORT int luaopen_deepspeech(lua_State* L) {
   lua_newtable(L);
   luaL_register(L, NULL, lds_api);
 
+  // Add sentinel userdata to free the model state on GC
+  lua_newuserdata(L, sizeof(void*));
+  lua_createtable(L, 0, 1);
+  lua_pushcfunction(L, lds_destroy);
+  lua_setfield(L, -2, "__gc");
+  lua_setmetatable(L, -2);
+  lua_setfield(L, -2, "");
+
   if (luaL_newmetatable(L, "lds_Stream")) {
     lua_pushvalue(L, -1);
     lua_setfield(L, -2, "__index");

+ 3 - 0
tup.config.sample

@@ -0,0 +1,3 @@
+CONFIG_LUA_CFLAGS=`pkg-config --cflags lua5.1`
+CONFIG_LUA_LFLAGS=
+CONFIG_NATIVE_CLIENT_PATH=/path/to/native_client