/*
 * (C) 2019-2022 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
 * All rights reserved.
 *
 * Author: Pau Espin Pedrol <pespin@sysmocom.de>
 *
 * Released under the terms of GNU General Public License, Version 2 or
 * (at your option) any later version.
 */

module AMR_Types {

import from General_Types all;
import from Osmocom_Types all;

/* AMR voice frame type identifiers
 * See also 3GPP TS 26.101, Table 1a: Interpretation of Frame Type, Mode
 * Indication and Mode Request fields */
type enumerated AMRFT {
  AMR_FT_0,	/* 4.75 */
  AMR_FT_1,	/* 5.15 */
  AMR_FT_2,	/* 5.90 */
  AMR_FT_3,	/* 6.70 */
  AMR_FT_4,	/* 7.40 */
  AMR_FT_5,	/* 7.95 */
  AMR_FT_6,	/* 10.2 */
  AMR_FT_7,	/* 12.2 */
  AMR_FT_SID	/* SID */
};

/* AMR voice frame length (in bytes, rounded),
 * See also RFC 3267, chapter 3.6 */
const integer c_AMRFT_len[9] := {12, 13, 15, 17, 19, 20, 26, 31, 5};

function f_amrft_payload_len(INT4b amr_ft) return integer {
        return c_AMRFT_len[amr_ft];
}

type record RTP_AMR_Hdr {
	uint4_t cmr,
	BIT4 padding1,
	BIT1 f,
	uint4_t ft,
	BIT1 q,
	BIT2 padding2
} with { variant "FIELDORDER(msb)" };

template (value) RTP_AMR_Hdr ts_RTP_AMR_Hdr(template (value) uint4_t cmr,
					    template (value) uint4_t ft,
					    template (value) BIT1 q := '1'B,
					    template (value) BIT1 f := '0'B) := {
	cmr := cmr,
	padding1 := '0000'B,
	f := f,
	ft := ft,
	q := q,
	padding2 := '00'B
}
external function enc_RTP_AMR_Hdr(in RTP_AMR_Hdr amr_hdr) return octetstring
        with { extension "prototype(convert) encode(RAW)" };
external function dec_RTP_AMR_Hdr(in octetstring stream) return RTP_AMR_Hdr
        with { extension "prototype(convert) decode(RAW)" };

} with { encode "RAW"}
