summaryrefslogtreecommitdiff
path: root/kaldi_io/src
diff options
context:
space:
mode:
Diffstat (limited to 'kaldi_io/src')
-rw-r--r--kaldi_io/src/cwrapper_kaldi.cpp111
-rw-r--r--kaldi_io/src/cwrapper_kaldi.h29
-rw-r--r--kaldi_io/src/init.c106
-rw-r--r--kaldi_io/src/test.c48
4 files changed, 294 insertions, 0 deletions
diff --git a/kaldi_io/src/cwrapper_kaldi.cpp b/kaldi_io/src/cwrapper_kaldi.cpp
new file mode 100644
index 0000000..f48d343
--- /dev/null
+++ b/kaldi_io/src/cwrapper_kaldi.cpp
@@ -0,0 +1,111 @@
+#include <string>
+#include "base/kaldi-common.h"
+#include "hmm/posterior.h"
+#include "util/table-types.h"
+typedef kaldi::BaseFloat BaseFloat;
+
+extern "C" {
+#include "cwrapper_kaldi.h"
+#include "string.h"
+#include "assert.h"
+#include "nerv/common.h"
+
+ extern Matrix *nerv_matrix_host_float_create(long nrow, long ncol, Status *status);
+ extern Matrix *nerv_matrix_host_double_create(long nrow, long ncol, Status *status);
+
+ struct KaldiFeatureRepo {
+ kaldi::SequentialBaseFloatMatrixReader* feature_reader;
+ string utt;
+ };
+
+ KaldiFeatureRepo *kaldi_feature_repo_new(const char *feature_rspecifier) {
+ KaldiFeatureRepo *repo = new KaldiFeatureRepo();
+ repo->feature_reader = new kaldi::SequentialBaseFloatMatrixReader(string(feature_rspecifier));
+ return repo;
+ }
+
+ Matrix *kaldi_feature_repo_read_utterance(KaldiFeatureRepo *repo, lua_State *L, int debug) {
+ Matrix *mat; /* nerv implementation */
+
+ repo->utt = repo->feature_reader->Key();
+ kaldi::Matrix<BaseFloat> kmat = repo->feature_reader->Value();
+
+ int n = kmat.NumRows();
+ int m = kmat.NumCols();
+ Status status;
+ assert(sizeof(BaseFloat) == sizeof(float));
+ if(sizeof(BaseFloat) == sizeof(float))
+ mat = nerv_matrix_host_float_create(n, m, &status);
+ else if(sizeof(BaseFloat) == sizeof(double))
+ mat = nerv_matrix_host_double_create(n, m, &status);
+ NERV_LUA_CHECK_STATUS(L, status);
+ size_t stride = mat->stride;
+ if (debug)
+ fprintf(stderr, "[kaldi] feature: %s %d %d\n", repo->utt.c_str(), n, m);
+
+ for (int i = 0; i < n; i++)
+ {
+ const BaseFloat *row = kmat.RowData(i);
+ BaseFloat *nerv_row = (BaseFloat *)((char *)mat->data.f + i * stride);
+ /* use memmove to copy the row, since KaldiLib uses compact storage */
+ memmove(nerv_row, row, sizeof(BaseFloat) * m);
+ }
+ return mat;
+ }
+
+ void kaldi_feature_repo_next(KaldiFeatureRepo *repo) {
+ repo->feature_reader->Next();
+ }
+
+ int kaldi_feature_repo_is_end(KaldiFeatureRepo *repo) {
+ return repo->feature_reader->Done();
+ }
+
+ void kaldi_feature_repo_destroy(KaldiFeatureRepo *repo) {
+ if (repo->feature_reader)
+ delete repo->feature_reader;
+ delete repo;
+ }
+
+ struct KaldiLabelRepo {
+ kaldi::RandomAccessPosteriorReader *targets_reader;
+ };
+
+ KaldiLabelRepo *kaldi_label_repo_new(const char *targets_rspecifier, const char *fmt) {
+ KaldiLabelRepo *repo = new KaldiLabelRepo();
+ repo->targets_reader = new kaldi::RandomAccessPosteriorReader(string(targets_rspecifier));
+ return repo;
+ }
+
+ Matrix *kaldi_label_repo_read_utterance(KaldiLabelRepo *repo, KaldiFeatureRepo *frepo, int frm_ext, int nframes,
+ lua_State *L,
+ int debug) {
+ Matrix *mat;
+ kaldi::Posterior targets = repo->targets_reader->Value(frepo->utt);
+
+ int n = targets.size() < nframes ? targets.size() : nframes;
+ int m = (int)targets[0].size();
+
+ Status status;
+ assert(sizeof(BaseFloat) == sizeof(float));
+ if(sizeof(BaseFloat) == sizeof(float))
+ mat = nerv_matrix_host_float_create(n, m, &status);
+ else if(sizeof(BaseFloat) == sizeof(double))
+ mat = nerv_matrix_host_double_create(n, m, &status);
+ NERV_LUA_CHECK_STATUS(L, status);
+ size_t stride = mat->stride;
+
+ if (debug)
+ fprintf(stderr, "[kaldi] label: %s %d %d\n", frepo->utt.c_str(), n, m);
+ for (int i = 0; i < n; i++)
+ for(int j = 0; j < m; j++)
+ *((BaseFloat *)((char *)mat->data.f + (i * stride + j))) = (BaseFloat)targets[i][j].first;
+ return mat;
+ }
+
+ void kaldi_label_repo_destroy(KaldiLabelRepo *repo) {
+ if(repo->targets_reader)
+ delete repo->targets_reader;
+ delete repo;
+ }
+}
diff --git a/kaldi_io/src/cwrapper_kaldi.h b/kaldi_io/src/cwrapper_kaldi.h
new file mode 100644
index 0000000..e34cb5a
--- /dev/null
+++ b/kaldi_io/src/cwrapper_kaldi.h
@@ -0,0 +1,29 @@
+#ifndef NERV_kaldi_KALDI_IO_CWRAPPER
+#define NERV_kaldi_KALDI_IO_CWRAPPER
+#include "nerv/matrix/matrix.h"
+#include "nerv/common.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ typedef struct KaldiFeatureRepo KaldiFeatureRepo;
+
+ KaldiFeatureRepo *kaldi_feature_repo_new(const char *);
+ Matrix *kaldi_feature_repo_read_utterance(KaldiFeatureRepo *repo, lua_State *L, int debug);
+ void kaldi_feature_repo_next(KaldiFeatureRepo *repo);
+ int kaldi_feature_repo_is_end(KaldiFeatureRepo *repo);
+ void kaldi_feature_repo_destroy(KaldiFeatureRepo *repo);
+
+ typedef struct KaldiLabelRepo KaldiLabelRepo;
+
+ KaldiLabelRepo *kaldi_label_repo_new(const char *, const char *fmt);
+
+ Matrix *kaldi_label_repo_read_utterance(KaldiLabelRepo *repo, KaldiFeatureRepo *, int, int,
+ lua_State *L,
+ int debug);
+
+ void kaldi_label_repo_destroy(KaldiLabelRepo *repo);
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/kaldi_io/src/init.c b/kaldi_io/src/init.c
new file mode 100644
index 0000000..413452c
--- /dev/null
+++ b/kaldi_io/src/init.c
@@ -0,0 +1,106 @@
+#include "nerv/common.h"
+#include "cwrapper_kaldi.h"
+#include <stdio.h>
+
+const char *nerv_kaldi_feat_repo_tname = "nerv.KaldiFeatureRepo";
+const char *nerv_kaldi_label_repo_tname = "nerv.KaldiLabelRepo";
+const char *nerv_matrix_host_float_tname = "nerv.MMatrixFloat";
+
+static int feat_repo_new(lua_State *L) {
+ const char *feature_rsepcifier = luaL_checkstring(L, 1);
+ KaldiFeatureRepo *repo = kaldi_feature_repo_new(feature_rsepcifier);
+ luaT_pushudata(L, repo, nerv_kaldi_feat_repo_tname);
+ return 1;
+}
+
+static int feat_repo_destroy(lua_State *L) {
+ KaldiFeatureRepo *repo = luaT_checkudata(L, 1, nerv_kaldi_feat_repo_tname);
+ kaldi_feature_repo_destroy(repo);
+ return 0;
+}
+
+static int feat_repo_current_utterance(lua_State *L) {
+ KaldiFeatureRepo *repo = luaT_checkudata(L, 1, nerv_kaldi_feat_repo_tname);
+ int debug;
+ if (!lua_isboolean(L, 2))
+ nerv_error(L, "debug flag should be a boolean");
+ debug = lua_toboolean(L, 2);
+ Matrix *utter = kaldi_feature_repo_read_utterance(repo, L, debug);
+ luaT_pushudata(L, utter, nerv_matrix_host_float_tname);
+ return 1;
+}
+
+static int feat_repo_next(lua_State *L) {
+ KaldiFeatureRepo *repo = luaT_checkudata(L, 1, nerv_kaldi_feat_repo_tname);
+ kaldi_feature_repo_next(repo);
+ return 0;
+}
+
+static int feat_repo_is_end(lua_State *L) {
+ KaldiFeatureRepo *repo = luaT_checkudata(L, 1, nerv_kaldi_feat_repo_tname);
+ lua_pushboolean(L, kaldi_feature_repo_is_end(repo));
+ return 1;
+}
+
+static const luaL_Reg feat_repo_methods[] = {
+ {"cur_utter", feat_repo_current_utterance},
+ {"next", feat_repo_next},
+ {"is_end", feat_repo_is_end},
+ {NULL, NULL}
+};
+
+static int label_repo_new(lua_State *L) {
+ const char *targets_rspecifier = luaL_checkstring(L, 1);
+ const char *fmt = luaL_checkstring(L, 2);
+ KaldiLabelRepo *repo = kaldi_label_repo_new(targets_rspecifier, fmt);
+ luaT_pushudata(L, repo, nerv_kaldi_label_repo_tname);
+ return 1;
+}
+
+static int label_repo_read_utterance(lua_State *L) {
+ KaldiLabelRepo *repo = luaT_checkudata(L, 1, nerv_kaldi_label_repo_tname);
+ KaldiFeatureRepo *feat_repo = luaT_checkudata(L, 2, nerv_kaldi_feat_repo_tname);
+ int frm_ext, nframes, debug;
+ if (!lua_isnumber(L, 3))
+ nerv_error(L, "frm_ext should be a number");
+ frm_ext = lua_tonumber(L, 3);
+ if (!lua_isnumber(L, 4))
+ nerv_error(L, "nframes should be a number");
+ nframes = lua_tonumber(L, 4);
+ if (!lua_isboolean(L, 5))
+ nerv_error(L, "debug flag should be a boolean");
+ debug = lua_toboolean(L, 5);
+ Matrix *utter = kaldi_label_repo_read_utterance(repo, feat_repo, frm_ext, nframes, L, debug);
+ luaT_pushudata(L, utter, nerv_matrix_host_float_tname);
+ return 1;
+}
+
+static int label_repo_destroy(lua_State *L) {
+ KaldiLabelRepo *repo = luaT_checkudata(L, 1, nerv_kaldi_label_repo_tname);
+ kaldi_label_repo_destroy(repo);
+ return 0;
+}
+
+static const luaL_Reg label_repo_methods[] = {
+ {"get_utter", label_repo_read_utterance},
+ {NULL, NULL}
+};
+
+static void feat_repo_init(lua_State *L) {
+ luaT_newmetatable(L, nerv_kaldi_feat_repo_tname, NULL,
+ feat_repo_new, feat_repo_destroy, NULL);
+ luaL_register(L, NULL, feat_repo_methods);
+ lua_pop(L, 1);
+}
+
+static void label_repo_init(lua_State *L) {
+ luaT_newmetatable(L, nerv_kaldi_label_repo_tname, NULL,
+ label_repo_new, label_repo_destroy, NULL);
+ luaL_register(L, NULL, label_repo_methods);
+ lua_pop(L, 1);
+}
+
+void kaldi_io_init(lua_State *L) {
+ feat_repo_init(L);
+ label_repo_init(L);
+}
diff --git a/kaldi_io/src/test.c b/kaldi_io/src/test.c
new file mode 100644
index 0000000..e92b4c9
--- /dev/null
+++ b/kaldi_io/src/test.c
@@ -0,0 +1,48 @@
+/*********************************************************************************
+* File Name : test.c
+* Created By : YIMMON, yimmon.zhuang@gmail.com
+* Creation Date : [2015-08-05 17:39]
+* Last Modified : [2015-08-06 14:28]
+* Description :
+**********************************************************************************/
+
+#include "cwrapper_kaldi.h"
+#include <stdio.h>
+
+char feature_rspecifier[] = {"ark:/slfs6/users/ymz09/kaldi/src/featbin/copy-feats scp:/slfs6/users/ymz09/swb_ivec/train_bp.scp ark:- |"};
+
+void print_nerv_matrix(Matrix *mat) {
+ int n = mat->nrow;
+ int m = mat->ncol;
+ int i, j;
+ size_t stride = mat->stride;
+ for (i = 0; i < n; i++)
+ {
+ float *nerv_row = (float *)((char *)mat->data.f + i * stride);
+ for (j = 0; j < m; j++)
+ printf("%.8f ", nerv_row[j]);
+ puts("");
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ Matrix *mat;
+ KaldiFeatureRepo *repo = kaldi_feature_repo_new(feature_rspecifier);
+
+ mat = kaldi_feature_repo_read_utterance(repo, NULL, 1);
+ printf("1st uttrance\n");
+ print_nerv_matrix(mat);
+
+ kaldi_feature_repo_next(repo);
+
+ mat = kaldi_feature_repo_read_utterance(repo, NULL, 1);
+ printf("2nd uttrance\n");
+ print_nerv_matrix(mat);
+
+ printf("is end: %d\n", kaldi_feature_repo_is_end(repo));
+
+ kaldi_feature_repo_destroy(repo);
+
+ return 0;
+}