blob: 00f57cfd2b7cafda85caca0af4c9231766d48209
1 | /* |
2 | *=================================================================== |
3 | * 3GPP AMR Wideband Floating-point Speech Codec |
4 | *=================================================================== |
5 | */ |
6 | #include <stdlib.h> |
7 | #include <memory.h> |
8 | #include "typedef.h" |
9 | #include "dec_if.h" |
10 | #include "if_rom.h" |
11 | #include "dec.h" |
12 | |
13 | #define L_FRAME16k 320 /* Frame size at 16kHz */ |
14 | #define MODE_7k 0 /* modes */ |
15 | #define MODE_9k 1 |
16 | #define MODE_12k 2 |
17 | #define MODE_14k 3 |
18 | #define MODE_16k 4 |
19 | #define MODE_18k 5 |
20 | #define MODE_20k 6 |
21 | #define MODE_23k 7 |
22 | #define MODE_24k 8 |
23 | #define MRDTX 9 |
24 | #define NUM_OF_MODES 10 |
25 | #define LOST_FRAME 14 |
26 | #define MRNO_DATA 15 |
27 | #define EHF_MASK (Word16)0x0008 /* homing frame pattern */ |
28 | |
29 | typedef struct { |
30 | Word16 reset_flag_old; /* previous was homing frame */ |
31 | Word16 prev_ft; /* previous frame type */ |
32 | Word16 prev_mode; /* previous mode */ |
33 | void *decoder_state; /* Points decoder state */ |
34 | } WB_dec_if_state; |
35 | |
36 | #ifdef ENABLE_CPU2_DECODER |
37 | CPU2_DATA_START |
38 | #endif |
39 | |
40 | Word16 nb_of_param_first[NUM_OF_SPMODES] = { |
41 | 9, 14, 15, |
42 | 15, 15, 19, |
43 | 19, 19, 19 |
44 | }; |
45 | |
46 | #ifdef ENABLE_CPU2_DECODER |
47 | CPU2_DATA_END |
48 | #endif |
49 | |
50 | extern const Word16 mode_7k[]; |
51 | extern const Word16 mode_9k[]; |
52 | extern const Word16 mode_12k[]; |
53 | extern const Word16 mode_14k[]; |
54 | extern const Word16 mode_16k[]; |
55 | extern const Word16 mode_18k[]; |
56 | extern const Word16 mode_20k[]; |
57 | extern const Word16 mode_23k[]; |
58 | extern const Word16 mode_24k[]; |
59 | extern const Word16 mode_DTX[]; |
60 | |
61 | extern const Word16 nb_of_param[]; |
62 | |
63 | extern const Word16 dfh_M7k[]; |
64 | extern const Word16 dfh_M9k[]; |
65 | extern const Word16 dfh_M12k[]; |
66 | extern const Word16 dfh_M14k[]; |
67 | extern const Word16 dfh_M16k[]; |
68 | extern const Word16 dfh_M18k[]; |
69 | extern const Word16 dfh_M20k[]; |
70 | extern const Word16 dfh_M23k[]; |
71 | extern const Word16 dfh_M24k[]; |
72 | |
73 | /* overall table with the parameters of the |
74 | decoder homing frames for all modes */ |
75 | |
76 | extern const Word16 *dhf[10]; |
77 | |
78 | /* |
79 | * Decoder_Interface_Homing_Frame_test |
80 | * |
81 | * Parameters: |
82 | * input_frame I: input parameters |
83 | * mode I: speech mode |
84 | * |
85 | * Function: |
86 | * Check parameters for matching homing frame |
87 | * |
88 | * Returns: |
89 | * If homing frame |
90 | */ |
91 | Word16 D_IF_homing_frame_test(Word16 input_frame[], Word16 mode) |
92 | { |
93 | |
94 | if (mode != MODE_24k) { |
95 | /* perform test for COMPLETE parameter frame */ |
96 | return (Word16)!memcmp(input_frame, dhf[mode], nb_of_param[mode] * sizeof(Word16)); |
97 | } else { |
98 | /* discard high-band energy */ |
99 | return (Word16)!( |
100 | (memcmp(input_frame, dhf[MODE_24k], 19 * sizeof(Word16))) | |
101 | (memcmp(input_frame + 20, dhf[MODE_24k] + 20, 11 * sizeof(Word16))) | |
102 | (memcmp(input_frame + 32, dhf[MODE_24k] + 32, 11 * sizeof(Word16))) | |
103 | (memcmp(input_frame + 44, dhf[MODE_24k] + 44, 11 * sizeof(Word16)))); |
104 | |
105 | } |
106 | } |
107 | |
108 | |
109 | Word16 D_IF_homing_frame_test_first(Word16 input_frame[], Word16 mode) |
110 | { |
111 | /* perform test for FIRST SUBFRAME of parameter frame ONLY */ |
112 | return (Word16)!memcmp(input_frame, dhf[mode], nb_of_param_first[mode] * sizeof(Word16)); |
113 | } |
114 | |
115 | #ifdef IF2 |
116 | /* |
117 | * D_IF_conversion |
118 | * |
119 | * |
120 | * Parameters: |
121 | * param O: AMR parameters |
122 | * stream I: input bitstream |
123 | * frame_type O: frame type |
124 | * speech_mode O: speech mode in DTX |
125 | * fqi O: frame quality indicator |
126 | * |
127 | * Function: |
128 | * Unpacks IF2 octet stream |
129 | * |
130 | * Returns: |
131 | * mode used mode |
132 | */ |
133 | Word16 D_IF_conversion(Word16 *param, UWord8 *stream, UWord8 *frame_type, |
134 | Word16 *speech_mode, Word16 *fqi) |
135 | { |
136 | Word32 mode; |
137 | Word32 j; |
138 | Word16 const *mask; |
139 | |
140 | memset(param, 0, PRMNO_24k << 1); |
141 | mode = *stream >> 4; |
142 | *fqi = (Word16)((*stream >> 3) & 0x1); |
143 | *stream <<= (HEADER_SIZE - 1); |
144 | |
145 | switch (mode) { |
146 | case MRDTX: |
147 | mask = mode_DTX; |
148 | |
149 | for (j = HEADER_SIZE; j < T_NBBITS_SID; j++) { |
150 | if (*stream & 0x80) { |
151 | param[*mask] = (Word16)(param[*mask] + * (mask + 1)); |
152 | } |
153 | |
154 | mask += 2; |
155 | |
156 | if (j % 8) { |
157 | *stream <<= 1; |
158 | } else { |
159 | stream++; |
160 | } |
161 | } |
162 | |
163 | /* get SID type bit */ |
164 | |
165 | *frame_type = RX_SID_FIRST; |
166 | |
167 | if (*stream & 0x80) { |
168 | *frame_type = RX_SID_UPDATE; |
169 | } |
170 | |
171 | *stream <<= 1; |
172 | |
173 | /* speech mode indicator */ |
174 | *speech_mode = (Word16)(*stream >> 4); |
175 | break; |
176 | |
177 | case MRNO_DATA: |
178 | *frame_type = RX_NO_DATA; |
179 | break; |
180 | |
181 | case LOST_FRAME: |
182 | *frame_type = RX_SPEECH_LOST; |
183 | break; |
184 | |
185 | case MODE_7k: |
186 | mask = mode_7k; |
187 | |
188 | for (j = HEADER_SIZE; j < T_NBBITS_7k; j++) { |
189 | if (*stream & 0x80) { |
190 | param[*mask] = (Word16)(param[*mask] + * (mask + 1)); |
191 | } |
192 | mask += 2; |
193 | |
194 | if (j % 8) { |
195 | *stream <<= 1; |
196 | } else { |
197 | stream++; |
198 | } |
199 | } |
200 | |
201 | *frame_type = RX_SPEECH_GOOD; |
202 | break; |
203 | |
204 | case MODE_9k: |
205 | mask = mode_9k; |
206 | |
207 | for (j = HEADER_SIZE; j < T_NBBITS_9k; j++) { |
208 | if (*stream & 0x80) { |
209 | param[*mask] = (Word16)(param[*mask] + * (mask + 1)); |
210 | } |
211 | mask += 2; |
212 | |
213 | if (j % 8) { |
214 | *stream <<= 1; |
215 | } else { |
216 | stream++; |
217 | } |
218 | } |
219 | |
220 | *frame_type = RX_SPEECH_GOOD; |
221 | break; |
222 | |
223 | case MODE_12k: |
224 | mask = mode_12k; |
225 | |
226 | for (j = HEADER_SIZE; j < T_NBBITS_12k; j++) { |
227 | if (*stream & 0x80) { |
228 | param[*mask] = (Word16)(param[*mask] + * (mask + 1)); |
229 | } |
230 | mask += 2; |
231 | |
232 | if (j % 8) { |
233 | *stream <<= 1; |
234 | } else { |
235 | stream++; |
236 | } |
237 | } |
238 | |
239 | *frame_type = RX_SPEECH_GOOD; |
240 | break; |
241 | |
242 | case MODE_14k: |
243 | mask = mode_14k; |
244 | |
245 | for (j = HEADER_SIZE; j < T_NBBITS_14k; j++) { |
246 | if (*stream & 0x80) { |
247 | param[*mask] = (Word16)(param[*mask] + * (mask + 1)); |
248 | } |
249 | |
250 | mask += 2; |
251 | |
252 | if (j % 8) { |
253 | *stream <<= 1; |
254 | } else { |
255 | stream++; |
256 | } |
257 | } |
258 | |
259 | *frame_type = RX_SPEECH_GOOD; |
260 | break; |
261 | |
262 | case MODE_16k: |
263 | mask = mode_16k; |
264 | |
265 | for (j = HEADER_SIZE; j < T_NBBITS_16k; j++) { |
266 | if (*stream & 0x80) { |
267 | param[*mask] = (Word16)(param[*mask] + * (mask + 1)); |
268 | } |
269 | |
270 | mask += 2; |
271 | |
272 | if (j % 8) { |
273 | *stream <<= 1; |
274 | } else { |
275 | stream++; |
276 | } |
277 | } |
278 | |
279 | *frame_type = RX_SPEECH_GOOD; |
280 | break; |
281 | |
282 | case MODE_18k: |
283 | mask = mode_18k; |
284 | |
285 | for (j = HEADER_SIZE; j < T_NBBITS_18k; j++) { |
286 | if (*stream & 0x80) { |
287 | param[*mask] = (Word16)(param[*mask] + * (mask + 1)); |
288 | } |
289 | |
290 | mask += 2; |
291 | |
292 | if (j % 8) { |
293 | *stream <<= 1; |
294 | } else { |
295 | stream++; |
296 | } |
297 | } |
298 | |
299 | *frame_type = RX_SPEECH_GOOD; |
300 | break; |
301 | |
302 | case MODE_20k: |
303 | mask = mode_20k; |
304 | |
305 | for (j = HEADER_SIZE; j < T_NBBITS_20k; j++) { |
306 | if (*stream & 0x80) { |
307 | param[*mask] = (Word16)(param[*mask] + * (mask + 1)); |
308 | } |
309 | |
310 | mask += 2; |
311 | |
312 | if (j % 8) { |
313 | *stream <<= 1; |
314 | } else { |
315 | stream++; |
316 | } |
317 | } |
318 | |
319 | *frame_type = RX_SPEECH_GOOD; |
320 | break; |
321 | |
322 | case MODE_23k: |
323 | mask = mode_23k; |
324 | |
325 | for (j = HEADER_SIZE; j < T_NBBITS_23k; j++) { |
326 | if (*stream & 0x80) { |
327 | param[*mask] = (Word16)(param[*mask] + * (mask + 1)); |
328 | } |
329 | |
330 | mask += 2; |
331 | |
332 | if (j % 8) { |
333 | *stream <<= 1; |
334 | } else { |
335 | stream++; |
336 | } |
337 | |
338 | } |
339 | |
340 | *frame_type = RX_SPEECH_GOOD; |
341 | break; |
342 | |
343 | case MODE_24k: |
344 | mask = mode_24k; |
345 | |
346 | for (j = HEADER_SIZE; j < T_NBBITS_24k; j++) { |
347 | if (*stream & 0x80) { |
348 | param[*mask] = (Word16)(param[*mask] + * (mask + 1)); |
349 | } |
350 | |
351 | mask += 2; |
352 | |
353 | if (j % 8) { |
354 | *stream <<= 1; |
355 | } else { |
356 | stream++; |
357 | } |
358 | |
359 | } |
360 | |
361 | *frame_type = RX_SPEECH_GOOD; |
362 | break; |
363 | |
364 | default: |
365 | *frame_type = RX_SPEECH_LOST; |
366 | *fqi = 0; |
367 | break; |
368 | |
369 | } |
370 | |
371 | if (*fqi == 0) { |
372 | if (*frame_type == RX_SPEECH_GOOD) { |
373 | *frame_type = RX_SPEECH_BAD; |
374 | } |
375 | if ((*frame_type == RX_SID_FIRST) | (*frame_type == RX_SID_UPDATE)) { |
376 | *frame_type = RX_SID_BAD; |
377 | } |
378 | } |
379 | |
380 | return (Word16)mode; |
381 | } |
382 | |
383 | #else |
384 | |
385 | /* |
386 | * D_IF_mms_conversion |
387 | * |
388 | * |
389 | * Parameters: |
390 | * param O: AMR parameters |
391 | * stream I: input bitstream |
392 | * frame_type O: frame type |
393 | * speech_mode O: speech mode in DTX |
394 | * fqi O: frame quality indicator |
395 | * |
396 | * Function: |
397 | * Unpacks MMS formatted octet stream (see RFC 3267, section 5.3) |
398 | * |
399 | * Returns: |
400 | * mode used mode |
401 | */ |
402 | Word16 D_IF_mms_conversion(Word16 *param, UWord8 *stream, UWord8 *frame_type, |
403 | Word16 *speech_mode, Word16 *fqi) |
404 | { |
405 | Word32 mode; |
406 | Word32 j; |
407 | Word16 const *mask; |
408 | |
409 | memset(param, 0, PRMNO_24k << 1); |
410 | |
411 | *fqi = (Word16)((*stream >> 2) & 0x01); |
412 | mode = (Word32)((*stream >> 3) & 0x0F); |
413 | |
414 | stream++; |
415 | |
416 | switch (mode) { |
417 | case MRDTX: |
418 | mask = mode_DTX; |
419 | |
420 | for (j = 1; j <= NBBITS_SID; j++) { |
421 | if (*stream & 0x80) { |
422 | param[*mask] = (Word16)(param[*mask] + * (mask + 1)); |
423 | } |
424 | |
425 | mask += 2; |
426 | |
427 | if (j % 8) { |
428 | *stream <<= 1; |
429 | } else { |
430 | stream++; |
431 | } |
432 | } |
433 | |
434 | /* get SID type bit */ |
435 | |
436 | *frame_type = RX_SID_FIRST; |
437 | |
438 | if (*stream & 0x80) { |
439 | *frame_type = RX_SID_UPDATE; |
440 | } |
441 | |
442 | *stream <<= 1; |
443 | |
444 | /* speech mode indicator */ |
445 | *speech_mode = (Word16)(*stream >> 4); |
446 | break; |
447 | |
448 | case MRNO_DATA: |
449 | *frame_type = RX_NO_DATA; |
450 | break; |
451 | |
452 | case LOST_FRAME: |
453 | *frame_type = RX_SPEECH_LOST; |
454 | break; |
455 | |
456 | case MODE_7k: |
457 | mask = mode_7k; |
458 | |
459 | for (j = 1; j <= NBBITS_7k; j++) { |
460 | if (*stream & 0x80) { |
461 | param[*mask] = (Word16)(param[*mask] + * (mask + 1)); |
462 | } |
463 | mask += 2; |
464 | |
465 | if (j % 8) { |
466 | *stream <<= 1; |
467 | } else { |
468 | stream++; |
469 | } |
470 | } |
471 | |
472 | *frame_type = RX_SPEECH_GOOD; |
473 | break; |
474 | |
475 | case MODE_9k: |
476 | mask = mode_9k; |
477 | |
478 | for (j = 1; j <= NBBITS_9k; j++) { |
479 | if (*stream & 0x80) { |
480 | param[*mask] = (Word16)(param[*mask] + * (mask + 1)); |
481 | } |
482 | mask += 2; |
483 | |
484 | if (j % 8) { |
485 | *stream <<= 1; |
486 | } else { |
487 | stream++; |
488 | } |
489 | } |
490 | |
491 | *frame_type = RX_SPEECH_GOOD; |
492 | break; |
493 | |
494 | case MODE_12k: |
495 | mask = mode_12k; |
496 | |
497 | for (j = 1; j <= NBBITS_12k; j++) { |
498 | if (*stream & 0x80) { |
499 | param[*mask] = (Word16)(param[*mask] + * (mask + 1)); |
500 | } |
501 | mask += 2; |
502 | |
503 | if (j % 8) { |
504 | *stream <<= 1; |
505 | } else { |
506 | stream++; |
507 | } |
508 | } |
509 | |
510 | *frame_type = RX_SPEECH_GOOD; |
511 | break; |
512 | |
513 | case MODE_14k: |
514 | mask = mode_14k; |
515 | |
516 | for (j = 1; j <= NBBITS_14k; j++) { |
517 | if (*stream & 0x80) { |
518 | param[*mask] = (Word16)(param[*mask] + * (mask + 1)); |
519 | } |
520 | |
521 | mask += 2; |
522 | |
523 | if (j % 8) { |
524 | *stream <<= 1; |
525 | } else { |
526 | stream++; |
527 | } |
528 | } |
529 | |
530 | *frame_type = RX_SPEECH_GOOD; |
531 | break; |
532 | |
533 | case MODE_16k: |
534 | mask = mode_16k; |
535 | |
536 | for (j = 1; j <= NBBITS_16k; j++) { |
537 | if (*stream & 0x80) { |
538 | param[*mask] = (Word16)(param[*mask] + * (mask + 1)); |
539 | } |
540 | |
541 | mask += 2; |
542 | |
543 | if (j % 8) { |
544 | *stream <<= 1; |
545 | } else { |
546 | stream++; |
547 | } |
548 | } |
549 | |
550 | *frame_type = RX_SPEECH_GOOD; |
551 | break; |
552 | |
553 | case MODE_18k: |
554 | mask = mode_18k; |
555 | |
556 | for (j = 1; j <= NBBITS_18k; j++) { |
557 | if (*stream & 0x80) { |
558 | param[*mask] = (Word16)(param[*mask] + * (mask + 1)); |
559 | } |
560 | |
561 | mask += 2; |
562 | |
563 | if (j % 8) { |
564 | *stream <<= 1; |
565 | } else { |
566 | stream++; |
567 | } |
568 | } |
569 | |
570 | *frame_type = RX_SPEECH_GOOD; |
571 | break; |
572 | |
573 | case MODE_20k: |
574 | mask = mode_20k; |
575 | |
576 | for (j = 1; j <= NBBITS_20k; j++) { |
577 | if (*stream & 0x80) { |
578 | param[*mask] = (Word16)(param[*mask] + * (mask + 1)); |
579 | } |
580 | |
581 | mask += 2; |
582 | |
583 | if (j % 8) { |
584 | *stream <<= 1; |
585 | } else { |
586 | stream++; |
587 | } |
588 | } |
589 | |
590 | *frame_type = RX_SPEECH_GOOD; |
591 | break; |
592 | |
593 | case MODE_23k: |
594 | mask = mode_23k; |
595 | |
596 | for (j = 1; j <= NBBITS_23k; j++) { |
597 | if (*stream & 0x80) { |
598 | param[*mask] = (Word16)(param[*mask] + * (mask + 1)); |
599 | } |
600 | |
601 | mask += 2; |
602 | |
603 | if (j % 8) { |
604 | *stream <<= 1; |
605 | } else { |
606 | stream++; |
607 | } |
608 | |
609 | } |
610 | |
611 | *frame_type = RX_SPEECH_GOOD; |
612 | break; |
613 | |
614 | case MODE_24k: |
615 | mask = mode_24k; |
616 | |
617 | for (j = 1; j <= NBBITS_24k; j++) { |
618 | if (*stream & 0x80) { |
619 | param[*mask] = (Word16)(param[*mask] + * (mask + 1)); |
620 | } |
621 | |
622 | mask += 2; |
623 | |
624 | if (j % 8) { |
625 | *stream <<= 1; |
626 | } else { |
627 | stream++; |
628 | } |
629 | |
630 | } |
631 | |
632 | *frame_type = RX_SPEECH_GOOD; |
633 | break; |
634 | |
635 | default: |
636 | *frame_type = RX_SPEECH_LOST; |
637 | *fqi = 0; |
638 | break; |
639 | |
640 | } |
641 | |
642 | if (*fqi == 0) { |
643 | if (*frame_type == RX_SPEECH_GOOD) { |
644 | *frame_type = RX_SPEECH_BAD; |
645 | } |
646 | if ((*frame_type == RX_SID_FIRST) | (*frame_type == RX_SID_UPDATE)) { |
647 | *frame_type = RX_SID_BAD; |
648 | } |
649 | } |
650 | |
651 | return (Word16)mode; |
652 | } |
653 | |
654 | #endif |
655 | |
656 | /* |
657 | * D_IF_decode |
658 | * |
659 | * |
660 | * Parameters: |
661 | * st B: pointer to state structure |
662 | * bits I: bitstream form the encoder |
663 | * synth O: decoder output |
664 | * lfi I: lost frame indicator |
665 | * _good_frame, _bad_frame, _lost_frame, _no_frame |
666 | * |
667 | * Function: |
668 | * Decoding one frame of speech. Lost frame indicator can be used |
669 | * to inform encoder about the problems in the received frame. |
670 | * _good_frame:good speech or sid frame is received. |
671 | * _bad_frame: frame with possible bit errors |
672 | * _lost_frame:speech of sid frame is lost in transmission |
673 | * _no_frame: indicates non-received frames in dtx-operation |
674 | * Returns: |
675 | * |
676 | */ |
677 | void D_IF_decode(void *st, UWord8 *bits, Word16 *synth, Word32 lfi) |
678 | { |
679 | Word32 i; |
680 | Word16 mode = 0; /* AMR mode */ |
681 | Word16 speech_mode = MODE_7k; /* speech mode */ |
682 | Word16 fqi; /* frame quality indicator */ |
683 | |
684 | Word16 prm[PRMNO_24k]; /* AMR parameters */ |
685 | |
686 | UWord8 frame_type; /* frame type */ |
687 | Word16 reset_flag = 0; /* reset flag */ |
688 | WB_dec_if_state * s; /* pointer to structure */ |
689 | |
690 | s = (WB_dec_if_state*)st; |
691 | |
692 | /* bits -> param, if needed */ |
693 | if ((lfi == _good_frame) | (lfi == _bad_frame)) { |
694 | /* add fqi data */ |
695 | #ifdef IF2 |
696 | *bits = (UWord8)((Word32) * bits & ~(lfi << 3)); |
697 | #else |
698 | *bits = (UWord8)((Word32) * bits & ~(lfi << 2)); |
699 | #endif |
700 | /* |
701 | * extract mode information and frame_type, |
702 | * octets to parameters |
703 | */ |
704 | #ifdef IF2 |
705 | mode = D_IF_conversion(prm, bits, &frame_type, &speech_mode, &fqi); |
706 | #else |
707 | mode = D_IF_mms_conversion(prm, bits, &frame_type, &speech_mode, &fqi); |
708 | #endif |
709 | |
710 | } else if (lfi == _no_frame) { |
711 | frame_type = RX_NO_DATA; |
712 | } else { |
713 | frame_type = RX_SPEECH_LOST; |
714 | } |
715 | |
716 | /* |
717 | * if no mode information |
718 | * guess one from the previous frame |
719 | */ |
720 | if ((frame_type == RX_SPEECH_LOST) | (frame_type == RX_NO_DATA)) { |
721 | mode = s->prev_mode; |
722 | } |
723 | |
724 | if (mode == MRDTX) { |
725 | mode = speech_mode; |
726 | } |
727 | |
728 | /* if homed: check if this frame is another homing frame */ |
729 | if (s->reset_flag_old == 1) { |
730 | /* only check until end of first subframe */ |
731 | reset_flag = D_IF_homing_frame_test_first(prm, mode); |
732 | } |
733 | |
734 | /* produce encoder homing frame if homed & input=decoder homing frame */ |
735 | if ((reset_flag != 0) && (s->reset_flag_old != 0)) { |
736 | for (i = 0; i < L_FRAME16k; i++) { |
737 | synth[i] = EHF_MASK; |
738 | } |
739 | } else { |
740 | D_MAIN_decode(mode, prm, synth, s->decoder_state, frame_type); |
741 | } |
742 | |
743 | for (i = 0; i < L_FRAME16k; i++) { /* Delete the 2 LSBs (14-bit input) */ |
744 | synth[i] = (Word16)(synth[i] & 0xfffC); |
745 | } |
746 | |
747 | /* if not homed: check whether current frame is a homing frame */ |
748 | if ((s->reset_flag_old == 0) & (mode < 9)) { |
749 | /* check whole frame */ |
750 | reset_flag = D_IF_homing_frame_test(prm, mode); |
751 | } |
752 | /* reset decoder if current frame is a homing frame */ |
753 | if (reset_flag != 0) { |
754 | D_MAIN_reset(s->decoder_state, 1); |
755 | } |
756 | s->reset_flag_old = reset_flag; |
757 | |
758 | s->prev_ft = frame_type; |
759 | s->prev_mode = mode; |
760 | } |
761 | |
762 | /* |
763 | * D_IF_reset |
764 | * |
765 | * Parameters: |
766 | * st O: state struct |
767 | * |
768 | * Function: |
769 | * Reset homing frame counter |
770 | * |
771 | * Returns: |
772 | * void |
773 | */ |
774 | void D_IF_reset(WB_dec_if_state *st) |
775 | { |
776 | st->reset_flag_old = 1; |
777 | st->prev_ft = RX_SPEECH_GOOD; |
778 | st->prev_mode = MODE_7k; /* minimum bitrate */ |
779 | } |
780 | |
781 | /* |
782 | * D_IF_init |
783 | * |
784 | * Parameters: |
785 | * |
786 | * Function: |
787 | * Allocates state memory and initializes state memory |
788 | * |
789 | * Returns: |
790 | * pointer to encoder interface structure |
791 | */ |
792 | void *D_IF_init(void) |
793 | { |
794 | WB_dec_if_state *s = NULL; |
795 | |
796 | /* allocate memory */ |
797 | if ((s = (WB_dec_if_state*)malloc(sizeof(WB_dec_if_state))) == NULL) { |
798 | return NULL; |
799 | } |
800 | |
801 | D_MAIN_init(&(s->decoder_state)); |
802 | if (s->decoder_state == NULL) { |
803 | free(s); |
804 | return NULL; |
805 | } |
806 | |
807 | D_IF_reset(s); |
808 | |
809 | return (void *)s; |
810 | } |
811 | |
812 | /* |
813 | * D_IF_exit |
814 | * |
815 | * Parameters: |
816 | * state I: state structure |
817 | * |
818 | * Function: |
819 | * The memory used for state memory is freed |
820 | * |
821 | * Returns: |
822 | * Void |
823 | */ |
824 | void D_IF_exit(void *state) |
825 | { |
826 | WB_dec_if_state *s; |
827 | |
828 | s = (WB_dec_if_state *)state; |
829 | |
830 | /* free memory */ |
831 | D_MAIN_close(&s->decoder_state); |
832 | free(s); |
833 | state = NULL; |
834 | } |
835 |