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 }