diff --git a/op25/gr-op25_repeater/apps/tx/dv_tx.py b/op25/gr-op25_repeater/apps/tx/dv_tx.py index 8691d87..c51ebe3 100644 --- a/op25/gr-op25_repeater/apps/tx/dv_tx.py +++ b/op25/gr-op25_repeater/apps/tx/dv_tx.py @@ -69,6 +69,35 @@ class my_top_block(gr.top_block): (options, args) = parser.parse_args() max_inputs = 1 + + output_gains = { + 'dmr': 5.5, + 'dstar': 0.95, + 'p25': 5.5, + 'ysf': 5.5 + } + generators = { + 'dmr': transfer_function_dmr, + 'p25': transfer_function_tx, + 'ysf': transfer_function_dmr + } + gain_adjust = { + 'dmr': 3.0, + 'dstar': 6.0, + 'ysf': 5.0 + } + gain_adjust_fullrate = { + 'p25': 2.0, + 'ysf': 3.0 + } + output_gain = output_gains[options.protocol] + if options.protocol in generators.keys(): + generator = generators[options.protocol] + if options.protocol in gain_adjust.keys(): + os.environ['GAIN_ADJUST'] = str(gain_adjust[options.protocol]) + if options.protocol in gain_adjust_fullrate.keys(): + os.environ['GAIN_ADJUST_FULLRATE'] = str(gain_adjust_fullrate[options.protocol]) + if options.protocol == 'dmr': max_inputs = 2 ENCODER = op25_repeater.ambe_encoder_sb(options.verbose) @@ -76,11 +105,8 @@ class my_top_block(gr.top_block): DMR = op25_repeater.dmr_bs_tx_bb(options.verbose, options.config_file) self.connect(ENCODER, (DMR, 0)) self.connect(ENCODER2, (DMR, 1)) - output_gain = 5.5 - generator = transfer_function_dmr # RRC elif options.protocol == 'dstar': ENCODER = op25_repeater.dstar_tx_sb(options.verbose, options.config_file) - output_gain = 0.95 elif options.protocol == 'p25': ENCODER = op25_repeater.vocoder(True, # 0=Decode,True=Encode 0, # Verbose flag @@ -88,12 +114,8 @@ class my_top_block(gr.top_block): "", # udp ip address 0, # udp port False) # dump raw u vectors - output_gain = 5.5 - generator = transfer_function_tx # RC+preemphasis elif options.protocol == 'ysf': ENCODER = op25_repeater.ysf_tx_sb(options.verbose, options.config_file, options.fullrate_mode) - output_gain = 5.5 - generator = transfer_function_dmr # RRC else: print 'protocol [-p] option missing' sys.exit(0) diff --git a/op25/gr-op25_repeater/lib/ambe_encoder.cc b/op25/gr-op25_repeater/lib/ambe_encoder.cc index c011699..0349137 100644 --- a/op25/gr-op25_repeater/lib/ambe_encoder.cc +++ b/op25/gr-op25_repeater/lib/ambe_encoder.cc @@ -155,7 +155,7 @@ static inline float make_f0(int b0) { return (powf(2, (-4.311767578125 - (2.1336e-2 * ((float)b0+0.5))))); } -static void encode_ambe(const IMBE_PARAM *imbe_param, int b[], mbe_parms*cur_mp, mbe_parms*prev_mp, bool dstar) { +static void encode_ambe(const IMBE_PARAM *imbe_param, int b[], mbe_parms*cur_mp, mbe_parms*prev_mp, bool dstar, float gain_adjust) { static const float SQRT_2 = sqrtf(2.0); static const int b0_lmax = sizeof(b0_lookup) / sizeof(b0_lookup[0]); // int b[9]; @@ -237,20 +237,20 @@ static void encode_ambe(const IMBE_PARAM *imbe_param, int b[], mbe_parms*cur_mp, float lsa[NUM_HARMS_MAX]; float lsa_sum=0.0; - static const float DIV_F = 1.0/2.0; - for (int i1 = 0; i1 < imbe_param->num_harms; i1++) { float sa = (float)imbe_param->sa[i1]; if (sa < 1) sa = 1.0; if (imbe_param->v_uv_dsn[i1]) - lsa[i1] = log_l_2 + log2f(DIV_F*sa); + lsa[i1] = log_l_2 + log2f(sa); else - lsa[i1] = log_l_w0 + log2f(DIV_F*sa); + lsa[i1] = log_l_w0 + log2f(sa); lsa_sum += lsa[i1]; } float gain = lsa_sum / num_harms_f; float diff_gain = gain - 0.5 * prev_mp->gamma; + diff_gain -= gain_adjust; + float error; int error_index; int max_dg = (dstar) ? 64 : 32; @@ -283,8 +283,7 @@ static void encode_ambe(const IMBE_PARAM *imbe_param, int b[], mbe_parms*cur_mp, int kl_floor = (int) kl; float kl_frac = kl - kl_floor; T[i1] = lsa[i1] - 0.65 * (1.0 - kl_frac) * prev_mp->log2Ml[kl_floor +0] \ - - 0.65 * kl_frac * prev_mp->log2Ml[kl_floor+1 +0] \ - + (0.65 / num_harms_f) * tmp_s; + - 0.65 * kl_frac * prev_mp->log2Ml[kl_floor+1 +0]; } // DCT @@ -541,10 +540,20 @@ static void encode_49bit(uint8_t outp[49], const int b[9]) { ambe_encoder::ambe_encoder(void) : d_49bit_mode(false), - d_dstar_mode(false) + d_dstar_mode(false), + d_gain_adjust(0) { mbe_parms enh_mp; mbe_initMbeParms (&cur_mp, &prev_mp, &enh_mp); + // this is a hack to cut down on overloading + // value is in log2 + char *gfp = getenv("GAIN_ADJUST"); + if (gfp) { + float gain_adj = 0.0; + sscanf(gfp, "%f", &gain_adj); + if (!isnan(gain_adj)) + d_gain_adjust = gain_adj; + } } void ambe_encoder::set_dstar_mode(void) @@ -572,7 +581,7 @@ void ambe_encoder::encode(int16_t samples[], uint8_t codeword[]) vocoder.imbe_encode(frame_vector, samples); // halfrate audio encoding - output rate is 2450 (49 bits) - encode_ambe(vocoder.param(), b, &cur_mp, &prev_mp, d_dstar_mode); + encode_ambe(vocoder.param(), b, &cur_mp, &prev_mp, d_dstar_mode, d_gain_adjust); if (d_dstar_mode) { interleaver.encode_dstar(codeword, b); diff --git a/op25/gr-op25_repeater/lib/ambe_encoder.h b/op25/gr-op25_repeater/lib/ambe_encoder.h index 5bba34d..5605d36 100644 --- a/op25/gr-op25_repeater/lib/ambe_encoder.h +++ b/op25/gr-op25_repeater/lib/ambe_encoder.h @@ -35,6 +35,7 @@ private: mbe_parms prev_mp; bool d_49bit_mode; bool d_dstar_mode; + float d_gain_adjust; }; #endif /* INCLUDED_AMBE_ENCODER_H */ diff --git a/op25/gr-op25_repeater/lib/imbe_vocoder/imbe_vocoder.cc b/op25/gr-op25_repeater/lib/imbe_vocoder/imbe_vocoder.cc index b61e3b0..b31b5a9 100644 --- a/op25/gr-op25_repeater/lib/imbe_vocoder/imbe_vocoder.cc +++ b/op25/gr-op25_repeater/lib/imbe_vocoder/imbe_vocoder.cc @@ -5,6 +5,7 @@ */ #include +#include #include "imbe_vocoder.h" @@ -21,7 +22,8 @@ imbe_vocoder::imbe_vocoder (void) : num_harms_prev3(0), fund_freq_prev(0), th_max(0), - dc_rmv_mem(0) + dc_rmv_mem(0), + d_gain_adjust(0) { memset(wr_array, 0, sizeof(wr_array)); memset(wi_array, 0, sizeof(wi_array)); @@ -42,6 +44,16 @@ imbe_vocoder::imbe_vocoder (void) : decode_init(&my_imbe_param); encode_init(); + // this is a hack to cut down on overloading + // value is in log2 + char *gfp = getenv("GAIN_ADJUST_FULLRATE"); + if (gfp) { + int gain_adj = 0; + sscanf(gfp, "%d", &gain_adj); + if (gain_adj) + d_gain_adjust = (Word32) gain_adj; + } + if (!already_printed) { already_printed = 1; fprintf(stderr,"Project 25 IMBE Encoder/Decoder Fixed-Point implementation\n"); diff --git a/op25/gr-op25_repeater/lib/imbe_vocoder/imbe_vocoder.h b/op25/gr-op25_repeater/lib/imbe_vocoder/imbe_vocoder.h index 144e415..940d5bb 100644 --- a/op25/gr-op25_repeater/lib/imbe_vocoder/imbe_vocoder.h +++ b/op25/gr-op25_repeater/lib/imbe_vocoder/imbe_vocoder.h @@ -59,6 +59,7 @@ private: Word32 dc_rmv_mem; Cmplx16 fft_buf[FFTLENGTH]; Word16 pe_lpf_mem[PE_LPF_ORD]; + Word32 d_gain_adjust; /* member functions */ void idct(Word16 *in, Word16 m_lim, Word16 i_lim, Word16 *out); diff --git a/op25/gr-op25_repeater/lib/imbe_vocoder/sa_encode.cc b/op25/gr-op25_repeater/lib/imbe_vocoder/sa_encode.cc index 7553f74..766032a 100644 --- a/op25/gr-op25_repeater/lib/imbe_vocoder/sa_encode.cc +++ b/op25/gr-op25_repeater/lib/imbe_vocoder/sa_encode.cc @@ -99,7 +99,7 @@ void imbe_vocoder::sa_encode(IMBE_PARAM *imbe_param) if(si_coef == 0) { tmp_word32 = L_mpy_ls(sa_prev2[index], ro_coef); // sa_prev2 here is in Q10.22 format - *vec32_ptr++ = L_sub(Log2(*sa_ptr++), tmp_word32); + *vec32_ptr = L_sub(Log2(*sa_ptr++), tmp_word32); sum = L_add(sum, sa_prev2[index]); // sum in Q10.22 format } else @@ -112,8 +112,10 @@ void imbe_vocoder::sa_encode(IMBE_PARAM *imbe_param) sum = L_add(sum, tmp_word32); *vec32_ptr = L_sub(*vec32_ptr, L_mpy_ls(tmp_word32, ro_coef)); - vec32_ptr++; } + if (d_gain_adjust) + *vec32_ptr = L_sub(*vec32_ptr, d_gain_adjust << 22); // would be nicer to allow fractional increments... + vec32_ptr++; k_acc += k_coef; }