static int acmod_process_full_raw(acmod_t *acmod, int16 const **inout_raw, size_t *inout_n_samps) { int32 nfr, ntail; mfcc_t **cepptr; /* Write to logging file if any. */ if (acmod->rawfh) fwrite(*inout_raw, 2, *inout_n_samps, acmod->rawfh); /* Resize mfc_buf to fit. */ if (fe_process_frames(acmod->fe, NULL, inout_n_samps, NULL, &nfr) < 0) return -1; if (acmod->n_mfc_alloc < nfr + 1) { ckd_free_2d(acmod->mfc_buf); acmod->mfc_buf = ckd_calloc_2d(nfr + 1, fe_get_output_size(acmod->fe), sizeof(**acmod->mfc_buf)); acmod->n_mfc_alloc = nfr + 1; } acmod->n_mfc_frame = 0; acmod->mfc_outidx = 0; fe_start_utt(acmod->fe); if (fe_process_frames(acmod->fe, inout_raw, inout_n_samps, acmod->mfc_buf, &nfr) < 0) return -1; fe_end_utt(acmod->fe, acmod->mfc_buf[nfr], &ntail); nfr += ntail; cepptr = acmod->mfc_buf; nfr = acmod_process_full_cep(acmod, &cepptr, &nfr); acmod->n_mfc_frame = 0; return nfr; }
/** * Process PCM audio from a filehandle. Assume that wtf->infh is * positioned just after the file header. */ static int decode_pcm(sphinx_wave2feat_t *wtf) { size_t nsamp; int32 n, nfr, nchans, whichchan; uint32 nfloat; nchans = cmd_ln_int32_r(wtf->config, "-nchans"); whichchan = cmd_ln_int32_r(wtf->config, "-whichchan"); fe_start_utt(wtf->fe); nfloat = 0; while ((nsamp = fread(wtf->audio, 2, wtf->blocksize, wtf->infh)) != 0) { size_t nvec; int16 const *inspeech; /* Byteswap stuff here if necessary. */ if (wtf->byteswap) { for (n = 0; n < nsamp; ++n) SWAP_INT16(wtf->audio + n); } /* Mix or pick channels. */ if (nchans > 1) nsamp = mixnpick_channels(wtf->audio, nsamp, nchans, whichchan); inspeech = wtf->audio; nvec = wtf->featsize; /* Consume all samples. */ while (nsamp) { nfr = nvec; fe_process_frames(wtf->fe, &inspeech, &nsamp, wtf->feat, &nfr, NULL); if (nfr) { if ((n = (*wtf->ot->output_frames)(wtf, wtf->feat, nfr)) < 0) return -1; nfloat += n; } } inspeech = wtf->audio; } /* Now process any leftover audio frames. */ fe_end_utt(wtf->fe, wtf->feat[0], &nfr); if (nfr) { if ((n = (*wtf->ot->output_frames)(wtf, wtf->feat, nfr)) < 0) return -1; nfloat += n; } if (fclose(wtf->infh) == EOF) E_ERROR_SYSTEM("Failed to close input file"); wtf->infh = NULL; return nfloat; }
/** * Process PCM audio from a libsndfile file. FIXME: looks a lot like * decode_pcm! Also needs stereo support (as does decode_pcm). */ static int decode_sndfile(sphinx_wave2feat_t *wtf) { size_t nsamp; int32 nfr, nchans, whichchan; int nfloat, n; nchans = cmd_ln_int32_r(wtf->config, "-nchans"); whichchan = cmd_ln_int32_r(wtf->config, "-whichchan"); fe_start_utt(wtf->fe); nfloat = 0; while ((nsamp = sf_read_short(wtf->insfh, wtf->audio, wtf->blocksize)) != 0) { int16 const *inspeech; size_t nvec; /* Mix or pick channels. */ if (nchans > 1) nsamp = mixnpick_channels(wtf->audio, nsamp, nchans, whichchan); inspeech = wtf->audio; nvec = wtf->featsize; /* Consume all samples. */ while (nsamp) { nfr = nvec; fe_process_frames(wtf->fe, &inspeech, &nsamp, wtf->feat, &nfr, NULL); if (nfr) { if ((n = (*wtf->ot->output_frames)(wtf, wtf->feat, nfr)) < 0) return -1; nfloat += n; } } inspeech = wtf->audio; } /* Now process any leftover audio frames. */ fe_end_utt(wtf->fe, wtf->feat[0], &nfr); if (nfr) { if ((n = (*wtf->ot->output_frames)(wtf, wtf->feat, nfr)) < 0) return -1; nfloat += n; } sf_close(wtf->insfh); wtf->insfh = NULL; return nfloat; }
int acmod_end_utt(acmod_t *acmod) { int32 nfr = 0; acmod->state = ACMOD_ENDED; if (acmod->n_mfc_frame < acmod->n_mfc_alloc) { int inptr; /* Where to start writing them (circular buffer) */ inptr = (acmod->mfc_outidx + acmod->n_mfc_frame) % acmod->n_mfc_alloc; /* nfr is always either zero or one. */ fe_end_utt(acmod->fe, acmod->mfc_buf[inptr], &nfr); acmod->n_mfc_frame += nfr; /* Process whatever's left, and any leadout or update stats if needed. */ if (nfr) nfr = acmod_process_mfcbuf(acmod); else feat_update_stats(acmod->fcb); } if (acmod->mfcfh) { long outlen; int32 rv; outlen = (ftell(acmod->mfcfh) - 4) / 4; if (!WORDS_BIGENDIAN) SWAP_INT32(&outlen); /* Try to seek and write */ if ((rv = fseek(acmod->mfcfh, 0, SEEK_SET)) == 0) { fwrite(&outlen, 4, 1, acmod->mfcfh); } fclose(acmod->mfcfh); acmod->mfcfh = NULL; } if (acmod->rawfh) { fclose(acmod->rawfh); acmod->rawfh = NULL; } if (acmod->senfh) { fclose(acmod->senfh); acmod->senfh = NULL; } return nfr; }
int ld_utt_proc_raw_impl(live_decoder_t *decoder, int16 *samples, int32 num_samples, int32 begin_utt, int32 end_utt) { float32 dummy_frame[MAX_CEP_LEN]; float32 **frames = 0; int32 num_frames = 0; int32 num_features = 0; num_frames = fe_process_utt(decoder->fe, samples, num_samples, &frames); if (end_utt) { fe_end_utt(decoder->fe, dummy_frame); } if (num_frames > 0) { num_features = feat_s2mfc2feat_block(kbcore_fcb(decoder->kbcore), frames, num_frames, begin_utt, end_utt, decoder->features); } if (num_features > 0) { utt_decode_block(decoder->features, num_features, &decoder->frame_num, &decoder->kb, decoder->max_wpf, decoder->max_histpf, decoder->max_hmmpf, decoder->phones_skip, decoder->hmm_log); } if (frames) { ckd_free_2d((void **)frames); } return 0; }
void segment_audio() { FILE *file; int16 pcm_buf[BLOCKSIZE]; mfcc_t **cep_buf; int16 voiced_buf = NULL; int32 voiced_nsamps, out_frameidx, uttstart = 0; char file_name[1024]; uint8 cur_vad_state, vad_state, writing; int uttno, uttlen, sample_rate; int32 nframes, nframes_tmp; int16 frame_size, frame_shift, frame_rate; size_t k; sample_rate = (int) cmd_ln_float32_r(config, "-samprate"); frame_rate = cmd_ln_int32_r(config, "-frate"); frame_size = (int32) (cmd_ln_float32_r(config, "-wlen") * sample_rate + 0.5); frame_shift = (int32) (sample_rate / cmd_ln_int32_r(config, "-frate") + 0.5); nframes = (BLOCKSIZE - frame_size) / frame_shift; cep_buf = (mfcc_t **) ckd_calloc_2d(nframes, fe_get_output_size(fe), sizeof(mfcc_t)); uttno = 0; uttlen = 0; cur_vad_state = 0; voiced_nsamps = 0; writing = 0; file = NULL; fe_start_stream(fe); fe_start_utt(fe); while ((k = read_audio(pcm_buf, BLOCKSIZE)) > 0) { int16 const *pcm_buf_tmp; pcm_buf_tmp = &pcm_buf[0]; while (k) { nframes_tmp = nframes; fe_process_frames_ext(fe, &pcm_buf_tmp, &k, cep_buf, &nframes_tmp, voiced_buf, &voiced_nsamps, &out_frameidx); if (out_frameidx > 0) { uttstart = out_frameidx; } vad_state = fe_get_vad_state(fe); if (!cur_vad_state && vad_state) { /* silence->speech transition, time to start new file */ uttno++; if (!singlefile) { sprintf(file_name, "%s%04d.raw", infile_path, uttno); if ((file = fopen(file_name, "wb")) == NULL) E_FATAL_SYSTEM("Failed to open '%s' for writing", file_name); } else { sprintf(file_name, "%s.raw", infile_path); if ((file = fopen(file_name, "ab")) == NULL) E_FATAL_SYSTEM("Failed to open '%s' for writing", file_name); } writing = 1; } if (writing && file && voiced_nsamps > 0) { fwrite(voiced_buf, sizeof(int16), voiced_nsamps, file); uttlen += voiced_nsamps; } if (cur_vad_state && !vad_state) { /* speech -> silence transition, time to finish file */ fclose(file); printf("Utterance %04d: file %s start %.1f sec length %d samples ( %.2f sec )\n", uttno, file_name, ((double) uttstart) / frame_rate, uttlen, ((double) uttlen) / sample_rate); fflush(stdout); fe_end_utt(fe, cep_buf[0], &nframes_tmp); writing = 0; uttlen = 0; voiced_nsamps = 0; fe_start_utt(fe); } cur_vad_state = vad_state; } } if (writing) { fclose(file); printf("Utterance %04d: file %s start %.1f sec length %d samples ( %.2f sec )\n", uttno, file_name, ((double) uttstart) / frame_rate, uttlen, ((double) uttlen) / sample_rate); fflush(stdout); } fe_end_utt(fe, cep_buf[0], &nframes); ckd_free_2d(cep_buf); }
int ps_decoder_test(cmd_ln_t *config, char const *sname, char const *expected) { ps_decoder_t *ps; mfcc_t **cepbuf; FILE *rawfh; int16 *buf; int16 const *bptr; size_t nread; size_t nsamps; int32 nfr, i, score, prob; char const *hyp; char const *uttid; double n_speech, n_cpu, n_wall; ps_seg_t *seg; TEST_ASSERT(ps = ps_init(config)); /* Test it first with pocketsphinx_decode_raw() */ TEST_ASSERT(rawfh = fopen(DATADIR "/goforward.raw", "rb")); ps_decode_raw(ps, rawfh, "goforward", -1); hyp = ps_get_hyp(ps, &score, &uttid); prob = ps_get_prob(ps, &uttid); printf("%s (%s): %s (%d, %d)\n", sname, uttid, hyp, score, prob); TEST_EQUAL(0, strcmp(hyp, expected)); TEST_ASSERT(prob <= 0); ps_get_utt_time(ps, &n_speech, &n_cpu, &n_wall); printf("%.2f seconds speech, %.2f seconds CPU, %.2f seconds wall\n", n_speech, n_cpu, n_wall); printf("%.2f xRT (CPU), %.2f xRT (elapsed)\n", n_cpu / n_speech, n_wall / n_speech); /* Test it with ps_process_raw() */ clearerr(rawfh); fseek(rawfh, 0, SEEK_END); nsamps = ftell(rawfh) / sizeof(*buf); fseek(rawfh, 0, SEEK_SET); TEST_EQUAL(0, ps_start_utt(ps, NULL)); nsamps = 2048; buf = ckd_calloc(nsamps, sizeof(*buf)); while (!feof(rawfh)) { nread = fread(buf, sizeof(*buf), nsamps, rawfh); ps_process_raw(ps, buf, nread, FALSE, FALSE); } TEST_EQUAL(0, ps_end_utt(ps)); hyp = ps_get_hyp(ps, &score, &uttid); prob = ps_get_prob(ps, &uttid); printf("%s (%s): %s (%d, %d)\n", sname, uttid, hyp, score, prob); TEST_EQUAL(0, strcmp(uttid, "000000000")); TEST_EQUAL(0, strcmp(hyp, expected)); ps_get_utt_time(ps, &n_speech, &n_cpu, &n_wall); printf("%.2f seconds speech, %.2f seconds CPU, %.2f seconds wall\n", n_speech, n_cpu, n_wall); printf("%.2f xRT (CPU), %.2f xRT (elapsed)\n", n_cpu / n_speech, n_wall / n_speech); /* Now read the whole file and produce an MFCC buffer. */ clearerr(rawfh); fseek(rawfh, 0, SEEK_END); nsamps = ftell(rawfh) / sizeof(*buf); fseek(rawfh, 0, SEEK_SET); bptr = buf = ckd_realloc(buf, nsamps * sizeof(*buf)); TEST_EQUAL(nsamps, fread(buf, sizeof(*buf), nsamps, rawfh)); fe_process_frames(ps->acmod->fe, &bptr, &nsamps, NULL, &nfr); cepbuf = ckd_calloc_2d(nfr + 1, fe_get_output_size(ps->acmod->fe), sizeof(**cepbuf)); fe_start_utt(ps->acmod->fe); fe_process_frames(ps->acmod->fe, &bptr, &nsamps, cepbuf, &nfr); fe_end_utt(ps->acmod->fe, cepbuf[nfr], &i); /* Decode it with process_cep() */ TEST_EQUAL(0, ps_start_utt(ps, NULL)); for (i = 0; i < nfr; ++i) { ps_process_cep(ps, cepbuf + i, 1, FALSE, FALSE); } TEST_EQUAL(0, ps_end_utt(ps)); hyp = ps_get_hyp(ps, &score, &uttid); prob = ps_get_prob(ps, &uttid); printf("%s (%s): %s (%d, %d)\n", sname, uttid, hyp, score, prob); TEST_EQUAL(0, strcmp(uttid, "000000001")); TEST_EQUAL(0, strcmp(hyp, expected)); TEST_ASSERT(prob <= 0); for (seg = ps_seg_iter(ps, &score); seg; seg = ps_seg_next(seg)) { char const *word; int sf, ef; int32 post, lscr, ascr, lback; word = ps_seg_word(seg); ps_seg_frames(seg, &sf, &ef); post = ps_seg_prob(seg, &ascr, &lscr, &lback); printf("%s (%d:%d) P(w|o) = %f ascr = %d lscr = %d lback = %d\n", word, sf, ef, logmath_exp(ps_get_logmath(ps), post), ascr, lscr, lback); TEST_ASSERT(post <= 2); // Due to numerical errors with float it sometimes could go out of 0 } ps_get_utt_time(ps, &n_speech, &n_cpu, &n_wall); printf("%.2f seconds speech, %.2f seconds CPU, %.2f seconds wall\n", n_speech, n_cpu, n_wall); printf("%.2f xRT (CPU), %.2f xRT (elapsed)\n", n_cpu / n_speech, n_wall / n_speech); ps_get_all_time(ps, &n_speech, &n_cpu, &n_wall); printf("TOTAL: %.2f seconds speech, %.2f seconds CPU, %.2f seconds wall\n", n_speech, n_cpu, n_wall); printf("TOTAL: %.2f xRT (CPU), %.2f xRT (elapsed)\n", n_cpu / n_speech, n_wall / n_speech); fclose(rawfh); ps_free(ps); cmd_ln_free_r(config); ckd_free_2d(cepbuf); ckd_free(buf); return 0; }
int main(int argc, char *argv[]) { acmod_t *acmod; logmath_t *lmath; cmd_ln_t *config; FILE *rawfh; int16 *buf; int16 const *bptr; mfcc_t **cepbuf, **cptr; size_t nread, nsamps; int nfr; int frame_counter; int bestsen1[270]; lmath = logmath_init(1.0001, 0, 0); config = cmd_ln_init(NULL, ps_args(), TRUE, "-featparams", MODELDIR "/hmm/en_US/hub4wsj_sc_8k/feat.params", "-mdef", MODELDIR "/hmm/en_US/hub4wsj_sc_8k/mdef", "-mean", MODELDIR "/hmm/en_US/hub4wsj_sc_8k/means", "-var", MODELDIR "/hmm/en_US/hub4wsj_sc_8k/variances", "-tmat", MODELDIR "/hmm/en_US/hub4wsj_sc_8k/transition_matrices", "-sendump", MODELDIR "/hmm/en_US/hub4wsj_sc_8k/sendump", "-compallsen", "true", "-cmn", "prior", "-tmatfloor", "0.0001", "-mixwfloor", "0.001", "-varfloor", "0.0001", "-mmap", "no", "-topn", "4", "-ds", "1", "-input_endian", "little", "-samprate", "16000", NULL); TEST_ASSERT(config); TEST_ASSERT(acmod = acmod_init(config, lmath, NULL, NULL)); cmn_prior_set(acmod->fcb->cmn_struct, prior); nsamps = 2048; frame_counter = 0; buf = ckd_calloc(nsamps, sizeof(*buf)); TEST_ASSERT(rawfh = fopen(DATADIR "/goforward.raw", "rb")); TEST_EQUAL(0, acmod_start_utt(acmod)); E_INFO("Incremental(2048):\n"); while (!feof(rawfh)) { nread = fread(buf, sizeof(*buf), nsamps, rawfh); bptr = buf; while ((nfr = acmod_process_raw(acmod, &bptr, &nread, FALSE)) > 0 || nread > 0) { int16 const *senscr; int16 best_score; int frame_idx = -1, best_senid; while (acmod->n_feat_frame > 0) { senscr = acmod_score(acmod, &frame_idx); acmod_advance(acmod); best_score = acmod_best_score(acmod, &best_senid); E_INFO("Frame %d best senone %d score %d\n", frame_idx, best_senid, best_score); TEST_EQUAL(frame_counter, frame_idx); if (frame_counter < 190) bestsen1[frame_counter] = best_score; ++frame_counter; frame_idx = -1; } } } TEST_EQUAL(0, acmod_end_utt(acmod)); nread = 0; { int16 const *senscr; int16 best_score; int frame_idx = -1, best_senid; while (acmod->n_feat_frame > 0) { senscr = acmod_score(acmod, &frame_idx); acmod_advance(acmod); best_score = acmod_best_score(acmod, &best_senid); E_INFO("Frame %d best senone %d score %d\n", frame_idx, best_senid, best_score); if (frame_counter < 190) bestsen1[frame_counter] = best_score; TEST_EQUAL(frame_counter, frame_idx); ++frame_counter; frame_idx = -1; } } /* Now try to process the whole thing at once. */ E_INFO("Whole utterance:\n"); cmn_prior_set(acmod->fcb->cmn_struct, prior); nsamps = ftell(rawfh) / sizeof(*buf); clearerr(rawfh); fseek(rawfh, 0, SEEK_SET); buf = ckd_realloc(buf, nsamps * sizeof(*buf)); TEST_EQUAL(nsamps, fread(buf, sizeof(*buf), nsamps, rawfh)); bptr = buf; TEST_EQUAL(0, acmod_start_utt(acmod)); acmod_process_raw(acmod, &bptr, &nsamps, TRUE); TEST_EQUAL(0, acmod_end_utt(acmod)); { int16 const *senscr; int16 best_score; int frame_idx = -1, best_senid; frame_counter = 0; while (acmod->n_feat_frame > 0) { senscr = acmod_score(acmod, &frame_idx); acmod_advance(acmod); best_score = acmod_best_score(acmod, &best_senid); E_INFO("Frame %d best senone %d score %d\n", frame_idx, best_senid, best_score); if (frame_counter < 190) TEST_EQUAL_LOG(best_score, bestsen1[frame_counter]); TEST_EQUAL(frame_counter, frame_idx); ++frame_counter; frame_idx = -1; } } /* Now process MFCCs and make sure we get the same results. */ cepbuf = ckd_calloc_2d(frame_counter, fe_get_output_size(acmod->fe), sizeof(**cepbuf)); fe_start_utt(acmod->fe); nsamps = ftell(rawfh) / sizeof(*buf); bptr = buf; nfr = frame_counter; fe_process_frames(acmod->fe, &bptr, &nsamps, cepbuf, &nfr); fe_end_utt(acmod->fe, cepbuf[frame_counter-1], &nfr); E_INFO("Incremental(MFCC):\n"); cmn_prior_set(acmod->fcb->cmn_struct, prior); TEST_EQUAL(0, acmod_start_utt(acmod)); cptr = cepbuf; nfr = frame_counter; frame_counter = 0; while ((acmod_process_cep(acmod, &cptr, &nfr, FALSE)) > 0) { int16 const *senscr; int16 best_score; int frame_idx = -1, best_senid; while (acmod->n_feat_frame > 0) { senscr = acmod_score(acmod, &frame_idx); acmod_advance(acmod); best_score = acmod_best_score(acmod, &best_senid); E_INFO("Frame %d best senone %d score %d\n", frame_idx, best_senid, best_score); TEST_EQUAL(frame_counter, frame_idx); if (frame_counter < 190) TEST_EQUAL_LOG(best_score, bestsen1[frame_counter]); ++frame_counter; frame_idx = -1; } } TEST_EQUAL(0, acmod_end_utt(acmod)); nfr = 0; acmod_process_cep(acmod, &cptr, &nfr, FALSE); { int16 const *senscr; int16 best_score; int frame_idx = -1, best_senid; while (acmod->n_feat_frame > 0) { senscr = acmod_score(acmod, &frame_idx); acmod_advance(acmod); best_score = acmod_best_score(acmod, &best_senid); E_INFO("Frame %d best senone %d score %d\n", frame_idx, best_senid, best_score); TEST_EQUAL(frame_counter, frame_idx); if (frame_counter < 190) TEST_EQUAL_LOG(best_score, bestsen1[frame_counter]); ++frame_counter; frame_idx = -1; } } /* Note that we have to process the whole thing again because * !#@$@ s2mfc2feat modifies its argument (not for long) */ fe_start_utt(acmod->fe); nsamps = ftell(rawfh) / sizeof(*buf); bptr = buf; nfr = frame_counter; fe_process_frames(acmod->fe, &bptr, &nsamps, cepbuf, &nfr); fe_end_utt(acmod->fe, cepbuf[frame_counter-1], &nfr); E_INFO("Whole utterance (MFCC):\n"); cmn_prior_set(acmod->fcb->cmn_struct, prior); TEST_EQUAL(0, acmod_start_utt(acmod)); cptr = cepbuf; nfr = frame_counter; acmod_process_cep(acmod, &cptr, &nfr, TRUE); TEST_EQUAL(0, acmod_end_utt(acmod)); { int16 const *senscr; int16 best_score; int frame_idx = -1, best_senid; frame_counter = 0; while (acmod->n_feat_frame > 0) { senscr = acmod_score(acmod, &frame_idx); acmod_advance(acmod); best_score = acmod_best_score(acmod, &best_senid); E_INFO("Frame %d best senone %d score %d\n", frame_idx, best_senid, best_score); if (frame_counter < 190) TEST_EQUAL_LOG(best_score, bestsen1[frame_counter]); TEST_EQUAL(frame_counter, frame_idx); ++frame_counter; frame_idx = -1; } } E_INFO("Rewound (MFCC):\n"); TEST_EQUAL(0, acmod_rewind(acmod)); { int16 const *senscr; int16 best_score; int frame_idx = -1, best_senid; frame_counter = 0; while (acmod->n_feat_frame > 0) { senscr = acmod_score(acmod, &frame_idx); acmod_advance(acmod); best_score = acmod_best_score(acmod, &best_senid); E_INFO("Frame %d best senone %d score %d\n", frame_idx, best_senid, best_score); if (frame_counter < 190) TEST_EQUAL_LOG(best_score, bestsen1[frame_counter]); TEST_EQUAL(frame_counter, frame_idx); ++frame_counter; frame_idx = -1; } } /* Clean up, go home. */ ckd_free_2d(cepbuf); fclose(rawfh); ckd_free(buf); acmod_free(acmod); logmath_free(lmath); cmd_ln_free_r(config); return 0; }
int main(int argc, char *argv[]) { static const arg_t fe_args[] = { waveform_to_cepstral_command_line_macro(), { NULL, 0, NULL, NULL } }; FILE *raw; cmd_ln_t *config; fe_t *fe; int16 buf[1024]; int16 const *inptr; int32 frame_shift, frame_size; mfcc_t **cepbuf1, **cepbuf2, **cptr; int32 nfr, i; size_t nsamp; TEST_ASSERT(config = cmd_ln_parse_r(NULL, fe_args, argc, argv, FALSE)); TEST_ASSERT(fe = fe_init_auto_r(config)); TEST_EQUAL(fe_get_output_size(fe), DEFAULT_NUM_CEPSTRA); fe_get_input_size(fe, &frame_shift, &frame_size); TEST_EQUAL(frame_shift, DEFAULT_FRAME_SHIFT); TEST_EQUAL(frame_size, (int)(DEFAULT_WINDOW_LENGTH*DEFAULT_SAMPLING_RATE)); TEST_ASSERT(raw = fopen(TESTDATADIR "/chan3.raw", "rb")); TEST_EQUAL(0, fe_start_utt(fe)); TEST_EQUAL(1024, fread(buf, sizeof(int16), 1024, raw)); nsamp = 1024; TEST_ASSERT(fe_process_frames(fe, NULL, &nsamp, NULL, &nfr) >= 0); TEST_EQUAL(1024, nsamp); TEST_EQUAL(4, nfr); cepbuf1 = ckd_calloc_2d(5, DEFAULT_NUM_CEPSTRA, sizeof(**cepbuf1)); inptr = &buf[0]; nfr = 1; printf("frame_size %d frame_shift %d\n", frame_size, frame_shift); /* Process the first frame. */ TEST_ASSERT(fe_process_frames(fe, &inptr, &nsamp, &cepbuf1[0], &nfr) >= 0); printf("inptr %d nsamp %d nfr %d\n", inptr - buf, nsamp, nfr); TEST_EQUAL(nfr, 1); /* Note that this next one won't actually consume any frames * of input, because it already got sufficient overflow * samples last time around. This is implementation-dependent * so we shouldn't actually test for it. */ TEST_ASSERT(fe_process_frames(fe, &inptr, &nsamp, &cepbuf1[1], &nfr) >= 0); printf("inptr %d nsamp %d nfr %d\n", inptr - buf, nsamp, nfr); TEST_EQUAL(nfr, 1); TEST_ASSERT(fe_process_frames(fe, &inptr, &nsamp, &cepbuf1[2], &nfr) >= 0); printf("inptr %d nsamp %d nfr %d\n", inptr - buf, nsamp, nfr); TEST_EQUAL(nfr, 1); TEST_ASSERT(fe_process_frames(fe, &inptr, &nsamp, &cepbuf1[3], &nfr) >= 0); printf("inptr %d nsamp %d nfr %d\n", inptr - buf, nsamp, nfr); TEST_EQUAL(nfr, 1); TEST_ASSERT(fe_end_utt(fe, cepbuf1[4], &nfr) >= 0); printf("nfr %d\n", nfr); TEST_EQUAL(nfr, 1); /* What we *should* test is that the output we get by * processing one frame at a time is exactly the same as what * we get from doing them all at once. So let's do that */ cepbuf2 = ckd_calloc_2d(5, DEFAULT_NUM_CEPSTRA, sizeof(**cepbuf2)); inptr = &buf[0]; nfr = 5; nsamp = 1024; TEST_EQUAL(0, fe_start_utt(fe)); TEST_ASSERT(fe_process_frames(fe, &inptr, &nsamp, cepbuf2, &nfr) >= 0); printf("nfr %d\n", nfr); TEST_EQUAL(nfr, 4); nfr = 1; TEST_ASSERT(fe_end_utt(fe, cepbuf2[4], &nfr) >= 0); printf("nfr %d\n", nfr); TEST_EQUAL(nfr, 1); for (i = 0; i < 5; ++i) { int j; printf("%d: ", i); for (j = 0; j < DEFAULT_NUM_CEPSTRA; ++j) { printf("%.2f,%.2f ", MFCC2FLOAT(cepbuf1[i][j]), MFCC2FLOAT(cepbuf2[i][j])); TEST_EQUAL_FLOAT(cepbuf1[i][j], cepbuf2[i][j]); } printf("\n"); } /* Now, also test to make sure that even if we feed data in * little tiny bits we can still make things work. */ memset(cepbuf2[0], 0, 5 * DEFAULT_NUM_CEPSTRA * sizeof(**cepbuf2)); inptr = &buf[0]; cptr = &cepbuf2[0]; nfr = 5; i = 5; nsamp = 256; TEST_EQUAL(0, fe_start_utt(fe)); TEST_ASSERT(fe_process_frames(fe, &inptr, &nsamp, cptr, &i) >= 0); printf("inptr %d nsamp %d nfr %d\n", inptr - buf, nsamp, i); cptr += i; nfr -= i; i = nfr; nsamp = 256; TEST_ASSERT(fe_process_frames(fe, &inptr, &nsamp, cptr, &i) >= 0); printf("inptr %d nsamp %d nfr %d\n", inptr - buf, nsamp, i); cptr += i; nfr -= i; i = nfr; nsamp = 256; TEST_ASSERT(fe_process_frames(fe, &inptr, &nsamp, cptr, &i) >= 0); printf("inptr %d nsamp %d nfr %d\n", inptr - buf, nsamp, i); cptr += i; nfr -= i; i = nfr; nsamp = 256; TEST_ASSERT(fe_process_frames(fe, &inptr, &nsamp, cptr, &i) >= 0); printf("inptr %d nsamp %d nfr %d\n", inptr - buf, nsamp, i); cptr += i; nfr -= i; TEST_ASSERT(fe_end_utt(fe, *cptr, &nfr) >= 0); printf("nfr %d\n", nfr); TEST_EQUAL(nfr, 1); for (i = 0; i < 5; ++i) { int j; printf("%d: ", i); for (j = 0; j < DEFAULT_NUM_CEPSTRA; ++j) { printf("%.2f,%.2f ", MFCC2FLOAT(cepbuf1[i][j]), MFCC2FLOAT(cepbuf2[i][j])); TEST_EQUAL_FLOAT(cepbuf1[i][j], cepbuf2[i][j]); } printf("\n"); } /* And now, finally, test fe_process_utt() */ inptr = &buf[0]; i = 0; TEST_EQUAL(0, fe_start_utt(fe)); TEST_ASSERT(fe_process_utt(fe, inptr, 256, &cptr, &nfr) >= 0); printf("i %d nfr %d\n", i, nfr); if (nfr) memcpy(cepbuf2[i], cptr[0], nfr * DEFAULT_NUM_CEPSTRA * sizeof(**cptr)); ckd_free_2d(cptr); i += nfr; inptr += 256; TEST_ASSERT(fe_process_utt(fe, inptr, 256, &cptr, &nfr) >= 0); printf("i %d nfr %d\n", i, nfr); if (nfr) memcpy(cepbuf2[i], cptr[0], nfr * DEFAULT_NUM_CEPSTRA * sizeof(**cptr)); ckd_free_2d(cptr); i += nfr; inptr += 256; TEST_ASSERT(fe_process_utt(fe, inptr, 256, &cptr, &nfr) >= 0); printf("i %d nfr %d\n", i, nfr); if (nfr) memcpy(cepbuf2[i], cptr[0], nfr * DEFAULT_NUM_CEPSTRA * sizeof(**cptr)); ckd_free_2d(cptr); i += nfr; inptr += 256; TEST_ASSERT(fe_process_utt(fe, inptr, 256, &cptr, &nfr) >= 0); printf("i %d nfr %d\n", i, nfr); if (nfr) memcpy(cepbuf2[i], cptr[0], nfr * DEFAULT_NUM_CEPSTRA * sizeof(**cptr)); ckd_free_2d(cptr); i += nfr; inptr += 256; TEST_ASSERT(fe_end_utt(fe, cepbuf2[i], &nfr) >= 0); printf("i %d nfr %d\n", i, nfr); TEST_EQUAL(nfr, 1); for (i = 0; i < 5; ++i) { int j; printf("%d: ", i); for (j = 0; j < DEFAULT_NUM_CEPSTRA; ++j) { printf("%.2f,%.2f ", MFCC2FLOAT(cepbuf1[i][j]), MFCC2FLOAT(cepbuf2[i][j])); TEST_EQUAL_FLOAT(cepbuf1[i][j], cepbuf2[i][j]); } printf("\n"); } ckd_free_2d(cepbuf1); ckd_free_2d(cepbuf2); fclose(raw); fe_free(fe); return 0; }
int32 live_utt_decode_block (int16 *samples, int32 nsamples, int32 live_endutt, partialhyp_t **ohyp) { static int32 live_begin_new_utt = 1; static int32 frmno; float32 **live_feat; int32 live_nfr, live_nfeatvec; int32 nwds; /* int32 id; */ /* unreferenced variable */ /* glist_t hyp; */ /* unreferenced variable */ /* gnode_t *gn; */ /* unreferenced variable */ /* hyp_t *h; */ /* unreferenced variable */ /* dict_t *dict; */ /* unreferenced variable */ float32 **mfcbuf; if (live_begin_new_utt){ fe_start_utt(fe); utt_begin (kb); frmno = 0; kb->nfr = 0; kb->utt_hmm_eval = 0; kb->utt_sen_eval = 0; kb->utt_gau_eval = 0; live_begin_new_utt = 0; } sample_blk++; /* 10.jan.01 RAH, fe_process_utt now requires ***mfcbuf and it allocates the memory internally) */ mfcbuf = NULL; live_nfr = fe_process_utt(fe, samples, nsamples, &mfcbuf); /* */ if (live_endutt) /* RAH, It seems that we shouldn't throw out this data */ fe_end_utt(fe,dummyframe); /* Flush out the fe */ /* Compute feature vectors */ live_nfeatvec = feat_s2mfc2feat_block(kbcore_fcb(kbcore), mfcbuf, live_nfr, live_begin_new_utt, live_endutt, &live_feat); E_INFO ("live_nfeatvec: %ld\n",live_nfeatvec); /* decode the block */ if (sample_blk<=START_BLOCK) single_utt_decode_block (live_feat, live_nfeatvec, &frmno, kb, maxwpf, maxhistpf, maxhmmpf, ptranskip, hmmdumpfp); else utt_decode_block (live_feat, live_nfeatvec, &frmno, kb, maxwpf, maxhistpf, maxhmmpf, ptranskip, hmmdumpfp); /* Pull out partial hypothesis */ nwds = live_get_partialhyp(live_endutt); *ohyp = parthyp; /* Clean up */ if (live_endutt) { live_begin_new_utt = 1; kb->tot_fr += kb->nfr; utt_end(kb); } else { live_begin_new_utt = 0; } /* I'm starting to think that fe_process_utt should not be allocating its memory, that or it should allocate some max and just keep on going, this idea of constantly allocating freeing memory seems dangerous to me.*/ ckd_free_2d((void **) mfcbuf); /* RAH, this must be freed since fe_process_utt allocates it */ return(nwds); }
int32 live_utt_decode_block (int16 *samples, int32 nsamples, int32 live_endutt, partialhyp_t **ohyp) { static int32 live_begin_new_utt = 1; static int32 frmno; static float32 ***live_feat = NULL; int32 live_nfr, live_nfeatvec; int32 nwds =0; float32 **mfcbuf; /* int i,j;*/ /* 2004/08/27 L Galescu <*****@*****.**> -- added raw audio file saving */ static char uttfn[1024]; static FILE *rawfp = NULL; int16 block_peak_amplitude; if(live_feat==NULL) live_feat = feat_array_alloc (kbcore_fcb(kbcore), LIVEBUFBLOCKSIZE); if (live_begin_new_utt){ fe_start_utt(fe); utt_begin (kb); frmno = 0; kb->nfr = 0; kb->utt_hmm_eval = 0; kb->utt_sen_eval = 0; kb->utt_gau_eval = 0; live_begin_new_utt = 0; sprintf(uttfn, "%s/%s.raw", cmd_ln_str("-outrawdir"), kb->uttid); rawfp = fopen(uttfn, "wb"); } /* 10.jan.01 RAH, fe_process_utt now requires ***mfcbuf and it allocates the memory internally) */ mfcbuf = NULL; /* LG 20080613 */ block_peak_amplitude = get_peak_amplitude(samples, nsamples); if (block_peak_amplitude > peak_amplitude) peak_amplitude = block_peak_amplitude; E_INFO("segment peak %d\n",peak_amplitude); live_nfr = fe_process_utt(fe, samples, nsamples, &mfcbuf); /**/ if (rawfp != NULL) { fwrite(samples, sizeof(int16), nsamples, rawfp); if (live_endutt) fclose(rawfp); } if (live_endutt) { /* RAH, It seems that we shouldn't throw out this data */ fe_end_utt(fe,dummyframe); /* Flush out the fe */ } #if 0 E_INFO("Number frame after fe_process_utt %d\n",live_nfr); for(i=0;i<live_nfr;i++){ printf("%d ",i); for(j=0;j<13;j++){ printf("%f ",mfcbuf[i][j]); fflush(stdout); } printf("\n"); fflush(stdout); } #endif /* lgalescu 2004/08/22 -- i am under the impression that * feat_s2mfc2feat_block() needs to be called at the end of utt * even if no frames need processing */ /* lgalescu 2004/10/13 -- rescinded the above */ if(live_nfr>0){ /* Compute feature vectors */ live_nfeatvec = feat_s2mfc2feat_block(kbcore_fcb(kbcore), mfcbuf, live_nfr, live_begin_new_utt, live_endutt, live_feat); #if 0 E_INFO ("live_nfeatvec: %ld\n",live_nfeatvec); #endif #if 0 E_INFO("Current frame number %d, Number of frames %d, Number frame after feat_s2mfcfeat_block %d\n",frmno,live_nfr,live_nfeatvec); for(i=0;i<live_nfeatvec;i++){ printf("%d\n",i); printf("Cep: "); fflush(stdout); for(j=0;j<13;j++){ printf("%f ",live_feat[i][0][j]); fflush(stdout); } printf("\n"); fflush(stdout); printf("Del: "); fflush(stdout); for(j=13;j<26;j++){ printf("%f ",live_feat[i][0][j]); fflush(stdout); } printf("\n"); fflush(stdout); printf("Acc: "); fflush(stdout); for(j=26;j<39;j++){ printf("%f ",live_feat[i][0][j]); fflush(stdout); } printf("\n"); fflush(stdout); } #endif /* decode the block */ utt_decode_block (live_feat, live_nfeatvec, &frmno, kb, maxwpf, maxhistpf, maxhmmpf, ptranskip, hmmdumpfp); /* lgalescu 2004/08/21 * moved the following block out of the previous if(){} because we need * the output even when no feature computation has to be done. */ /* lgalescu 2004/10/13 -- rescinded */ /* Pull out partial hypothesis */ nwds = live_get_partialhyp(live_endutt); *ohyp = parthyp; parthyplen = nwds; } /* Clean up */ if (live_endutt) { live_begin_new_utt = 1; kb->tot_fr += kb->nfr; utt_end(kb); } else { live_begin_new_utt = 0; } /* I'm starting to think that fe_process_utt should not be allocating its * memory, that or it should allocate some max and just keep on going, * this idea of constantly allocating freeing memory seems dangerous to me. */ /* 20040318 ARCHAN : It sounds extremely dangerous to me and I will * eliminate it sometime. */ /* lgalescu: i second that! the memory issue needs to be investigated: after a run on linux, i noticed some 1.6M of memory having "disappeared"! */ if(live_nfr>0){ ckd_free_2d((void **) mfcbuf); /* RAH, this must be freed since fe_process_utt allocates it */ } return(parthyplen); }
void ld_process_raw_impl(live_decoder_t * _decoder, int16 * samples, int32 num_samples, int32 end_utt) { float32 dummy_frame[MAX_CEP_LEN]; float32 **frames = 0; int32 num_frames = 0; int32 num_features = 0; int32 begin_utt = _decoder->num_frames_entered == 0; int32 return_value; int i; assert(_decoder != NULL); if (begin_utt) { fe_start_utt(_decoder->fe); } if (_decoder->swap) { for (i = 0; i < num_samples; i++) { SWAP_INT16(samples + i); } } return_value = fe_process_utt(_decoder->fe, samples, num_samples, &frames, &num_frames); if (end_utt) { return_value = fe_end_utt(_decoder->fe, dummy_frame, &num_frames); if (num_frames != 0) { /* ARCHAN: If num_frames !=0, assign this last ending frame to frames again. The computation will then be correct. Should clean up the finite state logic in fe_interface layer. */ frames = (float32 **) ckd_calloc_2d(1, _decoder->fe->NUM_CEPSTRA, sizeof(float32)); memcpy(frames[0], dummy_frame, _decoder->fe->NUM_CEPSTRA * sizeof(float32)); } } if (FE_ZERO_ENERGY_ERROR == return_value) { E_WARN("Zero energy frame(s). Consider using dither\n"); } if (num_frames > 0) { num_features = feat_s2mfc2feat_block(kbcore_fcb(_decoder->kbcore), frames, num_frames, begin_utt, end_utt, _decoder->features); _decoder->num_frames_entered += num_frames; } if (num_features > 0) { utt_decode_block(_decoder->features, num_features, &_decoder->num_frames_decoded, &_decoder->kb); } if (frames != NULL) { ckd_free_2d((void **) frames); } }
int main (int32 argc, char *argv[]) { char line[4096], filename[4096], idspec[4096], *uttid, *result; int32 sf, ef, sps, adcin, nf; int16 adbuf[4096]; int32 i, k; float32 **mfcbuf; CDCN_type *cdcn; param_t param; fe_t *fe = NULL; fbs_init (argc, argv); /* Assume that cdcn_init is part of the above fbs_init() */ cdcn = uttproc_get_cdcn_ptr(); adcin = query_adc_input(); assert (adcin); /* Limited to processing audio input files (not cep) */ sps = query_sampling_rate(); fe_init_params(¶m); param.SAMPLING_RATE = (float)sps; if ((fe = fe_init (¶m)) == NULL) { E_ERROR("fe_init() failed to initialize\n"); exit (-1); } mfcbuf = (float32 **) ckd_calloc_2d (8192, 13, sizeof(float32)); /* Process "control file" input through stdin */ while (fgets (line, sizeof(line), stdin) != NULL) { if (uttproc_parse_ctlfile_entry (line, filename, &sf, &ef, idspec) < 0) continue; assert ((sf < 0) && (ef < 0)); /* Processing entire input file */ uttid = build_uttid (idspec); uttproc_begin_utt (uttid); /* Convert raw data file to cepstra */ if (uttfile_open (filename) < 0) { E_ERROR("uttfile_open(%s) failed\n", filename); continue; } fe_start_utt(fe); nf = 0; while ((k = adc_file_read (adbuf, 4096)) >= 0) { if (fe_process_utt (fe, adbuf, k, mfcbuf+nf, &k) == FE_ZERO_ENERGY_ERROR) { E_WARN("Frames with zero energy. Consider using dither\n"); } nf += k; /* WARNING!! No check for mfcbuf overflow */ } fe_end_utt(fe, mfcbuf[nf], &k); fe_close(fe); uttfile_close (); if (nf <= 0) { E_ERROR("Empty utterance\n"); continue; } else E_INFO("%d frames\n", nf); /* Update CDCN module */ cdcn_converged_update (mfcbuf, /* cepstra buffer */ nf, /* Number of frames */ cdcn, /* The CDCN wrapper */ 1 /* One iteration */ ); /* CDCN */ for (i = 0; i < nf; i++) cdcn_norm (mfcbuf[i], cdcn); /* Process normalized cepstra */ uttproc_cepdata (mfcbuf, nf, 1); uttproc_end_utt (); uttproc_result (&k, &result, 1); printf ("\n"); fflush (stdout); } ckd_free_2d((void **)mfcbuf); fbs_end (); return 0; }