dmr updates
This commit is contained in:
parent
b81ad173b1
commit
560f0c5461
|
@ -0,0 +1,73 @@
|
||||||
|
#################################################################################
|
||||||
|
#
|
||||||
|
# config file for DMR BS TX
|
||||||
|
#
|
||||||
|
#################################################################################
|
||||||
|
#
|
||||||
|
# DMR Encoder (C) Copyright 2017 Max H. Parke KA1RBI
|
||||||
|
#
|
||||||
|
# This file is part of OP25
|
||||||
|
#
|
||||||
|
# This is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
#
|
||||||
|
# This software 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 General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this software; see the file COPYING. If not, write to
|
||||||
|
# the Free Software Foundation, Inc., 51 Franklin Street,
|
||||||
|
# Boston, MA 02110-1301, USA.
|
||||||
|
#################################################################################
|
||||||
|
#
|
||||||
|
# NOTE
|
||||||
|
#
|
||||||
|
# Everything in this file is doubled up due to the two slot TDMA.
|
||||||
|
#
|
||||||
|
# For example "en1" is for slot 1 and "en2" is for slot 2
|
||||||
|
#
|
||||||
|
# Syntax is unforgiving - no whitespace allowed (outside of comments)
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#################################################################################
|
||||||
|
#
|
||||||
|
# slot enable [1 bit: 0=disable; 1=enable]
|
||||||
|
# - transmits voice sync when enabled, idle slot sync when disabled
|
||||||
|
# - the GR block consumes input samples on both channels (whether or not enabled)
|
||||||
|
#
|
||||||
|
en1=1
|
||||||
|
en2=1
|
||||||
|
#################################################################################
|
||||||
|
#
|
||||||
|
# color code [4 bits]
|
||||||
|
#
|
||||||
|
cc1=1
|
||||||
|
cc2=1
|
||||||
|
#################################################################################
|
||||||
|
#
|
||||||
|
# Activity Update
|
||||||
|
# - source: spec volume 2 para 7.1.3.2
|
||||||
|
# - specify the hashed address [8 bits]
|
||||||
|
# - compressed destination address 1 and destination address 2
|
||||||
|
# - typically set to zero [?]
|
||||||
|
#
|
||||||
|
ts1=0
|
||||||
|
ts2=0
|
||||||
|
#################################################################################
|
||||||
|
#
|
||||||
|
# Group Voice Channel User LC PDU
|
||||||
|
# - source: spec volume 2 paragraph 7.1.1.1
|
||||||
|
# - the so/ga/sa (Service Options/[talk]Group Address/Source Address)
|
||||||
|
# - values are specified in decimal [so: 8 bits; sa and ga: 24 bits]
|
||||||
|
# - service options are typically set to zero [?]
|
||||||
|
#
|
||||||
|
so1=0
|
||||||
|
so2=0
|
||||||
|
ga1=1
|
||||||
|
ga2=311
|
||||||
|
sa1=1
|
||||||
|
sa2=1
|
|
@ -76,6 +76,18 @@ def transfer_function_tx():
|
||||||
xfer.append(pf * hf)
|
xfer.append(pf * hf)
|
||||||
return xfer
|
return xfer
|
||||||
|
|
||||||
|
def transfer_function_dmr():
|
||||||
|
xfer = [] # frequency domain transfer function
|
||||||
|
for f in xrange(0, 2881): # specs cover 0 - 2,880 Hz
|
||||||
|
if f < 1920:
|
||||||
|
hf = 1.0
|
||||||
|
else:
|
||||||
|
hf = 0.5 + 0.5 * cos (2 * pi * float(f) / 1920.0)
|
||||||
|
xfer.append(hf)
|
||||||
|
xfer = np.array(xfer, dtype=np.float64)
|
||||||
|
xfer = np.sqrt(xfer) # root cosine
|
||||||
|
return xfer
|
||||||
|
|
||||||
class c4fm_taps(object):
|
class c4fm_taps(object):
|
||||||
"""Generate filter coefficients as per P25 C4FM spec"""
|
"""Generate filter coefficients as per P25 C4FM spec"""
|
||||||
def __init__(self, filter_gain = 1.0, sample_rate=_def_output_sample_rate, symbol_rate=_def_symbol_rate, span=_def_span, generator=transfer_function_tx):
|
def __init__(self, filter_gain = 1.0, sample_rate=_def_output_sample_rate, symbol_rate=_def_symbol_rate, span=_def_span, generator=transfer_function_tx):
|
||||||
|
@ -106,6 +118,7 @@ class p25_mod_bf(gr.hier_block2):
|
||||||
output_sample_rate=_def_output_sample_rate,
|
output_sample_rate=_def_output_sample_rate,
|
||||||
reverse=_def_reverse,
|
reverse=_def_reverse,
|
||||||
verbose=_def_verbose,
|
verbose=_def_verbose,
|
||||||
|
generator=transfer_function_tx,
|
||||||
log=_def_log):
|
log=_def_log):
|
||||||
"""
|
"""
|
||||||
Hierarchical block for RRC-filtered P25 FM modulation.
|
Hierarchical block for RRC-filtered P25 FM modulation.
|
||||||
|
@ -143,7 +156,9 @@ class p25_mod_bf(gr.hier_block2):
|
||||||
else:
|
else:
|
||||||
self.polarity = blocks.multiply_const_ff( 1)
|
self.polarity = blocks.multiply_const_ff( 1)
|
||||||
|
|
||||||
self.filter = filter.interp_fir_filter_fff(self._interp_factor, c4fm_taps(sample_rate=output_sample_rate).generate())
|
self.generator = generator
|
||||||
|
|
||||||
|
self.filter = filter.interp_fir_filter_fff(self._interp_factor, c4fm_taps(sample_rate=output_sample_rate, generator=self.generator).generate())
|
||||||
|
|
||||||
if verbose:
|
if verbose:
|
||||||
self._print_verbage()
|
self._print_verbage()
|
||||||
|
|
|
@ -119,17 +119,20 @@ static void encode_embedded(const uint8_t lc[72], uint8_t result[32*4]) {
|
||||||
for (int i=0; i<9; i++) {
|
for (int i=0; i<9; i++) {
|
||||||
csum += load_i(&lc[i*8], 8);
|
csum += load_i(&lc[i*8], 8);
|
||||||
}
|
}
|
||||||
|
csum = csum % 31;
|
||||||
|
for (int i=0; i<7; i++) {
|
||||||
|
memcpy(&encode[16*i], &lc[s_index], lengths[i]);
|
||||||
|
s_index += lengths[i];
|
||||||
|
}
|
||||||
for (int i=0; i<5; i++) {
|
for (int i=0; i<5; i++) {
|
||||||
encode[(i+2)*16+10] = (csum >> (4-i)) & 1;
|
encode[(i+2)*16+10] = (csum >> (4-i)) & 1;
|
||||||
}
|
}
|
||||||
for (int i=0; i<7; i++) {
|
for (int i=0; i<7; i++) {
|
||||||
memcpy(&encode[16*i], &lc[s_index], lengths[i]);
|
int acc = load_i(&encode[16*i], 11);
|
||||||
int acc = load_i(&lc[s_index], 11);
|
|
||||||
acc = hamming_16_11[acc];
|
acc = hamming_16_11[acc];
|
||||||
for (int j=0; j<5; j++){
|
for (int j=0; j<5; j++){
|
||||||
encode[i*16+j+11] = (acc >> (4-j)) & 1;
|
encode[i*16+j+11] = (acc >> (4-j)) & 1;
|
||||||
}
|
}
|
||||||
s_index += lengths[i];
|
|
||||||
}
|
}
|
||||||
for (int i=0; i<16; i++) {
|
for (int i=0; i<16; i++) {
|
||||||
encode[7*16+i] = (encode[0*16+i] + encode[1*16+i] + encode[2*16+i] + \
|
encode[7*16+i] = (encode[0*16+i] + encode[1*16+i] + encode[2*16+i] + \
|
||||||
|
@ -277,12 +280,12 @@ dmr_bs_tx_bb_impl::config()
|
||||||
}
|
}
|
||||||
for (;;) {
|
for (;;) {
|
||||||
cp = fgets(line, sizeof(line) - 2, fp1);
|
cp = fgets(line, sizeof(line) - 2, fp1);
|
||||||
|
if (!cp) break;
|
||||||
if (line[0] == '#') continue;
|
if (line[0] == '#') continue;
|
||||||
// cach: hashed addr ts1(8) and hashed addr ts2(8)
|
// cach: hashed addr ts1(8) and hashed addr ts2(8)
|
||||||
// emb: (one per ch) cc(4)
|
// emb: (one per ch) cc(4)
|
||||||
// group voice channel user PDU: service options (8), group address(24), source address(24)
|
// group voice channel user PDU: service options (8), group address(24), source address(24)
|
||||||
// (one per ch)
|
// (one per ch)
|
||||||
if (!cp) break;
|
|
||||||
if (memcmp(line, "ts1=", 4) == 0)
|
if (memcmp(line, "ts1=", 4) == 0)
|
||||||
sscanf(&line[4], "%d", &d_ts[0]);
|
sscanf(&line[4], "%d", &d_ts[0]);
|
||||||
else if (memcmp(line, "ts2=", 4) == 0)
|
else if (memcmp(line, "ts2=", 4) == 0)
|
||||||
|
@ -416,7 +419,7 @@ dmr_bs_tx_bb_impl::general_work (int noutput_items,
|
||||||
// -1: RC
|
// -1: RC
|
||||||
// 0|1|2|3: segment no. of embedded signalling
|
// 0|1|2|3: segment no. of embedded signalling
|
||||||
{-2, 0, 1, -1, 2, 3},
|
{-2, 0, 1, -1, 2, 3},
|
||||||
{-2, 0, 1, 2, 3, -1}
|
{-1, 2, 3, -2, 0, 1}
|
||||||
};
|
};
|
||||||
|
|
||||||
int nconsumed[2] = {0,0};
|
int nconsumed[2] = {0,0};
|
||||||
|
|
Loading…
Reference in New Issue