diff doc/EFR-library-API @ 161:fe5aceaf51e0

doc/EFR-library-API: document new handling of BFI with no data
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 15 Dec 2022 19:21:45 +0000
parents 1c529bb31219
children 9208db14b4b9
line wrap: on
line diff
--- a/doc/EFR-library-API	Thu Dec 15 07:23:18 2022 +0000
+++ b/doc/EFR-library-API	Thu Dec 15 19:21:45 2022 +0000
@@ -72,28 +72,46 @@
 function EFR_sid_classify() to determine SID from the frame itself per the rules
 of GSM 06.81 section 6.1.1.
 
-Many EFR decoder applications will also be faced with a situation where they
-receive a frame gap (no data at all), and they need to run the EFR decoder with
-BFI=1, but don't have any frame-bits input.  If you find yourself in this
-situation, call the following function:
+The canonical EFR decoder always expects frame bits input to be present, even
+during BFI condtions!  More specifically, if a BFI=1 decoding call comes in when
+the decoder is in comfort noise generation state (after a SID), then all frame
+bits passed along with BFI=1 are ignored as one would naturally expect for
+frames that typically aren't transmitted at all - but if a BFI=1 decoding call
+comes in when the decoder is in regular speech mode, the canonical decoder will
+use the "fixed codebook excitation pulses" part of the erroneous frame (one
+declared to be garbage) as part of its decoding operation!  (This part
+constitutes 35 bits per subframe or 140 bits out of 244 per frame.)
+
+BFI with no data
+================
+
+Many EFR decoder applications will be faced with a situation where they receive
+a frame gap (no data at all), and they need to run the EFR decoder with BFI=1 -
+but the application doesn't have any frame-bits input.  Yet the canonical EFR
+decoder requires *some* erroneous frame bits to be fed to it - so what gives?
+Our initial approach was to feed the decoder all zeros in the place of codec
+parameters - but further analysis reveals that approach to be bad.  (To see for
+yourself, study the code in d1035pf.c and think what it will do when the input
+is fixed at all zeros.)  Our new approach is to generate pseudorandom bits for
+these pulse parameters, as detailed below.
+
+If you find yourself in the situation of needing to feed BFI=1 with no frame
+data bits to the decoder, call the following function in the place of
+EFR_decode_frame():
 
 extern void EFR_decode_bfi_nodata(struct EFR_decoder_state *st, int taf,
 				  int16_t *pcm);
 
-EFR_decode_bfi_nodata() is equivalent to calling EFR_decode_frame() with a frame
-buffer of 31 zero bytes (or 0xC signature followed by 244 zero bits) and BFI=1,
-but is slightly more efficient in that the internal steps of EFR_frame2params()
-and EFR_sid_classify() are skipped, and the made-up "frame" of 244 zero bits is
-passed to the decoder core at the params array level.
-
-Note that the official EFR decoder from ETSI, which we've replicated in our
-librified form in libgsmefr, does make use of some presumed-invalid frame data
-bits under BFI=1 conditions: see the description in GSM 06.61 section 6.1, where
-the last sentence reads "The received fixed codebook excitation pulses from the
-erroneous frame are always used as such."  With our current implementation, the
-"erroneous frame" in the case of completely lost or missing frames is a made-up
-frame of 244 zero bits; the question of whether this approach is good enough or
-if we need to do something more complex remains for further study.
+This function begins by checking the internal state flag RX_SP_FLAG, indicating
+whether the decoder is in speech or comfort noise generation mode.  If
+RX_SP_FLAG is set, indicating speech state, then the main body of the decoder
+will be making use of fixed codebook pulse parameters even for erroneous frames,
+and EFR_decode_bfi_nodata() will invoke a PRNG to fill in pseudorandom bits.
+If RX_SP_FLAG is clear, then the decoder is generating comfort noise following
+reception of a SID, and BFI conditions are fully expected because the
+transmitter is expected to be off.  In this case EFR_decode_bfi_nodata() feeds
+all-zeros parameters to the main body of the decoder, as none of them will be
+used.
 
 Stateless utility functions
 ===========================