mirror of https://gerrit.osmocom.org/libosmocore
add gsm0808_amr_modes_from_cfg
Provide the definitions from 3GPP TS 28.062, Table 7.11.3.1.3-2 as generally usable API. Likely users: - upcoming patch to improve conversion between S0-S15 and MultiRate config, I900fda192742fa8f6dd54e9131ef1704b14cc41a - osmo-msc to figure out conversion between SDP AMR mode-set and 3GPP TS 48.008 Permitted Speech S0-S15. - osmo-bsc to choose AMR modes for channel activation from cfg / permitted speech from MSC. Related: SYS#5066 Change-Id: Icef7dd626d3d4641c66b8dd87e2047fc0ab547d1
This commit is contained in:
parent
64277a0217
commit
593d20d637
|
@ -687,6 +687,29 @@ enum gsm0808_speech_codec_rate {
|
|||
GSM0808_SC_CFG_AMR_12_2 = 0x0080,
|
||||
};
|
||||
|
||||
/* Bit index of a mode as returned by gsm0808_amr_modes_from_cfg[].
|
||||
* Example:
|
||||
* if (gsm0808_amr_modes_from_cfg[full_rate ? 1 : 0][9] & GSM0808_AMR_MODE_4_75)
|
||||
* printf("S9 supports 4k75");
|
||||
*/
|
||||
enum gsm0808_amr_mode {
|
||||
GSM0808_AMR_MODE_4_75 = 0,
|
||||
GSM0808_AMR_MODE_5_15,
|
||||
GSM0808_AMR_MODE_5_90,
|
||||
GSM0808_AMR_MODE_6_70,
|
||||
GSM0808_AMR_MODE_7_40,
|
||||
GSM0808_AMR_MODE_7_95,
|
||||
GSM0808_AMR_MODE_10_2,
|
||||
GSM0808_AMR_MODE_12_2,
|
||||
};
|
||||
extern const struct value_string gsm0808_amr_mode_names[];
|
||||
static inline const char *gsm0808_amr_mode_name(enum gsm0808_amr_mode val)
|
||||
{
|
||||
return get_value_string(gsm0808_amr_mode_names, val);
|
||||
}
|
||||
|
||||
extern const uint8_t gsm0808_amr_modes_from_cfg[2][16];
|
||||
|
||||
/* 3GPP TS 48.008 3.2.2.103 Speech Codec List */
|
||||
#define SPEECH_CODEC_MAXLEN 255
|
||||
struct gsm0808_speech_codec_list {
|
||||
|
|
|
@ -2028,4 +2028,101 @@ const struct value_string gsm0808_lcls_status_names[] = {
|
|||
{ 0, NULL }
|
||||
};
|
||||
|
||||
/* Convert one S0-S15 bit to its set of AMR modes, for HR AMR and FR AMR.
|
||||
* This is 3GPP TS 28.062 Table 7.11.3.1.3-2: "Preferred Configurations", with some configurations removed as specified
|
||||
* in 3GPP TS 48.008 3.2.2.103:
|
||||
*
|
||||
* FR_AMR is coded ‘0011’.
|
||||
* S11, S13 and S15 are reserved and coded with zeroes.
|
||||
*
|
||||
* HR_AMR is coded ‘0100’.
|
||||
* S6 - S7 and S11 – S15 are reserved and coded with zeroes.
|
||||
*
|
||||
* Meaning: for FR, exclude all Optimisation Mode configurations.
|
||||
* For HR, exclude all that are not supported by HR AMR -- drop all that include at least one of
|
||||
* 10.2 or 12.2.
|
||||
*
|
||||
* Also, for HR, drop 12.2k from S1.
|
||||
*
|
||||
* The first array dimension is 0 for half rate and 1 for full rate.
|
||||
* The second array dimension is the configuration number (0..15) aka Sn.
|
||||
* The values are bitmask combinations of (1 << GSM0808_AMR_MODE_nnnn).
|
||||
*
|
||||
* For example, accumulate all modes that are possible in a given my_s15_s0:
|
||||
*
|
||||
* uint8_t modes = 0;
|
||||
* for (s_bit = 0; s_bit < 15; s_bit++)
|
||||
* if (my_s15_s0 & (1 << s_bit))
|
||||
* modes |= gsm0808_amr_modes_from_cfg[full_rate ? 1 : 0][s_bit];
|
||||
* for (i = 0; i < 8; i++)
|
||||
* if (modes & (1 << i))
|
||||
* printf(" %s", gsm0808_amr_mode_name(i));
|
||||
*/
|
||||
const uint8_t gsm0808_amr_modes_from_cfg[2][16] = {
|
||||
#define B(X) (1 << (GSM0808_AMR_MODE_##X))
|
||||
/* HR */
|
||||
{
|
||||
/* Sn = modes */
|
||||
[0] = B(4_75),
|
||||
[1] = B(4_75) | B(5_90) | B(7_40),
|
||||
[2] = B(5_90),
|
||||
[3] = B(6_70),
|
||||
[4] = B(7_40),
|
||||
[5] = B(7_95),
|
||||
[6] = 0,
|
||||
[7] = 0,
|
||||
|
||||
[8] = B(4_75) | B(5_90),
|
||||
[9] = B(4_75) | B(5_90) | B(6_70),
|
||||
[10] = B(4_75) | B(5_90) | B(6_70) | B(7_40),
|
||||
[11] = 0,
|
||||
[12] = 0,
|
||||
[13] = 0,
|
||||
[14] = 0,
|
||||
[15] = 0,
|
||||
},
|
||||
/* FR */
|
||||
{
|
||||
/* Sn = modes */
|
||||
[0] = B(4_75),
|
||||
[1] = B(4_75) | B(5_90) | B(7_40) | B(12_2),
|
||||
[2] = B(5_90),
|
||||
[3] = B(6_70),
|
||||
[4] = B(7_40),
|
||||
[5] = B(7_95),
|
||||
[6] = B(10_2),
|
||||
[7] = B(12_2),
|
||||
|
||||
[8] = B(4_75) | B(5_90),
|
||||
[9] = B(4_75) | B(5_90) | B(6_70),
|
||||
[10] = B(4_75) | B(5_90) | B(6_70) | B(7_40),
|
||||
[11] = 0,
|
||||
[12] = B(4_75) | B(5_90) | B(6_70) | B(10_2),
|
||||
[13] = 0,
|
||||
[14] = B(4_75) | B(5_90) | B(7_95) | B(12_2),
|
||||
[15] = 0,
|
||||
}
|
||||
};
|
||||
|
||||
/* AMR mode names from GSM0808_AMR_MODE_*, for use with gsm0808_amr_modes_from_cfg.
|
||||
*
|
||||
* For example:
|
||||
* printf("S9: ");
|
||||
* uint8_t s9_modes = gsm0808_amr_modes_from_cfg[full_rate ? 1 : 0][9];
|
||||
* for (bit = 0; bit < 8; bit++)
|
||||
* if (s9_modes & (1 << bit))
|
||||
* printf("%s,", gsm0808_amr_mode_name(bit));
|
||||
*/
|
||||
const struct value_string gsm0808_amr_mode_names[] = {
|
||||
{ GSM0808_AMR_MODE_4_75, "4.75" },
|
||||
{ GSM0808_AMR_MODE_5_15, "5.15" },
|
||||
{ GSM0808_AMR_MODE_5_90, "5.90" },
|
||||
{ GSM0808_AMR_MODE_6_70, "6.70" },
|
||||
{ GSM0808_AMR_MODE_7_40, "7.40" },
|
||||
{ GSM0808_AMR_MODE_7_95, "7.95" },
|
||||
{ GSM0808_AMR_MODE_10_2, "10.2" },
|
||||
{ GSM0808_AMR_MODE_12_2, "12.2" },
|
||||
{}
|
||||
};
|
||||
|
||||
/*! @} */
|
||||
|
|
|
@ -252,6 +252,8 @@ gsm0808_chan_type_to_speech_codec;
|
|||
gsm0808_speech_codec_from_chan_type;
|
||||
gsm0808_sc_cfg_from_gsm48_mr_cfg;
|
||||
gsm48_mr_cfg_from_gsm0808_sc_cfg;
|
||||
gsm0808_amr_modes_from_cfg;
|
||||
gsm0808_amr_mode_names;
|
||||
gsm0808_speech_codec_type_names;
|
||||
gsm0808_permitted_speech_names;
|
||||
gsm0808_chosen_enc_alg_names;
|
||||
|
|
Loading…
Reference in New Issue