FreeCalypso > hg > gsm-codec-lib
changeset 633:3ab76caba41c
doc/HR-codec-library: document stateless utility functions
| author | Mychaela Falconia <falcon@freecalypso.org> |
|---|---|
| date | Fri, 20 Mar 2026 02:17:55 +0000 |
| parents | 7fc57e2a6784 |
| children | 4c5a4fcf9236 |
| files | doc/HR-codec-library |
| diffstat | 1 files changed, 170 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/doc/HR-codec-library Thu Mar 19 04:13:45 2026 +0000 +++ b/doc/HR-codec-library Fri Mar 20 02:17:55 2026 +0000 @@ -248,3 +248,173 @@ proceeds by applying classic Rx front end processing that only emits speech frames, and then replacing output with SID frames under certain conditions if DTXd is enabled. + +Stateless utility functions +=========================== + +All functions in this section are stateless (no encoder, decoder or RxFE state +structure is needed); they merely manipulate data formats. + +void gsmhr_pack_ts101318(const int16_t *param, uint8_t *payload); + +This function converts a 112-bit GSM-HR codec frame from an array of speech +parameters (18 16-bit words) into the packed format of ETSI TS 101 318, which +is a buffer of 14 octets with every bit used for payload. Any extraneous bits +in input 16-bit words (beyond the size of each parameter in bits) are ignored. + +void gsmhr_unpack_ts101318(const uint8_t *payload, int16_t *param); + +This function converts a 112-bit GSM-HR codec frame from the packed format of +TS 101 318 into an array of 18 speech parameters. + +void gsmhr_encoder_twts002_out(const int16_t *param, uint8_t *payload); + +This function converts a cod-style frame (output from gsmhr_encode_frame() or +gsmhr_tfo_xfrm(), or read from an ETSI *.cod file) into TW-TS-002 format. The +output is always 15 octets long (the buffer must have this much room), and is +valid per both RFC 5993 and TW-TS-002 specs. The only two possible frame types +in this context are good speech and good SID, distinguished by SP flag in the +cod-style input and by FT field in RFC 5993 output. + +int gsmhr_decoder_twts002_in(const uint8_t *payload, int16_t *param); + +This function reads a super-5993 frame in TW-TS-002 format from a buffer and +converts it into the required form for input to gsmhr_decode_frame() or +gsmhr_tfo_xfrm(), which is an extended form of ETSI's *.dec format. The input +must be a valid super-5993 in the following sense: + +* The first octet in the buffer must be valid ToC per TW-TS-002 section 5.1; + +* F bit in this ToC octet must be cleared; + +* FT field must equal 0, 1, 2, 6 or 7 per TW-TS-002 section 5.2; + +* If FT equals 0, 2 or 6, the ToC octet must be followed by 14 octets of frame + payload. + +If any of these rules are violated, gsmhr_decoder_twts002_in() returns a +negative value (-1 if F bit is set or -2 if FT is invalid) and does not write +anything into the output array. Otherwise, the function returns 0 (indicating +success) and the output array is filled as follows: + +* For frame types 0, 2 and 6, the 18 speech parameters are filled from the + TS-101-318-like payload portion of super-5993 input. + +* For frame types 1 and 7, the 18 speech parameters are set to all zeros, with + the expectation that gsmhr_decode_frame() or gsmhr_tfo_xfrm() will ignore + them. Please note that "verbose" invalid SID bits that may be present in + TW-TS-002 transport are ignored. + +* The 4 metadata flags BFI, UFI, SID and TAF are set based on FT and the + additional ToC flags defined in TW-TS-002 section 5.3. + +* Themyscira extension of BFI=2, described earlier in this document, is used + to represent FT=7. + +* Invalid SID frames (FT=1) are converted to BFI=1 SID=1. + +int gsmhr_rtp_in_preen(const uint8_t *rtp_in, unsigned rtp_in_len, + uint8_t *canon_pl); + +This function performs initial processing of RTP input that is expected to be +one of the defined RTP formats for GSM-HR codec. It accepts all possibilities +of TW-TS-002, RFC 5993 or TS 101 318 (listed in ThemWi order of preference) and +writes canonical TW-TS-002 super-5993 format into a buffer. The output buffer +must have 15 bytes of space, and the frame written into this buffer will ALWAYS +be a valid input to gsmhr_decoder_twts002_in() function described above. + +The input arguments are RTP payload and its length. The return value is 0 if +RTP input was in a recognized format, or -1 if it is invalid. In the case of +invalid RTP input, the output is filled with ToC of 0x70 (BFI with no data) - +the output is always valid. + +Zero-length RTP payloads are acceptable; if rtp_in_len is 0, then rtp_in pointer +may be NULL. The output in this case is filled with ToC of 0x70 (BFI with no +data), but the return value is 0, indicating success. The intent is that truly +invalid RTP payloads are error events which should be counted, while NULL input +is a normal occurrence when ThemWi jitter buffer (twjit) does not hold a +previously received RTP packet that maps to the current tick. (Actually +transmitted RTP packets with a zero-length payloads are also possible: they are +ThemWi preferred alternative to IETF approach of intentional gaps in the RTP +stream.) + +int gsmhr_rtp_in_direct(const uint8_t *rtp_in, unsigned rtp_in_len, + int16_t *param); + +This function is fully equivalent to calling first gsmhr_rtp_in_preen(), then +gsmhr_decoder_twts002_in(). It is however slightly more efficient, as it avoids +the intermediate buffer and some copying. The return value is the same as +gsmhr_rtp_in_preen(), and just like with that function, the output is always +valid. + +Reading *.cod and *.dec files +----------------------------- + +The most native representation format for GSM-HR codec frames in libgsmhr1 is +arrays of broken-down speech parameters. However, unlike TS 101 318 format in +which every possible bit pattern is a plausible GSM-HR codec frame, an array of +broken-down parameters that purports to be a GSM-HR frame can contain garbage. +The additional metadata flags in the canonical decoder input format can also +contain garbage - which our speech decoder and TFO transform engines are NOT +prepared for! There is no potential for malfunction if these arrays of +parameters and metadata flags come only from libgsmhr1 functions - but if an +application needs to read *.cod or *.dec files, or otherwise accept external +input in any of these formats, then an explicit validation step is required. + +int gsmhr_check_common_params(const int16_t *params); + +This function examines an array of 18 codec parameters in the int16_t +representation used in this library, and checks if the unused upper bits of +each int16_t word are cleared as they should be. The return value is 0 if the +frame is valid or -1 if some extraneous high bits are set. + +int gsmhr_check_encoder_params(const int16_t *params); + +This function examines a frame of 20 int16_t words that corresponds to GSM-HR +encoder output format, and checks if the unused upper bits of each int16_t word +are cleared as they should be. This function should be used when reading from +ETSI-format *.cod files, to guard against reading garbage or wrong endian. The +return value is 0 if the frame is valid or -1 if some extraneous high bits are +set. + +int gsmhr_check_decoder_params(const int16_t *params); + +This function examines a frame of 22 int16_t words that corresponds to GSM-HR +decoder input format, and checks if the unused upper bits of each int16_t word +are cleared as they should be. This function should be used when reading from +ETSI-format *.dec files, to guard against reading garbage or wrong endian. The +return value is 0 if the frame is valid or -1 if some extraneous high bits are +set. Both BFI and SID words are limited to range [0,2], i.e., Themyscira BFI=2 +extension is accepted. + +SID field manipulation +---------------------- + +Unlike FR and EFR, GSM-HR codec lacks fixed rules for Rx frame classification +as valid SID, invalid SID or non-SID speech. The BTS makes this classification +decision according to its internal private rules, and the SID flag then needs +to be carried out of band in Abis, Ater and TFO. GSM 08.61 and TW-TS-002 +(extended 5993) formats provide the necessary out-of-band SID indication, but +the bare format of TS 101 318 does not. Therefore, the only kind of GSM-HR SID +that can be represented in TS 101 318 format are perfect, 100% error-free SID +frames in which all 79 bits of the SID field are set to 1. + +int gsmhr_ts101318_is_perfect_sid(const uint8_t *payload); + +This function checks the given TS 101 318 payload for the possibility of +perfect SID. The return value is 2 (GSM 06.41 code for valid SID) if the frame +is indeed a perfect SID, or 0 (GSM 06.41 code for non-SID speech) otherwise. + +void gsmhr_ts101318_set_sid_codeword(uint8_t *payload); + +This function sets all 79 bits of the SID field to 1s, forming a perfect SID +frame in the 14-byte buffer. The first 33 bits that carry R0 and LPC parameters +must already be filled correctly. + +void gsmhr_set_sid_cw_params(int16_t *params); + +This function fills parameters 4 through 17 of generated SID frames, setting +them to the required SID codeword. It can also be used to transform a speech +frame into a SID frame with the same R0 and LPC parameters. It is logically +equivalent to gsmhr_ts101318_set_sid_codeword(), but operates on the array of +parameters form, rather than TS 101 318 packed format.
