diff --git a/src/Makefile b/src/Makefile index 19887e5..38263b9 100644 --- a/src/Makefile +++ b/src/Makefile @@ -9,7 +9,7 @@ all: conv_enc_test crc_test tetra-rx float_to_bits tunctl libosmo-tetra-phy.a: phy/tetra_burst_sync.o phy/tetra_burst.o $(AR) r $@ $^ -libosmo-tetra-mac.a: lower_mac/tetra_conv_enc.o tetra_tdma.o lower_mac/tetra_scramb.o lower_mac/tetra_rm3014.o lower_mac/tetra_interleave.o lower_mac/crc_simple.o tetra_common.o lower_mac/viterbi.o lower_mac/viterbi_cch.o lower_mac/viterbi_tch.o lower_mac/tetra_lower_mac.o tetra_upper_mac.o tetra_mac_pdu.o tetra_llc_pdu.o tetra_llc.o tetra_mle_pdu.o tetra_mm_pdu.o tetra_cmce_pdu.o tetra_sndcp_pdu.o tetra_gsmtap.o tuntap.o +libosmo-tetra-mac.a: lower_mac/tetra_conv_enc.o lower_mac/tch_reordering.o tetra_tdma.o lower_mac/tetra_scramb.o lower_mac/tetra_rm3014.o lower_mac/tetra_interleave.o lower_mac/crc_simple.o tetra_common.o lower_mac/viterbi.o lower_mac/viterbi_cch.o lower_mac/viterbi_tch.o lower_mac/tetra_lower_mac.o tetra_upper_mac.o tetra_mac_pdu.o tetra_llc_pdu.o tetra_llc.o tetra_mle_pdu.o tetra_mm_pdu.o tetra_cmce_pdu.o tetra_sndcp_pdu.o tetra_gsmtap.o tuntap.o $(AR) r $@ $^ float_to_bits: float_to_bits.o diff --git a/src/lower_mac/tch_reordering.c b/src/lower_mac/tch_reordering.c new file mode 100644 index 0000000..00fa4d5 --- /dev/null +++ b/src/lower_mac/tch_reordering.c @@ -0,0 +1,140 @@ +/* Bit re-ordering for TETRA ACELP speech codec */ + +/* (C) 2011 by Harald Welte + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +#include +#include + + +/* EN 300 395-2 V1.3.1 Table 4 */ + +#define NUM_ACELP_CLASS0_BITS 51 +/* 51 Unprotected Class0 bits */ +static const uint8_t class0_positions[NUM_ACELP_CLASS0_BITS] = { + 35, 36, 37, + 38, 39, 40, + 41, 42, 33, + 47, 48, + 56, + 61, 62, 63, + 65, 66, 67, + 68, 69, 70, + 74, 75, + 83, + 88, + 89, 90, 91, + 92, 93, 94, + 95, 96, 97, + 101, 102, + 110, + 115, + 116, 117, 118, + 119, 120, 121, + 122, 123, 124, + 128, 129, + 137 +}; + +#define NUM_ACELP_CLASS1_BITS 56 +static const uint8_t class1_positions[NUM_ACELP_CLASS1_BITS] = { + 58, 85, 112, + 54, 81, 108, 135, + 50, 77, + 104, 131, + 45, 72, 99, 126, + 55, 82, 109, 136, + 5, 13, 34, + 8, 16, 17, + 22, 23, 24, + 25, 26, + 6, 14, 7, 15, + 60, 87 ,114, + 46, + 73, 100, 127, + 44, 71, 98, 125, + 33, 49, + 76, 103, 130, + 59, 86, 113, + 57, 84, 111 +}; + +#define NUM_ACELP_CLASS2_BITS 30 +static const uint8_t class2_positions[NUM_ACELP_CLASS2_BITS] = { + 18, 19, 20, 21, + 31, 32, + 53, 80, 107, 134, + 1, 2, 3, 4, + 9, 10, 11, 12, + 27, 28, 29, 30, + 52, 79, 106, 133, + 51, 78, 105, 132 +}; + +#define NUM_ACELP_BITS (NUM_ACELP_CLASS0_BITS+NUM_ACELP_CLASS1_BITS+NUM_ACELP_CLASS2_BITS) + +/* reorder the 432-bit incoming (decoded) type2 bits of a full-rate speech + * frame in order to generate two consecutive 216-bit ACELP codec frames */ +void tetra_acelp_type2_to_codec(const uint8_t *in, uint8_t *out) +{ + int bit, frame; + const uint8_t *in_cur = in; + + for (bit = 0; bit < NUM_ACELP_CLASS0_BITS; bit++) { + for (frame = 0; frame < 2; frame++) + out[frame*NUM_ACELP_BITS + class0_positions[bit] - 1] = in_cur[2*bit + frame]; + } + in_cur += 2*NUM_ACELP_CLASS0_BITS; + + for (bit = 0; bit < NUM_ACELP_CLASS1_BITS; bit++) { + for (frame = 0; frame < 2; frame++) + out[frame*NUM_ACELP_BITS + class1_positions[bit] - 1] = in_cur[2*bit + frame]; + } + in_cur += 2*NUM_ACELP_CLASS1_BITS; + + for (bit = 0; bit < NUM_ACELP_CLASS2_BITS; bit++) { + for (frame = 0; frame < 2; frame++) + out[frame*NUM_ACELP_BITS + class2_positions[bit] - 1] = in_cur[2*bit + frame]; + } + + /* FIXME: same for STCH use */ +} + +void tetra_acelp_codec_to_acelp(const uint8_t *in, uint8_t *out) +{ + int bit, frame; + uint8_t *out_cur = out; + + for (bit = 0; bit < NUM_ACELP_CLASS0_BITS; bit++) { + for (frame = 0; frame < 2; frame++) + out_cur[2*bit + frame] = in[frame*NUM_ACELP_BITS + class0_positions[bit] - 1]; + } + out_cur += 2*NUM_ACELP_CLASS0_BITS; + + for (bit = 0; bit < NUM_ACELP_CLASS1_BITS; bit++) { + for (frame = 0; frame < 2; frame++) + out_cur[2*bit + frame] = in[frame*NUM_ACELP_BITS + class1_positions[bit] - 1]; + } + out_cur += 2*NUM_ACELP_CLASS1_BITS; + + for (bit = 0; bit < NUM_ACELP_CLASS2_BITS; bit++) { + for (frame = 0; frame < 2; frame++) + out_cur[2*bit + frame] = in[frame*NUM_ACELP_BITS + class2_positions[bit] - 1]; + } +}