├── .gitignore ├── CMakeLists.txt ├── README.md ├── cmake └── Modules │ ├── CMakeParseArgumentsCopy.cmake │ ├── FindCppUnit.cmake │ ├── FindGnuradioAudio.cmake │ ├── FindGnuradioCore.cmake │ ├── FindGnuradioFCD.cmake │ ├── FindGnuradioFCDPP.cmake │ ├── FindGnuradioIQBalance.cmake │ ├── FindGnuradioRuntime.cmake │ ├── FindGnuradioUHD.cmake │ ├── FindGrOsmoSDR.cmake │ ├── FindLibDSD.cmake │ ├── FindLibHackRF.cmake │ ├── FindLibMiriSDR.cmake │ ├── FindLibOP25.cmake │ ├── FindLibOP25Repeater.cmake │ ├── FindLibOsmoSDR.cmake │ ├── FindLibRTLSDR.cmake │ ├── FindLibbladeRF.cmake │ ├── FindUHD.cmake │ ├── GrComponent.cmake │ ├── GrMiscUtils.cmake │ ├── GrPlatform.cmake │ ├── GrPython.cmake │ ├── GrSwig.cmake │ ├── GrTest.cmake │ └── GrVersion.cmake ├── debug.grc ├── debug_recorder.cc ├── debug_recorder.h ├── main.cc ├── nonstop_wavfile_sink.h ├── nonstop_wavfile_sink_impl.cc ├── nonstop_wavfile_sink_impl.h ├── p25_decoder.cc ├── p25_decoder.h ├── tes.wav ├── test3.wav └── wavfile.cc /.gitignore: -------------------------------------------------------------------------------- 1 | CMakeCache.txt 2 | CMakeFiles 3 | CMakeScripts 4 | Makefile 5 | cmake_install.cmake 6 | install_manifest.txt 7 | 2016 8 | decoder -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright 2011 Free Software Foundation, Inc. 2 | # 3 | # This file is part of GNU Radio 4 | # 5 | # GNU Radio is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 3, or (at your option) 8 | # any later version. 9 | # 10 | # GNU Radio is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with GNU Radio; see the file COPYING. If not, write to 17 | # the Free Software Foundation, Inc., 51 Franklin Street, 18 | # Boston, MA 02110-1301, USA. 19 | 20 | 21 | 22 | cmake_minimum_required(VERSION 2.6) 23 | project(Trunk-Recorder CXX C) 24 | 25 | set(CMAKE_BUILD_TYPE Debug) 26 | 27 | list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules) 28 | 29 | 30 | ######################################################################## 31 | # Install directories 32 | ######################################################################## 33 | include(GrPlatform) #define LIB_SUFFIX 34 | set(GR_RUNTIME_DIR bin) 35 | set(GR_LIBRARY_DIR lib${LIB_SUFFIX}) 36 | set(GR_INCLUDE_DIR include/howto) 37 | set(GR_DATA_DIR share) 38 | set(GR_PKG_DATA_DIR ${GR_DATA_DIR}/${CMAKE_PROJECT_NAME}) 39 | set(GR_DOC_DIR ${GR_DATA_DIR}/doc) 40 | set(GR_PKG_DOC_DIR ${GR_DOC_DIR}/${CMAKE_PROJECT_NAME}) 41 | set(GR_CONF_DIR etc) 42 | set(GR_PKG_CONF_DIR ${GR_CONF_DIR}/${CMAKE_PROJECT_NAME}/conf.d) 43 | set(GR_LIBEXEC_DIR libexec) 44 | set(GR_PKG_LIBEXEC_DIR ${GR_LIBEXEC_DIR}/${CMAKE_PROJECT_NAME}) 45 | set(GRC_BLOCKS_DIR ${GR_PKG_DATA_DIR}/grc/blocks) 46 | 47 | ######################################################################## 48 | # Find gnuradio build dependencies 49 | ######################################################################## 50 | 51 | # Search for GNU Radio and its components and versions. Add any 52 | # components required to the list of GR_REQUIRED_COMPONENTS (in all 53 | # caps such as FILTER or FFT) and change the version to the minimum 54 | # API compatible version required. 55 | set(GR_REQUIRED_COMPONENTS RUNTIME PMT AUDIO BLOCKS FILTER DIGITAL ANALOG) 56 | find_package(Gnuradio "3.7.2" REQUIRED) 57 | 58 | 59 | 60 | 61 | ######################################################################## 62 | # Find build dependencies 63 | ######################################################################## 64 | 65 | 66 | #find_package(LibOsmoSDR) 67 | #find_package(LibRTLSDR) 68 | #find_package(LibMiriSDR) 69 | find_package(GrOsmoSDR) 70 | find_package(LibHackRF) 71 | #find_package(LibbladeRF) 72 | find_package(LibOP25) 73 | find_package(LibOP25Repeater) 74 | find_package(GnuradioUHD) 75 | find_package(UHD) 76 | 77 | 78 | if(NOT GNURADIO_RUNTIME_FOUND) 79 | message(FATAL_ERROR "GnuRadio Runtime required to build " ${CMAKE_PROJECT_NAME}) 80 | endif() 81 | 82 | 83 | 84 | ######################################################################## 85 | # Setup boost 86 | ######################################################################## 87 | MESSAGE(STATUS "Configuring Boost C++ Libraries...") 88 | 89 | # Although not required on my system, some users have linking issues without 90 | SET(BOOST_REQUIRED_COMPONENTS 91 | thread 92 | system 93 | program_options 94 | filesystem 95 | log 96 | ) 97 | 98 | if(UNIX AND NOT BOOST_ROOT AND EXISTS "/usr/lib64") 99 | list(APPEND BOOST_LIBRARYDIR "/usr/lib64") #fedora 64-bit fix 100 | endif(UNIX AND NOT BOOST_ROOT AND EXISTS "/usr/lib64") 101 | 102 | set(Boost_ADDITIONAL_VERSIONS 103 | "1.35.0" "1.35" "1.36.0" "1.36" "1.37.0" "1.37" "1.38.0" "1.38" "1.39.0" "1.39" 104 | "1.40.0" "1.40" "1.41.0" "1.41" "1.42.0" "1.42" "1.43.0" "1.43" "1.44.0" "1.44" 105 | "1.45.0" "1.45" "1.46.0" "1.46" "1.47.0" "1.47" "1.48.0" "1.48" "1.49.0" "1.49" 106 | "1.50.0" "1.50" "1.51.0" "1.51" "1.52.0" "1.52" "1.53.0" "1.53" "1.54.0" "1.54" 107 | "1.55.0" "1.55" "1.56.0" "1.56" "1.57.0" "1.57" "1.58.0" "1.58" "1.59.0" "1.59" 108 | "1.60.0" "1.60" "1.61.0" "1.61" "1.62.0" "1.62" "1.63.0" "1.63" "1.64.0" "1.64" 109 | "1.65.0" "1.65" "1.66.0" "1.66" "1.67.0" "1.67" "1.68.0" "1.68" "1.69.0" "1.69" 110 | ) 111 | 112 | find_package(Boost COMPONENTS ${BOOST_REQUIRED_COMPONENTS}) 113 | 114 | if(NOT Boost_FOUND) 115 | message(FATAL_ERROR "Boost required to build " ${CMAKE_PROJECT_NAME}) 116 | endif() 117 | 118 | ADD_DEFINITIONS(-DBOOST_ALL_DYN_LINK) 119 | 120 | 121 | 122 | 123 | 124 | ######################################################################## 125 | # Setup the include and linker paths 126 | ######################################################################## 127 | include_directories( 128 | ${Boost_INCLUDE_DIRS} 129 | ${GNURADIO_RUNTIME_INCLUDE_DIRS} 130 | ${GROSMOSDR_INCLUDE_DIR} 131 | #./lib/ 132 | ) 133 | 134 | link_directories( 135 | ${Boost_LIBRARY_DIRS} 136 | ${GNURADIO_RUNTIME_LIBRARY_DIRS} 137 | ${GROSMOSDR_LIBRARIES} 138 | ${GNURADIO_UHD_LIBRARIES} 139 | ${UHD_LIBRARIES} 140 | #/usr/local/lib/ 141 | #/usr/local/lib/pyton2.7/dist-packages/gnuradio/ 142 | ) 143 | 144 | #set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall") 145 | set(CMAKE_CXX_FLAGS_DEBUG "-pthread -Wall") 146 | 147 | 148 | add_executable(decoder main.cc p25_decoder.cc nonstop_wavfile_sink_impl.cc) 149 | target_link_libraries(decoder ${GNURADIO_RUNTIME_LIBRARIES} ${GNURADIO_PMT_LIBRARIES} ${GNURADIO_FILTER_LIBRARIES} ${GNURADIO_DIGITAL_LIBRARIES} ${GNURADIO_ANALOG_LIBRARIES} ${GNURADIO_AUDIO_LIBRARIES} ${GNURADIO_UHD_LIBRARIES} ${UHD_LIBRARIES} ${GNURADIO_BLOCKS_LIBRARIES} ${GROSMOSDR_LIBRARIES} ${Boost_LIBRARIES} ${LIBOP25_LIBRARIES} ${LIBOP25_REPEATER_LIBRARIES} itpp ncurses menu) 150 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Trunk Recorder 2 | ================= 3 | 4 | Trunk Recorder is able to record the calls on a trunked radio system. It uses 1 or more Software Defined Radios (SDRs) to do. The SDRs capture large swatches of RF and then use software to process what was recieved. GNURadio is used to do this processing and provides lots of convienent RF blocks that can be pieced together to do complex RF processing. Right now it can only record one Trunked System at a time. 5 | 6 | Trunk Recorder currently supports the following: 7 | - P25 & SmartNet Trunking Systems 8 | - SDRs that use the OsmoSDR source ( HackRF, RTL - TV Dongles, BladeRF, and more) 9 | - Ettus USRP 10 | - P25 Phase 1 & Analog voice 11 | 12 | I have tested things on both Unbuntu 14.04 & OSX 10.10. I have been using it with an Ettus b200, and a HackRF Jawbreaker. 13 | 14 | ##Compile 15 | 16 | ###Requirements 17 | - GNURadio 3.7 18 | - GR-DSD (The version I forked) 19 | - OP-25 20 | 21 | **GNURadio** 22 | 23 | It is important to have a very recent version of GnuRadio (GR). There was a bug in earlier versions that messed up the smartnet trunking. Make sure your install is up to date if you are having trouble deoding smartnet trunking. 24 | 25 | If you are running Linux, the easiest way to install GR is by using [Pybombs](http://gnuradio.org/redmine/projects/pybombs/wiki/QuickStart). After you have installed using pybombs, make sure you setup you Environment variables. In your pybombs directory, run: `./pybombs env` and then load them `source $prefix/setup_env.sh`, with $prefix being the directory you installed GR in. 26 | 27 | If you are on OSX, the [MacPorts](https://gnuradio.org/redmine/projects/gnuradio/wiki/MacInstall) install has worked for me. 28 | 29 | **GR-DSD** 30 | 31 | I made a fork of this code to allow for more statistics to be collected and the also make usre multiple copies can run at once. It has a few dependencies: 32 | - Lib Snd File: `sudo apt-get install libsndfile1-dev` 33 | - ITPP: `sudo apt-get install libitpp-dev` 34 | - CMake: `sudo apt-get install cmake` 35 | - Boost: `sudo apt-get install libboost-dev libboost-system-dev libboost-thread-dev` 36 | - CppUnit: `sudo apt-get install libcppunit-dev` 37 | 38 | Now download, compile and install the code. Make sure you have loaded the environment variables that point to the GR libaries first. 39 | ``` 40 | git clone https://github.com/robotastic/gr-dsd.git 41 | cd gr-dsd 42 | cmake -DCMAKE_PREFIX_PATH=/path/to/GR/install . 43 | make 44 | sudo make install 45 | sudo ldconfig 46 | ``` 47 | Note - if you did not install GR in the standard spot, use the -DCMAKE_PREFIX_PATH to point to it. 48 | 49 | **OP25** 50 | 51 | This should be as simple doing `./pybombs install gr-op25`. On OSX, it is quite a bit trickier. Right now the code is not patched for OSX installs. I will try to put together an easy way to do an OSX install in the future. 52 | 53 | ###Trunk Recorder 54 | Okay, with that out of the way, here is how you compile Trunk Recorder: 55 | ``` 56 | git clone https://github.com/robotastic/trunk-recorder.git 57 | cd trunk-recorder 58 | cmake -DCMAKE_PREFIX_PATH=/path/to/GR/install . 59 | make 60 | ``` 61 | Hopefully this should compile with no errors. 62 | 63 | ##Configure 64 | Configuring Trunk Recorder and getting things setup can be rather complex. I am looking to make things simpler in the future. 65 | 66 | **config.json** 67 | 68 | This file is used to configure how Trunk Recorder is setup. It defines the SDRs that are available and the trunk system that will be recorded. The following is an example for my local system in DC, using an Ettus B200: 69 | 70 | ``` 71 | { 72 | "sources": [{ 73 | "center": 857000000.0, 74 | "rate": 8000000.0, 75 | "error": 0, 76 | "gain": 40, 77 | "antenna": "TX/RX", 78 | "digitalRecorders": 2, 79 | "driver": "usrp", 80 | "device": "" 81 | }], 82 | "system": { 83 | "control_channels": [854862500], 84 | "type": "smartnet" 85 | }, 86 | "talkgroupsFile": "ChanList.csv" 87 | } 88 | ``` 89 | Here are the different arguments: 90 | - **sources** - an array of JSON objects that define the different SDRs available and how to configure them 91 | - **center** - the center frequency in Hz to tune the SDR to 92 | - **rate** - the sampling rate to set the SDR to, in samples / second 93 | - **error** - the tuning error for the SDR in Hz. This is the difference between the target value and the actual value. So if you wanted to recv 856MHz but you had to tune your SDR to 855MHz to actually recieve it, you would set this to -1000000. You should also probably get a new SDR. 94 | - **gain** - the RF gain to set the SDR to. Use a program like GQRX to find a good value. 95 | - **ifGain** - [hackrf only] sets the ifgain. 96 | - **bbGain** - [hackrf only] sets the bbgain. 97 | - **antenna** - [usrp] lets you select which antenna jack to user on devices that support it 98 | - **digitalRecorders** - the number of Digital Recorders to have attached to this source. This is essentaully the number of simultanious call you can record at the same time in the frequency range that this SDR will be tuned to. It is limited by the CPU power of the machine. Some experimentation might be needed to find the appropriate number. It will use DSD or OP25 to decode the P25 CAI voice. 99 | - **analogRecorders** - the number of Analog Recorder to have attached to this source. This is the same as Digital Recorders except for Analog Voice channels. 100 | - **driver** - the GNURadio block you wish to use for the SDR. The options are *usrp* & *osmosdr*. 101 | - **device** - the serial number for the device. You only need to do this if there are more than one. 102 | - **system** - This object defines the trunking system that will be recorded 103 | - **control_channels** - an array of the control channel frequencies for the system, in Hz. Right now, only the first value is used. 104 | - **type** - the type of trunking system. The options are *smartnet* & *p25*. 105 | - **talkgroupsFile** - this is a CSV file that provides information about the talkgroups. It determines whether a talkgroup is analog or digital, and what priority it should have. 106 | 107 | **ChanList.csv** 108 | 109 | This file provides info on the different talkgroups in a trunking system. A lot of this info can be found on the Radio Reference website. You need to be a site member to download the table for your system. If you are not, try clicking on the "List All in one table" link, selecting everything in the table and copying it into Excel or a spreadsheet. 110 | 111 | You will have to add an additional column that adds a priority for each talkgroup. You need that number of recorders available to record a call at that priority. So, 1 is the highest, you would need 2 recorders available to record a priority 2, 3 record for a priority 3 and so on. 112 | 113 | The Trunk Record program really only uses the priority information and the Dec Talkgroup ID. The Website uses the same file though to help display information about each talkgroup. 114 | 115 | Here are the column headers and some sample data: 116 | 117 | | DEC | HEX | Mode | Alpha Tag | Description | Tag | Group | Priority | 118 | |-----|-----|------|-----------|-------------|-----|-------|----------| 119 | |101 | 065 | D | DCFD 01 Disp | 01 Dispatch | Fire Dispatch | Fire | 1 | 120 | |2227 | 8b3 | D | DC StcarYard | Streetcar Yard | Transportation | Services | 3 | 121 | 122 | ###Multiple SDR 123 | Most trunk systems use a wide range of spectrum. Often a more powerful SDR is needed to have enough bandwidth to capture all of the potential channels that a system may broadcast on. However it is possible to use multiple SDRs working together to cover all of the channels. This means that you can use a bunch of cheap RTL-SDR to capture an entire system. 124 | 125 | In addition to being able to use a cheaper SDR, it also helps with performance. When a single SDR is used, each of the Recorders gets fed all of the sampled signal. Each Recorder needs to cut down the multi-megasamples per second into a small 12.5Khz sliver. When you use multiple SDRs, each SDR is capturing only partial slice of the system so the Recorders have to cut down a much smaller amount of sample to get to the sliver they are interested in. This menans that you can have a lot more recorders running! 126 | 127 | To user mutliple SDRs, simply define additional Sources in the Source array. The `confing-multi-rtl.json.sample` has an example of how to do this. In order to tell the different SDRs apart and make sure they get the right error correction value, give them a serial number using the `rtl_eeprom -s` command and then specifying that number in the `device` setting for that Source. 128 | 129 | ###How Trunking Works 130 | Here is a little background on trunking radio systems, for those not familiar. In a Trunking system, one of the radio channels is set aside for to manage the assignment of radio channels to talkgroups. When someone wants to talk, they send a message on the control channel. The system then assigns them a channel and sends a Channel Grant message on the control channel. This lets the talker know what channel to transmit on and anyone who is a member of the talkgroup know that they should listen to that channel. 131 | 132 | In order to follow all of the transmissions, this system constantly listens to and decodes the control channel. When a channel is granted to a talkgroup, the system creates a monitoring process. This process will start to process and decode the part of the radio spectrum for that channel which the SDR is already pulling in. 133 | 134 | No message is transmitted on the control channel when a talkgroup’s conversation is over. So instead the monitoring process keeps track of transmissions and if there has been no activity for 5 seconds, it ends the recording. 135 | 136 | 137 | 138 | 139 | -------------------------------------------------------------------------------- /cmake/Modules/CMakeParseArgumentsCopy.cmake: -------------------------------------------------------------------------------- 1 | # CMAKE_PARSE_ARGUMENTS( args...) 2 | # 3 | # CMAKE_PARSE_ARGUMENTS() is intended to be used in macros or functions for 4 | # parsing the arguments given to that macro or function. 5 | # It processes the arguments and defines a set of variables which hold the 6 | # values of the respective options. 7 | # 8 | # The argument contains all options for the respective macro, 9 | # i.e. keywords which can be used when calling the macro without any value 10 | # following, like e.g. the OPTIONAL keyword of the install() command. 11 | # 12 | # The argument contains all keywords for this macro 13 | # which are followed by one value, like e.g. DESTINATION keyword of the 14 | # install() command. 15 | # 16 | # The argument contains all keywords for this macro 17 | # which can be followed by more than one value, like e.g. the TARGETS or 18 | # FILES keywords of the install() command. 19 | # 20 | # When done, CMAKE_PARSE_ARGUMENTS() will have defined for each of the 21 | # keywords listed in , and 22 | # a variable composed of the given 23 | # followed by "_" and the name of the respective keyword. 24 | # These variables will then hold the respective value from the argument list. 25 | # For the keywords this will be TRUE or FALSE. 26 | # 27 | # All remaining arguments are collected in a variable 28 | # _UNPARSED_ARGUMENTS, this can be checked afterwards to see whether 29 | # your macro was called with unrecognized parameters. 30 | # 31 | # As an example here a my_install() macro, which takes similar arguments as the 32 | # real install() command: 33 | # 34 | # function(MY_INSTALL) 35 | # set(options OPTIONAL FAST) 36 | # set(oneValueArgs DESTINATION RENAME) 37 | # set(multiValueArgs TARGETS CONFIGURATIONS) 38 | # cmake_parse_arguments(MY_INSTALL "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) 39 | # ... 40 | # 41 | # Assume my_install() has been called like this: 42 | # my_install(TARGETS foo bar DESTINATION bin OPTIONAL blub) 43 | # 44 | # After the cmake_parse_arguments() call the macro will have set the following 45 | # variables: 46 | # MY_INSTALL_OPTIONAL = TRUE 47 | # MY_INSTALL_FAST = FALSE (this option was not used when calling my_install() 48 | # MY_INSTALL_DESTINATION = "bin" 49 | # MY_INSTALL_RENAME = "" (was not used) 50 | # MY_INSTALL_TARGETS = "foo;bar" 51 | # MY_INSTALL_CONFIGURATIONS = "" (was not used) 52 | # MY_INSTALL_UNPARSED_ARGUMENTS = "blub" (no value expected after "OPTIONAL" 53 | # 54 | # You can the continue and process these variables. 55 | # 56 | # Keywords terminate lists of values, e.g. if directly after a one_value_keyword 57 | # another recognized keyword follows, this is interpreted as the beginning of 58 | # the new option. 59 | # E.g. my_install(TARGETS foo DESTINATION OPTIONAL) would result in 60 | # MY_INSTALL_DESTINATION set to "OPTIONAL", but MY_INSTALL_DESTINATION would 61 | # be empty and MY_INSTALL_OPTIONAL would be set to TRUE therefor. 62 | 63 | #============================================================================= 64 | # Copyright 2010 Alexander Neundorf 65 | # 66 | # Distributed under the OSI-approved BSD License (the "License"); 67 | # see accompanying file Copyright.txt for details. 68 | # 69 | # This software is distributed WITHOUT ANY WARRANTY; without even the 70 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 71 | # See the License for more information. 72 | #============================================================================= 73 | # (To distribute this file outside of CMake, substitute the full 74 | # License text for the above reference.) 75 | 76 | 77 | if(__CMAKE_PARSE_ARGUMENTS_INCLUDED) 78 | return() 79 | endif() 80 | set(__CMAKE_PARSE_ARGUMENTS_INCLUDED TRUE) 81 | 82 | 83 | function(CMAKE_PARSE_ARGUMENTS prefix _optionNames _singleArgNames _multiArgNames) 84 | # first set all result variables to empty/FALSE 85 | foreach(arg_name ${_singleArgNames} ${_multiArgNames}) 86 | set(${prefix}_${arg_name}) 87 | endforeach(arg_name) 88 | 89 | foreach(option ${_optionNames}) 90 | set(${prefix}_${option} FALSE) 91 | endforeach(option) 92 | 93 | set(${prefix}_UNPARSED_ARGUMENTS) 94 | 95 | set(insideValues FALSE) 96 | set(currentArgName) 97 | 98 | # now iterate over all arguments and fill the result variables 99 | foreach(currentArg ${ARGN}) 100 | list(FIND _optionNames "${currentArg}" optionIndex) # ... then this marks the end of the arguments belonging to this keyword 101 | list(FIND _singleArgNames "${currentArg}" singleArgIndex) # ... then this marks the end of the arguments belonging to this keyword 102 | list(FIND _multiArgNames "${currentArg}" multiArgIndex) # ... then this marks the end of the arguments belonging to this keyword 103 | 104 | if(${optionIndex} EQUAL -1 AND ${singleArgIndex} EQUAL -1 AND ${multiArgIndex} EQUAL -1) 105 | if(insideValues) 106 | if("${insideValues}" STREQUAL "SINGLE") 107 | set(${prefix}_${currentArgName} ${currentArg}) 108 | set(insideValues FALSE) 109 | elseif("${insideValues}" STREQUAL "MULTI") 110 | list(APPEND ${prefix}_${currentArgName} ${currentArg}) 111 | endif() 112 | else(insideValues) 113 | list(APPEND ${prefix}_UNPARSED_ARGUMENTS ${currentArg}) 114 | endif(insideValues) 115 | else() 116 | if(NOT ${optionIndex} EQUAL -1) 117 | set(${prefix}_${currentArg} TRUE) 118 | set(insideValues FALSE) 119 | elseif(NOT ${singleArgIndex} EQUAL -1) 120 | set(currentArgName ${currentArg}) 121 | set(${prefix}_${currentArgName}) 122 | set(insideValues "SINGLE") 123 | elseif(NOT ${multiArgIndex} EQUAL -1) 124 | set(currentArgName ${currentArg}) 125 | set(${prefix}_${currentArgName}) 126 | set(insideValues "MULTI") 127 | endif() 128 | endif() 129 | 130 | endforeach(currentArg) 131 | 132 | # propagate the result variables to the caller: 133 | foreach(arg_name ${_singleArgNames} ${_multiArgNames} ${_optionNames}) 134 | set(${prefix}_${arg_name} ${${prefix}_${arg_name}} PARENT_SCOPE) 135 | endforeach(arg_name) 136 | set(${prefix}_UNPARSED_ARGUMENTS ${${prefix}_UNPARSED_ARGUMENTS} PARENT_SCOPE) 137 | 138 | endfunction(CMAKE_PARSE_ARGUMENTS _options _singleArgs _multiArgs) 139 | -------------------------------------------------------------------------------- /cmake/Modules/FindCppUnit.cmake: -------------------------------------------------------------------------------- 1 | # http://www.cmake.org/pipermail/cmake/2006-October/011446.html 2 | # Modified to use pkg config and use standard var names 3 | 4 | # 5 | # Find the CppUnit includes and library 6 | # 7 | # This module defines 8 | # CPPUNIT_INCLUDE_DIR, where to find tiff.h, etc. 9 | # CPPUNIT_LIBRARIES, the libraries to link against to use CppUnit. 10 | # CPPUNIT_FOUND, If false, do not try to use CppUnit. 11 | 12 | INCLUDE(FindPkgConfig) 13 | PKG_CHECK_MODULES(PC_CPPUNIT "cppunit") 14 | 15 | FIND_PATH(CPPUNIT_INCLUDE_DIRS 16 | NAMES cppunit/TestCase.h 17 | HINTS ${PC_CPPUNIT_INCLUDE_DIR} 18 | PATHS 19 | /usr/local/include 20 | /usr/include 21 | ) 22 | 23 | FIND_LIBRARY(CPPUNIT_LIBRARIES 24 | NAMES cppunit 25 | HINTS ${PC_CPPUNIT_LIBDIR} 26 | PATHS 27 | ${CPPUNIT_INCLUDE_DIRS}/../lib 28 | /usr/local/lib 29 | /usr/lib 30 | ) 31 | 32 | LIST(APPEND CPPUNIT_LIBRARIES ${CMAKE_DL_LIBS}) 33 | 34 | INCLUDE(FindPackageHandleStandardArgs) 35 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(CPPUNIT DEFAULT_MSG CPPUNIT_LIBRARIES CPPUNIT_INCLUDE_DIRS) 36 | MARK_AS_ADVANCED(CPPUNIT_LIBRARIES CPPUNIT_INCLUDE_DIRS) 37 | -------------------------------------------------------------------------------- /cmake/Modules/FindGnuradioAudio.cmake: -------------------------------------------------------------------------------- 1 | INCLUDE(FindPkgConfig) 2 | PKG_CHECK_MODULES(PC_GNURADIO_AUDIO gnuradio-audio) 3 | 4 | FIND_PATH( 5 | GNURADIO_AUDIO_INCLUDE_DIRS 6 | NAMES gnuradio/gr_audio_api.h 7 | HINTS $ENV{GNURADIO_AUDIO_DIR}/include 8 | ${PC_GNURADIO_AUDIO_INCLUDEDIR} 9 | PATHS /usr/local/include 10 | /usr/include 11 | ) 12 | 13 | FIND_LIBRARY( 14 | GNURADIO_AUDIO_LIBRARIES 15 | NAMES gnuradio-audio 16 | HINTS $ENV{GNURADIO_AUDIO_DIR}/lib 17 | ${PC_GNURADIO_AUDIO_LIBDIR} 18 | PATHS /usr/local/lib 19 | /usr/local/lib64 20 | /usr/lib 21 | /usr/lib64 22 | ) 23 | 24 | INCLUDE(FindPackageHandleStandardArgs) 25 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(GNURADIO_AUDIO DEFAULT_MSG GNURADIO_AUDIO_LIBRARIES GNURADIO_AUDIO_INCLUDE_DIRS) 26 | MARK_AS_ADVANCED(GNURADIO_AUDIO_LIBRARIES GNURADIO_AUDIO_INCLUDE_DIRS) 27 | -------------------------------------------------------------------------------- /cmake/Modules/FindGnuradioCore.cmake: -------------------------------------------------------------------------------- 1 | INCLUDE(FindPkgConfig) 2 | PKG_CHECK_MODULES(PC_GNURADIO_CORE gnuradio-core) 3 | 4 | FIND_PATH( 5 | GNURADIO_CORE_INCLUDE_DIRS 6 | NAMES gr_core_api.h 7 | HINTS $ENV{GNURADIO_CORE_DIR}/include/gnuradio 8 | ${PC_GNURADIO_CORE_INCLUDEDIR} 9 | ${CMAKE_INSTALL_PREFIX}/include/gnuradio 10 | PATHS /usr/local/include/gnuradio 11 | /usr/include/gnuradio 12 | ) 13 | 14 | FIND_LIBRARY( 15 | GNURADIO_CORE_LIBRARIES 16 | NAMES gnuradio-core 17 | HINTS $ENV{GNURADIO_CORE_DIR}/lib 18 | ${PC_GNURADIO_CORE_LIBDIR} 19 | ${CMAKE_INSTALL_PREFIX}/lib64 20 | ${CMAKE_INSTALL_PREFIX}/lib 21 | PATHS /usr/local/lib 22 | /usr/local/lib64 23 | /usr/lib 24 | /usr/lib64 25 | ) 26 | 27 | INCLUDE(FindPackageHandleStandardArgs) 28 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(GNURADIO_CORE DEFAULT_MSG GNURADIO_CORE_LIBRARIES GNURADIO_CORE_INCLUDE_DIRS) 29 | MARK_AS_ADVANCED(GNURADIO_CORE_LIBRARIES GNURADIO_CORE_INCLUDE_DIRS) 30 | -------------------------------------------------------------------------------- /cmake/Modules/FindGnuradioFCD.cmake: -------------------------------------------------------------------------------- 1 | INCLUDE(FindPkgConfig) 2 | PKG_CHECK_MODULES(PC_GNURADIO_FCD gnuradio-fcd) 3 | 4 | FIND_PATH( 5 | GNURADIO_FCD_INCLUDE_DIRS 6 | NAMES gnuradio/fcd_api.h 7 | HINTS $ENV{GNURADIO_FCD_DIR}/include 8 | ${PC_GNURADIO_FCD_INCLUDEDIR} 9 | PATHS /usr/local/include 10 | /usr/include 11 | ) 12 | 13 | FIND_LIBRARY( 14 | GNURADIO_FCD_LIBRARIES 15 | NAMES gnuradio-fcd 16 | HINTS $ENV{GNURADIO_FCD_DIR}/lib 17 | ${PC_GNURADIO_FCD_LIBDIR} 18 | PATHS /usr/local/lib 19 | /usr/local/lib64 20 | /usr/lib 21 | /usr/lib64 22 | ) 23 | 24 | if(GNURADIO_FCD_INCLUDE_DIRS AND GNURADIO_FCD_LIBRARIES) 25 | set(GNURADIO_FCD_FOUND TRUE CACHE INTERNAL "gnuradio-fcd found") 26 | message(STATUS "Found gnuradio-fcd: ${GNURADIO_FCD_INCLUDE_DIRS}, ${GNURADIO_FCD_LIBRARIES}") 27 | else(GNURADIO_FCD_INCLUDE_DIRS AND GNURADIO_FCD_LIBRARIES) 28 | set(GNURADIO_FCD_FOUND FALSE CACHE INTERNAL "gnuradio-fcd found") 29 | message(STATUS "gnuradio-fcd not found.") 30 | endif(GNURADIO_FCD_INCLUDE_DIRS AND GNURADIO_FCD_LIBRARIES) 31 | 32 | INCLUDE(FindPackageHandleStandardArgs) 33 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(GNURADIO_FCD DEFAULT_MSG GNURADIO_FCD_LIBRARIES GNURADIO_FCD_INCLUDE_DIRS) 34 | MARK_AS_ADVANCED(GNURADIO_FCD_LIBRARIES GNURADIO_FCD_INCLUDE_DIRS) 35 | -------------------------------------------------------------------------------- /cmake/Modules/FindGnuradioFCDPP.cmake: -------------------------------------------------------------------------------- 1 | INCLUDE(FindPkgConfig) 2 | PKG_CHECK_MODULES(PC_GNURADIO_FCDPP gnuradio-fcdproplus) 3 | 4 | FIND_PATH( 5 | GNURADIO_FCDPP_INCLUDE_DIRS 6 | NAMES fcdproplus/api.h 7 | HINTS $ENV{GNURADIO_FCDPP_DIR}/include 8 | ${PC_GNURADIO_FCDPP_INCLUDEDIR} 9 | PATHS /usr/local/include 10 | /usr/include 11 | ) 12 | 13 | FIND_LIBRARY( 14 | GNURADIO_FCDPP_LIBRARIES 15 | NAMES gnuradio-fcdproplus 16 | HINTS $ENV{GNURADIO_FCDPP_DIR}/lib 17 | ${PC_GNURADIO_FCDPP_LIBDIR} 18 | PATHS /usr/local/lib 19 | /usr/local/lib64 20 | /usr/lib 21 | /usr/lib64 22 | ) 23 | 24 | if(GNURADIO_FCDPP_INCLUDE_DIRS AND GNURADIO_FCDPP_LIBRARIES) 25 | set(GNURADIO_FCDPP_FOUND TRUE CACHE INTERNAL "gnuradio-fcdproplus found") 26 | message(STATUS "Found gnuradio-fcdproplus: ${GNURADIO_FCDPP_INCLUDE_DIRS}, ${GNURADIO_FCDPP_LIBRARIES}") 27 | else(GNURADIO_FCDPP_INCLUDE_DIRS AND GNURADIO_FCDPP_LIBRARIES) 28 | set(GNURADIO_FCDPP_FOUND FALSE CACHE INTERNAL "gnuradio-fcdproplus found") 29 | message(STATUS "gnuradio-fcdproplus not found.") 30 | endif(GNURADIO_FCDPP_INCLUDE_DIRS AND GNURADIO_FCDPP_LIBRARIES) 31 | 32 | INCLUDE(FindPackageHandleStandardArgs) 33 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(GNURADIO_FCDPP DEFAULT_MSG GNURADIO_FCDPP_LIBRARIES GNURADIO_FCDPP_INCLUDE_DIRS) 34 | MARK_AS_ADVANCED(GNURADIO_FCDPP_LIBRARIES GNURADIO_FCDPP_INCLUDE_DIRS) 35 | -------------------------------------------------------------------------------- /cmake/Modules/FindGnuradioIQBalance.cmake: -------------------------------------------------------------------------------- 1 | INCLUDE(FindPkgConfig) 2 | PKG_CHECK_MODULES(PC_GNURADIO_IQBALANCE gnuradio-iqbalance) 3 | 4 | FIND_PATH( 5 | GNURADIO_IQBALANCE_INCLUDE_DIRS 6 | NAMES iqbalance_api.h 7 | HINTS $ENV{GNURADIO_IQBALANCE_DIR}/include/iqbalance 8 | ${PC_GNURADIO_IQBALANCE_INCLUDEDIR} 9 | ${CMAKE_INSTALL_PREFIX}/include/iqbalance 10 | PATHS /usr/local/include/iqbalance 11 | /usr/include/iqbalance 12 | ) 13 | 14 | FIND_LIBRARY( 15 | GNURADIO_IQBALANCE_LIBRARIES 16 | NAMES gnuradio-iqbalance 17 | HINTS $ENV{GNURADIO_IQBALANCE_DIR}/lib 18 | ${PC_GNURADIO_IQBALANCE_LIBDIR} 19 | ${CMAKE_INSTALL_PREFIX}/lib64 20 | ${CMAKE_INSTALL_PREFIX}/lib 21 | PATHS /usr/local/lib 22 | /usr/local/lib64 23 | /usr/lib 24 | /usr/lib64 25 | ) 26 | 27 | INCLUDE(FindPackageHandleStandardArgs) 28 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(GNURADIO_IQBALANCE DEFAULT_MSG GNURADIO_IQBALANCE_LIBRARIES GNURADIO_IQBALANCE_INCLUDE_DIRS) 29 | MARK_AS_ADVANCED(GNURADIO_IQBALANCE_LIBRARIES GNURADIO_IQBALANCE_INCLUDE_DIRS) 30 | -------------------------------------------------------------------------------- /cmake/Modules/FindGnuradioRuntime.cmake: -------------------------------------------------------------------------------- 1 | INCLUDE(FindPkgConfig) 2 | PKG_CHECK_MODULES(PC_GNURADIO_RUNTIME gnuradio-runtime) 3 | 4 | if(PC_GNURADIO_RUNTIME_FOUND) 5 | # look for include files 6 | FIND_PATH( 7 | GNURADIO_RUNTIME_INCLUDE_DIRS 8 | NAMES gnuradio/top_block.h 9 | HINTS $ENV{GNURADIO_RUNTIME_DIR}/include 10 | ${PC_GNURADIO_RUNTIME_INCLUDE_DIRS} 11 | ${CMAKE_INSTALL_PREFIX}/include 12 | PATHS /usr/local/include 13 | /usr/include 14 | ) 15 | 16 | # look for libs 17 | FIND_LIBRARY( 18 | GNURADIO_RUNTIME_LIBRARIES 19 | NAMES gnuradio-runtime 20 | HINTS $ENV{GNURADIO_RUNTIME_DIR}/lib 21 | ${PC_GNURADIO_RUNTIME_LIBDIR} 22 | ${CMAKE_INSTALL_PREFIX}/lib/ 23 | ${CMAKE_INSTALL_PREFIX}/lib64/ 24 | PATHS /usr/local/lib 25 | /usr/local/lib64 26 | /usr/lib 27 | /usr/lib64 28 | ) 29 | 30 | set(GNURADIO_RUNTIME_FOUND ${PC_GNURADIO_RUNTIME_FOUND}) 31 | endif(PC_GNURADIO_RUNTIME_FOUND) 32 | 33 | INCLUDE(FindPackageHandleStandardArgs) 34 | # do not check GNURADIO_RUNTIME_INCLUDE_DIRS, is not set when default include path us used. 35 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(GNURADIO_RUNTIME DEFAULT_MSG GNURADIO_RUNTIME_LIBRARIES) 36 | MARK_AS_ADVANCED(GNURADIO_RUNTIME_LIBRARIES GNURADIO_RUNTIME_INCLUDE_DIRS) 37 | -------------------------------------------------------------------------------- /cmake/Modules/FindGnuradioUHD.cmake: -------------------------------------------------------------------------------- 1 | INCLUDE(FindPkgConfig) 2 | PKG_CHECK_MODULES(PC_GNURADIO_UHD gnuradio-uhd) 3 | 4 | FIND_PATH( 5 | GNURADIO_UHD_INCLUDE_DIRS 6 | NAMES gnuradio/gr_uhd_api.h 7 | HINTS $ENV{GNURADIO_UHD_DIR}/include 8 | ${PC_GNURADIO_UHD_INCLUDEDIR} 9 | PATHS /usr/local/include 10 | /usr/include 11 | ) 12 | 13 | FIND_LIBRARY( 14 | GNURADIO_UHD_LIBRARIES 15 | NAMES gnuradio-uhd 16 | HINTS $ENV{GNURADIO_UHD_DIR}/lib 17 | ${PC_GNURADIO_UHD_LIBDIR} 18 | PATHS /usr/local/lib 19 | /usr/local/lib64 20 | /usr/lib 21 | /usr/lib64 22 | ) 23 | 24 | if(GNURADIO_UHD_INCLUDE_DIRS AND GNURADIO_UHD_LIBRARIES) 25 | set(GNURADIO_UHD_FOUND TRUE CACHE INTERNAL "gnuradio-uhd found") 26 | message(STATUS "Found gnuradio-uhd: ${GNURADIO_UHD_INCLUDE_DIRS}, ${GNURADIO_UHD_LIBRARIES}") 27 | else(GNURADIO_UHD_INCLUDE_DIRS AND GNURADIO_UHD_LIBRARIES) 28 | set(GNURADIO_UHD_FOUND FALSE CACHE INTERNAL "gnuradio-uhd found") 29 | message(STATUS "gnuradio-uhd not found.") 30 | endif(GNURADIO_UHD_INCLUDE_DIRS AND GNURADIO_UHD_LIBRARIES) 31 | 32 | INCLUDE(FindPackageHandleStandardArgs) 33 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(GNURADIO_UHD DEFAULT_MSG GNURADIO_UHD_LIBRARIES GNURADIO_UHD_INCLUDE_DIRS) 34 | MARK_AS_ADVANCED(GNURADIO_UHD_LIBRARIES GNURADIO_UHD_INCLUDE_DIRS) 35 | -------------------------------------------------------------------------------- /cmake/Modules/FindGrOsmoSDR.cmake: -------------------------------------------------------------------------------- 1 | # Tries to find gr-osmosdr. 2 | # 3 | # Usage of this module as follows: 4 | # 5 | # find_package(GrOsmoSDR) 6 | # 7 | # Variables used by this module, they can change the default behaviour and need 8 | # to be set before calling find_package: 9 | # 10 | # GrOsmoSDR_ROOT_DIR Set this variable to the root installation of 11 | # gr-osmosdr if the module has problems finding 12 | # the proper installation path. 13 | # 14 | # Variables defined by this module: 15 | # 16 | # GROSMOSDR_FOUND System has gr-osmosdr libs/headers 17 | # GROSMOSDR_LIBRARIES The gr-osmosdr libraries (gnuradio-osmosdr) 18 | # GROSMOSDR_INCLUDE_DIR The location of gr-osmosdr headers 19 | 20 | pkg_check_modules (GROSMOSDR_PKG gnuradio-osmosdr) 21 | 22 | FIND_PATH(GROSMOSDR_INCLUDE_DIR 23 | NAMES osmosdr/source_c.h 24 | osmosdr/api.h 25 | HINTS ${GROSMOSDR_PKG_INCLUDE_DIRS} 26 | PATHS /usr/local/include 27 | /usr/include 28 | ) 29 | 30 | 31 | find_library(GROSMOSDR_LIBRARIES 32 | NAMES gnuradio-osmosdr 33 | HINTS ${GROSMOSDR_PKG_LIBRARY_DIRS} 34 | PATHS /usr/local/lib 35 | /usr/lib 36 | ) 37 | 38 | 39 | include(FindPackageHandleStandardArgs) 40 | find_package_handle_standard_args( 41 | GrOsmoSDR 42 | DEFAULT_MSG 43 | GROSMOSDR_LIBRARIES 44 | GROSMOSDR_INCLUDE_DIR 45 | ) 46 | 47 | 48 | mark_as_advanced( 49 | GROSMOSDR_LIBRARIES 50 | GROSMOSDR_INCLUDE_DIR 51 | ) 52 | 53 | message(STATUS "Pkg: ${LIBDSD_PKG}, ${LIBDSD_PKG_INCLUDE_DIRS}, ${LIBDSD_PKG_LIBRARY_DIRS}") 54 | message(STATUS "Vars: ${GROSMOSDR_INCLUDE_DIR}, ${GROSMOSDR_LIBRARIES}") 55 | -------------------------------------------------------------------------------- /cmake/Modules/FindLibDSD.cmake: -------------------------------------------------------------------------------- 1 | INCLUDE(FindPkgConfig) 2 | if(NOT LIBDSD_FOUND) 3 | pkg_check_modules (LIBDSD_PKG libdsd) 4 | find_path(LIBDSD_INCLUDE_DIR 5 | NAMES dsd/dsd_api.h 6 | HINTS ${LIBDSD_PKG_INCLUDE_DIRS} 7 | PATHS /usr/include 8 | /usr/local/include 9 | ) 10 | 11 | find_library(LIBDSD_LIBRARIES 12 | NAMES gr-dsd 13 | HINTS ${LIBDSD_PKG_LIBRARY_DIRS} 14 | PATHS /usr/lib 15 | /usr/local/lib 16 | ) 17 | message(STATUS "Pkg: ${LIBDSD_PKG}, ${LIBDSD_PKG_INCLUDE_DIRS}, ${LIBDSD_PKG_LIBRARY_DIRS}") 18 | message(STATUS "Vars: ${LIBDSD_INCLUDE_DIR}, ${LIBDSD_LIBRARIES}") 19 | if(LIBDSD_INCLUDE_DIR AND LIBDSD_LIBRARIES) 20 | set(LIBDSD_FOUND TRUE CACHE INTERNAL "libdsd found") 21 | message(STATUS "Found libdsd: ${LIBDSD_INCLUDE_DIR}, ${LIBDSD_LIBRARIES}") 22 | else(LIBDSD_INCLUDE_DIR AND LIBDSD_LIBRARIES) 23 | set(LIBDSD_FOUND FALSE CACHE INTERNAL "libdsd found") 24 | message(STATUS "libdsd not found.") 25 | endif(LIBDSD_INCLUDE_DIR AND LIBDSD_LIBRARIES) 26 | 27 | mark_as_advanced(LIBDSD_INCLUDE_DIR LIBDSD_LIBRARIES) 28 | 29 | endif(NOT LIBDSD_FOUND) 30 | -------------------------------------------------------------------------------- /cmake/Modules/FindLibHackRF.cmake: -------------------------------------------------------------------------------- 1 | INCLUDE(FindPkgConfig) 2 | PKG_CHECK_MODULES(PC_LIBHACKRF libhackrf) 3 | 4 | FIND_PATH( 5 | LIBHACKRF_INCLUDE_DIRS 6 | NAMES libhackrf/hackrf.h 7 | HINTS $ENV{LIBHACKRF_DIR}/include 8 | ${PC_LIBHACKRF_INCLUDEDIR} 9 | PATHS /usr/local/include 10 | /usr/include 11 | ) 12 | 13 | FIND_LIBRARY( 14 | LIBHACKRF_LIBRARIES 15 | NAMES hackrf 16 | HINTS $ENV{LIBHACKRF_DIR}/lib 17 | ${PC_LIBHACKRF_LIBDIR} 18 | PATHS /usr/local/lib 19 | /usr/lib 20 | ) 21 | 22 | INCLUDE(FindPackageHandleStandardArgs) 23 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBHACKRF DEFAULT_MSG LIBHACKRF_LIBRARIES LIBHACKRF_INCLUDE_DIRS) 24 | MARK_AS_ADVANCED(LIBHACKRF_LIBRARIES LIBHACKRF_INCLUDE_DIRS) 25 | -------------------------------------------------------------------------------- /cmake/Modules/FindLibMiriSDR.cmake: -------------------------------------------------------------------------------- 1 | if(NOT LIBMIRISDR_FOUND) 2 | pkg_check_modules (LIBMIRISDR_PKG libmirisdr) 3 | find_path(LIBMIRISDR_INCLUDE_DIR NAMES mirisdr.h 4 | PATHS 5 | ${LIBMIRISDR_PKG_INCLUDE_DIRS} 6 | /usr/include 7 | /usr/local/include 8 | ) 9 | 10 | find_library(LIBMIRISDR_LIBRARIES NAMES mirisdr 11 | PATHS 12 | ${LIBMIRISDR_PKG_LIBRARY_DIRS} 13 | /usr/lib 14 | /usr/local/lib 15 | ) 16 | 17 | if(LIBMIRISDR_INCLUDE_DIR AND LIBMIRISDR_LIBRARIES) 18 | set(LIBMIRISDR_FOUND TRUE CACHE INTERNAL "libmirisdr found") 19 | message(STATUS "Found libmirisdr: ${LIBMIRISDR_INCLUDE_DIR}, ${LIBMIRISDR_LIBRARIES}") 20 | else(LIBMIRISDR_INCLUDE_DIR AND LIBMIRISDR_LIBRARIES) 21 | set(LIBMIRISDR_FOUND FALSE CACHE INTERNAL "libmirisdr found") 22 | message(STATUS "libmirisdr not found.") 23 | endif(LIBMIRISDR_INCLUDE_DIR AND LIBMIRISDR_LIBRARIES) 24 | 25 | mark_as_advanced(LIBMIRISDR_INCLUDE_DIR LIBMIRISDR_LIBRARIES) 26 | 27 | endif(NOT LIBMIRISDR_FOUND) 28 | -------------------------------------------------------------------------------- /cmake/Modules/FindLibOP25.cmake: -------------------------------------------------------------------------------- 1 | INCLUDE(FindPkgConfig) 2 | if(NOT LIBOP25_FOUND) 3 | pkg_check_modules (LIBOP25_PKG libop25) 4 | find_path(LIBOP25_INCLUDE_DIR 5 | NAMES op25/api.h 6 | HINTS $ENV{GNURADIO_RUNTIME_DIR}/include 7 | ${PC_GNURADIO_RUNTIME_INCLUDE_DIRS} 8 | ${CMAKE_INSTALL_PREFIX}/include 9 | PATHS /usr/local/include 10 | /usr/include 11 | ) 12 | 13 | find_library(LIBOP25_LIBRARIES 14 | NAMES gnuradio-op25 15 | HINTS $ENV{GNURADIO_RUNTIME_DIR}/lib 16 | ${PC_GNURADIO_RUNTIME_LIBDIR} 17 | ${CMAKE_INSTALL_PREFIX}/lib/ 18 | ${CMAKE_INSTALL_PREFIX}/lib64/ 19 | PATHS /usr/local/lib 20 | /usr/local/lib64 21 | /usr/lib 22 | /usr/lib64 23 | ) 24 | message(STATUS "Pkg: ${LIBOP25_PKG}, ${LIBOP25_PKG_INCLUDE_DIRS}, ${LIBOP25_PKG_LIBRARY_DIRS}") 25 | message(STATUS "Vars: ${LIBOP25_INCLUDE_DIR}, ${LIBOP25_LIBRARIES}") 26 | if(LIBOP25_INCLUDE_DIR AND LIBOP25_LIBRARIES) 27 | set(LIBOP25_FOUND TRUE CACHE INTERNAL "libop25 found") 28 | message(STATUS "Found libop25: ${LIBOP25_INCLUDE_DIR}, ${LIBOP25_LIBRARIES}") 29 | else(LIBOP25_INCLUDE_DIR AND LIBOP25_LIBRARIES) 30 | set(LIBOP25_FOUND FALSE CACHE INTERNAL "libop25 found") 31 | message(STATUS "libop25 not found.") 32 | endif(LIBOP25_INCLUDE_DIR AND LIBOP25_LIBRARIES) 33 | 34 | mark_as_advanced(LIBOP25_INCLUDE_DIR LIBOP25_LIBRARIES) 35 | 36 | endif(NOT LIBOP25_FOUND) 37 | -------------------------------------------------------------------------------- /cmake/Modules/FindLibOP25Repeater.cmake: -------------------------------------------------------------------------------- 1 | INCLUDE(FindPkgConfig) 2 | 3 | if(NOT LIBOP25_REPEATER_FOUND) 4 | pkg_check_modules (LIBOP25_REPEATER_PKG libop25_repeater) 5 | FIND_PATH(LIBOP25_REPEATER_INCLUDE_DIR 6 | NAMES op25_repeater/api.h 7 | HINTS $ENV{GNURADIO_RUNTIME_DIR}/include 8 | ${PC_GNURADIO_RUNTIME_INCLUDE_DIRS} 9 | ${CMAKE_INSTALL_PREFIX}/include 10 | PATHS /usr/local/include 11 | /usr/include 12 | ) 13 | 14 | find_library(LIBOP25_REPEATER_LIBRARIES 15 | NAMES gnuradio-op25_repeater 16 | HINTS $ENV{GNURADIO_RUNTIME_DIR}/lib 17 | ${PC_GNURADIO_RUNTIME_LIBDIR} 18 | ${CMAKE_INSTALL_PREFIX}/lib/ 19 | ${CMAKE_INSTALL_PREFIX}/lib64/ 20 | PATHS /usr/local/lib 21 | /usr/local/lib64 22 | /usr/lib 23 | /usr/lib64 24 | ) 25 | 26 | message(STATUS "Pkg: ${LIBOP25_REPEATER_PKG}, ${LIBOP25_REPEATER_PKG_INCLUDE_DIRS}, ${LIBOP25_REPEATER_PKG_LIBRARY_DIRS}") 27 | message(STATUS "Vars: ${LIBOP25_REPEATER_INCLUDE_DIR}, ${LIBOP25_REPEATER_LIBRARIES}") 28 | if(LIBOP25_REPEATER_INCLUDE_DIR AND LIBOP25_REPEATER_LIBRARIES) 29 | set(LIBOP25_REPEATER_FOUND TRUE CACHE INTERNAL "libop25 repeater found") 30 | message(STATUS "Found libop25 repeater: ${LIBOP25_REPEATER_INCLUDE_DIR}, ${LIBOP25_REPEATER_LIBRARIES}") 31 | else(LIBOP25_REPEATER_INCLUDE_DIR AND LIBOP25_REPEATER_LIBRARIES) 32 | set(LIBOP25_REPEATER_FOUND FALSE CACHE INTERNAL "libop25 repeater found") 33 | message(STATUS "libop25 repeater not found.") 34 | endif(LIBOP25_REPEATER_INCLUDE_DIR AND LIBOP25_REPEATER_LIBRARIES) 35 | 36 | mark_as_advanced(LIBOP25_REPEATER_INCLUDE_DIR LIBOP25_REPEATER_LIBRARIES) 37 | 38 | endif(NOT LIBOP25_REPEATER_FOUND) 39 | -------------------------------------------------------------------------------- /cmake/Modules/FindLibOsmoSDR.cmake: -------------------------------------------------------------------------------- 1 | # Tries to find libosmosdr. 2 | # 3 | # Usage of this module as follows: 4 | # 5 | # find_package(LibOsmoSDR) 6 | # 7 | # 8 | # Variables defined by this module: 9 | # 10 | # LIBOSMOSDR_FOUND System has libosmosdr libs/headers 11 | # LIBOSMOSDR_LIBRARIES The libosmosdr libraries 12 | # LIBOSMOSDR_INCLUDE_DIR The location of libosmosdr headers 13 | 14 | 15 | if(NOT LIBOSMOSDR_FOUND) 16 | pkg_check_modules (LIBOSMOSDR_PKG libosmosdr) 17 | find_path(LIBOSMOSDR_INCLUDE_DIR NAMES osmosdr.h 18 | PATHS 19 | ${LIBOSMOSDR_PKG_INCLUDE_DIRS} 20 | /usr/include 21 | /usr/local/include 22 | ) 23 | 24 | find_library(LIBOSMOSDR_LIBRARIES NAMES osmosdr 25 | PATHS 26 | ${LIBOSMOSDR_PKG_LIBRARY_DIRS} 27 | /usr/lib 28 | /usr/local/lib 29 | ) 30 | 31 | if(LIBOSMOSDR_INCLUDE_DIR AND LIBOSMOSDR_LIBRARIES) 32 | set(LIBOSMOSDR_FOUND TRUE CACHE INTERNAL "libosmosdr found") 33 | message(STATUS "Found libosmosdr: ${LIBOSMOSDR_INCLUDE_DIR}, ${LIBOSMOSDR_LIBRARIES}") 34 | else(LIBOSMOSDR_INCLUDE_DIR AND LIBOSMOSDR_LIBRARIES) 35 | set(LIBOSMOSDR_FOUND FALSE CACHE INTERNAL "libosmosdr found") 36 | message(STATUS "libosmosdr not found.") 37 | endif(LIBOSMOSDR_INCLUDE_DIR AND LIBOSMOSDR_LIBRARIES) 38 | 39 | mark_as_advanced(LIBOSMOSDR_INCLUDE_DIR LIBOSMOSDR_LIBRARIES) 40 | 41 | endif(NOT LIBOSMOSDR_FOUND) 42 | -------------------------------------------------------------------------------- /cmake/Modules/FindLibRTLSDR.cmake: -------------------------------------------------------------------------------- 1 | if(NOT LIBRTLSDR_FOUND) 2 | pkg_check_modules (LIBRTLSDR_PKG librtlsdr) 3 | find_path(LIBRTLSDR_INCLUDE_DIR NAMES rtl-sdr.h 4 | PATHS 5 | ${LIBRTLSDR_PKG_INCLUDE_DIRS} 6 | /usr/include 7 | /usr/local/include 8 | ) 9 | 10 | find_library(LIBRTLSDR_LIBRARIES NAMES rtlsdr 11 | PATHS 12 | ${LIBRTLSDR_PKG_LIBRARY_DIRS} 13 | /usr/lib 14 | /usr/local/lib 15 | ) 16 | 17 | if(LIBRTLSDR_INCLUDE_DIR AND LIBRTLSDR_LIBRARIES) 18 | set(LIBRTLSDR_FOUND TRUE CACHE INTERNAL "librtlsdr found") 19 | message(STATUS "Found librtlsdr: ${LIBRTLSDR_INCLUDE_DIR}, ${LIBRTLSDR_LIBRARIES}") 20 | else(LIBRTLSDR_INCLUDE_DIR AND LIBRTLSDR_LIBRARIES) 21 | set(LIBRTLSDR_FOUND FALSE CACHE INTERNAL "librtlsdr found") 22 | message(STATUS "librtlsdr not found.") 23 | endif(LIBRTLSDR_INCLUDE_DIR AND LIBRTLSDR_LIBRARIES) 24 | 25 | mark_as_advanced(LIBRTLSDR_INCLUDE_DIR LIBRTLSDR_LIBRARIES) 26 | 27 | endif(NOT LIBRTLSDR_FOUND) 28 | -------------------------------------------------------------------------------- /cmake/Modules/FindLibbladeRF.cmake: -------------------------------------------------------------------------------- 1 | if(NOT LIBBLADERF_FOUND) 2 | pkg_check_modules (LIBBLADERF_PKG libbladeRF) 3 | find_path(LIBBLADERF_INCLUDE_DIR NAMES libbladeRF.h 4 | PATHS 5 | ${LIBBLADERF_PKG_INCLUDE_DIRS} 6 | /usr/include 7 | /usr/local/include 8 | ) 9 | 10 | find_library(LIBBLADERF_LIBRARIES NAMES bladeRF 11 | PATHS 12 | ${LIBBLADERF_PKG_LIBRARY_DIRS} 13 | /usr/lib 14 | /usr/local/lib 15 | ) 16 | 17 | if(LIBBLADERF_INCLUDE_DIR AND LIBBLADERF_LIBRARIES) 18 | set(LIBBLADERF_FOUND TRUE CACHE INTERNAL "libbladeRF found") 19 | message(STATUS "Found libbladeRF: ${LIBBLADERF_INCLUDE_DIR}, ${LIBBLADERF_LIBRARIES}") 20 | else(LIBBLADERF_INCLUDE_DIR AND LIBBLADERF_LIBRARIES) 21 | set(LIBBLADERF_FOUND FALSE CACHE INTERNAL "libbladeRF found") 22 | message(STATUS "libbladeRF not found.") 23 | endif(LIBBLADERF_INCLUDE_DIR AND LIBBLADERF_LIBRARIES) 24 | 25 | mark_as_advanced(LIBBLADERF_INCLUDE_DIR LIBBLADERF_LIBRARIES) 26 | 27 | endif(NOT LIBBLADERF_FOUND) 28 | -------------------------------------------------------------------------------- /cmake/Modules/FindUHD.cmake: -------------------------------------------------------------------------------- 1 | ######################################################################## 2 | # Find the library for the USRP Hardware Driver 3 | ######################################################################## 4 | 5 | INCLUDE(FindPkgConfig) 6 | PKG_CHECK_MODULES(PC_UHD uhd) 7 | 8 | FIND_PATH( 9 | UHD_INCLUDE_DIRS 10 | NAMES uhd/config.hpp 11 | HINTS $ENV{UHD_DIR}/include 12 | ${PC_UHD_INCLUDEDIR} 13 | PATHS /usr/local/include 14 | /usr/include 15 | ) 16 | 17 | FIND_LIBRARY( 18 | UHD_LIBRARIES 19 | NAMES uhd 20 | HINTS $ENV{UHD_DIR}/lib 21 | ${PC_UHD_LIBDIR} 22 | PATHS /usr/local/lib 23 | /usr/lib 24 | ) 25 | 26 | INCLUDE(FindPackageHandleStandardArgs) 27 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(UHD DEFAULT_MSG UHD_LIBRARIES UHD_INCLUDE_DIRS) 28 | MARK_AS_ADVANCED(UHD_LIBRARIES UHD_INCLUDE_DIRS) 29 | -------------------------------------------------------------------------------- /cmake/Modules/GrComponent.cmake: -------------------------------------------------------------------------------- 1 | # Copyright 2010-2011 Free Software Foundation, Inc. 2 | # 3 | # This file is part of GNU Radio 4 | # 5 | # GNU Radio is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 3, or (at your option) 8 | # any later version. 9 | # 10 | # GNU Radio is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with GNU Radio; see the file COPYING. If not, write to 17 | # the Free Software Foundation, Inc., 51 Franklin Street, 18 | # Boston, MA 02110-1301, USA. 19 | 20 | if(DEFINED __INCLUDED_GR_COMPONENT_CMAKE) 21 | return() 22 | endif() 23 | set(__INCLUDED_GR_COMPONENT_CMAKE TRUE) 24 | 25 | set(_gr_enabled_components "" CACHE INTERNAL "" FORCE) 26 | set(_gr_disabled_components "" CACHE INTERNAL "" FORCE) 27 | 28 | if(NOT DEFINED ENABLE_DEFAULT) 29 | set(ENABLE_DEFAULT ON) 30 | message(STATUS "") 31 | message(STATUS "The build system will automatically enable all components.") 32 | message(STATUS "Use -DENABLE_DEFAULT=OFF to disable components by default.") 33 | endif() 34 | 35 | ######################################################################## 36 | # Register a component into the system 37 | # - name: canonical component name 38 | # - var: variable for enabled status 39 | # - argn: list of dependencies 40 | ######################################################################## 41 | function(GR_REGISTER_COMPONENT name var) 42 | include(CMakeDependentOption) 43 | message(STATUS "") 44 | message(STATUS "Configuring ${name} support...") 45 | foreach(dep ${ARGN}) 46 | message(STATUS " Dependency ${dep} = ${${dep}}") 47 | endforeach(dep) 48 | 49 | #if the user set the var to force, we note this 50 | if("${${var}}" STREQUAL "FORCE") 51 | set(${var} ON) 52 | set(var_force TRUE) 53 | else() 54 | set(var_force FALSE) 55 | endif() 56 | 57 | #rewrite the dependency list so that deps that are also components use the cached version 58 | unset(comp_deps) 59 | foreach(dep ${ARGN}) 60 | list(FIND _gr_enabled_components ${dep} dep_enb_index) 61 | list(FIND _gr_disabled_components ${dep} dep_dis_index) 62 | if (${dep_enb_index} EQUAL -1 AND ${dep_dis_index} EQUAL -1) 63 | list(APPEND comp_deps ${dep}) 64 | else() 65 | list(APPEND comp_deps ${dep}_cached) #is a component, use cached version 66 | endif() 67 | endforeach(dep) 68 | 69 | #setup the dependent option for this component 70 | CMAKE_DEPENDENT_OPTION(${var} "enable ${name} support" ${ENABLE_DEFAULT} "${comp_deps}" OFF) 71 | set(${var} "${${var}}" PARENT_SCOPE) 72 | set(${var}_cached "${${var}}" CACHE INTERNAL "" FORCE) 73 | 74 | #force was specified, but the dependencies were not met 75 | if(NOT ${var} AND var_force) 76 | message(FATAL_ERROR "user force-enabled ${name} but configuration checked failed") 77 | endif() 78 | 79 | #append the component into one of the lists 80 | if(${var}) 81 | message(STATUS " Enabling ${name} support.") 82 | list(APPEND _gr_enabled_components ${name}) 83 | else(${var}) 84 | message(STATUS " Disabling ${name} support.") 85 | list(APPEND _gr_disabled_components ${name}) 86 | endif(${var}) 87 | message(STATUS " Override with -D${var}=ON/OFF") 88 | 89 | #make components lists into global variables 90 | set(_gr_enabled_components ${_gr_enabled_components} CACHE INTERNAL "" FORCE) 91 | set(_gr_disabled_components ${_gr_disabled_components} CACHE INTERNAL "" FORCE) 92 | endfunction(GR_REGISTER_COMPONENT) 93 | 94 | ######################################################################## 95 | # Print the registered component summary 96 | ######################################################################## 97 | function(GR_PRINT_COMPONENT_SUMMARY) 98 | message(STATUS "") 99 | message(STATUS "######################################################") 100 | message(STATUS "# gr-osmosdr enabled components ") 101 | message(STATUS "######################################################") 102 | foreach(comp ${_gr_enabled_components}) 103 | message(STATUS " * ${comp}") 104 | endforeach(comp) 105 | 106 | message(STATUS "") 107 | message(STATUS "######################################################") 108 | message(STATUS "# gr-osmosdr disabled components ") 109 | message(STATUS "######################################################") 110 | foreach(comp ${_gr_disabled_components}) 111 | message(STATUS " * ${comp}") 112 | endforeach(comp) 113 | 114 | message(STATUS "") 115 | endfunction(GR_PRINT_COMPONENT_SUMMARY) 116 | -------------------------------------------------------------------------------- /cmake/Modules/GrMiscUtils.cmake: -------------------------------------------------------------------------------- 1 | # Copyright 2010-2011 Free Software Foundation, Inc. 2 | # 3 | # This file is part of GNU Radio 4 | # 5 | # GNU Radio is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 3, or (at your option) 8 | # any later version. 9 | # 10 | # GNU Radio is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with GNU Radio; see the file COPYING. If not, write to 17 | # the Free Software Foundation, Inc., 51 Franklin Street, 18 | # Boston, MA 02110-1301, USA. 19 | 20 | if(DEFINED __INCLUDED_GR_MISC_UTILS_CMAKE) 21 | return() 22 | endif() 23 | set(__INCLUDED_GR_MISC_UTILS_CMAKE TRUE) 24 | 25 | ######################################################################## 26 | # Set global variable macro. 27 | # Used for subdirectories to export settings. 28 | # Example: include and library paths. 29 | ######################################################################## 30 | function(GR_SET_GLOBAL var) 31 | set(${var} ${ARGN} CACHE INTERNAL "" FORCE) 32 | endfunction(GR_SET_GLOBAL) 33 | 34 | ######################################################################## 35 | # Set the pre-processor definition if the condition is true. 36 | # - def the pre-processor definition to set and condition name 37 | ######################################################################## 38 | function(GR_ADD_COND_DEF def) 39 | if(${def}) 40 | add_definitions(-D${def}) 41 | endif(${def}) 42 | endfunction(GR_ADD_COND_DEF) 43 | 44 | ######################################################################## 45 | # Check for a header and conditionally set a compile define. 46 | # - hdr the relative path to the header file 47 | # - def the pre-processor definition to set 48 | ######################################################################## 49 | function(GR_CHECK_HDR_N_DEF hdr def) 50 | include(CheckIncludeFileCXX) 51 | CHECK_INCLUDE_FILE_CXX(${hdr} ${def}) 52 | GR_ADD_COND_DEF(${def}) 53 | endfunction(GR_CHECK_HDR_N_DEF) 54 | 55 | ######################################################################## 56 | # Include subdirectory macro. 57 | # Sets the CMake directory variables, 58 | # includes the subdirectory CMakeLists.txt, 59 | # resets the CMake directory variables. 60 | # 61 | # This macro includes subdirectories rather than adding them 62 | # so that the subdirectory can affect variables in the level above. 63 | # This provides a work-around for the lack of convenience libraries. 64 | # This way a subdirectory can append to the list of library sources. 65 | ######################################################################## 66 | macro(GR_INCLUDE_SUBDIRECTORY subdir) 67 | #insert the current directories on the front of the list 68 | list(INSERT _cmake_source_dirs 0 ${CMAKE_CURRENT_SOURCE_DIR}) 69 | list(INSERT _cmake_binary_dirs 0 ${CMAKE_CURRENT_BINARY_DIR}) 70 | 71 | #set the current directories to the names of the subdirs 72 | set(CMAKE_CURRENT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/${subdir}) 73 | set(CMAKE_CURRENT_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/${subdir}) 74 | 75 | #include the subdirectory CMakeLists to run it 76 | file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) 77 | include(${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt) 78 | 79 | #reset the value of the current directories 80 | list(GET _cmake_source_dirs 0 CMAKE_CURRENT_SOURCE_DIR) 81 | list(GET _cmake_binary_dirs 0 CMAKE_CURRENT_BINARY_DIR) 82 | 83 | #pop the subdir names of the front of the list 84 | list(REMOVE_AT _cmake_source_dirs 0) 85 | list(REMOVE_AT _cmake_binary_dirs 0) 86 | endmacro(GR_INCLUDE_SUBDIRECTORY) 87 | 88 | ######################################################################## 89 | # Check if a compiler flag works and conditionally set a compile define. 90 | # - flag the compiler flag to check for 91 | # - have the variable to set with result 92 | ######################################################################## 93 | macro(GR_ADD_CXX_COMPILER_FLAG_IF_AVAILABLE flag have) 94 | include(CheckCXXCompilerFlag) 95 | CHECK_CXX_COMPILER_FLAG(${flag} ${have}) 96 | if(${have}) 97 | add_definitions(${flag}) 98 | endif(${have}) 99 | endmacro(GR_ADD_CXX_COMPILER_FLAG_IF_AVAILABLE) 100 | 101 | ######################################################################## 102 | # Generates the .la libtool file 103 | # This appears to generate libtool files that cannot be used by auto*. 104 | # Usage GR_LIBTOOL(TARGET [target] DESTINATION [dest]) 105 | # Notice: there is not COMPONENT option, these will not get distributed. 106 | ######################################################################## 107 | function(GR_LIBTOOL) 108 | if(NOT DEFINED GENERATE_LIBTOOL) 109 | set(GENERATE_LIBTOOL OFF) #disabled by default 110 | endif() 111 | 112 | if(GENERATE_LIBTOOL) 113 | include(CMakeParseArgumentsCopy) 114 | CMAKE_PARSE_ARGUMENTS(GR_LIBTOOL "" "TARGET;DESTINATION" "" ${ARGN}) 115 | 116 | find_program(LIBTOOL libtool) 117 | if(LIBTOOL) 118 | include(CMakeMacroLibtoolFile) 119 | CREATE_LIBTOOL_FILE(${GR_LIBTOOL_TARGET} /${GR_LIBTOOL_DESTINATION}) 120 | endif(LIBTOOL) 121 | endif(GENERATE_LIBTOOL) 122 | 123 | endfunction(GR_LIBTOOL) 124 | 125 | ######################################################################## 126 | # Do standard things to the library target 127 | # - set target properties 128 | # - make install rules 129 | # Also handle gnuradio custom naming conventions w/ extras mode. 130 | ######################################################################## 131 | function(GR_LIBRARY_FOO target) 132 | #parse the arguments for component names 133 | include(CMakeParseArgumentsCopy) 134 | CMAKE_PARSE_ARGUMENTS(GR_LIBRARY "" "RUNTIME_COMPONENT;DEVEL_COMPONENT" "" ${ARGN}) 135 | 136 | #set additional target properties 137 | set_target_properties(${target} PROPERTIES SOVERSION ${LIBVER}) 138 | 139 | #install the generated files like so... 140 | install(TARGETS ${target} 141 | LIBRARY DESTINATION ${GR_LIBRARY_DIR} COMPONENT ${GR_LIBRARY_RUNTIME_COMPONENT} # .so/.dylib file 142 | ARCHIVE DESTINATION ${GR_LIBRARY_DIR} COMPONENT ${GR_LIBRARY_DEVEL_COMPONENT} # .lib file 143 | RUNTIME DESTINATION ${GR_RUNTIME_DIR} COMPONENT ${GR_LIBRARY_RUNTIME_COMPONENT} # .dll file 144 | ) 145 | 146 | #extras mode enabled automatically on linux 147 | if(NOT DEFINED LIBRARY_EXTRAS) 148 | set(LIBRARY_EXTRAS ${LINUX}) 149 | endif() 150 | 151 | #special extras mode to enable alternative naming conventions 152 | if(LIBRARY_EXTRAS) 153 | 154 | #create .la file before changing props 155 | GR_LIBTOOL(TARGET ${target} DESTINATION ${GR_LIBRARY_DIR}) 156 | 157 | #give the library a special name with ultra-zero soversion 158 | set_target_properties(${target} PROPERTIES LIBRARY_OUTPUT_NAME ${target}-${LIBVER} SOVERSION "0.0.0") 159 | set(target_name lib${target}-${LIBVER}.so.0.0.0) 160 | 161 | #custom command to generate symlinks 162 | add_custom_command( 163 | TARGET ${target} 164 | POST_BUILD 165 | COMMAND ${CMAKE_COMMAND} -E create_symlink ${target_name} ${CMAKE_CURRENT_BINARY_DIR}/lib${target}.so 166 | COMMAND ${CMAKE_COMMAND} -E create_symlink ${target_name} ${CMAKE_CURRENT_BINARY_DIR}/lib${target}-${LIBVER}.so.0 167 | COMMAND ${CMAKE_COMMAND} -E touch ${target_name} #so the symlinks point to something valid so cmake 2.6 will install 168 | ) 169 | 170 | #and install the extra symlinks 171 | install( 172 | FILES 173 | ${CMAKE_CURRENT_BINARY_DIR}/lib${target}.so 174 | ${CMAKE_CURRENT_BINARY_DIR}/lib${target}-${LIBVER}.so.0 175 | DESTINATION ${GR_LIBRARY_DIR} COMPONENT ${GR_LIBRARY_RUNTIME_COMPONENT} 176 | ) 177 | 178 | endif(LIBRARY_EXTRAS) 179 | endfunction(GR_LIBRARY_FOO) 180 | 181 | ######################################################################## 182 | # Create a dummy custom command that depends on other targets. 183 | # Usage: 184 | # GR_GEN_TARGET_DEPS(unique_name target_deps ...) 185 | # ADD_CUSTOM_COMMAND( ${target_deps}) 186 | # 187 | # Custom command cant depend on targets, but can depend on executables, 188 | # and executables can depend on targets. So this is the process: 189 | ######################################################################## 190 | function(GR_GEN_TARGET_DEPS name var) 191 | file( 192 | WRITE ${CMAKE_CURRENT_BINARY_DIR}/${name}.cpp.in 193 | "int main(void){return 0;}\n" 194 | ) 195 | execute_process( 196 | COMMAND ${CMAKE_COMMAND} -E copy_if_different 197 | ${CMAKE_CURRENT_BINARY_DIR}/${name}.cpp.in 198 | ${CMAKE_CURRENT_BINARY_DIR}/${name}.cpp 199 | ) 200 | add_executable(${name} ${CMAKE_CURRENT_BINARY_DIR}/${name}.cpp) 201 | if(ARGN) 202 | add_dependencies(${name} ${ARGN}) 203 | endif(ARGN) 204 | 205 | if(CMAKE_CROSSCOMPILING) 206 | set(${var} "DEPENDS;${name}" PARENT_SCOPE) #cant call command when cross 207 | else() 208 | set(${var} "DEPENDS;${name};COMMAND;${name}" PARENT_SCOPE) 209 | endif() 210 | endfunction(GR_GEN_TARGET_DEPS) 211 | -------------------------------------------------------------------------------- /cmake/Modules/GrPlatform.cmake: -------------------------------------------------------------------------------- 1 | # Copyright 2011 Free Software Foundation, Inc. 2 | # 3 | # This file is part of GNU Radio 4 | # 5 | # GNU Radio is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 3, or (at your option) 8 | # any later version. 9 | # 10 | # GNU Radio is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with GNU Radio; see the file COPYING. If not, write to 17 | # the Free Software Foundation, Inc., 51 Franklin Street, 18 | # Boston, MA 02110-1301, USA. 19 | 20 | if(DEFINED __INCLUDED_GR_PLATFORM_CMAKE) 21 | return() 22 | endif() 23 | set(__INCLUDED_GR_PLATFORM_CMAKE TRUE) 24 | 25 | ######################################################################## 26 | # Setup additional defines for OS types 27 | ######################################################################## 28 | if(CMAKE_SYSTEM_NAME STREQUAL "Linux") 29 | set(LINUX TRUE) 30 | endif() 31 | 32 | if(LINUX AND EXISTS "/etc/debian_version") 33 | set(DEBIAN TRUE) 34 | endif() 35 | 36 | if(LINUX AND EXISTS "/etc/redhat-release") 37 | set(REDHAT TRUE) 38 | endif() 39 | 40 | ######################################################################## 41 | # when the library suffix should be 64 (applies to redhat linux family) 42 | ######################################################################## 43 | if(NOT DEFINED LIB_SUFFIX AND REDHAT AND CMAKE_SYSTEM_PROCESSOR MATCHES "64$") 44 | set(LIB_SUFFIX 64) 45 | endif() 46 | set(LIB_SUFFIX ${LIB_SUFFIX} CACHE STRING "lib directory suffix") 47 | -------------------------------------------------------------------------------- /cmake/Modules/GrPython.cmake: -------------------------------------------------------------------------------- 1 | # Copyright 2010-2011 Free Software Foundation, Inc. 2 | # 3 | # This file is part of GNU Radio 4 | # 5 | # GNU Radio is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 3, or (at your option) 8 | # any later version. 9 | # 10 | # GNU Radio is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with GNU Radio; see the file COPYING. If not, write to 17 | # the Free Software Foundation, Inc., 51 Franklin Street, 18 | # Boston, MA 02110-1301, USA. 19 | 20 | if(DEFINED __INCLUDED_GR_PYTHON_CMAKE) 21 | return() 22 | endif() 23 | set(__INCLUDED_GR_PYTHON_CMAKE TRUE) 24 | 25 | ######################################################################## 26 | # Setup the python interpreter: 27 | # This allows the user to specify a specific interpreter, 28 | # or finds the interpreter via the built-in cmake module. 29 | ######################################################################## 30 | #this allows the user to override PYTHON_EXECUTABLE 31 | if(PYTHON_EXECUTABLE) 32 | 33 | set(PYTHONINTERP_FOUND TRUE) 34 | 35 | #otherwise if not set, try to automatically find it 36 | else(PYTHON_EXECUTABLE) 37 | 38 | #use the built-in find script 39 | find_package(PythonInterp 2) 40 | 41 | #and if that fails use the find program routine 42 | if(NOT PYTHONINTERP_FOUND) 43 | find_program(PYTHON_EXECUTABLE NAMES python python2 python2.7 python2.6 python2.5) 44 | if(PYTHON_EXECUTABLE) 45 | set(PYTHONINTERP_FOUND TRUE) 46 | endif(PYTHON_EXECUTABLE) 47 | endif(NOT PYTHONINTERP_FOUND) 48 | 49 | endif(PYTHON_EXECUTABLE) 50 | 51 | #make the path to the executable appear in the cmake gui 52 | set(PYTHON_EXECUTABLE ${PYTHON_EXECUTABLE} CACHE FILEPATH "python interpreter") 53 | 54 | #make sure we can use -B with python (introduced in 2.6) 55 | if(PYTHON_EXECUTABLE) 56 | execute_process( 57 | COMMAND ${PYTHON_EXECUTABLE} -B -c "" 58 | OUTPUT_QUIET ERROR_QUIET 59 | RESULT_VARIABLE PYTHON_HAS_DASH_B_RESULT 60 | ) 61 | if(PYTHON_HAS_DASH_B_RESULT EQUAL 0) 62 | set(PYTHON_DASH_B "-B") 63 | endif() 64 | endif(PYTHON_EXECUTABLE) 65 | 66 | ######################################################################## 67 | # Check for the existence of a python module: 68 | # - desc a string description of the check 69 | # - mod the name of the module to import 70 | # - cmd an additional command to run 71 | # - have the result variable to set 72 | ######################################################################## 73 | macro(GR_PYTHON_CHECK_MODULE desc mod cmd have) 74 | message(STATUS "") 75 | message(STATUS "Python checking for ${desc}") 76 | execute_process( 77 | COMMAND ${PYTHON_EXECUTABLE} -c " 78 | ######################################### 79 | try: import ${mod} 80 | except: exit(-1) 81 | try: assert ${cmd} 82 | except: exit(-1) 83 | #########################################" 84 | RESULT_VARIABLE ${have} 85 | ) 86 | if(${have} EQUAL 0) 87 | message(STATUS "Python checking for ${desc} - found") 88 | set(${have} TRUE) 89 | else(${have} EQUAL 0) 90 | message(STATUS "Python checking for ${desc} - not found") 91 | set(${have} FALSE) 92 | endif(${have} EQUAL 0) 93 | endmacro(GR_PYTHON_CHECK_MODULE) 94 | 95 | ######################################################################## 96 | # Sets the python installation directory GR_PYTHON_DIR 97 | ######################################################################## 98 | execute_process(COMMAND ${PYTHON_EXECUTABLE} -c " 99 | from distutils import sysconfig 100 | print sysconfig.get_python_lib(plat_specific=True, prefix='') 101 | " OUTPUT_VARIABLE GR_PYTHON_DIR OUTPUT_STRIP_TRAILING_WHITESPACE 102 | ) 103 | file(TO_CMAKE_PATH ${GR_PYTHON_DIR} GR_PYTHON_DIR) 104 | 105 | ######################################################################## 106 | # Create an always-built target with a unique name 107 | # Usage: GR_UNIQUE_TARGET( ) 108 | ######################################################################## 109 | function(GR_UNIQUE_TARGET desc) 110 | file(RELATIVE_PATH reldir ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}) 111 | execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "import re, hashlib 112 | unique = hashlib.md5('${reldir}${ARGN}').hexdigest()[:5] 113 | print(re.sub('\\W', '_', '${desc} ${reldir} ' + unique))" 114 | OUTPUT_VARIABLE _target OUTPUT_STRIP_TRAILING_WHITESPACE) 115 | add_custom_target(${_target} ALL DEPENDS ${ARGN}) 116 | endfunction(GR_UNIQUE_TARGET) 117 | 118 | ######################################################################## 119 | # Install python sources (also builds and installs byte-compiled python) 120 | ######################################################################## 121 | function(GR_PYTHON_INSTALL) 122 | include(CMakeParseArgumentsCopy) 123 | CMAKE_PARSE_ARGUMENTS(GR_PYTHON_INSTALL "" "DESTINATION;COMPONENT" "FILES;PROGRAMS" ${ARGN}) 124 | 125 | #################################################################### 126 | if(GR_PYTHON_INSTALL_FILES) 127 | #################################################################### 128 | install(${ARGN}) #installs regular python files 129 | 130 | #create a list of all generated files 131 | unset(pysrcfiles) 132 | unset(pycfiles) 133 | unset(pyofiles) 134 | foreach(pyfile ${GR_PYTHON_INSTALL_FILES}) 135 | get_filename_component(pyfile ${pyfile} ABSOLUTE) 136 | list(APPEND pysrcfiles ${pyfile}) 137 | 138 | #determine if this file is in the source or binary directory 139 | file(RELATIVE_PATH source_rel_path ${CMAKE_CURRENT_SOURCE_DIR} ${pyfile}) 140 | string(LENGTH "${source_rel_path}" source_rel_path_len) 141 | file(RELATIVE_PATH binary_rel_path ${CMAKE_CURRENT_BINARY_DIR} ${pyfile}) 142 | string(LENGTH "${binary_rel_path}" binary_rel_path_len) 143 | 144 | #and set the generated path appropriately 145 | if(${source_rel_path_len} GREATER ${binary_rel_path_len}) 146 | set(pygenfile ${CMAKE_CURRENT_BINARY_DIR}/${binary_rel_path}) 147 | else() 148 | set(pygenfile ${CMAKE_CURRENT_BINARY_DIR}/${source_rel_path}) 149 | endif() 150 | list(APPEND pycfiles ${pygenfile}c) 151 | list(APPEND pyofiles ${pygenfile}o) 152 | 153 | #ensure generation path exists 154 | get_filename_component(pygen_path ${pygenfile} PATH) 155 | file(MAKE_DIRECTORY ${pygen_path}) 156 | 157 | endforeach(pyfile) 158 | 159 | #the command to generate the pyc files 160 | add_custom_command( 161 | DEPENDS ${pysrcfiles} OUTPUT ${pycfiles} 162 | COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_BINARY_DIR}/python_compile_helper.py ${pysrcfiles} ${pycfiles} 163 | ) 164 | 165 | #the command to generate the pyo files 166 | add_custom_command( 167 | DEPENDS ${pysrcfiles} OUTPUT ${pyofiles} 168 | COMMAND ${PYTHON_EXECUTABLE} -O ${CMAKE_BINARY_DIR}/python_compile_helper.py ${pysrcfiles} ${pyofiles} 169 | ) 170 | 171 | #create install rule and add generated files to target list 172 | set(python_install_gen_targets ${pycfiles} ${pyofiles}) 173 | install(FILES ${python_install_gen_targets} 174 | DESTINATION ${GR_PYTHON_INSTALL_DESTINATION} 175 | COMPONENT ${GR_PYTHON_INSTALL_COMPONENT} 176 | ) 177 | 178 | 179 | #################################################################### 180 | elseif(GR_PYTHON_INSTALL_PROGRAMS) 181 | #################################################################### 182 | file(TO_NATIVE_PATH ${PYTHON_EXECUTABLE} pyexe_native) 183 | 184 | foreach(pyfile ${GR_PYTHON_INSTALL_PROGRAMS}) 185 | get_filename_component(pyfile_name ${pyfile} NAME) 186 | get_filename_component(pyfile ${pyfile} ABSOLUTE) 187 | string(REPLACE "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}" pyexefile "${pyfile}.exe") 188 | list(APPEND python_install_gen_targets ${pyexefile}) 189 | 190 | get_filename_component(pyexefile_path ${pyexefile} PATH) 191 | file(MAKE_DIRECTORY ${pyexefile_path}) 192 | 193 | add_custom_command( 194 | OUTPUT ${pyexefile} DEPENDS ${pyfile} 195 | COMMAND ${PYTHON_EXECUTABLE} -c 196 | \"open('${pyexefile}', 'w').write('\#!${pyexe_native}\\n'+open('${pyfile}').read())\" 197 | COMMENT "Shebangin ${pyfile_name}" 198 | ) 199 | 200 | #on windows, python files need an extension to execute 201 | get_filename_component(pyfile_ext ${pyfile} EXT) 202 | if(WIN32 AND NOT pyfile_ext) 203 | set(pyfile_name "${pyfile_name}.py") 204 | endif() 205 | 206 | install(PROGRAMS ${pyexefile} RENAME ${pyfile_name} 207 | DESTINATION ${GR_PYTHON_INSTALL_DESTINATION} 208 | COMPONENT ${GR_PYTHON_INSTALL_COMPONENT} 209 | ) 210 | endforeach(pyfile) 211 | 212 | endif() 213 | 214 | GR_UNIQUE_TARGET("pygen" ${python_install_gen_targets}) 215 | 216 | endfunction(GR_PYTHON_INSTALL) 217 | 218 | ######################################################################## 219 | # Write the python helper script that generates byte code files 220 | ######################################################################## 221 | file(WRITE ${CMAKE_BINARY_DIR}/python_compile_helper.py " 222 | import sys, py_compile 223 | files = sys.argv[1:] 224 | srcs, gens = files[:len(files)/2], files[len(files)/2:] 225 | for src, gen in zip(srcs, gens): 226 | py_compile.compile(file=src, cfile=gen, doraise=True) 227 | ") 228 | -------------------------------------------------------------------------------- /cmake/Modules/GrSwig.cmake: -------------------------------------------------------------------------------- 1 | # Copyright 2010-2011 Free Software Foundation, Inc. 2 | # 3 | # This file is part of GNU Radio 4 | # 5 | # GNU Radio is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 3, or (at your option) 8 | # any later version. 9 | # 10 | # GNU Radio is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with GNU Radio; see the file COPYING. If not, write to 17 | # the Free Software Foundation, Inc., 51 Franklin Street, 18 | # Boston, MA 02110-1301, USA. 19 | 20 | if(DEFINED __INCLUDED_GR_SWIG_CMAKE) 21 | return() 22 | endif() 23 | set(__INCLUDED_GR_SWIG_CMAKE TRUE) 24 | 25 | include(GrPython) 26 | 27 | ######################################################################## 28 | # Builds a swig documentation file to be generated into python docstrings 29 | # Usage: GR_SWIG_MAKE_DOCS(output_file input_path input_path....) 30 | # 31 | # Set the following variable to specify extra dependent targets: 32 | # - GR_SWIG_DOCS_SOURCE_DEPS 33 | # - GR_SWIG_DOCS_TARGET_DEPS 34 | ######################################################################## 35 | function(GR_SWIG_MAKE_DOCS output_file) 36 | find_package(Doxygen) 37 | if(DOXYGEN_FOUND) 38 | 39 | #setup the input files variable list, quote formated 40 | set(input_files) 41 | unset(INPUT_PATHS) 42 | foreach(input_path ${ARGN}) 43 | if (IS_DIRECTORY ${input_path}) #when input path is a directory 44 | file(GLOB input_path_h_files ${input_path}/*.h) 45 | else() #otherwise its just a file, no glob 46 | set(input_path_h_files ${input_path}) 47 | endif() 48 | list(APPEND input_files ${input_path_h_files}) 49 | set(INPUT_PATHS "${INPUT_PATHS} \"${input_path}\"") 50 | endforeach(input_path) 51 | 52 | #determine the output directory 53 | get_filename_component(name ${output_file} NAME_WE) 54 | get_filename_component(OUTPUT_DIRECTORY ${output_file} PATH) 55 | set(OUTPUT_DIRECTORY ${OUTPUT_DIRECTORY}/${name}_swig_docs) 56 | make_directory(${OUTPUT_DIRECTORY}) 57 | 58 | #generate the Doxyfile used by doxygen 59 | configure_file( 60 | ${CMAKE_SOURCE_DIR}/docs/doxygen/Doxyfile.swig_doc.in 61 | ${OUTPUT_DIRECTORY}/Doxyfile 62 | @ONLY) 63 | 64 | #Create a dummy custom command that depends on other targets 65 | include(GrMiscUtils) 66 | GR_GEN_TARGET_DEPS(_${name}_tag tag_deps ${GR_SWIG_DOCS_TARGET_DEPS}) 67 | 68 | #call doxygen on the Doxyfile + input headers 69 | add_custom_command( 70 | OUTPUT ${OUTPUT_DIRECTORY}/xml/index.xml 71 | DEPENDS ${input_files} ${GR_SWIG_DOCS_SOURCE_DEPS} ${tag_deps} 72 | COMMAND ${DOXYGEN_EXECUTABLE} ${OUTPUT_DIRECTORY}/Doxyfile 73 | COMMENT "Generating doxygen xml for ${name} docs" 74 | ) 75 | 76 | #call the swig_doc script on the xml files 77 | add_custom_command( 78 | OUTPUT ${output_file} 79 | DEPENDS ${input_files} ${OUTPUT_DIRECTORY}/xml/index.xml 80 | COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B} 81 | ${CMAKE_SOURCE_DIR}/docs/doxygen/swig_doc.py 82 | ${OUTPUT_DIRECTORY}/xml 83 | ${output_file} 84 | WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/docs/doxygen 85 | ) 86 | 87 | else(DOXYGEN_FOUND) 88 | file(WRITE ${output_file} "\n") #no doxygen -> empty file 89 | endif(DOXYGEN_FOUND) 90 | endfunction(GR_SWIG_MAKE_DOCS) 91 | 92 | ######################################################################## 93 | # Build a swig target for the common gnuradio use case. Usage: 94 | # GR_SWIG_MAKE(target ifile ifile ifile...) 95 | # 96 | # Set the following variables before calling: 97 | # - GR_SWIG_FLAGS 98 | # - GR_SWIG_INCLUDE_DIRS 99 | # - GR_SWIG_LIBRARIES 100 | # - GR_SWIG_SOURCE_DEPS 101 | # - GR_SWIG_TARGET_DEPS 102 | # - GR_SWIG_DOC_FILE 103 | # - GR_SWIG_DOC_DIRS 104 | ######################################################################## 105 | macro(GR_SWIG_MAKE name) 106 | set(ifiles ${ARGN}) 107 | 108 | #do swig doc generation if specified 109 | if (GR_SWIG_DOC_FILE) 110 | set(GR_SWIG_DOCS_SOURCE_DEPS ${GR_SWIG_SOURCE_DEPS}) 111 | set(GR_SWIG_DOCS_TAREGT_DEPS ${GR_SWIG_TARGET_DEPS}) 112 | GR_SWIG_MAKE_DOCS(${GR_SWIG_DOC_FILE} ${GR_SWIG_DOC_DIRS}) 113 | list(APPEND GR_SWIG_SOURCE_DEPS ${GR_SWIG_DOC_FILE}) 114 | endif() 115 | 116 | #append additional include directories 117 | find_package(PythonLibs 2) 118 | list(APPEND GR_SWIG_INCLUDE_DIRS ${PYTHON_INCLUDE_PATH}) #deprecated name (now dirs) 119 | list(APPEND GR_SWIG_INCLUDE_DIRS ${PYTHON_INCLUDE_DIRS}) 120 | list(APPEND GR_SWIG_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}) 121 | list(APPEND GR_SWIG_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR}) 122 | 123 | #determine include dependencies for swig file 124 | execute_process( 125 | COMMAND ${PYTHON_EXECUTABLE} 126 | ${CMAKE_BINARY_DIR}/get_swig_deps.py 127 | "${ifiles}" "${GR_SWIG_INCLUDE_DIRS}" 128 | OUTPUT_STRIP_TRAILING_WHITESPACE 129 | OUTPUT_VARIABLE SWIG_MODULE_${name}_EXTRA_DEPS 130 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 131 | ) 132 | 133 | #Create a dummy custom command that depends on other targets 134 | include(GrMiscUtils) 135 | GR_GEN_TARGET_DEPS(_${name}_swig_tag tag_deps ${GR_SWIG_TARGET_DEPS}) 136 | set(tag_file ${CMAKE_CURRENT_BINARY_DIR}/${name}.tag) 137 | add_custom_command( 138 | OUTPUT ${tag_file} 139 | DEPENDS ${GR_SWIG_SOURCE_DEPS} ${tag_deps} 140 | COMMAND ${CMAKE_COMMAND} -E touch ${tag_file} 141 | ) 142 | 143 | #append the specified include directories 144 | include_directories(${GR_SWIG_INCLUDE_DIRS}) 145 | list(APPEND SWIG_MODULE_${name}_EXTRA_DEPS ${tag_file}) 146 | 147 | #setup the swig flags with flags and include directories 148 | set(CMAKE_SWIG_FLAGS -fvirtual -modern -keyword -w511 -module ${name} ${GR_SWIG_FLAGS}) 149 | foreach(dir ${GR_SWIG_INCLUDE_DIRS}) 150 | list(APPEND CMAKE_SWIG_FLAGS "-I${dir}") 151 | endforeach(dir) 152 | 153 | #set the C++ property on the swig .i file so it builds 154 | set_source_files_properties(${ifiles} PROPERTIES CPLUSPLUS ON) 155 | 156 | #setup the actual swig library target to be built 157 | include(UseSWIG) 158 | SWIG_ADD_MODULE(${name} python ${ifiles}) 159 | SWIG_LINK_LIBRARIES(${name} ${PYTHON_LIBRARIES} ${GR_SWIG_LIBRARIES}) 160 | 161 | endmacro(GR_SWIG_MAKE) 162 | 163 | ######################################################################## 164 | # Install swig targets generated by GR_SWIG_MAKE. Usage: 165 | # GR_SWIG_INSTALL( 166 | # TARGETS target target target... 167 | # [DESTINATION destination] 168 | # [COMPONENT component] 169 | # ) 170 | ######################################################################## 171 | macro(GR_SWIG_INSTALL) 172 | 173 | include(CMakeParseArgumentsCopy) 174 | CMAKE_PARSE_ARGUMENTS(GR_SWIG_INSTALL "" "DESTINATION;COMPONENT" "TARGETS" ${ARGN}) 175 | 176 | foreach(name ${GR_SWIG_INSTALL_TARGETS}) 177 | install(TARGETS ${SWIG_MODULE_${name}_REAL_NAME} 178 | DESTINATION ${GR_SWIG_INSTALL_DESTINATION} 179 | COMPONENT ${GR_SWIG_INSTALL_COMPONENT} 180 | ) 181 | 182 | include(GrPython) 183 | GR_PYTHON_INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${name}.py 184 | DESTINATION ${GR_SWIG_INSTALL_DESTINATION} 185 | COMPONENT ${GR_SWIG_INSTALL_COMPONENT} 186 | ) 187 | 188 | GR_LIBTOOL( 189 | TARGET ${SWIG_MODULE_${name}_REAL_NAME} 190 | DESTINATION ${GR_SWIG_INSTALL_DESTINATION} 191 | ) 192 | 193 | endforeach(name) 194 | 195 | endmacro(GR_SWIG_INSTALL) 196 | 197 | ######################################################################## 198 | # Generate a python file that can determine swig dependencies. 199 | # Used by the make macro above to determine extra dependencies. 200 | # When you build C++, CMake figures out the header dependencies. 201 | # This code essentially performs that logic for swig includes. 202 | ######################################################################## 203 | file(WRITE ${CMAKE_BINARY_DIR}/get_swig_deps.py " 204 | 205 | import os, sys, re 206 | 207 | include_matcher = re.compile('[#|%]include\\s*[<|\"](.*)[>|\"]') 208 | include_dirs = sys.argv[2].split(';') 209 | 210 | def get_swig_incs(file_path): 211 | file_contents = open(file_path, 'r').read() 212 | return include_matcher.findall(file_contents, re.MULTILINE) 213 | 214 | def get_swig_deps(file_path, level): 215 | deps = [file_path] 216 | if level == 0: return deps 217 | for inc_file in get_swig_incs(file_path): 218 | for inc_dir in include_dirs: 219 | inc_path = os.path.join(inc_dir, inc_file) 220 | if not os.path.exists(inc_path): continue 221 | deps.extend(get_swig_deps(inc_path, level-1)) 222 | return deps 223 | 224 | if __name__ == '__main__': 225 | ifiles = sys.argv[1].split(';') 226 | deps = sum([get_swig_deps(ifile, 3) for ifile in ifiles], []) 227 | #sys.stderr.write(';'.join(set(deps)) + '\\n\\n') 228 | print(';'.join(set(deps))) 229 | ") 230 | -------------------------------------------------------------------------------- /cmake/Modules/GrTest.cmake: -------------------------------------------------------------------------------- 1 | # Copyright 2010-2011 Free Software Foundation, Inc. 2 | # 3 | # This file is part of GNU Radio 4 | # 5 | # GNU Radio is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 3, or (at your option) 8 | # any later version. 9 | # 10 | # GNU Radio is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with GNU Radio; see the file COPYING. If not, write to 17 | # the Free Software Foundation, Inc., 51 Franklin Street, 18 | # Boston, MA 02110-1301, USA. 19 | 20 | if(DEFINED __INCLUDED_GR_TEST_CMAKE) 21 | return() 22 | endif() 23 | set(__INCLUDED_GR_TEST_CMAKE TRUE) 24 | 25 | ######################################################################## 26 | # Add a unit test and setup the environment for a unit test. 27 | # Takes the same arguments as the ADD_TEST function. 28 | # 29 | # Before calling set the following variables: 30 | # GR_TEST_TARGET_DEPS - built targets for the library path 31 | # GR_TEST_LIBRARY_DIRS - directories for the library path 32 | # GR_TEST_PYTHON_DIRS - directories for the python path 33 | ######################################################################## 34 | function(GR_ADD_TEST test_name) 35 | 36 | if(WIN32) 37 | #Ensure that the build exe also appears in the PATH. 38 | list(APPEND GR_TEST_TARGET_DEPS ${ARGN}) 39 | 40 | #In the land of windows, all libraries must be in the PATH. 41 | #Since the dependent libraries are not yet installed, 42 | #we must manually set them in the PATH to run tests. 43 | #The following appends the path of a target dependency. 44 | foreach(target ${GR_TEST_TARGET_DEPS}) 45 | get_target_property(location ${target} LOCATION) 46 | if(location) 47 | get_filename_component(path ${location} PATH) 48 | string(REGEX REPLACE "\\$\\(.*\\)" ${CMAKE_BUILD_TYPE} path ${path}) 49 | list(APPEND GR_TEST_LIBRARY_DIRS ${path}) 50 | endif(location) 51 | endforeach(target) 52 | 53 | #SWIG generates the python library files into a subdirectory. 54 | #Therefore, we must append this subdirectory into PYTHONPATH. 55 | #Only do this for the python directories matching the following: 56 | foreach(pydir ${GR_TEST_PYTHON_DIRS}) 57 | get_filename_component(name ${pydir} NAME) 58 | if(name MATCHES "^(swig|lib|src)$") 59 | list(APPEND GR_TEST_PYTHON_DIRS ${pydir}/${CMAKE_BUILD_TYPE}) 60 | endif() 61 | endforeach(pydir) 62 | endif(WIN32) 63 | 64 | file(TO_NATIVE_PATH ${CMAKE_CURRENT_SOURCE_DIR} srcdir) 65 | file(TO_NATIVE_PATH "${GR_TEST_LIBRARY_DIRS}" libpath) #ok to use on dir list? 66 | file(TO_NATIVE_PATH "${GR_TEST_PYTHON_DIRS}" pypath) #ok to use on dir list? 67 | 68 | set(environs "GR_DONT_LOAD_PREFS=1" "srcdir=${srcdir}") 69 | 70 | #http://www.cmake.org/pipermail/cmake/2009-May/029464.html 71 | #Replaced this add test + set environs code with the shell script generation. 72 | #Its nicer to be able to manually run the shell script to diagnose problems. 73 | #ADD_TEST(${ARGV}) 74 | #SET_TESTS_PROPERTIES(${test_name} PROPERTIES ENVIRONMENT "${environs}") 75 | 76 | if(UNIX) 77 | set(binpath "${CMAKE_CURRENT_BINARY_DIR}:$PATH") 78 | #set both LD and DYLD paths to cover multiple UNIX OS library paths 79 | list(APPEND libpath "$LD_LIBRARY_PATH" "$DYLD_LIBRARY_PATH") 80 | list(APPEND pypath "$PYTHONPATH") 81 | 82 | #replace list separator with the path separator 83 | string(REPLACE ";" ":" libpath "${libpath}") 84 | string(REPLACE ";" ":" pypath "${pypath}") 85 | list(APPEND environs "PATH=${binpath}" "LD_LIBRARY_PATH=${libpath}" "DYLD_LIBRARY_PATH=${libpath}" "PYTHONPATH=${pypath}") 86 | 87 | #generate a bat file that sets the environment and runs the test 88 | find_program(SHELL sh) 89 | set(sh_file ${CMAKE_CURRENT_BINARY_DIR}/${test_name}_test.sh) 90 | file(WRITE ${sh_file} "#!${SHELL}\n") 91 | #each line sets an environment variable 92 | foreach(environ ${environs}) 93 | file(APPEND ${sh_file} "export ${environ}\n") 94 | endforeach(environ) 95 | #load the command to run with its arguments 96 | foreach(arg ${ARGN}) 97 | file(APPEND ${sh_file} "${arg} ") 98 | endforeach(arg) 99 | file(APPEND ${sh_file} "\n") 100 | 101 | #make the shell file executable 102 | execute_process(COMMAND chmod +x ${sh_file}) 103 | 104 | add_test(${test_name} ${SHELL} ${sh_file}) 105 | 106 | endif(UNIX) 107 | 108 | if(WIN32) 109 | list(APPEND libpath ${DLL_PATHS} "%PATH%") 110 | list(APPEND pypath "%PYTHONPATH%") 111 | 112 | #replace list separator with the path separator (escaped) 113 | string(REPLACE ";" "\\;" libpath "${libpath}") 114 | string(REPLACE ";" "\\;" pypath "${pypath}") 115 | list(APPEND environs "PATH=${libpath}" "PYTHONPATH=${pypath}") 116 | 117 | #generate a bat file that sets the environment and runs the test 118 | set(bat_file ${CMAKE_CURRENT_BINARY_DIR}/${test_name}_test.bat) 119 | file(WRITE ${bat_file} "@echo off\n") 120 | #each line sets an environment variable 121 | foreach(environ ${environs}) 122 | file(APPEND ${bat_file} "SET ${environ}\n") 123 | endforeach(environ) 124 | #load the command to run with its arguments 125 | foreach(arg ${ARGN}) 126 | file(APPEND ${bat_file} "${arg} ") 127 | endforeach(arg) 128 | file(APPEND ${bat_file} "\n") 129 | 130 | add_test(${test_name} ${bat_file}) 131 | endif(WIN32) 132 | 133 | endfunction(GR_ADD_TEST) 134 | -------------------------------------------------------------------------------- /cmake/Modules/GrVersion.cmake: -------------------------------------------------------------------------------- 1 | # Copyright 2011,2013 Free Software Foundation, Inc. 2 | # 3 | # This file is part of GNU Radio 4 | # 5 | # GNU Radio is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 3, or (at your option) 8 | # any later version. 9 | # 10 | # GNU Radio is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with GNU Radio; see the file COPYING. If not, write to 17 | # the Free Software Foundation, Inc., 51 Franklin Street, 18 | # Boston, MA 02110-1301, USA. 19 | 20 | if(DEFINED __INCLUDED_GR_VERSION_CMAKE) 21 | return() 22 | endif() 23 | set(__INCLUDED_GR_VERSION_CMAKE TRUE) 24 | 25 | #eventually, replace version.sh and fill in the variables below 26 | set(MAJOR_VERSION ${VERSION_INFO_MAJOR_VERSION}) 27 | set(API_COMPAT ${VERSION_INFO_API_COMPAT}) 28 | set(MINOR_VERSION ${VERSION_INFO_MINOR_VERSION}) 29 | set(MAINT_VERSION ${VERSION_INFO_MAINT_VERSION}) 30 | 31 | ######################################################################## 32 | # Extract the version string from git describe. 33 | ######################################################################## 34 | find_package(Git) 35 | 36 | if(GIT_FOUND AND EXISTS ${CMAKE_SOURCE_DIR}/.git) 37 | message(STATUS "Extracting version information from git describe...") 38 | execute_process( 39 | COMMAND ${GIT_EXECUTABLE} describe --always --abbrev=8 --long 40 | OUTPUT_VARIABLE GIT_DESCRIBE OUTPUT_STRIP_TRAILING_WHITESPACE 41 | WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} 42 | ) 43 | else() 44 | set(GIT_DESCRIBE "v${MAJOR_VERSION}.${API_COMPAT}.x-xxx-xunknown") 45 | endif() 46 | 47 | ######################################################################## 48 | # Use the logic below to set the version constants 49 | ######################################################################## 50 | if("${MINOR_VERSION}" STREQUAL "git") 51 | # VERSION: 3.3git-xxx-gxxxxxxxx 52 | # DOCVER: 3.3git 53 | # LIBVER: 3.3git 54 | set(VERSION "${GIT_DESCRIBE}") 55 | set(DOCVER "${MAJOR_VERSION}.${API_COMPAT}${MINOR_VERSION}") 56 | set(LIBVER "${MAJOR_VERSION}.${API_COMPAT}${MINOR_VERSION}") 57 | set(RC_MINOR_VERSION "0") 58 | set(RC_MAINT_VERSION "0") 59 | elseif("${MAINT_VERSION}" STREQUAL "git") 60 | # VERSION: 3.3.1git-xxx-gxxxxxxxx 61 | # DOCVER: 3.3.1git 62 | # LIBVER: 3.3.1git 63 | set(VERSION "${GIT_DESCRIBE}") 64 | set(DOCVER "${MAJOR_VERSION}.${API_COMPAT}.${MINOR_VERSION}${MAINT_VERSION}") 65 | set(LIBVER "${MAJOR_VERSION}.${API_COMPAT}.${MINOR_VERSION}${MAINT_VERSION}") 66 | math(EXPR RC_MINOR_VERSION "${MINOR_VERSION} - 1") 67 | set(RC_MAINT_VERSION "0") 68 | else() 69 | # This is a numbered release. 70 | # VERSION: 3.3.1{.x} 71 | # DOCVER: 3.3.1{.x} 72 | # LIBVER: 3.3.1{.x} 73 | if("${MAINT_VERSION}" STREQUAL "0") 74 | set(VERSION "${MAJOR_VERSION}.${API_COMPAT}.${MINOR_VERSION}") 75 | else() 76 | set(VERSION "${MAJOR_VERSION}.${API_COMPAT}.${MINOR_VERSION}.${MAINT_VERSION}") 77 | endif() 78 | set(DOCVER "${VERSION}") 79 | set(LIBVER "${VERSION}") 80 | set(RC_MINOR_VERSION ${MINOR_VERSION}) 81 | set(RC_MAINT_VERSION ${MAINT_VERSION}) 82 | endif() 83 | -------------------------------------------------------------------------------- /debug.grc: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Tue Nov 11 08:27:57 2014 5 | 6 | options 7 | 8 | id 9 | debug_grc 10 | 11 | 12 | _enabled 13 | True 14 | 15 | 16 | title 17 | 18 | 19 | 20 | author 21 | 22 | 23 | 24 | description 25 | 26 | 27 | 28 | window_size 29 | 1320, 1024 30 | 31 | 32 | generate_options 33 | wx_gui 34 | 35 | 36 | category 37 | Custom 38 | 39 | 40 | run_options 41 | prompt 42 | 43 | 44 | run 45 | True 46 | 47 | 48 | max_nouts 49 | 0 50 | 51 | 52 | realtime_scheduling 53 | 54 | 55 | 56 | alias 57 | 58 | 59 | 60 | _coordinate 61 | (10, 10) 62 | 63 | 64 | _rotation 65 | 0 66 | 67 | 68 | 69 | variable 70 | 71 | id 72 | decim 73 | 74 | 75 | _enabled 76 | True 77 | 78 | 79 | value 80 | 15 81 | 82 | 83 | alias 84 | 85 | 86 | 87 | _coordinate 88 | (112, 374) 89 | 90 | 91 | _rotation 92 | 0 93 | 94 | 95 | 96 | variable 97 | 98 | id 99 | channel_rate 100 | 101 | 102 | _enabled 103 | True 104 | 105 | 106 | value 107 | 4800*samp_per_sym 108 | 109 | 110 | alias 111 | 112 | 113 | 114 | _coordinate 115 | (219, 503) 116 | 117 | 118 | _rotation 119 | 0 120 | 121 | 122 | 123 | variable 124 | 125 | id 126 | samp_per_sym 127 | 128 | 129 | _enabled 130 | True 131 | 132 | 133 | value 134 | 10 135 | 136 | 137 | alias 138 | 139 | 140 | 141 | _coordinate 142 | (220, 313) 143 | 144 | 145 | _rotation 146 | 0 147 | 148 | 149 | 150 | variable 151 | 152 | id 153 | samp_rate 154 | 155 | 156 | _enabled 157 | True 158 | 159 | 160 | value 161 | 48000 162 | 163 | 164 | alias 165 | 166 | 167 | 168 | _coordinate 169 | (7, 82) 170 | 171 | 172 | _rotation 173 | 0 174 | 175 | 176 | 177 | import 178 | 179 | id 180 | import_0 181 | 182 | 183 | _enabled 184 | True 185 | 186 | 187 | import 188 | import math 189 | 190 | 191 | alias 192 | 193 | 194 | 195 | _coordinate 196 | (219, 417) 197 | 198 | 199 | _rotation 200 | 0 201 | 202 | 203 | 204 | variable_slider 205 | 206 | id 207 | audio_mul 208 | 209 | 210 | _enabled 211 | True 212 | 213 | 214 | label 215 | Audio mul 216 | 217 | 218 | value 219 | 0 220 | 221 | 222 | min 223 | -30 224 | 225 | 226 | max 227 | 10 228 | 229 | 230 | num_steps 231 | 40 232 | 233 | 234 | style 235 | wx.SL_HORIZONTAL 236 | 237 | 238 | converver 239 | float_converter 240 | 241 | 242 | grid_pos 243 | 244 | 245 | 246 | notebook 247 | 248 | 249 | 250 | alias 251 | 252 | 253 | 254 | _coordinate 255 | (111, 441) 256 | 257 | 258 | _rotation 259 | 0 260 | 261 | 262 | 263 | note 264 | 265 | id 266 | note_0 267 | 268 | 269 | _enabled 270 | True 271 | 272 | 273 | note 274 | Enable your source! 275 | 276 | 277 | alias 278 | 279 | 280 | 281 | _coordinate 282 | (391, 152) 283 | 284 | 285 | _rotation 286 | 0 287 | 288 | 289 | 290 | notebook 291 | 292 | id 293 | nb 294 | 295 | 296 | _enabled 297 | True 298 | 299 | 300 | style 301 | wx.NB_TOP 302 | 303 | 304 | labels 305 | ['BB-1', 'BB-2', 'Xlate-1', 'Xlate-2', '4FSK'] 306 | 307 | 308 | grid_pos 309 | 310 | 311 | 312 | notebook 313 | 314 | 315 | 316 | alias 317 | 318 | 319 | 320 | _coordinate 321 | (6, 691) 322 | 323 | 324 | _rotation 325 | 0 326 | 327 | 328 | 329 | wxgui_waterfallsink2 330 | 331 | id 332 | wxgui_waterfallsink2_0_0 333 | 334 | 335 | _enabled 336 | True 337 | 338 | 339 | type 340 | complex 341 | 342 | 343 | title 344 | Waterfall Plot 345 | 346 | 347 | samp_rate 348 | channel_rate 349 | 350 | 351 | baseband_freq 352 | 0 353 | 354 | 355 | dynamic_range 356 | 10 357 | 358 | 359 | ref_level 360 | 10 361 | 362 | 363 | ref_scale 364 | 2.0 365 | 366 | 367 | fft_size 368 | 512 369 | 370 | 371 | fft_rate 372 | 15 373 | 374 | 375 | average 376 | False 377 | 378 | 379 | avg_alpha 380 | 0 381 | 382 | 383 | win 384 | None 385 | 386 | 387 | win_size 388 | 389 | 390 | 391 | grid_pos 392 | 393 | 394 | 395 | notebook 396 | nb, 3 397 | 398 | 399 | freqvar 400 | None 401 | 402 | 403 | alias 404 | 405 | 406 | 407 | affinity 408 | 409 | 410 | 411 | _coordinate 412 | (1048, 266) 413 | 414 | 415 | _rotation 416 | 0 417 | 418 | 419 | 420 | wxgui_fftsink2 421 | 422 | id 423 | wxgui_fftsink2_0_0 424 | 425 | 426 | _enabled 427 | True 428 | 429 | 430 | type 431 | complex 432 | 433 | 434 | title 435 | FFT Plot 436 | 437 | 438 | samp_rate 439 | channel_rate 440 | 441 | 442 | baseband_freq 443 | 0 444 | 445 | 446 | y_per_div 447 | 10 448 | 449 | 450 | y_divs 451 | 10 452 | 453 | 454 | ref_level 455 | 0 456 | 457 | 458 | ref_scale 459 | 2.0 460 | 461 | 462 | fft_size 463 | 1024 464 | 465 | 466 | fft_rate 467 | 30 468 | 469 | 470 | peak_hold 471 | False 472 | 473 | 474 | average 475 | True 476 | 477 | 478 | avg_alpha 479 | 0 480 | 481 | 482 | win 483 | window.flattop 484 | 485 | 486 | win_size 487 | 488 | 489 | 490 | grid_pos 491 | 492 | 493 | 494 | notebook 495 | nb, 2 496 | 497 | 498 | freqvar 499 | 0 500 | 501 | 502 | alias 503 | 504 | 505 | 506 | affinity 507 | 508 | 509 | 510 | _coordinate 511 | (1160, 39) 512 | 513 | 514 | _rotation 515 | 0 516 | 517 | 518 | 519 | wxgui_scopesink2 520 | 521 | id 522 | wxgui_scopesink2_1 523 | 524 | 525 | _enabled 526 | True 527 | 528 | 529 | type 530 | float 531 | 532 | 533 | title 534 | Scope Plot 535 | 536 | 537 | samp_rate 538 | channel_rate 539 | 540 | 541 | v_scale 542 | 1.5 543 | 544 | 545 | v_offset 546 | 0 547 | 548 | 549 | t_scale 550 | 0.05 551 | 552 | 553 | ac_couple 554 | False 555 | 556 | 557 | xy_mode 558 | False 559 | 560 | 561 | num_inputs 562 | 1 563 | 564 | 565 | win_size 566 | 567 | 568 | 569 | grid_pos 570 | 571 | 572 | 573 | notebook 574 | nb, 4 575 | 576 | 577 | trig_mode 578 | wxgui.TRIG_MODE_AUTO 579 | 580 | 581 | y_axis_label 582 | Counts 583 | 584 | 585 | alias 586 | 587 | 588 | 589 | affinity 590 | 591 | 592 | 593 | _coordinate 594 | (1104, 442) 595 | 596 | 597 | _rotation 598 | 0 599 | 600 | 601 | 602 | fir_filter_xxx 603 | 604 | id 605 | fir_filter_xxx_0 606 | 607 | 608 | _enabled 609 | True 610 | 611 | 612 | type 613 | fff 614 | 615 | 616 | decim 617 | 1 618 | 619 | 620 | taps 621 | (1.0/samp_per_sym,)*samp_per_sym 622 | 623 | 624 | samp_delay 625 | 0 626 | 627 | 628 | alias 629 | 630 | 631 | 632 | affinity 633 | 634 | 635 | 636 | minoutbuf 637 | 0 638 | 639 | 640 | maxoutbuf 641 | 0 642 | 643 | 644 | _coordinate 645 | (835, 598) 646 | 647 | 648 | _rotation 649 | 0 650 | 651 | 652 | 653 | variable_slider 654 | 655 | id 656 | xlate_bandwidth 657 | 658 | 659 | _enabled 660 | True 661 | 662 | 663 | label 664 | Xlate BW 665 | 666 | 667 | value 668 | 12500 669 | 670 | 671 | min 672 | 5000 673 | 674 | 675 | max 676 | 50000 677 | 678 | 679 | num_steps 680 | 1000 681 | 682 | 683 | style 684 | wx.SL_HORIZONTAL 685 | 686 | 687 | converver 688 | float_converter 689 | 690 | 691 | grid_pos 692 | 693 | 694 | 695 | notebook 696 | 697 | 698 | 699 | alias 700 | 701 | 702 | 703 | _coordinate 704 | (376, 524) 705 | 706 | 707 | _rotation 708 | 0 709 | 710 | 711 | 712 | wxgui_waterfallsink2 713 | 714 | id 715 | wxgui_waterfallsink2_0 716 | 717 | 718 | _enabled 719 | True 720 | 721 | 722 | type 723 | complex 724 | 725 | 726 | title 727 | Waterfall Plot 728 | 729 | 730 | samp_rate 731 | samp_rate 732 | 733 | 734 | baseband_freq 735 | 0 736 | 737 | 738 | dynamic_range 739 | 100 740 | 741 | 742 | ref_level 743 | 50 744 | 745 | 746 | ref_scale 747 | 2.0 748 | 749 | 750 | fft_size 751 | 512 752 | 753 | 754 | fft_rate 755 | 15 756 | 757 | 758 | average 759 | False 760 | 761 | 762 | avg_alpha 763 | 0 764 | 765 | 766 | win 767 | window.flattop 768 | 769 | 770 | win_size 771 | 772 | 773 | 774 | grid_pos 775 | 776 | 777 | 778 | notebook 779 | nb, 1 780 | 781 | 782 | freqvar 783 | None 784 | 785 | 786 | alias 787 | 788 | 789 | 790 | affinity 791 | 792 | 793 | 794 | _coordinate 795 | (672, 61) 796 | 797 | 798 | _rotation 799 | 0 800 | 801 | 802 | 803 | wxgui_fftsink2 804 | 805 | id 806 | wxgui_fftsink2_0 807 | 808 | 809 | _enabled 810 | True 811 | 812 | 813 | type 814 | complex 815 | 816 | 817 | title 818 | FFT Plot 819 | 820 | 821 | samp_rate 822 | samp_rate 823 | 824 | 825 | baseband_freq 826 | 0 827 | 828 | 829 | y_per_div 830 | 20 831 | 832 | 833 | y_divs 834 | 10 835 | 836 | 837 | ref_level 838 | 0 839 | 840 | 841 | ref_scale 842 | 2.0 843 | 844 | 845 | fft_size 846 | 1024 847 | 848 | 849 | fft_rate 850 | 30 851 | 852 | 853 | peak_hold 854 | False 855 | 856 | 857 | average 858 | True 859 | 860 | 861 | avg_alpha 862 | 0 863 | 864 | 865 | win 866 | None 867 | 868 | 869 | win_size 870 | 871 | 872 | 873 | grid_pos 874 | 875 | 876 | 877 | notebook 878 | nb, 0 879 | 880 | 881 | freqvar 882 | 0 883 | 884 | 885 | alias 886 | 887 | 888 | 889 | affinity 890 | 891 | 892 | 893 | _coordinate 894 | (912, 39) 895 | 896 | 897 | _rotation 898 | 0 899 | 900 | 901 | 902 | blocks_throttle 903 | 904 | id 905 | blocks_throttle_0 906 | 907 | 908 | _enabled 909 | True 910 | 911 | 912 | type 913 | complex 914 | 915 | 916 | samples_per_second 917 | 48000 918 | 919 | 920 | vlen 921 | 1 922 | 923 | 924 | ignoretag 925 | True 926 | 927 | 928 | alias 929 | 930 | 931 | 932 | affinity 933 | 934 | 935 | 936 | minoutbuf 937 | 0 938 | 939 | 940 | maxoutbuf 941 | 0 942 | 943 | 944 | _coordinate 945 | (440, 224) 946 | 947 | 948 | _rotation 949 | 0 950 | 951 | 952 | 953 | freq_xlating_fir_filter_xxx 954 | 955 | id 956 | freq_xlating_fir_filter_xxx_0 957 | 958 | 959 | _enabled 960 | True 961 | 962 | 963 | type 964 | ccc 965 | 966 | 967 | decim 968 | 1 969 | 970 | 971 | taps 972 | firdes.low_pass(1, samp_rate, xlate_bandwidth/2, 5000) 973 | 974 | 975 | center_freq 976 | xlate_offset_fine 977 | 978 | 979 | samp_rate 980 | samp_rate 981 | 982 | 983 | alias 984 | 985 | 986 | 987 | affinity 988 | 989 | 990 | 991 | minoutbuf 992 | 0 993 | 994 | 995 | maxoutbuf 996 | 0 997 | 998 | 999 | _coordinate 1000 | (400, 393) 1001 | 1002 | 1003 | _rotation 1004 | 0 1005 | 1006 | 1007 | 1008 | variable_slider 1009 | 1010 | id 1011 | xlate_offset_fine 1012 | 1013 | 1014 | _enabled 1015 | True 1016 | 1017 | 1018 | label 1019 | Fine Offset 1020 | 1021 | 1022 | value 1023 | 0 1024 | 1025 | 1026 | min 1027 | -10000 1028 | 1029 | 1030 | max 1031 | 10000 1032 | 1033 | 1034 | num_steps 1035 | 1000 1036 | 1037 | 1038 | style 1039 | wx.SL_HORIZONTAL 1040 | 1041 | 1042 | converver 1043 | float_converter 1044 | 1045 | 1046 | grid_pos 1047 | 1048 | 1049 | 1050 | notebook 1051 | 1052 | 1053 | 1054 | alias 1055 | 1056 | 1057 | 1058 | _coordinate 1059 | (464, 820) 1060 | 1061 | 1062 | _rotation 1063 | 0 1064 | 1065 | 1066 | 1067 | analog_quadrature_demod_cf 1068 | 1069 | id 1070 | analog_quadrature_demod_cf_0 1071 | 1072 | 1073 | _enabled 1074 | True 1075 | 1076 | 1077 | gain 1078 | demod_gain 1079 | 1080 | 1081 | alias 1082 | 1083 | 1084 | 1085 | affinity 1086 | 1087 | 1088 | 1089 | minoutbuf 1090 | 0 1091 | 1092 | 1093 | maxoutbuf 1094 | 0 1095 | 1096 | 1097 | _coordinate 1098 | (598, 536) 1099 | 1100 | 1101 | _rotation 1102 | 0 1103 | 1104 | 1105 | 1106 | variable_slider 1107 | 1108 | id 1109 | demod_gain 1110 | 1111 | 1112 | _enabled 1113 | True 1114 | 1115 | 1116 | label 1117 | Quad Demog Gain 1118 | 1119 | 1120 | value 1121 | 1 1122 | 1123 | 1124 | min 1125 | 1 1126 | 1127 | 1128 | max 1129 | 100 1130 | 1131 | 1132 | num_steps 1133 | 1 1134 | 1135 | 1136 | style 1137 | wx.SL_HORIZONTAL 1138 | 1139 | 1140 | converver 1141 | float_converter 1142 | 1143 | 1144 | grid_pos 1145 | 1146 | 1147 | 1148 | notebook 1149 | 1150 | 1151 | 1152 | alias 1153 | 1154 | 1155 | 1156 | _coordinate 1157 | (336, 676) 1158 | 1159 | 1160 | _rotation 1161 | 0 1162 | 1163 | 1164 | 1165 | dsd_block_ff 1166 | 1167 | id 1168 | dsd_block_ff_1 1169 | 1170 | 1171 | _enabled 1172 | True 1173 | 1174 | 1175 | frame 1176 | dsd.dsd_FRAME_P25_PHASE_1 1177 | 1178 | 1179 | mod 1180 | dsd.dsd_MOD_GFSK 1181 | 1182 | 1183 | uvquality 1184 | 3 1185 | 1186 | 1187 | errorbars 1188 | True 1189 | 1190 | 1191 | verbosity 1192 | 2 1193 | 1194 | 1195 | empty 1196 | False 1197 | 1198 | 1199 | num 1200 | 0 1201 | 1202 | 1203 | alias 1204 | 1205 | 1206 | 1207 | affinity 1208 | 1209 | 1210 | 1211 | minoutbuf 1212 | 0 1213 | 1214 | 1215 | maxoutbuf 1216 | 0 1217 | 1218 | 1219 | _coordinate 1220 | (656, 771) 1221 | 1222 | 1223 | _rotation 1224 | 0 1225 | 1226 | 1227 | 1228 | audio_sink 1229 | 1230 | id 1231 | audio_sink_0 1232 | 1233 | 1234 | _enabled 1235 | False 1236 | 1237 | 1238 | samp_rate 1239 | 48000 1240 | 1241 | 1242 | device_name 1243 | 1244 | 1245 | 1246 | ok_to_block 1247 | True 1248 | 1249 | 1250 | num_inputs 1251 | 1 1252 | 1253 | 1254 | alias 1255 | 1256 | 1257 | 1258 | affinity 1259 | 1260 | 1261 | 1262 | _coordinate 1263 | (1136, 742) 1264 | 1265 | 1266 | _rotation 1267 | 0 1268 | 1269 | 1270 | 1271 | blocks_multiply_const_vxx 1272 | 1273 | id 1274 | blocks_multiply_const_vxx_0 1275 | 1276 | 1277 | _enabled 1278 | False 1279 | 1280 | 1281 | type 1282 | float 1283 | 1284 | 1285 | const 1286 | 10.**(audio_mul/10.) 1287 | 1288 | 1289 | vlen 1290 | 1 1291 | 1292 | 1293 | alias 1294 | 1295 | 1296 | 1297 | affinity 1298 | 1299 | 1300 | 1301 | minoutbuf 1302 | 0 1303 | 1304 | 1305 | maxoutbuf 1306 | 0 1307 | 1308 | 1309 | _coordinate 1310 | (1128, 663) 1311 | 1312 | 1313 | _rotation 1314 | 0 1315 | 1316 | 1317 | 1318 | rational_resampler_xxx 1319 | 1320 | id 1321 | rational_resampler_xxx_1 1322 | 1323 | 1324 | _enabled 1325 | False 1326 | 1327 | 1328 | type 1329 | fff 1330 | 1331 | 1332 | interp 1333 | 8000 1334 | 1335 | 1336 | decim 1337 | 48000 1338 | 1339 | 1340 | taps 1341 | 1342 | 1343 | 1344 | fbw 1345 | 0 1346 | 1347 | 1348 | alias 1349 | 1350 | 1351 | 1352 | affinity 1353 | 1354 | 1355 | 1356 | minoutbuf 1357 | 0 1358 | 1359 | 1360 | maxoutbuf 1361 | 0 1362 | 1363 | 1364 | _coordinate 1365 | (920, 793) 1366 | 1367 | 1368 | _rotation 1369 | 0 1370 | 1371 | 1372 | 1373 | blocks_null_sink 1374 | 1375 | id 1376 | blocks_null_sink_0 1377 | 1378 | 1379 | _enabled 1380 | True 1381 | 1382 | 1383 | type 1384 | float 1385 | 1386 | 1387 | vlen 1388 | 1 1389 | 1390 | 1391 | num_inputs 1392 | 1 1393 | 1394 | 1395 | bus_conns 1396 | [[0,],] 1397 | 1398 | 1399 | alias 1400 | 1401 | 1402 | 1403 | affinity 1404 | 1405 | 1406 | 1407 | _coordinate 1408 | (1008, 904) 1409 | 1410 | 1411 | _rotation 1412 | 0 1413 | 1414 | 1415 | 1416 | blocks_file_source 1417 | 1418 | id 1419 | blocks_file_source_0 1420 | 1421 | 1422 | _enabled 1423 | True 1424 | 1425 | 1426 | file 1427 | /Users/luke/Programming/dsd-debug/103-1426965236_8.57988e+08.raw 1428 | 1429 | 1430 | type 1431 | complex 1432 | 1433 | 1434 | repeat 1435 | True 1436 | 1437 | 1438 | vlen 1439 | 1 1440 | 1441 | 1442 | alias 1443 | 1444 | 1445 | 1446 | affinity 1447 | 1448 | 1449 | 1450 | minoutbuf 1451 | 0 1452 | 1453 | 1454 | maxoutbuf 1455 | 0 1456 | 1457 | 1458 | _coordinate 1459 | (216, 221) 1460 | 1461 | 1462 | _rotation 1463 | 0 1464 | 1465 | 1466 | 1467 | blocks_multiply_const_vxx_0 1468 | audio_sink_0 1469 | 0 1470 | 0 1471 | 1472 | 1473 | analog_quadrature_demod_cf_0 1474 | fir_filter_xxx_0 1475 | 0 1476 | 0 1477 | 1478 | 1479 | blocks_throttle_0 1480 | wxgui_waterfallsink2_0 1481 | 0 1482 | 0 1483 | 1484 | 1485 | blocks_throttle_0 1486 | wxgui_fftsink2_0 1487 | 0 1488 | 0 1489 | 1490 | 1491 | blocks_file_source_0 1492 | blocks_throttle_0 1493 | 0 1494 | 0 1495 | 1496 | 1497 | rational_resampler_xxx_1 1498 | blocks_multiply_const_vxx_0 1499 | 0 1500 | 0 1501 | 1502 | 1503 | fir_filter_xxx_0 1504 | dsd_block_ff_1 1505 | 0 1506 | 0 1507 | 1508 | 1509 | dsd_block_ff_1 1510 | rational_resampler_xxx_1 1511 | 0 1512 | 0 1513 | 1514 | 1515 | freq_xlating_fir_filter_xxx_0 1516 | wxgui_waterfallsink2_0_0 1517 | 0 1518 | 0 1519 | 1520 | 1521 | freq_xlating_fir_filter_xxx_0 1522 | analog_quadrature_demod_cf_0 1523 | 0 1524 | 0 1525 | 1526 | 1527 | freq_xlating_fir_filter_xxx_0 1528 | wxgui_fftsink2_0_0 1529 | 0 1530 | 0 1531 | 1532 | 1533 | analog_quadrature_demod_cf_0 1534 | wxgui_scopesink2_1 1535 | 0 1536 | 0 1537 | 1538 | 1539 | blocks_throttle_0 1540 | freq_xlating_fir_filter_xxx_0 1541 | 0 1542 | 0 1543 | 1544 | 1545 | dsd_block_ff_1 1546 | blocks_null_sink_0 1547 | 0 1548 | 0 1549 | 1550 | 1551 | -------------------------------------------------------------------------------- /debug_recorder.cc: -------------------------------------------------------------------------------- 1 | 2 | #include "debug_recorder.h" 3 | using namespace std; 4 | 5 | bool debug_recorder::logging = false; 6 | 7 | debug_recorder_sptr make_debug_recorder(Source *src, long t, int n) 8 | { 9 | return gnuradio::get_initial_sptr(new debug_recorder(src, t, n)); 10 | } 11 | 12 | debug_recorder::debug_recorder(Source *src, long t, int n) 13 | : gr::hier_block2 ("debug_recorder", 14 | gr::io_signature::make (1, 1, sizeof(gr_complex)), 15 | gr::io_signature::make (0, 0, sizeof(float))) 16 | { 17 | source = src; 18 | freq = source->get_center(); 19 | center = source->get_center(); 20 | samp_rate = source->get_rate(); 21 | talkgroup = t; 22 | num = n; 23 | active = false; 24 | 25 | 26 | starttime = time(NULL); 27 | 28 | float offset = 0; //have to flip for 3.7 29 | 30 | int samp_per_sym = 10; 31 | double decim = floor(samp_rate / 100000); 32 | float xlate_bandwidth = 25000; //14000; //24260.0; 33 | float channel_rate = 4800 * samp_per_sym; 34 | double pre_channel_rate = samp_rate/decim; 35 | 36 | 37 | 38 | lpf_taps = gr::filter::firdes::low_pass(1, samp_rate, xlate_bandwidth/2, 5000, gr::filter::firdes::WIN_BLACKMAN); 39 | 40 | prefilter = gr::filter::freq_xlating_fir_filter_ccf::make(decim, 41 | lpf_taps, 42 | offset, 43 | samp_rate); 44 | unsigned int d = GCD(channel_rate, pre_channel_rate); 45 | channel_rate = floor(channel_rate / d); 46 | pre_channel_rate = floor(pre_channel_rate / d); 47 | resampler_taps = design_filter(channel_rate, pre_channel_rate); 48 | 49 | downsample_sig = gr::filter::rational_resampler_base_ccf::make(channel_rate, pre_channel_rate, resampler_taps); 50 | valve = gr::blocks::copy::make(sizeof(gr_complex)); 51 | valve->set_enabled(false); 52 | 53 | 54 | tm *ltm = localtime(&starttime); 55 | 56 | std::stringstream path_stream; 57 | path_stream << boost::filesystem::current_path().string() << "/debug"; 58 | 59 | boost::filesystem::create_directories(path_stream.str()); 60 | sprintf(filename, "%s/%ld-%ld_%g.raw", path_stream.str().c_str(),talkgroup,starttime,freq); 61 | raw_sink = gr::blocks::file_sink::make(sizeof(gr_complex), filename); 62 | 63 | 64 | 65 | 66 | connect(self(),0, valve,0); 67 | connect(valve,0, prefilter,0); 68 | connect(prefilter, 0, downsample_sig, 0); 69 | connect(downsample_sig, 0, raw_sink, 0); 70 | } 71 | 72 | debug_recorder::~debug_recorder() { 73 | 74 | } 75 | 76 | 77 | bool debug_recorder::is_active() { 78 | return active; 79 | } 80 | 81 | long debug_recorder::get_talkgroup() { 82 | return talkgroup; 83 | } 84 | 85 | double debug_recorder::get_freq() { 86 | return freq; 87 | } 88 | 89 | Source *debug_recorder::get_source() { 90 | return source; 91 | } 92 | 93 | char *debug_recorder::get_filename() { 94 | return filename; 95 | } 96 | 97 | void debug_recorder::tune_offset(double f) { 98 | freq = f; 99 | long offset_amount = (f - center); 100 | prefilter->set_center_freq(offset_amount); // have to flip this for 3.7 101 | } 102 | void debug_recorder::deactivate() { 103 | BOOST_LOG_TRIVIAL(info) << "debug_recorder.cc: Deactivating Logger [ " << num << " ] - freq[ " << freq << "] \t talkgroup[ " << talkgroup << " ]"; 104 | 105 | 106 | raw_sink->close(); 107 | 108 | 109 | 110 | active = false; 111 | valve->set_enabled(false); 112 | 113 | 114 | 115 | 116 | } 117 | 118 | void debug_recorder::activate( long t, double f, int n, char *existing_filename) { 119 | 120 | starttime = time(NULL); 121 | 122 | talkgroup = t; 123 | freq = f; 124 | 125 | tm *ltm = localtime(&starttime); 126 | BOOST_LOG_TRIVIAL(info) << "debug_recorder.cc: Activating Logger [ " << num << " ] - freq[ " << freq << "] \t talkgroup[ " << talkgroup << " ]"; 127 | 128 | 129 | prefilter->set_center_freq(f - center); // have to flip for 3.7 130 | std::stringstream path_stream; 131 | path_stream << boost::filesystem::current_path().string() << "/debug"; 132 | 133 | boost::filesystem::create_directories(path_stream.str()); 134 | sprintf(filename, "%s/%ld-%ld_%g.raw", path_stream.str().c_str(),talkgroup,starttime,freq); 135 | 136 | 137 | raw_sink->open(filename); 138 | 139 | 140 | active = true; 141 | valve->set_enabled(true); 142 | } 143 | -------------------------------------------------------------------------------- /debug_recorder.h: -------------------------------------------------------------------------------- 1 | #ifndef DEBUG_RECORDER_H 2 | #define DEBUG_RECORDER_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | //Valve 41 | //#include 42 | //#include 43 | #include 44 | //#include 45 | //#include 46 | #include "nonstop_wavfile_sink.h" 47 | 48 | //#include 49 | #include 50 | //#include 51 | #include "recorder.h" 52 | #include "smartnet.h" 53 | 54 | class Source; 55 | class debug_recorder; 56 | typedef boost::shared_ptr debug_recorder_sptr; 57 | 58 | #include "source.h" 59 | 60 | debug_recorder_sptr make_debug_recorder( Source *src, long t, int n); 61 | 62 | class debug_recorder : public gr::hier_block2 , public Recorder 63 | { 64 | friend debug_recorder_sptr make_debug_recorder( Source *src, long t, int n); 65 | protected: 66 | debug_recorder( Source *src, long t, int n); 67 | 68 | public: 69 | ~debug_recorder(); 70 | void tune_offset(double f); 71 | void activate( long t, double f, int n, char *existing_filename); 72 | 73 | void deactivate(); 74 | double get_freq(); 75 | Source *get_source(); 76 | long get_talkgroup(); 77 | bool is_active(); 78 | int lastupdate(); 79 | long elapsed(); 80 | void close(); 81 | void mute(); 82 | void unmute(); 83 | char *get_filename(); 84 | //void forecast(int noutput_items, gr_vector_int &ninput_items_required); 85 | static bool logging; 86 | private: 87 | double center, freq; 88 | bool recording; 89 | long talkgroup; 90 | long samp_rate; 91 | time_t timestamp; 92 | time_t starttime; 93 | char filename[160]; 94 | 95 | int num; 96 | 97 | bool iam_logging; 98 | bool active; 99 | std::vector lpf_taps; 100 | std::vector resampler_taps; 101 | std::vector sym_taps; 102 | 103 | Source *source; 104 | 105 | /* GR blocks */ 106 | gr::filter::fir_filter_ccf::sptr lpf; 107 | gr::filter::fir_filter_fff::sptr lpf_second; 108 | gr::filter::fir_filter_fff::sptr sym_filter; 109 | gr::filter::freq_xlating_fir_filter_ccf::sptr prefilter; 110 | gr::analog::sig_source_c::sptr offset_sig; 111 | 112 | gr::blocks::multiply_cc::sptr mixer; 113 | gr::blocks::file_sink::sptr fs; 114 | gr::blocks::multiply_const_ff::sptr quiet; 115 | gr::blocks::multiply_const_ff::sptr levels; 116 | 117 | 118 | gr::filter::rational_resampler_base_ccf::sptr downsample_sig; 119 | gr::filter::rational_resampler_base_fff::sptr upsample_audio; 120 | //gr::analog::quadrature_demod_cf::sptr demod; 121 | gr::analog::quadrature_demod_cf::sptr demod; 122 | 123 | gr::blocks::file_sink::sptr raw_sink; 124 | gr::blocks::null_sink::sptr null_sink; 125 | gr::blocks::head::sptr head_source; 126 | gr::blocks::copy::sptr valve; 127 | //gr_kludge_copy_sptr copier; 128 | 129 | }; 130 | 131 | 132 | #endif 133 | -------------------------------------------------------------------------------- /main.cc: -------------------------------------------------------------------------------- 1 | 2 | //#define DSD 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | 33 | 34 | 35 | #include "p25_decoder.h" 36 | 37 | 38 | 39 | 40 | #include 41 | 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | 51 | 52 | using namespace std; 53 | namespace logging = boost::log; 54 | 55 | 56 | 57 | string system_type; 58 | gr::top_block_sptr tb; 59 | 60 | gr::msg_queue::sptr queue; 61 | 62 | volatile sig_atomic_t exit_flag = 0; 63 | 64 | 65 | 66 | void exit_interupt(int sig) { // can be called asynchronously 67 | exit_flag = 1; // set flag 68 | } 69 | 70 | 71 | 72 | 73 | int main(int argc, // Number of strings in array argv 74 | char *argv[]) 75 | { 76 | gr::blocks::file_source::sptr source; 77 | gr::blocks::throttle::sptr throttle; 78 | 79 | p25_decoder_sptr decoder = make_p25_decoder(argv[2]); 80 | BOOST_STATIC_ASSERT(true) __attribute__((unused)); 81 | signal(SIGINT, exit_interupt); 82 | logging::core::get()->set_filter 83 | ( 84 | logging::trivial::severity >= logging::trivial::info 85 | ); 86 | 87 | tb = gr::make_top_block("Trunking"); 88 | source = gr::blocks::file_source::make(sizeof(float),argv[1], false); 89 | throttle =gr::blocks::throttle::make(sizeof(float),48000); 90 | 91 | 92 | 93 | tb->connect(source,0, throttle,0); 94 | tb->connect(throttle,0, decoder, 0); 95 | 96 | //tb->run(); 97 | tb->start(); 98 | 99 | //------------------------------------------------------------------ 100 | //-- stop flow graph execution 101 | //------------------------------------------------------------------ 102 | BOOST_LOG_TRIVIAL(info) << "stopping flow graph"; 103 | 104 | tb->wait(); 105 | 106 | 107 | 108 | 109 | 110 | return 0; 111 | 112 | } 113 | -------------------------------------------------------------------------------- /nonstop_wavfile_sink.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2008,2009,2013 Free Software Foundation, Inc. 4 | * 5 | * This file is part of GNU Radio 6 | * 7 | * GNU Radio is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 3, or (at your option) 10 | * any later version. 11 | * 12 | * GNU Radio is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with GNU Radio; see the file COPYING. If not, write to 19 | * the Free Software Foundation, Inc., 51 Franklin Street, 20 | * Boston, MA 02110-1301, USA. 21 | */ 22 | 23 | #ifndef INCLUDED_GR_NONSTOP_WAVFILE_SINK_H 24 | #define INCLUDED_GR_NONSTOP_WAVFILE_SINK_H 25 | 26 | #include 27 | #include 28 | 29 | namespace gr { 30 | namespace blocks { 31 | 32 | /*! 33 | * \brief Write stream to a Microsoft PCM (.wav) file. 34 | * \ingroup audio_blk 35 | * 36 | * \details 37 | * Values must be floats within [-1;1]. 38 | * Check gr_make_wavfile_sink() for extra info. 39 | */ 40 | class BLOCKS_API nonstop_wavfile_sink : virtual public sync_block 41 | { 42 | public: 43 | // gr::blocks::wavfile_sink::sptr 44 | typedef boost::shared_ptr sptr; 45 | 46 | /* 47 | * \param filename The .wav file to be opened 48 | * \param n_channels Number of channels (2 = stereo or I/Q output) 49 | * \param sample_rate Sample rate [S/s] 50 | * \param bits_per_sample 16 or 8 bit, default is 16 51 | */ 52 | static sptr make(const char *filename, 53 | int n_channels, 54 | unsigned int sample_rate, 55 | int bits_per_sample = 16); 56 | 57 | /*! 58 | * \brief Opens a new file and writes a WAV header. Thread-safe. 59 | */ 60 | virtual bool open(const char* filename) = 0; 61 | 62 | /*! 63 | * \brief Closes the currently active file and completes the WAV 64 | * header. Thread-safe. 65 | */ 66 | virtual void close() = 0; 67 | 68 | /*! 69 | * \brief Set the sample rate. This will not affect the WAV file 70 | * currently opened. Any following open() calls will use this new 71 | * sample rate. 72 | */ 73 | virtual void set_sample_rate(unsigned int sample_rate) = 0; 74 | 75 | /*! 76 | * \brief Set bits per sample. This will not affect the WAV file 77 | * currently opened (see set_sample_rate()). If the value is 78 | * neither 8 nor 16, the call is ignored and the current value 79 | * is kept. 80 | */ 81 | virtual void set_bits_per_sample(int bits_per_sample) = 0; 82 | 83 | virtual float length_in_seconds() = 0; 84 | }; 85 | 86 | } /* namespace blocks */ 87 | } /* namespace gr */ 88 | 89 | #endif /* INCLUDED_GR_WAVFILE_SINK_H */ -------------------------------------------------------------------------------- /nonstop_wavfile_sink_impl.cc: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2004,2006-2011,2013 Free Software Foundation, Inc. 4 | * 5 | * This file is part of GNU Radio 6 | * 7 | * GNU Radio is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 3, or (at your option) 10 | * any later version. 11 | * 12 | * GNU Radio is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with GNU Radio; see the file COPYING. If not, write to 19 | * the Free Software Foundation, Inc., 51 Franklin Street, 20 | * Boston, MA 02110-1301, USA. 21 | */ 22 | 23 | #ifdef HAVE_CONFIG_H 24 | #include "config.h" 25 | #endif 26 | 27 | #include "nonstop_wavfile_sink_impl.h" 28 | #include "nonstop_wavfile_sink.h" 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | // win32 (mingw/msvc) specific 40 | #ifdef HAVE_IO_H 41 | #include 42 | #endif 43 | #ifdef O_BINARY 44 | #define OUR_O_BINARY O_BINARY 45 | #else 46 | #define OUR_O_BINARY 0 47 | #endif 48 | 49 | // should be handled via configure 50 | #ifdef O_LARGEFILE 51 | #define OUR_O_LARGEFILE O_LARGEFILE 52 | #else 53 | #define OUR_O_LARGEFILE 0 54 | #endif 55 | 56 | namespace gr { 57 | namespace blocks { 58 | 59 | nonstop_wavfile_sink::sptr 60 | nonstop_wavfile_sink::make(const char *filename, 61 | int n_channels, 62 | unsigned int sample_rate, 63 | int bits_per_sample) 64 | { 65 | return gnuradio::get_initial_sptr 66 | (new nonstop_wavfile_sink_impl(filename, n_channels, 67 | sample_rate, bits_per_sample)); 68 | } 69 | 70 | nonstop_wavfile_sink_impl::nonstop_wavfile_sink_impl(const char *filename, 71 | int n_channels, 72 | unsigned int sample_rate, 73 | int bits_per_sample) 74 | : sync_block("nonstop_wavfile_sink", 75 | io_signature::make(1, n_channels, sizeof(float)), 76 | io_signature::make(0, 0, 0)), 77 | d_sample_rate(sample_rate), d_nchans(n_channels), 78 | d_fp(0), d_new_fp(0), d_updated(false) 79 | { 80 | if(bits_per_sample != 8 && bits_per_sample != 16) { 81 | throw std::runtime_error("Invalid bits per sample (supports 8 and 16)"); 82 | } 83 | d_bytes_per_sample = bits_per_sample / 8; 84 | d_bytes_per_sample_new = d_bytes_per_sample; 85 | 86 | if(!open(filename)) { 87 | throw std::runtime_error("can't open file"); 88 | } 89 | 90 | if(bits_per_sample == 8) { 91 | d_max_sample_val = 0xFF; 92 | d_min_sample_val = 0; 93 | d_normalize_fac = d_max_sample_val/2; 94 | d_normalize_shift = 1; 95 | } 96 | else { 97 | d_max_sample_val = 0x7FFF; 98 | d_min_sample_val = -0x7FFF; 99 | d_normalize_fac = d_max_sample_val; 100 | d_normalize_shift = 0; 101 | if(bits_per_sample != 16) { 102 | fprintf(stderr, "Invalid bits per sample value requested, using 16"); 103 | } 104 | } 105 | } 106 | 107 | bool 108 | nonstop_wavfile_sink_impl::open(const char* filename) 109 | { 110 | gr::thread::scoped_lock guard(d_mutex); 111 | 112 | // we use the open system call to get access to the O_LARGEFILE flag. 113 | int fd; 114 | if((fd = ::open(filename, 115 | O_WRONLY|O_CREAT|OUR_O_LARGEFILE|OUR_O_BINARY, 116 | 0664)) < 0) { 117 | perror(filename); 118 | return false; 119 | } 120 | 121 | if(d_new_fp) { // if we've already got a new one open, close it 122 | fclose(d_new_fp); 123 | d_new_fp = 0; 124 | } 125 | 126 | if((d_new_fp = fdopen (fd, "wb")) == NULL) { 127 | perror(filename); 128 | ::close(fd); // don't leak file descriptor if fdopen fails. 129 | return false; 130 | } 131 | d_updated = true; 132 | 133 | if(!wavheader_write(d_new_fp, 134 | d_sample_rate, 135 | d_nchans, 136 | d_bytes_per_sample_new)) { 137 | fprintf(stderr, "[%s] could not write to WAV file\n", __FILE__); 138 | exit(-1); 139 | } 140 | 141 | return true; 142 | } 143 | 144 | void 145 | nonstop_wavfile_sink_impl::close() 146 | { 147 | gr::thread::scoped_lock guard(d_mutex); 148 | 149 | if(!d_fp) 150 | return; 151 | 152 | close_wav(); 153 | } 154 | 155 | void 156 | nonstop_wavfile_sink_impl::close_wav() 157 | { 158 | unsigned int byte_count = d_sample_count * d_bytes_per_sample; 159 | 160 | wavheader_complete(d_fp, byte_count); 161 | 162 | fclose(d_fp); 163 | d_fp = NULL; 164 | } 165 | 166 | nonstop_wavfile_sink_impl::~nonstop_wavfile_sink_impl() 167 | { 168 | if(d_new_fp) { 169 | fclose(d_new_fp); 170 | d_new_fp = NULL; 171 | } 172 | 173 | close(); 174 | } 175 | 176 | bool nonstop_wavfile_sink_impl::stop() 177 | { 178 | 179 | 180 | return true; 181 | } 182 | 183 | int 184 | nonstop_wavfile_sink_impl::work(int noutput_items, 185 | gr_vector_const_void_star &input_items, 186 | gr_vector_void_star &output_items) 187 | { 188 | float **in = (float**)&input_items[0]; 189 | int n_in_chans = input_items.size(); 190 | 191 | short int sample_buf_s; 192 | 193 | int nwritten; 194 | 195 | gr::thread::scoped_lock guard(d_mutex); // hold mutex for duration of this block 196 | do_update(); // update: d_fp is reqd 197 | if(!d_fp) // drop output on the floor 198 | return noutput_items; 199 | 200 | for(nwritten = 0; nwritten < noutput_items; nwritten++) { 201 | for(int chan = 0; chan < d_nchans; chan++) { 202 | // Write zeros to channels which are in the WAV file 203 | // but don't have any inputs here 204 | if(chan < n_in_chans) { 205 | sample_buf_s = 206 | convert_to_short(in[chan][nwritten]); 207 | } 208 | else { 209 | sample_buf_s = 0; 210 | } 211 | 212 | wav_write_sample(d_fp, sample_buf_s, d_bytes_per_sample); 213 | 214 | if(feof(d_fp) || ferror(d_fp)) { 215 | fprintf(stderr, "[%s] file i/o error\n", __FILE__); 216 | close(); 217 | exit(-1); 218 | } 219 | d_sample_count++; 220 | } 221 | } 222 | 223 | return nwritten; 224 | } 225 | 226 | short int 227 | nonstop_wavfile_sink_impl::convert_to_short(float sample) 228 | { 229 | sample += d_normalize_shift; 230 | sample *= d_normalize_fac; 231 | if(sample > d_max_sample_val) { 232 | sample = d_max_sample_val; 233 | } 234 | else if(sample < d_min_sample_val) { 235 | sample = d_min_sample_val; 236 | } 237 | 238 | return (short int)boost::math::iround(sample); 239 | } 240 | 241 | void 242 | nonstop_wavfile_sink_impl::set_bits_per_sample(int bits_per_sample) 243 | { 244 | gr::thread::scoped_lock guard(d_mutex); 245 | if(bits_per_sample == 8 || bits_per_sample == 16) { 246 | d_bytes_per_sample_new = bits_per_sample / 8; 247 | } 248 | } 249 | 250 | void 251 | nonstop_wavfile_sink_impl::set_sample_rate(unsigned int sample_rate) 252 | { 253 | gr::thread::scoped_lock guard(d_mutex); 254 | d_sample_rate = sample_rate; 255 | } 256 | 257 | int 258 | nonstop_wavfile_sink_impl::bits_per_sample() 259 | { 260 | return d_bytes_per_sample_new; 261 | } 262 | 263 | unsigned int 264 | nonstop_wavfile_sink_impl::sample_rate() 265 | { 266 | return d_sample_rate; 267 | } 268 | 269 | float 270 | nonstop_wavfile_sink_impl::length_in_seconds() 271 | { 272 | return d_sample_count / d_sample_rate; 273 | } 274 | 275 | void 276 | nonstop_wavfile_sink_impl::do_update() 277 | { 278 | if(!d_updated) { 279 | return; 280 | } 281 | 282 | if(d_fp) { 283 | close_wav(); 284 | } 285 | 286 | d_fp = d_new_fp; // install new file pointer 287 | d_new_fp = 0; 288 | d_sample_count = 0; 289 | d_bytes_per_sample = d_bytes_per_sample_new; 290 | 291 | if(d_bytes_per_sample == 1) { 292 | d_max_sample_val = UCHAR_MAX; 293 | d_min_sample_val = 0; 294 | d_normalize_fac = d_max_sample_val/2; 295 | d_normalize_shift = 1; 296 | } 297 | else if(d_bytes_per_sample == 2) { 298 | d_max_sample_val = SHRT_MAX; 299 | d_min_sample_val = SHRT_MIN; 300 | d_normalize_fac = d_max_sample_val; 301 | d_normalize_shift = 0; 302 | } 303 | 304 | d_updated = false; 305 | } 306 | 307 | } /* namespace blocks */ 308 | } /* namespace gr */ -------------------------------------------------------------------------------- /nonstop_wavfile_sink_impl.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2008,2009,2013 Free Software Foundation, Inc. 4 | * 5 | * This file is part of GNU Radio 6 | * 7 | * GNU Radio is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 3, or (at your option) 10 | * any later version. 11 | * 12 | * GNU Radio is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with GNU Radio; see the file COPYING. If not, write to 19 | * the Free Software Foundation, Inc., 51 Franklin Street, 20 | * Boston, MA 02110-1301, USA. 21 | */ 22 | 23 | #ifndef INCLUDED_GR_nonstop_wavfile_SINK_IMPL_H 24 | #define INCLUDED_GR_nonstop_wavfile_SINK_IMPL_H 25 | 26 | #include "nonstop_wavfile_sink.h" 27 | #include 28 | 29 | namespace gr { 30 | namespace blocks { 31 | 32 | class nonstop_wavfile_sink_impl : public nonstop_wavfile_sink 33 | { 34 | private: 35 | unsigned d_sample_rate; 36 | int d_nchans; 37 | unsigned d_sample_count; 38 | int d_bytes_per_sample; 39 | int d_bytes_per_sample_new; 40 | int d_max_sample_val; 41 | int d_min_sample_val; 42 | int d_normalize_shift; 43 | int d_normalize_fac; 44 | 45 | FILE *d_fp; 46 | FILE *d_new_fp; 47 | bool d_updated; 48 | boost::mutex d_mutex; 49 | 50 | /*! 51 | * \brief Convert a sample value within [-1;+1] to a corresponding 52 | * short integer value 53 | */ 54 | short convert_to_short(float sample); 55 | 56 | /*! 57 | * \brief If any file changes have occurred, update now. This is called 58 | * internally by work() and thus doesn't usually need to be called by 59 | * hand. 60 | */ 61 | void do_update(); 62 | 63 | /*! 64 | * \brief Writes information to the WAV header which is not available 65 | * a-priori (chunk size etc.) and closes the file. Not thread-safe and 66 | * assumes d_fp is a valid file pointer, should thus only be called by 67 | * other methods. 68 | */ 69 | void close_wav(); 70 | 71 | protected: 72 | bool stop(); 73 | 74 | public: 75 | nonstop_wavfile_sink_impl(const char *filename, 76 | int n_channels, 77 | unsigned int sample_rate, 78 | int bits_per_sample); 79 | ~nonstop_wavfile_sink_impl(); 80 | 81 | bool open(const char* filename); 82 | void close(); 83 | 84 | void set_sample_rate(unsigned int sample_rate); 85 | void set_bits_per_sample(int bits_per_sample); 86 | 87 | int bits_per_sample(); 88 | unsigned int sample_rate(); 89 | 90 | float length_in_seconds(); 91 | 92 | int work(int noutput_items, 93 | gr_vector_const_void_star &input_items, 94 | gr_vector_void_star &output_items); 95 | }; 96 | 97 | } /* namespace blocks */ 98 | } /* namespace gr */ 99 | 100 | #endif /* INCLUDED_GR_nonstop_wavfile_SINK_IMPL_H */ -------------------------------------------------------------------------------- /p25_decoder.cc: -------------------------------------------------------------------------------- 1 | 2 | #include "p25_decoder.h" 3 | #include 4 | 5 | 6 | p25_decoder_sptr make_p25_decoder(char *filename) 7 | { 8 | return gnuradio::get_initial_sptr(new p25_decoder(filename)); 9 | } 10 | 11 | 12 | 13 | 14 | 15 | p25_decoder::p25_decoder(char *filename) 16 | : gr::hier_block2 ("p25_decoder", 17 | gr::io_signature::make (1, 1, sizeof(float)), 18 | gr::io_signature::make (0, 0, sizeof(float))) 19 | { 20 | 21 | 22 | 23 | 24 | 25 | float symbol_rate = 4800; 26 | double samples_per_symbol = 10; 27 | float symbol_deviation = 600.0; 28 | 29 | std::vector sym_taps; 30 | const double pi = M_PI; //boost::math::constants::pi(); 31 | 32 | timestamp = time(NULL); 33 | starttime = time(NULL); 34 | 35 | 36 | float if_rate = 48000; 37 | float gain_mu = 0.025; 38 | float costas_alpha = 0.04; 39 | double sps = 0.0; 40 | float bb_gain = 1.0; 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | // convert from radians such that signal is in -3/-1/+1/+3 49 | rescale = gr::blocks::multiply_const_ff::make( (1 / (pi / 4)) ); 50 | 51 | 52 | 53 | 54 | 55 | double symbol_decim = 1; 56 | 57 | tune_queue = gr::msg_queue::make(2); 58 | traffic_queue = gr::msg_queue::make(2); 59 | rx_queue = gr::msg_queue::make(100); 60 | const float l[] = { -2.0, 0.0, 2.0, 4.0 }; 61 | std::vector levels( l,l + sizeof( l ) / sizeof( l[0] ) ); 62 | slicer = gr::op25_repeater::fsk4_slicer_fb::make(levels); 63 | 64 | int udp_port = 0; 65 | int verbosity = 10; 66 | const char * wireshark_host="127.0.0.1"; 67 | bool do_imbe = 1; 68 | bool do_output = 1; 69 | bool do_msgq = 0; 70 | bool do_audio_output = 1; 71 | bool do_tdma = 0; 72 | op25_frame_assembler = gr::op25_repeater::p25_frame_assembler::make(wireshark_host,udp_port,verbosity,do_imbe, do_output, do_msgq, rx_queue, do_audio_output, do_tdma); 73 | 74 | converter = gr::blocks::short_to_float::make(1,32768.0);// 4096.0);//8192.0);//16384);//32768.0);//8192.0); 75 | 76 | float convert_num = float(1.0)/float(256.0); 77 | //float convert_num = float(1.0)/float(8192.0); 78 | //float convert_num = float(1.0)/float(32768.0); 79 | 80 | multiplier = gr::blocks::multiply_const_ff::make(convert_num); 81 | /* tm *ltm = localtime(&starttime); 82 | 83 | std::stringstream path_stream; 84 | path_stream << boost::filesystem::current_path().string() << "/" << 1900 + ltm->tm_year << "/" << 1 + ltm->tm_mon << "/" << ltm->tm_mday; 85 | 86 | boost::filesystem::create_directories(path_stream.str()); 87 | sprintf(filename, "%s/%ld-%ld_%g.wav", path_stream.str().c_str(),talkgroup,timestamp,freq);*/ 88 | wav_sink = gr::blocks::nonstop_wavfile_sink::make(filename,1,8000,16); 89 | 90 | null_sink = gr::blocks::null_sink::make(sizeof(int16_t)); //sizeof(gr_complex)); 91 | 92 | 93 | 94 | connect(self(),0, rescale, 0); 95 | connect(rescale, 0, slicer, 0); 96 | 97 | 98 | connect(slicer,0, op25_frame_assembler,0); 99 | 100 | 101 | connect(op25_frame_assembler, 0, converter,0); 102 | 103 | connect(converter, 0, wav_sink,0); 104 | 105 | } 106 | 107 | 108 | p25_decoder::~p25_decoder() { 109 | 110 | wav_sink->close(); 111 | } 112 | 113 | 114 | -------------------------------------------------------------------------------- /p25_decoder.h: -------------------------------------------------------------------------------- 1 | #ifndef P25_RECORDER_H 2 | #define P25_RECORDER_H 3 | 4 | #define _USE_MATH_DEFINES 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | 30 | #include 31 | #include 32 | 33 | #include 34 | 35 | #include 36 | 37 | 38 | #include 39 | #include 40 | #include 41 | 42 | #include 43 | #include 44 | #include 45 | #include 46 | 47 | #include 48 | #include 49 | 50 | #include 51 | 52 | #include 53 | #include 54 | #include 55 | #include 56 | #include 57 | #include 58 | #include 59 | #include 60 | #include 61 | 62 | #include 63 | #include 64 | 65 | #include 66 | 67 | #include "nonstop_wavfile_sink.h" 68 | #include 69 | 70 | 71 | class p25_decoder; 72 | typedef boost::shared_ptr p25_decoder_sptr; 73 | p25_decoder_sptr make_p25_decoder(char *filename); 74 | 75 | 76 | 77 | class p25_decoder : public gr::hier_block2 78 | { 79 | friend p25_decoder_sptr make_p25_decoder(char *filename); 80 | protected: 81 | p25_decoder(char *filename); 82 | 83 | public: 84 | ~p25_decoder(); 85 | 86 | 87 | gr::msg_queue::sptr tune_queue; 88 | gr::msg_queue::sptr traffic_queue; 89 | gr::msg_queue::sptr rx_queue; 90 | //void forecast(int noutput_items, gr_vector_int &ninput_items_required); 91 | 92 | private: 93 | double center, freq; 94 | bool muted; 95 | long talkgroup; 96 | time_t timestamp; 97 | time_t starttime; 98 | 99 | int num; 100 | 101 | bool iam_logging; 102 | bool active; 103 | 104 | 105 | std::vector lpf_coeffs; 106 | std::vector arb_taps; 107 | std::vector sym_taps; 108 | 109 | /* GR blocks */ 110 | gr::filter::fir_filter_ccf::sptr lpf; 111 | gr::filter::fir_filter_fff::sptr sym_filter; 112 | 113 | gr::analog::sig_source_c::sptr lo; 114 | 115 | gr::digital::diff_phasor_cc::sptr diffdec; 116 | 117 | gr::blocks::multiply_cc::sptr mixer; 118 | gr::blocks::file_sink::sptr fs; 119 | 120 | gr::filter::pfb_arb_resampler_ccf::sptr arb_resampler; 121 | 122 | gr::filter::rational_resampler_base_ccf::sptr downsample_sig; 123 | gr::filter::rational_resampler_base_fff::sptr upsample_audio; 124 | 125 | gr::analog::quadrature_demod_cf::sptr fm_demod; 126 | gr::analog::feedforward_agc_cc::sptr agc; 127 | 128 | gr::blocks::nonstop_wavfile_sink::sptr wav_sink; 129 | 130 | gr::blocks::null_sink::sptr null_sink; 131 | 132 | //gr::blocks::char_to_float::sptr converter; 133 | gr::blocks::short_to_float::sptr converter; 134 | gr::blocks::copy::sptr valve; 135 | gr::filter::freq_xlating_fir_filter_ccf::sptr prefilter; 136 | gr::blocks::multiply_const_ff::sptr multiplier; 137 | gr::blocks::multiply_const_ff::sptr rescale; 138 | gr::blocks::multiply_const_ff::sptr baseband_amp; 139 | gr::blocks::complex_to_arg::sptr to_float; 140 | gr::op25::fsk4_demod_ff::sptr fsk4_demod; 141 | gr::op25_repeater::p25_frame_assembler::sptr op25_frame_assembler; 142 | 143 | gr::op25_repeater::fsk4_slicer_fb::sptr slicer; 144 | gr::op25_repeater::vocoder::sptr op25_vocoder; 145 | gr::op25_repeater::gardner_costas_cc::sptr costas_clock; 146 | gr::blocks::file_sink::sptr raw_sink; 147 | unsigned GCD(unsigned u, unsigned v); 148 | std::vector design_filter(double interpolation, double deci); 149 | }; 150 | 151 | 152 | #endif 153 | 154 | -------------------------------------------------------------------------------- /tes.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robotastic/p25-decoder/4030f8d39e76acd2e5acb55e218997cd5a41a078/tes.wav -------------------------------------------------------------------------------- /test3.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robotastic/p25-decoder/4030f8d39e76acd2e5acb55e218997cd5a41a078/test3.wav -------------------------------------------------------------------------------- /wavfile.cc: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2004,2008,2012-2013 Free Software Foundation, Inc. 4 | * 5 | * This file is part of GNU Radio 6 | * 7 | * GNU Radio is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 3, or (at your option) 10 | * any later version. 11 | * 12 | * GNU Radio is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with GNU Radio; see the file COPYING. If not, write to 19 | * the Free Software Foundation, Inc., 51 Franklin Street, 20 | * Boston, MA 02110-1301, USA. 21 | */ 22 | 23 | #ifdef HAVE_CONFIG_H 24 | #include "config.h" 25 | #endif 26 | 27 | #include 28 | #include 29 | #include 30 | #include //BOOST_BIG_ENDIAN 31 | 32 | namespace gr { 33 | namespace blocks { 34 | #define VALID_COMPRESSION_TYPE 0x0001 35 | 36 | // Basically, this is the opposite of htonx() and ntohx() 37 | // Define host to/from worknet (little endian) short and long 38 | #ifdef BOOST_BIG_ENDIAN 39 | 40 | static inline uint16_t __gri_wav_bs16(uint16_t x) 41 | { 42 | return (x>>8) | (x<<8); 43 | } 44 | 45 | static inline uint32_t __gri_wav_bs32(uint32_t x) 46 | { 47 | return (uint32_t(__gri_wav_bs16(uint16_t(x&0xfffful)))<<16) | (__gri_wav_bs16(uint16_t(x>>16))); 48 | } 49 | 50 | #define htowl(x) __gri_wav_bs32(x) 51 | #define wtohl(x) __gri_wav_bs32(x) 52 | #define htows(x) __gri_wav_bs16(x) 53 | #define wtohs(x) __gri_wav_bs16(x) 54 | 55 | #else 56 | 57 | #define htowl(x) uint32_t(x) 58 | #define wtohl(x) uint32_t(x) 59 | #define htows(x) uint16_t(x) 60 | #define wtohs(x) uint16_t(x) 61 | 62 | #endif // BOOST_BIG_ENDIAN 63 | 64 | // WAV files are always little-endian, so we need some byte switching macros 65 | static inline uint32_t host_to_wav(uint32_t x) { 66 | return htowl(x); 67 | } 68 | static inline uint16_t host_to_wav(uint16_t x) { 69 | return htows(x); 70 | } 71 | static inline int16_t host_to_wav(int16_t x) { 72 | return htows(x); 73 | } 74 | static inline uint32_t wav_to_host(uint32_t x) { 75 | return wtohl(x); 76 | } 77 | static inline uint16_t wav_to_host(uint16_t x) { 78 | return wtohs(x); 79 | } 80 | static inline int16_t wav_to_host(int16_t x) { 81 | return wtohs(x); 82 | } 83 | 84 | bool 85 | wavheader_parse(FILE *fp, 86 | unsigned int &sample_rate_o, 87 | int &nchans_o, 88 | int &bytes_per_sample_o, 89 | int &first_sample_pos_o, 90 | unsigned int &samples_per_chan_o) 91 | { 92 | // _o variables take return values 93 | char str_buf[8] = {0}; 94 | 95 | uint32_t file_size; 96 | uint32_t fmt_hdr_skip; 97 | uint16_t compression_type; 98 | uint16_t nchans; 99 | uint32_t sample_rate; 100 | uint32_t avg_bytes_per_sec; 101 | uint16_t block_align; 102 | uint16_t bits_per_sample; 103 | uint32_t chunk_size; 104 | 105 | size_t fresult; 106 | 107 | fresult = fread(str_buf, 1, 4, fp); 108 | if(fresult != 4 || strncmp(str_buf, "RIFF", 4) || feof(fp)) { 109 | return false; 110 | } 111 | 112 | fresult = fread(&file_size, 1, 4, fp); 113 | 114 | fresult = fread(str_buf, 1, 8, fp); 115 | if(fresult != 8 || strncmp(str_buf, "WAVEfmt ", 8) || feof(fp)) { 116 | return false; 117 | } 118 | 119 | fresult = fread(&fmt_hdr_skip, 1, 4, fp); 120 | 121 | fresult = fread(&compression_type, 1, 2, fp); 122 | if(wav_to_host(compression_type) != VALID_COMPRESSION_TYPE) { 123 | return false; 124 | } 125 | 126 | fresult = fread(&nchans, 1, 2, fp); 127 | fresult = fread(&sample_rate, 1, 4, fp); 128 | fresult = fread(&avg_bytes_per_sec, 1, 4, fp); 129 | fresult = fread(&block_align, 1, 2, fp); 130 | fresult = fread(&bits_per_sample, 1, 2, fp); 131 | 132 | if(ferror(fp)) { 133 | return false; 134 | } 135 | 136 | fmt_hdr_skip = wav_to_host(fmt_hdr_skip); 137 | nchans = wav_to_host(nchans); 138 | sample_rate = wav_to_host(sample_rate); 139 | bits_per_sample = wav_to_host(bits_per_sample); 140 | 141 | if(bits_per_sample != 8 && bits_per_sample != 16) { 142 | return false; 143 | } 144 | 145 | fmt_hdr_skip -= 16; 146 | if(fmt_hdr_skip) { 147 | if (fseek(fp, fmt_hdr_skip, SEEK_CUR) != 0) { 148 | return false; 149 | } 150 | } 151 | 152 | // find data chunk 153 | fresult = fread(str_buf, 1, 4, fp); 154 | // keep parsing chunk until we hit the data chunk 155 | while(fresult != 4 || strncmp(str_buf, "data", 4)) 156 | { 157 | // all good? 158 | if(fresult != 4 || ferror(fp) || feof(fp)) { 159 | return false; 160 | } 161 | // get chunk body size and skip 162 | fresult = fread(&chunk_size, 1, 4, fp); 163 | if(fresult != 4 || ferror(fp) || feof(fp)) { 164 | return false; 165 | } 166 | chunk_size = wav_to_host(chunk_size); 167 | if(fseek(fp, chunk_size, SEEK_CUR) != 0) { 168 | return false; 169 | } 170 | // read next chunk type 171 | fresult = fread(str_buf, 1, 4, fp); 172 | } 173 | 174 | fresult = fread(&chunk_size, 1, 4, fp); 175 | if(ferror(fp)) { 176 | return false; 177 | } 178 | 179 | // More byte swapping 180 | chunk_size = wav_to_host(chunk_size); 181 | 182 | // Output values 183 | sample_rate_o = (unsigned)sample_rate; 184 | nchans_o = (int)nchans; 185 | bytes_per_sample_o = (int)(bits_per_sample / 8); 186 | first_sample_pos_o = (int)ftell(fp); 187 | samples_per_chan_o = (unsigned)(chunk_size / (bytes_per_sample_o * nchans)); 188 | return true; 189 | } 190 | 191 | 192 | short int 193 | wav_read_sample(FILE *fp, int bytes_per_sample) 194 | { 195 | int16_t buf_16bit; 196 | 197 | if(fread(&buf_16bit, bytes_per_sample, 1, fp) != 1) { 198 | return 0; 199 | } 200 | if(bytes_per_sample == 1) { 201 | return (short)buf_16bit; 202 | } 203 | return (short)wav_to_host(buf_16bit); 204 | } 205 | 206 | 207 | bool 208 | wavheader_write(FILE *fp, 209 | unsigned int sample_rate, 210 | int nchans, 211 | int bytes_per_sample) 212 | { 213 | const int header_len = 44; 214 | char wav_hdr[header_len] = "RIFF\0\0\0\0WAVEfmt \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0data\0\0\0"; 215 | uint16_t nchans_f = (uint16_t) nchans; 216 | uint32_t sample_rate_f = (uint32_t) sample_rate; 217 | uint16_t block_align = bytes_per_sample * nchans; 218 | uint32_t avg_bytes = sample_rate * block_align; 219 | uint16_t bits_per_sample = bytes_per_sample * 8; 220 | 221 | nchans_f = host_to_wav(nchans_f); 222 | sample_rate_f = host_to_wav(sample_rate_f); 223 | block_align = host_to_wav(block_align); 224 | avg_bytes = host_to_wav(avg_bytes); 225 | bits_per_sample = host_to_wav(bits_per_sample); 226 | 227 | wav_hdr[16] = 0x10; // no extra bytes 228 | wav_hdr[20] = 0x01; // no compression 229 | memcpy((void*)(wav_hdr + 22), (void*)&nchans_f, 2); 230 | memcpy((void*)(wav_hdr + 24), (void*)&sample_rate_f, 4); 231 | memcpy((void*)(wav_hdr + 28), (void*)&avg_bytes, 4); 232 | memcpy((void*)(wav_hdr + 32), (void*)&block_align, 2); 233 | memcpy((void*)(wav_hdr + 34), (void*)&bits_per_sample, 2); 234 | 235 | fwrite(&wav_hdr, 1, header_len, fp); 236 | if(ferror(fp)) { 237 | return false; 238 | } 239 | 240 | return true; 241 | } 242 | 243 | 244 | void 245 | wav_write_sample(FILE *fp, short int sample, int bytes_per_sample) 246 | { 247 | void *data_ptr; 248 | unsigned char buf_8bit; 249 | int16_t buf_16bit; 250 | 251 | if(bytes_per_sample == 1) { 252 | buf_8bit = (unsigned char)sample; 253 | data_ptr = (void*)&buf_8bit; 254 | } 255 | else { 256 | buf_16bit = host_to_wav((int16_t) sample); 257 | data_ptr = (void *) &buf_16bit; 258 | } 259 | 260 | fwrite(data_ptr, 1, bytes_per_sample, fp); 261 | } 262 | 263 | 264 | bool 265 | wavheader_complete(FILE *fp, unsigned int byte_count) 266 | { 267 | uint32_t chunk_size = (uint32_t)byte_count; 268 | chunk_size = host_to_wav(chunk_size); 269 | 270 | if (fseek(fp, 40, SEEK_SET) != 0) { 271 | return false; 272 | } 273 | fwrite(&chunk_size, 1, 4, fp); 274 | 275 | chunk_size = (uint32_t)byte_count + 36; // fmt chunk and data header 276 | chunk_size = host_to_wav(chunk_size); 277 | if (fseek(fp, 4, SEEK_SET) != 0) { 278 | return false; 279 | } 280 | 281 | fwrite(&chunk_size, 1, 4, fp); 282 | 283 | if(ferror(fp)) { 284 | return false; 285 | } 286 | 287 | return true; 288 | } 289 | 290 | } /* namespace blocks */ 291 | } /* namespace gr */ --------------------------------------------------------------------------------