├── README.md ├── custom_types ├── .gitignore ├── CMakeLists.txt ├── FluffyData.cpp ├── FluffyData.hpp ├── FluffyRemote.cpp ├── FluffySink.cpp ├── FluffySink.py ├── FluffySink2.cpp ├── FluffySource.cpp ├── FluffySource.py ├── FluffySource2.cpp ├── README.md ├── SpikeyData.py ├── SpikeySink.cpp ├── SpikeySink.py ├── SpikeySource.cpp ├── SpikeySource.py ├── __init__.py └── tester.py ├── filter_design ├── README.md ├── fir_designer_response.pothos ├── test_freq_xlating_filter.pothos └── test_iir_filter.pothos ├── jit_cpp_block ├── README.md ├── SimpleFloatAdder.conf ├── SimpleFloatAdder.cpp └── topology_with_adder.pothos ├── jit_python_block ├── README.md ├── SimpleAdder.conf ├── SimpleAdder.py └── topology_python_adder.pothos ├── modem_examples └── modem0_example.pothos └── simple_fm_demod ├── README.md └── simple_fm_demod.pothos /README.md: -------------------------------------------------------------------------------- 1 | # Pothos demonstration applications 2 | 3 | * https://github.com/pothosware/PothosDemos/wiki 4 | -------------------------------------------------------------------------------- /custom_types/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /custom_types/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ######################################################################## 2 | # Project setup 3 | ######################################################################## 4 | cmake_minimum_required(VERSION 2.8.9) 5 | project(CustomTypes CXX) 6 | 7 | find_package(Pothos "0.6.0" CONFIG REQUIRED) 8 | include(PothosPythonUtil) 9 | 10 | ######################################################################## 11 | # C++ type library 12 | ######################################################################## 13 | include_directories(${Pothos_INCLUDE_DIRS}) 14 | add_library(FluffyData SHARED FluffyData.cpp) 15 | target_link_libraries(FluffyData ${Pothos_LIBRARIES}) 16 | install(TARGETS FluffyData DESTINATION lib) 17 | 18 | ######################################################################## 19 | # C++ blocks 20 | ######################################################################## 21 | POTHOS_MODULE_UTIL( 22 | TARGET CustomTypesCpp 23 | SOURCES 24 | FluffySource.cpp 25 | FluffySource2.cpp 26 | FluffySink.cpp 27 | FluffySink2.cpp 28 | SpikeySource.cpp 29 | SpikeySink.cpp 30 | DESTINATION PothosDemos 31 | LIBRARIES FluffyData 32 | #ENABLE_DOCS 33 | ) 34 | 35 | ######################################################################## 36 | # Python blocks 37 | ######################################################################## 38 | POTHOS_PYTHON_UTIL( 39 | TARGET CustomTypesPython 40 | SOURCES 41 | __init__.py 42 | FluffySource.py 43 | FluffySink.py 44 | SpikeySource.py 45 | SpikeySink.py 46 | SpikeyData.py 47 | FACTORIES 48 | "/demos/fluffy_source_py:FluffySource" 49 | "/demos/fluffy_sink_py:FluffySink" 50 | "/demos/spikey_source_py:SpikeySource" 51 | "/demos/spikey_sink_py:SpikeySink" 52 | DESTINATION PothosDemosCustomTypes 53 | #ENABLE_DOCS 54 | ) 55 | 56 | ######################################################################## 57 | # Remote executables 58 | ######################################################################## 59 | include_directories(${Pothos_INCLUDE_DIRS}) 60 | add_executable(FluffyRemote FluffyRemote.cpp) 61 | target_link_libraries(FluffyRemote ${Pothos_LIBRARIES} FluffyData) 62 | -------------------------------------------------------------------------------- /custom_types/FluffyData.cpp: -------------------------------------------------------------------------------- 1 | #include "FluffyData.hpp" 2 | 3 | /*********************************************************************** 4 | * FluffyData class implementation 5 | **********************************************************************/ 6 | FluffyData::FluffyData(void): 7 | _fluff(0) 8 | { 9 | return; 10 | } 11 | 12 | FluffyData::FluffyData(const int fluff): 13 | _fluff(fluff) 14 | { 15 | return; 16 | } 17 | 18 | void FluffyData::setFluff(const int fluff) 19 | { 20 | _fluff = fluff; 21 | } 22 | 23 | int FluffyData::getFluff(void) const 24 | { 25 | return _fluff; 26 | } 27 | 28 | /*********************************************************************** 29 | * FluffyData class registration 30 | * Doing this lets us interact with FluffyData through Pothos::Proxy 31 | * which also includes network use and Python language integration. 32 | **********************************************************************/ 33 | #include 34 | 35 | static auto managedFluffyData = Pothos::ManagedClass() 36 | .registerConstructor() 37 | .registerConstructor() 38 | .registerMethod(POTHOS_FCN_TUPLE(FluffyData, getFluff)) 39 | .registerMethod(POTHOS_FCN_TUPLE(FluffyData, setFluff)) 40 | .registerField(POTHOS_FCN_TUPLE(FluffyData, wiggles)) 41 | .commit("FluffyData"); 42 | 43 | /*********************************************************************** 44 | * FluffyData class serialization 45 | * Serialization hooks allow FluffyData to be passed over a socket. 46 | **********************************************************************/ 47 | #include 48 | #include 49 | 50 | namespace Pothos { namespace serialization { 51 | template 52 | void save(Archive & ar, const FluffyData &t, const unsigned int) 53 | { 54 | std::cout << "save FluffyData" << std::endl; 55 | const int fluff(t.getFluff()); 56 | ar << fluff; 57 | ar << t.wiggles; 58 | } 59 | 60 | template 61 | void load(Archive & ar, FluffyData &t, const unsigned int) 62 | { 63 | std::cout << "load FluffyData" << std::endl; 64 | int fluff(0); 65 | ar >> fluff; 66 | t = FluffyData(fluff); 67 | ar >> t.wiggles; 68 | } 69 | }} 70 | 71 | POTHOS_SERIALIZATION_SPLIT_FREE(FluffyData) 72 | POTHOS_OBJECT_SERIALIZE(FluffyData) 73 | -------------------------------------------------------------------------------- /custom_types/FluffyData.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | #ifdef FluffyData_EXPORTS 6 | #define FluffyData_API POTHOS_HELPER_DLL_EXPORT 7 | #else 8 | #define FluffyData_API POTHOS_HELPER_DLL_IMPORT 9 | #endif 10 | 11 | //! FluffyData is a made up class to demonstrate type registration 12 | class FluffyData_API FluffyData 13 | { 14 | public: 15 | 16 | //! Empty constructor 17 | FluffyData(void); 18 | 19 | //! Constructor with parameter 20 | FluffyData(const int fluff); 21 | 22 | //! A setter 23 | void setFluff(const int fluff); 24 | 25 | //! A getter 26 | int getFluff(void) const; 27 | 28 | //! A field 29 | std::string wiggles; 30 | 31 | private: 32 | int _fluff; 33 | }; 34 | -------------------------------------------------------------------------------- /custom_types/FluffyRemote.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "FluffyData.hpp" //only needed for one of the snippets 5 | #include 6 | #include 7 | 8 | void demo(const std::string &uri) 9 | { 10 | //connect to the remote server 11 | Pothos::RemoteClient client(uri); 12 | 13 | //create a proxy environment for C++ objects 14 | auto env = client.makeEnvironment("managed"); 15 | 16 | //create a FluffyData 17 | auto FluffyDataCls = env->findProxy("FluffyData"); 18 | auto remoteData = FluffyDataCls(123); 19 | remoteData.set("wiggles", "yippee"); 20 | 21 | //print the data 22 | std::cout << "FluffyRemote: fluff=" << remoteData.call("getFluff") << std::endl; 23 | std::cout << "FluffyRemote: wiggles=" << remoteData.get("wiggles") << std::endl; 24 | 25 | //get a FluffyData locally using the FluffyData class definition 26 | //only this code snippet needs the #include "FluffyData.hpp" 27 | FluffyData localData = remoteData; 28 | std::cout << "FluffyLocal: fluff=" << localData.getFluff() << std::endl; 29 | std::cout << "FluffyLocal: wiggles=" << localData.wiggles << std::endl; 30 | 31 | //copy the local data back into a second remote object 32 | //and make a change to the copy on the remote end 33 | auto remoteData2 = env->makeProxy(localData); 34 | remoteData2.call("setFluff", 987); 35 | std::cout << "FluffyRemote2: fluff=" << remoteData2.call("getFluff") << std::endl; 36 | std::cout << "FluffyRemote2: wiggles=" << remoteData2.get("wiggles") << std::endl; 37 | 38 | //get a FluffyData locally from the second remote object 39 | //this time we get the data as an opaque object 40 | //and put it into a local proxy to be accessed 41 | auto localEnv = Pothos::ProxyEnvironment::make("managed"); 42 | auto localData2 = localEnv->makeProxy(remoteData2.toObject()); 43 | std::cout << "FluffyLocal2: fluff=" << localData2.call("getFluff") << std::endl; 44 | std::cout << "FluffyLocal2: wiggles=" << localData2.get("wiggles") << std::endl; 45 | } 46 | 47 | int main(int argc, char *argv[]) 48 | { 49 | if (argc != 2) 50 | { 51 | std::cout << "Usage: FluffyRemote tcp://host:port" << std::endl; 52 | return EXIT_FAILURE; 53 | } 54 | 55 | //load the modules into the plugin tree 56 | Pothos::ScopedInit init; 57 | 58 | //run the demo 59 | try 60 | { 61 | demo(argv[1]); 62 | } 63 | catch (const Pothos::Exception &ex) 64 | { 65 | std::cout << ex.displayText() << std::endl; 66 | return EXIT_FAILURE; 67 | } 68 | 69 | return EXIT_SUCCESS; 70 | } 71 | -------------------------------------------------------------------------------- /custom_types/FluffySink.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "FluffyData.hpp" //use class definition in sink version 1 3 | #include 4 | 5 | class FluffySink : public Pothos::Block 6 | { 7 | public: 8 | static Block *make(void) 9 | { 10 | return new FluffySink(); 11 | } 12 | 13 | FluffySink(void) 14 | { 15 | this->setupInput(0); 16 | } 17 | 18 | void work(void) 19 | { 20 | auto inPort = this->input(0); 21 | 22 | //do we have an input message? 23 | if (not inPort->hasMessage()) return; 24 | 25 | //extract the data 26 | const auto msg = inPort->popMessage(); 27 | const auto &data = msg.extract(); 28 | 29 | //print the data 30 | std::cout << "FluffySink: fluff=" << data.getFluff() << std::endl; 31 | std::cout << "FluffySink: wiggles=" << data.wiggles << std::endl; 32 | } 33 | }; 34 | 35 | static Pothos::BlockRegistry registerFluffySink( 36 | "/demos/fluffy_sink", &FluffySink::make); 37 | -------------------------------------------------------------------------------- /custom_types/FluffySink.py: -------------------------------------------------------------------------------- 1 | import Pothos 2 | 3 | class FluffySink(Pothos.Block): 4 | def __init__(self): 5 | Pothos.Block.__init__(self) 6 | self.setupInput(0) 7 | 8 | def work(self): 9 | inPort = self.input(0) 10 | 11 | #do we have an input message? 12 | if not inPort.hasMessage(): return 13 | 14 | #extract the data 15 | data = inPort.popMessage() 16 | 17 | #print the data 18 | print("FluffySinkPy: fluff=%d"%data.getFluff()) 19 | print("FluffySinkPy: wiggles=%s"%data.wiggles) 20 | -------------------------------------------------------------------------------- /custom_types/FluffySink2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | class FluffySink2 : public Pothos::Block 6 | { 7 | public: 8 | static Block *make(void) 9 | { 10 | return new FluffySink2(); 11 | } 12 | 13 | FluffySink2(void): 14 | _env(Pothos::ProxyEnvironment::make("managed")) 15 | { 16 | this->setupInput(0); 17 | } 18 | 19 | void work(void) 20 | { 21 | auto inPort = this->input(0); 22 | 23 | //do we have an input message? 24 | if (not inPort->hasMessage()) return; 25 | 26 | //extract the data 27 | const auto msg = inPort->popMessage(); 28 | const auto data = _env->makeProxy(msg); 29 | 30 | //print the data 31 | std::cout << "FluffySink2: fluff=" << data.call("getFluff") << std::endl; 32 | std::cout << "FluffySink2: wiggles=" << data.get("wiggles") << std::endl; 33 | } 34 | 35 | private: 36 | Pothos::ProxyEnvironment::Sptr _env; 37 | }; 38 | 39 | static Pothos::BlockRegistry registerFluffySink2( 40 | "/demos/fluffy_sink2", &FluffySink2::make); 41 | -------------------------------------------------------------------------------- /custom_types/FluffySource.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "FluffyData.hpp" //use class definition in source version 1 3 | 4 | class FluffySource : public Pothos::Block 5 | { 6 | public: 7 | static Block *make(void) 8 | { 9 | return new FluffySource(); 10 | } 11 | 12 | FluffySource(void) 13 | { 14 | this->setupOutput(0); 15 | } 16 | 17 | void work(void) 18 | { 19 | auto outPort = this->output(0); 20 | 21 | //setup the data 22 | FluffyData data(1); 23 | data.wiggles = "Wiggle1"; 24 | 25 | //produce the data as a message 26 | outPort->postMessage(data); 27 | } 28 | }; 29 | 30 | static Pothos::BlockRegistry registerFluffySource( 31 | "/demos/fluffy_source", &FluffySource::make); 32 | -------------------------------------------------------------------------------- /custom_types/FluffySource.py: -------------------------------------------------------------------------------- 1 | import Pothos 2 | 3 | class FluffySource(Pothos.Block): 4 | def __init__(self): 5 | Pothos.Block.__init__(self) 6 | self._env = Pothos.ProxyEnvironment("managed") 7 | self.setupOutput(0) 8 | 9 | def work(self): 10 | outPort = self.output(0) 11 | 12 | #setup the data 13 | FluffyData = self._env.findProxy("FluffyData") 14 | data = FluffyData(3) 15 | data.wiggles = "Wiggle3" 16 | 17 | #produce the data as a message 18 | outPort.postMessage(data) 19 | -------------------------------------------------------------------------------- /custom_types/FluffySource2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | class FluffySource2 : public Pothos::Block 5 | { 6 | public: 7 | static Block *make(void) 8 | { 9 | return new FluffySource2(); 10 | } 11 | 12 | FluffySource2(void): 13 | _env(Pothos::ProxyEnvironment::make("managed")) 14 | { 15 | this->setupOutput(0); 16 | } 17 | 18 | void work(void) 19 | { 20 | auto outPort = this->output(0); 21 | 22 | //setup the data 23 | auto FluffyData = _env->findProxy("FluffyData"); 24 | auto data = FluffyData(2); 25 | data.set("wiggles", "Wiggle2"); 26 | 27 | //produce the data as a message 28 | outPort->postMessage(data.toObject()); 29 | } 30 | 31 | private: 32 | Pothos::ProxyEnvironment::Sptr _env; 33 | }; 34 | 35 | static Pothos::BlockRegistry registerFluffySource2( 36 | "/demos/fluffy_source2", &FluffySource2::make); 37 | -------------------------------------------------------------------------------- /custom_types/README.md: -------------------------------------------------------------------------------- 1 | # Custom Types demo 2 | 3 | A family of blocks may employ the use of custom data types as messages. 4 | This demonstration shows how type registration and the Pothos::Proxy abstraction 5 | can be used with custom defined data types in both Python modules and C++ classes 6 | to cross language boundaries, and to work with types without class definitions. 7 | 8 | This demo provides a simple CMake build script to build and install the project. 9 | Several source and sink blocks and custom type definitions come with the projects, 10 | as well as a test runner to connect and run any pair of source and sink blocks. 11 | The goal is to demonstrate the concepts, the use of the API, and functionality. 12 | 13 | ## Custom C++ Type FluffyData 14 | 15 | Consider the custom type FluffyData. Using several variants of a simple 16 | source and sink block, we can demonstrate how a registered type 17 | can be interacted with using the Pothos::Proxy abstraction. 18 | 19 | * FluffySource.cpp - produces FluffySource with the class definition 20 | * FluffySource.cpp - produces FluffySource with the class registration 21 | * FluffySink1.cpp - consumes and prints FluffySource with the class definition 22 | * FluffySink2.cpp - consumes and prints FluffySource with the class registration 23 | * FluffySource.py - produces FluffySource in python 24 | * FluffySink.py - consumes and prints FluffySource in python 25 | * FluffyRemote.cpp - app to exchange FluffyData over a network 26 | 27 | ## Remote example with FluffyData 28 | 29 | On the server: 30 | ``` 31 | PothosUtil --proxy-server="" 32 | ``` 33 | 34 | On the client: 35 | ``` 36 | cd build 37 | ./FluffyRemote tcp://localhost 38 | ``` 39 | 40 | ## Custom Python Type SpikeyData 41 | 42 | Now consider a custom type SpikeyData which is defined in a Python module. 43 | Python blocks can easily pass the type between themselves. However, through 44 | the Pothos::Proxy abstraction, C++ blocks can just as easilyuse the type. 45 | 46 | * SpikeySource.py - produces SpikeyData in python 47 | * SpikeySink.py - consumes SpikeyData in python 48 | * SpikeySource.cpp - produces SpikeyData in C++ through Proxy 49 | * SpikeySink.cpp - consumes SpikeyData in C++ through Proxy 50 | 51 | ## Build the demo project 52 | 53 | ``` 54 | cd custom_types 55 | mkdir build && cd build 56 | cmake ../ 57 | make -j4 58 | sudo make install 59 | ``` 60 | 61 | ## Running test cases 62 | 63 | A simple test runner script is provided to connect and run a pair of blocks. 64 | Here are a few example test cases that show off the capabilities: 65 | 66 | ``` 67 | #Send FluffyData with the C++ source to the Python sink 68 | python tester.py /demos/fluffy_source /demos/fluffy_sink_py 69 | 70 | #Send FluffyData with the Python source to the C++ sink 71 | python tester.py /demos/fluffy_source_py /demos/fluffy_sink 72 | 73 | #Using proxy to manipulate FluffyData in C++ without class definitions 74 | python tester.py /demos/fluffy_source2 /demos/fluffy_sink2 75 | 76 | #Send SpikeyData with the C++ source to the Python sink 77 | python tester.py /demos/spikey_source /demos/spikey_sink_py 78 | 79 | #Send SpikeyData with the Python source to the C++ sink 80 | python tester.py /demos/spikey_source_py /demos/spikey_sink 81 | ``` 82 | -------------------------------------------------------------------------------- /custom_types/SpikeyData.py: -------------------------------------------------------------------------------- 1 | class SpikeyData: 2 | def __init__(self, spike=0): 3 | self._spike = spike 4 | self.ouch = "Ouch!" 5 | 6 | def getSpike(self): 7 | return self._spike 8 | 9 | def setSpike(self, spike): 10 | self._spike = spike 11 | -------------------------------------------------------------------------------- /custom_types/SpikeySink.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | class SpikeySink : public Pothos::Block 6 | { 7 | public: 8 | static Block *make(void) 9 | { 10 | return new SpikeySink(); 11 | } 12 | 13 | SpikeySink(void): 14 | _env(Pothos::ProxyEnvironment::make("managed")) 15 | { 16 | this->setupInput(0); 17 | } 18 | 19 | void work(void) 20 | { 21 | auto inPort = this->input(0); 22 | 23 | //do we have an input message? 24 | if (not inPort->hasMessage()) return; 25 | 26 | //extract the data 27 | const auto msg = inPort->popMessage(); 28 | const auto &data = msg.extract(); 29 | 30 | //print the data 31 | std::cout << "SpikeySink: spike=" << data.call("getSpike") << std::endl; 32 | std::cout << "SpikeySink: ouch=" << data.get("ouch") << std::endl; 33 | } 34 | 35 | private: 36 | Pothos::ProxyEnvironment::Sptr _env; 37 | }; 38 | 39 | static Pothos::BlockRegistry registerSpikeySink( 40 | "/demos/spikey_sink", &SpikeySink::make); 41 | -------------------------------------------------------------------------------- /custom_types/SpikeySink.py: -------------------------------------------------------------------------------- 1 | import Pothos 2 | 3 | class SpikeySink(Pothos.Block): 4 | def __init__(self): 5 | Pothos.Block.__init__(self) 6 | self.setupInput(0) 7 | 8 | def work(self): 9 | inPort = self.input(0) 10 | 11 | #do we have an input message? 12 | if not inPort.hasMessage(): return 13 | 14 | #extract the data 15 | data = inPort.popMessage() 16 | 17 | #print the data 18 | print("SpikeySinkPy: spike=%d"%data.getSpike()) 19 | print("SpikeySinkPy: ouch=%s"%data.ouch) 20 | -------------------------------------------------------------------------------- /custom_types/SpikeySource.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | class SpikeySource : public Pothos::Block 5 | { 6 | public: 7 | static Block *make(void) 8 | { 9 | return new SpikeySource(); 10 | } 11 | 12 | SpikeySource(void): 13 | _env(Pothos::ProxyEnvironment::make("python")) 14 | { 15 | this->setupOutput(0); 16 | } 17 | 18 | void work(void) 19 | { 20 | auto outPort = this->output(0); 21 | 22 | //setup the data 23 | auto DemoModule = _env->findProxy("PothosDemosCustomTypes"); 24 | auto SpikeyData = DemoModule.get("SpikeyData"); 25 | auto data = SpikeyData(5); 26 | data.set("ouch", "Ouch5"); 27 | 28 | //produce the data as a message 29 | outPort->postMessage(data); 30 | } 31 | 32 | private: 33 | Pothos::ProxyEnvironment::Sptr _env; 34 | }; 35 | 36 | static Pothos::BlockRegistry registerSpikeySource( 37 | "/demos/spikey_source", &SpikeySource::make); 38 | -------------------------------------------------------------------------------- /custom_types/SpikeySource.py: -------------------------------------------------------------------------------- 1 | import Pothos 2 | from SpikeyData import SpikeyData 3 | 4 | class SpikeySource(Pothos.Block): 5 | def __init__(self): 6 | Pothos.Block.__init__(self) 7 | self.setupOutput(0) 8 | 9 | def work(self): 10 | outPort = self.output(0) 11 | 12 | #setup the data 13 | data = SpikeyData(4) 14 | data.ouch = "Ouch4" 15 | 16 | #produce the data as a message 17 | outPort.postMessage(data) 18 | -------------------------------------------------------------------------------- /custom_types/__init__.py: -------------------------------------------------------------------------------- 1 | from SpikeyData import SpikeyData 2 | from FluffySource import FluffySource 3 | from FluffySink import FluffySink 4 | from SpikeySource import SpikeySource 5 | from SpikeySink import SpikeySink 6 | -------------------------------------------------------------------------------- /custom_types/tester.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import time 3 | import Pothos 4 | 5 | if __name__ == '__main__': 6 | if len(sys.argv) != 3: 7 | print("Usage: tester.py /demos/fluffy_source /demos/fluffy_sink") 8 | exit(-1) 9 | sourcePath = sys.argv[1] 10 | sinkPath = sys.argv[2] 11 | 12 | #make topology and blocks 13 | t = Pothos.Topology() 14 | source = Pothos.BlockRegistry(sourcePath) 15 | sink = Pothos.BlockRegistry(sinkPath) 16 | t.connect(source, 0, sink, 0) 17 | 18 | print('#'*40) 19 | print('## Run for 1 second...') 20 | print('#'*40) 21 | 22 | #run for 1 second 23 | t.commit() 24 | time.sleep(1) 25 | 26 | #cleanup connections 27 | t.disconnectAll() 28 | t.commit() 29 | 30 | print('#'*40) 31 | print('## Done!') 32 | print('#'*40) 33 | -------------------------------------------------------------------------------- /filter_design/README.md: -------------------------------------------------------------------------------- 1 | # Filter design 2 | 3 | Projects that demonstrate the use of filter blocks and the filter taps designer. 4 | -------------------------------------------------------------------------------- /filter_design/fir_designer_response.pothos: -------------------------------------------------------------------------------- 1 | { 2 | "globals" : [ 3 | { 4 | "name" : "rate", 5 | "value" : "1e6" 6 | } 7 | ], 8 | "pages" : [ 9 | { 10 | "graphObjects" : [ 11 | { 12 | "activeEditTab" : "Labels", 13 | "affinityZone" : "", 14 | "enabled" : true, 15 | "id" : "FIRFilter0", 16 | "inputDesc" : [ 17 | { 18 | "alias" : "0", 19 | "dtype" : "complex_float32", 20 | "isSigSlot" : false, 21 | "name" : "0", 22 | "size" : 8 23 | }, 24 | { 25 | "alias" : "setTaps", 26 | "dtype" : "unspecified", 27 | "isSigSlot" : true, 28 | "name" : "setTaps", 29 | "size" : 1 30 | }, 31 | { 32 | "alias" : "setDecimation", 33 | "dtype" : "unspecified", 34 | "isSigSlot" : true, 35 | "name" : "setDecimation", 36 | "size" : 1 37 | }, 38 | { 39 | "alias" : "setInterpolation", 40 | "dtype" : "unspecified", 41 | "isSigSlot" : true, 42 | "name" : "setInterpolation", 43 | "size" : 1 44 | }, 45 | { 46 | "alias" : "setWaitTaps", 47 | "dtype" : "unspecified", 48 | "isSigSlot" : true, 49 | "name" : "setWaitTaps", 50 | "size" : 1 51 | }, 52 | { 53 | "alias" : "setFrameStartId", 54 | "dtype" : "unspecified", 55 | "isSigSlot" : true, 56 | "name" : "setFrameStartId", 57 | "size" : 1 58 | }, 59 | { 60 | "alias" : "setFrameEndId", 61 | "dtype" : "unspecified", 62 | "isSigSlot" : true, 63 | "name" : "setFrameEndId", 64 | "size" : 1 65 | } 66 | ], 67 | "outputDesc" : [ 68 | { 69 | "alias" : "0", 70 | "dtype" : "complex_float32", 71 | "isSigSlot" : false, 72 | "name" : "0", 73 | "size" : 8 74 | } 75 | ], 76 | "path" : "\/comms\/fir_filter", 77 | "positionX" : 146, 78 | "positionY" : 256, 79 | "properties" : [ 80 | { 81 | "key" : "dtype", 82 | "value" : "\"complex_float32\"" 83 | }, 84 | { 85 | "key" : "tapsType", 86 | "value" : "\"COMPLEX\"" 87 | }, 88 | { 89 | "key" : "decim", 90 | "value" : "1" 91 | }, 92 | { 93 | "key" : "interp", 94 | "value" : "1" 95 | }, 96 | { 97 | "key" : "taps", 98 | "value" : "[1.0]" 99 | }, 100 | { 101 | "key" : "waitTaps", 102 | "value" : "false" 103 | }, 104 | { 105 | "key" : "frameStartId", 106 | "value" : "\"\"" 107 | }, 108 | { 109 | "key" : "frameEndId", 110 | "value" : "\"\"" 111 | } 112 | ], 113 | "rotation" : 180, 114 | "selected" : false, 115 | "what" : "Block", 116 | "zValue" : 248 117 | }, 118 | { 119 | "affinityZone" : "", 120 | "enabled" : true, 121 | "id" : "FIRDesigner0", 122 | "inputDesc" : [ 123 | { 124 | "alias" : "setBandType", 125 | "dtype" : "unspecified", 126 | "isSigSlot" : true, 127 | "name" : "setBandType", 128 | "size" : 1 129 | }, 130 | { 131 | "alias" : "setFilterType", 132 | "dtype" : "unspecified", 133 | "isSigSlot" : true, 134 | "name" : "setFilterType", 135 | "size" : 1 136 | }, 137 | { 138 | "alias" : "setWindowType", 139 | "dtype" : "unspecified", 140 | "isSigSlot" : true, 141 | "name" : "setWindowType", 142 | "size" : 1 143 | }, 144 | { 145 | "alias" : "setWindowArgs", 146 | "dtype" : "unspecified", 147 | "isSigSlot" : true, 148 | "name" : "setWindowArgs", 149 | "size" : 1 150 | }, 151 | { 152 | "alias" : "setSampleRate", 153 | "dtype" : "unspecified", 154 | "isSigSlot" : true, 155 | "name" : "setSampleRate", 156 | "size" : 1 157 | }, 158 | { 159 | "alias" : "setFrequencyLower", 160 | "dtype" : "unspecified", 161 | "isSigSlot" : true, 162 | "name" : "setFrequencyLower", 163 | "size" : 1 164 | }, 165 | { 166 | "alias" : "setFrequencyUpper", 167 | "dtype" : "unspecified", 168 | "isSigSlot" : true, 169 | "name" : "setFrequencyUpper", 170 | "size" : 1 171 | }, 172 | { 173 | "alias" : "setBandwidthTrans", 174 | "dtype" : "unspecified", 175 | "isSigSlot" : true, 176 | "name" : "setBandwidthTrans", 177 | "size" : 1 178 | }, 179 | { 180 | "alias" : "setNumTaps", 181 | "dtype" : "unspecified", 182 | "isSigSlot" : true, 183 | "name" : "setNumTaps", 184 | "size" : 1 185 | }, 186 | { 187 | "alias" : "setAlpha", 188 | "dtype" : "unspecified", 189 | "isSigSlot" : true, 190 | "name" : "setAlpha", 191 | "size" : 1 192 | }, 193 | { 194 | "alias" : "setStopDB", 195 | "dtype" : "unspecified", 196 | "isSigSlot" : true, 197 | "name" : "setStopDB", 198 | "size" : 1 199 | }, 200 | { 201 | "alias" : "setPassDB", 202 | "dtype" : "unspecified", 203 | "isSigSlot" : true, 204 | "name" : "setPassDB", 205 | "size" : 1 206 | }, 207 | { 208 | "alias" : "setGain", 209 | "dtype" : "unspecified", 210 | "isSigSlot" : true, 211 | "name" : "setGain", 212 | "size" : 1 213 | } 214 | ], 215 | "outputDesc" : [ 216 | { 217 | "alias" : "tapsChanged", 218 | "dtype" : "unspecified", 219 | "isSigSlot" : true, 220 | "name" : "tapsChanged", 221 | "size" : 1 222 | } 223 | ], 224 | "path" : "\/comms\/fir_designer", 225 | "positionX" : 331, 226 | "positionY" : 220, 227 | "properties" : [ 228 | { 229 | "key" : "type", 230 | "value" : "\"SINC\"" 231 | }, 232 | { 233 | "key" : "band", 234 | "value" : "\"LOW_PASS\"" 235 | }, 236 | { 237 | "key" : "window", 238 | "value" : "\"hann\"" 239 | }, 240 | { 241 | "key" : "windowArgs", 242 | "value" : "[10]" 243 | }, 244 | { 245 | "key" : "gain", 246 | "value" : "1.0" 247 | }, 248 | { 249 | "key" : "sampRate", 250 | "value" : "rate" 251 | }, 252 | { 253 | "key" : "freqLower", 254 | "value" : "1e5" 255 | }, 256 | { 257 | "key" : "freqUpper", 258 | "value" : "2e5" 259 | }, 260 | { 261 | "key" : "transBw", 262 | "value" : "1000" 263 | }, 264 | { 265 | "key" : "numTaps", 266 | "value" : "101" 267 | }, 268 | { 269 | "key" : "alpha", 270 | "value" : "0.5" 271 | }, 272 | { 273 | "key" : "stopDB", 274 | "value" : "60.0" 275 | }, 276 | { 277 | "key" : "passDB", 278 | "value" : "0.1" 279 | } 280 | ], 281 | "rotation" : 0, 282 | "selected" : false, 283 | "what" : "Block", 284 | "zValue" : 292 285 | }, 286 | { 287 | "affinityZone" : "", 288 | "enabled" : true, 289 | "id" : "Periodogram0", 290 | "inputDesc" : [ 291 | { 292 | "alias" : "setTitle", 293 | "dtype" : "unspecified", 294 | "isSigSlot" : true, 295 | "name" : "setTitle", 296 | "size" : 1 297 | }, 298 | { 299 | "alias" : "setSampleRate", 300 | "dtype" : "unspecified", 301 | "isSigSlot" : true, 302 | "name" : "setSampleRate", 303 | "size" : 1 304 | }, 305 | { 306 | "alias" : "setCenterFrequency", 307 | "dtype" : "unspecified", 308 | "isSigSlot" : true, 309 | "name" : "setCenterFrequency", 310 | "size" : 1 311 | }, 312 | { 313 | "alias" : "setNumPoints", 314 | "dtype" : "unspecified", 315 | "isSigSlot" : true, 316 | "name" : "setNumFFTBins", 317 | "size" : 1 318 | }, 319 | { 320 | "alias" : "setWindowType", 321 | "dtype" : "unspecified", 322 | "isSigSlot" : true, 323 | "name" : "setWindowType", 324 | "size" : 1 325 | }, 326 | { 327 | "alias" : "setReferenceLevel", 328 | "dtype" : "unspecified", 329 | "isSigSlot" : true, 330 | "name" : "setReferenceLevel", 331 | "size" : 1 332 | }, 333 | { 334 | "alias" : "setDynamicRange", 335 | "dtype" : "unspecified", 336 | "isSigSlot" : true, 337 | "name" : "setDynamicRange", 338 | "size" : 1 339 | }, 340 | { 341 | "alias" : "setAutoScale", 342 | "dtype" : "unspecified", 343 | "isSigSlot" : true, 344 | "name" : "setAutoScale", 345 | "size" : 1 346 | }, 347 | { 348 | "alias" : "setAverageFactor", 349 | "dtype" : "unspecified", 350 | "isSigSlot" : true, 351 | "name" : "setAverageFactor", 352 | "size" : 1 353 | }, 354 | { 355 | "alias" : "enableXAxis", 356 | "dtype" : "unspecified", 357 | "isSigSlot" : true, 358 | "name" : "enableXAxis", 359 | "size" : 1 360 | }, 361 | { 362 | "alias" : "enableYAxis", 363 | "dtype" : "unspecified", 364 | "isSigSlot" : true, 365 | "name" : "enableYAxis", 366 | "size" : 1 367 | }, 368 | { 369 | "alias" : "setYAxisTitle", 370 | "dtype" : "unspecified", 371 | "isSigSlot" : true, 372 | "name" : "setYAxisTitle", 373 | "size" : 1 374 | }, 375 | { 376 | "alias" : "setEventRate", 377 | "dtype" : "unspecified", 378 | "isSigSlot" : true, 379 | "name" : "setDisplayRate", 380 | "size" : 1 381 | }, 382 | { 383 | "alias" : "0", 384 | "dtype" : "unspecified", 385 | "isSigSlot" : false, 386 | "name" : "0", 387 | "size" : 1 388 | } 389 | ], 390 | "outputDesc" : [ 391 | { 392 | "alias" : "frequencySelected", 393 | "dtype" : "unspecified", 394 | "isSigSlot" : true, 395 | "name" : "frequencySelected", 396 | "size" : 1 397 | } 398 | ], 399 | "path" : "\/plotters\/periodogram", 400 | "positionX" : 148, 401 | "positionY" : 370, 402 | "properties" : [ 403 | { 404 | "key" : "title", 405 | "value" : "\"\"" 406 | }, 407 | { 408 | "key" : "numInputs", 409 | "value" : "1" 410 | }, 411 | { 412 | "key" : "displayRate", 413 | "value" : "10.0" 414 | }, 415 | { 416 | "key" : "sampleRate", 417 | "value" : "1e6" 418 | }, 419 | { 420 | "key" : "centerFreq", 421 | "value" : "0.0" 422 | }, 423 | { 424 | "key" : "numBins", 425 | "value" : "1024" 426 | }, 427 | { 428 | "key" : "window", 429 | "value" : "\"rectangular\"" 430 | }, 431 | { 432 | "key" : "windowArgs", 433 | "value" : "[100]" 434 | }, 435 | { 436 | "key" : "autoScale", 437 | "value" : "false" 438 | }, 439 | { 440 | "key" : "refLevel", 441 | "value" : "0.0" 442 | }, 443 | { 444 | "key" : "dynRange", 445 | "value" : "200.0" 446 | }, 447 | { 448 | "key" : "averaging", 449 | "value" : "0.0" 450 | }, 451 | { 452 | "key" : "enableXAxis", 453 | "value" : "false" 454 | }, 455 | { 456 | "key" : "enableYAxis", 457 | "value" : "false" 458 | }, 459 | { 460 | "key" : "yAxisTitle", 461 | "value" : "\"dB\"" 462 | }, 463 | { 464 | "key" : "freqLabelId", 465 | "value" : "\"rxFreq\"" 466 | }, 467 | { 468 | "key" : "rateLabelId", 469 | "value" : "\"rxRate\"" 470 | }, 471 | { 472 | "key" : "startLabelId", 473 | "value" : "\"START\"" 474 | } 475 | ], 476 | "rotation" : 0, 477 | "selected" : true, 478 | "what" : "Block", 479 | "zValue" : 293 480 | }, 481 | { 482 | "affinityZone" : "", 483 | "enabled" : true, 484 | "id" : "VectorSource0", 485 | "inputDesc" : [ 486 | { 487 | "alias" : "setElements", 488 | "dtype" : "unspecified", 489 | "isSigSlot" : true, 490 | "name" : "setElements", 491 | "size" : 1 492 | }, 493 | { 494 | "alias" : "setMode", 495 | "dtype" : "unspecified", 496 | "isSigSlot" : true, 497 | "name" : "setMode", 498 | "size" : 1 499 | }, 500 | { 501 | "alias" : "setStartId", 502 | "dtype" : "unspecified", 503 | "isSigSlot" : true, 504 | "name" : "setStartId", 505 | "size" : 1 506 | }, 507 | { 508 | "alias" : "setEndId", 509 | "dtype" : "unspecified", 510 | "isSigSlot" : true, 511 | "name" : "setEndId", 512 | "size" : 1 513 | } 514 | ], 515 | "outputDesc" : [ 516 | { 517 | "alias" : "0", 518 | "dtype" : "complex_float32", 519 | "isSigSlot" : false, 520 | "name" : "0", 521 | "size" : 8 522 | } 523 | ], 524 | "path" : "\/blocks\/vector_source", 525 | "positionX" : 142, 526 | "positionY" : 68, 527 | "properties" : [ 528 | { 529 | "key" : "dtype", 530 | "value" : "\"complex_float32\"" 531 | }, 532 | { 533 | "key" : "mode", 534 | "value" : "\"REPEAT\"" 535 | }, 536 | { 537 | "key" : "elements", 538 | "value" : "[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1024]" 539 | }, 540 | { 541 | "key" : "startId", 542 | "value" : "\"START\"" 543 | }, 544 | { 545 | "key" : "endId", 546 | "value" : "\"\"" 547 | } 548 | ], 549 | "rotation" : 0, 550 | "selected" : false, 551 | "what" : "Block", 552 | "zValue" : 282 553 | }, 554 | { 555 | "affinityZone" : "", 556 | "enabled" : true, 557 | "id" : "Pacer0", 558 | "inputDesc" : [ 559 | { 560 | "alias" : "0", 561 | "dtype" : "unspecified", 562 | "isSigSlot" : false, 563 | "name" : "0", 564 | "size" : 1 565 | }, 566 | { 567 | "alias" : "setRate", 568 | "dtype" : "unspecified", 569 | "isSigSlot" : true, 570 | "name" : "setRate", 571 | "size" : 1 572 | } 573 | ], 574 | "outputDesc" : [ 575 | { 576 | "alias" : "0", 577 | "dtype" : "unspecified", 578 | "isSigSlot" : false, 579 | "name" : "0", 580 | "size" : 1 581 | } 582 | ], 583 | "path" : "\/blocks\/pacer", 584 | "positionX" : 150, 585 | "positionY" : 165, 586 | "properties" : [ 587 | { 588 | "key" : "rate", 589 | "value" : "rate" 590 | } 591 | ], 592 | "rotation" : 0, 593 | "selected" : false, 594 | "what" : "Block", 595 | "zValue" : 281 596 | }, 597 | { 598 | "enabled" : true, 599 | "id" : "Connection_FIRFilter00_Periodogram00", 600 | "inputId" : "Periodogram0", 601 | "inputKey" : "0", 602 | "outputId" : "FIRFilter0", 603 | "outputKey" : "0", 604 | "positionX" : 0, 605 | "positionY" : 0, 606 | "rotation" : 0, 607 | "selected" : false, 608 | "what" : "Connection", 609 | "zValue" : 0 610 | }, 611 | { 612 | "enabled" : true, 613 | "id" : "Connection_FIRDesigner0signals_FIRFilter0", 614 | "positionX" : 0, 615 | "positionY" : 0, 616 | "rotation" : 0, 617 | "selected" : false, 618 | "sigSlots" : [ 619 | [ 620 | "tapsChanged", 621 | "setTaps" 622 | ] 623 | ], 624 | "signalId" : "FIRDesigner0", 625 | "signalKey" : "signals", 626 | "slotId" : "FIRFilter0", 627 | "slotKey" : "slots", 628 | "what" : "Connection", 629 | "zValue" : 18 630 | }, 631 | { 632 | "enabled" : true, 633 | "id" : "Connection_VectorSource00_Pacer00", 634 | "inputId" : "Pacer0", 635 | "inputKey" : "0", 636 | "outputId" : "VectorSource0", 637 | "outputKey" : "0", 638 | "positionX" : 0, 639 | "positionY" : 0, 640 | "rotation" : 0, 641 | "selected" : false, 642 | "what" : "Connection", 643 | "zValue" : 0 644 | }, 645 | { 646 | "enabled" : true, 647 | "id" : "Connection_Pacer00_FIRFilter00", 648 | "inputId" : "FIRFilter0", 649 | "inputKey" : "0", 650 | "outputId" : "Pacer0", 651 | "outputKey" : "0", 652 | "positionX" : 0, 653 | "positionY" : 0, 654 | "rotation" : 0, 655 | "selected" : false, 656 | "what" : "Connection", 657 | "zValue" : 0 658 | }, 659 | { 660 | "blockId" : "Periodogram0", 661 | "enabled" : true, 662 | "height" : 380, 663 | "id" : "WidgetPeriodogram0", 664 | "positionX" : 411, 665 | "positionY" : 16, 666 | "rotation" : 0, 667 | "selected" : false, 668 | "what" : "Widget", 669 | "width" : 683, 670 | "zValue" : 289 671 | } 672 | ], 673 | "pageName" : "Main", 674 | "selected" : true 675 | } 676 | ] 677 | } -------------------------------------------------------------------------------- /filter_design/test_freq_xlating_filter.pothos: -------------------------------------------------------------------------------- 1 | { 2 | "globals": [ 3 | { 4 | "name": "rate", 5 | "value": "1e6" 6 | } 7 | ], 8 | "pages": [ 9 | { 10 | "graphObjects": [ 11 | { 12 | "blockId": "NumericEntry0", 13 | "enabled": true, 14 | "height": 56, 15 | "id": "WidgetNumericEntry0", 16 | "positionX": 751, 17 | "positionY": 17, 18 | "rotation": 0, 19 | "selected": false, 20 | "state": "AAAABgAAAAAAAAAAAA==", 21 | "what": "Widget", 22 | "width": 233, 23 | "zValue": 219 24 | }, 25 | { 26 | "blockId": "NumericEntry1", 27 | "enabled": true, 28 | "height": 56, 29 | "id": "WidgetNumericEntry1", 30 | "positionX": 495, 31 | "positionY": 19, 32 | "rotation": 0, 33 | "selected": false, 34 | "state": "AAAABgAAAAAAAAAAAA==", 35 | "what": "Widget", 36 | "width": 229, 37 | "zValue": 215 38 | }, 39 | { 40 | "blockId": "Periodogram0", 41 | "enabled": true, 42 | "height": 293, 43 | "id": "WidgetPeriodogram0", 44 | "positionX": 31, 45 | "positionY": 94, 46 | "rotation": 0, 47 | "selected": false, 48 | "state": "AAAACAAAAAADAAAADgB2AGkAcwBpAGIAbABlAAAADQAAAAAEAwAAAAoAcwB0AGEAYwBrAAAACQAAAAABAAAAFADAf0AAAAAAAMBiwAAAAAAAQI9AAAAAAABAYsAAAAAAAAAAAAoAaQBuAGQAZQB4AAAAAwAAAAAA", 49 | "what": "Widget", 50 | "width": 1067, 51 | "zValue": 165 52 | } 53 | ], 54 | "pageName": "Main", 55 | "selected": true 56 | }, 57 | { 58 | "graphObjects": [ 59 | { 60 | "affinityZone": "", 61 | "enabled": true, 62 | "id": "Arithmetic0", 63 | "inputDesc": [ 64 | { 65 | "alias": "setNumInputs", 66 | "dtype": "unspecified", 67 | "isSigSlot": true, 68 | "name": "setNumInputs", 69 | "size": 1 70 | }, 71 | { 72 | "alias": "setPreload", 73 | "dtype": "unspecified", 74 | "isSigSlot": true, 75 | "name": "setPreload", 76 | "size": 1 77 | }, 78 | { 79 | "alias": "0", 80 | "dtype": "complex_float32", 81 | "isSigSlot": false, 82 | "name": "0", 83 | "size": 8 84 | }, 85 | { 86 | "alias": "1", 87 | "dtype": "complex_float32", 88 | "isSigSlot": false, 89 | "name": "1", 90 | "size": 8 91 | } 92 | ], 93 | "outputDesc": [ 94 | { 95 | "alias": "0", 96 | "dtype": "complex_float32", 97 | "isSigSlot": false, 98 | "name": "0", 99 | "size": 8 100 | } 101 | ], 102 | "path": "/comms/arithmetic", 103 | "positionX": 622, 104 | "positionY": 143, 105 | "properties": [ 106 | { 107 | "key": "dtype", 108 | "value": "\"complex_float32\"" 109 | }, 110 | { 111 | "key": "operation", 112 | "value": "\"ADD\"" 113 | }, 114 | { 115 | "key": "numInputs", 116 | "value": "2" 117 | }, 118 | { 119 | "key": "preload", 120 | "value": "[]" 121 | } 122 | ], 123 | "rotation": 0, 124 | "selected": false, 125 | "what": "Block", 126 | "zValue": 206 127 | }, 128 | { 129 | "affinityZone": "", 130 | "enabled": true, 131 | "id": "FIRDesigner0", 132 | "inputDesc": [ 133 | { 134 | "alias": "setBandType", 135 | "dtype": "unspecified", 136 | "isSigSlot": true, 137 | "name": "setBandType", 138 | "size": 1 139 | }, 140 | { 141 | "alias": "setFilterType", 142 | "dtype": "unspecified", 143 | "isSigSlot": true, 144 | "name": "setFilterType", 145 | "size": 1 146 | }, 147 | { 148 | "alias": "setWindowType", 149 | "dtype": "unspecified", 150 | "isSigSlot": true, 151 | "name": "setWindowType", 152 | "size": 1 153 | }, 154 | { 155 | "alias": "setWindowArgs", 156 | "dtype": "unspecified", 157 | "isSigSlot": true, 158 | "name": "setWindowArgs", 159 | "size": 1 160 | }, 161 | { 162 | "alias": "setSampleRate", 163 | "dtype": "unspecified", 164 | "isSigSlot": true, 165 | "name": "setSampleRate", 166 | "size": 1 167 | }, 168 | { 169 | "alias": "setFrequencies", 170 | "dtype": "unspecified", 171 | "isSigSlot": true, 172 | "name": "setFrequencies", 173 | "size": 1 174 | }, 175 | { 176 | "alias": "setFrequencyLower", 177 | "dtype": "unspecified", 178 | "isSigSlot": true, 179 | "name": "setFrequencyLower", 180 | "size": 1 181 | }, 182 | { 183 | "alias": "setFrequencyUpper", 184 | "dtype": "unspecified", 185 | "isSigSlot": true, 186 | "name": "setFrequencyUpper", 187 | "size": 1 188 | }, 189 | { 190 | "alias": "setBandwidthTrans", 191 | "dtype": "unspecified", 192 | "isSigSlot": true, 193 | "name": "setBandwidthTrans", 194 | "size": 1 195 | }, 196 | { 197 | "alias": "setNumTaps", 198 | "dtype": "unspecified", 199 | "isSigSlot": true, 200 | "name": "setNumTaps", 201 | "size": 1 202 | }, 203 | { 204 | "alias": "setAlpha", 205 | "dtype": "unspecified", 206 | "isSigSlot": true, 207 | "name": "setAlpha", 208 | "size": 1 209 | }, 210 | { 211 | "alias": "setStopDB", 212 | "dtype": "unspecified", 213 | "isSigSlot": true, 214 | "name": "setStopDB", 215 | "size": 1 216 | }, 217 | { 218 | "alias": "setPassDB", 219 | "dtype": "unspecified", 220 | "isSigSlot": true, 221 | "name": "setPassDB", 222 | "size": 1 223 | }, 224 | { 225 | "alias": "setGain", 226 | "dtype": "unspecified", 227 | "isSigSlot": true, 228 | "name": "setGain", 229 | "size": 1 230 | } 231 | ], 232 | "outputDesc": [ 233 | { 234 | "alias": "tapsChanged", 235 | "dtype": "unspecified", 236 | "isSigSlot": true, 237 | "name": "tapsChanged", 238 | "size": 1 239 | } 240 | ], 241 | "path": "/comms/fir_designer", 242 | "positionX": 304, 243 | "positionY": 264, 244 | "properties": [ 245 | { 246 | "key": "type", 247 | "value": "\"SINC\"" 248 | }, 249 | { 250 | "key": "band", 251 | "value": "\"LOW_PASS\"" 252 | }, 253 | { 254 | "key": "window", 255 | "value": "\"hann\"" 256 | }, 257 | { 258 | "key": "windowArgs", 259 | "value": "[]" 260 | }, 261 | { 262 | "key": "gain", 263 | "value": "1.0" 264 | }, 265 | { 266 | "key": "sampRate", 267 | "value": "rate" 268 | }, 269 | { 270 | "key": "freqLower", 271 | "value": "rate/20" 272 | }, 273 | { 274 | "key": "freqUpper", 275 | "value": "2000" 276 | }, 277 | { 278 | "key": "transBw", 279 | "value": "1000" 280 | }, 281 | { 282 | "key": "numTaps", 283 | "value": "51" 284 | }, 285 | { 286 | "key": "alpha", 287 | "value": "0.5" 288 | }, 289 | { 290 | "key": "stopDB", 291 | "value": "60.0" 292 | }, 293 | { 294 | "key": "passDB", 295 | "value": "0.1" 296 | } 297 | ], 298 | "rotation": 0, 299 | "selected": true, 300 | "what": "Block", 301 | "zValue": 228 302 | }, 303 | { 304 | "affinityZone": "", 305 | "enabled": true, 306 | "id": "FrequencyXlatingFIRFilter0", 307 | "inputDesc": [ 308 | { 309 | "alias": "0", 310 | "dtype": "complex_float32", 311 | "isSigSlot": false, 312 | "name": "0", 313 | "size": 8 314 | }, 315 | { 316 | "alias": "freq", 317 | "dtype": "unspecified", 318 | "isSigSlot": false, 319 | "name": "freq", 320 | "size": 1 321 | }, 322 | { 323 | "alias": "set_center_freq", 324 | "dtype": "unspecified", 325 | "isSigSlot": true, 326 | "name": "set_center_freq", 327 | "size": 1 328 | }, 329 | { 330 | "alias": "set_taps", 331 | "dtype": "unspecified", 332 | "isSigSlot": true, 333 | "name": "set_taps", 334 | "size": 1 335 | } 336 | ], 337 | "outputDesc": [ 338 | { 339 | "alias": "0", 340 | "dtype": "complex_float32", 341 | "isSigSlot": false, 342 | "name": "0", 343 | "size": 8 344 | } 345 | ], 346 | "path": "/gr/filter/freq_xlating_fir_filter", 347 | "positionX": 786, 348 | "positionY": 193, 349 | "properties": [ 350 | { 351 | "key": "type", 352 | "value": "\"freq_xlating_fir_filter_ccc\"" 353 | }, 354 | { 355 | "key": "decim", 356 | "value": "1" 357 | }, 358 | { 359 | "key": "taps", 360 | "value": "[1]" 361 | }, 362 | { 363 | "key": "center_freq", 364 | "value": "0.0" 365 | }, 366 | { 367 | "key": "samp_rate", 368 | "value": "rate" 369 | } 370 | ], 371 | "rotation": 0, 372 | "selected": false, 373 | "what": "Block", 374 | "zValue": 227 375 | }, 376 | { 377 | "affinityZone": "", 378 | "enabled": true, 379 | "id": "NoiseSource0", 380 | "inputDesc": [ 381 | { 382 | "alias": "setWaveform", 383 | "dtype": "unspecified", 384 | "isSigSlot": true, 385 | "name": "setWaveform", 386 | "size": 1 387 | }, 388 | { 389 | "alias": "setOffset", 390 | "dtype": "unspecified", 391 | "isSigSlot": true, 392 | "name": "setOffset", 393 | "size": 1 394 | }, 395 | { 396 | "alias": "setAmplitude", 397 | "dtype": "unspecified", 398 | "isSigSlot": true, 399 | "name": "setAmplitude", 400 | "size": 1 401 | }, 402 | { 403 | "alias": "setMean", 404 | "dtype": "unspecified", 405 | "isSigSlot": true, 406 | "name": "setMean", 407 | "size": 1 408 | }, 409 | { 410 | "alias": "setB", 411 | "dtype": "unspecified", 412 | "isSigSlot": true, 413 | "name": "setB", 414 | "size": 1 415 | } 416 | ], 417 | "outputDesc": [ 418 | { 419 | "alias": "0", 420 | "dtype": "complex_float32", 421 | "isSigSlot": false, 422 | "name": "0", 423 | "size": 8 424 | } 425 | ], 426 | "path": "/comms/noise_source", 427 | "positionX": 573, 428 | "positionY": 57, 429 | "properties": [ 430 | { 431 | "key": "dtype", 432 | "value": "\"complex_float32\"" 433 | }, 434 | { 435 | "key": "wave", 436 | "value": "\"NORMAL\"" 437 | }, 438 | { 439 | "key": "ampl", 440 | "value": "0.1" 441 | }, 442 | { 443 | "key": "offset", 444 | "value": "0.0" 445 | }, 446 | { 447 | "key": "mean", 448 | "value": "0.0" 449 | }, 450 | { 451 | "key": "b", 452 | "value": "1.0" 453 | } 454 | ], 455 | "rotation": 180, 456 | "selected": false, 457 | "what": "Block", 458 | "zValue": 205 459 | }, 460 | { 461 | "affinityZone": "", 462 | "enabled": true, 463 | "id": "NumericEntry0", 464 | "inputDesc": [ 465 | { 466 | "alias": "setTitle", 467 | "dtype": "unspecified", 468 | "isSigSlot": true, 469 | "name": "setTitle", 470 | "size": 1 471 | }, 472 | { 473 | "alias": "setValue", 474 | "dtype": "unspecified", 475 | "isSigSlot": true, 476 | "name": "setValue", 477 | "size": 1 478 | }, 479 | { 480 | "alias": "setMinimum", 481 | "dtype": "unspecified", 482 | "isSigSlot": true, 483 | "name": "setMinimum", 484 | "size": 1 485 | }, 486 | { 487 | "alias": "setMaximum", 488 | "dtype": "unspecified", 489 | "isSigSlot": true, 490 | "name": "setMaximum", 491 | "size": 1 492 | }, 493 | { 494 | "alias": "setDecimals", 495 | "dtype": "unspecified", 496 | "isSigSlot": true, 497 | "name": "setDecimals", 498 | "size": 1 499 | }, 500 | { 501 | "alias": "setSingleStep", 502 | "dtype": "unspecified", 503 | "isSigSlot": true, 504 | "name": "setSingleStep", 505 | "size": 1 506 | }, 507 | { 508 | "alias": "setSliderVisible", 509 | "dtype": "unspecified", 510 | "isSigSlot": true, 511 | "name": "setSliderVisible", 512 | "size": 1 513 | } 514 | ], 515 | "outputDesc": [ 516 | { 517 | "alias": "valueChanged", 518 | "dtype": "unspecified", 519 | "isSigSlot": true, 520 | "name": "valueChanged", 521 | "size": 1 522 | } 523 | ], 524 | "path": "/widgets/numeric_entry", 525 | "positionX": 787, 526 | "positionY": 423, 527 | "properties": [ 528 | { 529 | "key": "title", 530 | "value": "\"Filter freq (Hz)\"" 531 | }, 532 | { 533 | "key": "value", 534 | "value": "0.0" 535 | }, 536 | { 537 | "key": "minimum", 538 | "value": "-rate/2" 539 | }, 540 | { 541 | "key": "maximum", 542 | "value": "rate/2" 543 | }, 544 | { 545 | "key": "step", 546 | "value": "rate/100" 547 | }, 548 | { 549 | "key": "precision", 550 | "value": "0" 551 | }, 552 | { 553 | "key": "sliderVisible", 554 | "value": "true" 555 | } 556 | ], 557 | "rotation": 180, 558 | "selected": false, 559 | "what": "Block", 560 | "zValue": 224 561 | }, 562 | { 563 | "affinityZone": "", 564 | "enabled": true, 565 | "id": "NumericEntry1", 566 | "inputDesc": [ 567 | { 568 | "alias": "setTitle", 569 | "dtype": "unspecified", 570 | "isSigSlot": true, 571 | "name": "setTitle", 572 | "size": 1 573 | }, 574 | { 575 | "alias": "setValue", 576 | "dtype": "unspecified", 577 | "isSigSlot": true, 578 | "name": "setValue", 579 | "size": 1 580 | }, 581 | { 582 | "alias": "setMinimum", 583 | "dtype": "unspecified", 584 | "isSigSlot": true, 585 | "name": "setMinimum", 586 | "size": 1 587 | }, 588 | { 589 | "alias": "setMaximum", 590 | "dtype": "unspecified", 591 | "isSigSlot": true, 592 | "name": "setMaximum", 593 | "size": 1 594 | }, 595 | { 596 | "alias": "setDecimals", 597 | "dtype": "unspecified", 598 | "isSigSlot": true, 599 | "name": "setDecimals", 600 | "size": 1 601 | }, 602 | { 603 | "alias": "setSingleStep", 604 | "dtype": "unspecified", 605 | "isSigSlot": true, 606 | "name": "setSingleStep", 607 | "size": 1 608 | }, 609 | { 610 | "alias": "setSliderVisible", 611 | "dtype": "unspecified", 612 | "isSigSlot": true, 613 | "name": "setSliderVisible", 614 | "size": 1 615 | } 616 | ], 617 | "outputDesc": [ 618 | { 619 | "alias": "valueChanged", 620 | "dtype": "unspecified", 621 | "isSigSlot": true, 622 | "name": "valueChanged", 623 | "size": 1 624 | } 625 | ], 626 | "path": "/widgets/numeric_entry", 627 | "positionX": 71, 628 | "positionY": 83, 629 | "properties": [ 630 | { 631 | "key": "title", 632 | "value": "\"Tone freq (Hz)\"" 633 | }, 634 | { 635 | "key": "value", 636 | "value": "rate/7" 637 | }, 638 | { 639 | "key": "minimum", 640 | "value": "-rate/2" 641 | }, 642 | { 643 | "key": "maximum", 644 | "value": "rate/2" 645 | }, 646 | { 647 | "key": "step", 648 | "value": "rate/100" 649 | }, 650 | { 651 | "key": "precision", 652 | "value": "0" 653 | }, 654 | { 655 | "key": "sliderVisible", 656 | "value": "true" 657 | } 658 | ], 659 | "rotation": 0, 660 | "selected": false, 661 | "what": "Block", 662 | "zValue": 187 663 | }, 664 | { 665 | "affinityZone": "", 666 | "enabled": true, 667 | "id": "Pacer0", 668 | "inputDesc": [ 669 | { 670 | "alias": "0", 671 | "dtype": "unspecified", 672 | "isSigSlot": false, 673 | "name": "0", 674 | "size": 1 675 | }, 676 | { 677 | "alias": "setRate", 678 | "dtype": "unspecified", 679 | "isSigSlot": true, 680 | "name": "setRate", 681 | "size": 1 682 | }, 683 | { 684 | "alias": "actualRateTriggered", 685 | "dtype": "unspecified", 686 | "isSigSlot": true, 687 | "name": "actualRateTriggered", 688 | "size": 1 689 | } 690 | ], 691 | "outputDesc": [ 692 | { 693 | "alias": "0", 694 | "dtype": "unspecified", 695 | "isSigSlot": false, 696 | "name": "0", 697 | "size": 1 698 | }, 699 | { 700 | "alias": "probeActualRate", 701 | "dtype": "unspecified", 702 | "isSigSlot": true, 703 | "name": "probeActualRate", 704 | "size": 1 705 | } 706 | ], 707 | "path": "/blocks/pacer", 708 | "positionX": 941, 709 | "positionY": 193, 710 | "properties": [ 711 | { 712 | "key": "rate", 713 | "value": "rate" 714 | } 715 | ], 716 | "rotation": 0, 717 | "selected": false, 718 | "what": "Block", 719 | "zValue": 208 720 | }, 721 | { 722 | "affinityZone": "", 723 | "enabled": true, 724 | "id": "Periodogram0", 725 | "inputDesc": [ 726 | { 727 | "alias": "setTitle", 728 | "dtype": "unspecified", 729 | "isSigSlot": true, 730 | "name": "setTitle", 731 | "size": 1 732 | }, 733 | { 734 | "alias": "setSampleRate", 735 | "dtype": "unspecified", 736 | "isSigSlot": true, 737 | "name": "setSampleRate", 738 | "size": 1 739 | }, 740 | { 741 | "alias": "setCenterFrequency", 742 | "dtype": "unspecified", 743 | "isSigSlot": true, 744 | "name": "setCenterFrequency", 745 | "size": 1 746 | }, 747 | { 748 | "alias": "setNumPoints", 749 | "dtype": "unspecified", 750 | "isSigSlot": true, 751 | "name": "setNumFFTBins", 752 | "size": 1 753 | }, 754 | { 755 | "alias": "setWindowType", 756 | "dtype": "unspecified", 757 | "isSigSlot": true, 758 | "name": "setWindowType", 759 | "size": 1 760 | }, 761 | { 762 | "alias": "setFullScale", 763 | "dtype": "unspecified", 764 | "isSigSlot": true, 765 | "name": "setFullScale", 766 | "size": 1 767 | }, 768 | { 769 | "alias": "setFFTMode", 770 | "dtype": "unspecified", 771 | "isSigSlot": true, 772 | "name": "setFFTMode", 773 | "size": 1 774 | }, 775 | { 776 | "alias": "setReferenceLevel", 777 | "dtype": "unspecified", 778 | "isSigSlot": true, 779 | "name": "setReferenceLevel", 780 | "size": 1 781 | }, 782 | { 783 | "alias": "setDynamicRange", 784 | "dtype": "unspecified", 785 | "isSigSlot": true, 786 | "name": "setDynamicRange", 787 | "size": 1 788 | }, 789 | { 790 | "alias": "setAutoScale", 791 | "dtype": "unspecified", 792 | "isSigSlot": true, 793 | "name": "setAutoScale", 794 | "size": 1 795 | }, 796 | { 797 | "alias": "setAverageFactor", 798 | "dtype": "unspecified", 799 | "isSigSlot": true, 800 | "name": "setAverageFactor", 801 | "size": 1 802 | }, 803 | { 804 | "alias": "enableXAxis", 805 | "dtype": "unspecified", 806 | "isSigSlot": true, 807 | "name": "enableXAxis", 808 | "size": 1 809 | }, 810 | { 811 | "alias": "enableYAxis", 812 | "dtype": "unspecified", 813 | "isSigSlot": true, 814 | "name": "enableYAxis", 815 | "size": 1 816 | }, 817 | { 818 | "alias": "setYAxisTitle", 819 | "dtype": "unspecified", 820 | "isSigSlot": true, 821 | "name": "setYAxisTitle", 822 | "size": 1 823 | }, 824 | { 825 | "alias": "clearChannels", 826 | "dtype": "unspecified", 827 | "isSigSlot": true, 828 | "name": "clearChannels", 829 | "size": 1 830 | }, 831 | { 832 | "alias": "setEventRate", 833 | "dtype": "unspecified", 834 | "isSigSlot": true, 835 | "name": "setDisplayRate", 836 | "size": 1 837 | }, 838 | { 839 | "alias": "0", 840 | "dtype": "unspecified", 841 | "isSigSlot": false, 842 | "name": "0", 843 | "size": 1 844 | } 845 | ], 846 | "outputDesc": [ 847 | { 848 | "alias": "frequencySelected", 849 | "dtype": "unspecified", 850 | "isSigSlot": true, 851 | "name": "frequencySelected", 852 | "size": 1 853 | } 854 | ], 855 | "path": "/plotters/periodogram", 856 | "positionX": 1073, 857 | "positionY": 81, 858 | "properties": [ 859 | { 860 | "key": "title", 861 | "value": "\"Power vs Frequency\"" 862 | }, 863 | { 864 | "key": "numInputs", 865 | "value": "1" 866 | }, 867 | { 868 | "key": "displayRate", 869 | "value": "10.0" 870 | }, 871 | { 872 | "key": "sampleRate", 873 | "value": "1e6" 874 | }, 875 | { 876 | "key": "centerFreq", 877 | "value": "0.0" 878 | }, 879 | { 880 | "key": "numBins", 881 | "value": "1024" 882 | }, 883 | { 884 | "key": "window", 885 | "value": "\"hann\"" 886 | }, 887 | { 888 | "key": "windowArgs", 889 | "value": "[]" 890 | }, 891 | { 892 | "key": "fullScale", 893 | "value": "1.0" 894 | }, 895 | { 896 | "key": "fftMode", 897 | "value": "\"AUTO\"" 898 | }, 899 | { 900 | "key": "autoScale", 901 | "value": "false" 902 | }, 903 | { 904 | "key": "refLevel", 905 | "value": "0.0" 906 | }, 907 | { 908 | "key": "dynRange", 909 | "value": "150.0" 910 | }, 911 | { 912 | "key": "averaging", 913 | "value": "0.000" 914 | }, 915 | { 916 | "key": "enableXAxis", 917 | "value": "true" 918 | }, 919 | { 920 | "key": "enableYAxis", 921 | "value": "true" 922 | }, 923 | { 924 | "key": "yAxisTitle", 925 | "value": "\"dB\"" 926 | }, 927 | { 928 | "key": "freqLabelId", 929 | "value": "\"rxFreq\"" 930 | }, 931 | { 932 | "key": "rateLabelId", 933 | "value": "\"rxRate\"" 934 | }, 935 | { 936 | "key": "startLabelId", 937 | "value": "\"\"" 938 | } 939 | ], 940 | "rotation": 0, 941 | "selected": false, 942 | "what": "Block", 943 | "zValue": 209 944 | }, 945 | { 946 | "affinityZone": "", 947 | "enabled": true, 948 | "id": "WaveformSource0", 949 | "inputDesc": [ 950 | { 951 | "alias": "setWaveform", 952 | "dtype": "unspecified", 953 | "isSigSlot": true, 954 | "name": "setWaveform", 955 | "size": 1 956 | }, 957 | { 958 | "alias": "setOffset", 959 | "dtype": "unspecified", 960 | "isSigSlot": true, 961 | "name": "setOffset", 962 | "size": 1 963 | }, 964 | { 965 | "alias": "setAmplitude", 966 | "dtype": "unspecified", 967 | "isSigSlot": true, 968 | "name": "setAmplitude", 969 | "size": 1 970 | }, 971 | { 972 | "alias": "setFrequency", 973 | "dtype": "unspecified", 974 | "isSigSlot": true, 975 | "name": "setFrequency", 976 | "size": 1 977 | }, 978 | { 979 | "alias": "setSampleRate", 980 | "dtype": "unspecified", 981 | "isSigSlot": true, 982 | "name": "setSampleRate", 983 | "size": 1 984 | }, 985 | { 986 | "alias": "setResolution", 987 | "dtype": "unspecified", 988 | "isSigSlot": true, 989 | "name": "setResolution", 990 | "size": 1 991 | } 992 | ], 993 | "outputDesc": [ 994 | { 995 | "alias": "0", 996 | "dtype": "complex_float32", 997 | "isSigSlot": false, 998 | "name": "0", 999 | "size": 8 1000 | } 1001 | ], 1002 | "path": "/comms/waveform_source", 1003 | "positionX": 300, 1004 | "positionY": 84, 1005 | "properties": [ 1006 | { 1007 | "key": "dtype", 1008 | "value": "\"complex_float32\"" 1009 | }, 1010 | { 1011 | "key": "wave", 1012 | "value": "\"SINE\"" 1013 | }, 1014 | { 1015 | "key": "rate", 1016 | "value": "rate" 1017 | }, 1018 | { 1019 | "key": "freq", 1020 | "value": "0.0" 1021 | }, 1022 | { 1023 | "key": "ampl", 1024 | "value": "1.0" 1025 | }, 1026 | { 1027 | "key": "offset", 1028 | "value": "0.0" 1029 | }, 1030 | { 1031 | "key": "res", 1032 | "value": "0.0" 1033 | } 1034 | ], 1035 | "rotation": 0, 1036 | "selected": false, 1037 | "what": "Block", 1038 | "zValue": 223 1039 | }, 1040 | { 1041 | "enabled": true, 1042 | "id": "Connection_Arithmetic00_FrequencyXlatingFIRFilter00", 1043 | "inputId": "FrequencyXlatingFIRFilter0", 1044 | "inputKey": "0", 1045 | "outputId": "Arithmetic0", 1046 | "outputKey": "0", 1047 | "positionX": 0, 1048 | "positionY": 0, 1049 | "rotation": 0, 1050 | "selected": false, 1051 | "what": "Connection", 1052 | "zValue": 0 1053 | }, 1054 | { 1055 | "enabled": true, 1056 | "id": "Connection_FIRDesigner0signals_FrequencyXlatingFIRFilter0", 1057 | "positionX": 0, 1058 | "positionY": 0, 1059 | "rotation": 0, 1060 | "selected": false, 1061 | "sigSlots": [ 1062 | [ 1063 | "tapsChanged", 1064 | "set_taps" 1065 | ] 1066 | ], 1067 | "signalId": "FIRDesigner0", 1068 | "signalKey": "signals", 1069 | "slotId": "FrequencyXlatingFIRFilter0", 1070 | "slotKey": "slots", 1071 | "what": "Connection", 1072 | "zValue": 56 1073 | }, 1074 | { 1075 | "enabled": true, 1076 | "id": "Connection_FrequencyXlatingFIRFilter00_Pacer00", 1077 | "inputId": "Pacer0", 1078 | "inputKey": "0", 1079 | "outputId": "FrequencyXlatingFIRFilter0", 1080 | "outputKey": "0", 1081 | "positionX": 0, 1082 | "positionY": 0, 1083 | "rotation": 0, 1084 | "selected": false, 1085 | "what": "Connection", 1086 | "zValue": 0 1087 | }, 1088 | { 1089 | "enabled": true, 1090 | "id": "Connection_NoiseSource00_Arithmetic00", 1091 | "inputId": "Arithmetic0", 1092 | "inputKey": "0", 1093 | "outputId": "NoiseSource0", 1094 | "outputKey": "0", 1095 | "positionX": 0, 1096 | "positionY": 0, 1097 | "rotation": 0, 1098 | "selected": false, 1099 | "what": "Connection", 1100 | "zValue": 0 1101 | }, 1102 | { 1103 | "enabled": true, 1104 | "id": "Connection_NumericEntry0signals_FrequencyXlatingFIRFilter0", 1105 | "positionX": 0, 1106 | "positionY": 0, 1107 | "rotation": 0, 1108 | "selected": false, 1109 | "sigSlots": [ 1110 | [ 1111 | "valueChanged", 1112 | "set_center_freq" 1113 | ] 1114 | ], 1115 | "signalId": "NumericEntry0", 1116 | "signalKey": "signals", 1117 | "slotId": "FrequencyXlatingFIRFilter0", 1118 | "slotKey": "slots", 1119 | "what": "Connection", 1120 | "zValue": 78 1121 | }, 1122 | { 1123 | "enabled": true, 1124 | "id": "Connection_NumericEntry1signals_WaveformSource0", 1125 | "positionX": 0, 1126 | "positionY": 0, 1127 | "rotation": 0, 1128 | "selected": false, 1129 | "sigSlots": [ 1130 | [ 1131 | "valueChanged", 1132 | "setFrequency" 1133 | ] 1134 | ], 1135 | "signalId": "NumericEntry1", 1136 | "signalKey": "signals", 1137 | "slotId": "WaveformSource0", 1138 | "slotKey": "slots", 1139 | "what": "Connection", 1140 | "zValue": 145 1141 | }, 1142 | { 1143 | "enabled": true, 1144 | "id": "Connection_Pacer00_Periodogram00", 1145 | "inputId": "Periodogram0", 1146 | "inputKey": "0", 1147 | "outputId": "Pacer0", 1148 | "outputKey": "0", 1149 | "positionX": 0, 1150 | "positionY": 0, 1151 | "rotation": 0, 1152 | "selected": false, 1153 | "what": "Connection", 1154 | "zValue": 0 1155 | }, 1156 | { 1157 | "enabled": true, 1158 | "id": "Connection_WaveformSource00_Arithmetic01", 1159 | "inputId": "Arithmetic0", 1160 | "inputKey": "1", 1161 | "outputId": "WaveformSource0", 1162 | "outputKey": "0", 1163 | "positionX": 0, 1164 | "positionY": 0, 1165 | "rotation": 0, 1166 | "selected": false, 1167 | "what": "Connection", 1168 | "zValue": 0 1169 | } 1170 | ], 1171 | "pageName": "Control", 1172 | "selected": false 1173 | } 1174 | ] 1175 | } 1176 | -------------------------------------------------------------------------------- /filter_design/test_iir_filter.pothos: -------------------------------------------------------------------------------- 1 | { 2 | "globals": [ 3 | { 4 | "name": "rate", 5 | "value": "1e6" 6 | } 7 | ], 8 | "pages": [ 9 | { 10 | "graphObjects": [ 11 | { 12 | "affinityZone": "", 13 | "enabled": true, 14 | "id": "Arithmetic0", 15 | "inputDesc": [ 16 | { 17 | "alias": "setNumInputs", 18 | "dtype": "unspecified", 19 | "isSigSlot": true, 20 | "name": "setNumInputs", 21 | "size": 1 22 | }, 23 | { 24 | "alias": "setPreload", 25 | "dtype": "unspecified", 26 | "isSigSlot": true, 27 | "name": "setPreload", 28 | "size": 1 29 | }, 30 | { 31 | "alias": "0", 32 | "dtype": "complex_float64", 33 | "isSigSlot": false, 34 | "name": "0", 35 | "size": 16 36 | }, 37 | { 38 | "alias": "1", 39 | "dtype": "complex_float64", 40 | "isSigSlot": false, 41 | "name": "1", 42 | "size": 16 43 | } 44 | ], 45 | "outputDesc": [ 46 | { 47 | "alias": "0", 48 | "dtype": "complex_float64", 49 | "isSigSlot": false, 50 | "name": "0", 51 | "size": 16 52 | } 53 | ], 54 | "path": "/comms/arithmetic", 55 | "positionX": 368, 56 | "positionY": 230, 57 | "properties": [ 58 | { 59 | "key": "dtype", 60 | "value": "\"complex_float64\"" 61 | }, 62 | { 63 | "key": "operation", 64 | "value": "\"ADD\"" 65 | }, 66 | { 67 | "key": "numInputs", 68 | "value": "2" 69 | }, 70 | { 71 | "key": "preload", 72 | "value": "[]" 73 | } 74 | ], 75 | "rotation": 0, 76 | "selected": false, 77 | "what": "Block", 78 | "zValue": 494 79 | }, 80 | { 81 | "affinityZone": "", 82 | "enabled": true, 83 | "id": "IIRFilter0", 84 | "inputDesc": [ 85 | { 86 | "alias": "0", 87 | "dtype": "complex_float64", 88 | "isSigSlot": false, 89 | "name": "0", 90 | "size": 16 91 | }, 92 | { 93 | "alias": "setTaps", 94 | "dtype": "unspecified", 95 | "isSigSlot": true, 96 | "name": "setTaps", 97 | "size": 1 98 | }, 99 | { 100 | "alias": "setWaitTaps", 101 | "dtype": "unspecified", 102 | "isSigSlot": true, 103 | "name": "setWaitTaps", 104 | "size": 1 105 | } 106 | ], 107 | "outputDesc": [ 108 | { 109 | "alias": "0", 110 | "dtype": "complex_float64", 111 | "isSigSlot": false, 112 | "name": "0", 113 | "size": 16 114 | } 115 | ], 116 | "path": "/comms/iir_filter", 117 | "positionX": 677, 118 | "positionY": 218, 119 | "properties": [ 120 | { 121 | "key": "dtype", 122 | "value": "\"complex_float64\"" 123 | }, 124 | { 125 | "key": "taps", 126 | "value": "[0.2, 0.4, 0.2, 1, -0.36892, 0.1956]" 127 | }, 128 | { 129 | "key": "waitTaps", 130 | "value": "true" 131 | } 132 | ], 133 | "rotation": 0, 134 | "selected": false, 135 | "what": "Block", 136 | "zValue": 496 137 | }, 138 | { 139 | "affinityZone": "", 140 | "enabled": true, 141 | "id": "NoiseSource0", 142 | "inputDesc": [ 143 | { 144 | "alias": "setWaveform", 145 | "dtype": "unspecified", 146 | "isSigSlot": true, 147 | "name": "setWaveform", 148 | "size": 1 149 | }, 150 | { 151 | "alias": "setOffset", 152 | "dtype": "unspecified", 153 | "isSigSlot": true, 154 | "name": "setOffset", 155 | "size": 1 156 | }, 157 | { 158 | "alias": "setAmplitude", 159 | "dtype": "unspecified", 160 | "isSigSlot": true, 161 | "name": "setAmplitude", 162 | "size": 1 163 | }, 164 | { 165 | "alias": "setMean", 166 | "dtype": "unspecified", 167 | "isSigSlot": true, 168 | "name": "setMean", 169 | "size": 1 170 | }, 171 | { 172 | "alias": "setB", 173 | "dtype": "unspecified", 174 | "isSigSlot": true, 175 | "name": "setB", 176 | "size": 1 177 | } 178 | ], 179 | "outputDesc": [ 180 | { 181 | "alias": "0", 182 | "dtype": "complex_float64", 183 | "isSigSlot": false, 184 | "name": "0", 185 | "size": 16 186 | } 187 | ], 188 | "path": "/comms/noise_source", 189 | "positionX": 80, 190 | "positionY": 174, 191 | "properties": [ 192 | { 193 | "key": "dtype", 194 | "value": "\"complex_float64\"" 195 | }, 196 | { 197 | "key": "wave", 198 | "value": "\"NORMAL\"" 199 | }, 200 | { 201 | "key": "ampl", 202 | "value": "0.1" 203 | }, 204 | { 205 | "key": "offset", 206 | "value": "0.0" 207 | }, 208 | { 209 | "key": "mean", 210 | "value": "0.0" 211 | }, 212 | { 213 | "key": "b", 214 | "value": "1.0" 215 | } 216 | ], 217 | "rotation": 0, 218 | "selected": false, 219 | "what": "Block", 220 | "zValue": 491 221 | }, 222 | { 223 | "affinityZone": "", 224 | "enabled": true, 225 | "id": "NumericEntry0", 226 | "inputDesc": [ 227 | { 228 | "alias": "setTitle", 229 | "dtype": "unspecified", 230 | "isSigSlot": true, 231 | "name": "setTitle", 232 | "size": 1 233 | }, 234 | { 235 | "alias": "setValue", 236 | "dtype": "unspecified", 237 | "isSigSlot": true, 238 | "name": "setValue", 239 | "size": 1 240 | }, 241 | { 242 | "alias": "setMinimum", 243 | "dtype": "unspecified", 244 | "isSigSlot": true, 245 | "name": "setMinimum", 246 | "size": 1 247 | }, 248 | { 249 | "alias": "setMaximum", 250 | "dtype": "unspecified", 251 | "isSigSlot": true, 252 | "name": "setMaximum", 253 | "size": 1 254 | }, 255 | { 256 | "alias": "setDecimals", 257 | "dtype": "unspecified", 258 | "isSigSlot": true, 259 | "name": "setDecimals", 260 | "size": 1 261 | }, 262 | { 263 | "alias": "setSingleStep", 264 | "dtype": "unspecified", 265 | "isSigSlot": true, 266 | "name": "setSingleStep", 267 | "size": 1 268 | }, 269 | { 270 | "alias": "setSliderVisible", 271 | "dtype": "unspecified", 272 | "isSigSlot": true, 273 | "name": "setSliderVisible", 274 | "size": 1 275 | } 276 | ], 277 | "outputDesc": [ 278 | { 279 | "alias": "valueChanged", 280 | "dtype": "unspecified", 281 | "isSigSlot": true, 282 | "name": "valueChanged", 283 | "size": 1 284 | } 285 | ], 286 | "path": "/widgets/numeric_entry", 287 | "positionX": 701, 288 | "positionY": 405, 289 | "properties": [ 290 | { 291 | "key": "title", 292 | "value": "\"Lower Frequency\"" 293 | }, 294 | { 295 | "key": "value", 296 | "value": "0.0" 297 | }, 298 | { 299 | "key": "minimum", 300 | "value": "0.01*rate" 301 | }, 302 | { 303 | "key": "maximum", 304 | "value": "rate/2" 305 | }, 306 | { 307 | "key": "step", 308 | "value": "rate/100.0" 309 | }, 310 | { 311 | "key": "precision", 312 | "value": "2" 313 | }, 314 | { 315 | "key": "sliderVisible", 316 | "value": "true" 317 | } 318 | ], 319 | "rotation": 0, 320 | "selected": false, 321 | "what": "Block", 322 | "zValue": 498 323 | }, 324 | { 325 | "affinityZone": "", 326 | "enabled": true, 327 | "id": "NumericEntry1", 328 | "inputDesc": [ 329 | { 330 | "alias": "setTitle", 331 | "dtype": "unspecified", 332 | "isSigSlot": true, 333 | "name": "setTitle", 334 | "size": 1 335 | }, 336 | { 337 | "alias": "setValue", 338 | "dtype": "unspecified", 339 | "isSigSlot": true, 340 | "name": "setValue", 341 | "size": 1 342 | }, 343 | { 344 | "alias": "setMinimum", 345 | "dtype": "unspecified", 346 | "isSigSlot": true, 347 | "name": "setMinimum", 348 | "size": 1 349 | }, 350 | { 351 | "alias": "setMaximum", 352 | "dtype": "unspecified", 353 | "isSigSlot": true, 354 | "name": "setMaximum", 355 | "size": 1 356 | }, 357 | { 358 | "alias": "setDecimals", 359 | "dtype": "unspecified", 360 | "isSigSlot": true, 361 | "name": "setDecimals", 362 | "size": 1 363 | }, 364 | { 365 | "alias": "setSingleStep", 366 | "dtype": "unspecified", 367 | "isSigSlot": true, 368 | "name": "setSingleStep", 369 | "size": 1 370 | }, 371 | { 372 | "alias": "setSliderVisible", 373 | "dtype": "unspecified", 374 | "isSigSlot": true, 375 | "name": "setSliderVisible", 376 | "size": 1 377 | } 378 | ], 379 | "outputDesc": [ 380 | { 381 | "alias": "valueChanged", 382 | "dtype": "unspecified", 383 | "isSigSlot": true, 384 | "name": "valueChanged", 385 | "size": 1 386 | } 387 | ], 388 | "path": "/widgets/numeric_entry", 389 | "positionX": 78, 390 | "positionY": 322, 391 | "properties": [ 392 | { 393 | "key": "title", 394 | "value": "\"Tone freq (Hz)\"" 395 | }, 396 | { 397 | "key": "value", 398 | "value": "rate/7" 399 | }, 400 | { 401 | "key": "minimum", 402 | "value": "-rate/2" 403 | }, 404 | { 405 | "key": "maximum", 406 | "value": "rate/2" 407 | }, 408 | { 409 | "key": "step", 410 | "value": "rate/100" 411 | }, 412 | { 413 | "key": "precision", 414 | "value": "0" 415 | }, 416 | { 417 | "key": "sliderVisible", 418 | "value": "true" 419 | } 420 | ], 421 | "rotation": 0, 422 | "selected": false, 423 | "what": "Block", 424 | "zValue": 492 425 | }, 426 | { 427 | "affinityZone": "", 428 | "enabled": true, 429 | "id": "Pacer0", 430 | "inputDesc": [ 431 | { 432 | "alias": "0", 433 | "dtype": "unspecified", 434 | "isSigSlot": false, 435 | "name": "0", 436 | "size": 1 437 | }, 438 | { 439 | "alias": "setRate", 440 | "dtype": "unspecified", 441 | "isSigSlot": true, 442 | "name": "setRate", 443 | "size": 1 444 | }, 445 | { 446 | "alias": "actualRateTriggered", 447 | "dtype": "unspecified", 448 | "isSigSlot": true, 449 | "name": "actualRateTriggered", 450 | "size": 1 451 | } 452 | ], 453 | "outputDesc": [ 454 | { 455 | "alias": "0", 456 | "dtype": "unspecified", 457 | "isSigSlot": false, 458 | "name": "0", 459 | "size": 1 460 | }, 461 | { 462 | "alias": "probeActualRate", 463 | "dtype": "unspecified", 464 | "isSigSlot": true, 465 | "name": "probeActualRate", 466 | "size": 1 467 | } 468 | ], 469 | "path": "/blocks/pacer", 470 | "positionX": 504, 471 | "positionY": 216, 472 | "properties": [ 473 | { 474 | "key": "rate", 475 | "value": "rate" 476 | } 477 | ], 478 | "rotation": 0, 479 | "selected": false, 480 | "what": "Block", 481 | "zValue": 495 482 | }, 483 | { 484 | "affinityZone": "", 485 | "enabled": true, 486 | "id": "Periodogram0", 487 | "inputDesc": [ 488 | { 489 | "alias": "setTitle", 490 | "dtype": "unspecified", 491 | "isSigSlot": true, 492 | "name": "setTitle", 493 | "size": 1 494 | }, 495 | { 496 | "alias": "setSampleRate", 497 | "dtype": "unspecified", 498 | "isSigSlot": true, 499 | "name": "setSampleRate", 500 | "size": 1 501 | }, 502 | { 503 | "alias": "setCenterFrequency", 504 | "dtype": "unspecified", 505 | "isSigSlot": true, 506 | "name": "setCenterFrequency", 507 | "size": 1 508 | }, 509 | { 510 | "alias": "setNumPoints", 511 | "dtype": "unspecified", 512 | "isSigSlot": true, 513 | "name": "setNumFFTBins", 514 | "size": 1 515 | }, 516 | { 517 | "alias": "setWindowType", 518 | "dtype": "unspecified", 519 | "isSigSlot": true, 520 | "name": "setWindowType", 521 | "size": 1 522 | }, 523 | { 524 | "alias": "setFullScale", 525 | "dtype": "unspecified", 526 | "isSigSlot": true, 527 | "name": "setFullScale", 528 | "size": 1 529 | }, 530 | { 531 | "alias": "setFFTMode", 532 | "dtype": "unspecified", 533 | "isSigSlot": true, 534 | "name": "setFFTMode", 535 | "size": 1 536 | }, 537 | { 538 | "alias": "setReferenceLevel", 539 | "dtype": "unspecified", 540 | "isSigSlot": true, 541 | "name": "setReferenceLevel", 542 | "size": 1 543 | }, 544 | { 545 | "alias": "setDynamicRange", 546 | "dtype": "unspecified", 547 | "isSigSlot": true, 548 | "name": "setDynamicRange", 549 | "size": 1 550 | }, 551 | { 552 | "alias": "setAutoScale", 553 | "dtype": "unspecified", 554 | "isSigSlot": true, 555 | "name": "setAutoScale", 556 | "size": 1 557 | }, 558 | { 559 | "alias": "setAverageFactor", 560 | "dtype": "unspecified", 561 | "isSigSlot": true, 562 | "name": "setAverageFactor", 563 | "size": 1 564 | }, 565 | { 566 | "alias": "enableXAxis", 567 | "dtype": "unspecified", 568 | "isSigSlot": true, 569 | "name": "enableXAxis", 570 | "size": 1 571 | }, 572 | { 573 | "alias": "enableYAxis", 574 | "dtype": "unspecified", 575 | "isSigSlot": true, 576 | "name": "enableYAxis", 577 | "size": 1 578 | }, 579 | { 580 | "alias": "setYAxisTitle", 581 | "dtype": "unspecified", 582 | "isSigSlot": true, 583 | "name": "setYAxisTitle", 584 | "size": 1 585 | }, 586 | { 587 | "alias": "clearChannels", 588 | "dtype": "unspecified", 589 | "isSigSlot": true, 590 | "name": "clearChannels", 591 | "size": 1 592 | }, 593 | { 594 | "alias": "setEventRate", 595 | "dtype": "unspecified", 596 | "isSigSlot": true, 597 | "name": "setDisplayRate", 598 | "size": 1 599 | }, 600 | { 601 | "alias": "0", 602 | "dtype": "unspecified", 603 | "isSigSlot": false, 604 | "name": "0", 605 | "size": 1 606 | } 607 | ], 608 | "outputDesc": [ 609 | { 610 | "alias": "frequencySelected", 611 | "dtype": "unspecified", 612 | "isSigSlot": true, 613 | "name": "frequencySelected", 614 | "size": 1 615 | } 616 | ], 617 | "path": "/plotters/periodogram", 618 | "positionX": 896, 619 | "positionY": 203, 620 | "properties": [ 621 | { 622 | "key": "title", 623 | "value": "\"Power vs Frequency\"" 624 | }, 625 | { 626 | "key": "numInputs", 627 | "value": "1" 628 | }, 629 | { 630 | "key": "displayRate", 631 | "value": "10.0" 632 | }, 633 | { 634 | "key": "sampleRate", 635 | "value": "1e6" 636 | }, 637 | { 638 | "key": "centerFreq", 639 | "value": "0.0" 640 | }, 641 | { 642 | "key": "numBins", 643 | "value": "1024" 644 | }, 645 | { 646 | "key": "window", 647 | "value": "\"hann\"" 648 | }, 649 | { 650 | "key": "windowArgs", 651 | "value": "[]" 652 | }, 653 | { 654 | "key": "fullScale", 655 | "value": "1.0" 656 | }, 657 | { 658 | "key": "fftMode", 659 | "value": "\"AUTO\"" 660 | }, 661 | { 662 | "key": "autoScale", 663 | "value": "false" 664 | }, 665 | { 666 | "key": "refLevel", 667 | "value": "0.0" 668 | }, 669 | { 670 | "key": "dynRange", 671 | "value": "150.0" 672 | }, 673 | { 674 | "key": "averaging", 675 | "value": "0.000" 676 | }, 677 | { 678 | "key": "enableXAxis", 679 | "value": "true" 680 | }, 681 | { 682 | "key": "enableYAxis", 683 | "value": "true" 684 | }, 685 | { 686 | "key": "yAxisTitle", 687 | "value": "\"dB\"" 688 | }, 689 | { 690 | "key": "freqLabelId", 691 | "value": "\"rxFreq\"" 692 | }, 693 | { 694 | "key": "rateLabelId", 695 | "value": "\"rxRate\"" 696 | }, 697 | { 698 | "key": "startLabelId", 699 | "value": "\"\"" 700 | } 701 | ], 702 | "rotation": 0, 703 | "selected": false, 704 | "what": "Block", 705 | "zValue": 497 706 | }, 707 | { 708 | "affinityZone": "", 709 | "enabled": true, 710 | "id": "WaveformSource0", 711 | "inputDesc": [ 712 | { 713 | "alias": "setWaveform", 714 | "dtype": "unspecified", 715 | "isSigSlot": true, 716 | "name": "setWaveform", 717 | "size": 1 718 | }, 719 | { 720 | "alias": "setOffset", 721 | "dtype": "unspecified", 722 | "isSigSlot": true, 723 | "name": "setOffset", 724 | "size": 1 725 | }, 726 | { 727 | "alias": "setAmplitude", 728 | "dtype": "unspecified", 729 | "isSigSlot": true, 730 | "name": "setAmplitude", 731 | "size": 1 732 | }, 733 | { 734 | "alias": "setFrequency", 735 | "dtype": "unspecified", 736 | "isSigSlot": true, 737 | "name": "setFrequency", 738 | "size": 1 739 | }, 740 | { 741 | "alias": "setSampleRate", 742 | "dtype": "unspecified", 743 | "isSigSlot": true, 744 | "name": "setSampleRate", 745 | "size": 1 746 | }, 747 | { 748 | "alias": "setResolution", 749 | "dtype": "unspecified", 750 | "isSigSlot": true, 751 | "name": "setResolution", 752 | "size": 1 753 | } 754 | ], 755 | "outputDesc": [ 756 | { 757 | "alias": "0", 758 | "dtype": "complex_float64", 759 | "isSigSlot": false, 760 | "name": "0", 761 | "size": 16 762 | } 763 | ], 764 | "path": "/comms/waveform_source", 765 | "positionX": 239, 766 | "positionY": 397, 767 | "properties": [ 768 | { 769 | "key": "dtype", 770 | "value": "\"complex_float64\"" 771 | }, 772 | { 773 | "key": "wave", 774 | "value": "\"SINE\"" 775 | }, 776 | { 777 | "key": "rate", 778 | "value": "rate" 779 | }, 780 | { 781 | "key": "freq", 782 | "value": "0.0" 783 | }, 784 | { 785 | "key": "ampl", 786 | "value": "1.0" 787 | }, 788 | { 789 | "key": "offset", 790 | "value": "0.0" 791 | }, 792 | { 793 | "key": "res", 794 | "value": "0.0" 795 | } 796 | ], 797 | "rotation": 0, 798 | "selected": false, 799 | "what": "Block", 800 | "zValue": 493 801 | }, 802 | { 803 | "enabled": true, 804 | "id": "IIRDesigner2", 805 | "isInput": false, 806 | "nodeName": "IIRDesigner1", 807 | "positionX": 481, 808 | "positionY": 378, 809 | "rotation": 0, 810 | "selected": false, 811 | "what": "Breaker", 812 | "zValue": 485 813 | }, 814 | { 815 | "enabled": true, 816 | "id": "NumericEntry2", 817 | "isInput": true, 818 | "nodeName": "NumericEntry2", 819 | "positionX": 897, 820 | "positionY": 404, 821 | "rotation": 0, 822 | "selected": false, 823 | "what": "Breaker", 824 | "zValue": 486 825 | }, 826 | { 827 | "enabled": true, 828 | "id": "Connection_Arithmetic00_Pacer00", 829 | "inputId": "Pacer0", 830 | "inputKey": "0", 831 | "outputId": "Arithmetic0", 832 | "outputKey": "0", 833 | "positionX": 0, 834 | "positionY": 0, 835 | "rotation": 0, 836 | "selected": false, 837 | "what": "Connection", 838 | "zValue": 0 839 | }, 840 | { 841 | "enabled": true, 842 | "id": "Connection_IIRDesigner20_IIRFilter0", 843 | "outputId": "IIRDesigner2", 844 | "outputKey": "0", 845 | "positionX": 0, 846 | "positionY": 0, 847 | "rotation": 0, 848 | "selected": false, 849 | "sigSlots": [ 850 | [ 851 | "0", 852 | "setTaps" 853 | ] 854 | ], 855 | "slotId": "IIRFilter0", 856 | "slotKey": "slots", 857 | "what": "Connection", 858 | "zValue": 0 859 | }, 860 | { 861 | "enabled": true, 862 | "id": "Connection_IIRFilter00_Periodogram00", 863 | "inputId": "Periodogram0", 864 | "inputKey": "0", 865 | "outputId": "IIRFilter0", 866 | "outputKey": "0", 867 | "positionX": 0, 868 | "positionY": 0, 869 | "rotation": 0, 870 | "selected": false, 871 | "what": "Connection", 872 | "zValue": 0 873 | }, 874 | { 875 | "enabled": true, 876 | "id": "Connection_NoiseSource00_Arithmetic00", 877 | "inputId": "Arithmetic0", 878 | "inputKey": "0", 879 | "outputId": "NoiseSource0", 880 | "outputKey": "0", 881 | "positionX": 0, 882 | "positionY": 0, 883 | "rotation": 0, 884 | "selected": false, 885 | "what": "Connection", 886 | "zValue": 0 887 | }, 888 | { 889 | "enabled": true, 890 | "id": "Connection_NumericEntry0signals_NumericEntry20", 891 | "inputId": "NumericEntry2", 892 | "inputKey": "0", 893 | "positionX": 0, 894 | "positionY": 0, 895 | "rotation": 0, 896 | "selected": false, 897 | "sigSlots": [ 898 | [ 899 | "valueChanged", 900 | "0" 901 | ] 902 | ], 903 | "signalId": "NumericEntry0", 904 | "signalKey": "signals", 905 | "what": "Connection", 906 | "zValue": 0 907 | }, 908 | { 909 | "enabled": true, 910 | "id": "Connection_NumericEntry1signals_WaveformSource0", 911 | "positionX": 0, 912 | "positionY": 0, 913 | "rotation": 0, 914 | "selected": false, 915 | "sigSlots": [ 916 | [ 917 | "valueChanged", 918 | "setFrequency" 919 | ] 920 | ], 921 | "signalId": "NumericEntry1", 922 | "signalKey": "signals", 923 | "slotId": "WaveformSource0", 924 | "slotKey": "slots", 925 | "what": "Connection", 926 | "zValue": 145 927 | }, 928 | { 929 | "enabled": true, 930 | "id": "Connection_Pacer00_IIRFilter00", 931 | "inputId": "IIRFilter0", 932 | "inputKey": "0", 933 | "outputId": "Pacer0", 934 | "outputKey": "0", 935 | "positionX": 0, 936 | "positionY": 0, 937 | "rotation": 0, 938 | "selected": false, 939 | "what": "Connection", 940 | "zValue": 0 941 | }, 942 | { 943 | "enabled": true, 944 | "id": "Connection_WaveformSource00_Arithmetic01", 945 | "inputId": "Arithmetic0", 946 | "inputKey": "1", 947 | "outputId": "WaveformSource0", 948 | "outputKey": "0", 949 | "positionX": 0, 950 | "positionY": 0, 951 | "rotation": 0, 952 | "selected": false, 953 | "what": "Connection", 954 | "zValue": 0 955 | } 956 | ], 957 | "pageName": "Main", 958 | "selected": false 959 | }, 960 | { 961 | "graphObjects": [ 962 | { 963 | "affinityZone": "", 964 | "enabled": true, 965 | "id": "IIRDesigner0", 966 | "inputDesc": [ 967 | { 968 | "alias": "setFilterType", 969 | "dtype": "unspecified", 970 | "isSigSlot": true, 971 | "name": "setFilterType", 972 | "size": 1 973 | }, 974 | { 975 | "alias": "setIIRType", 976 | "dtype": "unspecified", 977 | "isSigSlot": true, 978 | "name": "setIIRType", 979 | "size": 1 980 | }, 981 | { 982 | "alias": "setSampleRate", 983 | "dtype": "unspecified", 984 | "isSigSlot": true, 985 | "name": "setSampleRate", 986 | "size": 1 987 | }, 988 | { 989 | "alias": "setFrequencyLower", 990 | "dtype": "unspecified", 991 | "isSigSlot": true, 992 | "name": "setFrequencyLower", 993 | "size": 1 994 | }, 995 | { 996 | "alias": "setFrequencyUpper", 997 | "dtype": "unspecified", 998 | "isSigSlot": true, 999 | "name": "setFrequencyUpper", 1000 | "size": 1 1001 | }, 1002 | { 1003 | "alias": "setOrder", 1004 | "dtype": "unspecified", 1005 | "isSigSlot": true, 1006 | "name": "setOrder", 1007 | "size": 1 1008 | }, 1009 | { 1010 | "alias": "setRipple", 1011 | "dtype": "unspecified", 1012 | "isSigSlot": true, 1013 | "name": "setRipple", 1014 | "size": 1 1015 | }, 1016 | { 1017 | "alias": "setStopBandAtten", 1018 | "dtype": "unspecified", 1019 | "isSigSlot": true, 1020 | "name": "setStopBandAtten", 1021 | "size": 1 1022 | } 1023 | ], 1024 | "outputDesc": [ 1025 | { 1026 | "alias": "tapsChanged", 1027 | "dtype": "unspecified", 1028 | "isSigSlot": true, 1029 | "name": "tapsChanged", 1030 | "size": 1 1031 | } 1032 | ], 1033 | "path": "/comms/iir_designer", 1034 | "positionX": 819, 1035 | "positionY": 87, 1036 | "properties": [ 1037 | { 1038 | "key": "type", 1039 | "value": "\"BAND_PASS\"" 1040 | }, 1041 | { 1042 | "key": "iir", 1043 | "value": "\"butterworth\"" 1044 | }, 1045 | { 1046 | "key": "sampRate", 1047 | "value": "rate" 1048 | }, 1049 | { 1050 | "key": "order", 1051 | "value": "5" 1052 | }, 1053 | { 1054 | "key": "freqLower", 1055 | "value": "0.2*rate" 1056 | }, 1057 | { 1058 | "key": "freqUpper", 1059 | "value": "0.3*rate" 1060 | }, 1061 | { 1062 | "key": "stopBandAtten", 1063 | "value": "80" 1064 | }, 1065 | { 1066 | "key": "ripple", 1067 | "value": "0.1" 1068 | } 1069 | ], 1070 | "rotation": 0, 1071 | "selected": false, 1072 | "what": "Block", 1073 | "zValue": 537 1074 | }, 1075 | { 1076 | "enabled": true, 1077 | "id": "IIRDesigner1", 1078 | "isInput": true, 1079 | "nodeName": "IIRDesigner1", 1080 | "positionX": 1022, 1081 | "positionY": 87, 1082 | "rotation": 0, 1083 | "selected": false, 1084 | "what": "Breaker", 1085 | "zValue": 540 1086 | }, 1087 | { 1088 | "enabled": true, 1089 | "id": "NumericEntry3", 1090 | "isInput": false, 1091 | "nodeName": "NumericEntry2", 1092 | "positionX": 556, 1093 | "positionY": 43, 1094 | "rotation": 0, 1095 | "selected": false, 1096 | "what": "Breaker", 1097 | "zValue": 538 1098 | }, 1099 | { 1100 | "enabled": true, 1101 | "id": "Connection_IIRDesigner0signals_IIRDesigner10", 1102 | "inputId": "IIRDesigner1", 1103 | "inputKey": "0", 1104 | "positionX": 0, 1105 | "positionY": 0, 1106 | "rotation": 0, 1107 | "selected": false, 1108 | "sigSlots": [ 1109 | [ 1110 | "tapsChanged", 1111 | "0" 1112 | ] 1113 | ], 1114 | "signalId": "IIRDesigner0", 1115 | "signalKey": "signals", 1116 | "what": "Connection", 1117 | "zValue": 0 1118 | }, 1119 | { 1120 | "enabled": true, 1121 | "id": "Connection_NumericEntry30_IIRDesigner0", 1122 | "outputId": "NumericEntry3", 1123 | "outputKey": "0", 1124 | "positionX": 0, 1125 | "positionY": 0, 1126 | "rotation": 0, 1127 | "selected": false, 1128 | "sigSlots": [ 1129 | [ 1130 | "0", 1131 | "setFrequencyLower" 1132 | ] 1133 | ], 1134 | "slotId": "IIRDesigner0", 1135 | "slotKey": "slots", 1136 | "what": "Connection", 1137 | "zValue": 0 1138 | }, 1139 | { 1140 | "blockId": "NumericEntry0", 1141 | "enabled": true, 1142 | "height": 56, 1143 | "id": "WidgetNumericEntry0", 1144 | "positionX": 270, 1145 | "positionY": 7, 1146 | "rotation": 0, 1147 | "selected": false, 1148 | "state": "AAAABgBA/70AAAAAAA==", 1149 | "what": "Widget", 1150 | "width": 220, 1151 | "zValue": 548 1152 | }, 1153 | { 1154 | "blockId": "NumericEntry1", 1155 | "enabled": true, 1156 | "height": 56, 1157 | "id": "WidgetNumericEntry1", 1158 | "positionX": 16, 1159 | "positionY": 10, 1160 | "rotation": 0, 1161 | "selected": false, 1162 | "state": "AAAABgBBCGoAAAAAAA==", 1163 | "what": "Widget", 1164 | "width": 229, 1165 | "zValue": 545 1166 | }, 1167 | { 1168 | "blockId": "Periodogram0", 1169 | "enabled": true, 1170 | "height": 328, 1171 | "id": "WidgetPeriodogram0", 1172 | "positionX": 32, 1173 | "positionY": 116, 1174 | "rotation": 0, 1175 | "selected": false, 1176 | "state": "AAAACAAAAAADAAAADgB2AGkAcwBpAGIAbABlAAAADQAAAAAEAwAAAAoAcwB0AGEAYwBrAAAACQAAAAABAAAAFADAf0AAAAAAAMBiwAAAAAAAQI9AAAAAAABAYsAAAAAAAAAAAAoAaQBuAGQAZQB4AAAAAwAAAAAA", 1177 | "what": "Widget", 1178 | "width": 627, 1179 | "zValue": 532 1180 | } 1181 | ], 1182 | "pageName": "Control", 1183 | "selected": true 1184 | } 1185 | ] 1186 | } 1187 | -------------------------------------------------------------------------------- /jit_cpp_block/README.md: -------------------------------------------------------------------------------- 1 | # C++ JIT block demo 2 | 3 | This directory is an example of a C++ JIT compilation unit. 4 | Its composed of: 5 | 6 | * SimpleFloatAdder.cpp - A simple C++ block with block description markup for the GUI 7 | * SimpleFloatAdder.conf - a config file to describe the compilation unit 8 | 9 | ## Installing 10 | 11 | Pothos will automatically take care of compiling the source when the block is instantiated. 12 | We only need to make Pothos aware of this compilation unit with configuration file. 13 | To do this we either need to copy this directory to a known location 14 | or to symlink this directory to a well known location. 15 | 16 | ## Option 1: symlink 17 | 18 | Symlink this directory into the user's home directory. 19 | Use this option when the source is being developed and maintained 20 | in a source code repository. Pothos will automatically rebuild 21 | on plugin reload if the local source in the repository is changed. 22 | 23 | ``` 24 | cd pothos-demos/jit_cpp_block 25 | mkdir -p ${HOME}/.config/Pothos/modules/examples 26 | ln -sf $(pwd) ${HOME}/.config/Pothos/modules/examples/simple_float_adder 27 | ``` 28 | 29 | ## Option 2: copy 30 | 31 | Copy this directory into system install prefix. 32 | Use this option when installing processing IP permanently, 33 | like from a larger build system or package manager. 34 | 35 | ``` 36 | cd pothos-demos/jit_cpp_block 37 | mkdir -p /usr/local/share/Pothos/modules/examples 38 | cp -r . /usr/local/share/Pothos/modules/examples/simple_float_adder 39 | ``` 40 | 41 | ## Running 42 | 43 | An demonstration topology ``topology_with_adder.pothos`` is included 44 | along with the simple adder block. Simply open this topology 45 | in the Pothos GUI and the block will be compiled automatically. 46 | -------------------------------------------------------------------------------- /jit_cpp_block/SimpleFloatAdder.conf: -------------------------------------------------------------------------------- 1 | # engage the JIT compiler hooks 2 | loader = jit_compiler 3 | 4 | # The build target or the file name for the compiled module. 5 | # Uses the config file's name when target is not specified. 6 | #target = SimpleFloatAdder 7 | 8 | # A list of sources for this module 9 | # supports both relative and absolute paths 10 | sources = SimpleFloatAdder.cpp 11 | 12 | # A list of include directories 13 | # supports both relative and absolute paths 14 | #includes = /usr/include/foo 15 | 16 | # A list of libraries to link against 17 | # supports both relative and absolute paths 18 | #libraries = /usr/lib/libfoo.so 19 | 20 | # A list of compiler flags 21 | #flags = -DHAS_FOO=1 22 | 23 | # A list of sources to search for block descriptions 24 | # When not specified, all specified sources are searched 25 | #doc_sources = MyBlock.hpp 26 | 27 | # A list of block factories 28 | # These are automatically extracted from the block descriptions. 29 | # Use factories when there are no descriptions (for non-gui use). 30 | #factories = /examples/my_block 31 | -------------------------------------------------------------------------------- /jit_cpp_block/SimpleFloatAdder.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /*********************************************************************** 4 | * |PothosDoc Simple Float Adder 5 | * 6 | * Add two floating point input streams and produce an output stream. 7 | * 8 | * This is an incredibly simple block. 9 | * Its main purpose is to demonstrate JIT compilation of C++ blocks. 10 | * 11 | * |category /Examples 12 | * |keywords math examples adder 13 | * 14 | * |factory /examples/simple_float_adder() 15 | **********************************************************************/ 16 | class SimpleFloatAdder : public Pothos::Block 17 | { 18 | public: 19 | SimpleFloatAdder(void) 20 | { 21 | this->setupInput(0, typeid(float)); 22 | this->setupInput(1, typeid(float)); 23 | this->setupOutput(0, typeid(float)); 24 | } 25 | 26 | static Block *make(void) 27 | { 28 | return new SimpleFloatAdder(); 29 | } 30 | 31 | void work(void) 32 | { 33 | //get the minimum number of elements available across all indexed ports 34 | const size_t N = this->workInfo().minElements; 35 | if (N == 0) return; 36 | 37 | //get pointers to the input and output ports and buffers 38 | auto inPort0 = this->input(0); 39 | auto inPort1 = this->input(1); 40 | auto outPort = this->output(0); 41 | const float *inBuff0 = inPort0->buffer(); 42 | const float *inBuff1 = inPort1->buffer(); 43 | float *outBuff = outPort->buffer(); 44 | 45 | //perform the addition operation 46 | for (size_t i = 0; i < N; i++) 47 | { 48 | outBuff[i] = inBuff0[i] + inBuff1[i]; 49 | } 50 | 51 | //produce and consume on all ports 52 | inPort0->consume(N); 53 | inPort1->consume(N); 54 | outPort->produce(N); 55 | } 56 | }; 57 | 58 | //register SimpleFloatAdder into the block registry 59 | static Pothos::BlockRegistry registerSimpleFloatAdder( 60 | "/examples/simple_float_adder", &SimpleFloatAdder::make); 61 | -------------------------------------------------------------------------------- /jit_cpp_block/topology_with_adder.pothos: -------------------------------------------------------------------------------- 1 | { 2 | "globals" : [ 3 | 4 | ], 5 | "pages" : [ 6 | { 7 | "graphObjects" : [ 8 | { 9 | "affinityZone" : "", 10 | "enabled" : true, 11 | "id" : "SimpleFloatAdder0", 12 | "inputDesc" : [ 13 | { 14 | "alias" : "0", 15 | "dtype" : "float32", 16 | "isSigSlot" : false, 17 | "name" : "0", 18 | "size" : 4 19 | }, 20 | { 21 | "alias" : "1", 22 | "dtype" : "float32", 23 | "isSigSlot" : false, 24 | "name" : "1", 25 | "size" : 4 26 | } 27 | ], 28 | "outputDesc" : [ 29 | { 30 | "alias" : "0", 31 | "dtype" : "float32", 32 | "isSigSlot" : false, 33 | "name" : "0", 34 | "size" : 4 35 | } 36 | ], 37 | "path" : "\/examples\/simple_float_adder", 38 | "positionX" : 425, 39 | "positionY" : 163, 40 | "properties" : [ 41 | 42 | ], 43 | "rotation" : 0, 44 | "selected" : false, 45 | "what" : "Block", 46 | "zValue" : 26 47 | }, 48 | { 49 | "affinityZone" : "", 50 | "enabled" : true, 51 | "id" : "NoiseSource0", 52 | "inputDesc" : [ 53 | { 54 | "alias" : "setWaveform", 55 | "dtype" : "unspecified", 56 | "isSigSlot" : true, 57 | "name" : "setWaveform", 58 | "size" : 1 59 | }, 60 | { 61 | "alias" : "setOffset", 62 | "dtype" : "unspecified", 63 | "isSigSlot" : true, 64 | "name" : "setOffset", 65 | "size" : 1 66 | }, 67 | { 68 | "alias" : "setAmplitude", 69 | "dtype" : "unspecified", 70 | "isSigSlot" : true, 71 | "name" : "setAmplitude", 72 | "size" : 1 73 | }, 74 | { 75 | "alias" : "setMean", 76 | "dtype" : "unspecified", 77 | "isSigSlot" : true, 78 | "name" : "setMean", 79 | "size" : 1 80 | }, 81 | { 82 | "alias" : "setB", 83 | "dtype" : "unspecified", 84 | "isSigSlot" : true, 85 | "name" : "setB", 86 | "size" : 1 87 | } 88 | ], 89 | "outputDesc" : [ 90 | { 91 | "alias" : "0", 92 | "dtype" : "float32", 93 | "isSigSlot" : false, 94 | "name" : "0", 95 | "size" : 4 96 | } 97 | ], 98 | "path" : "\/comms\/noise_source", 99 | "positionX" : 148, 100 | "positionY" : 251, 101 | "properties" : [ 102 | { 103 | "key" : "dtype", 104 | "value" : "\"float32\"" 105 | }, 106 | { 107 | "key" : "wave", 108 | "value" : "\"NORMAL\"" 109 | }, 110 | { 111 | "key" : "ampl", 112 | "value" : "0.01" 113 | }, 114 | { 115 | "key" : "offset", 116 | "value" : "0.0" 117 | }, 118 | { 119 | "key" : "mean", 120 | "value" : "0.0" 121 | }, 122 | { 123 | "key" : "b", 124 | "value" : "1.0" 125 | } 126 | ], 127 | "rotation" : 0, 128 | "selected" : false, 129 | "what" : "Block", 130 | "zValue" : 29 131 | }, 132 | { 133 | "affinityZone" : "", 134 | "enabled" : true, 135 | "id" : "WaveformSource0", 136 | "inputDesc" : [ 137 | { 138 | "alias" : "setWaveform", 139 | "dtype" : "unspecified", 140 | "isSigSlot" : true, 141 | "name" : "setWaveform", 142 | "size" : 1 143 | }, 144 | { 145 | "alias" : "setOffset", 146 | "dtype" : "unspecified", 147 | "isSigSlot" : true, 148 | "name" : "setOffset", 149 | "size" : 1 150 | }, 151 | { 152 | "alias" : "setAmplitude", 153 | "dtype" : "unspecified", 154 | "isSigSlot" : true, 155 | "name" : "setAmplitude", 156 | "size" : 1 157 | }, 158 | { 159 | "alias" : "setFrequency", 160 | "dtype" : "unspecified", 161 | "isSigSlot" : true, 162 | "name" : "setFrequency", 163 | "size" : 1 164 | }, 165 | { 166 | "alias" : "setSampleRate", 167 | "dtype" : "unspecified", 168 | "isSigSlot" : true, 169 | "name" : "setSampleRate", 170 | "size" : 1 171 | }, 172 | { 173 | "alias" : "setResolution", 174 | "dtype" : "unspecified", 175 | "isSigSlot" : true, 176 | "name" : "setResolution", 177 | "size" : 1 178 | } 179 | ], 180 | "outputDesc" : [ 181 | { 182 | "alias" : "0", 183 | "dtype" : "float32", 184 | "isSigSlot" : false, 185 | "name" : "0", 186 | "size" : 4 187 | } 188 | ], 189 | "path" : "\/comms\/waveform_source", 190 | "positionX" : 145, 191 | "positionY" : 109, 192 | "properties" : [ 193 | { 194 | "key" : "dtype", 195 | "value" : "\"float32\"" 196 | }, 197 | { 198 | "key" : "wave", 199 | "value" : "\"SINE\"" 200 | }, 201 | { 202 | "key" : "rate", 203 | "value" : "1e6" 204 | }, 205 | { 206 | "key" : "freq", 207 | "value" : "1.1e5" 208 | }, 209 | { 210 | "key" : "ampl", 211 | "value" : "1.0" 212 | }, 213 | { 214 | "key" : "offset", 215 | "value" : "0.0" 216 | }, 217 | { 218 | "key" : "res", 219 | "value" : "0.0" 220 | } 221 | ], 222 | "rotation" : 0, 223 | "selected" : false, 224 | "what" : "Block", 225 | "zValue" : 24 226 | }, 227 | { 228 | "affinityZone" : "", 229 | "enabled" : true, 230 | "id" : "Pacer0", 231 | "inputDesc" : [ 232 | { 233 | "alias" : "0", 234 | "dtype" : "unspecified", 235 | "isSigSlot" : false, 236 | "name" : "0", 237 | "size" : 1 238 | }, 239 | { 240 | "alias" : "setRate", 241 | "dtype" : "unspecified", 242 | "isSigSlot" : true, 243 | "name" : "setRate", 244 | "size" : 1 245 | }, 246 | { 247 | "alias" : "actualRateTriggered", 248 | "dtype" : "unspecified", 249 | "isSigSlot" : true, 250 | "name" : "actualRateTriggered", 251 | "size" : 1 252 | } 253 | ], 254 | "outputDesc" : [ 255 | { 256 | "alias" : "0", 257 | "dtype" : "unspecified", 258 | "isSigSlot" : false, 259 | "name" : "0", 260 | "size" : 1 261 | }, 262 | { 263 | "alias" : "probeActualRate", 264 | "dtype" : "unspecified", 265 | "isSigSlot" : true, 266 | "name" : "probeActualRate", 267 | "size" : 1 268 | } 269 | ], 270 | "path" : "\/blocks\/pacer", 271 | "positionX" : 660, 272 | "positionY" : 126, 273 | "properties" : [ 274 | { 275 | "key" : "rate", 276 | "value" : "1e6" 277 | } 278 | ], 279 | "rotation" : 0, 280 | "selected" : false, 281 | "what" : "Block", 282 | "zValue" : 28 283 | }, 284 | { 285 | "affinityZone" : "", 286 | "enabled" : true, 287 | "id" : "Periodogram0", 288 | "inputDesc" : [ 289 | { 290 | "alias" : "setTitle", 291 | "dtype" : "unspecified", 292 | "isSigSlot" : true, 293 | "name" : "setTitle", 294 | "size" : 1 295 | }, 296 | { 297 | "alias" : "setSampleRate", 298 | "dtype" : "unspecified", 299 | "isSigSlot" : true, 300 | "name" : "setSampleRate", 301 | "size" : 1 302 | }, 303 | { 304 | "alias" : "setCenterFrequency", 305 | "dtype" : "unspecified", 306 | "isSigSlot" : true, 307 | "name" : "setCenterFrequency", 308 | "size" : 1 309 | }, 310 | { 311 | "alias" : "setNumPoints", 312 | "dtype" : "unspecified", 313 | "isSigSlot" : true, 314 | "name" : "setNumFFTBins", 315 | "size" : 1 316 | }, 317 | { 318 | "alias" : "setWindowType", 319 | "dtype" : "unspecified", 320 | "isSigSlot" : true, 321 | "name" : "setWindowType", 322 | "size" : 1 323 | }, 324 | { 325 | "alias" : "setFullScale", 326 | "dtype" : "unspecified", 327 | "isSigSlot" : true, 328 | "name" : "setFullScale", 329 | "size" : 1 330 | }, 331 | { 332 | "alias" : "setFFTMode", 333 | "dtype" : "unspecified", 334 | "isSigSlot" : true, 335 | "name" : "setFFTMode", 336 | "size" : 1 337 | }, 338 | { 339 | "alias" : "setReferenceLevel", 340 | "dtype" : "unspecified", 341 | "isSigSlot" : true, 342 | "name" : "setReferenceLevel", 343 | "size" : 1 344 | }, 345 | { 346 | "alias" : "setDynamicRange", 347 | "dtype" : "unspecified", 348 | "isSigSlot" : true, 349 | "name" : "setDynamicRange", 350 | "size" : 1 351 | }, 352 | { 353 | "alias" : "setAutoScale", 354 | "dtype" : "unspecified", 355 | "isSigSlot" : true, 356 | "name" : "setAutoScale", 357 | "size" : 1 358 | }, 359 | { 360 | "alias" : "setAverageFactor", 361 | "dtype" : "unspecified", 362 | "isSigSlot" : true, 363 | "name" : "setAverageFactor", 364 | "size" : 1 365 | }, 366 | { 367 | "alias" : "enableXAxis", 368 | "dtype" : "unspecified", 369 | "isSigSlot" : true, 370 | "name" : "enableXAxis", 371 | "size" : 1 372 | }, 373 | { 374 | "alias" : "enableYAxis", 375 | "dtype" : "unspecified", 376 | "isSigSlot" : true, 377 | "name" : "enableYAxis", 378 | "size" : 1 379 | }, 380 | { 381 | "alias" : "setYAxisTitle", 382 | "dtype" : "unspecified", 383 | "isSigSlot" : true, 384 | "name" : "setYAxisTitle", 385 | "size" : 1 386 | }, 387 | { 388 | "alias" : "setEventRate", 389 | "dtype" : "unspecified", 390 | "isSigSlot" : true, 391 | "name" : "setDisplayRate", 392 | "size" : 1 393 | }, 394 | { 395 | "alias" : "0", 396 | "dtype" : "unspecified", 397 | "isSigSlot" : false, 398 | "name" : "0", 399 | "size" : 1 400 | } 401 | ], 402 | "outputDesc" : [ 403 | { 404 | "alias" : "frequencySelected", 405 | "dtype" : "unspecified", 406 | "isSigSlot" : true, 407 | "name" : "frequencySelected", 408 | "size" : 1 409 | } 410 | ], 411 | "path" : "\/plotters\/periodogram", 412 | "positionX" : 857, 413 | "positionY" : 144, 414 | "properties" : [ 415 | { 416 | "key" : "title", 417 | "value" : "\"Power vs Frequency\"" 418 | }, 419 | { 420 | "key" : "numInputs", 421 | "value" : "1" 422 | }, 423 | { 424 | "key" : "displayRate", 425 | "value" : "10.0" 426 | }, 427 | { 428 | "key" : "sampleRate", 429 | "value" : "1e6" 430 | }, 431 | { 432 | "key" : "centerFreq", 433 | "value" : "0.0" 434 | }, 435 | { 436 | "key" : "numBins", 437 | "value" : "1024" 438 | }, 439 | { 440 | "key" : "window", 441 | "value" : "\"hann\"" 442 | }, 443 | { 444 | "key" : "windowArgs", 445 | "value" : "[]" 446 | }, 447 | { 448 | "key" : "fullScale", 449 | "value" : "1.0" 450 | }, 451 | { 452 | "key" : "fftMode", 453 | "value" : "\"AUTO\"" 454 | }, 455 | { 456 | "key" : "autoScale", 457 | "value" : "false" 458 | }, 459 | { 460 | "key" : "refLevel", 461 | "value" : "0.0" 462 | }, 463 | { 464 | "key" : "dynRange", 465 | "value" : "100.0" 466 | }, 467 | { 468 | "key" : "averaging", 469 | "value" : "0.0" 470 | }, 471 | { 472 | "key" : "enableXAxis", 473 | "value" : "true" 474 | }, 475 | { 476 | "key" : "enableYAxis", 477 | "value" : "true" 478 | }, 479 | { 480 | "key" : "yAxisTitle", 481 | "value" : "\"dB\"" 482 | }, 483 | { 484 | "key" : "freqLabelId", 485 | "value" : "\"rxFreq\"" 486 | }, 487 | { 488 | "key" : "rateLabelId", 489 | "value" : "\"rxRate\"" 490 | }, 491 | { 492 | "key" : "startLabelId", 493 | "value" : "\"\"" 494 | } 495 | ], 496 | "rotation" : 0, 497 | "selected" : false, 498 | "what" : "Block", 499 | "zValue" : 27 500 | }, 501 | { 502 | "enabled" : true, 503 | "id" : "Connection_SimpleFloatAdder00_Pacer00", 504 | "inputId" : "Pacer0", 505 | "inputKey" : "0", 506 | "outputId" : "SimpleFloatAdder0", 507 | "outputKey" : "0", 508 | "positionX" : 0, 509 | "positionY" : 0, 510 | "rotation" : 0, 511 | "selected" : false, 512 | "what" : "Connection", 513 | "zValue" : 0 514 | }, 515 | { 516 | "enabled" : true, 517 | "id" : "Connection_WaveformSource00_SimpleFloatAdder00", 518 | "inputId" : "SimpleFloatAdder0", 519 | "inputKey" : "0", 520 | "outputId" : "WaveformSource0", 521 | "outputKey" : "0", 522 | "positionX" : 0, 523 | "positionY" : 0, 524 | "rotation" : 0, 525 | "selected" : false, 526 | "what" : "Connection", 527 | "zValue" : 0 528 | }, 529 | { 530 | "enabled" : true, 531 | "id" : "Connection_NoiseSource00_SimpleFloatAdder01", 532 | "inputId" : "SimpleFloatAdder0", 533 | "inputKey" : "1", 534 | "outputId" : "NoiseSource0", 535 | "outputKey" : "0", 536 | "positionX" : 0, 537 | "positionY" : 0, 538 | "rotation" : 0, 539 | "selected" : false, 540 | "what" : "Connection", 541 | "zValue" : 0 542 | }, 543 | { 544 | "enabled" : true, 545 | "id" : "Connection_Pacer00_Periodogram00", 546 | "inputId" : "Periodogram0", 547 | "inputKey" : "0", 548 | "outputId" : "Pacer0", 549 | "outputKey" : "0", 550 | "positionX" : 0, 551 | "positionY" : 0, 552 | "rotation" : 0, 553 | "selected" : false, 554 | "what" : "Connection", 555 | "zValue" : 0 556 | }, 557 | { 558 | "blockId" : "Periodogram0", 559 | "enabled" : true, 560 | "height" : 285, 561 | "id" : "WidgetPeriodogram0", 562 | "positionX" : 397, 563 | "positionY" : 307, 564 | "rotation" : 0, 565 | "selected" : false, 566 | "state" : "AAAACAAAAAADAAAADgB2AGkAcwBpAGIAbABlAAAADQAAAAAEAwAAAAoAcwB0AGEAYwBrAAAACQAAAAABAAAAFAAAAAAAAAAAAMBZAAAAAAAAQH9AAAAAAABAWQAAAAAAAAAAAAoAaQBuAGQAZQB4AAAAAwAAAAAA", 567 | "what" : "Widget", 568 | "width" : 543, 569 | "zValue" : 23 570 | } 571 | ], 572 | "pageName" : "Ma&in", 573 | "selected" : true 574 | } 575 | ] 576 | } -------------------------------------------------------------------------------- /jit_python_block/README.md: -------------------------------------------------------------------------------- 1 | # Python JIT block demo 2 | 3 | This directory demonstrates how to install a Python block 4 | without compiling any loadable wrapper code. 5 | Prior to this feature, making a block in Python 6 | required a CMake project and some minor compiling + installing. 7 | This project is composed of: 8 | 9 | * SimpleAdder.py - A simple Python adder with block description markup for the GUI 10 | * SimpleAdder.conf - a config file to describe the python modules and factory paths 11 | 12 | ## Installing 13 | 14 | Pothos will automatically take care of extracting the block descriptions 15 | and dynamically creating factories that call into python. 16 | These factories import the python module and instantiate the block. 17 | We only need to make Pothos aware of this compilation unit with configuration file. 18 | To do this we either need to copy this directory to a known location 19 | or to symlink this directory to a well known location. 20 | 21 | ## Option 1: symlink 22 | 23 | Symlink this directory into the user's home directory. 24 | Use this option when the source is being developed and maintained 25 | in a source code repository. Pothos will automatically rebuild 26 | on plugin reload if the local source in the repository is changed. 27 | 28 | ``` 29 | cd pothos-demos/jit_python_block 30 | mkdir -p ${HOME}/.config/Pothos/modules/examples 31 | ln -sf $(pwd) ${HOME}/.config/Pothos/modules/examples/simple_python_adder 32 | ``` 33 | 34 | ## Option 2: copy 35 | 36 | Copy this directory into system install prefix. 37 | Use this option when installing processing IP permanently, 38 | like from a larger build system or package manager. 39 | 40 | ``` 41 | cd pothos-demos/jit_python_block 42 | mkdir -p /usr/local/share/Pothos/modules/examples 43 | cp -r . /usr/local/share/Pothos/modules/examples/simple_python_adder 44 | ``` 45 | 46 | ## Running 47 | 48 | An demonstration topology ``topology_python_adder.pothos`` is included 49 | along with the python adder block. Simply open this topology 50 | in the Pothos GUI and the block will be automatically available. 51 | -------------------------------------------------------------------------------- /jit_python_block/SimpleAdder.conf: -------------------------------------------------------------------------------- 1 | # engage the Python loader support 2 | loader = python 3 | 4 | # A list of block factories paired with the Python module. 5 | # Each factory should be of the format: /block/path:Module.Function 6 | # 7 | # The Module will be imported as if python was run from this directory. 8 | # This supports regular .py files and __init__.py style directories. 9 | # 10 | # The Function is the name of a factory function or Pothos.Block class 11 | # in the specified module. 12 | factories = \ 13 | /examples/simple_python_adder:SimpleAdder.Adder 14 | 15 | # A list of sources to search for block descriptions 16 | # When not specified, all *.py sources in this directory are searched 17 | #doc_sources = SimpleAdder.py 18 | 19 | # A list of additional module search paths for sys.path 20 | # By default the directory for this conf file is searched. 21 | #path = /usr/local/lib/python2.7/dist-packages/ 22 | -------------------------------------------------------------------------------- /jit_python_block/SimpleAdder.py: -------------------------------------------------------------------------------- 1 | import Pothos 2 | 3 | """/* 4 | |PothosDoc Simple Python Adder 5 | 6 | Add two input streams, produce an output stream. 7 | 8 | |category /Math 9 | 10 | |param dtype[Data Type] The input and output data type. 11 | |default "float32" 12 | |widget DTypeChooser(float=1,cfloat=1,int=1,cint=1,dim=1) 13 | |preview disable 14 | 15 | |factory /examples/simple_python_adder(dtype) 16 | */""" 17 | class Adder(Pothos.Block): 18 | def __init__(self, dtype): 19 | Pothos.Block.__init__(self) 20 | self.setupInput(0, dtype) 21 | self.setupInput(1, dtype) 22 | self.setupOutput(0, dtype) 23 | 24 | def work(self): 25 | #how many elements to process? 26 | n = self.workInfo().minElements 27 | 28 | #grab the input and output ports 29 | inPort0 = self.input(0) 30 | inPort1 = self.input(1) 31 | outPort = self.output(0) 32 | 33 | #grab the input and output buffers 34 | in0 = inPort0.buffer() 35 | in1 = inPort1.buffer() 36 | out = outPort.buffer() 37 | 38 | #perform arithmetic 39 | out[:n] = in0[:n] + in1[:n] 40 | 41 | #produce and consume elements 42 | inPort0.consume(n) 43 | inPort1.consume(n) 44 | outPort.produce(n) 45 | -------------------------------------------------------------------------------- /jit_python_block/topology_python_adder.pothos: -------------------------------------------------------------------------------- 1 | { 2 | "globals" : [ 3 | 4 | ], 5 | "pages" : [ 6 | { 7 | "graphObjects" : [ 8 | { 9 | "enabled" : true, 10 | "id" : "Connection_NoiseSource00_SimplePythonAdder01", 11 | "inputId" : "SimplePythonAdder0", 12 | "inputKey" : "1", 13 | "outputId" : "NoiseSource0", 14 | "outputKey" : "0", 15 | "positionX" : 0, 16 | "positionY" : 0, 17 | "rotation" : 0, 18 | "selected" : false, 19 | "what" : "Connection", 20 | "zValue" : 0 21 | }, 22 | { 23 | "enabled" : true, 24 | "id" : "Connection_SimplePythonAdder00_Pacer00", 25 | "inputId" : "Pacer0", 26 | "inputKey" : "0", 27 | "outputId" : "SimplePythonAdder0", 28 | "outputKey" : "0", 29 | "positionX" : 0, 30 | "positionY" : 0, 31 | "rotation" : 0, 32 | "selected" : false, 33 | "what" : "Connection", 34 | "zValue" : 0 35 | }, 36 | { 37 | "affinityZone" : "", 38 | "enabled" : true, 39 | "id" : "NoiseSource0", 40 | "inputDesc" : [ 41 | { 42 | "alias" : "setWaveform", 43 | "dtype" : "unspecified", 44 | "isSigSlot" : true, 45 | "name" : "setWaveform", 46 | "size" : 1 47 | }, 48 | { 49 | "alias" : "setOffset", 50 | "dtype" : "unspecified", 51 | "isSigSlot" : true, 52 | "name" : "setOffset", 53 | "size" : 1 54 | }, 55 | { 56 | "alias" : "setAmplitude", 57 | "dtype" : "unspecified", 58 | "isSigSlot" : true, 59 | "name" : "setAmplitude", 60 | "size" : 1 61 | }, 62 | { 63 | "alias" : "setMean", 64 | "dtype" : "unspecified", 65 | "isSigSlot" : true, 66 | "name" : "setMean", 67 | "size" : 1 68 | }, 69 | { 70 | "alias" : "setB", 71 | "dtype" : "unspecified", 72 | "isSigSlot" : true, 73 | "name" : "setB", 74 | "size" : 1 75 | } 76 | ], 77 | "outputDesc" : [ 78 | { 79 | "alias" : "0", 80 | "dtype" : "float32", 81 | "isSigSlot" : false, 82 | "name" : "0", 83 | "size" : 4 84 | } 85 | ], 86 | "path" : "\/comms\/noise_source", 87 | "positionX" : 148, 88 | "positionY" : 251, 89 | "properties" : [ 90 | { 91 | "key" : "dtype", 92 | "value" : "\"float32\"" 93 | }, 94 | { 95 | "key" : "wave", 96 | "value" : "\"NORMAL\"" 97 | }, 98 | { 99 | "key" : "ampl", 100 | "value" : "0.01" 101 | }, 102 | { 103 | "key" : "offset", 104 | "value" : "0.0" 105 | }, 106 | { 107 | "key" : "mean", 108 | "value" : "0.0" 109 | }, 110 | { 111 | "key" : "b", 112 | "value" : "1.0" 113 | } 114 | ], 115 | "rotation" : 0, 116 | "selected" : false, 117 | "what" : "Block", 118 | "zValue" : 33 119 | }, 120 | { 121 | "affinityZone" : "", 122 | "enabled" : true, 123 | "id" : "WaveformSource0", 124 | "inputDesc" : [ 125 | { 126 | "alias" : "setWaveform", 127 | "dtype" : "unspecified", 128 | "isSigSlot" : true, 129 | "name" : "setWaveform", 130 | "size" : 1 131 | }, 132 | { 133 | "alias" : "setOffset", 134 | "dtype" : "unspecified", 135 | "isSigSlot" : true, 136 | "name" : "setOffset", 137 | "size" : 1 138 | }, 139 | { 140 | "alias" : "setAmplitude", 141 | "dtype" : "unspecified", 142 | "isSigSlot" : true, 143 | "name" : "setAmplitude", 144 | "size" : 1 145 | }, 146 | { 147 | "alias" : "setFrequency", 148 | "dtype" : "unspecified", 149 | "isSigSlot" : true, 150 | "name" : "setFrequency", 151 | "size" : 1 152 | }, 153 | { 154 | "alias" : "setSampleRate", 155 | "dtype" : "unspecified", 156 | "isSigSlot" : true, 157 | "name" : "setSampleRate", 158 | "size" : 1 159 | }, 160 | { 161 | "alias" : "setResolution", 162 | "dtype" : "unspecified", 163 | "isSigSlot" : true, 164 | "name" : "setResolution", 165 | "size" : 1 166 | } 167 | ], 168 | "outputDesc" : [ 169 | { 170 | "alias" : "0", 171 | "dtype" : "float32", 172 | "isSigSlot" : false, 173 | "name" : "0", 174 | "size" : 4 175 | } 176 | ], 177 | "path" : "\/comms\/waveform_source", 178 | "positionX" : 145, 179 | "positionY" : 109, 180 | "properties" : [ 181 | { 182 | "key" : "dtype", 183 | "value" : "\"float32\"" 184 | }, 185 | { 186 | "key" : "wave", 187 | "value" : "\"SINE\"" 188 | }, 189 | { 190 | "key" : "rate", 191 | "value" : "1e6" 192 | }, 193 | { 194 | "key" : "freq", 195 | "value" : "1.1e5" 196 | }, 197 | { 198 | "key" : "ampl", 199 | "value" : "1.0" 200 | }, 201 | { 202 | "key" : "offset", 203 | "value" : "0.0" 204 | }, 205 | { 206 | "key" : "res", 207 | "value" : "0.0" 208 | } 209 | ], 210 | "rotation" : 0, 211 | "selected" : false, 212 | "what" : "Block", 213 | "zValue" : 32 214 | }, 215 | { 216 | "affinityZone" : "", 217 | "enabled" : true, 218 | "id" : "Pacer0", 219 | "inputDesc" : [ 220 | { 221 | "alias" : "0", 222 | "dtype" : "unspecified", 223 | "isSigSlot" : false, 224 | "name" : "0", 225 | "size" : 1 226 | }, 227 | { 228 | "alias" : "setRate", 229 | "dtype" : "unspecified", 230 | "isSigSlot" : true, 231 | "name" : "setRate", 232 | "size" : 1 233 | }, 234 | { 235 | "alias" : "actualRateTriggered", 236 | "dtype" : "unspecified", 237 | "isSigSlot" : true, 238 | "name" : "actualRateTriggered", 239 | "size" : 1 240 | } 241 | ], 242 | "outputDesc" : [ 243 | { 244 | "alias" : "0", 245 | "dtype" : "unspecified", 246 | "isSigSlot" : false, 247 | "name" : "0", 248 | "size" : 1 249 | }, 250 | { 251 | "alias" : "probeActualRate", 252 | "dtype" : "unspecified", 253 | "isSigSlot" : true, 254 | "name" : "probeActualRate", 255 | "size" : 1 256 | } 257 | ], 258 | "path" : "\/blocks\/pacer", 259 | "positionX" : 660, 260 | "positionY" : 126, 261 | "properties" : [ 262 | { 263 | "key" : "rate", 264 | "value" : "1e6" 265 | } 266 | ], 267 | "rotation" : 0, 268 | "selected" : false, 269 | "what" : "Block", 270 | "zValue" : 28 271 | }, 272 | { 273 | "affinityZone" : "", 274 | "enabled" : true, 275 | "id" : "Periodogram0", 276 | "inputDesc" : [ 277 | { 278 | "alias" : "setTitle", 279 | "dtype" : "unspecified", 280 | "isSigSlot" : true, 281 | "name" : "setTitle", 282 | "size" : 1 283 | }, 284 | { 285 | "alias" : "setSampleRate", 286 | "dtype" : "unspecified", 287 | "isSigSlot" : true, 288 | "name" : "setSampleRate", 289 | "size" : 1 290 | }, 291 | { 292 | "alias" : "setCenterFrequency", 293 | "dtype" : "unspecified", 294 | "isSigSlot" : true, 295 | "name" : "setCenterFrequency", 296 | "size" : 1 297 | }, 298 | { 299 | "alias" : "setNumPoints", 300 | "dtype" : "unspecified", 301 | "isSigSlot" : true, 302 | "name" : "setNumFFTBins", 303 | "size" : 1 304 | }, 305 | { 306 | "alias" : "setWindowType", 307 | "dtype" : "unspecified", 308 | "isSigSlot" : true, 309 | "name" : "setWindowType", 310 | "size" : 1 311 | }, 312 | { 313 | "alias" : "setFullScale", 314 | "dtype" : "unspecified", 315 | "isSigSlot" : true, 316 | "name" : "setFullScale", 317 | "size" : 1 318 | }, 319 | { 320 | "alias" : "setFFTMode", 321 | "dtype" : "unspecified", 322 | "isSigSlot" : true, 323 | "name" : "setFFTMode", 324 | "size" : 1 325 | }, 326 | { 327 | "alias" : "setReferenceLevel", 328 | "dtype" : "unspecified", 329 | "isSigSlot" : true, 330 | "name" : "setReferenceLevel", 331 | "size" : 1 332 | }, 333 | { 334 | "alias" : "setDynamicRange", 335 | "dtype" : "unspecified", 336 | "isSigSlot" : true, 337 | "name" : "setDynamicRange", 338 | "size" : 1 339 | }, 340 | { 341 | "alias" : "setAutoScale", 342 | "dtype" : "unspecified", 343 | "isSigSlot" : true, 344 | "name" : "setAutoScale", 345 | "size" : 1 346 | }, 347 | { 348 | "alias" : "setAverageFactor", 349 | "dtype" : "unspecified", 350 | "isSigSlot" : true, 351 | "name" : "setAverageFactor", 352 | "size" : 1 353 | }, 354 | { 355 | "alias" : "enableXAxis", 356 | "dtype" : "unspecified", 357 | "isSigSlot" : true, 358 | "name" : "enableXAxis", 359 | "size" : 1 360 | }, 361 | { 362 | "alias" : "enableYAxis", 363 | "dtype" : "unspecified", 364 | "isSigSlot" : true, 365 | "name" : "enableYAxis", 366 | "size" : 1 367 | }, 368 | { 369 | "alias" : "setYAxisTitle", 370 | "dtype" : "unspecified", 371 | "isSigSlot" : true, 372 | "name" : "setYAxisTitle", 373 | "size" : 1 374 | }, 375 | { 376 | "alias" : "setEventRate", 377 | "dtype" : "unspecified", 378 | "isSigSlot" : true, 379 | "name" : "setDisplayRate", 380 | "size" : 1 381 | }, 382 | { 383 | "alias" : "0", 384 | "dtype" : "unspecified", 385 | "isSigSlot" : false, 386 | "name" : "0", 387 | "size" : 1 388 | } 389 | ], 390 | "outputDesc" : [ 391 | { 392 | "alias" : "frequencySelected", 393 | "dtype" : "unspecified", 394 | "isSigSlot" : true, 395 | "name" : "frequencySelected", 396 | "size" : 1 397 | } 398 | ], 399 | "path" : "\/plotters\/periodogram", 400 | "positionX" : 857, 401 | "positionY" : 144, 402 | "properties" : [ 403 | { 404 | "key" : "title", 405 | "value" : "\"Power vs Frequency\"" 406 | }, 407 | { 408 | "key" : "numInputs", 409 | "value" : "1" 410 | }, 411 | { 412 | "key" : "displayRate", 413 | "value" : "10.0" 414 | }, 415 | { 416 | "key" : "sampleRate", 417 | "value" : "1e6" 418 | }, 419 | { 420 | "key" : "centerFreq", 421 | "value" : "0.0" 422 | }, 423 | { 424 | "key" : "numBins", 425 | "value" : "1024" 426 | }, 427 | { 428 | "key" : "window", 429 | "value" : "\"hann\"" 430 | }, 431 | { 432 | "key" : "windowArgs", 433 | "value" : "[]" 434 | }, 435 | { 436 | "key" : "fullScale", 437 | "value" : "1.0" 438 | }, 439 | { 440 | "key" : "fftMode", 441 | "value" : "\"AUTO\"" 442 | }, 443 | { 444 | "key" : "autoScale", 445 | "value" : "false" 446 | }, 447 | { 448 | "key" : "refLevel", 449 | "value" : "0.0" 450 | }, 451 | { 452 | "key" : "dynRange", 453 | "value" : "100.0" 454 | }, 455 | { 456 | "key" : "averaging", 457 | "value" : "0.0" 458 | }, 459 | { 460 | "key" : "enableXAxis", 461 | "value" : "true" 462 | }, 463 | { 464 | "key" : "enableYAxis", 465 | "value" : "true" 466 | }, 467 | { 468 | "key" : "yAxisTitle", 469 | "value" : "\"dB\"" 470 | }, 471 | { 472 | "key" : "freqLabelId", 473 | "value" : "\"rxFreq\"" 474 | }, 475 | { 476 | "key" : "rateLabelId", 477 | "value" : "\"rxRate\"" 478 | }, 479 | { 480 | "key" : "startLabelId", 481 | "value" : "\"\"" 482 | } 483 | ], 484 | "rotation" : 0, 485 | "selected" : false, 486 | "what" : "Block", 487 | "zValue" : 27 488 | }, 489 | { 490 | "enabled" : true, 491 | "id" : "Connection_Pacer00_Periodogram00", 492 | "inputId" : "Periodogram0", 493 | "inputKey" : "0", 494 | "outputId" : "Pacer0", 495 | "outputKey" : "0", 496 | "positionX" : 0, 497 | "positionY" : 0, 498 | "rotation" : 0, 499 | "selected" : false, 500 | "what" : "Connection", 501 | "zValue" : 0 502 | }, 503 | { 504 | "blockId" : "Periodogram0", 505 | "enabled" : true, 506 | "height" : 285, 507 | "id" : "WidgetPeriodogram0", 508 | "positionX" : 397, 509 | "positionY" : 307, 510 | "rotation" : 0, 511 | "selected" : false, 512 | "state" : "AAAACAAAAAADAAAADgB2AGkAcwBpAGIAbABlAAAADQAAAAAEAwAAAAoAcwB0AGEAYwBrAAAACQAAAAABAAAAFAAAAAAAAAAAAMBZAAAAAAAAQH9AAAAAAABAWQAAAAAAAAAAAAoAaQBuAGQAZQB4AAAAAwAAAAAA", 513 | "what" : "Widget", 514 | "width" : 543, 515 | "zValue" : 23 516 | }, 517 | { 518 | "enabled" : true, 519 | "id" : "Connection_WaveformSource00_SimplePythonAdder00", 520 | "inputId" : "SimplePythonAdder0", 521 | "inputKey" : "0", 522 | "outputId" : "WaveformSource0", 523 | "outputKey" : "0", 524 | "positionX" : 0, 525 | "positionY" : 0, 526 | "rotation" : 0, 527 | "selected" : false, 528 | "what" : "Connection", 529 | "zValue" : 0 530 | }, 531 | { 532 | "affinityZone" : "", 533 | "enabled" : true, 534 | "id" : "SimplePythonAdder0", 535 | "inputDesc" : [ 536 | { 537 | "alias" : "0", 538 | "dtype" : "float32", 539 | "isSigSlot" : false, 540 | "name" : "0", 541 | "size" : 4 542 | }, 543 | { 544 | "alias" : "1", 545 | "dtype" : "float32", 546 | "isSigSlot" : false, 547 | "name" : "1", 548 | "size" : 4 549 | } 550 | ], 551 | "outputDesc" : [ 552 | { 553 | "alias" : "0", 554 | "dtype" : "float32", 555 | "isSigSlot" : false, 556 | "name" : "0", 557 | "size" : 4 558 | } 559 | ], 560 | "path" : "\/examples\/simple_python_adder", 561 | "positionX" : 382, 562 | "positionY" : 148, 563 | "properties" : [ 564 | { 565 | "key" : "dtype", 566 | "value" : "\"float32\"" 567 | } 568 | ], 569 | "rotation" : 0, 570 | "selected" : false, 571 | "what" : "Block", 572 | "zValue" : 34 573 | } 574 | ], 575 | "pageName" : "Ma&in", 576 | "selected" : true 577 | } 578 | ] 579 | } -------------------------------------------------------------------------------- /simple_fm_demod/README.md: -------------------------------------------------------------------------------- 1 | # Simple FM demod 2 | 3 | This is a simple WBFM demodulation using the Pothos GUI. 4 | 5 | ## Controls 6 | 7 | There are controls for frontend tuning, gain control, and volume control. 8 | The app has live plotters for the RF spectrum and the audio waveform. 9 | 10 | ## Hardware 11 | 12 | This demo application was tested with the RTL SDR USB dongle. 13 | Other devices should work, but may require sample rate and gain fiddling. 14 | --------------------------------------------------------------------------------