Skip to content

Commit

Permalink
Merge pull request #296 from robotastic/decim-osx
Browse files Browse the repository at this point in the history
Merge in Branch
  • Loading branch information
robotastic committed Jan 29, 2020
2 parents 9c5c175 + c1a0b2e commit 5305e8f
Show file tree
Hide file tree
Showing 87 changed files with 3,867 additions and 1,361 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
Trunk Recorder ChangeLog
========================

### Version 3.1.0
* Updated to the latest version of OP25.
* Updated P25 Recorder, P25 Trunking and SmartNet Trunking to use the double decimation technique from OP25. It should handle SDRs with a high sample rate better now.
* Updated to the latest version of the websocketpp library.

### Version 3.0.1
* Updated to the latest version of OP25. Supposed performance improvements.

Expand Down
17 changes: 12 additions & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@
cmake_minimum_required(VERSION 2.6)
project(Trunk-Recorder CXX C)



add_definitions(-DWEBSOCKET_STATUS=true)
set(WEBSOCKET_STATUS true)

#select the release build type by default to get optimization flags
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release")
Expand Down Expand Up @@ -97,10 +102,6 @@ endif()
########################################################################
# Find build dependencies
########################################################################
#find_package(LibOsmoSDR)
#find_package(LibRTLSDR)
#find_package(LibMiriSDR)
#find_package(LibbladeRF)
find_package(GnuradioUHD)
find_package(GrOsmoSDR)
find_package(LibHackRF)
Expand Down Expand Up @@ -140,6 +141,7 @@ set(Boost_ADDITIONAL_VERSIONS
"1.55.0" "1.55" "1.56.0" "1.56" "1.57.0" "1.57" "1.58.0" "1.58" "1.59.0" "1.59"
"1.60.0" "1.60" "1.61.0" "1.61" "1.62.0" "1.62" "1.63.0" "1.63" "1.64.0" "1.64"
"1.65.0" "1.65" "1.66.0" "1.66" "1.67.0" "1.67" "1.68.0" "1.68" "1.69.0" "1.69"
"1.70.0" "1.70" "1.71.0" "1.71" "1.72.0" "1.72" "1.73.0" "1.73" "1.74.0" "1.74"
)

find_package(Boost COMPONENTS ${BOOST_REQUIRED_COMPONENTS})
Expand Down Expand Up @@ -206,7 +208,6 @@ list(APPEND trunk_recorder_sources
trunk-recorder/source.cc
trunk-recorder/uploaders/uploader.cc
trunk-recorder/uploaders/call_uploader.cc
trunk-recorder/uploaders/stat_socket.cc
trunk-recorder/call_conventional.cc
trunk-recorder/call.cc
trunk-recorder/systems/smartnet_trunking.cc
Expand All @@ -229,6 +230,12 @@ list(APPEND trunk_recorder_sources
lib/lfsr/lfsr.cxx
)

if(WEBSOCKET_STATUS)
list(APPEND trunk_recorder_sources
trunk-recorder/uploaders/stat_socket.cc
)
endif()

set_source_files_properties(lib/lfsr/lfsr.cxx COMPILE_FLAGS "-w")

target_compile_options(
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
Trunk Recorder - v3.0.1
Trunk Recorder - v3.1.0
=======================

## Sponsors
**Do you find Trunk Recorder and OpenMHz useful? Become a [Sponsor](https://github.com/sponsors/robotastic) to help support continued development and operation.**
*Sponsors will be listed here*
Thank you: Vabrio, Blantonl, Olesza and others!

## Overview
Need help? Got something working? Share it!
Expand Down Expand Up @@ -127,9 +127,9 @@ Here are the different arguments:
- **callTimeout** - a Call will stop recording and save if it has not received anything on the control channel, after this many seconds. The default is 3.
- **logFile** - save the console output to a file. The options are *true* or *false*, without quotes. The default is *false*.
- **frequencyFormat** - the display format for frequencies to display in the console and log file. The options are *exp*, *mhz* & *hz*. The default is *exp*.
- **statusServer** - The URL for a WebSocket connect. Trunk Recorder will send JSON formatted update message to this address. HTTPS is currently not supported, but will be in the future. OpenMHz does not support this currently. [JSON format of messages](STATUS-JSON.md)
- **controlWarnRate** - Log the control channel decode rate when it falls bellow this threshold. The default is *10*. The value of *-1* will always log the decode rate.
- **statusAsString** - Show status as strings instead of numeric values The options are *true* or *false*, without quotes. The default is *false*.
- **statusAsString** - Show status as strings instead of numeric values The options are *true* or *false*, without quotes. The default is *true*.
- **statusServer** - The URL for a WebSocket connect. Trunk Recorder will send JSON formatted update message to this address. HTTPS is currently not supported, but will be in the future. OpenMHz does not support this currently. [JSON format of messages](STATUS-JSON.md)

**talkgroupsFile**

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ namespace gr {
*/
static sptr make(float samples_per_symbol, float gain_mu, float gain_omega, float alpha, float beta, float max_freq, float min_freq);
virtual void set_omega(float omega) {}
virtual float get_freq_error(void) {}
virtual float get_freq_error(void) { return 0;}
virtual void reset() {}
virtual void update_omega (float samples_per_symbol) {}
virtual void update_fmax (float max_freq) {}
Expand Down
170 changes: 170 additions & 0 deletions lib/op25_repeater/lib/BER.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
/*
* (C) 2019, Graham J Norbury
* gnorbury@bondcar.com
*
* Stand-alone utility to calculate bit error ratio of a binary dibit capture file
* compared to an APCO P25 pattern file
*
*/

#include <stdio.h>
#include <stdint.h>
#include <fstream>
#include <vector>

#include "frame_sync_magics.h"

typedef std::vector<uint8_t> byte_vector;

static const int FRAME_SIZE = 1728;
static const int SYNC_SIZE = 48;
static const unsigned int SYNC_THRESHOLD = 4;

bool test_sync(uint64_t cw, int &errs) {
int popcnt = 0;
popcnt = __builtin_popcountll(cw ^ P25_FRAME_SYNC_MAGIC);
if (popcnt <= SYNC_THRESHOLD) {
errs = popcnt;
return true;
}

return false;
}

int main (int argc, char* argv[]) {
char dibit;
uint64_t cw = 0;
int s_errs = 0;
byte_vector pattern;
byte_vector rx_syms;

if (argc != 3) {
fprintf(stderr, "Usage: BER <pattern> <filename>\n");
return 1;
}

// read in pattern file
pattern.clear();
std::fstream p_file(argv[1], std::ios::in | std::ios::binary);
if ( (p_file.rdstate() & std::ifstream::failbit ) != 0 ) {
printf("Error opening pattern file: %s\n", argv[1]);
return 1;
}
while (!p_file.eof()) {
p_file.read((&dibit), 1);
pattern.push_back((dibit >> 1) & 0x1);
pattern.push_back(dibit & 0x1);
}

// read in received symbols file
rx_syms.clear();
std::fstream r_file(argv[2], std::ios::in | std::ios::binary);
if ( (r_file.rdstate() & std::ifstream::failbit ) != 0 ) {
printf("Error opening symbol file: %s\n", argv[2]);
return 1;
}
while (!r_file.eof()) {
r_file.read((&dibit), 1);
rx_syms.push_back((dibit >> 1) & 0x1);
rx_syms.push_back(dibit & 0x1);
}

// find starting sync in pattern file
size_t p_pos = 0;
size_t p_start = 0;
int cw_bits = 0;
while (p_pos < pattern.size()) {
cw_bits++;
cw = ((cw << 1) + pattern[p_pos]) & 0xffffffffffff;
if ((cw_bits >= SYNC_SIZE) && test_sync(cw, s_errs)) {
p_start = p_pos - SYNC_SIZE + 1;
printf("Pattern sync at %lu, errs %d\n", p_start, s_errs);
break;
}
p_pos++;
}
if (p_pos >= pattern.size()) {
printf("Error: no sync found in pattern file\n");
return 1;
}

// pattern ichunk must be an even multiple of frame size
size_t p_len = pattern.size() - p_start;
if (p_len % FRAME_SIZE)
p_len -= (p_len % FRAME_SIZE);
printf("Pattern length: %lu bits\n", p_len);
printf("Symbols file: %lu bits\n", rx_syms.size());

size_t r_pos = 0;
size_t r_start = 0;
size_t r_len = rx_syms.size();
bool calculating = true;

// stats
size_t total_bit_errs = 0;
size_t total_bit_count = 0;
double total_ber = 0;
size_t max_bit_errs = 0;
size_t max_bit_count = 0;
double max_ber = 0;

// run through received symbols chunk by chunk
do {
size_t chunk_bit_errs = 0;
size_t chunk_bit_count = 0;
double chunk_ber = 0;

// find next sync in symbols file
cw = 0;
cw_bits = 0;
while (r_pos < r_len) {
cw_bits++;
cw = ((cw << 1) + rx_syms[r_pos]) & 0xffffffffffff;
if ((cw_bits >= SYNC_SIZE) && test_sync(cw, s_errs)) {
r_start = r_pos - SYNC_SIZE + 1;
break;
}
r_pos++;
}
if ((r_pos >= r_len) || (p_len > (r_len - r_start))) {
calculating = false;
break;
}

r_pos = r_start;
p_pos = p_start;
while(p_pos < p_len) {
if (rx_syms[r_pos] ^ pattern[p_pos])
chunk_bit_errs++;
r_pos++;
p_pos++;
chunk_bit_count++;
}
chunk_ber = 100 * (double)chunk_bit_errs / (double)chunk_bit_count;
printf("Pattern match (%lu) bit errs=%lu, BER=%lf%%\n", r_start, chunk_bit_errs, chunk_ber);
// Check for excessive BER and attempt to resync
// usually this means pattern and capture file got out of step with each other
if (chunk_ber > 5) {
printf("High BER >5.0 detected. Discarding current frame and attempting resync.\n");
r_pos = r_start + 2;
continue;
}

// Update totals
total_bit_count += chunk_bit_count;
total_bit_errs += chunk_bit_errs;
if (chunk_ber > max_ber) {
max_bit_errs = chunk_bit_errs;
max_bit_count = chunk_bit_count;
max_ber = chunk_ber;
}

} while (calculating);

total_ber = 100 * (double)total_bit_errs / (double)total_bit_count;
printf("Max bit errs=%lu, Max BER=%lf%%\n", max_bit_errs, max_ber);
printf("Total bit errs=%lu, Total BER=%lf%%\n", total_bit_errs, total_ber);

return 0;
}

6 changes: 4 additions & 2 deletions lib/op25_repeater/lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ list(APPEND op25_repeater_sources
vocoder_impl.cc
gardner_costas_cc_impl.cc
p25_frame_assembler_impl.cc
fsk4_slicer_fb_impl.cc
fsk4_demod_ff_impl.cc)
fsk4_demod_ff_impl.cc
fsk4_slicer_fb_impl.cc )

list(APPEND op25_repeater_sources
bch.cc
Expand All @@ -57,9 +57,11 @@ list(APPEND op25_repeater_sources
hamming.cc
golay2087.cc
bptc19696.cc
trellis.cc
dmr_cai.cc
dmr_slot.cc
op25_audio.cc
op25_timer
CCITTChecksumReverse.cpp
)

Expand Down
65 changes: 65 additions & 0 deletions lib/op25_repeater/lib/ber1011.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* (C) 2019, Graham J Norbury
* gnorbury@bondcar.com
*
* Stand-alone utility to calculate bit error rate of a binary dibit capture file
* containing APCO 1011Hz test tone sequence.
*
*/

#include <stdio.h>
#include <stdint.h>
#include <fstream>

#include "frame_sync_magics.h"

static const int SYNC_SIZE = 48; // 48 bits
static const unsigned int SYNC_THRESHOLD = 4; // 4 bit errors in sync allowed

bool test_sync(uint64_t cw, int &sync, int &errs)
{
int popcnt = 0;
popcnt = __builtin_popcountll(cw ^ P25_FRAME_SYNC_MAGIC);
if (popcnt <= SYNC_THRESHOLD)
{
errs = popcnt;
return true;
}

return false;
}

int main (int argc, char* argv[])
{
uint64_t cw = 0;
int sync = 0;
int s_errs = 0;

if (argc < 2)
{
fprintf(stderr, "Usage: ber1011 <filename>\n");
return 1;
}

char dibit;
size_t fpos = 0;
std::fstream file(argv[1], std::ios::in | std::ios::binary);
while (!file.eof())
{
file.read((&dibit), 1);
fpos++;

cw = ((cw << 1) + ((dibit >>1) & 0x1)) & 0xffffffffffff;
if (test_sync(cw, sync, s_errs))
printf("Matched sync with %d errs at %lu bit 1\n", s_errs, fpos);

cw = ((cw << 1) + (dibit & 0x1)) & 0xffffffffffff;
if (test_sync(cw, sync, s_errs))
printf("Matched sync with %d errs at %lu bit 0\n", s_errs, fpos);

}

return 0;

}

Loading

0 comments on commit 5305e8f

Please sign in to comment.