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. - 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. Related: SYS#5066 Change-Id: Icef7dd626d3d4641c66b8dd87e2047fc0ab547d1
This commit is contained in:
parent
bbe3024510
commit
a56e9705c9
|
@ -649,6 +649,25 @@ 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 uint8_t gsm0808_amr_modes_from_cfg[2][16];
|
||||
extern const char *gsm0808_amr_mode_str[8];
|
||||
|
||||
/* 3GPP TS 48.008 3.2.2.103 Speech Codec List */
|
||||
#define SPEECH_CODEC_MAXLEN 255
|
||||
struct gsm0808_speech_codec_list {
|
||||
|
|
|
@ -1968,4 +1968,91 @@ 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_str[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_str[bit]);
|
||||
*/
|
||||
const char *gsm0808_amr_mode_str[8] = {"4.75", "5.15", "5.90", "6.70", "7.40", "7.95", "10.2", "12.2"};
|
||||
|
||||
/*! @} */
|
||||
|
|
|
@ -246,6 +246,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_str;
|
||||
gsm0808_speech_codec_type_names;
|
||||
gsm0808_permitted_speech_names;
|
||||
gsm0808_chosen_enc_alg_names;
|
||||
|
|
Loading…
Reference in New Issue