@@ -68,6 +68,7 @@ void set_data_bits_per_frame(struct LDPC *ldpc, int new_data_bits_per_frame) {
6868 FEC protection scheme */
6969void ldpc_encode_frame (struct LDPC * ldpc , int codeword [], unsigned char tx_bits_char []) {
7070 unsigned char pbits [ldpc -> NumberParityBits ];
71+ int codec_frame ;
7172 int i , j ;
7273
7374 unsigned char tx_bits_char_padded [ldpc -> ldpc_data_bits_per_frame ];
@@ -95,27 +96,41 @@ void ldpc_encode_frame(struct LDPC *ldpc, int codeword[], unsigned char tx_bits_
9596 unmodified.
9697 */
9798 memcpy (tx_bits_char_padded , tx_bits_char , ldpc -> data_bits_per_frame );
98- int codec_frame ;
9999 for (codec_frame = 0 ; codec_frame < 6 ; codec_frame ++ )
100100 for (i = 11 ; i < 52 ; i ++ )
101101 tx_bits_char_padded [codec_frame * 52 + i ] = 1 ;
102102 assert (codec_frame * 52 == ldpc -> data_bits_per_frame );
103103 for (i = ldpc -> data_bits_per_frame ; i < ldpc -> ldpc_data_bits_per_frame ; i ++ )
104104 tx_bits_char_padded [i ] = 1 ;
105105 encode (ldpc , tx_bits_char_padded , pbits );
106+
107+ break ;
108+
109+ case LDPC_PROT_2020B :
110+ /* We only want to protect the stage 1 VQ data bits, 0..10 in
111+ each 52 bit codec frame. There are 3 codec frames 3x52=156
112+ bits, and 56 parity bits. We only use 11*3 = 33 bits of
113+ the LDPC codeword data bits, the rest are set to known
114+ values.
115+ */
116+ for (j = 0 ,codec_frame = 0 ; codec_frame < 3 ; codec_frame ++ )
117+ for (i = 0 ; i < 11 ; i ++ ,j ++ )
118+ tx_bits_char_padded [j ] = tx_bits_char [codec_frame * 52 + i ];
119+ assert (j == 33 );
120+ for (i = 33 ; i < ldpc -> ldpc_data_bits_per_frame ; i ++ )
121+ tx_bits_char_padded [i ] = 1 ;
122+ encode (ldpc , tx_bits_char_padded , pbits );
123+
106124 break ;
125+
107126 default :
108127 assert (0 );
109128 }
110129
111130 /* output codeword is concatenation of (used) data bits and parity
112131 bits, we don't bother sending unused (known) data bits */
113- for (i = 0 ; i < ldpc -> data_bits_per_frame ; i ++ ) {
114- codeword [i ] = tx_bits_char [i ];
115- }
116- for (j = 0 ; j < ldpc -> NumberParityBits ; i ++ , j ++ ) {
117- codeword [i ] = pbits [j ];
118- }
132+ for (i = 0 ; i < ldpc -> data_bits_per_frame ; i ++ ) codeword [i ] = tx_bits_char [i ];
133+ for (j = 0 ; j < ldpc -> NumberParityBits ; i ++ , j ++ ) codeword [i ] = pbits [j ];
119134}
120135
121136void qpsk_modulate_frame (COMP tx_symbols [], int codeword [], int n ) {
@@ -137,7 +152,8 @@ void ldpc_decode_frame(struct LDPC *ldpc, int *parityCheckCount, int *iter, uint
137152 float llr_full_codeword [ldpc -> ldpc_coded_bits_per_frame ];
138153 int unused_data_bits = ldpc -> ldpc_data_bits_per_frame - ldpc -> data_bits_per_frame ;
139154 uint8_t out_char_ldpc [ldpc -> coded_bits_per_frame ];
140- int i ;
155+ int i ,j ;
156+ int codec_frame ;
141157
142158 switch (ldpc -> protection_mode ) {
143159 case LDPC_PROT_EQUAL :
@@ -175,7 +191,6 @@ void ldpc_decode_frame(struct LDPC *ldpc, int *parityCheckCount, int *iter, uint
175191 }
176192
177193 // set up known bits
178- int codec_frame ;
179194 for (codec_frame = 0 ; codec_frame < 6 ; codec_frame ++ )
180195 for (i = 11 ; i < 52 ; i ++ )
181196 llr_full_codeword [codec_frame * 52 + i ] = -100.0f ;
@@ -194,6 +209,33 @@ void ldpc_decode_frame(struct LDPC *ldpc, int *parityCheckCount, int *iter, uint
194209 for (i = 0 ; i < 11 ; i ++ )
195210 out_char [codec_frame * 52 + i ] = out_char_ldpc [codec_frame * 52 + i ];
196211 break ;
212+ case LDPC_PROT_2020B :
213+ /* 2020B waveform, with unequal error protection. As per
214+ 2020A, only the stage1 VQ index of each LPCNet vocoder
215+ frames is protected. In this case the FEC codeword is much
216+ smaller than the payload data. */
217+
218+ // set up LDPC codeword
219+ for (j = 0 ,codec_frame = 0 ; codec_frame < 3 ; codec_frame ++ )
220+ for (i = 0 ; i < 11 ; i ++ ,j ++ )
221+ llr_full_codeword [j ] = llr [codec_frame * 52 + i ];
222+ // set known LDPC codeword data bits
223+ for (i = 33 ; i < ldpc -> ldpc_data_bits_per_frame ; i ++ )
224+ llr_full_codeword [i ] = -100 ;
225+ // parity bits at end
226+ for (i = 0 ; i < ldpc -> NumberParityBits ; i ++ )
227+ llr_full_codeword [ldpc -> ldpc_data_bits_per_frame + i ] = llr [ldpc -> data_bits_per_frame + i ];
228+ * iter = run_ldpc_decoder (ldpc , out_char_ldpc , llr_full_codeword , parityCheckCount );
229+
230+ // pass through received data bits, replacing only decoded bits
231+ for (i = 0 ; i < ldpc -> data_bits_per_frame ; i ++ ) {
232+ out_char [i ] = llr [i ] < 0 ;
233+ }
234+ for (j = 0 ,codec_frame = 0 ; codec_frame < 3 ; codec_frame ++ )
235+ for (i = 0 ; i < 11 ; i ++ ,j ++ )
236+ out_char [codec_frame * 52 + i ] = out_char_ldpc [j ];
237+
238+ break ;
197239 default :
198240 assert (0 );
199241 }
@@ -279,7 +321,19 @@ void count_errors_protection_mode(int protection_mode, int *pNerrs, int *pNcoded
279321 */
280322 for (int codec_frame = 0 ; codec_frame < 6 ; codec_frame ++ ) {
281323 for (i = 0 ; i < 11 ; i ++ ) {
282- if (tx_bits [i ] != rx_bits [i ]) Nerrs ++ ;
324+ if (tx_bits [codec_frame * 52 + i ] != rx_bits [codec_frame * 52 + i ]) Nerrs ++ ;
325+ Ncoded ++ ;
326+ }
327+ }
328+ break ;
329+ case LDPC_PROT_2020B :
330+ /* We only protect bits 0..10 in each 52 bit LPCNet codec
331+ frame. There are 3 codec frames 3x52=156 data bits, of
332+ which only 11*3 = 33 bits are protected.
333+ */
334+ for (int codec_frame = 0 ; codec_frame < 3 ; codec_frame ++ ) {
335+ for (i = 0 ; i < 11 ; i ++ ) {
336+ if (tx_bits [codec_frame * 52 + i ] != rx_bits [codec_frame * 52 + i ]) Nerrs ++ ;
283337 Ncoded ++ ;
284338 }
285339 }
0 commit comments