1 /*---------------------------------------------------------------------------*\
2
3 FILE........: c2enc.c
4 AUTHOR......: David Rowe
5 DATE CREATED: 23/8/2010
6
7 Encodes a file of raw speech samples using codec2 and outputs a file
8 of bits.
9
10 \*---------------------------------------------------------------------------*/
11
12 /*
13 Copyright (C) 2010 David Rowe
14
15 All rights reserved.
16
17 This program is free software; you can redistribute it and/or modify
18 it under the terms of the GNU Lesser General Public License version 2.1, as
19 published by the Free Software Foundation. This program is
20 distributed in the hope that it will be useful, but WITHOUT ANY
21 WARRANTY; without even the implied warranty of MERCHANTABILITY or
22 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
23 License for more details.
24
25 You should have received a copy of the GNU Lesser General Public License
26 along with this program; if not, see <http://www.gnu.org/licenses/>.
27 */
28
29 #include "codec2.h"
30 #include "c2file.h"
31
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <errno.h>
36 #include <math.h>
37
main(int argc,char * argv[])38 int main(int argc, char *argv[])
39 {
40 int mode;
41 void *codec2;
42 FILE *fin;
43 FILE *fout;
44 short *buf;
45 unsigned char *bits;
46 int nsam, nbit, nbyte, gray, softdec, bitperchar;
47 float *unpacked_bits_float;
48 char *unpacked_bits_char;
49 int bit, byte,i;
50 int report_var = 0;
51 int eq = 0;
52
53 if (argc < 4) {
54 printf("usage: c2enc 3200|2400|1600|1400|1300|1200|700C|450|450PWB InputRawspeechFile OutputBitFile [--natural] [--softdec] [--bitperchar] [--mlfeat f32File modelFile] [--loadcb stageNum Filename] [--var] [--eq]\n");
55 printf("e.g. (headerless) c2enc 1300 ../raw/hts1a.raw hts1a.bin\n");
56 printf("e.g. (with header to detect mode) c2enc 1300 ../raw/hts1a.raw hts1a.c2\n");
57 exit(1);
58 }
59
60 if (strcmp(argv[1],"3200") == 0)
61 mode = CODEC2_MODE_3200;
62 else if (strcmp(argv[1],"2400") == 0)
63 mode = CODEC2_MODE_2400;
64 else if (strcmp(argv[1],"1600") == 0)
65 mode = CODEC2_MODE_1600;
66 else if (strcmp(argv[1],"1400") == 0)
67 mode = CODEC2_MODE_1400;
68 else if (strcmp(argv[1],"1300") == 0)
69 mode = CODEC2_MODE_1300;
70 else if (strcmp(argv[1],"1200") == 0)
71 mode = CODEC2_MODE_1200;
72 else if (strcmp(argv[1],"700C") == 0)
73 mode = CODEC2_MODE_700C;
74 else if (strcmp(argv[1],"450") == 0)
75 mode = CODEC2_MODE_450;
76 else if (strcmp(argv[1],"450PWB") == 0)
77 mode = CODEC2_MODE_450;
78 else {
79 fprintf(stderr, "Error in mode: %s. Must be 3200, 2400, 1600, 1400, 1300, 1200, 700C, 450, 450PWB or WB\n", argv[1]);
80 exit(1);
81 }
82
83 if (strcmp(argv[2], "-") == 0) fin = stdin;
84 else if ( (fin = fopen(argv[2],"rb")) == NULL ) {
85 fprintf(stderr, "Error opening input speech file: %s: %s.\n",
86 argv[2], strerror(errno));
87 exit(1);
88 }
89
90 if (strcmp(argv[3], "-") == 0) fout = stdout;
91 else if ( (fout = fopen(argv[3],"wb")) == NULL ) {
92 fprintf(stderr, "Error opening output compressed bit file: %s: %s.\n",
93 argv[3], strerror(errno));
94 exit(1);
95 }
96
97 // Write a header if we're writing to a .c2 file
98 char *ext = strrchr(argv[3], '.');
99 if (ext != NULL) {
100 if (strcmp(ext, ".c2") == 0) {
101 struct c2_header out_hdr;
102 memcpy(out_hdr.magic,c2_file_magic,sizeof(c2_file_magic));
103 out_hdr.mode = mode;
104 out_hdr.version_major = CODEC2_VERSION_MAJOR;
105 out_hdr.version_minor = CODEC2_VERSION_MINOR;
106 // TODO: Handle flags (this block needs to be moved down)
107 out_hdr.flags = 0;
108 fwrite(&out_hdr,sizeof(out_hdr),1,fout);
109 };
110 };
111
112 codec2 = codec2_create(mode);
113 nsam = codec2_samples_per_frame(codec2);
114 nbit = codec2_bits_per_frame(codec2);
115 buf = (short*)malloc(nsam*sizeof(short));
116 nbyte = (nbit + 7) / 8;
117
118 bits = (unsigned char*)malloc(nbyte*sizeof(char));
119 unpacked_bits_float = (float*)malloc(nbit*sizeof(float));
120 unpacked_bits_char = (char*)malloc(nbit*sizeof(char));
121
122 gray = 1; softdec = 0; bitperchar = 0;
123 for (i=4; i<argc; i++) {
124 if (strcmp(argv[i], "--natural") == 0) {
125 gray = 0;
126 }
127 if (strcmp(argv[i], "--softdec") == 0) {
128 softdec = 1;
129 }
130 if (strcmp(argv[i], "--bitperchar") == 0) {
131 bitperchar = 1;
132 }
133 if (strcmp(argv[i], "--mlfeat") == 0) {
134 /* dump machine learning features (700C only) */
135 codec2_open_mlfeat(codec2, argv[i+1], argv[i+2]);
136 }
137 if (strcmp(argv[i], "--loadcb") == 0) {
138 /* load VQ stage (700C only) */
139 codec2_load_codebook(codec2, atoi(argv[i+1])-1, argv[i+2]);
140 }
141 if (strcmp(argv[i], "--var") == 0) {
142 report_var = 1;
143 }
144 if (strcmp(argv[i], "--eq") == 0) {
145 eq = 1;
146 }
147
148 }
149 codec2_set_natural_or_gray(codec2, gray);
150 codec2_700c_eq(codec2, eq);
151
152 //fprintf(stderr,"gray: %d softdec: %d\n", gray, softdec);
153
154 while(fread(buf, sizeof(short), nsam, fin) == (size_t)nsam) {
155
156 codec2_encode(codec2, bits, buf);
157
158 if (softdec || bitperchar) {
159 /* unpack bits, MSB first, send as soft decision float */
160
161 bit = 7; byte = 0;
162 for(i=0; i<nbit; i++) {
163 unpacked_bits_float[i] = 1.0 - 2.0*((bits[byte] >> bit) & 0x1);
164 unpacked_bits_char[i] = (bits[byte] >> bit) & 0x1;
165 bit--;
166 if (bit < 0) {
167 bit = 7;
168 byte++;
169 }
170 }
171 if (softdec) {
172 fwrite(unpacked_bits_float, sizeof(float), nbit, fout);
173 }
174 if (bitperchar) {
175 fwrite(unpacked_bits_char, sizeof(char), nbit, fout);
176 }
177 }
178 else
179 fwrite(bits, sizeof(char), nbyte, fout);
180
181 // if this is in a pipeline, we probably don't want the usual
182 // buffering to occur
183
184 if (fout == stdout) fflush(stdout);
185 }
186
187 if (report_var) {
188 float var = codec2_get_var(codec2);
189 fprintf(stderr, "%s var: %5.2f std: %5.2f\n", argv[2], var, sqrt(var));
190 }
191 codec2_destroy(codec2);
192
193 free(buf);
194 free(bits);
195 free(unpacked_bits_float);
196 free(unpacked_bits_char);
197 fclose(fin);
198 fclose(fout);
199
200 return 0;
201 }
202