I believe the code you mentioned is in there. just in case, here is my repeater_vocoder.cc:


/* -*- c++ -*- */
/*
 * GNU Radio interface for Pavel Yazev's Project 25 IMBE Encoder/Decoder
 *
 * Copyright 2004 Free Software Foundation, Inc.
 * Copyright 2009 Pavel Yazev E-mail: pyazev@gmail.com
 * Copyright 2009-2013 KA1RBI
 *
 * 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.
 *
 * It 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 it; see the file COPYING.  If not, write to
 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

/*
 * config.h is generated by configure.  It contains the results
 * of probing for features, options etc.  It should be the first
 * file included in your .cc file.
 */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <vector>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include <imbe_vocoder.h>
#include <repeater_vocoder.h>
#include <op25_p25_frame.h>
#include <op25_imbe_frame.h>
#include <gr_io_signature.h>

/* bits to be preset to 1 for all transmitted frames */
static const bool ldu1_preset[] = {
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0-35 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, /* 36-71 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 72-107 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, /* 108-143 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-179 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, /* 180-215 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 216-251 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, /* 252-287 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 288-323 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, /* 324-359 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 360-395 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, /* 396-431 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 432-467 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, /* 468-503 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 504-539 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, /* 540-575 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 576-611 */
  0,1,0,1,1,0,1,1,0,1,0,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,1,0,0,0,0,0,0,0,1,0, /* 612-647 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 648-683 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, /* 684-719 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 720-755 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0, /* 756-791 */
  1,0,1,0,0,1,1,0,1,0,1,0,1,0,0,1,1,0,1,0,1,0,1,0,0,1,1,0,1,0,1,0,1,0,0,1, /* 792-827 */
  1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, /* 828-863 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 864-899 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, /* 900-935 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 936-971 */
  0,0,0,0,0,0,1,0,1,1,1,0,0,0,0,1,1,1,1,1,0,0,1,1,1,1,1,0,0,1,0,1,0,1,1,0, /* 972-1007 */
  0,1,0,0,1,0,0,1,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1008-1043 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, /* 1044-1079 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1080-1115 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, /* 1116-1151 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,1,1,0,1,1, /* 1152-1187 */
  1,1,1,1,0,0,1,1,1,1,0,0,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, /* 1188-1223 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1224-1259 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, /* 1260-1295 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1296-1331 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,0,0,0,0,1,1, /* 1332-1367 */
  1,1,1,0,1,1,0,1,1,1,0,0,1,0,1,1,0,1,0,0,0,1,1,0,1,1,1,0,0,1,0,0,0,0,0,0, /* 1368-1403 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, /* 1404-1439 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1440-1475 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, /* 1476-1511 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, /* 1512-1547 */
  1,0,1,0,1,0,0,1,0,0,0,0,1,0,1,0,1,0,1,0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,1,0, /* 1548-1583 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1584-1619 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, /* 1620-1655 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1656-1691 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0  /* 1692-1727 */
};

static const bool ldu2_preset[] = {
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0-35 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, /* 36-71 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 72-107 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, /* 108-143 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-179 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, /* 180-215 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 216-251 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, /* 252-287 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 288-323 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, /* 324-359 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 360-395 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, /* 396-431 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 432-467 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, /* 468-503 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 504-539 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, /* 540-575 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 576-611 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, /* 612-647 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 648-683 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, /* 684-719 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 720-755 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, /* 756-791 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 792-827 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, /* 828-863 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 864-899 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, /* 900-935 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 936-971 */
  0,0,0,0,0,0,1,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, /* 972-1007 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1008-1043 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, /* 1044-1079 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1080-1115 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, /* 1116-1151 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,1,1,0,1,0,0,0,1,0,1,1,0,1,0,0, /* 1152-1187 */
  1,0,0,0,1,0,1,1,0,1,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, /* 1188-1223 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1224-1259 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, /* 1260-1295 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1296-1331 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1,0,1,0,1,0,1,1, /* 1332-1367 */
  1,1,1,1,0,1,0,0,1,1,1,1,0,0,0,1,1,1,1,1,1,1,0,1,0,1,1,0,0,0,0,0,0,0,0,0, /* 1368-1403 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, /* 1404-1439 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1440-1475 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, /* 1476-1511 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1512-1547 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, /* 1548-1583 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1584-1619 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, /* 1620-1655 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1656-1691 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, /* 1692-1727 */
};

static void clear_bits(bit_vector& v) {
    for (size_t i=0; i<v.size(); i++) {
        v[i]=0;
    }
}

/*
 * Create a new instance of repeater_vocoder and return
 * a boost shared_ptr.  This is effectively the public constructor.
 */
repeater_vocoder_sptr
repeater_make_vocoder (bool encode_flag, bool verbose_flag, int stretch_amt, char* udp_host, int udp_port, bool raw_vectors_flag)
{
  return repeater_vocoder_sptr (new repeater_vocoder (encode_flag, verbose_flag, stretch_amt, udp_host, udp_port, raw_vectors_flag));
}

//////////////////////////////////////////////////////////////
//    enc/dec        udp    operation
//    dec        no    byte input; short output
//    dec        yes    byte input; null output
//    enc        no    short input; char output
//    enc        yes    short input; null output

#define M_IN(encode_flag, udp_port)  (1)
#define M_OUT(encode_flag, udp_port) ((udp_port) ? 0 : 1)
#define S_IN(encode_flag, udp_port)  ((encode_flag) ? sizeof(int16_t) : sizeof(uint8_t))
#define S_OUT(encode_flag, udp_port) ((udp_port) ? 0 : ((encode_flag) ? sizeof(uint8_t) : sizeof(int16_t)))

/*
 * The private constructor
 */
repeater_vocoder::repeater_vocoder (bool encode_flag, bool verbose_flag, int stretch_amt, char* udp_host, int udp_port, bool raw_vectors_flag)
    : gr_block ("vocoder",
          gr_make_io_signature (M_IN(encode_flag, udp_port), M_IN(encode_flag, udp_port), S_IN(encode_flag, udp_port)),
          gr_make_io_signature (M_OUT(encode_flag, udp_port), M_OUT(encode_flag, udp_port), S_OUT(encode_flag, udp_port))),
    frame_cnt(0),
    write_sock(0),
    write_bufp(0),
    peak_amplitude(0),
    peak(0),
    samp_ct(0),
    rxbufp(0),
    codeword_ct(0),
    sampbuf_ct(0),
    stretch_count(0),
    save_l(0),
    f_body(P25_VOICE_FRAME_SIZE)
{
    opt_encode_flag = encode_flag;
    opt_dump_raw_vectors = raw_vectors_flag;
    opt_verbose = verbose_flag;
    opt_udp_port = udp_port;

    opt_stretch_amt = 0;
    if (stretch_amt < 0) {
        opt_stretch_sign = -1;
        opt_stretch_amt = 0 - stretch_amt;
    } else {
        opt_stretch_sign = 1;
        opt_stretch_amt = stretch_amt;
    }

    if (opt_udp_port == 0)
        if (encode_flag) {
            // local output to gr source
            // encoding: an LDU's worth of dibits
            set_output_multiple(P25_VOICE_FRAME_SIZE >> 1);
        } else {
            // decoding: an LDU's worth of audio samples
            // set_output_multiple(FRAME * nof_voice_codewords);
        }
    else
        // remote UDP output
        init_sock(udp_host, opt_udp_port);

    clear_bits(f_body);

    const char *p = getenv("IMBE");
    if (p && strcasecmp(p, "soft") == 0)
        d_software_imbe_decoder = true;
    else
        d_software_imbe_decoder = false;
}

/*
 * Our virtual destructor.
 */
repeater_vocoder::~repeater_vocoder ()
{
}

static const int STATS_INTERVAL = 20;
static const int SAMP_INTERVAL = 8192;

void repeater_vocoder::append_imbe_codeword(bit_vector& frame_body, int16_t frame_vector[], unsigned int& codeword_ct)
{
    voice_codeword cw(voice_codeword_sz);
    uint8_t obuf[P25_VOICE_FRAME_SIZE/2];
    // construct 144-bit codeword from 88 bits of parameters
    imbe_header_encode(cw, frame_vector[0], frame_vector[1], frame_vector[2], frame_vector[3], frame_vector[4], frame_vector[5], frame_vector[6], frame_vector[7]);

    // add codeword to voice data unit
    imbe_interleave(frame_body, cw, codeword_ct);

    // after the ninth and final codeword added, dispose of frame
    if (++codeword_ct >= nof_voice_codewords) {
        static const uint64_t hws[2] = { 0x293555ef2c653437LL, 0x293aba93bec26a2bLL };
                int ldu_type = frame_cnt & 1;    // set ldu_type = 0(LDU1) or 1(LDU2)
        const bool* ldu_preset = (ldu_type == 0) ? ldu1_preset : ldu2_preset;
       
        p25_setup_frame_header(frame_body, hws[ldu_type]);
        for (size_t i = 0; i < frame_body.size(); i++) {
            frame_body[i] = frame_body[i] | ldu_preset[i];
        }
        // finally, output the frame
        if (opt_udp_port > 0) {
            // pack the bits into bytes, MSB first
            size_t obuf_ct = 0;
            for (uint32_t i = 0; i < P25_VOICE_FRAME_SIZE; i += 8) {
                uint8_t b =
                    (frame_body[i+0] << 7) +
                    (frame_body[i+1] << 6) +
                    (frame_body[i+2] << 5) +
                    (frame_body[i+3] << 4) +
                    (frame_body[i+4] << 3) +
                    (frame_body[i+5] << 2) +
                    (frame_body[i+6] << 1) +
                    (frame_body[i+7]     );
                obuf[obuf_ct++] = b;
            }
            sendto(write_sock, obuf, obuf_ct, 0, (struct sockaddr*)&write_sock_addr, sizeof(write_sock_addr));
        } else {
            for (uint32_t i = 0; i < P25_VOICE_FRAME_SIZE; i += 2) {
                uint8_t dibit =
                    (frame_body[i+0] << 1) +
                    (frame_body[i+1]     );
                output_queue.push_back(dibit);
            }
        }
        codeword_ct = 0;
        frame_cnt++;
        if (opt_verbose && (frame_cnt % STATS_INTERVAL) == 0) {
            gettimeofday(&tv, &tz);
            int s = tv.tv_sec - oldtv.tv_sec;
            int us = tv.tv_usec - oldtv.tv_usec;
            if (us < 0) {
                us = us + 1000000;
                s  = s - 1;
            }
            float f = us;
            f /= 1000000;
            f += s;
            fprintf (stderr, "time %f peak %5d\n", f / STATS_INTERVAL, peak_amplitude);
            oldtv = tv;
        }
        clear_bits(f_body);
    }
}

void repeater_vocoder::rxchar(char c)
{
    int16_t snd[FRAME];
    int16_t frame_vector[8];
    int u[8];

    if (c < ' ') {
        if (c == '\n') {
            rxbuf[rxbufp] = 0;
            sscanf(rxbuf, "%x %x %x %x %x %x %x %x", &u[0], &u[1], &u[2], &u[3], &u[4], &u[5], &u[6], &u[7]);
            rxbufp = 0;
            // decode 88 bits, outputs 160 sound samples (8000 rate)
            if (d_software_imbe_decoder) {
                voice_codeword cw(voice_codeword_sz);
                imbe_header_encode(cw, u[0], u[1], u[2], u[3], u[4], u[5], u[6], u[7]);
                software_decoder.decode(cw);
                audio_samples *samples = software_decoder.audio();
                for (int i=0; i < FRAME; i++) {
                    if (samples->size() > 0) {
                        snd[i] = (int16_t)(samples->front() * 32768.0);
                        samples->pop_front();
                    } else {
                        snd[i] = 0;
                    }
                }
            } else {
                for (int i=0; i < 8; i++) {
                    frame_vector[i] = u[i];
                }
        /* TEST*/    frame_vector[7] >>= 1;
                vocoder.imbe_decode(frame_vector, snd);
            }
            if (opt_udp_port > 0) {
                sendto(write_sock, snd, FRAME * sizeof(int16_t), 0, (struct sockaddr*)&write_sock_addr, sizeof(write_sock_addr));
            } else {
                // add generated samples to output queue
                for (int i = 0; i < FRAME; i++) {
                    output_queue_decode.push_back(snd[i]);
                }
            }
        }
        return;
    }
    rxbuf[rxbufp++] = c;
    if (rxbufp >= RXBUF_MAX) {
        rxbufp = RXBUF_MAX - 1;
    }
}

void repeater_vocoder::compress_frame(int16_t snd[])
{
    int16_t frame_vector[8];   

    // encode 160 audio samples into 88 bits (u0-u7)
    vocoder.imbe_encode(frame_vector, snd);

    // if dump option, dump u0-u7 to output
    if (opt_dump_raw_vectors) {
        char s[128];
        sprintf(s, "%03x %03x %03x %03x %03x %03x %03x %03x\n", frame_vector[0], frame_vector[1], frame_vector[2], frame_vector[3], frame_vector[4], frame_vector[5], frame_vector[6], frame_vector[7]);
        memcpy(&write_buf[write_bufp], s, strlen(s));
        write_bufp += strlen(s);
        if (write_bufp >= 288) {
            sendto(write_sock, write_buf, 288, 0, (struct sockaddr*)&write_sock_addr, sizeof(write_sock_addr));
            write_bufp = 0;
        }
        return;
    }
    append_imbe_codeword(f_body, frame_vector, codeword_ct);
}

void repeater_vocoder::add_sample(int16_t samp)
{
    // add one sample to 160-sample frame buffer and process if filled
    sampbuf[sampbuf_ct++] = samp;
    if (sampbuf_ct >= FRAME) {
        compress_frame(sampbuf);
        sampbuf_ct = 0;
    }

    // track signal amplitudes
    int16_t asamp = (samp < 0) ? 0 - samp : samp;
    peak = (asamp > peak) ? asamp : peak;
    if (++samp_ct >= SAMP_INTERVAL) {
        peak_amplitude = peak;
        peak = 0;
        samp_ct = 0;
    }
}

void repeater_vocoder::compress_samp(int16_t samp)
{
    // Apply sample rate slew to accomodate sound card rate discrepancy -
    // workaround for USRP underrun problem occurring when sound card
    // capture rate is slower than the correct rate

    // FIXME: autodetect proper value for opt_stretch_amt
    // perhaps by steering the LDU output rate to a 180.0 msec. rate

    stretch_count++;
    if (opt_stretch_amt != 0 && stretch_count >= opt_stretch_amt) {
        stretch_count = 0;
        if (opt_stretch_sign < 0)
            // spill this samp
            return;
        // repeat this samp
        add_sample(samp);
    }
    add_sample(samp);
}

void repeater_vocoder::init_sock(char* udp_host, int udp_port)
{
        memset (&write_sock_addr, 0, sizeof(write_sock_addr));
        write_sock = socket(PF_INET, SOCK_DGRAM, 17);   // UDP socket
        if (write_sock < 0) {
                fprintf(stderr, "repeater_vocoder: socket: %d\n", errno);
                write_sock = 0;
        return;
        }
        if (!inet_aton(udp_host, &write_sock_addr.sin_addr)) {
                fprintf(stderr, "repeater_vocoder: bad IP address\n");
        close(write_sock);
        write_sock = 0;
        return;
    }
        write_sock_addr.sin_family = AF_INET;
        write_sock_addr.sin_port = htons(udp_port);
}

void
repeater_vocoder::forecast(int nof_output_items, gr_vector_int &nof_input_items_reqd)
{
   /* When encoding, this block consumes 8000 symbols/s and produces 4800
    * samples/s. That's a sampling rate of 5/3 or 1.66667.
    *
    * When decoding, the block consumes one line of text per voice codeword.
    * Each line of text is exactly 32 bytes.  It outputs 160 samples for each
    * codeword; the ratio is thus 32/160 = 0.2.
    *
    * Thanks to Matt Mills for catching a bug where this value wasn't set correctly
    */
   const size_t nof_inputs = nof_input_items_reqd.size();
   const int nof_samples_reqd = (opt_encode_flag) ? (1.66667 * nof_output_items) : (0.2 * nof_output_items);
   std::fill(&nof_input_items_reqd[0], &nof_input_items_reqd[nof_inputs], nof_samples_reqd);
}

int
repeater_vocoder::general_work_decode (int noutput_items,
                   gr_vector_int &ninput_items,
                   gr_vector_const_void_star &input_items,
                   gr_vector_void_star &output_items)
{
  const char *in = (const char *) input_items[0];

  for (int i = 0; i < ninput_items[0]; i++){
    rxchar(in[i]);
  }

  // Tell runtime system how many input items we consumed on
  // each input stream.

  consume_each (ninput_items[0]);

  uint16_t *out = reinterpret_cast<uint16_t*>(output_items[0]);
  const int n = std::min(static_cast<int>(output_queue_decode.size()), noutput_items);
  if(0 < n) {
     copy(output_queue_decode.begin(), output_queue_decode.begin() + n, out);
     output_queue_decode.erase(output_queue_decode.begin(), output_queue_decode.begin() + n);
  }
  // Tell runtime system how many output items we produced.
  return n;
}

int
repeater_vocoder::general_work_encode (int noutput_items,
                   gr_vector_int &ninput_items,
                   gr_vector_const_void_star &input_items,
                   gr_vector_void_star &output_items)
{
  const short *in = (const short *) input_items[0];

  for (int i = 0; i < ninput_items[0]; i++){
    compress_samp(in[i]);
  }

  // Tell runtime system how many input items we consumed on
  // each input stream.

  consume_each (ninput_items[0]);

  if (opt_udp_port > 0)        // in udp option, we are a gr sink only
    return 0;

  uint8_t *out = reinterpret_cast<uint8_t*>(output_items[0]);
  const int n = std::min(static_cast<int>(output_queue.size()), noutput_items);
  if(0 < n) {
     copy(output_queue.begin(), output_queue.begin() + n, out);
     output_queue.erase(output_queue.begin(), output_queue.begin() + n);
  }
  // Tell runtime system how many output items we produced.
  return n;
}

int
repeater_vocoder::general_work (int noutput_items,
                   gr_vector_int &ninput_items,
                   gr_vector_const_void_star &input_items,
                   gr_vector_void_star &output_items)
{
    if (opt_encode_flag)
        return general_work_encode(noutput_items, ninput_items, input_items, output_items);
    else
        return general_work_decode(noutput_items, ninput_items, input_items, output_items);
}


On Sat, Dec 28, 2013 at 9:47 AM, Ryan Schilder <rjschilder@gmail.com> wrote:
ok i'll give it a shot. just for giggles i tried the op25_audio_tx.py that I have on a local repeater. I was able to make it into the repeater!

I'll check the file you mentioned above right now.

Thanks!
-Ryan


On Sat, Dec 28, 2013 at 9:40 AM, <ikj1234i@yahoo.com> wrote:
 

Hi Ryan

This is an interesting update - sounds like some progress, anyway!

As to the encryption, older versions of the TX code did not properly set the crypto algo ID, and if you're
using one of these that would explain why.  The way to tell is to look in repeater_vocoder.cc to see if you
have the following (see below).  If this code is not there that would explain what's happening.  If it is there then I think the next step would be to run some type of trace so we can confirm what the settings are by looking at the actual air data, there would be no doubt as to whether or not the bits are being set OK...

73

Max

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

/* bits to be preset to 1 for all transmitted frames */
static const bool ldu1_preset[] = {
 ...



__._,_.___
Reply via web post Reply to sender Reply to group Start a New Topic Messages in this topic (12)
Recent Activity:
Visit Your Group
.

__,_._,___