diff --git a/CMakeLists.txt b/CMakeLists.txt index 711b9930d..bef3f85f9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,6 +48,7 @@ find_package(PkgConfig) find_package(Boost) find_package(FFTW3F) +find_package(LibDSDcc) find_package(LibMbe) IF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|AMD64|x86") @@ -373,10 +374,6 @@ qt5_use_modules(sdrangel Widgets Multimedia) add_subdirectory(plugins) -if(LIBMBE_FOUND) - add_subdirectory(dsdplus) -endif(LIBMBE_FOUND) - if(LIBUSB_FOUND AND UNIX) add_subdirectory(fcdhid) add_subdirectory(fcdlib) diff --git a/Readme.md b/Readme.md index 39f80deac..d78e528f7 100644 --- a/Readme.md +++ b/Readme.md @@ -115,6 +115,23 @@ There is an automated skew rate compensation in place. During rate readjustemnt Note that this plugin does not require any of the hardware support libraries nor the libusb library. It is alwasys available in the list of devices as `SDRdaemon[0]` even if no physical device is connected. +

Channel plugins with special conditions

+ +

DSD (Digital Speech Decoder)

+ +This is the `demoddsd` plugin. At present it can be used to decode the following digital speech formats: + + - DMR/MOTOTRBO + - D-Star + +It is based on the [DSDcc](https://github.com/f4exb/dsdcc) C++ library which is a rewrite of the original [DSD](https://github.com/szechyjs/dsd) program. So you will need to have DSDcc installed in your system. Please follow instructions in [DSDcc readme](https://github.com/f4exb/dsdcc/blob/master/Readme.md) to build and install DSDcc. If you install it in a custom location say `/opt/install/dsdcc` you will need to add these defines to the cmake command: `-DLIBDSDCC_INCLUDE_DIR=/opt/install/dsdcc/include/dsdcc -DLIBDSDCC_LIBRARIES=/opt/install/dsdcc/lib/libdsdcc.so` + +Please note that it also needs [mbelib](https://github.com/szechyjs/mbelib) and that mbelib comes with some copyright issues (see next). If you have mbelib installed in a custom location, say `/opt/install/mbelib` you will need to add these defines to the cmake command: `-DLIBMBE_INCLUDE_DIR=/opt/install/mbelib/include -DLIBMBE_LIBRARY=/opt/install/mbelib/lib/libmbe.so` + +While DSDcc is intended to be patent-free, `mbelib` that it uses describes functions that may be covered by one or more U.S. patents owned by DVSI Inc. The source code itself should not be infringing as it merely describes possible methods of implementation. Compiling or using `mbelib` may infringe on patents rights in your jurisdiction and/or require licensing. It is unknown if DVSI will sell licenses for software that uses `mbelib`. + +If you are not comfortable with this just do not install DSDcc and/or mbelib and the plugin will not be compiled and added to SDRangel. For packaged distributions just remove `libdemoddsd.so` or `libdemoddsd.dll` from the installed package. +

Software build

Ubuntu

diff --git a/cmake/Modules/FindLibDSDcc.cmake b/cmake/Modules/FindLibDSDcc.cmake new file mode 100644 index 000000000..ec28e2b0f --- /dev/null +++ b/cmake/Modules/FindLibDSDcc.cmake @@ -0,0 +1,30 @@ +# Find libdsdcc + +if(NOT LIBDSDCC_FOUND) + + pkg_check_modules (LIBDSDCC_PKG libdsdcc) + find_path(LIBDSDCC_INCLUDE_DIR NAMES dsd_decoder.h + PATHS + ${LIBDSDCC_PKG_INCLUDE_DIRS} + /usr/include + /usr/local/include + ) + + find_library(LIBDSDCC_LIBRARIES NAMES dsdcc + PATHS + ${LIBDSDCC_PKG_LIBRARY_DIRS} + /usr/lib + /usr/local/lib + ) + + if(LIBDSDCC_INCLUDE_DIR AND LIBDSDCC_LIBRARIES) + set(LIBDSDCC_FOUND TRUE CACHE INTERNAL "libdsdcc found") + message(STATUS "Found libdsdcc: ${LIBDSDCC_INCLUDE_DIR}, ${LIBDSDCC_LIBRARIES}") + else(LIBDSDCC_INCLUDE_DIR AND LIBDSDCC_LIBRARIES) + set(LIBDSDCC_FOUND FALSE CACHE INTERNAL "libdsdcc found") + message(STATUS "libdsdcc not found.") + endif(LIBDSDCC_INCLUDE_DIR AND LIBDSDCC_LIBRARIES) + + mark_as_advanced(LIBDSDCC_INCLUDE_DIR LIBDSDCC_LIBRARIES) + +endif(NOT LIBDSDCC_FOUND) \ No newline at end of file diff --git a/cmake/Modules/FindLibMbe.cmake b/cmake/Modules/FindLibMbe.cmake index 9e5528ab5..9a2b93f1d 100644 --- a/cmake/Modules/FindLibMbe.cmake +++ b/cmake/Modules/FindLibMbe.cmake @@ -11,7 +11,7 @@ ENDIF (LIBMBE_INCLUDE_DIR AND LIBMBE_LIBRARY) IF (LIBMBE_FOUND) IF (NOT LibMbe_FIND_QUIETLY) - MESSAGE (STATUS "Found LibMbe: ${LIBMBE_LIBRARY}") + MESSAGE (STATUS "Found LibMbe: ${LIBMBE_INCLUDE_DIR}, ${LIBMBE_LIBRARY}") ENDIF (NOT LibMbe_FIND_QUIETLY) ELSE (LIBMBE_FOUND) IF (LibMbe_FIND_REQUIRED) diff --git a/dsdplus/CMakeLists.txt b/dsdplus/CMakeLists.txt deleted file mode 100644 index 19440589b..000000000 --- a/dsdplus/CMakeLists.txt +++ /dev/null @@ -1,39 +0,0 @@ -project(dsdplus) - -set(dsdplus_SOURCES - descramble.cpp - dmr_data.cpp - dmr_voice.cpp - dsd_decoder.cpp - dsd_filters.cpp - dsd_mbe.cpp - dsd_opts.cpp - dsd_state.cpp - dstar.cpp -) - -set(dsdplus_HEADERS - descramble.h - dmr_data.h - dmr_voice.h - dsd_decoder.h - dsd_filters.h - dsd_mbe.h - dsd_opts.h - dsd_state.h - dstar.h -) - -include_directories( - ${PROJECT_SOURCE_DIR} - ${CMAKE_CURRENT_BINARY_DIR} - ${LIBMBE_INCLUDE_DIR} -) - -add_library(dsdplus SHARED - ${dsdplus_SOURCES} -) - -target_link_libraries(dsdplus ${LIBMBE_LIBRARY}) - -install(TARGETS dsdplus DESTINATION lib) diff --git a/dsdplus/descramble.cpp b/dsdplus/descramble.cpp deleted file mode 100644 index a83f6c5b5..000000000 --- a/dsdplus/descramble.cpp +++ /dev/null @@ -1,350 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////////// -// Copyright (C) 2016 Edouard Griffiths, F4EXB. // -// // -// This program 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 as version 3 of the License, or // -// // -// This program 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 V3 for more details. // -// // -// You should have received a copy of the GNU General Public License // -// along with this program. If not, see . // -/////////////////////////////////////////////////////////////////////////////////// - -/* descramble.h */ - -// Functions for processing the radio-header: -// descramble -// deinterleave -// FECdecoder - -// (C) 2011 Jonathan Naylor G4KLX - -/* - * This program 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; version 2 of the License. - * - * This program 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. - */ - -// This code was originally written by JOnathan Naylor, G4KLX, as part -// of the "pcrepeatercontroller" project -// More info: -// http://groups.yahoo.com/group/pcrepeatercontroller - - - -// Changes: -// Convert C++ to C - -// Version 20111106: initial release - -// F4EXB: Convert back to C++ ! - -#include -#include "descramble.h" - -namespace DSDplus -{ - -const int Descramble::SCRAMBLER_TABLE_BITS[] = { - 0,0,0,0,1,1,1,0,1,1,1,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,0,0,0,0,1,0, - 0,0,1,0,0,1,1,0,0,0,1,0,1,1,1,0,1,0,1,1,0,1,1,0,0,0,0,0,1,1,0,0, - 1,1,0,1,0,1,0,0,1,1,1,0,0,1,1,1,1,0,1,1,0,1,0,0,0,0,1,0,1,0,1,0, - 1,1,1,1,1,0,1,0,0,1,0,1,0,0,0,1,1,0,1,1,1,0,0,0,1,1,1,1,1,1,1,0, - 0,0,0,1,1,1,0,1,1,1,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,0,0,0,0,1,0,0, - 0,1,0,0,1,1,0,0,0,1,0,1,1,1,0,1,0,1,1,0,1,1,0,0,0,0,0,1,1,0,0,1, - 1,0,1,0,1,0,0,1,1,1,0,0,1,1,1,1,0,1,1,0,1,0,0,0,0,1,0,1,0,1,0,1, - 1,1,1,1,0,1,0,0,1,0,1,0,0,0,1,1,0,1,1,1,0,0,0,1,1,1,1,1,1,1,0,0, - 0,0,1,1,1,0,1,1,1,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,0,0,0,0,1,0,0,0, - 1,0,0,1,1,0,0,0,1,0,1,1,1,0,1,0,1,1,0,1,1,0,0,0,0,0,1,1,0,0,1,1, - 0,1,0,1,0,0,1,1,1,0,0,1,1,1,1,0,1,1,0,1,0,0,0,0,1,0,1,0,1,0,1,1, - 1,1,1,0,1,0,0,1,0,1,0,0,0,1,1,0,1,1,1,0,0,0,1,1,1,1,1,1,1,0,0,0, - 0,1,1,1,0,1,1,1,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,0,0,0,0,1,0,0,0,1, - 0,0,1,1,0,0,0,1,0,1,1,1,0,1,0,1,1,0,1,1,0,0,0,0,0,1,1,0,0,1,1,0, - 1,0,1,0,0,1,1,1,0,0,1,1,1,1,0,1,1,0,1,0,0,0,0,1,0,1,0,1,0,1,1,1, - 1,1,0,1,0,0,1,0,1,0,0,0,1,1,0,1,1,1,0,0,0,1,1,1,1,1,1,1,0,0,0,0, - 1,1,1,0,1,1,1,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,0,0,0,0,1,0,0,0,1,0, - 0,1,1,0,0,0,1,0,1,1,1,0,1,0,1,1,0,1,1,0,0,0,0,0,1,1,0,0,1,1,0,1, - 0,1,0,0,1,1,1,0,0,1,1,1,1,0,1,1,0,1,0,0,0,0,1,0,1,0,1,0,1,1,1,1, - 1,0,1,0,0,1,0,1,0,0,0,1,1,0,1,1,1,0,0,0,1,1,1,1,1,1,1,0,0,0,0,1, - 1,1,0,1,1,1,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,0,0,0,0,1,0,0,0,1,0,0, - 1,1,0,0,0,1,0,1,1,1,0,1,0,1,1,0,1,1,0,0,0,0,0,1,1,0,0,1,1,0,1,0, - 1,0,0,1,1,1,0,0,1,1,1,1,0,1,1,0}; - -int Descramble::traceBack(int * out, int * m_pathMemory0, int * m_pathMemory1, - int * m_pathMemory2, int * m_pathMemory3) -{ - enum FEC_STATE - { - S0, S1, S2, S3 - } state; - int loop; - int length = 0; - - state = S0; - - for (loop = 329; loop >= 0; loop--, length++) - { - - switch (state) - { - case S0: // if state S0 - if (m_pathMemory0[loop]) - { - state = S2; // lower path - } - else - { - state = S0; // upper path - } - ; // end else - if - out[loop] = 0; - break; - - case S1: // if state S1 - if (m_pathMemory1[loop]) - { - state = S2; // lower path - } - else - { - state = S0; // upper path - } - ; // end else - if - out[loop] = 1; - break; - - case S2: // if state S2 - if (m_pathMemory2[loop]) - { - state = S3; // lower path - } - else - { - state = S1; // upper path - } - ; // end else - if - out[loop] = 0; - break; - - case S3: // if state S3 - if (m_pathMemory3[loop]) - { - state = S3; // lower path - } - else - { - state = S1; // upper path - } - ; // end else - if - out[loop] = 1; - break; - - }; // end switch - }; // end for - - return (length); -} // end function - -void Descramble::viterbiDecode(int n, int *data, int *m_pathMemory0, int *m_pathMemory1, - int *m_pathMemory2, int *m_pathMemory3, int *m_pathMetric) -{ - int tempMetric[4]; - int metric[8]; - int loop; - - int m1; - int m2; - - metric[0] = (data[1] ^ 0) + (data[0] ^ 0); - metric[1] = (data[1] ^ 1) + (data[0] ^ 1); - metric[2] = (data[1] ^ 1) + (data[0] ^ 0); - metric[3] = (data[1] ^ 0) + (data[0] ^ 1); - metric[4] = (data[1] ^ 1) + (data[0] ^ 1); - metric[5] = (data[1] ^ 0) + (data[0] ^ 0); - metric[6] = (data[1] ^ 0) + (data[0] ^ 1); - metric[7] = (data[1] ^ 1) + (data[0] ^ 0); - - // Pres. state = S0, Prev. state = S0 & S2 - m1 = metric[0] + m_pathMetric[0]; - m2 = metric[4] + m_pathMetric[2]; - if (m1 < m2) - { - m_pathMemory0[n] = 0; - tempMetric[0] = m1; - } - else - { - m_pathMemory0[n] = 1; - tempMetric[0] = m2; - }; // end else - if - - // Pres. state = S1, Prev. state = S0 & S2 - m1 = metric[1] + m_pathMetric[0]; - m2 = metric[5] + m_pathMetric[2]; - if (m1 < m2) - { - m_pathMemory1[n] = 0; - tempMetric[1] = m1; - } - else - { - m_pathMemory1[n] = 1; - tempMetric[1] = m2; - }; // end else - if - - // Pres. state = S2, Prev. state = S2 & S3 - m1 = metric[2] + m_pathMetric[1]; - m2 = metric[6] + m_pathMetric[3]; - if (m1 < m2) - { - m_pathMemory2[n] = 0; - tempMetric[2] = m1; - } - else - { - m_pathMemory2[n] = 1; - tempMetric[2] = m2; - } - - // Pres. state = S3, Prev. state = S1 & S3 - m1 = metric[3] + m_pathMetric[1]; - m2 = metric[7] + m_pathMetric[3]; - if (m1 < m2) - { - m_pathMemory3[n] = 0; - tempMetric[3] = m1; - } - else - { - m_pathMemory3[n] = 1; - tempMetric[3] = m2; - }; // end else - if - - for (loop = 0; loop < 4; loop++) - { - m_pathMetric[loop] = tempMetric[loop]; - }; // end for - -} // end function ViterbiDecode - -int Descramble::FECdecoder(int * in, int * out) -{ - int outLen; - - int m_pathMemory0[330]; - memset(m_pathMemory0, 0, 330 * sizeof(int)); - int m_pathMemory1[330]; - memset(m_pathMemory1, 0, 330 * sizeof(int)); - int m_pathMemory2[330]; - memset(m_pathMemory2, 0, 330 * sizeof(int)); - int m_pathMemory3[330]; - memset(m_pathMemory3, 0, 330 * sizeof(int)); - int m_pathMetric[4]; - - int loop, loop2; - - int n = 0; - - for (loop = 0; loop < 4; loop++) - { - m_pathMetric[loop] = 0; - }; // end for - - for (loop2 = 0; loop2 < 660; loop2 += 2, n++) - { - int data[2]; - - if (in[loop2]) - { - data[1] = 1; - } - else - { - data[1] = 0; - }; // end else - if - - if (in[loop2 + 1]) - { - data[0] = 1; - } - else - { - data[0] = 0; - }; // end else - if - - viterbiDecode(n, data, m_pathMemory0, m_pathMemory1, m_pathMemory2, - m_pathMemory3, m_pathMetric); - }; // end for - - outLen = traceBack(out, m_pathMemory0, m_pathMemory1, m_pathMemory2, - m_pathMemory3); - -// Swap endian-ness -// code removed (done converting bits into octets), done in main program - -//for (loop=0;loop<330;loop+=8) { -// int temp; -// temp=out[loop];out[loop]=out[loop+7];out[loop+7]=temp; -// temp=out[loop+1];out[loop+1]=out[loop+6];out[loop+6]=temp; -// temp=out[loop+2];out[loop+2]=out[loop+5];out[loop+5]=temp; -// temp=out[loop+3];out[loop+3]=out[loop+4];out[loop+4]=temp; -//} - - return (outLen); -} // end function FECdecoder - -void Descramble::deinterleave(int * in, int * out) -{ - - int k = 0; - int loop = 0; -// function starts here - -// init vars - k = 0; - - for (loop = 0; loop < 660; loop++) - { - out[k] = in[loop]; - - k += 24; - - if (k >= 672) - { - k -= 671; - } - else if (k >= 660) - { - k -= 647; - }; // end elsif - if - }; // end for -} // end function deinterleave - -void Descramble::scramble (int * in,int * out) -{ - int loop = 0; - int m_count = 0; - - for (loop = 0; loop < 660; loop++) - { - out[loop] = in[loop] ^ SCRAMBLER_TABLE_BITS[m_count++]; - - if (m_count >= SCRAMBLER_TABLE_BITS_LENGTH) - { - m_count = 0U; - }; // end if - }; // end for -} - -} // namespace DSDplus - - diff --git a/dsdplus/descramble.h b/dsdplus/descramble.h deleted file mode 100644 index e40d21619..000000000 --- a/dsdplus/descramble.h +++ /dev/null @@ -1,44 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////////// -// Copyright (C) 2016 Edouard Griffiths, F4EXB. // -// // -// This program 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 as version 3 of the License, or // -// // -// This program 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 V3 for more details. // -// // -// You should have received a copy of the GNU General Public License // -// along with this program. If not, see . // -/////////////////////////////////////////////////////////////////////////////////// - -#ifndef DSDPLUS_DESCRAMBLE_H_ -#define DSDPLUS_DESCRAMBLE_H_ - -namespace DSDplus -{ - -class Descramble -{ -public: -// Descramble(); -// ~Descramble(); - - static void scramble (int * in,int * out); - static void deinterleave (int * in, int * out); - static int FECdecoder (int * in, int * out); - -private: - static int traceBack (int * out, int * m_pathMemory0, int * m_pathMemory1, int * m_pathMemory2, int * m_pathMemory3); - static void viterbiDecode (int n, int *data, int *m_pathMemory0, int *m_pathMemory1, int *m_pathMemory2, int *m_pathMemory3, int *m_pathMetric); - - static const int SCRAMBLER_TABLE_BITS_LENGTH=720; - static const int SCRAMBLER_TABLE_BITS[]; -}; - - -} // namespace DSDplus - -#endif /* DSDPLUS_DESCRAMBLE_H_ */ diff --git a/dsdplus/dmr_data.cpp b/dsdplus/dmr_data.cpp deleted file mode 100644 index 8826715af..000000000 --- a/dsdplus/dmr_data.cpp +++ /dev/null @@ -1,231 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////////// -// Copyright (C) 2016 Edouard Griffiths, F4EXB. // -// // -// This program 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 as version 3 of the License, or // -// // -// This program 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 V3 for more details. // -// // -// You should have received a copy of the GNU General Public License // -// along with this program. If not, see . // -/////////////////////////////////////////////////////////////////////////////////// - -#include "dmr_data.h" -#include "dsd_decoder.h" - -namespace DSDplus -{ - -DSDDMRData::DSDDMRData(DSDDecoder *dsdDecoder) : - m_dsdDecoder(dsdDecoder) -{ -} - -DSDDMRData::~DSDDMRData() -{ -} - -void DSDDMRData::init() -{ - cc[4] = 0; - bursttype[4] = 0; - dibit_p = m_dsdDecoder->m_state.dibit_buf_p - 90; - - preProcess(); - - m_symbolIndex = 0; // reset -} - -void DSDDMRData::preProcess() -{ - int dibit; - - // CACH - for (int i = 0; i < 12; i++) - { - dibit = *dibit_p; - dibit_p++; - - if (m_dsdDecoder->m_opts.inverted_dmr == 1) - { - dibit = (dibit ^ 2); - } - - cachdata[i] = dibit; - - if (i == 2) - { - m_dsdDecoder->m_state.currentslot = (1 & (dibit >> 1)); // bit 1 - if (m_dsdDecoder->m_state.currentslot == 0) - { - m_dsdDecoder->m_state.slot0light[0] = '['; - m_dsdDecoder->m_state.slot0light[6] = ']'; - m_dsdDecoder->m_state.slot1light[0] = ' '; - m_dsdDecoder->m_state.slot1light[6] = ' '; - } - else - { - m_dsdDecoder->m_state.slot1light[0] = '['; - m_dsdDecoder->m_state.slot1light[6] = ']'; - m_dsdDecoder->m_state.slot0light[0] = ' '; - m_dsdDecoder->m_state.slot0light[6] = ' '; - } - } - } - - cachdata[12] = 0; - - // current slot - dibit_p += 49; - - // slot type - dibit = *dibit_p; - dibit_p++; - - if (m_dsdDecoder->m_opts.inverted_dmr == 1) - { - dibit = (dibit ^ 2); - } - - cc[0] = (1 & (dibit >> 1)) + 48; // bit 1 - cc[1] = (1 & dibit) + 48; // bit 0 - - dibit = *dibit_p; - dibit_p++; - - if (m_dsdDecoder->m_opts.inverted_dmr == 1) - { - dibit = (dibit ^ 2); - } - - cc[2] = (1 & (dibit >> 1)) + 48; // bit 1 - cc[3] = (1 & dibit) + 48; // bit 0 - - dibit = *dibit_p; - dibit_p++; - - if (m_dsdDecoder->m_opts.inverted_dmr == 1) - { - dibit = (dibit ^ 2); - } - - bursttype[0] = (1 & (dibit >> 1)) + 48; // bit 1 - bursttype[1] = (1 & dibit) + 48; // bit 0 - - dibit = *dibit_p; - dibit_p++; - - if (m_dsdDecoder->m_opts.inverted_dmr == 1) - { - dibit = (dibit ^ 2); - } - - bursttype[2] = (1 & (dibit >> 1)) + 48; // bit 1 - bursttype[3] = (1 & dibit) + 48; // bit 0 - - // parity bit - dibit_p++; - - if (strcmp(bursttype, "0000") == 0) - { - sprintf(m_dsdDecoder->m_state.fsubtype, " PI Header "); - } - else if (strcmp(bursttype, "0001") == 0) - { - sprintf(m_dsdDecoder->m_state.fsubtype, " VOICE Header "); - } - else if (strcmp(bursttype, "0010") == 0) - { - sprintf(m_dsdDecoder->m_state.fsubtype, " TLC "); - } - else if (strcmp(bursttype, "0011") == 0) - { - sprintf(m_dsdDecoder->m_state.fsubtype, " CSBK "); - } - else if (strcmp(bursttype, "0100") == 0) - { - sprintf(m_dsdDecoder->m_state.fsubtype, " MBC Header "); - } - else if (strcmp(bursttype, "0101") == 0) - { - sprintf(m_dsdDecoder->m_state.fsubtype, " MBC "); - } - else if (strcmp(bursttype, "0110") == 0) - { - sprintf(m_dsdDecoder->m_state.fsubtype, " DATA Header "); - } - else if (strcmp(bursttype, "0111") == 0) - { - sprintf(m_dsdDecoder->m_state.fsubtype, " RATE 1/2 DATA"); - } - else if (strcmp(bursttype, "1000") == 0) - { - sprintf(m_dsdDecoder->m_state.fsubtype, " RATE 3/4 DATA"); - } - else if (strcmp(bursttype, "1001") == 0) - { - sprintf(m_dsdDecoder->m_state.fsubtype, " Slot idle "); - } - else if (strcmp(bursttype, "1010") == 0) - { - sprintf(m_dsdDecoder->m_state.fsubtype, " Rate 1 DATA "); - } - else - { - sprintf(m_dsdDecoder->m_state.fsubtype, " "); - } - - // signaling data or sync - for (int i = 0; i < 24; i++) - { - dibit = *dibit_p; - dibit_p++; - - if (m_dsdDecoder->m_opts.inverted_dmr == 1) - { - dibit = (dibit ^ 2); - } - - syncdata[i] = dibit; - sync[i] = (dibit | 1) + 48; - } - - sync[24] = 0; - syncdata[24] = 0; - - if ((strcmp(sync, DMR_BS_DATA_SYNC) == 0) - || (strcmp(sync, DMR_MS_DATA_SYNC) == 0)) - { - if (m_dsdDecoder->m_state.currentslot == 0) - { - sprintf(m_dsdDecoder->m_state.slot0light, "[slot0]"); - } - else - { - sprintf(m_dsdDecoder->m_state.slot1light, "[slot1]"); - } - } - - if (m_dsdDecoder->m_opts.errorbars == 1) - { - fprintf(stderr, "%s %s\n", m_dsdDecoder->m_state.slot0light, m_dsdDecoder->m_state.slot1light); - } -} - -void DSDDMRData::process() -{ - m_dsdDecoder->getDibit(); // get dibit from symbol but do nothing with it - - if (m_symbolIndex == 120 -1) // last dibit to skip - { - m_dsdDecoder->m_fsmState = DSDDecoder::DSDLookForSync; // go back to search sync state - } - - m_symbolIndex++; -} - -} // namespace DSDplus diff --git a/dsdplus/dmr_data.h b/dsdplus/dmr_data.h deleted file mode 100644 index d832dc278..000000000 --- a/dsdplus/dmr_data.h +++ /dev/null @@ -1,49 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////////// -// Copyright (C) 2016 Edouard Griffiths, F4EXB. // -// // -// This program 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 as version 3 of the License, or // -// // -// This program 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 V3 for more details. // -// // -// You should have received a copy of the GNU General Public License // -// along with this program. If not, see . // -/////////////////////////////////////////////////////////////////////////////////// - -#ifndef DSDPLUS_DMR_DATA_H_ -#define DSDPLUS_DMR_DATA_H_ - -namespace DSDplus -{ - -class DSDDecoder; - -class DSDDMRData -{ -public: - DSDDMRData(DSDDecoder *dsdDecoder); - ~DSDDMRData(); - - void init(); - void process(); - -private: - void preProcess(); //!< process the 90 in memory dibits in initial phase - - DSDDecoder *m_dsdDecoder; - int m_symbolIndex; //!< Current absolute symbol index - int *dibit_p; - char sync[25]; - char syncdata[25]; - char cachdata[13]; - char cc[5]; - char bursttype[5]; -}; - -} - -#endif /* DSDPLUS_DMR_DATA_H_ */ diff --git a/dsdplus/dmr_voice.cpp b/dsdplus/dmr_voice.cpp deleted file mode 100644 index 0300c61ee..000000000 --- a/dsdplus/dmr_voice.cpp +++ /dev/null @@ -1,488 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////////// -// Copyright (C) 2016 Edouard Griffiths, F4EXB. // -// // -// This program 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 as version 3 of the License, or // -// // -// This program 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 V3 for more details. // -// // -// You should have received a copy of the GNU General Public License // -// along with this program. If not, see . // -/////////////////////////////////////////////////////////////////////////////////// - -#include "dmr_voice.h" -#include "dsd_decoder.h" - -namespace DSDplus -{ - -/* - * DMR AMBE interleave schedule - */ -const int DSDDMRVoice::rW[36] = { - 0, 1, 0, 1, 0, 1, - 0, 1, 0, 1, 0, 1, - 0, 1, 0, 1, 0, 1, - 0, 1, 0, 1, 0, 2, - 0, 2, 0, 2, 0, 2, - 0, 2, 0, 2, 0, 2 -}; - -const int DSDDMRVoice::rX[36] = { - 23, 10, 22, 9, 21, 8, - 20, 7, 19, 6, 18, 5, - 17, 4, 16, 3, 15, 2, - 14, 1, 13, 0, 12, 10, - 11, 9, 10, 8, 9, 7, - 8, 6, 7, 5, 6, 4 -}; - -const int DSDDMRVoice::rY[36] = { - 0, 2, 0, 2, 0, 2, - 0, 2, 0, 3, 0, 3, - 1, 3, 1, 3, 1, 3, - 1, 3, 1, 3, 1, 3, - 1, 3, 1, 3, 1, 3, - 1, 3, 1, 3, 1, 3 -}; - -const int DSDDMRVoice::rZ[36] = { - 5, 3, 4, 2, 3, 1, - 2, 0, 1, 13, 0, 12, - 22, 11, 21, 10, 20, 9, - 19, 8, 18, 7, 17, 6, - 16, 5, 15, 4, 14, 3, - 13, 2, 12, 1, 11, 0 -}; - - -DSDDMRVoice::DSDDMRVoice(DSDDecoder *dsdDecoder) : - m_dsdDecoder(dsdDecoder), - m_symbolIndex(0), - m_dibitIndex(0), - mutecurrentslot(0), - m_slotIndex(-1) -{ -} - -DSDDMRVoice::~DSDDMRVoice() -{ -} - -void DSDDMRVoice::init() -{ - mutecurrentslot = 0; - msMode = 0; - dibit_p = m_dsdDecoder->m_state.dibit_buf_p - 144; - m_symbolIndex = 0; - - preProcess(); - - m_symbolIndex = 144; // reposition symbol index in frame -} - -void DSDDMRVoice::process() -{ - m_majorBlock = m_symbolIndex / 288; // frame (major block) index - m_dibitIndex = m_symbolIndex % 288; // index of symbol in frame - int symbolIndex = getSlotIndex(m_dibitIndex); // returns symbol index in current slot. Updates m_slotIndex. - - switch(m_slotIndex) - { - case 0: - processSlot0(symbolIndex); - break; - case 1: - processSlot1(symbolIndex); - break; - case 2: - processSlot2(symbolIndex); - break; - case 3: - processSlot3(symbolIndex); - break; - case 4: - processSlot4(symbolIndex); - break; - case 5: - processSlot5(symbolIndex); - break; - case 6: - processSlot6(symbolIndex); - break; - case 7: - processSlot7(symbolIndex); - break; - case 8: - processSlot8(symbolIndex); - break; - case 9: - processSlot9(symbolIndex); - break; - case 10: // this is the post-process case - postProcess(symbolIndex); - break; - default: - m_dsdDecoder->m_fsmState = DSDDecoder::DSDLookForSync; - break; - } - - m_symbolIndex++; -} - -void DSDDMRVoice::preProcess() -{ - // copy in memory to dibit cache - memcpy((void *) m_dibitCache, (const void *) dibit_p, 144 * sizeof(int)); - - m_dibitIndex = 54-1; // set cache pointer - skip slot 0 - - m_dibitIndex += 12; // advance cache pointer - processSlot1(12-1); - - m_dibitIndex += 36; // advance cache pointer - processSlot2(36-1); - - m_dibitIndex += 18; // advance cache pointer - processSlot3(18-1); - - m_dibitIndex += 24; // advance cache pointer - processSlot4(24-1); - - m_dibitIndex += 18; // advance cache pointer - processSlot5(18-1); - - m_dibitIndex += 36; // advance cache pointer - processSlot6(36-1); - - m_dibitIndex += 12; // advance cache pointer - processSlot7(12-1); - - m_dibitIndex += 54; // advance cache pointer - skip slot 8 - - processSlot9(24-1); - m_dibitIndex += 24; // advance cache pointer - processSlot9(24-1); - - m_symbolIndex = 144; // advance the main symbol index -} - -void DSDDMRVoice::postProcess(int symbolIndex) -{ - //fprintf(stderr, "DSDDMRVoice::postProcess: m_symbolIndex: %d", m_symbolIndex); - m_dsdDecoder->getDibit(); // get dibit from symbol but do nothing with it - - if (symbolIndex == 54+12+54-1) // very last symbol -> go back to search sync state - { - fprintf(stderr, "DSDDMRVoice::postProcess: end of frame\n"); - m_dsdDecoder->m_fsmState = DSDDecoder::DSDLookForSync; - } -} - -void DSDDMRVoice::processSlot0(int symbolIndex) // Slot0 is a 54 symbol slot -{ - m_dsdDecoder->getDibit(); // get dibit from symbol but do nothing with it -} - -void DSDDMRVoice::processSlot8(int symbolIndex) // Slot8 is a 54 symbol slot -{ - m_dsdDecoder->getDibit(); // get dibit from symbol but do nothing with it -} - -void DSDDMRVoice::processSlot1(int symbolIndex) // Slot1 is a 12 symbol slot -{ - if (m_majorBlock > 0) // 0:1 reads from 144 in memory dibits. Handled by upper layer. - { - int dibit = m_dsdDecoder->getDibit(); // get dibit from symbol and store it in cache - m_dibitCache[m_dibitIndex] = dibit; - } - - if (symbolIndex == 12-1) // last symbol -> launch process - { - int *dibitCache = &m_dibitCache[m_dibitIndex - symbolIndex]; // move back to start of corresponding cache section - // CACH - for (int i = 0; i < 12; i++) - { - int dibit = dibitCache[i]; - cachdata[i] = dibit; - - if (i == 2) - { - m_dsdDecoder->m_state.currentslot = (1 & (dibit >> 1)); // bit 1 - - if (m_dsdDecoder->m_state.currentslot == 0) - { - m_dsdDecoder->m_state.slot0light[0] = '['; - m_dsdDecoder->m_state.slot0light[6] = ']'; - m_dsdDecoder->m_state.slot1light[0] = ' '; - m_dsdDecoder->m_state.slot1light[6] = ' '; - } - else - { - m_dsdDecoder->m_state.slot1light[0] = '['; - m_dsdDecoder->m_state.slot1light[6] = ']'; - m_dsdDecoder->m_state.slot0light[0] = ' '; - m_dsdDecoder->m_state.slot0light[6] = ' '; - } - } - } - - cachdata[12] = 0; - } -} - -void DSDDMRVoice::processSlot2(int symbolIndex) // Slot2 is a 36 symbol slot -{ - if (m_majorBlock > 0) // 0:2 reads from 144 in memory dibits. Handled by upper layer. - { - int dibit = m_dsdDecoder->getDibit(); // get dibit from symbol and store it in cache - m_dibitCache[m_dibitIndex] = dibit; - } - - if (symbolIndex == 36-1) // last symbol -> launch process - { - int *dibitCache = &m_dibitCache[m_dibitIndex - symbolIndex]; // move back to start of corresponding cache section - - w = rW; - x = rX; - y = rY; - z = rZ; - - for (int i = 0; i < 36; i++) - { - int dibit = dibitCache[i]; - - ambe_fr[*w][*x] = (1 & (dibit >> 1)); // bit 1 - ambe_fr[*y][*z] = (1 & dibit); // bit 0 - w++; - x++; - y++; - z++; - } - } -} - -void DSDDMRVoice::processSlot3(int symbolIndex) // Slot3 is a 18 symbol slot -{ - if (m_majorBlock > 0) // 0:3 reads from 144 in memory dibits. Handled by upper layer. - { - int dibit = m_dsdDecoder->getDibit(); // get dibit from symbol and store it in cache - m_dibitCache[m_dibitIndex] = dibit; - } - - if (symbolIndex == 18-1) // last symbol -> launch process - { - int *dibitCache = &m_dibitCache[m_dibitIndex - symbolIndex]; // move back to start of corresponding cache section - - w = rW; - x = rX; - y = rY; - z = rZ; - - for (int i = 0; i < 18; i++) - { - int dibit = dibitCache[i]; - - ambe_fr2[*w][*x] = (1 & (dibit >> 1)); // bit 1 - ambe_fr2[*y][*z] = (1 & dibit); // bit 0 - w++; - x++; - y++; - z++; - } - } -} - -void DSDDMRVoice::processSlot4(int symbolIndex) // Slot4 is a 24 symbol slot -{ - if (m_majorBlock > 0) // 0:3 reads from 144 in memory dibits. Handled by upper layer. - { - int dibit = m_dsdDecoder->getDibit(); // get dibit from symbol and store it in cache - m_dibitCache[m_dibitIndex] = dibit; - } - - if (symbolIndex == 24-1) // last symbol -> launch process - { - int *dibitCache = &m_dibitCache[m_dibitIndex - symbolIndex]; // move back to start of corresponding cache section - - for (int i = 0; i < 24; i++) - { - int dibit = dibitCache[i]; - - syncdata[i] = dibit; - sync[i] = (dibit | 1) + 48; - } - - sync[24] = 0; - syncdata[24] = 0; - - if ((strcmp(sync, DMR_BS_DATA_SYNC) == 0) - || (strcmp(sync, DMR_MS_DATA_SYNC) == 0)) - { - mutecurrentslot = 1; - if (m_dsdDecoder->m_state.currentslot == 0) - { - sprintf(m_dsdDecoder->m_state.slot0light, "[slot0]"); - } - else - { - sprintf(m_dsdDecoder->m_state.slot1light, "[slot1]"); - } - } - else if ((strcmp(sync, DMR_BS_VOICE_SYNC) == 0) - || (strcmp(sync, DMR_MS_VOICE_SYNC) == 0)) - { - mutecurrentslot = 0; - if (m_dsdDecoder->m_state.currentslot == 0) - { - sprintf(m_dsdDecoder->m_state.slot0light, "[SLOT0]"); - } - else - { - sprintf(m_dsdDecoder->m_state.slot1light, "[SLOT1]"); - } - } - if ((strcmp(sync, DMR_MS_VOICE_SYNC) == 0) - || (strcmp(sync, DMR_MS_DATA_SYNC) == 0)) - { - msMode = 1; - } - - if ((m_majorBlock == 0) && (m_dsdDecoder->m_opts.errorbars == 1)) - { - fprintf(stderr, "%s %s VOICE e:", m_dsdDecoder->m_state.slot0light, m_dsdDecoder->m_state.slot1light); - } - } -} - -void DSDDMRVoice::processSlot5(int symbolIndex) // Slot5 is a 18 symbol slot -{ - int dibit = m_dsdDecoder->getDibit(); // get dibit from symbol and store it in cache - m_dibitCache[m_dibitIndex] = dibit; - - if (symbolIndex == 18-1) // last symbol -> launch process - { - int *dibitCache = &m_dibitCache[m_dibitIndex - symbolIndex]; // move back to start of corresponding cache section - - for (int i = 0; i < 18; i++) - { - int dibit = dibitCache[i]; - - ambe_fr2[*w][*x] = (1 & (dibit >> 1)); // bit 1 - ambe_fr2[*y][*z] = (1 & dibit); // bit 0 - w++; - x++; - y++; - z++; - } - - if (mutecurrentslot == 0) - { - if (m_dsdDecoder->m_state.firstframe == 1) - { // we don't know if anything received before the first sync after no carrier is valid - m_dsdDecoder->m_state.firstframe = 0; - } - else - { - if (m_dsdDecoder->m_opts.errorbars == 1) { - fprintf(stderr, "\nMBE: "); - } - - m_dsdDecoder->m_mbeDecoder.processFrame(0, ambe_fr, 0); - if (m_dsdDecoder->m_opts.errorbars == 1) { - fprintf(stderr, "."); - } - - m_dsdDecoder->m_mbeDecoder.processFrame(0, ambe_fr2, 0); - if (m_dsdDecoder->m_opts.errorbars == 1) { - fprintf(stderr, "."); - } - } - } - } -} - -void DSDDMRVoice::processSlot6(int symbolIndex) // Slot6 is a 36 symbol slot -{ - int dibit = m_dsdDecoder->getDibit(); // get dibit from symbol and store it in cache - m_dibitCache[m_dibitIndex] = dibit; - - if (symbolIndex == 36-1) // last symbol -> launch process - { - int *dibitCache = &m_dibitCache[m_dibitIndex - symbolIndex]; // move back to start of corresponding cache section - - // current slot frame 3 - w = rW; - x = rX; - y = rY; - z = rZ; - - for (int i = 0; i < 36; i++) - { - int dibit = dibitCache[i]; - - ambe_fr3[*w][*x] = (1 & (dibit >> 1)); // bit 1 - ambe_fr3[*y][*z] = (1 & dibit); // bit 0 - w++; - x++; - y++; - z++; - } - - if (mutecurrentslot == 0) - { - m_dsdDecoder->m_mbeDecoder.processFrame(0, ambe_fr3, 0); - - if (m_dsdDecoder->m_opts.errorbars == 1) { - fprintf(stderr, "\n"); - } - } - } -} - -void DSDDMRVoice::processSlot7(int symbolIndex) // Slot7 is a 12 symbol slot -{ - int dibit = m_dsdDecoder->getDibit(); // get dibit from symbol and store it in cache - m_dibitCache[m_dibitIndex] = dibit; - - if (symbolIndex == 12-1) // last symbol -> launch process - { - int *dibitCache = &m_dibitCache[m_dibitIndex - symbolIndex]; // move back to start of corresponding cache section - // CACH - for (int i = 0; i < 12; i++) - { - int dibit = dibitCache[i]; - cachdata[i] = dibit; - } - - cachdata[12] = 0; - } -} - -void DSDDMRVoice::processSlot9(int symbolIndex) // Slot9 is a 24 symbol slot -{ - int dibit = m_dsdDecoder->getDibit(); // get dibit from symbol and store it in cache - m_dibitCache[m_dibitIndex] = dibit; - - if (symbolIndex == 24-1) // last symbol -> launch process - { - int *dibitCache = &m_dibitCache[m_dibitIndex - symbolIndex]; // move back to start of corresponding cache section - - for (int i = 0; i < 24; i++) - { - int dibit = dibitCache[i]; - - syncdata[i] = dibit; - sync[i] = (dibit | 1) + 48; - } - - sync[24] = 0; - syncdata[24] = 0; - } -} - -} // namespace dsdplus diff --git a/dsdplus/dmr_voice.h b/dsdplus/dmr_voice.h deleted file mode 100644 index f8d9ad611..000000000 --- a/dsdplus/dmr_voice.h +++ /dev/null @@ -1,166 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////////// -// Copyright (C) 2016 Edouard Griffiths, F4EXB. // -// // -// This program 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 as version 3 of the License, or // -// // -// This program 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 V3 for more details. // -// // -// You should have received a copy of the GNU General Public License // -// along with this program. If not, see . // -/////////////////////////////////////////////////////////////////////////////////// - -/* - * DMR voice frames - * 6 Major blocks of 10 slots. 2 groups of slots of 144 bytes each. - * Map is as follows in number of bytes - * - * 0 ... 5 - * A 0 54 ... 54 <- AMBE DMR slot 0 frame 2 1/2 + frame 3: skipped - * 1 12 12 <- CACH data - * 2 36 36 <- AMBE DMR slot 1 frame 1 - * 3 18 18 <- AMBE DMR slot 1 frame 2 1/2 - * 4 24 24 <- SYNC data - * B 5 18 18 <- AMBE DMR slot 1 frame 2 1/2 - * 6 36 36 <- AMBE DMR slot 1 frame 3 - * 7 12 12 <- CACH data - * 8 54 54 <- AMBE DMR slot 0 frame 1 + frame 2 1/2: skipped - * 9 24 24 <- SYNC data - * - * The A group of the first major block is already in memory and is processed - * at initialization time - * Then dibits for each slot are stored in cache and processed right after the - * last dibit for the slot has been added. - * For skipped slots the dibits are simply thrown away - * - * The DMR slot 0 is ignored. Only the DMR slot 1 is processed (listening to one conversation at a time) - * - */ - -#ifndef DSDPLUS_DMR_VOICE_H_ -#define DSDPLUS_DMR_VOICE_H_ - -namespace DSDplus -{ - -class DSDDecoder; - -class DSDDMRVoice -{ -public: - DSDDMRVoice(DSDDecoder *dsdDecoder); - ~DSDDMRVoice(); - - void init(); - void process(); - -private: - int getSlotIndex(int symbolInMajorBlockIndex) //!< calculates current slot index and returns symbol index in the slot - { - if (m_majorBlock > 5) // this is the post-process case - { - m_slotIndex = 10; - return symbolInMajorBlockIndex; - } - - if (symbolInMajorBlockIndex < 54) - { - m_slotIndex = 0; - return symbolInMajorBlockIndex; - } - else if (symbolInMajorBlockIndex < 54+12) - { - m_slotIndex = 1; - return symbolInMajorBlockIndex - 54; - } - else if (symbolInMajorBlockIndex < 54+12+36) - { - m_slotIndex = 2; - return symbolInMajorBlockIndex - 54+12; - } - else if (symbolInMajorBlockIndex < 54+12+36+18) - { - m_slotIndex = 3; - return symbolInMajorBlockIndex - 54+12+36; - } - else if (symbolInMajorBlockIndex < 54+12+36+18+24) - { - m_slotIndex = 4; - return symbolInMajorBlockIndex - 54+12+36+18; - } - else if (symbolInMajorBlockIndex < 54+12+36+18+24+18) - { - m_slotIndex = 5; - return symbolInMajorBlockIndex - 54+12+36+18+24; - } - else if (symbolInMajorBlockIndex < 54+12+36+18+24+18+36) - { - m_slotIndex = 6; - return symbolInMajorBlockIndex - 54+12+36+18+24+18; - } - else if (symbolInMajorBlockIndex < 54+12+36+18+24+18+36+12) - { - m_slotIndex = 7; - return symbolInMajorBlockIndex - 54+12+36+18+24+18+36; - } - else if (symbolInMajorBlockIndex < 54+12+36+18+24+18+36+12+54) - { - m_slotIndex = 8; - return symbolInMajorBlockIndex - 54+12+36+18+24+18+36+12; - } - else if (symbolInMajorBlockIndex < 54+12+36+18+24+18+36+12+54+24) - { - m_slotIndex = 9; - return symbolInMajorBlockIndex - 54+12+36+18+24+18+36+12+54; - } - else // cannot go there if using this function in its valid context (input is a remainder of division by 288) - { - m_slotIndex = -1; // invalid slot - return 0; - } - } - - void preProcess(); //!< process the 144 in memory dibits in initial phase - void postProcess(int symbolIndex); //!< skip 54 + 12 + 54 symbols at the end of the last slot (block 5 slot 9) - void processSlot0(int symbolIndex); - void processSlot1(int symbolIndex); - void processSlot2(int symbolIndex); - void processSlot3(int symbolIndex); - void processSlot4(int symbolIndex); - void processSlot5(int symbolIndex); - void processSlot6(int symbolIndex); - void processSlot7(int symbolIndex); - void processSlot8(int symbolIndex); - void processSlot9(int symbolIndex); - - DSDDecoder *m_dsdDecoder; - // extracts AMBE frames from DMR frame - int m_symbolIndex; //!< Current absolute symbol index - int m_slotIndex; //!< Slot index in major block 0..9 //i; - int m_majorBlock; //!< Major block index 0..5 //j; - int *dibit_p; - char ambe_fr[4][24]; - char ambe_fr2[4][24]; - char ambe_fr3[4][24]; - const int *w, *x, *y, *z; - char sync[25]; - char syncdata[25]; - char cachdata[13]; - int mutecurrentslot; - int msMode; - int m_dibitCache[288]; // has to handle a complete frame (288 dibits) - int m_dibitIndex; // index in dibit cache - - static const int rW[36]; - static const int rX[36]; - static const int rY[36]; - static const int rZ[36]; -}; - -} - -#endif /* DSDPLUS_DMR_VOICE_H_ */ diff --git a/dsdplus/dsd_decoder.cpp b/dsdplus/dsd_decoder.cpp deleted file mode 100644 index 29c780ad9..000000000 --- a/dsdplus/dsd_decoder.cpp +++ /dev/null @@ -1,1687 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////////// -// Copyright (C) 2016 Edouard Griffiths, F4EXB. // -// // -// This program 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 as version 3 of the License, or // -// // -// This program 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 V3 for more details. // -// // -// You should have received a copy of the GNU General Public License // -// along with this program. If not, see . // -/////////////////////////////////////////////////////////////////////////////////// - -#include -#include "dsd_decoder.h" - -namespace DSDplus -{ - -DSDDecoder::DSDDecoder() : - m_symbol(0), - m_fsmState(DSDLookForSync), - m_hasSync(0), - m_mbeDecoder(this), - m_dsdDMRVoice(this), - m_dsdDMRData(this), - m_dsdDstar(this) -{ - resetSymbol(); - resetFrameSync(); - noCarrier(); -} - -DSDDecoder::~DSDDecoder() -{ -} - -void DSDDecoder::run(short sample) -{ - if (pushSample(sample, 0)) // a symbol is retrieved - { - switch (m_fsmState) - { - case DSDLookForSync: - m_hasSync = 0; - m_state.synctype = getFrameSync(); // -> -2: still looking, -1 not found, 0 and above: sync found - - if (m_state.synctype > -2) // -1 and above means syncing has been processed (sync found or not but not searching) - { - // recalibrate center/umid/lmid - m_state.center = ((m_state.max) + (m_state.min)) / 2; - m_state.umid = (((m_state.max) - m_state.center) * 5 / 8) + m_state.center; - m_state.lmid = (((m_state.min) - m_state.center) * 5 / 8) + m_state.center; - - if (m_state.synctype > -1) // 0 and above means a sync has been found - { - m_hasSync = 1; - processFrame(); // process the frame which sync has been found. This will change FSM state - } - else // no sync has been found after searching -> call noCarrier() and go back searching (same FSM state) - { - noCarrier(); - } - } - // still searching -> no change in FSM state - break; - case DSDprocessDMRvoice: - m_dsdDMRVoice.process(); - break; - case DSDprocessDMRdata: - m_dsdDMRData.process(); - break; - case DSDprocessDSTAR: - m_dsdDstar.process(); - break; - case DSDprocessDSTAR_HD: - m_dsdDstar.processHD(); - break; - default: - break; - } - } -} - -void DSDDecoder::resetSymbol() -{ - m_sampleIndex = 0; - m_sum = 0; - m_count = 0; -} - -bool DSDDecoder::pushSample(short sample, int have_sync) -{ - // timing control - if ((m_sampleIndex == 0) && (have_sync == 0)) - { - if (m_state.samplesPerSymbol == 20) - { - if ((m_state.jitter >= 7) && (m_state.jitter <= 10)) - { - m_sampleIndex--; - } - else if ((m_state.jitter >= 11) && (m_state.jitter <= 14)) - { - m_sampleIndex++; - } - } - else if (m_state.rf_mod == 1) - { - if ((m_state.jitter >= 0) - && (m_state.jitter < m_state.symbolCenter)) - { - m_sampleIndex++; // fall back - } - else if ((m_state.jitter > m_state.symbolCenter) - && (m_state.jitter < 10)) - { - m_sampleIndex--; // catch up - } - } - else if (m_state.rf_mod == 2) - { - if ((m_state.jitter >= m_state.symbolCenter - 1) - && (m_state.jitter <= m_state.symbolCenter)) - { - m_sampleIndex--; - } - else if ((m_state.jitter >= m_state.symbolCenter + 1) - && (m_state.jitter <= m_state.symbolCenter + 2)) - { - m_sampleIndex++; - } - } - else if (m_state.rf_mod == 0) - { - if ((m_state.jitter > 0) - && (m_state.jitter <= m_state.symbolCenter)) - { - m_sampleIndex--; // catch up - } - else if ((m_state.jitter > m_state.symbolCenter) - && (m_state.jitter < m_state.samplesPerSymbol)) - { - m_sampleIndex++; // fall back - } - } - - m_state.jitter = -1; - } - - // process sample - if (m_opts.use_cosine_filter) - { - if (m_state.lastsynctype >= 10 && m_state.lastsynctype <= 13) - { - sample = m_dsdFilters.dmr_filter(sample); - } - else if (m_state.lastsynctype == 8 || m_state.lastsynctype == 9 - || m_state.lastsynctype == 16 || m_state.lastsynctype == 17) - { - sample = m_dsdFilters.nxdn_filter(sample); - } - } - - if ((sample > m_state.max) && (have_sync == 1) && (m_state.rf_mod == 0)) - { - sample = m_state.max; - } - else if ((sample < m_state.min) && (have_sync == 1) - && (m_state.rf_mod == 0)) - { - sample = m_state.min; - } - - if (sample > m_state.center) - { - if (m_state.lastsample < m_state.center) - { - m_state.numflips += 1; - } - if (sample > (m_state.maxref * 1.25)) - { - if (m_state.lastsample < (m_state.maxref * 1.25)) - { - m_state.numflips += 1; - } - if ((m_state.jitter < 0) && (m_state.rf_mod == 1)) - { // first spike out of place - m_state.jitter = m_sampleIndex; - } - if ((m_opts.symboltiming == 1) && (have_sync == 0) - && (m_state.lastsynctype != -1)) - { - fprintf(stderr, "O"); - } - } - else - { - if ((m_opts.symboltiming == 1) && (have_sync == 0) - && (m_state.lastsynctype != -1)) - { - fprintf(stderr, "+"); - } - if ((m_state.jitter < 0) - && (m_state.lastsample < m_state.center) - && (m_state.rf_mod != 1)) - { // first transition edge - m_state.jitter = m_sampleIndex; - } - } - } - else - { // sample < 0 - if (m_state.lastsample > m_state.center) - { - m_state.numflips += 1; - } - if (sample < (m_state.minref * 1.25)) - { - if (m_state.lastsample > (m_state.minref * 1.25)) - { - m_state.numflips += 1; - } - if ((m_state.jitter < 0) && (m_state.rf_mod == 1)) - { // first spike out of place - m_state.jitter = m_sampleIndex; - } - if ((m_opts.symboltiming == 1) && (have_sync == 0) - && (m_state.lastsynctype != -1)) - { - fprintf(stderr, "X"); - } - } - else - { - if ((m_opts.symboltiming == 1) && (have_sync == 0) - && (m_state.lastsynctype != -1)) - { - fprintf(stderr, "-"); - } - if ((m_state.jitter < 0) - && (m_state.lastsample > m_state.center) - && (m_state.rf_mod != 1)) - { // first transition edge - m_state.jitter = m_sampleIndex; - } - } - } - if (m_state.samplesPerSymbol == 20) - { - if ((m_sampleIndex >= 9) && (m_sampleIndex <= 11)) - { - m_sum += sample; - m_count++; - } - } - if (m_state.samplesPerSymbol == 5) - { - if (m_sampleIndex == 2) - { - m_sum += sample; - m_count++; - } - } - else - { - if (((m_sampleIndex >= m_state.symbolCenter - 1) - && (m_sampleIndex <= m_state.symbolCenter + 2) - && (m_state.rf_mod == 0)) - || (((m_sampleIndex == m_state.symbolCenter) - || (m_sampleIndex == m_state.symbolCenter + 1)) - && (m_state.rf_mod != 0))) - { - m_sum += sample; - m_count++; - } - } - - m_state.lastsample = sample; - - if (m_sampleIndex == m_state.samplesPerSymbol - 1) // conclusion - { - m_symbol = m_sum / m_count; - if ((m_opts.symboltiming == 1) && (have_sync == 0) - && (m_state.lastsynctype != -1)) - { - if (m_state.jitter >= 0) - { - fprintf(stderr, " %i\n", m_state.jitter); - } - else - { - fprintf(stderr, "\n"); - } - } - - m_state.symbolcnt++; - resetSymbol(); - return true; // new symbol available - } - else - { - m_sampleIndex++; // wait for next sample - return false; - } -} - -int DSDDecoder::getDibit() -{ - // returns one dibit value - int i, j, o, symbol; - int sbuf2[128]; - int spectrum[64]; - char modulation[8]; - int lmin, lmax, lsum; - - m_state.numflips = 0; - - symbol = m_symbol; - m_state.sbuf[m_state.sidx] = m_symbol; - - for (i = 0; i < m_opts.ssize; i++) - { - sbuf2[i] = m_state.sbuf[i]; - } - - qsort(sbuf2, m_opts.ssize, sizeof(int), comp); - // continuous update of min/max in rf_mod=1 (QPSK) mode - // in c4fm min/max must only be updated during sync - if (m_state.rf_mod == 1) - { - lmin = (sbuf2[0] + sbuf2[1]) / 2; - lmax = (sbuf2[(m_opts.ssize - 1)] + sbuf2[(m_opts.ssize - 2)]) / 2; - m_state.minbuf[m_state.midx] = lmin; - m_state.maxbuf[m_state.midx] = lmax; - - if (m_state.midx == (m_opts.msize - 1)) - { - m_state.midx = 0; - } - else - { - m_state.midx++; - } - - lsum = 0; - - for (i = 0; i < m_opts.msize; i++) - { - lsum += m_state.minbuf[i]; - } - - m_state.min = lsum / m_opts.msize; - lsum = 0; - - for (i = 0; i < m_opts.msize; i++) - { - lsum += m_state.maxbuf[i]; - } - - m_state.max = lsum / m_opts.msize; - m_state.center = ((m_state.max) + (m_state.min)) / 2; - m_state.umid = (((m_state.max) - m_state.center) * 5 / 8) + m_state.center; - m_state.lmid = (((m_state.min) - m_state.center) * 5 / 8) + m_state.center; - m_state.maxref = ((m_state.max) * 0.80); - m_state.minref = ((m_state.min) * 0.80); - } - else - { - m_state.maxref = m_state.max; - m_state.minref = m_state.min; - } - - if (m_state.sidx == (m_opts.ssize - 1)) - { - m_state.sidx = 0; - - if (m_opts.datascope == 1) - { - if (m_state.rf_mod == 0) - { - sprintf(modulation, "C4FM"); - } - else if (m_state.rf_mod == 1) - { - sprintf(modulation, "QPSK"); - } - else if (m_state.rf_mod == 2) - { - sprintf(modulation, "GFSK"); - } - - for (i = 0; i < 64; i++) - { - spectrum[i] = 0; - } - for (i = 0; i < m_opts.ssize; i++) - { - o = (sbuf2[i] + 32768) / 1024; - spectrum[o]++; - } - if (m_state.symbolcnt > (4800 / m_opts.scoperate)) - { - m_state.symbolcnt = 0; - fprintf(stderr, "\n"); - fprintf(stderr, - "Demod mode: %s Nac: %4X\n", - modulation, m_state.nac); - fprintf(stderr, - "Frame Type: %s Talkgroup: %7i\n", - m_state.ftype, m_state.lasttg); - fprintf(stderr, - "Frame Subtype: %s Source: %12i\n", - m_state.fsubtype, m_state.lastsrc); - fprintf(stderr, - "TDMA activity: %s %s Voice errors: %s\n", - m_state.slot0light, m_state.slot1light, m_state.err_str); - fprintf(stderr, - "+----------------------------------------------------------------+\n"); - - for (i = 0; i < 10; i++) - { - fprintf(stderr, "|"); - - for (j = 0; j < 64; j++) - { - if (i == 0) - { - if ((j == ((m_state.min) + 32768) / 1024) - || (j == ((m_state.max) + 32768) / 1024)) - { - fprintf(stderr, "#"); - } - else if ((j == ((m_state.lmid) + 32768) / 1024) - || (j == ((m_state.umid) + 32768) / 1024)) - { - fprintf(stderr, "^"); - } - else if (j == (m_state.center + 32768) / 1024) - { - fprintf(stderr, "!"); - } - else - { - if (j == 32) - { - fprintf(stderr, "|"); - } - else - { - fprintf(stderr, " "); - } - } - } - else - { - if (spectrum[j] > 9 - i) - { - fprintf(stderr, "*"); - } - else - { - if (j == 32) - { - fprintf(stderr, "|"); - } - else - { - fprintf(stderr, " "); - } - } - } - } - fprintf(stderr, "|\n"); - } - fprintf(stderr, - "+----------------------------------------------------------------+\n"); - } - } - } - else - { - m_state.sidx++; - } - - if (m_state.dibit_buf_p > m_state.dibit_buf + 900000) - { - m_state.dibit_buf_p = m_state.dibit_buf + 200; - } - - // determine dibit state - if ((m_state.synctype == 6) || (m_state.synctype == 14) - || (m_state.synctype == 18)) - { - if (m_symbol > m_state.center) - { - *m_state.dibit_buf_p = 1; - m_state.dibit_buf_p++; - return (0); - } - else - { - *m_state.dibit_buf_p = 3; - m_state.dibit_buf_p++; - return (1); - } - } - else if ((m_state.synctype == 7) || (m_state.synctype == 15) - || (m_state.synctype == 19)) - { - if (m_symbol > m_state.center) - { - *m_state.dibit_buf_p = 1; - m_state.dibit_buf_p++; - return (1); - } - else - { - *m_state.dibit_buf_p = 3; - m_state.dibit_buf_p++; - return (0); - } - } - else if ((m_state.synctype == 1) || (m_state.synctype == 3) - || (m_state.synctype == 5) || (m_state.synctype == 9) - || (m_state.synctype == 11) || (m_state.synctype == 13)) - { - if (m_symbol > m_state.center) - { - if (m_symbol > m_state.umid) - { - *m_state.dibit_buf_p = 1; // store non-inverted values in dibit_buf - m_state.dibit_buf_p++; - return (3); - } - else - { - *m_state.dibit_buf_p = 0; - m_state.dibit_buf_p++; - return (2); - } - } - else - { - if (m_symbol < m_state.lmid) - { - *m_state.dibit_buf_p = 3; - m_state.dibit_buf_p++; - return (1); - } - else - { - *m_state.dibit_buf_p = 2; - m_state.dibit_buf_p++; - return (0); - } - } - } - else - { - if (m_symbol > m_state.center) - { - if (m_symbol > m_state.umid) - { - *m_state.dibit_buf_p = 1; - m_state.dibit_buf_p++; - return (1); - } - else - { - *m_state.dibit_buf_p = 0; - m_state.dibit_buf_p++; - return (0); - } - } - else - { - if (m_symbol < m_state.lmid) - { - *m_state.dibit_buf_p = 3; - m_state.dibit_buf_p++; - return (3); - } - else - { - *m_state.dibit_buf_p = 2; - m_state.dibit_buf_p++; - return (2); - } - } - } -} - -void DSDDecoder::resetFrameSync() -{ - for (int i = 18; i < 24; i++) - { - m_lbuf[i] = 0; - m_lbuf2[i] = 0; - } - - // reset detect frame sync engine - m_t = 0; - m_synctest[24] = 0; - m_synctest18[18] = 0; - m_synctest32[32] = 0; - m_synctest_pos = 0; - m_synctest_p = m_synctest_buf + 10; - m_lmin = 0; - m_lmax = 0; - m_lidx = 0; - m_lastt = 0; - m_state.numflips = 0; - m_sync = -2; // make in progress - - if ((m_opts.symboltiming == 1) && (m_state.carrier == 1)) - { - fprintf(stderr, "\nSymbol Timing:\n"); - } - - m_fsmState = DSDLookForSync; -} - -void DSDDecoder::printFrameSync(const char *frametype, int offset, char *modulation) -{ - if (m_opts.verbose > 0) - { - fprintf(stderr, "Sync: %s ", frametype); - } - if (m_opts.verbose > 2) - { - fprintf(stderr, "o: %4i ", offset); - } - if (m_opts.verbose > 1) - { - fprintf(stderr, "mod: %s ", modulation); - } - if (m_opts.verbose > 2) - { - fprintf(stderr, "g: %f ", m_state.aout_gain); - } -} - -int DSDDecoder::getFrameSync() -{ - /* detects frame sync and returns frame type - * -2 = in progress - * -1 = no sync - * 0 = +P25p1 - * 1 = -P25p1 - * 2 = +X2-TDMA (non inverted signal data frame) - * 3 = +X2-TDMA (inverted signal voice frame) - * 4 = -X2-TDMA (non inverted signal voice frame) - * 5 = -X2-TDMA (inverted signal data frame) - * 6 = +D-STAR - * 7 = -D-STAR - * 8 = +NXDN (non inverted voice frame) - * 9 = -NXDN (inverted voice frame) - * 10 = +DMR (non inverted singlan data frame) - * 11 = -DMR (inverted signal voice frame) - * 12 = +DMR (non inverted signal voice frame) - * 13 = -DMR (inverted signal data frame) - * 14 = +ProVoice - * 15 = -ProVoice - * 16 = +NXDN (non inverted data frame) - * 17 = -NXDN (inverted data frame) - * 18 = +D-STAR_HD - * 19 = -D-STAR_HD - */ - - // smelly while was starting here - //symbol = getSymbol(opts, state, 0); - m_t++; - m_lbuf[m_lidx] = m_symbol; - m_state.sbuf[m_state.sidx] = m_symbol; - - if (m_lidx == 23) - { - m_lidx = 0; - } - else - { - m_lidx++; - } - - if (m_state.sidx == (m_opts.ssize - 1)) - { - m_state.sidx = 0; - } - else - { - m_state.sidx++; - } - - if (m_lastt == 23) - { - m_lastt = 0; - - if (m_state.numflips > m_opts.mod_threshold) - { - if (m_opts.mod_qpsk == 1) - { - m_state.rf_mod = 1; - } - } - else if (m_state.numflips > 18) - { - if (m_opts.mod_gfsk == 1) - { - m_state.rf_mod = 2; - } - } - else - { - if (m_opts.mod_c4fm == 1) - { - m_state.rf_mod = 0; - } - } - - m_state.numflips = 0; - } - else - { - m_lastt++; - } - - if (m_state.dibit_buf_p > m_state.dibit_buf + 900000) - { - m_state.dibit_buf_p = m_state.dibit_buf + 200; - } - - //determine dibit state - if (m_symbol > 0) - { - *m_state.dibit_buf_p = 1; - m_state.dibit_buf_p++; - m_dibit = 49; - } - else - { - *m_state.dibit_buf_p = 3; - m_state.dibit_buf_p++; - m_dibit = 51; - } - - *m_synctest_p = m_dibit; - - if (m_t >= 18) - { - for (int i = 0; i < 24; i++) - { - m_lbuf2[i] = m_lbuf[i]; - } - - qsort(m_lbuf2, 24, sizeof(int), comp); - - m_lmin = (m_lbuf2[2] + m_lbuf2[3] + m_lbuf2[4]) / 3; - m_lmax = (m_lbuf2[21] + m_lbuf2[20] + m_lbuf2[19]) / 3; - - if (m_state.rf_mod == 1) - { - m_state.minbuf[m_state.midx] = m_lmin; - m_state.maxbuf[m_state.midx] = m_lmax; - - if (m_state.midx == (m_opts.msize - 1)) - { - m_state.midx = 0; - } - else - { - m_state.midx++; - } - - m_lsum = 0; - - for (int i = 0; i < m_opts.msize; i++) - { - m_lsum += m_state.minbuf[i]; - } - - m_state.min = m_lsum / m_opts.msize; - m_lsum = 0; - - for (int i = 0; i < m_opts.msize; i++) - { - m_lsum += m_state.maxbuf[i]; - } - - m_state.max = m_lsum / m_opts.msize; - m_state.center = ((m_state.max) + (m_state.min)) / 2; - m_state.maxref = ((m_state.max) * 0.80); - m_state.minref = ((m_state.min) * 0.80); - } - else - { - m_state.maxref = m_state.max; - m_state.minref = m_state.min; - } - - if (m_state.rf_mod == 0) - { - sprintf(m_modulation, "C4FM"); - } - else if (m_state.rf_mod == 1) - { - sprintf(m_modulation, "QPSK"); - } - else if (m_state.rf_mod == 2) - { - sprintf(m_modulation, "GFSK"); - } - - if (m_opts.datascope == 1) - { - if (m_lidx == 0) - { - for (int i = 0; i < 64; i++) - { - m_spectrum[i] = 0; - } - - for (int i = 0; i < 24; i++) - { - int o = (m_lbuf2[i] + 32768) / 1024; - m_spectrum[o]++; - } - if (m_state.symbolcnt > (4800 / m_opts.scoperate)) - { - m_state.symbolcnt = 0; - - fprintf(stderr, "\n"); - fprintf(stderr, - "Demod mode: %s Nac: %4X\n", - m_modulation, m_state.nac); - fprintf(stderr, - "Frame Type: %s Talkgroup: %7i\n", - m_state.ftype, m_state.lasttg); - fprintf(stderr, - "Frame Subtype: %s Source: %12i\n", - m_state.fsubtype, m_state.lastsrc); - fprintf(stderr, - "TDMA activity: %s %s Voice errors: %s\n", - m_state.slot0light, m_state.slot1light, - m_state.err_str); - fprintf(stderr, - "+----------------------------------------------------------------+\n"); - - for (int i = 0; i < 10; i++) - { - fprintf(stderr, "|"); - - for (int j = 0; j < 64; j++) - { - if (i == 0) - { - if ((j == ((m_state.min) + 32768) / 1024) || (j == ((m_state.max) + 32768) / 1024)) - { - fprintf(stderr, "#"); - } - else if (j == (m_state.center + 32768) / 1024) - { - fprintf(stderr, "!"); - } - else - { - if (j == 32) - { - fprintf(stderr, "|"); - } - else - { - fprintf(stderr, " "); - } - } - } - else - { - if (m_spectrum[j] > 9 - i) - { - fprintf(stderr, "*"); - } - else - { - if (j == 32) - { - fprintf(stderr, "|"); - } - else - { - fprintf(stderr, " "); - } - } - } - } - - fprintf(stderr, "|\n"); - } - - fprintf(stderr, - "+----------------------------------------------------------------+\n"); - } - } - } // m_opts.datascope == 1 - - strncpy(m_synctest, (m_synctest_p - 23), 24); - - if (m_opts.frame_p25p1 == 1) - { - if (strcmp(m_synctest, P25P1_SYNC) == 0) - { - m_state.carrier = 1; - m_state.offset = m_synctest_pos; - m_state.max = ((m_state.max) + m_lmax) / 2; - m_state.min = ((m_state.min) + m_lmin) / 2; - - sprintf(m_state.ftype, " P25 Phase 1 "); - - if (m_opts.errorbars == 1) - { - printFrameSync(" +P25p1 ", m_synctest_pos + 1, m_modulation); - } - - m_state.lastsynctype = 0; - return(0); - } - if (strcmp(m_synctest, INV_P25P1_SYNC) == 0) - { - m_state.carrier = 1; - m_state.offset = m_synctest_pos; - m_state.max = ((m_state.max) + m_lmax) / 2; - m_state.min = ((m_state.min) + m_lmin) / 2; - - sprintf(m_state.ftype, " P25 Phase 1 "); - - if (m_opts.errorbars == 1) - { - printFrameSync(" -P25p1 ", m_synctest_pos + 1, m_modulation); - } - - m_state.lastsynctype = 1; - return(1); - } - } - if (m_opts.frame_x2tdma == 1) - { - if ((strcmp(m_synctest, X2TDMA_BS_DATA_SYNC) == 0) - || (strcmp(m_synctest, X2TDMA_MS_DATA_SYNC) == 0)) - { - m_state.carrier = 1; - m_state.offset = m_synctest_pos; - m_state.max = ((m_state.max) + (m_lmax)) / 2; - m_state.min = ((m_state.min) + (m_lmin)) / 2; - - if (m_opts.inverted_x2tdma == 0) - { - // data frame - sprintf(m_state.ftype, " X2-TDMA "); - - if (m_opts.errorbars == 1) - { - printFrameSync(" +X2-TDMA ", m_synctest_pos + 1, m_modulation); - } - - m_state.lastsynctype = 2; - return(2); // done - } - else - { - // inverted voice frame - sprintf(m_state.ftype, " X2-TDMA "); - - if (m_opts.errorbars == 1) - { - printFrameSync(" -X2-TDMA ", m_synctest_pos + 1, m_modulation); - } - - if (m_state.lastsynctype != 3) - { - m_state.firstframe = 1; - } - - m_state.lastsynctype = 3; - return(3); // done - } - } - if ((strcmp(m_synctest, X2TDMA_BS_VOICE_SYNC) == 0) - || (strcmp(m_synctest, X2TDMA_MS_VOICE_SYNC) == 0)) - { - m_state.carrier = 1; - m_state.offset = m_synctest_pos; - m_state.max = ((m_state.max) + m_lmax) / 2; - m_state.min = ((m_state.min) + m_lmin) / 2; - - if (m_opts.inverted_x2tdma == 0) - { - // voice frame - sprintf(m_state.ftype, " X2-TDMA "); - - if (m_opts.errorbars == 1) - { - printFrameSync(" +X2-TDMA ", m_synctest_pos + 1, m_modulation); - } - - if (m_state.lastsynctype != 4) - { - m_state.firstframe = 1; - } - - m_state.lastsynctype = 4; - return(4); // done - } - else - { - // inverted data frame - sprintf(m_state.ftype, " X2-TDMA "); - - if (m_opts.errorbars == 1) - { - printFrameSync(" -X2-TDMA ", m_synctest_pos + 1, m_modulation); - } - - m_state.lastsynctype = 5; - return(5); // done - } - } - } - if (m_opts.frame_dmr == 1) - { - if ((strcmp(m_synctest, DMR_MS_DATA_SYNC) == 0) - || (strcmp(m_synctest, DMR_BS_DATA_SYNC) == 0)) - { - m_state.carrier = 1; - m_state.offset = m_synctest_pos; - m_state.max = ((m_state.max) + (m_lmax)) / 2; - m_state.min = ((m_state.min) + (m_lmin)) / 2; - - if (m_opts.inverted_dmr == 0) - { - // data frame - sprintf(m_state.ftype, " DMR "); - - if (m_opts.errorbars == 1) - { - printFrameSync(" +DMRd ", m_synctest_pos + 1, m_modulation); - } - - m_state.lastsynctype = 10; - return(10); // done - } - else - { - // inverted voice frame - sprintf(m_state.ftype, " DMR "); - - if (m_opts.errorbars == 1) - { - printFrameSync(" -DMRv ", m_synctest_pos + 1, m_modulation); - } - - if (m_state.lastsynctype != 11) - { - m_state.firstframe = 1; - } - - m_state.lastsynctype = 11; - return(11); // done - } - } - if ((strcmp(m_synctest, DMR_MS_VOICE_SYNC) == 0) - || (strcmp(m_synctest, DMR_BS_VOICE_SYNC) == 0)) - { - m_state.carrier = 1; - m_state.offset = m_synctest_pos; - m_state.max = ((m_state.max) + m_lmax) / 2; - m_state.min = ((m_state.min) + m_lmin) / 2; - - if (m_opts.inverted_dmr == 0) - { - // voice frame - sprintf(m_state.ftype, " DMR "); - - if (m_opts.errorbars == 1) - { - printFrameSync(" +DMRv ", m_synctest_pos + 1, m_modulation); - } - - if (m_state.lastsynctype != 12) - { - m_state.firstframe = 1; - } - - m_state.lastsynctype = 12; - return(12); // done - } - else - { - // inverted data frame - sprintf(m_state.ftype, " DMR "); - - if (m_opts.errorbars == 1) - { - printFrameSync(" -DMRd ", m_synctest_pos + 1, m_modulation); - } - - m_state.lastsynctype = 13; - return(13); // done - } - } - } - if (m_opts.frame_provoice == 1) - { - strncpy(m_synctest32, (m_synctest_p - 31), 32); - - if ((strcmp(m_synctest32, PROVOICE_SYNC) == 0) - || (strcmp(m_synctest32, PROVOICE_EA_SYNC) == 0)) - { - m_state.carrier = 1; - m_state.offset = m_synctest_pos; - m_state.max = ((m_state.max) + m_lmax) / 2; - m_state.min = ((m_state.min) + m_lmin) / 2; - - sprintf(m_state.ftype, " ProVoice "); - - if (m_opts.errorbars == 1) - { - printFrameSync(" -ProVoice ", m_synctest_pos + 1, m_modulation); - } - - m_state.lastsynctype = 14; - return(14); // done - } - else if ((strcmp(m_synctest32, INV_PROVOICE_SYNC) == 0) - || (strcmp(m_synctest32, INV_PROVOICE_EA_SYNC) == 0)) - { - m_state.carrier = 1; - m_state.offset = m_synctest_pos; - m_state.max = ((m_state.max) + m_lmax) / 2; - m_state.min = ((m_state.min) + m_lmin) / 2; - - sprintf(m_state.ftype, " ProVoice "); - - if (m_opts.errorbars == 1) - { - printFrameSync(" -ProVoice ", m_synctest_pos + 1, m_modulation); - } - - m_state.lastsynctype = 15; - return(15); // done - } - - } - if ((m_opts.frame_nxdn96 == 1) || (m_opts.frame_nxdn48 == 1)) - { - strncpy(m_synctest18, (m_synctest_p - 17), 18); - - if ((strcmp(m_synctest18, NXDN_BS_VOICE_SYNC) == 0) - || (strcmp(m_synctest18, NXDN_MS_VOICE_SYNC) == 0)) - { - if ((m_state.lastsynctype == 8) - || (m_state.lastsynctype == 16)) - { - m_state.carrier = 1; - m_state.offset = m_synctest_pos; - m_state.max = ((m_state.max) + m_lmax) / 2; - m_state.min = ((m_state.min) + m_lmin) / 2; - - if (m_state.samplesPerSymbol == 20) - { - sprintf(m_state.ftype, " NXDN48 "); - - if (m_opts.errorbars == 1) - { - printFrameSync(" +NXDN48 ", m_synctest_pos + 1, m_modulation); - } - } - else - { - sprintf(m_state.ftype, " NXDN96 "); - - if (m_opts.errorbars == 1) - { - printFrameSync(" +NXDN96 ", m_synctest_pos + 1, m_modulation); - } - } - - m_state.lastsynctype = 8; - return(8); // done - } - else - { - m_state.lastsynctype = 8; - } - } - else if ((strcmp(m_synctest18, INV_NXDN_BS_VOICE_SYNC) == 0) - || (strcmp(m_synctest18, INV_NXDN_MS_VOICE_SYNC) == 0)) - { - if ((m_state.lastsynctype == 9) - || (m_state.lastsynctype == 17)) - { - m_state.carrier = 1; - m_state.offset = m_synctest_pos; - m_state.max = ((m_state.max) + m_lmax) / 2; - m_state.min = ((m_state.min) + m_lmin) / 2; - - if (m_state.samplesPerSymbol == 20) - { - sprintf(m_state.ftype, " NXDN48 "); - - if (m_opts.errorbars == 1) - { - printFrameSync(" -NXDN48 ", m_synctest_pos + 1, m_modulation); - } - } - else - { - sprintf(m_state.ftype, " NXDN96 "); - - if (m_opts.errorbars == 1) - { - printFrameSync(" -NXDN96 ", m_synctest_pos + 1, m_modulation); - } - } - - m_state.lastsynctype = 9; - return(9); // done - } - else - { - m_state.lastsynctype = 9; - } - } - else if ((strcmp(m_synctest18, NXDN_BS_DATA_SYNC) == 0) - || (strcmp(m_synctest18, NXDN_MS_DATA_SYNC) == 0)) - { - if ((m_state.lastsynctype == 8) - || (m_state.lastsynctype == 16)) - { - m_state.carrier = 1; - m_state.offset = m_synctest_pos; - m_state.max = ((m_state.max) + m_lmax) / 2; - m_state.min = ((m_state.min) + m_lmin) / 2; - - if (m_state.samplesPerSymbol == 20) - { - sprintf(m_state.ftype, " NXDN48 "); - - if (m_opts.errorbars == 1) - { - printFrameSync(" +NXDN48 ", m_synctest_pos + 1, m_modulation); - } - } - else - { - sprintf(m_state.ftype, " NXDN96 "); - - if (m_opts.errorbars == 1) - { - printFrameSync(" +NXDN96 ", m_synctest_pos + 1, m_modulation); - } - } - - m_state.lastsynctype = 16; - return(16); // done - } - else - { - m_state.lastsynctype = 16; - } - } - else if ((strcmp(m_synctest18, INV_NXDN_BS_DATA_SYNC) == 0) - || (strcmp(m_synctest18, INV_NXDN_MS_DATA_SYNC) == 0)) - { - if ((m_state.lastsynctype == 9) - || (m_state.lastsynctype == 17)) - { - m_state.carrier = 1; - m_state.offset = m_synctest_pos; - m_state.max = ((m_state.max) + m_lmax) / 2; - m_state.min = ((m_state.min) + m_lmin) / 2; - - sprintf(m_state.ftype, " NXDN "); - - if (m_state.samplesPerSymbol == 20) - { - sprintf(m_state.ftype, " NXDN48 "); - - if (m_opts.errorbars == 1) - { - printFrameSync(" -NXDN48 ", m_synctest_pos + 1, m_modulation); - } - } - else - { - sprintf(m_state.ftype, " NXDN96 "); - - if (m_opts.errorbars == 1) - { - printFrameSync(" -NXDN96 ", m_synctest_pos + 1, m_modulation); - } - } - - m_state.lastsynctype = 17; - return(17); // done - } - else - { - m_state.lastsynctype = 17; - } - } - } - if (m_opts.frame_dstar == 1) - { - if (strcmp(m_synctest, DSTAR_SYNC) == 0) - { - m_state.carrier = 1; - m_state.offset = m_synctest_pos; - m_state.max = ((m_state.max) + m_lmax) / 2; - m_state.min = ((m_state.min) + m_lmin) / 2; - - sprintf(m_state.ftype, " D-STAR "); - - if (m_opts.errorbars == 1) - { - printFrameSync(" +D-STAR ", m_synctest_pos + 1, m_modulation); - } - - m_state.lastsynctype = 6; - return(6); - } - if (strcmp(m_synctest, INV_DSTAR_SYNC) == 0) - { - m_state.carrier = 1; - m_state.offset = m_synctest_pos; - m_state.max = ((m_state.max) + m_lmax) / 2; - m_state.min = ((m_state.min) + m_lmin) / 2; - - sprintf(m_state.ftype, " D-STAR "); - - if (m_opts.errorbars == 1) - { - printFrameSync(" -D-STAR ", m_synctest_pos + 1, m_modulation); - } - - m_state.lastsynctype = 7; - return(7); // done - } - if (strcmp(m_synctest, DSTAR_HD) == 0) - { - m_state.carrier = 1; - m_state.offset = m_synctest_pos; - m_state.max = ((m_state.max) + m_lmax) / 2; - m_state.min = ((m_state.min) + m_lmin) / 2; - - sprintf(m_state.ftype, " D-STAR_HD "); - - if (m_opts.errorbars == 1) - { - printFrameSync(" +D-STAR_HD ", m_synctest_pos + 1, m_modulation); - } - - m_state.lastsynctype = 18; - return(18); // done - } - if (strcmp(m_synctest, INV_DSTAR_HD) == 0) - { - m_state.carrier = 1; - m_state.offset = m_synctest_pos; - m_state.max = ((m_state.max) + m_lmax) / 2; - m_state.min = ((m_state.min) + m_lmin) / 2; - - sprintf(m_state.ftype, " D-STAR_HD "); - - if (m_opts.errorbars == 1) - { - printFrameSync(" -D-STAR_HD ", m_synctest_pos + 1, m_modulation); - } - - m_state.lastsynctype = 19; - return(19); - } - } - - if ((m_t == 24) && (m_state.lastsynctype != -1)) - { - if ((m_state.lastsynctype == 0) - && ((m_state.lastp25type == 1) - || (m_state.lastp25type == 2))) - { - m_state.carrier = 1; - m_state.offset = m_synctest_pos; - m_state.max = ((m_state.max) + (m_lmax)) / 2; - m_state.min = ((m_state.min) + (m_lmin)) / 2; - - sprintf(m_state.ftype, "(P25 Phase 1)"); - - if (m_opts.errorbars == 1) - { - printFrameSync("(+P25p1) ", m_synctest_pos + 1, m_modulation); - } - - m_state.lastsynctype = -1; - return(0); // done - } - else if ((m_state.lastsynctype == 1) && ((m_state.lastp25type == 1) || (m_state.lastp25type == 2))) - { - m_state.carrier = 1; - m_state.offset = m_synctest_pos; - m_state.max = ((m_state.max) + m_lmax) / 2; - m_state.min = ((m_state.min) + m_lmin) / 2; - sprintf(m_state.ftype, "(P25 Phase 1)"); - if (m_opts.errorbars == 1) - { - printFrameSync("(-P25p1) ", m_synctest_pos + 1, m_modulation); - } - - m_state.lastsynctype = -1; - return(1); // done - } - else if ((m_state.lastsynctype == 3) && ((strcmp(m_synctest, X2TDMA_BS_VOICE_SYNC) != 0) || (strcmp(m_synctest, X2TDMA_MS_VOICE_SYNC) != 0))) - { - m_state.carrier = 1; - m_state.offset = m_synctest_pos; - m_state.max = ((m_state.max) + m_lmax) / 2; - m_state.min = ((m_state.min) + m_lmin) / 2; - - sprintf(m_state.ftype, "(X2-TDMA) "); - - if (m_opts.errorbars == 1) - { - printFrameSync("(-X2-TDMA) ", m_synctest_pos + 1, m_modulation); - } - - m_state.lastsynctype = -1; - return(3); - } - else if ((m_state.lastsynctype == 4) && ((strcmp(m_synctest, X2TDMA_BS_DATA_SYNC) != 0) || (strcmp(m_synctest, X2TDMA_MS_DATA_SYNC) != 0))) - { - m_state.carrier = 1; - m_state.offset = m_synctest_pos; - m_state.max = ((m_state.max) + m_lmax) / 2; - m_state.min = ((m_state.min) + m_lmin) / 2; - - sprintf(m_state.ftype, "(X2-TDMA) "); - - if (m_opts.errorbars == 1) - { - printFrameSync("(+X2-TDMA) ", m_synctest_pos + 1, m_modulation); - } - - m_state.lastsynctype = -1; - return(4); - } - else if ((m_state.lastsynctype == 11) && ((strcmp(m_synctest, DMR_BS_VOICE_SYNC) != 0) || (strcmp(m_synctest, DMR_MS_VOICE_SYNC) != 0))) - { - m_state.carrier = 1; - m_state.offset = m_synctest_pos; - m_state.max = ((m_state.max) + m_lmax) / 2; - m_state.min = ((m_state.min) + m_lmin) / 2; - - sprintf(m_state.ftype, "(DMR) "); - - if (m_opts.errorbars == 1) - { - printFrameSync("(-DMR) ", m_synctest_pos + 1, m_modulation); - } - - m_state.lastsynctype = -1; - return(11); // done - } - else if ((m_state.lastsynctype == 12) && ((strcmp(m_synctest, DMR_BS_DATA_SYNC) != 0) || (strcmp(m_synctest, DMR_MS_DATA_SYNC) != 0))) - { - m_state.carrier = 1; - m_state.offset = m_synctest_pos; - m_state.max = ((m_state.max) + m_lmax) / 2; - m_state.min = ((m_state.min) + m_lmin) / 2; - - sprintf(m_state.ftype, "(DMR) "); - - if (m_opts.errorbars == 1) - { - printFrameSync("(+DMR) ", m_synctest_pos + 1, m_modulation); - } - - m_state.lastsynctype = -1; - return(12); // done - } - } - } - - if (m_synctest_pos < 10200) - { - m_synctest_pos++; - m_synctest_p++; - } - else - { - // buffer reset - m_synctest_pos = 0; - m_synctest_p = m_synctest_buf; - noCarrier(); - } - - if (m_state.lastsynctype != 1) - { - if (m_synctest_pos >= 1800) - { - if ((m_opts.errorbars == 1) && (m_opts.verbose > 1) - && (m_state.carrier == 1)) - { - printf("Sync: no sync\n"); - } - - noCarrier(); - return(-1); // done - } - } - - return(-2); // still searching -} - -void DSDDecoder::noCarrier() -{ - m_state.dibit_buf_p = m_state.dibit_buf + 200; - memset(m_state.dibit_buf, 0, sizeof(int) * 200); - m_state.jitter = -1; - m_state.lastsynctype = -1; - m_state.carrier = 0; - m_state.max = 15000; - m_state.min = -15000; - m_state.center = 0; - m_state.err_str[0] = 0; - - sprintf(m_state.fsubtype, " "); - sprintf(m_state.ftype, " "); - - m_state.errs = 0; - m_state.errs2 = 0; - m_state.lasttg = 0; - m_state.lastsrc = 0; - m_state.lastp25type = 0; - m_state.repeat = 0; - m_state.nac = 0; - m_state.numtdulc = 0; - - sprintf(m_state.slot0light, " slot0 "); - sprintf(m_state.slot1light, " slot1 "); - - m_state.firstframe = 0; - - if (m_opts.audio_gain == (float) 0) - { - m_state.aout_gain = 25; - } - - memset(m_state.aout_max_buf, 0, sizeof(float) * 200); - m_state.aout_max_buf_p = m_state.aout_max_buf; - m_state.aout_max_buf_idx = 0; - sprintf(m_state.algid, "________"); - sprintf(m_state.keyid, "________________"); - mbe_initMbeParms(m_state.cur_mp, m_state.prev_mp, m_state.prev_mp_enhanced); -} - -void DSDDecoder::printFrameInfo() -{ - - int level = (int) m_state.max / 164; - - if (m_opts.verbose > 0) - { - fprintf(stderr, "inlvl: %2i%% ", level); - } - if (m_state.nac != 0) - { - fprintf(stderr, "nac: %4X ", m_state.nac); - } - - if (m_opts.verbose > 1) - { - fprintf(stderr, "src: %8i ", m_state.lastsrc); - } - - fprintf(stderr, "tg: %5i ", m_state.lasttg); -} - -int DSDDecoder::comp(const void *a, const void *b) -{ - if (*((const int *) a) == *((const int *) b)) - return 0; - else if (*((const int *) a) < *((const int *) b)) - return -1; - else - return 1; -} - -void DSDDecoder::processFrame() -{ - if (m_state.rf_mod == 1) - { - m_state.maxref = (m_state.max * 0.80); - m_state.minref = (m_state.min * 0.80); - } - else - { - m_state.maxref = m_state.max; - m_state.minref = m_state.min; - } - - if ((m_state.synctype >= 10) && (m_state.synctype <= 13)) - { - m_state.nac = 0; - m_state.lastsrc = 0; - m_state.lasttg = 0; - - if (m_opts.errorbars == 1) - { - if (m_opts.verbose > 0) - { - int level = (int) m_state.max / 164; - fprintf(stderr, "inlvl: %2i%% ", level); - } - } - - if ((m_state.synctype == 11) || (m_state.synctype == 12)) - { - sprintf(m_state.fsubtype, " VOICE "); - m_dsdDMRVoice.init(); - m_fsmState = DSDprocessDMRvoice; - } - else - { - m_state.err_str[0] = 0; - m_dsdDMRData.init(); - m_fsmState = DSDprocessDMRdata; - } - } - else if ((m_state.synctype == 6) || (m_state.synctype == 7)) - { - m_state.nac = 0; - m_state.lastsrc = 0; - m_state.lasttg = 0; - - if (m_opts.errorbars == 1) - { - if (m_opts.verbose > 0) - { - int level = (int) m_state.max / 164; - printf("inlvl: %2i%% ", level); - } - } - - m_state.nac = 0; - sprintf(m_state.fsubtype, " VOICE "); - m_dsdDstar.init(); - m_fsmState = DSDprocessDSTAR; - } - else if ((m_state.synctype == 18) || (m_state.synctype == 19)) - { - m_state.nac = 0; - m_state.lastsrc = 0; - m_state.lasttg = 0; - - if (m_opts.errorbars == 1) - { - if (m_opts.verbose > 0) - { - int level = (int) m_state.max / 164; - fprintf(stderr, "inlvl: %2i%% ", level); - } - } - - m_state.nac = 0; - sprintf(m_state.fsubtype, " DATA "); - m_dsdDstar.init(); - m_fsmState = DSDprocessDSTAR_HD; - } - else - { - noCarrier(); - m_fsmState = DSDLookForSync; - } -} - -} // namespace dsdplus diff --git a/dsdplus/dsd_decoder.h b/dsdplus/dsd_decoder.h deleted file mode 100644 index 68552cc80..000000000 --- a/dsdplus/dsd_decoder.h +++ /dev/null @@ -1,157 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////////// -// Copyright (C) 2016 Edouard Griffiths, F4EXB. // -// // -// This program 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 as version 3 of the License, or // -// // -// This program 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 V3 for more details. // -// // -// You should have received a copy of the GNU General Public License // -// along with this program. If not, see . // -/////////////////////////////////////////////////////////////////////////////////// - -#ifndef DSDPLUS_DSD_DECODER_H_ -#define DSDPLUS_DSD_DECODER_H_ - -#include "dsd_opts.h" -#include "dsd_state.h" -#include "dsd_filters.h" -#include "dsd_mbe.h" -#include "dmr_voice.h" -#include "dmr_data.h" -#include "dstar.h" - -/* - * Frame sync patterns - */ -#define INV_P25P1_SYNC "333331331133111131311111" -#define P25P1_SYNC "111113113311333313133333" - -#define X2TDMA_BS_VOICE_SYNC "113131333331313331113311" -#define X2TDMA_BS_DATA_SYNC "331313111113131113331133" -#define X2TDMA_MS_DATA_SYNC "313113333111111133333313" -#define X2TDMA_MS_VOICE_SYNC "131331111333333311111131" - -#define DSTAR_HD "131313131333133113131111" -#define INV_DSTAR_HD "313131313111311331313333" -#define DSTAR_SYNC "313131313133131113313111" -#define INV_DSTAR_SYNC "131313131311313331131333" - -#define NXDN_MS_DATA_SYNC "313133113131111333" -#define INV_NXDN_MS_DATA_SYNC "131311331313333111" -#define NXDN_MS_VOICE_SYNC "313133113131113133" -#define INV_NXDN_MS_VOICE_SYNC "131311331313331311" -#define INV_NXDN_BS_DATA_SYNC "131311331313333131" -#define NXDN_BS_DATA_SYNC "313133113131111313" -#define INV_NXDN_BS_VOICE_SYNC "131311331313331331" -#define NXDN_BS_VOICE_SYNC "313133113131113113" - -#define DMR_BS_DATA_SYNC "313333111331131131331131" -#define DMR_BS_VOICE_SYNC "131111333113313313113313" -#define DMR_MS_DATA_SYNC "311131133313133331131113" -#define DMR_MS_VOICE_SYNC "133313311131311113313331" - -#define INV_PROVOICE_SYNC "31313111333133133311331133113311" -#define PROVOICE_SYNC "13131333111311311133113311331133" -#define INV_PROVOICE_EA_SYNC "13313133113113333311313133133311" -#define PROVOICE_EA_SYNC "31131311331331111133131311311133" - -namespace DSDplus -{ - -class DSDDecoder -{ - friend class DSDMBEDecoder; - friend class DSDDMRVoice; - friend class DSDDMRData; - friend class DSDDstar; -public: - typedef enum - { - DSDLookForSync, - DSDNoSync, - DSDprocessFrame, - DSDprocessNXDNVoice, - DSDprocessNXDNData, - DSDprocessDSTAR, - DSDprocessDSTAR_HD, - DSDprocessDMRvoice, - DSDprocessDMRdata, - DSDprocessX2TDMAvoice, - DSDprocessX2TDMAdata, - DSDprocessProVoice, - DSDprocessUnknown - } DSDFSMState; - - DSDDecoder(); - ~DSDDecoder(); - - void run(short sample); - - short *getAudio(int& nbSamples) - { - nbSamples = m_state.audio_out_nb_samples; - return m_state.audio_out_buf; - } - - void resetAudio() - { - m_state.audio_out_nb_samples = 0; - m_state.audio_out_buf_p = m_state.audio_out_buf; - } - - DSDOpts *getOpts() { return &m_opts; } - DSDState *getState() { return &m_state; } - -private: - bool pushSample(short sample, int have_sync); //!< push a new sample into the decoder. Returns true if a new symbol is available - int getDibit(); //!< get dibit from the last retrieved symbol. Returns the dibit as its dibit value: 0,1,2,3 - int getFrameSync(); - void resetSymbol(); - void resetFrameSync(); - void printFrameSync(const char *frametype, int offset, char *modulation); - void noCarrier(); - void printFrameInfo(); - void processFrame(); - static int comp(const void *a, const void *b); - - DSDOpts m_opts; - DSDState m_state; - DSDFSMState m_fsmState; - // symbol engine - int m_symbol; //!< the last retrieved symbol - int m_sampleIndex; //!< the current sample index for the symbol in progress - int m_sum; - int m_count; - // sync engine: - int m_sync; //!< The current sync type - int m_dibit, m_synctest_pos, m_lastt; - char m_synctest[25]; - char m_synctest18[19]; - char m_synctest32[33]; - char m_modulation[8]; - char *m_synctest_p; - char m_synctest_buf[10240]; - int m_lmin, m_lmax, m_lidx; - int m_lbuf[24], m_lbuf2[24]; - int m_lsum; - char m_spectrum[64]; - int m_t; - int m_hasSync; //!< tells whether we are in synced phase - // Other - DSDFilters m_dsdFilters; - // MBE decoder - DSDMBEDecoder m_mbeDecoder; - // Frame decoders - DSDDMRVoice m_dsdDMRVoice; - DSDDMRData m_dsdDMRData; - DSDDstar m_dsdDstar; -}; - -} // namespace dsdplus - -#endif /* DSDPLUS_DSD_DECODER_H_ */ diff --git a/dsdplus/dsd_filters.cpp b/dsdplus/dsd_filters.cpp deleted file mode 100644 index 69b4b1600..000000000 --- a/dsdplus/dsd_filters.cpp +++ /dev/null @@ -1,145 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////////// -// Copyright (C) 2016 Edouard Griffiths, F4EXB. // -// // -// This program 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 as version 3 of the License, or // -// // -// This program 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 V3 for more details. // -// // -// You should have received a copy of the GNU General Public License // -// along with this program. If not, see . // -/////////////////////////////////////////////////////////////////////////////////// - -#include "dsd_filters.h" - -namespace DSDplus -{ - -// DMR filter -const float DSDFilters::xcoeffs[] = -{ -0.0083649323f, -0.0265444850f, -0.0428141462f, -0.0537571943f, - -0.0564141052f, -0.0489161045f, -0.0310068662f, -0.0043393881f, - +0.0275375106f, +0.0595423283f, +0.0857543325f, +0.1003565948f, - +0.0986944931f, +0.0782804830f, +0.0395670487f, -0.0136691535f, - -0.0744390415f, -0.1331834575f, -0.1788967208f, -0.2005995448f, - -0.1889627181f, -0.1378439993f, -0.0454976231f, +0.0847488694f, - +0.2444859269f, +0.4209222342f, +0.5982295474f, +0.7593684540f, - +0.8881539892f, +0.9712773915f, +0.9999999166f, +0.9712773915f, - +0.8881539892f, +0.7593684540f, +0.5982295474f, +0.4209222342f, - +0.2444859269f, +0.0847488694f, -0.0454976231f, -0.1378439993f, - -0.1889627181f, -0.2005995448f, -0.1788967208f, -0.1331834575f, - -0.0744390415f, -0.0136691535f, +0.0395670487f, +0.0782804830f, - +0.0986944931f, +0.1003565948f, +0.0857543325f, +0.0595423283f, - +0.0275375106f, -0.0043393881f, -0.0310068662f, -0.0489161045f, - -0.0564141052f, -0.0537571943f, -0.0428141462f, -0.0265444850f, - -0.0083649323f, }; - -// NXDN filter -const float DSDFilters::nxcoeffs[] = -{ +0.031462429f, +0.031747267f, +0.030401148f, +0.027362877f, +0.022653298f, - +0.016379869f, +0.008737200f, +0.000003302f, -0.009468531f, - -0.019262057f, -0.028914291f, -0.037935027f, -0.045828927f, - -0.052119261f, -0.056372283f, -0.058221106f, -0.057387924f, - -0.053703443f, -0.047122444f, -0.037734535f, -0.025769308f, - -0.011595336f, +0.004287292f, +0.021260954f, +0.038610717f, - +0.055550276f, +0.071252765f, +0.084885375f, +0.095646450f, - +0.102803611f, +0.105731303f, +0.103946126f, +0.097138329f, - +0.085197939f, +0.068234131f, +0.046586711f, +0.020828821f, - -0.008239664f, -0.039608255f, -0.072081234f, -0.104311776f, - -0.134843790f, -0.162160200f, -0.184736015f, -0.201094346f, - -0.209863285f, -0.209831516f, -0.200000470f, -0.179630919f, - -0.148282051f, -0.105841323f, -0.052543664f, +0.011020985f, - +0.083912428f, +0.164857408f, +0.252278939f, +0.344336996f, - +0.438979335f, +0.534000832f, +0.627109358f, +0.715995947f, - +0.798406824f, +0.872214756f, +0.935487176f, +0.986548646f, - +1.024035395f, +1.046939951f, +1.054644241f, +1.046939951f, - +1.024035395f, +0.986548646f, +0.935487176f, +0.872214756f, - +0.798406824f, +0.715995947f, +0.627109358f, +0.534000832f, - +0.438979335f, +0.344336996f, +0.252278939f, +0.164857408f, - +0.083912428f, +0.011020985f, -0.052543664f, -0.105841323f, - -0.148282051f, -0.179630919f, -0.200000470f, -0.209831516f, - -0.209863285f, -0.201094346f, -0.184736015f, -0.162160200f, - -0.134843790f, -0.104311776f, -0.072081234f, -0.039608255f, - -0.008239664f, +0.020828821f, +0.046586711f, +0.068234131f, - +0.085197939f, +0.097138329f, +0.103946126f, +0.105731303f, - +0.102803611f, +0.095646450f, +0.084885375f, +0.071252765f, - +0.055550276f, +0.038610717f, +0.021260954f, +0.004287292f, - -0.011595336f, -0.025769308f, -0.037734535f, -0.047122444f, - -0.053703443f, -0.057387924f, -0.058221106f, -0.056372283f, - -0.052119261f, -0.045828927f, -0.037935027f, -0.028914291f, - -0.019262057f, -0.009468531f, +0.000003302f, +0.008737200f, - +0.016379869f, +0.022653298f, +0.027362877f, +0.030401148f, - +0.031747267f, +0.031462429f, }; - -DSDFilters::DSDFilters() -{ - for (int i=0; i < NZEROS+1; i++) { - xv[i] = 0.0f; - } - - for (int i=0; i < NXZEROS+1; i++) { - nxv[i] = 0.0f; - } -} - -DSDFilters::~DSDFilters() -{ -} - -short DSDFilters::dmr_filter(short sample) -{ - return dsd_input_filter(sample, 1); -} - -short DSDFilters::nxdn_filter(short sample) -{ - return dsd_input_filter(sample, 2); -} - -short DSDFilters::dsd_input_filter(short sample, int mode) -{ - float sum; - int i; - float gain; - int zeros; - float *v; - const float *coeffs; - - switch (mode) - { - case 1: - gain = ngain; - v = xv; - coeffs = xcoeffs; - zeros = NZEROS; - break; - case 2: - gain = nxgain; - v = nxv; - coeffs = nxcoeffs; - zeros = NXZEROS; - break; - default: - return sample; - } - - for (i = 0; i < zeros; i++) { - v[i] = v[i + 1]; - } - - v[zeros] = sample; // unfiltered sample in - sum = 0.0f; - - for (i = 0; i <= zeros; i++) { - sum += (coeffs[i] * v[i]); - } - - return sum / ngain; // filtered sample out -} - -} // namespace dsdplus - diff --git a/dsdplus/dsd_filters.h b/dsdplus/dsd_filters.h deleted file mode 100644 index e30ff491f..000000000 --- a/dsdplus/dsd_filters.h +++ /dev/null @@ -1,49 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////////// -// Copyright (C) 2016 Edouard Griffiths, F4EXB. // -// // -// This program 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 as version 3 of the License, or // -// // -// This program 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 V3 for more details. // -// // -// You should have received a copy of the GNU General Public License // -// along with this program. If not, see . // -/////////////////////////////////////////////////////////////////////////////////// - -#ifndef DSDPLUS_DSD_FILTERS_H_ -#define DSDPLUS_DSD_FILTERS_H_ - -#define NZEROS 60 -#define NXZEROS 134 - - -namespace DSDplus -{ - -class DSDFilters -{ -public: - DSDFilters(); - ~DSDFilters(); - - static const float ngain = 7.423339364f; - static const float xcoeffs[]; - static const float nxgain = 15.95930463f; - static const float nxcoeffs[]; - - short dsd_input_filter(short sample, int mode); - short dmr_filter(short sample); - short nxdn_filter(short sample); - -private: - float xv[NZEROS+1]; - float nxv[NXZEROS+1]; -}; - -} - -#endif /* DSDPLUS_DSD_FILTERS_H_ */ diff --git a/dsdplus/dsd_mbe.cpp b/dsdplus/dsd_mbe.cpp deleted file mode 100644 index ba3f729b4..000000000 --- a/dsdplus/dsd_mbe.cpp +++ /dev/null @@ -1,319 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////////// -// Copyright (C) 2016 Edouard Griffiths, F4EXB. // -// // -// This program 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 as version 3 of the License, or // -// // -// This program 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 V3 for more details. // -// // -// You should have received a copy of the GNU General Public License // -// along with this program. If not, see . // -/////////////////////////////////////////////////////////////////////////////////// - -#include -#include -#include "dsd_mbe.h" -#include "dsd_decoder.h" - -extern "C" { -#include -} - -namespace DSDplus -{ - -DSDMBEDecoder::DSDMBEDecoder(DSDDecoder *dsdDecoder) : - m_dsdDecoder(dsdDecoder) -{ -} - -DSDMBEDecoder::~DSDMBEDecoder() -{ -} - -void DSDMBEDecoder::processFrame(char imbe_fr[8][23], char ambe_fr[4][24], char imbe7100_fr[7][24]) -{ -// for (int i = 0; i < 88; i++) -// { -// imbe_d[i] = 0; -// } - memset((void *) imbe_d, 0, 88); - - if ((m_dsdDecoder->m_state.synctype == 0) || (m_dsdDecoder->m_state.synctype == 1)) - { - mbe_processImbe7200x4400Framef(m_dsdDecoder->m_state.audio_out_temp_buf, &m_dsdDecoder->m_state.errs, - &m_dsdDecoder->m_state.errs2, m_dsdDecoder->m_state.err_str, imbe_fr, imbe_d, m_dsdDecoder->m_state.cur_mp, - m_dsdDecoder->m_state.prev_mp, m_dsdDecoder->m_state.prev_mp_enhanced, m_dsdDecoder->m_opts.uvquality); - } - else if ((m_dsdDecoder->m_state.synctype == 14) || (m_dsdDecoder->m_state.synctype == 15)) - { - mbe_processImbe7100x4400Framef(m_dsdDecoder->m_state.audio_out_temp_buf, &m_dsdDecoder->m_state.errs, - &m_dsdDecoder->m_state.errs2, m_dsdDecoder->m_state.err_str, imbe7100_fr, imbe_d, - m_dsdDecoder->m_state.cur_mp, m_dsdDecoder->m_state.prev_mp, m_dsdDecoder->m_state.prev_mp_enhanced, - m_dsdDecoder->m_opts.uvquality); - } - else if ((m_dsdDecoder->m_state.synctype == 6) || (m_dsdDecoder->m_state.synctype == 7)) - { - mbe_processAmbe3600x2400Framef(m_dsdDecoder->m_state.audio_out_temp_buf, &m_dsdDecoder->m_state.errs, - &m_dsdDecoder->m_state.errs2, m_dsdDecoder->m_state.err_str, ambe_fr, ambe_d, m_dsdDecoder->m_state.cur_mp, - m_dsdDecoder->m_state.prev_mp, m_dsdDecoder->m_state.prev_mp_enhanced, m_dsdDecoder->m_opts.uvquality); - } - else - { - mbe_processAmbe3600x2450Framef(m_dsdDecoder->m_state.audio_out_temp_buf, &m_dsdDecoder->m_state.errs, - &m_dsdDecoder->m_state.errs2, m_dsdDecoder->m_state.err_str, ambe_fr, ambe_d, m_dsdDecoder->m_state.cur_mp, - m_dsdDecoder->m_state.prev_mp, m_dsdDecoder->m_state.prev_mp_enhanced, m_dsdDecoder->m_opts.uvquality); - } - - if (m_dsdDecoder->m_opts.errorbars == 1) - { - fprintf(stderr, "%s", m_dsdDecoder->m_state.err_str); - } - - processAudio(); -// if (m_dsdDecoder->m_opts.wav_out_f != NULL) -// { -// writeSynthesizedVoice(opts, state); -// } -// -// if (m_dsdDecoder->m_opts.audio_out == 1) -// { -// playSynthesizedVoice(opts, state); -// } -} - -void DSDMBEDecoder::processAudio() -{ - int i, n; - float aout_abs, max, gainfactor, gaindelta, maxbuf; - - if (m_dsdDecoder->m_opts.audio_gain == (float) 0) - { - // detect max level - max = 0; - m_dsdDecoder->m_state.audio_out_temp_buf_p = m_dsdDecoder->m_state.audio_out_temp_buf; - - for (n = 0; n < 160; n++) - { - aout_abs = fabsf(*m_dsdDecoder->m_state.audio_out_temp_buf_p); - - if (aout_abs > max) - { - max = aout_abs; - } - - m_dsdDecoder->m_state.audio_out_temp_buf_p++; - } - - *m_dsdDecoder->m_state.aout_max_buf_p = max; - m_dsdDecoder->m_state.aout_max_buf_p++; - m_dsdDecoder->m_state.aout_max_buf_idx++; - - if (m_dsdDecoder->m_state.aout_max_buf_idx > 24) - { - m_dsdDecoder->m_state.aout_max_buf_idx = 0; - m_dsdDecoder->m_state.aout_max_buf_p = m_dsdDecoder->m_state.aout_max_buf; - } - - // lookup max history - for (i = 0; i < 25; i++) - { - maxbuf = m_dsdDecoder->m_state.aout_max_buf[i]; - - if (maxbuf > max) - { - max = maxbuf; - } - } - - // determine optimal gain level - if (max > (float) 0) - { - gainfactor = ((float) 30000 / max); - } - else - { - gainfactor = (float) 50; - } - - if (gainfactor < m_dsdDecoder->m_state.aout_gain) - { - m_dsdDecoder->m_state.aout_gain = gainfactor; - gaindelta = (float) 0; - } - else - { - if (gainfactor > (float) 50) - { - gainfactor = (float) 50; - } - - gaindelta = gainfactor - m_dsdDecoder->m_state.aout_gain; - - if (gaindelta > ((float) 0.05 * m_dsdDecoder->m_state.aout_gain)) - { - gaindelta = ((float) 0.05 * m_dsdDecoder->m_state.aout_gain); - } - } - - gaindelta /= (float) 160; - } - else - { - gaindelta = (float) 0; - } - - if (m_dsdDecoder->m_opts.audio_gain >= 0) - { - // adjust output gain - m_dsdDecoder->m_state.audio_out_temp_buf_p = m_dsdDecoder->m_state.audio_out_temp_buf; - - for (n = 0; n < 160; n++) - { - *m_dsdDecoder->m_state.audio_out_temp_buf_p = (m_dsdDecoder->m_state.aout_gain - + ((float) n * gaindelta)) * (*m_dsdDecoder->m_state.audio_out_temp_buf_p); - m_dsdDecoder->m_state.audio_out_temp_buf_p++; - } - - m_dsdDecoder->m_state.aout_gain += ((float) 160 * gaindelta); - } - - // copy audio data to output buffer and upsample if necessary - m_dsdDecoder->m_state.audio_out_temp_buf_p = m_dsdDecoder->m_state.audio_out_temp_buf; - - if ((m_dsdDecoder->m_opts.split == 0) || (m_dsdDecoder->m_opts.upsample != 0)) // upsampling to 48k - { - if (m_dsdDecoder->m_state.audio_out_nb_samples + 960 >= m_dsdDecoder->m_state.audio_out_buf_size) - { - m_dsdDecoder->resetAudio(); - } - - m_dsdDecoder->m_state.audio_out_float_buf_p = m_dsdDecoder->m_state.audio_out_float_buf; - - for (n = 0; n < 160; n++) - { - upsample(*m_dsdDecoder->m_state.audio_out_temp_buf_p); - m_dsdDecoder->m_state.audio_out_temp_buf_p++; - m_dsdDecoder->m_state.audio_out_float_buf_p += 6; - m_dsdDecoder->m_state.audio_out_idx += 6; - m_dsdDecoder->m_state.audio_out_idx2 += 6; - } - - m_dsdDecoder->m_state.audio_out_float_buf_p = m_dsdDecoder->m_state.audio_out_float_buf; - - // copy to output (short) buffer - for (n = 0; n < 960; n++) - { - if (*m_dsdDecoder->m_state.audio_out_float_buf_p > (float) 32760) - { - *m_dsdDecoder->m_state.audio_out_float_buf_p = (float) 32760; - } - else if (*m_dsdDecoder->m_state.audio_out_float_buf_p < (float) -32760) - { - *m_dsdDecoder->m_state.audio_out_float_buf_p = (float) -32760; - } - - *m_dsdDecoder->m_state.audio_out_buf_p = (short) *m_dsdDecoder->m_state.audio_out_float_buf_p; - m_dsdDecoder->m_state.audio_out_buf_p++; - - if (m_dsdDecoder->m_opts.stereo) // produce second channel - { - *m_dsdDecoder->m_state.audio_out_buf_p = (short) *m_dsdDecoder->m_state.audio_out_float_buf_p; - m_dsdDecoder->m_state.audio_out_buf_p++; - } - - m_dsdDecoder->m_state.audio_out_nb_samples++; - m_dsdDecoder->m_state.audio_out_float_buf_p++; - } - - m_dsdDecoder->m_state.audio_out_float_buf_p += m_dsdDecoder->m_opts.playoffset; - } - else // leave at 8k - { - if (m_dsdDecoder->m_state.audio_out_nb_samples + 160 >= m_dsdDecoder->m_state.audio_out_buf_size) - { - m_dsdDecoder->resetAudio(); - } - - for (n = 0; n < 160; n++) - { - if (*m_dsdDecoder->m_state.audio_out_temp_buf_p > (float) 32760) - { - *m_dsdDecoder->m_state.audio_out_temp_buf_p = (float) 32760; - } - else if (*m_dsdDecoder->m_state.audio_out_temp_buf_p < (float) -32760) - { - *m_dsdDecoder->m_state.audio_out_temp_buf_p = (float) -32760; - } - - *m_dsdDecoder->m_state.audio_out_buf_p = (short) *m_dsdDecoder->m_state.audio_out_temp_buf_p; - m_dsdDecoder->m_state.audio_out_buf_p++; - - if (m_dsdDecoder->m_opts.stereo) // produce second channel - { - *m_dsdDecoder->m_state.audio_out_buf_p = (short) *m_dsdDecoder->m_state.audio_out_float_buf_p; - m_dsdDecoder->m_state.audio_out_buf_p++; - } - - m_dsdDecoder->m_state.audio_out_nb_samples++; - m_dsdDecoder->m_state.audio_out_temp_buf_p++; - m_dsdDecoder->m_state.audio_out_idx++; - m_dsdDecoder->m_state.audio_out_idx2++; - } - } -} - -void DSDMBEDecoder::upsample(float invalue) -{ - int i, j, sum; - float *outbuf1, c, d; - - outbuf1 = m_dsdDecoder->m_state.audio_out_float_buf_p; - outbuf1--; - c = *outbuf1; - d = invalue; - // basic triangle interpolation - outbuf1++; - *outbuf1 = ((invalue * (float) 0.166) + (c * (float) 0.834)); - outbuf1++; - *outbuf1 = ((invalue * (float) 0.332) + (c * (float) 0.668)); - outbuf1++; - *outbuf1 = ((invalue * (float) 0.5) + (c * (float) 0.5)); - outbuf1++; - *outbuf1 = ((invalue * (float) 0.668) + (c * (float) 0.332)); - outbuf1++; - *outbuf1 = ((invalue * (float) 0.834) + (c * (float) 0.166)); - outbuf1++; - *outbuf1 = d; - outbuf1++; - - if (m_dsdDecoder->m_state.audio_out_idx2 > 24) - { - // smoothing - outbuf1 -= 16; - for (j = 0; j < 4; j++) - { - for (i = 0; i < 6; i++) - { - sum = 0; - outbuf1 -= 2; - sum += *outbuf1; - outbuf1 += 2; - sum += *outbuf1; - outbuf1 += 2; - sum += *outbuf1; - outbuf1 -= 2; - *outbuf1 = (sum / (float) 3); - outbuf1++; - } - outbuf1 -= 8; - } - } -} - - -} diff --git a/dsdplus/dsd_mbe.h b/dsdplus/dsd_mbe.h deleted file mode 100644 index c35c7aa32..000000000 --- a/dsdplus/dsd_mbe.h +++ /dev/null @@ -1,45 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////////// -// Copyright (C) 2016 Edouard Griffiths, F4EXB. // -// // -// This program 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 as version 3 of the License, or // -// // -// This program 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 V3 for more details. // -// // -// You should have received a copy of the GNU General Public License // -// along with this program. If not, see . // -/////////////////////////////////////////////////////////////////////////////////// - -#ifndef DSDPLUS_DSD_MBE_H_ -#define DSDPLUS_DSD_MBE_H_ - -namespace DSDplus -{ - -class DSDDecoder; - -class DSDMBEDecoder -{ -public: - DSDMBEDecoder(DSDDecoder *dsdDecoder); - ~DSDMBEDecoder(); - - void processFrame(char imbe_fr[8][23], char ambe_fr[4][24], char imbe7100_fr[7][24]); - -private: - void processAudio(); - void upsample(float invalue); - - DSDDecoder *m_dsdDecoder; - char imbe_d[88]; - char ambe_d[49]; - -}; - -} - -#endif /* DSDPLUS_DSD_MBE_H_ */ diff --git a/dsdplus/dsd_opts.cpp b/dsdplus/dsd_opts.cpp deleted file mode 100644 index 610f49ef8..000000000 --- a/dsdplus/dsd_opts.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////////// -// Copyright (C) 2016 Edouard Griffiths, F4EXB. // -// // -// This program 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 as version 3 of the License, or // -// // -// This program 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 V3 for more details. // -// // -// You should have received a copy of the GNU General Public License // -// along with this program. If not, see . // -/////////////////////////////////////////////////////////////////////////////////// - -#include "dsd_opts.h" - -namespace DSDplus -{ - -DSDOpts::DSDOpts() -{ - onesymbol = 10; - errorbars = 1; - datascope = 0; - symboltiming = 0; - verbose = 2; - p25enc = 0; - p25lc = 0; - p25status = 0; - p25tg = 0; - scoperate = 15; - split = 0; - playoffset = 0; - audio_gain = 0; - audio_out = 1; - resume = 0; - frame_dstar = 0; - frame_x2tdma = 1; - frame_p25p1 = 1; - frame_nxdn48 = 0; - frame_nxdn96 = 1; - frame_dmr = 1; - frame_provoice = 0; - mod_c4fm = 1; - mod_qpsk = 1; - mod_gfsk = 1; - uvquality = 3; - inverted_x2tdma = 1; // most transmitter + scanner + sound card combinations show inverted signals for this - inverted_dmr = 0; // most transmitter + scanner + sound card combinations show non-inverted signals for this - mod_threshold = 26; - ssize = 36; - msize = 15; - delay = 0; - use_cosine_filter = 1; - unmute_encrypted_p25 = 0; - upsample = 0; - stereo = 0; -} - -DSDOpts::~DSDOpts() -{ -} - -} // namespace dsdplus - diff --git a/dsdplus/dsd_opts.h b/dsdplus/dsd_opts.h deleted file mode 100644 index 7c2e44cf8..000000000 --- a/dsdplus/dsd_opts.h +++ /dev/null @@ -1,69 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////////// -// Copyright (C) 2016 Edouard Griffiths, F4EXB. // -// // -// This program 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 as version 3 of the License, or // -// // -// This program 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 V3 for more details. // -// // -// You should have received a copy of the GNU General Public License // -// along with this program. If not, see . // -/////////////////////////////////////////////////////////////////////////////////// - -#ifndef DSDPLUS_DSD_OPTS_H_ -#define DSDPLUS_DSD_OPTS_H_ - -namespace DSDplus -{ - -class DSDOpts -{ -public: - DSDOpts(); - ~DSDOpts(); - - int onesymbol; - int errorbars; - int datascope; - int symboltiming; - int verbose; - int p25enc; - int p25lc; - int p25status; - int p25tg; - int scoperate; - int split; - int playoffset; - float audio_gain; - int audio_out; - int resume; - int frame_dstar; - int frame_x2tdma; - int frame_p25p1; - int frame_nxdn48; - int frame_nxdn96; - int frame_dmr; - int frame_provoice; - int mod_c4fm; - int mod_qpsk; - int mod_gfsk; - int uvquality; - int inverted_x2tdma; - int inverted_dmr; - int mod_threshold; - int ssize; - int msize; - int delay; - int use_cosine_filter; - int unmute_encrypted_p25; - int upsample; //!< force audio upsampling to 48k - int stereo; //!< double each audio sample to produce L+R channels -}; - -} // namespace dsdplus - -#endif /* DSDPLUS_DSD_OPTS_H_ */ diff --git a/dsdplus/dsd_state.cpp b/dsdplus/dsd_state.cpp deleted file mode 100644 index 2be8bedba..000000000 --- a/dsdplus/dsd_state.cpp +++ /dev/null @@ -1,140 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////////// -// Copyright (C) 2016 Edouard Griffiths, F4EXB. // -// // -// This program 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 as version 3 of the License, or // -// // -// This program 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 V3 for more details. // -// // -// You should have received a copy of the GNU General Public License // -// along with this program. If not, see . // -/////////////////////////////////////////////////////////////////////////////////// - -#include "dsd_state.h" - -namespace DSDplus -{ - -DSDState::DSDState() -{ - int i, j; - - repeat = 0; - - dibit_buf = (int *) malloc(sizeof(int) * 1000000); - memset(dibit_buf, 0, sizeof(int) * 200); - dibit_buf_p = dibit_buf + 200; - - audio_out_buf = (short *) malloc(sizeof(short) * 2 * 48000); // 1s of L+R S16LE samples - memset(audio_out_buf, 0, sizeof(short) * 2 * 48000); - audio_out_buf_p = audio_out_buf; - audio_out_nb_samples = 0; - audio_out_buf_size = 48000; // given in number of unique samples - - audio_out_float_buf = (float *) malloc(sizeof(float) * 960); // 1 frame of 160 samples upampled 6 times - memset(audio_out_float_buf, 0, sizeof(float) * 960); - audio_out_float_buf_p = audio_out_float_buf; - - audio_out_temp_buf_p = audio_out_temp_buf; - - audio_out_idx = 0; - audio_out_idx2 = 0; - - center = 0; - jitter = -1; - synctype = -1; - min = -15000; - max = 15000; - lmid = 0; - umid = 0; - minref = -12000; - maxref = 12000; - lastsample = 0; - - for (i = 0; i < 128; i++) - { - sbuf[i] = 0; - } - - sidx = 0; - - for (i = 0; i < 1024; i++) - { - maxbuf[i] = 15000; - } - - for (i = 0; i < 1024; i++) - { - minbuf[i] = -15000; - } - - midx = 0; - err_str[0] = 0; - sprintf(fsubtype, " "); - sprintf(ftype, " "); - symbolcnt = 0; - rf_mod = 0; - numflips = 0; - lastsynctype = -1; - lastp25type = 0; - offset = 0; - carrier = 0; - - for (i = 0; i < 25; i++) - { - for (j = 0; j < 16; j++) - { - tg[i][j] = 48; - } - } - - tgcount = 0; - lasttg = 0; - lastsrc = 0; - nac = 0; - errs = 0; - errs2 = 0; - mbe_file_type = -1; - optind = 0; - numtdulc = 0; - firstframe = 0; - sprintf(slot0light, " slot0 "); - sprintf(slot1light, " slot1 "); - aout_gain = 25; - memset(aout_max_buf, 0, sizeof(float) * 200); - aout_max_buf_p = aout_max_buf; - aout_max_buf_idx = 0; - samplesPerSymbol = 10; - symbolCenter = 4; - sprintf(algid, "________"); - sprintf(keyid, "________________"); - currentslot = 0; - cur_mp = (mbe_parms *) malloc(sizeof(mbe_parms)); - prev_mp = (mbe_parms *) malloc(sizeof(mbe_parms)); - prev_mp_enhanced = (mbe_parms *) malloc(sizeof(mbe_parms)); - mbe_initMbeParms(cur_mp, prev_mp, prev_mp_enhanced); - p25kid = 0; - - output_finished = 0; - output_offset = 0; - output_num_samples = 0; - output_samples = 0; - output_length = 0; - output_buffer = 0; -} - -DSDState::~DSDState() -{ - free(prev_mp_enhanced); - free(prev_mp); - free(cur_mp); - free(audio_out_float_buf); - free(audio_out_buf); - free(dibit_buf); -} - -} // namespace dsdplus diff --git a/dsdplus/dsd_state.h b/dsdplus/dsd_state.h deleted file mode 100644 index 394a71ac5..000000000 --- a/dsdplus/dsd_state.h +++ /dev/null @@ -1,112 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////////// -// Copyright (C) 2016 Edouard Griffiths, F4EXB. // -// // -// This program 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 as version 3 of the License, or // -// // -// This program 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 V3 for more details. // -// // -// You should have received a copy of the GNU General Public License // -// along with this program. If not, see . // -/////////////////////////////////////////////////////////////////////////////////// - -#ifndef DSDPLUS_DSD_STATE_H_ -#define DSDPLUS_DSD_STATE_H_ - -#include -#include -#include - -extern "C" { -#include -} - -namespace DSDplus -{ - -class DSDState -{ -public: - DSDState(); - ~DSDState(); - - int *dibit_buf; - int *dibit_buf_p; - int repeat; - short *audio_out_buf; //!< final result - short *audio_out_buf_p; - int audio_out_nb_samples; - int audio_out_buf_size; - float *audio_out_float_buf; //!< output of upsampler - float *audio_out_float_buf_p; - float audio_out_temp_buf[160]; //!< output of decoder - float *audio_out_temp_buf_p; - int audio_out_idx; - int audio_out_idx2; - int center; - int jitter; - int synctype; - int min; - int max; - int lmid; - int umid; - int minref; - int maxref; - int lastsample; - int sbuf[128]; - int sidx; - int maxbuf[1024]; - int minbuf[1024]; - int midx; - char err_str[64]; - char fsubtype[16]; - char ftype[16]; - int symbolcnt; - int rf_mod; - int numflips; - int lastsynctype; - int lastp25type; - int offset; - int carrier; - char tg[25][16]; - int tgcount; - int lasttg; - int lastsrc; - int nac; - int errs; - int errs2; - int mbe_file_type; - int optind; - int numtdulc; - int firstframe; - char slot0light[8]; - char slot1light[8]; - float aout_gain; - float aout_max_buf[200]; - float *aout_max_buf_p; - int aout_max_buf_idx; - int samplesPerSymbol; - int symbolCenter; - char algid[9]; - char keyid[17]; - int currentslot; - mbe_parms *cur_mp; - mbe_parms *prev_mp; - mbe_parms *prev_mp_enhanced; - int p25kid; - - short *output_buffer; - int output_offset; - float *output_samples; - int output_num_samples; - int output_length; - int output_finished; -}; - -} // namespace dsdplus - -#endif /* DSDPLUS_DSD_STATE_H_ */ diff --git a/dsdplus/dstar.cpp b/dsdplus/dstar.cpp deleted file mode 100644 index ef6c5e4ec..000000000 --- a/dsdplus/dstar.cpp +++ /dev/null @@ -1,392 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////////// -// Copyright (C) 2016 Edouard Griffiths, F4EXB. // -// // -// This program 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 as version 3 of the License, or // -// // -// This program 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 V3 for more details. // -// // -// You should have received a copy of the GNU General Public License // -// along with this program. If not, see . // -/////////////////////////////////////////////////////////////////////////////////// - -#include -#include "dstar.h" -#include "dsd_decoder.h" -#include "descramble.h" - -namespace DSDplus -{ - -const int DSDDstar::dW[72] = { - - // 0-11 - 0, 0, - 3, 2, - 1, 1, - 0, 0, - 1, 1, - 0, 0, - - // 12-23 - 3, 2, - 1, 1, - 3, 2, - 1, 1, - 0, 0, - 3, 2, - - // 24-35 - 0, 0, - 3, 2, - 1, 1, - 0, 0, - 1, 1, - 0, 0, - - // 36-47 - 3, 2, - 1, 1, - 3, 2, - 1, 1, - 0, 0, - 3, 2, - - // 48-59 - 0, 0, - 3, 2, - 1, 1, - 0, 0, - 1, 1, - 0, 0, - - // 60-71 - 3, 2, - 1, 1, - 3, 3, - 2, 1, - 0, 0, - 3, 3, -}; - -const int DSDDstar::dX[72] = { - - // 0-11 - 10, 22, - 11, 9, - 10, 22, - 11, 23, - 8, 20, - 9, 21, - - // 12-23 - 10, 8, - 9, 21, - 8, 6, - 7, 19, - 8, 20, - 9, 7, - - // 24-35 - 6, 18, - 7, 5, - 6, 18, - 7, 19, - 4, 16, - 5, 17, - - // 36-47 - 6, 4, - 5, 17, - 4, 2, - 3, 15, - 4, 16, - 5, 3, - - // 48-59 - 2, 14, - 3, 1, - 2, 14, - 3, 15, - 0, 12, - 1, 13, - - // 60-71 - 2, 0, - 1, 13, - 0, 12, - 10, 11, - 0, 12, - 1, 13, -}; - -DSDDstar::DSDDstar(DSDDecoder *dsdDecoder) : - m_dsdDecoder(dsdDecoder) -{ -} - -DSDDstar::~DSDDstar() -{ -} - -void DSDDstar::init() -{ - if (m_dsdDecoder->m_opts.errorbars == 1) { - fprintf(stderr, "e:"); - } - - if (m_dsdDecoder->m_state.synctype == 18) { - framecount = 0; - m_dsdDecoder->m_state.synctype = 6; - } else if (m_dsdDecoder->m_state.synctype == 19) { - framecount = 0; - m_dsdDecoder->m_state.synctype = 7; - } else { - framecount = 1; //just saw a sync frame; there should be 20 not 21 till the next - } - - sync_missed = 0; - bitbuffer = 0; - m_symbolIndex = 0; - m_symbolIndexHD = 0; -} - -void DSDDstar::initVoiceFrame() -{ - memset(ambe_fr, 0, 96); - // voice frame - w = dW; - x = dX; -} -void DSDDstar::initDataFrame() -{ -} - -void DSDDstar::process() -{ - if (m_symbolIndex < 72) // voice frame - { - if (m_symbolIndex == 0) { - initVoiceFrame(); - } - - processVoice(); - } - else if (m_symbolIndex < 97) // data frame - { - if (m_symbolIndex == 72) { - initDataFrame(); - } - - processData(); - } - else - { - m_dsdDecoder->m_fsmState = DSDDecoder::DSDLookForSync; // end - } - - m_symbolIndex++; -} - -void DSDDstar::processHD() -{ - int dibit = m_dsdDecoder->getDibit(); // get dibit from symbol and store it in HD cache - radioheaderbuffer[m_symbolIndexHD] = dibit; - - if (m_symbolIndexHD == 660-1) - { - dstar_header_decode(); - m_dsdDecoder->m_fsmState = DSDDecoder::DSDprocessDSTAR; // go to DSTAR - } - - m_symbolIndexHD++; -} - -void DSDDstar::processVoice() -{ - int dibit = m_dsdDecoder->getDibit(); // get dibit from symbol and store it in cache - m_dibitCache[m_symbolIndex] = dibit; - - if (m_symbolIndex == 72-1) // last dibit in voice frame - { - for (int i = 0; i < 72; i++) - { - int dibit = m_dibitCache[i]; - - bitbuffer <<= 1; - - if (dibit == 1) { - bitbuffer |= 0x01; - } - - if ((bitbuffer & 0x00FFFFFF) == 0x00AAB468) - { - // we're slipping bits - fprintf(stderr, "sync in voice after i=%d, restarting\n", i); - //ugh just start over - i = 0; - w = dW; - x = dX; - framecount = 1; - continue; - } - - ambe_fr[*w][*x] = (1 & dibit); - w++; - x++; - } - - m_dsdDecoder->m_mbeDecoder.processFrame(0, ambe_fr, 0); - } -} - -void DSDDstar::processData() -{ - bool terminate = false; - int dibit = m_dsdDecoder->getDibit(); // get dibit from symbol and store it in cache - m_dibitCache[m_symbolIndex] = dibit; - - if (m_symbolIndex == 97-1) // last dibit in data frame - { - for (int i = 73; i < 97; i++) - { - int dibit = m_dibitCache[i]; - - bitbuffer <<= 1; - - if (dibit == 1) { - bitbuffer |= 0x01; - } - - if ((bitbuffer & 0x00FFFFFF) == 0x00AAB468) - { - // looking if we're slipping bits - if (i != 96) - { - fprintf(stderr, "sync after i=%d\n", i); - break; - } - } - } - - slowdata[0] = (bitbuffer >> 16) & 0x000000FF; - slowdata[1] = (bitbuffer >> 8) & 0x000000FF; - slowdata[2] = (bitbuffer) & 0x000000FF; - slowdata[3] = 0; - - if ((bitbuffer & 0x00FFFFFF) == 0x00AAB468) - { - //We got sync! - //printf("Sync on framecount = %d\n", framecount); - sync_missed = 0; - } - else if ((bitbuffer & 0x00FFFFFF) == 0xAAAAAA) - { - //End of transmission - printf("End of transmission\n"); - terminate = true; - } - else if (framecount % 21 == 0) - { - printf("Missed sync on framecount = %d, value = %x/%x/%x\n", - framecount, slowdata[0], slowdata[1], slowdata[2]); - sync_missed++; - } - else if (framecount != 0 && (bitbuffer & 0x00FFFFFF) != 0x000000) - { - slowdata[0] ^= 0x70; - slowdata[1] ^= 0x4f; - slowdata[2] ^= 0x93; - //printf("unscrambled- %s",slowdata); - } - else if (framecount == 0) - { - //printf("never scrambled-%s\n",slowdata); - } - - if (terminate) - { - m_dsdDecoder->m_fsmState = DSDDecoder::DSDLookForSync; // end - } - else if (sync_missed < 3) - { - m_symbolIndex = 0; // restart a frame sequence - framecount++; - } - else - { - m_dsdDecoder->m_fsmState = DSDDecoder::DSDLookForSync; // end - } - } -} - -void DSDDstar::dstar_header_decode() -{ - int radioheaderbuffer2[660]; - unsigned char radioheader[41]; - int octetcount, bitcount, loop; - unsigned char bit2octet[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}; - unsigned int FCSinheader; - unsigned int FCScalculated; - int len; - - Descramble::scramble(radioheaderbuffer, radioheaderbuffer2); - Descramble::deinterleave(radioheaderbuffer2, radioheaderbuffer); - len = Descramble::FECdecoder(radioheaderbuffer, radioheaderbuffer2); - memset(radioheader, 0, 41); - - // note we receive 330 bits, but we only use 328 of them (41 octets) - // bits 329 and 330 are unused - octetcount = 0; - bitcount = 0; - - for (loop = 0; loop < 328; loop++) - { - if (radioheaderbuffer2[loop]) - { - radioheader[octetcount] |= bit2octet[bitcount]; - }; - - bitcount++; - - // increase octetcounter and reset bitcounter every 8 bits - if (bitcount >= 8) - { - octetcount++; - bitcount = 0; - } - } - - // print header - printf("\nDSTAR HEADER: "); - //printf("FLAG1: %02X - FLAG2: %02X - FLAG3: %02X\n", radioheader[0], - // radioheader[1], radioheader[2]); - printf("RPT 2: %c%c%c%c%c%c%c%c ", radioheader[3], radioheader[4], - radioheader[5], radioheader[6], radioheader[7], radioheader[8], - radioheader[9], radioheader[10]); - printf("RPT 1: %c%c%c%c%c%c%c%c ", radioheader[11], radioheader[12], - radioheader[13], radioheader[14], radioheader[15], radioheader[16], - radioheader[17], radioheader[18]); - printf("YOUR: %c%c%c%c%c%c%c%c ", radioheader[19], radioheader[20], - radioheader[21], radioheader[22], radioheader[23], radioheader[24], - radioheader[25], radioheader[26]); - printf("MY: %c%c%c%c%c%c%c%c/%c%c%c%c\n", radioheader[27], radioheader[28], - radioheader[29], radioheader[30], radioheader[31], radioheader[32], - radioheader[33], radioheader[34], radioheader[35], radioheader[36], - radioheader[37], radioheader[38]); - - //FCSinheader = ((radioheader[39] << 8) | radioheader[40]) & 0xFFFF; - //FCScalculated = calc_fcs((unsigned char*) radioheader, 39); - //printf("Check sum = %04X ", FCSinheader); - //if (FCSinheader == FCScalculated) { - // printf("(OK)\n"); - //} else { - // printf("(NOT OK- Calculated FCS = %04X)\n", FCScalculated); - //}; // end else - if -} - -} // namespace DSDplus diff --git a/dsdplus/dstar.h b/dsdplus/dstar.h deleted file mode 100644 index ebf56ad66..000000000 --- a/dsdplus/dstar.h +++ /dev/null @@ -1,68 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////////// -// Copyright (C) 2016 Edouard Griffiths, F4EXB. // -// // -// This program 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 as version 3 of the License, or // -// // -// This program 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 V3 for more details. // -// // -// You should have received a copy of the GNU General Public License // -// along with this program. If not, see . // -/////////////////////////////////////////////////////////////////////////////////// - -#ifndef DSDPLUS_DSTAR_H_ -#define DSDPLUS_DSTAR_H_ - -namespace DSDplus -{ - -class DSDDecoder; - -class DSDDstar -{ -public: - DSDDstar(DSDDecoder *dsdDecoder); - ~DSDDstar(); - - void init(); - void process(); - void processHD(); - -private: - void initVoiceFrame(); - void initDataFrame(); - void processVoice(); - void processData(); - void dstar_header_decode(); - - DSDDecoder *m_dsdDecoder; - int m_symbolIndex; //!< Current symbol index in non HD sequence - int m_symbolIndexHD; //!< Current symbol index in HD sequence - int m_dibitCache[97]; // has to handle a voice + data frame (97 dibits) - int m_dibitIndex; // index in dibit cache - - // DSTAR - char ambe_fr[4][24]; - unsigned char data[9]; - unsigned int bits[4]; - int framecount; - int sync_missed; - unsigned char slowdata[4]; - unsigned int bitbuffer; - const int *w, *x; - - // DSTAR-HD - int radioheaderbuffer[660]; - - // constants - static const int dW[72]; - static const int dX[72]; -}; - -} // namespace DSDplus - -#endif /* DSDPLUS_DSTAR_H_ */ diff --git a/plugins/channel/CMakeLists.txt b/plugins/channel/CMakeLists.txt index 7b0d70a9d..5d866bfa4 100644 --- a/plugins/channel/CMakeLists.txt +++ b/plugins/channel/CMakeLists.txt @@ -10,6 +10,6 @@ add_subdirectory(udpsrc) add_subdirectory(demodwfm) add_subdirectory(chanalyzer) -if(LIBMBE_FOUND) +if(LIBDSDCC_FOUND AND LIBMBE_FOUND) add_subdirectory(demoddsd) -endif(LIBMBE_FOUND) +endif(LIBDSDCC_FOUND AND LIBMBE_FOUND) diff --git a/plugins/channel/demoddsd/CMakeLists.txt b/plugins/channel/demoddsd/CMakeLists.txt index 600f419f1..aaaa4f573 100644 --- a/plugins/channel/demoddsd/CMakeLists.txt +++ b/plugins/channel/demoddsd/CMakeLists.txt @@ -20,8 +20,8 @@ set(dsddemod_FORMS include_directories( . - ../../../dsdplus ${CMAKE_CURRENT_BINARY_DIR} + ${LIBDSDCC_INCLUDE_DIR} ${LIBMBE_INCLUDE_DIR} ) @@ -41,7 +41,7 @@ add_library(demoddsd SHARED target_link_libraries(demoddsd ${QT_LIBRARIES} sdrbase - dsdplus + ${LIBDSDCC_LIBRARIES} ${LIBMBE_LIBRARY} ) diff --git a/plugins/channel/demoddsd/dsddecoder.cpp b/plugins/channel/demoddsd/dsddecoder.cpp index 95936f0ae..3a3e82b4e 100644 --- a/plugins/channel/demoddsd/dsddecoder.cpp +++ b/plugins/channel/demoddsd/dsddecoder.cpp @@ -22,36 +22,12 @@ DSDDecoder::DSDDecoder() { - DSDplus::DSDOpts *dsdopts = m_decoder.getOpts(); - DSDplus::DSDState *dsdstate = m_decoder.getState(); - - dsdopts->split = 1; - dsdopts->upsample = 1; // force upsampling of audio to 48k - dsdopts->playoffset = 0; - dsdopts->delay = 0; - - // Initialize with auto-detect: - dsdopts->frame_dstar = 1; - dsdopts->frame_x2tdma = 1; - dsdopts->frame_p25p1 = 1; - dsdopts->frame_nxdn48 = 0; - dsdopts->frame_nxdn96 = 1; - dsdopts->frame_dmr = 1; - dsdopts->frame_provoice = 0; - - dsdopts->uvquality = 3; // This is gr-dsd default - dsdopts->verbose = 2; // This is gr-dsd default - dsdopts->errorbars = 1; // This is gr-dsd default - - // Initialize with auto detection of modulation optimization: - dsdopts->mod_c4fm = 1; - dsdopts->mod_qpsk = 1; - dsdopts->mod_gfsk = 1; - dsdstate->rf_mod = 0; - - dsdstate->output_offset = 0; - dsdopts->upsample = 1; - dsdopts->stereo = 1; + m_decoder.setQuiet(); + m_decoder.setUpsampling(6); // force upsampling of audio to 48k + m_decoder.setStereo(true); // force copy to L+R channels + m_decoder.setDecodeMode(DSDcc::DSDDecoder::DSDDecodeAuto, true); // Initialize with auto-detect + m_decoder.setUvQuality(3); // This is gr-dsd default + m_decoder.setModulationOptimizations(DSDcc::DSDDecoder::DSDModulationOptimAuto); // Initialize with auto detection of modulation optimization: } DSDDecoder::~DSDDecoder() diff --git a/plugins/channel/demoddsd/dsddecoder.h b/plugins/channel/demoddsd/dsddecoder.h index 20177358c..1a2f4f955 100644 --- a/plugins/channel/demoddsd/dsddecoder.h +++ b/plugins/channel/demoddsd/dsddecoder.h @@ -33,7 +33,7 @@ public: void resetAudio() { m_decoder.resetAudio(); } private: - DSDplus::DSDDecoder m_decoder; + DSDcc::DSDDecoder m_decoder; }; #endif /* PLUGINS_CHANNEL_DEMODDSD_DSDDECODER_H_ */