FreeCalypso > hg > gsmhr-codec-ref
comparison gsm_hr.c @ 0:9008dbc8ca74
import original C code from GSM 06.06
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Fri, 14 Jun 2024 23:27:16 +0000 |
parents | |
children | a6db7d8d6df4 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:9008dbc8ca74 |
---|---|
1 /************************************************************************** | |
2 * | |
3 * File Name: gsm_hr.c | |
4 * | |
5 * Purpose: | |
6 * | |
7 * This file contains the main routine for the GSM Half Rate speech | |
8 * codec. The code for the speech coder, including the VAD, DTX, | |
9 * Comfort Noise, bad frame handling (error concealment), and codec | |
10 * homing functions is in the files listed below: | |
11 * | |
12 * gsm_hr.c globdefs.c homing.c host.c | |
13 * mathdp31.c mathhalf.c sp_dec.c sp_enc.c | |
14 * sp_frm.c sp_rom.c sp_sfrm.c vad.c | |
15 * dtx.c err_conc.c | |
16 * | |
17 * This particular file only has the level 0, main(), and all level | |
18 * 1, main()'s daughter functions, in it. | |
19 * | |
20 * Details on how to run gsm_hr are in the readme.txt file. | |
21 * | |
22 * Below is a listing of all the functions appearing in the file. | |
23 * The ordering is hierarchical. | |
24 * | |
25 * main() "gsm_hr", main program. | |
26 * encode() - encodes a speech file, outputs an encoded parameter file | |
27 * decode() - decodes a parameter file, outputs a decoded speech file | |
28 * | |
29 **************************************************************************/ | |
30 | |
31 /*_________________________________________________________________________ | |
32 | | | |
33 | Include Files | | |
34 |_________________________________________________________________________| | |
35 */ | |
36 | |
37 #include <stdio.h> | |
38 #include <stdlib.h> | |
39 #include <string.h> | |
40 #include <ctype.h> | |
41 | |
42 #include "gsm_hr.h" | |
43 #include "homing.h" | |
44 #include "host.h" | |
45 #include "sp_dec.h" | |
46 #include "sp_enc.h" | |
47 #include "typedefs.h" | |
48 | |
49 /**************************************************************************** | |
50 * | |
51 * PROGRAM NAME: gsm_hr | |
52 * | |
53 * PURPOSE: | |
54 * gsm_hr - main program for the GSM Half-Rate speech coder. | |
55 * Allows running one of the following operational modes: | |
56 * 0. Encoder only with speech input / encoded parameter data output. | |
57 * 1. Decoder only with speech parameter data input / speech output. | |
58 * | |
59 * INPUT: | |
60 * inputFileName 0. speech file in 8 kHz, pcm format. | |
61 * 1. speech parameter file in decoder input format. | |
62 * <number of frames> - number of frames to be processed (optional). | |
63 * <dtx|nodtx> - switch to enable/disable the DTX functions. | |
64 * | |
65 * OUTPUT: | |
66 * outputFileName 0. encoded paramter output file. | |
67 * 1. synthesized speech file in 8 kHz, pcm format. | |
68 * | |
69 * RETURN: | |
70 * none | |
71 * | |
72 * REFERENCES: Sub-clause 4.0 of GSM Recomendation 06.20 | |
73 * | |
74 * KEYWORDS: main, gsm_hr, speech codec, top level | |
75 * | |
76 ***************************************************************************/ | |
77 | |
78 int main(int argc, char *argv[]) | |
79 { | |
80 | |
81 /*_________________________________________________________________________ | |
82 | | | |
83 | Local Constants | | |
84 |_________________________________________________________________________| | |
85 */ | |
86 | |
87 #define DEFAULT_NUMFRAMES 32766 | |
88 | |
89 /*_________________________________________________________________________ | |
90 | | | |
91 | Automatic Variables | | |
92 |_________________________________________________________________________| | |
93 */ | |
94 | |
95 int iDoneFrm, | |
96 iMaxNumFrms, | |
97 option, | |
98 i; | |
99 | |
100 FILE *pfileInFile, | |
101 *pfileOutFile; | |
102 | |
103 /*_________________________________________________________________________ | |
104 | | | |
105 | Executable Code | | |
106 |_________________________________________________________________________| | |
107 */ | |
108 | |
109 /* check command line arguments */ | |
110 /* ---------------------------- */ | |
111 | |
112 iMaxNumFrms = DEFAULT_NUMFRAMES; | |
113 giDTXon = 1; | |
114 | |
115 /* check command line arguments */ | |
116 /* ---------------------------- */ | |
117 | |
118 switch (argc) | |
119 { | |
120 case 4: | |
121 | |
122 break; | |
123 | |
124 case 5: | |
125 case 6: | |
126 | |
127 for (i = 4; i < argc; i++) | |
128 { | |
129 if (!strcmp(argv[i], "dtx")) | |
130 giDTXon = 1; | |
131 else if (!strcmp(argv[i], "nodtx")) | |
132 giDTXon = 0; | |
133 else if ((iMaxNumFrms = atoi(argv[i])) <= 0) | |
134 { | |
135 printf("invalid number of frames or wrong DTX switch, %s", argv[i]); | |
136 exit(1); | |
137 } | |
138 } | |
139 break; | |
140 | |
141 default: | |
142 | |
143 printf("\n\nUsage:\n\n"); | |
144 printf("gsm_hr option inputFileName outputFileName "); | |
145 printf("<number of frames> <dtx|nodtx>\n"); | |
146 printf(" or\n"); | |
147 printf("gsm_hr option inputFileName outputFileName "); | |
148 printf("<dtx|nodtx> <number of frames>\n"); | |
149 printf("\nOptions: "); | |
150 printf("enc "); | |
151 puts("inputFileName: speech --> outputFileName: encoder output"); | |
152 printf(" "); | |
153 printf("dec "); | |
154 puts("inputFileName: decoder input --> outputFileName: speech"); | |
155 printf("\n"); | |
156 exit(1); | |
157 } | |
158 | |
159 /* check encoding and decoding options */ | |
160 /* ----------------------------------- */ | |
161 | |
162 if (!strcmp(argv[1], "enc")) | |
163 option = 0; | |
164 else if (!strcmp(argv[1], "dec")) | |
165 option = 1; | |
166 else | |
167 { | |
168 printf("error in option selection\n"); | |
169 printf(" Your entry : %s \n", argv[1]); | |
170 printf("\n\nUsage:\n\n"); | |
171 printf("gsm_hr option inputFileName outputFileName "); | |
172 printf("<number of frames> <dtx|nodtx>\n"); | |
173 printf(" or\n"); | |
174 printf("gsm_hr option inputFileName outputFileName "); | |
175 printf("<dtx|nodtx> <number of frames>\n"); | |
176 printf("\nOptions: "); | |
177 printf("enc "); | |
178 puts("inputFileName: speech --> outputFileName: encoder output"); | |
179 printf(" "); | |
180 printf("dec "); | |
181 puts("inputFileName: decoder input --> outputFileName: speech"); | |
182 printf("\n"); | |
183 exit(1); | |
184 } | |
185 | |
186 | |
187 /* open the input and output files */ | |
188 /* ------------------------------- */ | |
189 | |
190 #ifdef VAX | |
191 pfileInFile = fopen(argv[2], "rb", "mrs=2", "rfm=fix", "ctx=stm"); | |
192 pfileOutFile = fopen(argv[3], "wb", "mrs=2", "rfm=fix", "ctx=stm"); | |
193 #else | |
194 pfileInFile = fopen(argv[2], "rb"); | |
195 pfileOutFile = fopen(argv[3], "wb"); | |
196 #endif | |
197 | |
198 if (pfileInFile == NULL) | |
199 { | |
200 printf("error: can not open file %s\n", argv[2]); | |
201 exit(1); | |
202 } | |
203 if (pfileOutFile == NULL) | |
204 { | |
205 printf("error: can not open file %s\n", argv[3]); | |
206 exit(1); | |
207 } | |
208 | |
209 puts("\n\n"); | |
210 puts(" ****************************************"); | |
211 puts(" * *"); | |
212 puts(" * GSM Half-Rate Speech Coder *"); | |
213 puts(" * *"); | |
214 puts(" * *"); | |
215 printf(" * %s *\n", VERSION); | |
216 printf(" * %s *\n", DATE); | |
217 puts(" * *"); | |
218 puts(" ****************************************"); | |
219 puts("\n"); | |
220 | |
221 | |
222 printf("option: "); | |
223 | |
224 switch (option) | |
225 { | |
226 case 0: | |
227 puts("enc (speech encoder)"); | |
228 break; | |
229 case 1: | |
230 puts("dec (speech decoder)"); | |
231 break; | |
232 default: | |
233 puts("invalid option"); | |
234 exit(1); | |
235 } | |
236 | |
237 if (giDTXon) | |
238 printf("DTX mode: enabled\n"); | |
239 else | |
240 printf("DTX mode: disabled\n"); | |
241 | |
242 printf("input file: %s\n", argv[2]); | |
243 printf("output file: %s\n\n", argv[3]); | |
244 | |
245 | |
246 switch (option) | |
247 { | |
248 case 0: /* encode */ | |
249 | |
250 /* start the encoder, VAD, and transmit DTX in the home state */ | |
251 /* ---------------------------------------------------------- */ | |
252 | |
253 resetEnc(); | |
254 | |
255 /* encode: analyze 8 kHz speech and output encoded parameter file */ | |
256 /* --------------------------------------------------------------- */ | |
257 | |
258 for (giFrmCnt = 1, iDoneFrm = 0; | |
259 !iDoneFrm && giFrmCnt <= iMaxNumFrms; | |
260 giFrmCnt++) | |
261 { | |
262 | |
263 #ifndef SILENT | |
264 printf("encoding frame %d \r", giFrmCnt); | |
265 #endif | |
266 | |
267 if (encode(pfileInFile, pfileOutFile)) | |
268 iDoneFrm = 1; | |
269 } | |
270 | |
271 if (iDoneFrm) | |
272 giFrmCnt--; | |
273 | |
274 printf(" %d speech frames encoded\n", giFrmCnt - 1); | |
275 break; | |
276 | |
277 case 1: /* decode */ | |
278 | |
279 /* start the decoder and receive DTX in the home state */ | |
280 /* --------------------------------------------------- */ | |
281 | |
282 resetDec(); | |
283 | |
284 /* decode: synthesize speech */ | |
285 /* -------------------------- */ | |
286 | |
287 for (giFrmCnt = 1, iDoneFrm = 0; | |
288 !iDoneFrm && giFrmCnt <= iMaxNumFrms; | |
289 giFrmCnt++) | |
290 { | |
291 | |
292 #ifndef SILENT | |
293 printf("decoding frame %d \r", giFrmCnt); | |
294 #endif | |
295 | |
296 if (decode(pfileInFile, pfileOutFile)) | |
297 iDoneFrm = 1; | |
298 } | |
299 | |
300 if (iDoneFrm) | |
301 giFrmCnt--; | |
302 | |
303 printf(" %d speech frames decoded\n", giFrmCnt - 1); | |
304 break; | |
305 } | |
306 | |
307 fclose(pfileInFile); | |
308 fclose(pfileOutFile); | |
309 | |
310 return (0); | |
311 } | |
312 | |
313 /************************************************************************** | |
314 * | |
315 * FUNCTION NAME: decode | |
316 * | |
317 * PURPOSE: | |
318 * Reads in one frame of speech parameters and outputs one frame of | |
319 * synthesized speech. Resets the decoder to the home state if the | |
320 * Decoder Homing Frame pattern is detected. | |
321 * | |
322 * INPUT: | |
323 * pfileDec speech parameter input file. | |
324 * | |
325 * OUTPUT: | |
326 * pfileSpeechOut synthesized speech file | |
327 * | |
328 * RETURN: | |
329 * 0 successfully synthesized a complete frame of speech | |
330 * 1 failed to synthesize a complete frame of speech | |
331 * | |
332 * REFERENCES: Sub-clause 4.2 of GSM Recomendation 06.20 | |
333 * | |
334 * KEYWORDS: | |
335 * pfileDec, pfileSpeechOut | |
336 **************************************************************************/ | |
337 | |
338 int decode(FILE *pfileDec, FILE *pfileSpeechOut) | |
339 { | |
340 | |
341 /*_________________________________________________________________________ | |
342 | | | |
343 | Local Constants | | |
344 |_________________________________________________________________________| | |
345 */ | |
346 | |
347 /* These constants define the number of consecutive */ | |
348 /* parameters that decoderHomingFrameTest checks. */ | |
349 /* -------------------------------------------------*/ | |
350 | |
351 #define WHOLE_FRAME 18 | |
352 #define TO_FIRST_SUBFRAME 9 | |
353 | |
354 /*_________________________________________________________________________ | |
355 | | | |
356 | Static Variables | | |
357 |_________________________________________________________________________| | |
358 */ | |
359 static Shortword pswSpeechPara[22], | |
360 pswDecodedSpeechFrame[F_LEN]; | |
361 | |
362 static int reset_flag_decoder_old = 1; | |
363 | |
364 /*_________________________________________________________________________ | |
365 | | | |
366 | Automatic Variables | | |
367 |_________________________________________________________________________| | |
368 */ | |
369 int i, | |
370 reset_flag_decoder; | |
371 | |
372 /*_________________________________________________________________________ | |
373 | | | |
374 | Executable Code | | |
375 |_________________________________________________________________________| | |
376 */ | |
377 | |
378 if (readDecfile(pfileDec, pswSpeechPara)) | |
379 return (1); | |
380 | |
381 if(reset_flag_decoder_old) | |
382 reset_flag_decoder=decoderHomingFrameTest(pswSpeechPara, | |
383 TO_FIRST_SUBFRAME); | |
384 else | |
385 reset_flag_decoder=0; | |
386 | |
387 if (reset_flag_decoder && reset_flag_decoder_old) | |
388 { | |
389 /* force the output to be the encoder homing frame pattern */ | |
390 | |
391 for (i = 0; i < F_LEN; i++) | |
392 pswDecodedSpeechFrame[i] = EHF_MASK; | |
393 } | |
394 else | |
395 { | |
396 speechDecoder(pswSpeechPara, pswDecodedSpeechFrame); | |
397 } | |
398 | |
399 speechDecoderHostInterface(pswDecodedSpeechFrame, pfileSpeechOut); | |
400 | |
401 if(!reset_flag_decoder_old) | |
402 reset_flag_decoder=decoderHomingFrameTest(pswSpeechPara, WHOLE_FRAME); | |
403 | |
404 if (reset_flag_decoder) | |
405 resetDec(); /* bring the decoder and receive DTX | |
406 * to the home state */ | |
407 | |
408 reset_flag_decoder_old = reset_flag_decoder; | |
409 | |
410 return (0); | |
411 } | |
412 | |
413 /************************************************************************** | |
414 * | |
415 * FUNCTION NAME: encode | |
416 * | |
417 * PURPOSE: | |
418 * Reads in one frame of speech samples and outputs one frame of | |
419 * speech parameters. Resets the encoder to the home state if the | |
420 * Encoder Homing Frame pattern is detected. | |
421 * | |
422 * INPUT: | |
423 * pfileSpeechIn speech file | |
424 * | |
425 * OUTPUT: | |
426 * pfileEnc speech, encoded paramater data | |
427 * | |
428 * RETURN: | |
429 * 0 successfully wrote a complete frame of data | |
430 * 1 failed to write a complete frame of data | |
431 * | |
432 * REFERENCES: Sub-clause 4.1 of GSM Recomendation 06.20 | |
433 * | |
434 * KEYWORDS: | |
435 * pfileSpeechIn, pfileEnc | |
436 **************************************************************************/ | |
437 | |
438 int encode(FILE *pfileSpeechIn, FILE *pfileEnc) | |
439 { | |
440 | |
441 /*_________________________________________________________________________ | |
442 | | | |
443 | Static Variables | | |
444 |_________________________________________________________________________| | |
445 */ | |
446 static Shortword pswSpeechPara[20]; | |
447 static Shortword pswSpeechBuff[F_LEN]; | |
448 | |
449 /*_________________________________________________________________________ | |
450 | | | |
451 | Automatic Variables | | |
452 |_________________________________________________________________________| | |
453 */ | |
454 int iNumRead, | |
455 reset_flag; | |
456 | |
457 /*_________________________________________________________________________ | |
458 | | | |
459 | Executable Code | | |
460 |_________________________________________________________________________| | |
461 */ | |
462 | |
463 iNumRead = hostEncoderInterface(pfileSpeechIn, F_LEN, &pswSpeechBuff[0]); | |
464 | |
465 if (iNumRead < F_LEN) | |
466 return (1); | |
467 | |
468 reset_flag = encoderHomingFrameTest(&pswSpeechBuff[0]); | |
469 | |
470 speechEncoder(&pswSpeechBuff[0], pswSpeechPara); | |
471 | |
472 if (writeEncfile(pswSpeechPara, pfileEnc) != 20) | |
473 return (1); | |
474 | |
475 if (reset_flag) | |
476 resetEnc(); /* Bring the encoder, VAD, and DTX to | |
477 * the home state */ | |
478 | |
479 return (0); | |
480 } |