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 }