1 #include <stdio.h>
2 #include <errno.h>
3 
4 #include "fe.h"
5 #include "feat.h"
6 #include "cmd_ln.h"
7 #include "ckd_alloc.h"
8 
9 #include "test_macros.h"
10 
11 int
main(int argc,char * argv[])12 main(int argc, char *argv[])
13 {
14 	static const arg_t fe_args[] = {
15 		waveform_to_cepstral_command_line_macro(),
16 		{ NULL, 0, NULL, NULL }
17 	};
18 	FILE *raw;
19 	cmd_ln_t *config;
20 	fe_t *fe;
21 	feat_t *fcb;
22 	int16 buf[2048];
23 	mfcc_t **cepbuf, **cptr;
24 	mfcc_t ***featbuf1, ***featbuf2, ***fptr;
25 	size_t nsamp;
26 	int32 total_frames, ncep, nfr, i;
27 
28 	if ((raw = fopen(TESTDATADIR "/chan3.raw", "rb")) == NULL) {
29 		perror(TESTDATADIR "/chan3.raw");
30 		return 1;
31 	}
32 
33 	config = cmd_ln_parse_r(NULL, fe_args, argc, argv, FALSE);
34 	fe = fe_init_auto_r(config);
35 	fcb = feat_init("1s_c_d_dd", CMN_NONE, FALSE, AGC_NONE,
36 			TRUE, fe_get_output_size(fe));
37 
38 	/* Determine how much data and how many MFCC frames we need. */
39 	fseek(raw, 0, SEEK_END);
40 	nsamp = ftell(raw) / sizeof(int16);
41 	fe_process_frames(fe, NULL, &nsamp, NULL, &total_frames);
42 	printf("%d samples, %d + 1 frames\n", nsamp, total_frames);
43 	total_frames++; /* For the possible fe_end_utt() frame */
44 	cepbuf = ckd_calloc_2d(total_frames + 1, fe_get_output_size(fe), sizeof(**cepbuf));
45 	fseek(raw, 0, SEEK_SET);
46 
47 	/* Pay close attention, kids.  This is how you use fe_process_frames(). */
48 	fe_start_utt(fe);
49 	cptr = cepbuf;
50 	nfr = total_frames;
51 	while ((nsamp = fread(buf, sizeof(int16), 2048, raw)) > 0) {
52 		int16 const *bptr = buf;
53 		while (nsamp) {
54 			int32 ncep = nfr;
55 			fe_process_frames(fe, &bptr, &nsamp, cptr, &ncep);
56 			cptr += ncep;
57 			nfr -= ncep;
58 		}
59 	}
60 	fe_end_utt(fe, *cptr, &nfr);
61 
62 	/* Now test some feature extraction problems. */
63 	featbuf1 = feat_array_alloc(fcb, total_frames);
64 	featbuf2 = feat_array_alloc(fcb, total_frames);
65 
66 	/* Whole utterance: canonical, assumed to be correct. */
67 	ncep = total_frames;
68 	TEST_EQUAL(total_frames,
69 		   feat_s2mfc2feat_live(fcb, cepbuf,
70 					&ncep, TRUE, TRUE,
71 					featbuf1));
72 	TEST_EQUAL(ncep, total_frames);
73 
74 	/* Process one frame at a time. */
75 	cptr = cepbuf;
76 	fptr = featbuf2;
77 	ncep = 1;
78 	nfr = feat_s2mfc2feat_live(fcb, cptr, &ncep, TRUE, FALSE, fptr);
79 	TEST_EQUAL(nfr, 0); /* Not possible to make any frames yet. */
80 	TEST_EQUAL(ncep, 1); /* But we shold have consumed one. */
81 	cptr += ncep;
82 	for (i = 1; i < total_frames - 1; ++i) {
83 		ncep = 1;
84 		nfr = feat_s2mfc2feat_live(fcb, cptr, &ncep, FALSE, FALSE, fptr);
85 		cptr += ncep;
86 		fptr += nfr;
87 	}
88 	nfr = feat_s2mfc2feat_live(fcb, cptr, &ncep, FALSE, TRUE, fptr);
89 	TEST_EQUAL(nfr, 4); /* This should have dumped the trailing window. */
90 	TEST_EQUAL(ncep, 1); /* And only consumed one frame of MFCCs. */
91 	cptr += ncep;
92 	fptr += nfr;
93 	/* Verify that we actually got the correct number of frames. */
94 	TEST_EQUAL(cptr - cepbuf, total_frames);
95 	TEST_EQUAL(fptr - featbuf2, total_frames);
96 
97 	/* Now verify that the results are equal. */
98 	for (i = 0; i < total_frames; ++i) {
99 		int32 j;
100 		printf("%-4d ", i);
101 		for (j = 0; j < feat_dimension(fcb); ++j) {
102 			TEST_EQUAL_FLOAT(featbuf1[i][0][j], featbuf2[i][0][j]);
103 		}
104 		if (i % 10 == 9)
105 			printf("\n");
106 	}
107 	printf("\n");
108 
109 	/* Process large chunks of frames at once, so as to exceed the
110 	 * internal ringbuffer size in feat_s2mfc2feat_live(). */
111 	cptr = cepbuf;
112 	fptr = featbuf2;
113 	ncep = total_frames;
114 	nfr = feat_s2mfc2feat_live(fcb, cptr, &ncep, TRUE, FALSE, fptr);
115 	TEST_ASSERT(ncep != nfr);
116 	cptr += ncep;
117 	fptr += nfr;
118 	ncep = total_frames - ncep;
119 	while (ncep) {
120 		int32 tmp_ncep;
121 		tmp_ncep = ncep;
122 		nfr = feat_s2mfc2feat_live(fcb, cptr, &tmp_ncep, FALSE, FALSE, fptr);
123 		cptr += tmp_ncep;
124 		fptr += nfr;
125 		ncep -= tmp_ncep;
126 	}
127 	nfr = feat_s2mfc2feat_live(fcb, cptr, &ncep, FALSE, TRUE, fptr);
128 	cptr += ncep;
129 	fptr += nfr;
130 	TEST_EQUAL(cptr - cepbuf, total_frames);
131 	TEST_EQUAL(fptr - featbuf2, total_frames);
132 
133 	/* Now verify that the results are equal. */
134 	for (i = 0; i < total_frames; ++i) {
135 		int32 j;
136 		printf("%-4d ", i);
137 		for (j = 0; j < feat_dimension(fcb); ++j)
138 			TEST_EQUAL_FLOAT(featbuf1[i][0][j], featbuf2[i][0][j]);
139 		if (i % 10 == 9)
140 			printf("\n");
141 	}
142 	printf("\n");
143 
144 	fclose(raw);
145 	fe_free(fe);
146 	feat_array_free(featbuf1);
147 	feat_array_free(featbuf2);
148 	feat_free(fcb);
149 	ckd_free_2d(cepbuf);
150 	cmd_ln_free_r(config);
151 
152 	return 0;
153 }
154