Merge pull request #18 from robojay/master

Modifications for conda-forge and local conda (Windows) building
master
Mobilinkd LLC 2022-03-27 19:27:56 -05:00 zatwierdzone przez GitHub
commit 7e30f0601a
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
14 zmienionych plików z 107 dodań i 56 usunięć

Wyświetl plik

@ -5,7 +5,7 @@ project(m17cxx
DESCRIPTION "M17 Digital Voice modulation and demodulation"
LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD 20)
# Require out-of-source builds
file(TO_CMAKE_PATH "${PROJECT_BINARY_DIR}/CMakeLists.txt" LOC_PATH)
@ -24,10 +24,9 @@ message(STATUS "# Checking dependencies")
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
include(FindPkgConfig)
include(GNUInstallDirs)
pkg_check_modules(CODEC2 REQUIRED codec2)
find_package(codec2 REQUIRED)
set(Boost_USE_STATIC_LIBS FALSE)
find_package(Boost COMPONENTS program_options REQUIRED)

Wyświetl plik

@ -31,6 +31,20 @@ It also requires a modern C++17 compiler (GCC 8 minimum).
make test
sudo make install
## Build Steps for local building under Anaconda for Windows
### Prequisites
- Microsoft Visual Studio 2019
- Miniconda (or Anaconda) x64 for Windows
### From a clean Conda environment
conda config --add channels conda-forge
conda create -n M17 vs2019_win-64 cmake ninja pkg-config boost-cpp gtest gmock gtest libcodec2
conda activate M17
### And then from the top level of the m17-cxx-demod repo, execute win_build.bat
## Running
This program was designed to be used with RTL-SDR, specifically rtl-fm.

Wyświetl plik

@ -1,7 +1,7 @@
add_executable(m17-demod m17-demod.cpp)
target_link_libraries(m17-demod PRIVATE m17cxx ${CODEC2_LIBRARIES} ${Boost_LIBRARIES})
target_link_libraries(m17-demod PRIVATE m17cxx codec2 Boost::program_options)
add_executable(m17-mod m17-mod.cpp)
target_link_libraries(m17-mod PRIVATE m17cxx ${CODEC2_LIBRARIES} ${Boost_LIBRARIES} Threads::Threads)
target_link_libraries(m17-mod PRIVATE m17cxx codec2 Boost::program_options Threads::Threads)
install(TARGETS m17-demod m17-mod RUNTIME DESTINATION bin)

Wyświetl plik

@ -190,15 +190,15 @@ bool demodulate_audio(mobilinkd::M17FrameDecoder::audio_buffer_t const& audio, i
if (noise_blanker && viterbi_cost > 80)
{
buf.fill(0);
std::cout.write((const char*)buf.begin(), 320);
std::cout.write((const char*)buf.begin(), 320);
std::cout.write((const char*)buf.data(), 320);
std::cout.write((const char*)buf.data(), 320);
}
else
{
codec2_decode(codec2, buf.begin(), audio.begin() + 2);
std::cout.write((const char*)buf.begin(), 320);
codec2_decode(codec2, buf.begin(), audio.begin() + 10);
std::cout.write((const char*)buf.begin(), 320);
codec2_decode(codec2, buf.data(), audio.data() + 2);
std::cout.write((const char*)buf.data(), 320);
codec2_decode(codec2, buf.data(), audio.data() + 10);
std::cout.write((const char*)buf.data(), 320);
}
return result;

Wyświetl plik

@ -104,11 +104,11 @@ class ClockRecovery
int8_t offset = sample_index_ - prev_sample_index_;
// When in spec, the clock should drift by less than 1 sample per frame.
if (__builtin_expect(offset >= MAX_OFFSET, 0))
if (offset >= MAX_OFFSET) [[unlikely]]
{
offset -= SAMPLES_PER_SYMBOL;
}
else if (__builtin_expect(offset <= -MAX_OFFSET, 0))
else if (offset <= -MAX_OFFSET) [[unlikely]]
{
offset += SAMPLES_PER_SYMBOL;
}
@ -120,7 +120,7 @@ class ClockRecovery
{
// update_sample_index_() must be called first.
if (__builtin_expect((frame_count_ == 0), 0))
if (frame_count_ == 0) [[unlikely]]
{
prev_sample_index_ = sample_index_;
offset_ = 0.0;

Wyświetl plik

@ -2,20 +2,16 @@
#pragma once
#include <bit>
#include <cstdint>
#include <cstddef>
#ifdef _MSC_VER
# include <intrin.h>
# define __builtin_popcount __popcnt
#endif
namespace mobilinkd
{
inline constexpr uint32_t convolve_bit(uint32_t poly, uint32_t memory)
{
return __builtin_popcount(poly & memory) & 1;
return std::popcount(poly & memory) & 1;
}
template <size_t K, size_t k = 1>

Wyświetl plik

@ -4,15 +4,11 @@
#pragma once
#include <array>
#include <bit>
#include <cstdint>
#include <algorithm>
#include <utility>
#ifdef _MSC_VER
# include <intrin.h>
# define __builtin_popcount __popcnt
#endif
namespace mobilinkd {
// Parts are adapted from:
@ -90,11 +86,13 @@ constexpr array<T, N> sort(array<T, N> array)
// static constexpr uint16_t POLY = 0xAE3;
constexpr uint16_t POLY = 0xC75;
struct __attribute__((packed)) SyndromeMapEntry
#pragma pack(push, 1)
struct SyndromeMapEntry
{
uint32_t a{0};
uint16_t b{0};
};
#pragma pack(pop)
/**
* Calculate the syndrome of a [23,12] Golay codeword.
@ -115,7 +113,7 @@ constexpr uint32_t syndrome(uint32_t codeword)
constexpr bool parity(uint32_t codeword)
{
return __builtin_popcount(codeword) & 1;
return std::popcount(codeword) & 1;
}
constexpr SyndromeMapEntry makeSyndromeMapEntry(uint64_t val)
@ -217,7 +215,7 @@ bool decode(uint32_t input, uint32_t& output)
// Apply the correction to the input.
output = input ^ correction;
// Only test parity for 3-bit errors.
return __builtin_popcount(syndrm) < 3 || !parity(output);
return std::popcount(syndrm) < 3 || !parity(output);
}
return false;

Wyświetl plik

@ -556,7 +556,7 @@ void M17Demodulator<FloatType>::operator()(const FloatType input)
// We need to pump a few ms of data through on startup to initialize
// the demodulator.
if (__builtin_expect((initializing), 0))
if (initializing) [[unlikely]]
{
--initializing;
initialize(input);

Wyświetl plik

@ -32,7 +32,7 @@ struct M17Framer
if (index_ == N)
{
index_ = 0;
*result = buffer_.begin();
*result = buffer_.data();
return N;
}
return 0;
@ -46,7 +46,7 @@ struct M17Framer
if (index_ == N)
{
index_ = 0;
*result = buffer_.begin();
*result = buffer_.data();
return N;
}
return 0;

Wyświetl plik

@ -2,13 +2,9 @@
#pragma once
#include <bit>
#include <cstdint>
#ifdef _MSC_VER
# include <intrin.h>
# define __builtin_popcount __popcnt
#endif
namespace mobilinkd
{
@ -29,7 +25,7 @@ struct M17Synchronizer
buffer_ = ((buffer_ << 2) | bits) & 0xFFFF;
auto tmp = buffer_ ^ expected_;
return __builtin_popcount(tmp) <= allowable_errors_;
return std::popcount(tmp) <= allowable_errors_;
}
void reset() { buffer_ = 0; }

Wyświetl plik

@ -5,7 +5,13 @@ target_include_directories(m17cxx INTERFACE
$<INSTALL_INTERFACE:include>
)
target_compile_features(m17cxx INTERFACE cxx_std_17)
target_compile_features(m17cxx INTERFACE cxx_std_20)
if(MSVC)
# specify standards-conformance mode
target_compile_options(m17cxx INTERFACE /permissive-)
target_compile_definitions(m17cxx INTERFACE _USE_MATH_DEFINES)
endif()
source_group(
TREE "${PROJECT_SOURCE_DIR}/include"

Wyświetl plik

@ -1,71 +1,76 @@
include(GoogleTest)
pkg_check_modules(CODEC2 REQUIRED codec2)
include_directories (
${TEST_SOURCE_DIR}
..
)
if(WIN32)
set(PTHREAD "")
else()
set(PTHREAD "pthread")
endif(WIN32)
add_executable (ConvolutionTest ConvolutionTest.cpp)
target_link_libraries(ConvolutionTest m17cxx gtest pthread)
target_link_libraries(ConvolutionTest m17cxx GTest::GTest ${PTHREAD})
gtest_add_tests(ConvolutionTest "" AUTO)
add_executable (M17FramerTest M17FramerTest.cpp)
target_link_libraries(M17FramerTest m17cxx gtest pthread)
target_link_libraries(M17FramerTest m17cxx GTest::GTest ${PTHREAD})
gtest_add_tests(M17FramerTest "" AUTO)
add_executable (TrellisTest TrellisTest.cpp)
target_link_libraries(TrellisTest m17cxx gtest pthread)
target_link_libraries(TrellisTest m17cxx GTest::GTest ${PTHREAD})
gtest_add_tests(TrellisTest "" AUTO)
add_executable (ViterbiTest ViterbiTest.cpp)
target_link_libraries(ViterbiTest m17cxx gtest pthread)
target_link_libraries(ViterbiTest m17cxx GTest::GTest ${PTHREAD})
gtest_add_tests(ViterbiTest "" AUTO)
add_executable (Golay24Test Golay24Test.cpp)
target_link_libraries(Golay24Test m17cxx gtest pthread)
target_link_libraries(Golay24Test m17cxx GTest::GTest ${PTHREAD})
gtest_add_tests(Golay24Test "" AUTO)
add_executable (CRC16Test CRC16Test.cpp)
target_link_libraries(CRC16Test m17cxx gtest pthread)
target_link_libraries(CRC16Test m17cxx GTest::GTest ${PTHREAD})
gtest_add_tests(CRC16Test "" AUTO)
add_executable (M17RandomizerTest M17RandomizerTest.cpp)
target_link_libraries(M17RandomizerTest m17cxx gtest pthread)
target_link_libraries(M17RandomizerTest m17cxx GTest::GTest ${PTHREAD})
gtest_add_tests(M17RandomizerTest "" AUTO)
add_executable (PolynomialInterleaverTest PolynomialInterleaverTest.cpp)
target_link_libraries(PolynomialInterleaverTest m17cxx gtest pthread)
target_link_libraries(PolynomialInterleaverTest m17cxx GTest::GTest ${PTHREAD})
gtest_add_tests(PolynomialInterleaverTest "" AUTO)
add_executable (M17ModulatorTest M17ModulatorTest.cpp)
target_link_libraries(M17ModulatorTest m17cxx gtest pthread codec2)
target_link_libraries(M17ModulatorTest m17cxx GTest::GTest ${PTHREAD} codec2)
gtest_add_tests(M17ModulatorTest "" AUTO)
add_executable (UtilTest UtilTest.cpp)
target_link_libraries(UtilTest m17cxx gtest pthread)
target_link_libraries(UtilTest m17cxx GTest::GTest ${PTHREAD})
gtest_add_tests(UtilTest "" AUTO)
add_executable (LinkSetupFrameTest LinkSetupFrameTest.cpp)
target_link_libraries(LinkSetupFrameTest m17cxx gtest pthread)
target_link_libraries(LinkSetupFrameTest m17cxx GTest::GTest ${PTHREAD})
gtest_add_tests(LinkSetupFrameTest "" AUTO)
add_executable (SlidingDFTTest SlidingDFTTest.cpp)
target_link_libraries(SlidingDFTTest m17cxx gtest pthread)
target_link_libraries(SlidingDFTTest m17cxx GTest::GTest ${PTHREAD})
gtest_add_tests(SlidingDFTTest "" AUTO)
add_executable (DataCarrierDetectTest DataCarrierDetectTest.cpp)
target_link_libraries(DataCarrierDetectTest m17cxx gtest pthread)
target_link_libraries(DataCarrierDetectTest m17cxx GTest::GTest ${PTHREAD})
gtest_add_tests(DataCarrierDetectTest "" AUTO)
add_executable (ClockRecoveryTest ClockRecoveryTest.cpp)
target_link_libraries(ClockRecoveryTest m17cxx gtest pthread)
target_link_libraries(ClockRecoveryTest m17cxx GTest::GTest ${PTHREAD})
gtest_add_tests(ClockRecoveryTest "" AUTO)
add_executable (FreqDevEstimatorTest FreqDevEstimatorTest.cpp)
target_link_libraries(FreqDevEstimatorTest m17cxx gtest pthread)
target_link_libraries(FreqDevEstimatorTest m17cxx GTest::GTest ${PTHREAD})
gtest_add_tests(FreqDevEstimatorTest "" AUTO)
add_executable (CorrelatorTest CorrelatorTest.cpp)
target_link_libraries(CorrelatorTest m17cxx gtest pthread)
target_link_libraries(CorrelatorTest m17cxx GTest::GTest ${PTHREAD})
gtest_add_tests(CorrelatorTest "" AUTO)

Wyświetl plik

@ -2,6 +2,7 @@
#include <gtest/gtest.h>
#include <bit>
#include <cstdint>
int main(int argc, char **argv) {
@ -210,7 +211,7 @@ TEST_F(UtilTest, PRBS9)
uint16_t lfsr = 0x100;
for (size_t i = 0; i != 511; ++i) {
lfsr = ((__builtin_popcount(lfsr & 0x11) & 1) << 8) | (lfsr >> 1);
lfsr = ((std::popcount(lfsr & 0x11u) & 1) << 8) | (lfsr >> 1);
bool p = (lfsr & 0x100) == 0x100;
bool n = prbs.generate();
EXPECT_EQ(p,n) << "i = " << i;

36
win_build.bat 100644
Wyświetl plik

@ -0,0 +1,36 @@
::
:: win_build.bat
::
:: Batch file to locally build under Windows using Conda
::
:: See README.md for details
::
setlocal EnableDelayedExpansion
@echo on
:: Set number of CPUs to use for build
set CPU_COUNT=3
:: Make a build folder and change to it
mkdir build
cd build
:: configure
cmake -G "Ninja" ^
-DCMAKE_BUILD_TYPE:STRING=Release ^
-DCMAKE_INSTALL_PREFIX:PATH="%LIBRARY_PREFIX%" ^
-DCMAKE_PREFIX_PATH:PATH="%LIBRARY_PREFIX%" ^
..
if errorlevel 1 exit /B 1
:: build
cmake --build . --config Release -- -j%CPU_COUNT%
if errorlevel 1 exit /B 1
:: install
cmake --build . --config Release --target install
if errorlevel 1 exit /B 1
:: test
ctest --build-config Release --output-on-failure --timeout 120 -j%CPU_COUNT%
if errorlevel 1 exit /B 1