diff options
Diffstat (limited to 'kaldi_io/src')
-rw-r--r-- | kaldi_io/src/cwrapper_kaldi.cpp | 111 | ||||
-rw-r--r-- | kaldi_io/src/cwrapper_kaldi.h | 29 | ||||
-rw-r--r-- | kaldi_io/src/init.c | 106 | ||||
-rw-r--r-- | kaldi_io/src/test.c | 48 |
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, [email protected] +* 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; +} |