# HG changeset patch # User Mychaela Falconia # Date 1671132105 0 # Node ID fe5aceaf51e09cc2548be9d279ab8e9f315a7c68 # Parent eefef9f6d533c687ab848e10b6f31594d0378e9c doc/EFR-library-API: document new handling of BFI with no data diff -r eefef9f6d533 -r fe5aceaf51e0 doc/EFR-library-API --- 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 ===========================