FreeCalypso > hg > gsm-codec-lib
comparison libgsmfr2/pp_bad.c @ 256:a33edf624061
libgsmfr2: start with API definition and port of libgsmfrp code
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Fri, 12 Apr 2024 20:49:53 +0000 |
parents | libgsmfrp/bad_frame.c@6ac547f0b903 |
children | 573afa985df6 |
comparison
equal
deleted
inserted
replaced
255:07f936338de1 | 256:a33edf624061 |
---|---|
1 /* | |
2 * In this module we implement our handling of BFI frame gaps | |
3 * and invalid SID frames. | |
4 */ | |
5 | |
6 #include <stdint.h> | |
7 #include <string.h> | |
8 #include "tw_gsmfr.h" | |
9 #include "pp_internal.h" | |
10 | |
11 static int reduce_xmaxc(uint8_t *frame) | |
12 { | |
13 int mute_flag = 1; | |
14 unsigned sub, xmaxc; | |
15 | |
16 for (sub = 0; sub < 4; sub++) { | |
17 xmaxc = ((frame[sub*7+6] & 0x1F) << 1) | (frame[sub*7+7] >> 7); | |
18 if (xmaxc > 4) { | |
19 xmaxc -= 4; | |
20 mute_flag = 0; | |
21 } else | |
22 xmaxc = 0; | |
23 frame[sub*7+6] &= 0xE0; | |
24 frame[sub*7+6] |= xmaxc >> 1; | |
25 frame[sub*7+7] &= 0x7F; | |
26 frame[sub*7+7] |= (xmaxc & 1) << 7; | |
27 } | |
28 return mute_flag; | |
29 } | |
30 | |
31 static void random_grid_pos(struct gsmfr_preproc_state *st, uint8_t *frame) | |
32 { | |
33 unsigned sub, Mc; | |
34 | |
35 for (sub = 0; sub < 4; sub++) { | |
36 Mc = gsmfr_preproc_prng(st, 2); | |
37 frame[sub*7+6] &= 0x9F; | |
38 frame[sub*7+6] |= Mc << 5; | |
39 } | |
40 } | |
41 | |
42 static int reduce_xmaxc_sid(struct gsmfr_preproc_state *st) | |
43 { | |
44 if (st->sid_xmaxc > 4) { | |
45 st->sid_xmaxc -= 4; | |
46 return 0; | |
47 } else { | |
48 st->sid_xmaxc = 0; | |
49 return 1; | |
50 } | |
51 } | |
52 | |
53 void gsmfr_preproc_bfi(struct gsmfr_preproc_state *st, int taf, uint8_t *frame) | |
54 { | |
55 int mute; | |
56 | |
57 switch (st->rx_state) { | |
58 case NO_DATA: | |
59 memcpy(frame, &gsmfr_preproc_silence_frame, | |
60 GSMFR_RTP_FRAME_LEN); | |
61 return; | |
62 case SPEECH: | |
63 memcpy(frame, &st->speech_frame, GSMFR_RTP_FRAME_LEN); | |
64 st->rx_state = SPEECH_MUTING; | |
65 return; | |
66 case SPEECH_MUTING: | |
67 mute = reduce_xmaxc(st->speech_frame); | |
68 memcpy(frame, &st->speech_frame, GSMFR_RTP_FRAME_LEN); | |
69 random_grid_pos(st, frame); | |
70 if (mute) | |
71 st->rx_state = NO_DATA; | |
72 return; | |
73 case COMFORT_NOISE: | |
74 if (taf) | |
75 st->rx_state = LOST_SID; | |
76 gsmfr_preproc_gen_cn(st, frame); | |
77 return; | |
78 case LOST_SID: | |
79 if (taf) { | |
80 st->rx_state = CN_MUTING; | |
81 reduce_xmaxc_sid(st); | |
82 } | |
83 gsmfr_preproc_gen_cn(st, frame); | |
84 return; | |
85 case CN_MUTING: | |
86 if (reduce_xmaxc_sid(st)) { | |
87 st->rx_state = NO_DATA; | |
88 memcpy(frame, &gsmfr_preproc_silence_frame, | |
89 GSMFR_RTP_FRAME_LEN); | |
90 } else | |
91 gsmfr_preproc_gen_cn(st, frame); | |
92 return; | |
93 } | |
94 } | |
95 | |
96 void gsmfr_preproc_invalid_sid(struct gsmfr_preproc_state *st, uint8_t *frame) | |
97 { | |
98 int mute; | |
99 | |
100 switch (st->rx_state) { | |
101 case NO_DATA: | |
102 memcpy(frame, &gsmfr_preproc_silence_frame, | |
103 GSMFR_RTP_FRAME_LEN); | |
104 return; | |
105 case SPEECH: | |
106 /* | |
107 * Make CN out of the last good speech frame, following the | |
108 * "NOTE" at the end of section 6.1.2 in TS 46.031. | |
109 */ | |
110 st->rx_state = COMFORT_NOISE; | |
111 memcpy(st->sid_prefix, &st->speech_frame, 5); | |
112 st->sid_xmaxc = gsmfr_preproc_xmaxc_mean(st->speech_frame); | |
113 gsmfr_preproc_gen_cn(st, frame); | |
114 return; | |
115 case SPEECH_MUTING: | |
116 /* ignore invalid SID in this state and act as if we got BFI */ | |
117 mute = reduce_xmaxc(st->speech_frame); | |
118 memcpy(frame, &st->speech_frame, GSMFR_RTP_FRAME_LEN); | |
119 random_grid_pos(st, frame); | |
120 if (mute) | |
121 st->rx_state = NO_DATA; | |
122 return; | |
123 case COMFORT_NOISE: | |
124 case LOST_SID: | |
125 st->rx_state = COMFORT_NOISE; | |
126 gsmfr_preproc_gen_cn(st, frame); | |
127 return; | |
128 case CN_MUTING: | |
129 if (reduce_xmaxc_sid(st)) { | |
130 st->rx_state = NO_DATA; | |
131 memcpy(frame, &gsmfr_preproc_silence_frame, | |
132 GSMFR_RTP_FRAME_LEN); | |
133 } else | |
134 gsmfr_preproc_gen_cn(st, frame); | |
135 return; | |
136 } | |
137 } |