diff --git a/CMakeLists.txt b/CMakeLists.txt index 7319927..37a7b52 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt index a419e7c..ea00798 100644 --- a/apps/CMakeLists.txt +++ b/apps/CMakeLists.txt @@ -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) diff --git a/apps/m17-demod.cpp b/apps/m17-demod.cpp index b26fad8..0dd7649 100644 --- a/apps/m17-demod.cpp +++ b/apps/m17-demod.cpp @@ -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; diff --git a/include/m17cxx/ClockRecovery.h b/include/m17cxx/ClockRecovery.h index 611d2b4..37529e6 100644 --- a/include/m17cxx/ClockRecovery.h +++ b/include/m17cxx/ClockRecovery.h @@ -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; diff --git a/include/m17cxx/Convolution.h b/include/m17cxx/Convolution.h index 4f28b18..122effa 100644 --- a/include/m17cxx/Convolution.h +++ b/include/m17cxx/Convolution.h @@ -2,6 +2,7 @@ #pragma once +#include #include #include @@ -10,7 +11,7 @@ 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 diff --git a/include/m17cxx/Golay24.h b/include/m17cxx/Golay24.h index 58c2f0f..20ee171 100644 --- a/include/m17cxx/Golay24.h +++ b/include/m17cxx/Golay24.h @@ -4,6 +4,7 @@ #pragma once #include +#include #include #include #include @@ -85,11 +86,13 @@ constexpr array sort(array 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. @@ -110,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) @@ -212,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; diff --git a/include/m17cxx/M17Demodulator.h b/include/m17cxx/M17Demodulator.h index 3a21f11..4510651 100644 --- a/include/m17cxx/M17Demodulator.h +++ b/include/m17cxx/M17Demodulator.h @@ -556,7 +556,7 @@ void M17Demodulator::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); diff --git a/include/m17cxx/M17Framer.h b/include/m17cxx/M17Framer.h index c87fa04..c80365e 100644 --- a/include/m17cxx/M17Framer.h +++ b/include/m17cxx/M17Framer.h @@ -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; diff --git a/include/m17cxx/M17Synchronizer.h b/include/m17cxx/M17Synchronizer.h index 1861ed3..422fd3a 100644 --- a/include/m17cxx/M17Synchronizer.h +++ b/include/m17cxx/M17Synchronizer.h @@ -2,6 +2,7 @@ #pragma once +#include #include namespace mobilinkd @@ -24,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; } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c402b40..12a375d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -5,7 +5,13 @@ target_include_directories(m17cxx INTERFACE $ ) -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" diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index d188b05..a2dc698 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,5 +1,4 @@ include(GoogleTest) -pkg_check_modules(CODEC2 REQUIRED codec2) include_directories ( ${TEST_SOURCE_DIR} @@ -7,65 +6,65 @@ include_directories ( ) add_executable (ConvolutionTest ConvolutionTest.cpp) -target_link_libraries(ConvolutionTest m17cxx gtest pthread) +target_link_libraries(ConvolutionTest m17cxx GTest::GTest) gtest_add_tests(ConvolutionTest "" AUTO) add_executable (M17FramerTest M17FramerTest.cpp) -target_link_libraries(M17FramerTest m17cxx gtest pthread) +target_link_libraries(M17FramerTest m17cxx GTest::Gtest) gtest_add_tests(M17FramerTest "" AUTO) add_executable (TrellisTest TrellisTest.cpp) -target_link_libraries(TrellisTest m17cxx gtest pthread) +target_link_libraries(TrellisTest m17cxx GTest::Gtest) gtest_add_tests(TrellisTest "" AUTO) add_executable (ViterbiTest ViterbiTest.cpp) -target_link_libraries(ViterbiTest m17cxx gtest pthread) +target_link_libraries(ViterbiTest m17cxx GTest::Gtest) gtest_add_tests(ViterbiTest "" AUTO) add_executable (Golay24Test Golay24Test.cpp) -target_link_libraries(Golay24Test m17cxx gtest pthread) +target_link_libraries(Golay24Test m17cxx GTest::Gtest) gtest_add_tests(Golay24Test "" AUTO) add_executable (CRC16Test CRC16Test.cpp) -target_link_libraries(CRC16Test m17cxx gtest pthread) +target_link_libraries(CRC16Test m17cxx GTest::Gtest) gtest_add_tests(CRC16Test "" AUTO) add_executable (M17RandomizerTest M17RandomizerTest.cpp) -target_link_libraries(M17RandomizerTest m17cxx gtest pthread) +target_link_libraries(M17RandomizerTest m17cxx GTest::Gtest) gtest_add_tests(M17RandomizerTest "" AUTO) add_executable (PolynomialInterleaverTest PolynomialInterleaverTest.cpp) -target_link_libraries(PolynomialInterleaverTest m17cxx gtest pthread) +target_link_libraries(PolynomialInterleaverTest m17cxx GTest::Gtest) 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 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) gtest_add_tests(UtilTest "" AUTO) add_executable (LinkSetupFrameTest LinkSetupFrameTest.cpp) -target_link_libraries(LinkSetupFrameTest m17cxx gtest pthread) +target_link_libraries(LinkSetupFrameTest m17cxx GTest::Gtest) gtest_add_tests(LinkSetupFrameTest "" AUTO) add_executable (SlidingDFTTest SlidingDFTTest.cpp) -target_link_libraries(SlidingDFTTest m17cxx gtest pthread) +target_link_libraries(SlidingDFTTest m17cxx GTest::Gtest) gtest_add_tests(SlidingDFTTest "" AUTO) add_executable (DataCarrierDetectTest DataCarrierDetectTest.cpp) -target_link_libraries(DataCarrierDetectTest m17cxx gtest pthread) +target_link_libraries(DataCarrierDetectTest m17cxx GTest::Gtest) gtest_add_tests(DataCarrierDetectTest "" AUTO) add_executable (ClockRecoveryTest ClockRecoveryTest.cpp) -target_link_libraries(ClockRecoveryTest m17cxx gtest pthread) +target_link_libraries(ClockRecoveryTest m17cxx GTest::Gtest) gtest_add_tests(ClockRecoveryTest "" AUTO) add_executable (FreqDevEstimatorTest FreqDevEstimatorTest.cpp) -target_link_libraries(FreqDevEstimatorTest m17cxx gtest pthread) +target_link_libraries(FreqDevEstimatorTest m17cxx GTest::Gtest) gtest_add_tests(FreqDevEstimatorTest "" AUTO) add_executable (CorrelatorTest CorrelatorTest.cpp) -target_link_libraries(CorrelatorTest m17cxx gtest pthread) +target_link_libraries(CorrelatorTest m17cxx GTest::Gtest) gtest_add_tests(CorrelatorTest "" AUTO) diff --git a/tests/UtilTest.cpp b/tests/UtilTest.cpp index 4adebe2..cfddcdf 100644 --- a/tests/UtilTest.cpp +++ b/tests/UtilTest.cpp @@ -2,6 +2,7 @@ #include +#include #include 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;