FreeCalypso > hg > gsm-codec-lib
changeset 510:5bf71b091323
libgsmhr1: add direct conversion from RTP input to decoder params
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 25 Aug 2024 02:19:37 +0000 |
parents | b7ddcb178ef6 |
children | a5d61331b675 |
files | libgsmhr1/Makefile libgsmhr1/rtp_in_direct.c libgsmhr1/tw_gsmhr.h |
diffstat | 3 files changed, 88 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/libgsmhr1/Makefile Sat Aug 17 23:11:51 2024 +0000 +++ b/libgsmhr1/Makefile Sun Aug 25 02:19:37 2024 +0000 @@ -1,6 +1,6 @@ OBJS= dhf_params.o enc_out_order.o mathdp31.o mathhalf.o pack_frame.o \ - rtp_in.o sid_detect.o sid_reset.o sp_rom.o twts002_in.o twts002_out.o \ - unpack_frame.o + rtp_in.o rtp_in_direct.o sid_detect.o sid_reset.o sp_rom.o twts002_in.o\ + twts002_out.o unpack_frame.o HDRS= enc_out_order.h mathdp31.h mathhalf.h namespace.h sp_rom.h tw_gsmhr.h \ typedefs.h LIB= libgsmhr1.a
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libgsmhr1/rtp_in_direct.c Sun Aug 25 02:19:37 2024 +0000 @@ -0,0 +1,84 @@ +/* + * The function implemented in this module takes whatever HRv1 payload format + * came in from RTP (can be RFC 5993 with or without TW-TS-002 extensions, + * can be bare TS 101 318, can be zero-length or missing payload) and turns it + * into the internal input form for the HRv1 decoder. It is logically + * equivalent to calling gsmhr_rtp_in_preen() followed by + * gsmhr_decoder_twts002_in(), but is more efficient by avoiding the extra + * intermediate buffer and copying. + */ + +#include <stdint.h> +#include <string.h> +#include "tw_gsmhr.h" + +static void emit_bfi_nodata(int16_t *params) +{ + memset(params, 0, sizeof(int16_t) * GSMHR_NUM_PARAMS); + params[18] = 2; /* BFI with no data */ + params[19] = 0; /* UFI */ + params[20] = 0; /* SID */ + params[21] = 0; /* TAF */ +} + +int gsmhr_rtp_in_direct(const uint8_t *rtp_in, unsigned rtp_in_len, + int16_t *params) +{ + int ft; + + switch (rtp_in_len) { + case 0: + /* BFI-no-data, but not an invalid RTP input per se */ + emit_bfi_nodata(params); + return 0; + case 1: + /* + * This length is valid only if the payload is in + * RFC 5993 or TW-TS-002 format with FT=1 or FT=7. + */ + if (rtp_in[0] & 0x80) + goto bad_rtp_input; + ft = rtp_in[0] >> 4; + if (ft == 1 || ft == 7) { + gsmhr_decoder_twts002_in(rtp_in, params); + return 0; + } else + goto bad_rtp_input; + case GSMHR_FRAME_LEN_RPF: + /* + * The length is that of a TS 101 318 payload. + * No further checks can be done: every possible + * bit pattern is a valid payload in this format. + * But we do need to check for a perfect SID + * (the only kind of SID this format allows) + * and mark it accordingly in the output. + */ + gsmhr_unpack_ts101318(rtp_in, params); + params[18] = 0; /* BFI */ + params[19] = 0; /* UFI */ + params[20] = gsmhr_ts101318_is_perfect_sid(rtp_in); + params[21] = 0; /* TAF */ + return 0; + case GSMHR_FRAME_LEN_5993: + /* + * This length is valid only if the payload is in + * RFC 5993 or TW-TS-002 format with FT=0, FT=2 or FT=6. + */ + if (rtp_in[0] & 0x80) + goto bad_rtp_input; + ft = rtp_in[0] >> 4; + if (ft == 0 || ft == 2 || ft == 6) { + gsmhr_decoder_twts002_in(rtp_in, params); + return 0; + } else + goto bad_rtp_input; + default: + bad_rtp_input: + /* + * Treat it like BFI-no-data, and tell the caller + * that we received an invalid RTP payload. + */ + emit_bfi_nodata(params); + return -1; + } +}
--- a/libgsmhr1/tw_gsmhr.h Sat Aug 17 23:11:51 2024 +0000 +++ b/libgsmhr1/tw_gsmhr.h Sun Aug 25 02:19:37 2024 +0000 @@ -48,6 +48,8 @@ int gsmhr_rtp_in_preen(const uint8_t *rtp_in, unsigned rtp_in_len, uint8_t *canon_pl); +int gsmhr_rtp_in_direct(const uint8_t *rtp_in, unsigned rtp_in_len, + int16_t *param); /* perfect SID detection and regeneration */