/* -*- c++ -*- */ /* * NXDN 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. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "nxdn.h" #include "mbelib.h" #include "p25p2_vf.h" #include "nxdn_tx_sb_impl.h" #include "nxdn_const.h" #include #include #include #include #include #include #include #include #include #include static const uint8_t nxdn_fs[] = {3, 0, 3, 1, 3, 3, 1, 1, 2, 1}; #if 0 static inline void print_result(char title[], const uint8_t r[], int len) { uint8_t buf[256]; for (int i=0; i> (len-1-i)) & 1; } } static inline void bits_to_dibits(uint8_t* dest, const uint8_t* src, int n_dibits) { for (int i=0; i src, int n_dibits) { for (int i=0; i>3] >> (7-(i%8))) & 1; } } static inline int crc6(const uint8_t * bits, int len) { uint8_t s[6] = {1,1,1,1,1,1}; for (int i=0; i(output_items[0]); int nframes=0; int16_t frame_vector[8]; voice_codeword cw(voice_codeword_sz); uint8_t ambe_codeword[36]; // dibits std::vector interleaved_buf(144); for (int n=0;n < (noutput_items/d_output_amount);n++) { // need (at least) four voice codewords worth of samples if (ninput_items[0] - nconsumed < 4*160) break; memcpy(out, nxdn_fs, sizeof(nxdn_fs)); memcpy(out+10, d_lich_x1, 8); memcpy(out+18, d_sacch[d_sacch_seq++ % 4], 30); // TODO: would be nice to multithread these for (int vcw = 0; vcw < 4; vcw++) { d_halfrate_encoder.encode(in, ambe_codeword); memcpy(out+48+36*vcw, ambe_codeword, sizeof(ambe_codeword)); in += 160; nconsumed += 160; } nxdn_descramble(out+10, 182); if (d_nxdn96_mode) { memcpy(out+192, nxdn_fs, sizeof(nxdn_fs)); memcpy(out+192+10, d_lich_x2, 8); memcpy(out+192+18, d_sacch[d_sacch_seq++ % 4], 30); memcpy(out+192+48, d_facch1, 72); memcpy(out+192+120, d_facch1, 72); nxdn_descramble(out+192+10, 182); } nframes += 1; out += d_output_amount; } // Tell runtime system how many input items we consumed on // each input stream. if (nconsumed) consume_each(nconsumed); // Tell runtime system how many output items we produced. return (nframes * d_output_amount); } void nxdn_tx_sb_impl::set_gain_adjust(float gain_adjust) { d_halfrate_encoder.set_gain_adjust(gain_adjust); } } /* namespace op25_repeater */ } /* namespace gr */