diff options
607 files changed, 39399 insertions, 668 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index a33ecc60d..4d0e59e70 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright 2010-2011 Free Software Foundation, Inc. +# Copyright 2010-2012 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -41,8 +41,8 @@ list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules) # Set the version information here set(VERSION_INFO_MAJOR_VERSION 3) set(VERSION_INFO_API_COMPAT 6) -set(VERSION_INFO_MINOR_VERSION 2) -set(VERSION_INFO_MAINT_VERSION 0) +set(VERSION_INFO_MINOR_VERSION 3) +set(VERSION_INFO_MAINT_VERSION git) include(GrVersion) #setup version info # Append -O2 optimization flag for Debug builds @@ -50,6 +50,13 @@ SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O2") SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O2") ######################################################################## +# Environment setup +######################################################################## +IF(NOT DEFINED BOOST_ROOT) + SET(BOOST_ROOT ${CMAKE_INSTALL_PREFIX}) +ENDIF() + +######################################################################## # Import executables from a native build (for cross compiling) # http://www.vtk.org/Wiki/CMake_Cross_Compiling#Using_executables_in_the_build_created_during_the_build ######################################################################## @@ -225,6 +232,8 @@ install( ######################################################################## list(APPEND GR_TEST_TARGET_DEPS volk gruel gnuradio-core) list(APPEND GR_TEST_PYTHON_DIRS + ${CMAKE_SOURCE_DIR}/gruel/src/python + ${CMAKE_BINARY_DIR}/gruel/src/swig ${CMAKE_BINARY_DIR}/gnuradio-core/src/python ${CMAKE_BINARY_DIR}/gnuradio-core/src/lib/swig ) @@ -242,6 +251,7 @@ add_subdirectory(gr-filter) add_subdirectory(gr-atsc) add_subdirectory(gr-audio) add_subdirectory(gr-comedi) +add_subdirectory(gr-analog) add_subdirectory(gr-digital) add_subdirectory(gr-noaa) add_subdirectory(gr-pager) @@ -255,6 +265,7 @@ add_subdirectory(gr-vocoder) add_subdirectory(gr-fcd) add_subdirectory(gr-wavelet) add_subdirectory(gr-wxgui) +add_subdirectory(gr-blocks) #finalize cpack after subdirs processed include(GrPackage) diff --git a/cmake/Modules/GrMiscUtils.cmake b/cmake/Modules/GrMiscUtils.cmake index a73e3e6d7..3e80846d6 100644 --- a/cmake/Modules/GrMiscUtils.cmake +++ b/cmake/Modules/GrMiscUtils.cmake @@ -208,3 +208,70 @@ function(GR_GEN_TARGET_DEPS name var) set(${var} "DEPENDS;${name};COMMAND;${name}" PARENT_SCOPE) endif() endfunction(GR_GEN_TARGET_DEPS) + + +######################################################################## +# Run GRCC to compile .grc files into .py files. +# +# Usage: GRCC(filename, directory) +# - filenames: List of file name of .grc file +# - directory: directory of built .py file - usually in +# ${CMAKE_CURRENT_BINARY_DIR} +# - Sets PYFILES: output converted GRC file names to Python files. +######################################################################## +function(GRCC) + # Extract directory from list of args, remove it for the list of filenames. + list(GET ARGV -1 directory) + list(REMOVE_AT ARGV -1) + set(filenames ${ARGV}) + file(MAKE_DIRECTORY ${directory}) + + SET(GRCC_COMMAND ${CMAKE_SOURCE_DIR}/gr-utils/src/python/grcc) + + # GRCC uses some stuff in grc and gnuradio-core, so we force + # the known paths here + list(APPEND PYTHONPATHS + ${CMAKE_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/gnuradio-core/src/python + ${CMAKE_SOURCE_DIR}/gnuradio-core/src/lib/swig + ${CMAKE_BINARY_DIR}/gnuradio-core/src/lib/swig + ) + + if(WIN32) + #SWIG generates the python library files into a subdirectory. + #Therefore, we must append this subdirectory into PYTHONPATH. + #Only do this for the python directories matching the following: + foreach(pydir ${PYTHONPATHS}) + get_filename_component(name ${pydir} NAME) + if(name MATCHES "^(swig|lib|src)$") + list(APPEND PYTHONPATHS ${pydir}/${CMAKE_BUILD_TYPE}) + endif() + endforeach(pydir) + endif(WIN32) + + file(TO_NATIVE_PATH "${PYTHONPATHS}" pypath) + + if(UNIX) + list(APPEND pypath "$PYTHONPATH") + string(REPLACE ";" ":" pypath "${pypath}") + set(ENV{PYTHONPATH} ${pypath}) + endif(UNIX) + + if(WIN32) + list(APPEND pypath "%PYTHONPATH%") + string(REPLACE ";" "\\;" pypath "${pypath}") + #list(APPEND environs "PYTHONPATH=${pypath}") + set(ENV{PYTHONPATH} ${pypath}) + endif(WIN32) + + foreach(f ${filenames}) + execute_process( + COMMAND ${GRCC_COMMAND} -d ${directory} ${f} + ) + string(REPLACE ".grc" ".py" pyfile "${f}") + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_BINARY_DIR}" pyfile "${pyfile}") + list(APPEND pyfiles ${pyfile}) + endforeach(f) + + set(PYFILES ${pyfiles} PARENT_SCOPE) +endfunction(GRCC) diff --git a/cmake/Modules/GrPython.cmake b/cmake/Modules/GrPython.cmake index 14f2b29cd..791114e05 100644 --- a/cmake/Modules/GrPython.cmake +++ b/cmake/Modules/GrPython.cmake @@ -96,11 +96,13 @@ endmacro(GR_PYTHON_CHECK_MODULE) ######################################################################## # Sets the python installation directory GR_PYTHON_DIR ######################################################################## +if(NOT DEFINED GR_PYTHON_DIR) execute_process(COMMAND ${PYTHON_EXECUTABLE} -c " from distutils import sysconfig print sysconfig.get_python_lib(plat_specific=True, prefix='') " OUTPUT_VARIABLE GR_PYTHON_DIR OUTPUT_STRIP_TRAILING_WHITESPACE ) +endif() file(TO_CMAKE_PATH ${GR_PYTHON_DIR} GR_PYTHON_DIR) ######################################################################## diff --git a/docs/doxygen/Doxyfile.in b/docs/doxygen/Doxyfile.in index ad3c2d01f..78a7a5d16 100644 --- a/docs/doxygen/Doxyfile.in +++ b/docs/doxygen/Doxyfile.in @@ -455,12 +455,6 @@ MAX_INITIALIZER_LINES = 30 SHOW_USED_FILES = YES -# If the sources in your project are distributed over multiple directories -# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy -# in the documentation. The default is NO. - -SHOW_DIRECTORIES = NO - # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. @@ -862,12 +856,6 @@ HTML_FOOTER = HTML_STYLESHEET = -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to -# NO a bullet list will be used. - -HTML_ALIGN_MEMBERS = YES - # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. For this to work a browser that supports diff --git a/docs/doxygen/Doxyfile.swig_doc.in b/docs/doxygen/Doxyfile.swig_doc.in index 94e14bda1..8f6182ca8 100644 --- a/docs/doxygen/Doxyfile.swig_doc.in +++ b/docs/doxygen/Doxyfile.swig_doc.in @@ -470,12 +470,6 @@ MAX_INITIALIZER_LINES = 30 SHOW_USED_FILES = YES -# If the sources in your project are distributed over multiple directories -# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy -# in the documentation. The default is NO. - -SHOW_DIRECTORIES = NO - # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. @@ -796,12 +790,6 @@ HTML_FOOTER = HTML_STYLESHEET = -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to -# NO a bullet list will be used. - -HTML_ALIGN_MEMBERS = YES - # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. For this to work a browser that supports @@ -950,11 +938,6 @@ ENUM_VALUES_PER_LINE = 4 GENERATE_TREEVIEW = NO -# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, -# and Class Hierarchy pages using a tree view instead of an ordered list. - -USE_INLINE_TREES = NO - # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. diff --git a/docs/doxygen/doxyxml/example/Doxyfile b/docs/doxygen/doxyxml/example/Doxyfile index 9780043be..dd2e5c77e 100644 --- a/docs/doxygen/doxyxml/example/Doxyfile +++ b/docs/doxygen/doxyxml/example/Doxyfile @@ -476,12 +476,6 @@ MAX_INITIALIZER_LINES = 30 SHOW_USED_FILES = YES -# If the sources in your project are distributed over multiple directories -# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy -# in the documentation. The default is NO. - -SHOW_DIRECTORIES = NO - # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. @@ -808,12 +802,6 @@ HTML_STYLESHEET = HTML_TIMESTAMP = YES -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to -# NO a bullet list will be used. - -HTML_ALIGN_MEMBERS = YES - # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. For this to work a browser that supports @@ -978,11 +966,6 @@ ENUM_VALUES_PER_LINE = 4 GENERATE_TREEVIEW = NO -# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, -# and Class Hierarchy pages using a tree view instead of an ordered list. - -USE_INLINE_TREES = NO - # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. diff --git a/docs/doxygen/other/group_defs.dox b/docs/doxygen/other/group_defs.dox index 213486b7a..4aee49ec8 100644 --- a/docs/doxygen/other/group_defs.dox +++ b/docs/doxygen/other/group_defs.dox @@ -28,6 +28,7 @@ /*! \defgroup slicedice_blk Slicing and Dicing Streams */ /*! \defgroup vocoder_blk Voice Encoders and Decoders */ /*! \defgroup digital Digital Modulation Blocks */ +/*! \defgroup analog Analog Communications Blocks */ /*! \defgroup qtgui_blk QT Graphical Interfaces */ /*! \defgroup uhd_blk UHD Interface */ /*! \defgroup audio_blk Audio Interface */ diff --git a/docs/doxygen/other/main_page.dox b/docs/doxygen/other/main_page.dox index 8f69a9737..abdc21b0c 100644 --- a/docs/doxygen/other/main_page.dox +++ b/docs/doxygen/other/main_page.dox @@ -37,8 +37,288 @@ More details on packages in GNU Radio: \li \ref page_qtgui \li \ref page_uhd \li \ref page_vocoder + +More details on GNU Radio concepts: +\li \ref page_pmt +\li \ref page_msg_passing +\li \ref page_metadata +\li \ref volk_guide \li \ref page_pfb + +\section flowgraph Operating a Flowgraph + +The basic data structure in GNU Radio is the flowgraph, which +represents the connections of the blocks through which a continuous +stream of samples flows. The concept of a flowgraph is an acyclic +directional graph with one or more source blocks (to insert samples +into the flowgraph), one or more sink blocks (to terminate or export +samples from the flowgraph), and any signal processing blocks in +between. + +A program must at least create a GNU Radio 'top_block', which +represents the top-most structure of the flowgraph. The top blocks +provide the overall control and hold methods such as 'start,' 'stop,' +and 'wait.' + +The general construction of a GNU Radio application is to create a +gr_top_block, instantiate the blocks, connect the blocks together, and +then start the gr_top_block. The following program shows how this is +done. A single source and sink are used with a FIR filter between +them. + +\code + from gnuradio import gr, filter + + class my_topblock(gr.top_block): + def __init__(self): + gr.top_block.__init__(self) + + amp = 1 + taps = filter.firdes.low_pass(1, 1, 0.1, 0.01) + + self.src = gr.noise_source_c(gr.GR_GAUSSIAN, amp) + self.flt = filter.fir_filter_ccf(1, taps) + self.snk = gr.null_sink(gr.sizeof_gr_complex) + + self.connect(self.src, self.flt, self.snk) + + if __name__ == "__main__": + tb = my_topblock() + tb.start() + tb.wait() +\endcode + +The 'tb.start()' starts the data flowing through the flowgraph while +the 'tb.wait()' is the equivalent of a thread's 'join' operation and +blocks until the gr_top_block is done. + +An alternative to using the 'start' and 'wait' methods, a 'run' method is +also provided for convenience that is a blocking start call; +equivalent to the above 'start' followed by a 'wait.' + + +\subsection latency Latency and Throughput + +By default, GNU Radio runs a scheduler that attempts to optimize +throughput. Using a dynamic scheduler, blocks in a flowgraph pass +chunks of items from sources to sinks. The sizes of these chunks will +vary depending on the speed of processing. For each block, the number +of items is can process is dependent on how much space it has in its +output buffer(s) and how many items are available on the input +buffer(s). + +The consequence of this is that often a block may be called with a very +large number of items to process (several thousand). In terms of +speed, this is efficient since now the majority of the processing time +is taken up with processing samples. Smaller chunks mean more calls +into the scheduler to retrieve more data. The downside to this is that +it can lead to large latency while a block is processing a large chunk +of data. + +To combat this problem, the gr_top_block can be passed a limit on the +number of output items a block will ever receive. A block may get less +than this number, but never more, and so it serves as an upper limit +to the latency any block will exhibit. By limiting the number of items +per call to a block, though, we increase the overhead of the +scheduler, and so reduce the overall efficiency of the application. + +To set the maximum number of output items, we pass a value into the +'start' or 'run' method of the gr_top_block: + +\code + tb.start(1000) + tb.wait() +or + tb.run(1000) +\endcode + +Using this method, we place a global restriction on the size of items +to all blocks. Each block, though, has the ability to overwrite this +with its own limit. Using the 'set_max_noutput_items(m)' method for an +individual block will overwrite the global setting. For example, in +the following code, the global setting is 1000 items max, except for +the FIR filter, which can receive up to 2000 items. + +\code + tb.flt.set_max_noutput_items(2000) + tb.run(1000) +\endcode + +In some situations, you might actually want to restrict the size of +the buffer itself. This can help to prevent a buffer who is blocked +for data from just increasing the amount of items in its buffer, which +will then cause an increased latency for new samples. You can set the +size of an output buffer for each output port for every block. + +WARNING: This is an advanced feature in GNU Radio and should not be +used without a full understanding of this concept as explained below. + +To set the output buffer size of a block, you simply call: + +\code + tb.blk0.set_max_output_buffer(2000) + tb.blk1.set_max_output_buffer(1, 2000) + tb.start() + print tb.blk1.max_output_buffer(0) + print tb.blk1.max_output_buffer(1) +\endcode + +In the above example, all ports of blk0 are set to a buffer size of +2000 in _items_ (not bytes), and blk1 only sets the size for output +port 1, any and all other ports use the default. The third and fourth +lines just print out the buffer sizes for ports 0 and 1 of blk1. This +is done after start() is called because the values are updated based +on what is actually allocated to the block's buffers. + +NOTES: + +1. Buffer length assignment is done once at runtime (i.e., when run() +or start() is called). So to set the max buffer lengths, the +set_max_output_buffer calls must be done before this. + +2. Once the flowgraph is started, the buffer lengths for a block are +set and cannot be dynamically changed, even during a +lock()/unlock(). If you need to change the buffer size, you will have +to delete the block and rebuild it, and therefore must disconnect and +reconnect the blocks. + +3. This can affect throughput. Large buffers are designed to improve +the efficiency and speed of the program at the expense of +latency. Limiting the size of the buffer may decrease performance. + +4. The real buffer size is actually based on a minimum granularity of +the system. Typically, this is a page size, which is typically 4096 +bytes. This means that any buffer size that is specified with this +command will get rounded up to the nearest granularity (e.g., page) +size. When calling max_output_buffer(port) after the flowgraph is +started, you will get how many items were actually allocated in the +buffer, which may be different than what was initially specified. + + +\section reconfigure Reconfiguring Flowgraphs + +It is possible to reconfigure the flowgraph at runtime. The +reconfiguration is meant for changes in the flowgraph structure, not +individual parameter settings of the blocks. For example, changing the +constant in a gr_add_const_cc block can be done while the flowgraph is +running using the 'set_k(k)' method. + +Reconfiguration is done by locking the flowgraph, which stops it from +running and processing data, performing the reconfiguration, and then +restarting the graph by unlocking it. + +The following example code shows a graph that first adds two +gr_noise_source_c blocks and then replaces the gr_add_cc block with a +gr_sub_cc block to then subtract the sources. + +\code +from gnuradio import gr +import time + +class mytb(gr.top_block): + def __init__(self): + gr.top_block.__init__(self) + + self.src0 = gr.noise_source_c(gr.GR_GAUSSIAN, 1) + self.src1 = gr.noise_source_c(gr.GR_GAUSSIAN, 1) + self.add = gr.add_cc() + self.sub = gr.sub_cc() + self.head = gr.head(gr.sizeof_gr_complex, 1000000) + self.snk = gr.file_sink(gr.sizeof_gr_complex, "output.32fc") + + self.connect(self.src0, (self.add,0)) + self.connect(self.src1, (self.add,1)) + self.connect(self.add, self.head) + self.connect(self.head, self.snk) + +def main(): + tb = mytb() + tb.start() + time.sleep(0.01) + + # Stop flowgraph and disconnect the add block + tb.lock() + tb.disconnect(tb.add, tb.head) + tb.disconnect(tb.src0, (tb.add,0)) + tb.disconnect(tb.src1, (tb.add,1)) + + # Connect the sub block and restart + tb.connect(tb.sub, tb.head) + tb.connect(tb.src0, (tb.sub,0)) + tb.connect(tb.src1, (tb.sub,1)) + tb.unlock() + + tb.wait() + +if __name__ == "__main__": + main() +\endcode + +During reconfiguration, the maximum noutput_items value can be changed +either globally using the 'set_max_noutput_items(m)' on the gr_top_block +object or locally using the 'set_max_noutput_items(m)' on any given +block object. + +A block also has a 'unset_max_noutput_items()' method that unsets the +local max noutput_items value so that block reverts back to using the +global value. + +The following example expands the previous example but sets and resets +the max noutput_items both locally and globally. + +\code +from gnuradio import gr +import time + +class mytb(gr.top_block): + def __init__(self): + gr.top_block.__init__(self) + + self.src0 = gr.noise_source_c(gr.GR_GAUSSIAN, 1) + self.src1 = gr.noise_source_c(gr.GR_GAUSSIAN, 1) + self.add = gr.add_cc() + self.sub = gr.sub_cc() + self.head = gr.head(gr.sizeof_gr_complex, 1000000) + self.snk = gr.file_sink(gr.sizeof_gr_complex, "output.32fc") + + self.connect(self.src0, (self.add,0)) + self.connect(self.src1, (self.add,1)) + self.connect(self.add, self.head) + self.connect(self.head, self.snk) + +def main(): + # Start the gr_top_block after setting some max noutput_items. + tb = mytb() + tb.src1.set_max_noutput_items(2000) + tb.start(100) + time.sleep(0.01) + + # Stop flowgraph and disconnect the add block + tb.lock() + + tb.disconnect(tb.add, tb.head) + tb.disconnect(tb.src0, (tb.add,0)) + tb.disconnect(tb.src1, (tb.add,1)) + + # Connect the sub block + tb.connect(tb.sub, tb.head) + tb.connect(tb.src0, (tb.sub,0)) + tb.connect(tb.src1, (tb.sub,1)) + + # Set new max_noutput_items for the gr_top_block + # and unset the local value for src1 + tb.set_max_noutput_items(1000) + tb.src1.unset_max_noutput_items() + tb.unlock() + + tb.wait() + +if __name__ == "__main__": + main() +\endcode + + \section volk_main Using Volk in GNU Radio The \ref volk_guide page provides an overview of how to incorporate @@ -48,4 +328,5 @@ Many blocks have already been converted to use Volk in their calls, so they can also serve as examples. See the gr_complex_to_xxx.h file for examples of various blocks that make use of Volk. + */ diff --git a/docs/doxygen/other/metadata.dox b/docs/doxygen/other/metadata.dox new file mode 100644 index 000000000..f867a06f2 --- /dev/null +++ b/docs/doxygen/other/metadata.dox @@ -0,0 +1,330 @@ +/*! \page page_metadata Metadata Information + +\section Introduction + +Metadata files have extra information in the form of headers that +carry metadata about the samples in the file. Raw, binary files carry +no extra information and must be handled delicately. Any changes in +the system state such as sample rate or if a receiver's frequency are +not conveyed with the data in the file itself. Header of metadata +solve this problem. + +We write metadata files using gr::blocks::file_meta_sink and read metadata +files using gr::blocks::file_meta_source. + +Metadata files have headers that carry information about a segment of +data within the file. The header structure is described in detail in +the next section. A metadata file always starts with a header that +describes the basic structure of the data. It contains information +about the item size, data type, if it's complex, the sample rate of +the segment, the time stamp of the first sample of the segment, and +information regarding the header size and segment size. + +Headers have two main tags associated with them: + +- rx_rate: the sample rate of the stream. +- rx_time: the time stamp of the first item in the segment. + +These tags were inspired by the UHD tag format. + +The header gives enough information to process and handle the +data. One cautionary note, though, is that the data type should never +change within a file. There should be very little need for this, but +more importantly. GNU Radio blocks can only set the data type of their +IO signatures in the constructor, so changes in the data type +afterward will not be recognized. + +We also have an extra header segment that is option. This can be +loaded up at the beginning by the user specifying some extra metadata +that should be transmitted along with the data. It also grows whenever +it sees a stream tag, so the dictionary will contain and key:value +pairs out of tags from the flowgraph. + + +\subsection types Types of Metadata Files + +GNU Radio currently supports two types of metadata files: + +- inline: headers are inline with the data in the same file. +- detached: headers are in a separate header file from the data. + +The inline method is the standard version. When a detached header is +used, the headers are simply inserted back-to-back in the detached +header file. The dat file, then, is the standard raw binary format +with no interruptions in the data. + + +\subsection updating Updating Headers + +While there is always a header that starts a metadata file, they are +updated throughout as well. There are two events that trigger a new +header. We define a segment as the unit of data associated with the +last header. + +The first event that will trigger a new header is when enough samples +have been written for the given segment. This number is defined as the +maximum segment size and is a parameter we pass to the +file_meta_sink. It defaults to 1 million items (items, not +bytes). When that number of items is reached, a new header is +generated and a new segment is started. This makes it easier for us to +manipulate the data later and helps protect against catastrophic data +loss. + +The second event to trigger a new segment is if a new tag is +observed. If the tag is a standard tag in the header, the header value +is updated, the header and current extras are written to file, and the +segment begins again. If a tag from the extras is seen, the value +associated with that tag is updated; and if a new tag is seen, a new +key:value pair are added to the extras dictionary. + +When new tags are seen, we generate a new segment so that we make sure +that all samples in that segment are defined by the header. If the +sample rate changes, we create a new segment where all of the new +samples are at that new rate. Also, in the case of UHD devices, if a +segment loss is observed, it will generate a new timestamp as a tag of +'rx_time'. We create a new file segment that reflects this change to +keep the sample times exact. + + +\subsection implementation Implementation + +Metadata files are created using gr::blocks::file_meta_sink. The +default behavior is to create a single file with inline headers as +metadata. An option can be set to switch to detached header mode. + +Metadata file are read into a flowgraph using +gr::blocks::file_meta_source. This source reads a metadata file, +inline by default with a settable option to use detached headers. The +data from the segments is converted into a standard streaming +output. The 'rx_rate' and 'rx_time' and all key:value pairs in the +extra header are converted into tags and added to the stream tags +interface. + + +\section structure Structure + +The file metadata consists of a static mandatory header and a dynamic +optional extras header. Each header is a separate PMT +dictionary. Headers are created by building a PMT dictionary +(pmt::pmt_make_dict) of key:value pairs, then the dictionary is +serialized into a string to be written to file. The header is always +the same length that is predetermined by the version of the header +(this must be known already). The header will then indicate if there +is an extra data to be extracted as a separate serialized dictionary. + +To work with the PMTs for creating and extracting header information, +we use PMT operators. For example, we create a simplified version of +the header in C++ like this: + +\code + using namespace pmt; + const char METADATA_VERSION = 0x0; + pmt_t header; + header = pmt_make_dict(); + header = pmt_dict_add(header, mp("version"), mp(METADATA_VERSION)); + header = pmt_dict_add(header, mp("rx_rate"), mp(samp_rate)); + std::string hdr_str = pmt_serialize_str(header); +\endcode + +The call to pmt::pmt_dict_add adds a new key:value pair to the +dictionary. Notice that it both takes and returns the 'header' +variable. This is because we are actually creating a new dictionary +with this function, so we just assign it to the same variable. + +The 'mp' functions are convenience functions provided by the PMT +library. They interpret the data type of the value being inserted and +call the correct 'pmt_from_xxx' function. For more direct control over +the data type, see PMT functions in pmt.h, such as +pmt::pmt_from_uint64 or pmt::pmt_from_double. + +We finish this off by using pmt::pmt_serialize_str to convert the PMT +dictionary into a specialized string format that makes it easy to +write to a file. + +The header is always METADATA_HEADER_SIZE bytes long and a metadata +file always starts with a header. So to extract the header from a +file, we need to read in this many bytes from the beginning of the +file and deserialize it. An important note about this is that the +deserialize function must operate on a std::string. The serialized +format of a dictionary contains null characters, so normal C character +arrays (e.g., 'char *s') get confused. + +Assuming that 'std::string str' contains the full string as read from +a file, we can access the dictionary in C++ like this: + +\code + pmt_t hdr = pmt_deserialize_str(str); + if(pmt_dict_has_key(hdr, pmt_string_to_symbol("strt"))) { + pmt_t r = pmt_dict_ref(hdr, pmt_string_to_symbol("strt"), PMT_NIL); + uint64_t seg_start = pmt_to_uint64(r); + uint64_t extra_len = seg_start - METADATA_HEADER_SIZE; + } +\endcode + +This example first deserializes the string into a PMT dictionary +again. This will throw an error if the string is malformed and cannot +be deserialized correctly. We then want to get access to the item with +key 'strt'. As the next subsection will show, this value indicates at +which byte the data segment starts. We first check to make sure that +this key exists in the dictionary. If not, our header does not contain +the correct information and we might want to handle this as an error. + +Assuming the header is properly formatted, we then get the particular +item referenced by the key 'strt'. This is a uint64_t, so we use the +PMT function to extract and convert this value properly. We now know +if we have an extra header in the file by looking at the difference +between 'seg_start' and the static header size, +METADATA_HEADER_SIZE. If the 'extra_len' is greater than 0, we know we +have an extra header that we can process. Moreover, this also tells us +the size of the serialized PMT dictionary in bytes, so we can easily +read this many bytes from the file. We can then deserialize and parse +this header just like the first. + + +\subsection header Header Information + +The header is a PMT dictionary with a known structure. This structure +may change, but we version the headers, so all headers of version X +must be the same length and structure. As of now, we only have version +0 headers, which look like the following: + +- version: (char) version number (usually set to METADATA_VERSION) +- rx_rate: (double) Stream's sample rate +- rx_time: (pmt::pmt_t pair - (uint64_t, double)) Time stamp (format from UHD) +- size: (int) item size in bytes - reflects vector length if any. +- type: (int) data type (enum below) +- cplx: (bool) true if data is complex +- strt: (uint64_t) start of data relative to current header +- bytes: (uint64_t) size of following data segment in bytes + +The data types are indicated by an integer value from the following +enumeration type: + +\code +enum gr_file_types { + GR_FILE_BYTE=0, + GR_FILE_CHAR=0, + GR_FILE_SHORT=1, + GR_FILE_INT, + GR_FILE_LONG, + GR_FILE_LONG_LONG, + GR_FILE_FLOAT, + GR_FILE_DOUBLE, +}; +\endcode + +\subsection extras Extras Information + +The extras section is an optional segment of the header. If 'strt' == +METADATA_HEADER_SIZE, then there is no extras. Otherwise, it is simply +a PMT dictionary of key:value pairs. The extras header can contain +anything and can grow while a program is running. + +We can insert extra data into the header at the beginning if we +wish. All we need to do is use the pmt::pmt_dict_add function to insert +our hand-made metadata. This can be useful to add our own markers and +information. + +The main role of the extras header, though, is as a container to hold +any stream tags. When a stream tag is observed coming in, the tag's +key and value are added to the dictionary. Like a standard dictionary, +any time a key already exists, the value will be updated. If the key +does not exist, a new entry is created and the new key:value pair are +added together. So any new tags that the file metadata sink sees will +add to the dictionary. It is therefore important to always check the +'strt' value of the header to see if the length of the extras +dictionary has changed at all. + +When reading out data from the extras, we do not necessarily know the +data type of the PMT value. The key is always a PMT symbol, but the +value can be any other PMT type. There are PMT functions that allow us +to query the PMT to test if it is a particular type. We also have the +ability to do pmt::pmt_print on any PMT object to print it to +screen. Before converting from a PMT to it's natural data type, it is +necessary to know the data type. + + +\section Utilities + +GNU Radio comes with a couple of utilities to help in debugging and +manipulating metadata files. There is a general parser in Python that +will convert the PMT header and extra header into Python +dictionaries. This utility is: + +- gr-blocks/python/parse_file_metadata.py + +This program is installed into the Python directory under the +'gnuradio' module, so it can be accessed with: + +\code +from gnuradio.blocks import parse_file_metadata +\endcode + +It defines HEADER_LENGTH as the static length of the metadata header +size. It also has dictionaries that can be used to convert from the +file type to a string (ftype_to_string) and one to convert from the +file type to the size of the data type in bytes (ftype_to_size). + +The 'parse_header' takes in a PMT dictionary, parses it, and returns a +Python dictionary. An optional 'VERBOSE' bool can be set to print the +information to standard out. + +The 'parse_extra_dict' is similar in that it converts from a PMT +dictionary to a Python dictionary. The values are kept in their PMT +format since we do not necessarily know the native data type. + +A program called 'gr_read_file_metadata' is installed into the path +and can be used to read out all header information from a metadata +file. This program is just called with the file name as the first +command-line argument. An option '-D' will handle detached header +files where the file of headers is expected to be the file name of the +data with '.hdr' appended to it. + + +\section Examples + +Examples are located in: + +- gr-blocks/examples/metadata + +Currently, there are a few GRC example programs. + +- file_metadata_sink: create a metadata file from UHD samples. +- file_metadata_source: read the metadata file as input to a simple graph. +- file_metadata_vector_sink: create a metadata file from UHD samples. +- file_metadata_vector_source: read the metadata file as input to a simple graph. + +The file sink example can be switched to use a signal source instead +of a UHD source, but no extra tagged data is used in this mode. + +The file source example pushes the data stream to a new raw file while +a tag debugger block prints out any tags observed in the metedata +file. A QT GUI time sink is used to look at the signal as well. + +The versions with 'vector' in the name are similar except they use +vectors of data. + +The following shows a simple way of creating extra metadata for a +metadata file. This example is just showing how we can insert a date +into the metadata to keep track of later. The date in this case is +encoded as a vector of uint16 with [day, month, year]. + +\code + from gruel import pmt + from gnuradio import blocks + + key = pmt.pmt_intern("date") + val = pmt.pmt_init_u16vector(3, [13,12,2012]) + + extras = pmt.pmt_make_dict() + extras = pmt.pmt_dict_add(extras, key, val) + extras_str = pmt.pmt_serialize_str(extras) + self.sink = blocks.file_meta_sink(gr.sizeof_gr_complex, + "/tmp/metadat_file.out", + samp_rate, 1, + blocks.GR_FILE_FLOAT, True, + 1000000, extra_str, False) + +\endcode + +*/ diff --git a/docs/doxygen/other/msg_passing.dox b/docs/doxygen/other/msg_passing.dox new file mode 100644 index 000000000..aea0ac94a --- /dev/null +++ b/docs/doxygen/other/msg_passing.dox @@ -0,0 +1,269 @@ +/*! \page page_msg_passing Message Passing + +\section intro Introduction + +GNU Radio was originally a streaming system with no other mechanism to +pass data between blocks. Streams of data are a model that work well +for samples, bits, etc., but are not really the right mechanism for +control data, metadata, and, often, packet structures (at least at +some point in the processing chain). + +We solved part of this problem a few years ago by introducing the tag +stream. This is a parallel stream to the data streaming. The +difference is that tags are designed to hold metadata and control +information. Tags are specifically associated with a particular sample +in the data stream and flow downstream alongside the data. This model +allows other blocks to identify that an event or action has occurred +or should occur on a particular item. The major limitation is that the +tag stream is really only accessible inside a work function and only +flows in one direction. Its benefit is that it is isosynchronous with +the data. + +We want a more general message passing system for a couple of +reasons. The first is to allow blocks downstream to communicate back +to blocks upstream. The second is to allow an easier way for us to +communicate back and forth between external applications and GNU +Radio. The new message passing interface handles these cases, although +it does so on an asynchronous basis. + +The message passing interface heavily relies on Polymorphic Types +(PMTs) in GNU Radio. For further information about these data +structures, see the page \ref page_pmt. + +\section api Message Passing API + +The message passing interface is designed into the gr_basic_block, +which is the parent class for all blocks in GNU Radio. Each block has +a set of message queues to hold incoming messages and can post +messages to the message queues of other blocks. The blocks also +distinguish between input and output ports. + +A block has to declare its input and output message ports in its +constructor. The message ports are described by a name, which is in +practice a PMT symbol (<em>i.e.</em>, an interned string). The API calls +to register a new port are: + +\code + void message_port_register_in(pmt::pmt_t port_id) + void message_port_register_out(pmt::pmt_t port_id) +\endcode + +The ports are now identifiable by that port name. Other blocks who may +want to post or receive messages on a port must subscribe to it. When +a block has a message to send, they are published on a particular +port. The subscribe and publish API looks like: + +\code + void message_port_pub(pmt::pmt_t port_id, + pmt::pmt_t msg); + void message_port_sub(pmt::pmt_t port_id, + pmt::pmt_t target); + void message_port_unsub(pmt::pmt_t port_id, + pmt::pmt_t target); +\endcode + +Any block that has a subscription to another block's output message +port will receive the message when it is published. Internally, when a +block publishes a message, it simply iterates through all blocks that +have subscribed and uses the gr_basic_block::_post method to send the +message to that block's message queue. + +From the flowgraph level, we have instrumented a gr_hier_block2::msg_connect +method to make it easy to subscribe blocks to other blocks' +messages. The message connection method looks like the following +code. Assume that the block \b src has an output message port named +\a pdus and the block \b dbg has an input port named \a print. + +\code + self.tb.msg_connect(src, "pdus", dbg, "print") +\endcode + +All messages published by the \b src block on port \a pdus will be +received by \b dbg on port \a print. Note here how we are just using +strings to define the ports, not PMT symbols. This is a convenience to +the user to be able to more easily type in the port names (for +reference, you can create a PMT symbol in Python using the +pmt::pmt_intern function as pmt.pmt_intern("string")). + +Users can also query blocks for the names of their input and output +ports using the following API calls: + +\code + pmt::pmt_t message_ports_in(); + pmt::pmt_t message_ports_out(); +\endcode + +The return value for these are a PMT vector filled with PMT symbols, +so PMT operators must be used to manipulate them. + +Each block has internal methods to handle posting and receiving of +messages. The gr_basic_block::_post method takes in a message and +places it into its queue. The publishing model uses the +gr_basic_block::_post method of the blocks as the way to access the +message queue. So the message queue of the right name will have a new +message. Posting messages also has the benefit of waking up the +block's thread if it is in a wait state. So if idle, as soon as a +message is posted, it will wake up and and call the message handler. + +The other side of the action in a block is in the message +handler. When a block has an input message port, it needs a callback +function to handle messages received on that port. We use a Boost bind +operator to bind the message port to the message handling +function. When a new message is pushed onto a port's message queue, +it is this function that is used to process the message. + + +\section examples Code Examples + +The following is snippets of code from blocks current in GNU Radio +that take advantage of message passing. We will be using +gr_message_debug and gr_tagged_stream_to_pdu below to show setting up +both input and output message passing capabilities. + +The gr_message_debug block is used for debugging the message passing +system. It describes two input message ports: \a print and \a +store. The \a print port simply prints out all messages to standard +out while the \a store port keeps a list of all messages posted to +it. This latter port works in conjunction with a +gr_message_debug::get_message(int i) call that allows us to retrieve +message \p i afterward. + +The constructor of this block looks like this: + +\code +{ + message_port_register_in(pmt::mp("print")); + set_msg_handler(pmt::mp("print"), + boost::bind(&gr_message_debug::print, this, _1)); + + message_port_register_in(pmt::mp("store")); + set_msg_handler(pmt::mp("store"), + boost::bind(&gr_message_debug::store, this, _1)); +} +\endcode + +So the two ports are registered by their respective names. We then use +the gr_basic_block::set_msg_handler function to identify this +particular port name with a callback function. The Boost \a bind +function (<a target="_blank" +href="http://www.boost.org/doc/libs/1_52_0/libs/bind/bind.html">Boost::bind</a>) +here binds the callback to a function of this block's class. So now +the block's gr_message_debug::print and gr_message_debug::store +functions are assigned to handle messages passed to them. Below is the +\a print function for reference. + +\code +void +gr_message_debug::print(pmt::pmt_t msg) +{ + std::cout << "***** MESSAGE DEBUG PRINT ********\n"; + pmt::pmt_print(msg); + std::cout << "**********************************\n"; +} +\endcode + +The function simply takes in the PMT message and prints it. The method +pmt::pmt_print is a function in the PMT library to print the +PMT in a friendly, (mostly) pretty manner. + +The gr_tagged_stream_to_pdu block only defines a single +output message port. In this case, its constructor looks like: + +\code +{ + message_port_register_out(pdu_port_id); +} +\endcode + +So we are only creating a single output port where \a pdu_port_id +is defined in the file gr_pdu.h as \a pdus. + +This blocks purpose is to take in a stream of samples along with +stream tags and construct a predefined PDU message from this. In GNU +Radio, we define a PDU as a PMT pair of (metadata, data). The metadata +describes the samples found in the data portion of the +pair. Specifically, the metadata can contain the length of the data +segment and any other information (sample rate, etc.). The PMT vectors +know their own length, so the length value is not actually necessary +unless useful for purposes down the line. The metadata is a PMT +dictionary while the data segment is a PMT uniform vector of either +bytes, floats, or complex values. + +In the end, when a PDU message is ready, the block calls its +gr_tagged_stream_to_pdu::send_message function that is shown below. + +\code +void +gr_tagged_stream_to_pdu::send_meassage() +{ + if(pmt::pmt_length(d_pdu_vector) != d_pdu_length) { + throw std::runtime_error("msg length not correct"); + } + + pmt::pmt_t msg = pmt::pmt_cons(d_pdu_meta, + d_pdu_vector); + message_port_pub(pdu_port_id, msg); + + d_pdu_meta = pmt::PMT_NIL; + d_pdu_vector = pmt::PMT_NIL; + d_pdu_length = 0; + d_pdu_remain = 0; + d_inpdu = false; +} +\endcode + +This function does a bit of checking to make sure the PDU is ok as +well as some cleanup in the end. But it is the line where the message +is published that is important to this discussion. Here, the block +posts the PDU message to any subscribers by calling +gr_basic_block::message_port_pub publishing method. + +There is similarly a gr_pdu_to_tagged_stream block that essentially +does the opposite. It acts as a source to a flowgraph and waits for +PDU messages to be posted to it on its input port \a pdus. It extracts +the metadata and data and processes them. The metadata dictionary is +split up into key:value pairs and stream tags are created out of +them. The data is then converted into an output stream of items and +passed along. The next section describes how PDUs can be passed into a +flowgraph using the gr_pdu_to_tagged_stream block. + +\section posting Posting from External Sources + +The last feature of the message passing architecture to discuss here +is how it can be used to take in messages from an external source. We +can call a block's gr_basic_block::_post method directly and pass it a +message. So any block with an input message port can receive messages +from the outside in this way. + +The following example uses a gr_pdu_to_tagged_stream block +as the source block to a flowgraph. Its purpose is to wait for +messages as PDUs posted to it and convert them to a normal stream. The +payload will be sent on as a normal stream while the meta data will be +decoded into tags and sent on the tagged stream. + +So if we have created a \b src block as a PDU to stream, it has a \a +pdus input port, which is how we will inject PDU messages to the +flowgraph. These PDUs could come from another block or flowgraph, but +here, we will create and insert them by hand. + +\code + port = pmt.pmt_intern("pdus") + msg = pmt.pmt_cons(pmt.PMT_NIL, + pmt.pmt_make_u8vector(16, 0xFF)) + src.to_basic_block()._post(port, msg) +\endcode + +The PDU's metadata section is empty, hence the pmt::PMT_NIL +object. The payload is now just a simple vector of 16 bytes of all +1's. To post the message, we have to access the block's gr_basic_block +class, which we do using the gr_basic_block::to_basic_block method and +then call the gr_basic_block::_post method to pass the PDU to the +right port. + +All of these mechanisms are explored and tested in the QA code of the +file qa_pdu.py. + +There are some examples of using the message passing infrastructure +through GRC in gnuradio-core/src/examples/msg_passing. + +*/ diff --git a/docs/doxygen/other/pmt.dox b/docs/doxygen/other/pmt.dox new file mode 100644 index 000000000..61b73bca1 --- /dev/null +++ b/docs/doxygen/other/pmt.dox @@ -0,0 +1,348 @@ +/*! \page page_pmt Polymorphic Types + +\section intro Introduction + +Polymorphic Types are opaque data types that are designed as generic +containers of data that can be safely passed around between blocks and +threads in GNU Radio. They are heavily used in the stream tags and +message passing interfaces. The most complete list of PMT function is, +of course, the source code, specifically the header file pmt.h. This +manual page summarizes the most important features and points of PMTs. + + +\section datatype PMT Data Type + +All PMTs are of the type pmt::pmt_t. This is an opaque container and +PMT functions must be used to manipulate and even do things like +compare PMTs. PMTs are also \a immutable (except PMT vectors). We +never change the data in a PMT; instead, we create a new PMT with the +new data. The main reason for this is thread safety. We can pass PMTs +as tags and messages between blocks and each receives its own copy +that we can read from. However, we can never write to this object, and +so if multiple blocks have a reference to the same PMT, there is no +possibility of thread-safety issues of one reading the PMT data while +another is writing the data. If a block is trying to write new data to +a PMT, it actually creates a new PMT to put the data into. Thus we +allow easy access to data in the PMT format without worrying about +mutex locking and unlocking while manipulating them. + +PMTs can represent the following: + +- Boolean values of true/false +- Strings (as symbols) +- Integers (long and uint64) +- Floats (as doubles) +- Complex (as two doubles) +- Pairs +- Tuples +- Vectors (of PMTs) +- Uniform vectors (of any standard data type) +- Dictionaries (list of key:value pairs) +- Any (contains a boost::any pointer to hold anything) + +The PMT library also defines a set of functions that operate directly +on PMTs such as: + +- Equal/equivalence between PMTs +- Length (of a tuple or vector) +- Map (apply a function to all elements in the PMT) +- Reverse +- Get a PMT at a position in a list +- Serialize and deserialize +- Printing + +The constants in the PMT library are: + +- pmt::PMT_T - a PMT True +- pmt::PMT_F - a PMT False +- pmt::PMT_NIL - an empty PMT (think Python's 'None') + +\section insert Inserting and Extracting Data + +Use pmt.h for a complete guide to the list of functions used to create +PMTs and get the data from a PMT. When using these functions, remember +that while PMTs are opaque and designed to hold any data, the data +underneath is still a C++ typed object, and so the right type of +set/get function must be used for the data type. + +Typically, a PMT object can be made from a scalar item using a call +like "pmt::pmt_from_<type>". Similarly, when getting data out of a +PMT, we use a call like "pmt::pmt_to_<type>". For example: + +\code +double a = 1.2345; +pmt::pmt_t pmt_a = pmt::pmt_from_double(a); +double b = pmt::pmt_to_double(pmt_a); + +int c = 12345; +pmt::pmt_t pmt_c = pmt::pmt_from_long(c); +int d = pmt::pmt_to_long(pmt_c); +\endcode + +As a side-note, making a PMT from a complex number is not obvious: + +\code +std::complex<double> a(1.2, 3.4); +pmt::pmt_t pmt_a = pmt::pmt_make_rectangular(a.real(), b.imag()); +std::complex<double> b = pmt::pmt_to_complex(pmt_a); +\endcode + +Pairs, dictionaries, and vectors have different constructors and ways +to manipulate them, and these are explained in their own sections. + + +\section strings Strings + +PMTs have a way of representing short strings. These strings are +actually stored as interned symbols in a hash table, so in other +words, only one PMT object for a given string exists. If creating a +new symbol from a string, if that string already exists in the hash +table, the constructor will return a reference to the existing PMT. + +We create strings with the following functions, where the second +function, pmt::pmt_intern, is simply an alias of the first. + +\code +pmt::pmt_t str0 = pmt::pmt_string_to_symbol(std::string("some string")); +pmt::pmt_t str1 = pmt::pmt_intern(std::string("some string")); +\endcode + +The string can be retrieved using the inverse function: + +\code +std::string s = pmt::pmt_symbol_to_string(str0); +\endcode + + +\section tests Tests and Comparisons + +The PMT library comes with a number of functions to test and compare +PMT objects. In general, for any PMT data type, there is an equivalent +"pmt::pmt_is_<type>". We can use these to test the PMT before trying +to access the data inside. Expanding our examples above, we have: + +\code +pmt::pmt_t str0 = pmt::pmt_string_to_symbol(std::string("some string")); +if(pmt::pmt_is_symbol(str0)) + std::string s = pmt::pmt_symbol_to_string(str0); + +double a = 1.2345; +pmt::pmt_t pmt_a = pmt::pmt_from_double(a); +if(pmt::pmt_is_double(pmt_a)) + double b = pmt::pmt_to_double(pmt_a); + +int c = 12345; +pmt::pmt_t pmt_c = pmt::pmt_from_long(c); +if(pmt::pmt_is_long(pmt_a)) + int d = pmt::pmt_to_long(pmt_c); + +\\ This will fail the test. Otherwise, trying to coerce \b pmt_c as a +\\ double when internally it is a long will result in an exception. +if(pmt::pmt_is_double(pmt_a)) + double d = pmt::pmt_to_double(pmt_c); + +\endcode + + +\section dict Dictionaries + +PMT dictionaries and lists of key:value pairs. They have a +well-defined interface for creating, adding, removing, and accessing +items in the dictionary. Note that every operation that changes the +dictionary both takes a PMT dictionary as an argument and returns a +PMT dictionary. The dictionary used as an input is not changed and the +returned dictionary is a new PMT with the changes made there. + +The following is a list of PMT dictionary functions. Click through to +get more information on what each does. + +- bool pmt::pmt_is_dict(const pmt_t &obj) +- pmt_t pmt::pmt_make_dict() +- pmt_t pmt::pmt_dict_add(const pmt_t &dict, const pmt_t &key, const pmt_t &value) +- pmt_t pmt::pmt_dict_delete(const pmt_t &dict, const pmt_t &key) +- bool pmt::pmt_dict_has_key(const pmt_t &dict, const pmt_t &key) +- pmt_t pmt::pmt_dict_ref(const pmt_t &dict, const pmt_t &key, const pmt_t ¬_found) +- pmt_t pmt::pmt_dict_items(pmt_t dict) +- pmt_t pmt::pmt_dict_keys(pmt_t dict) +- pmt_t pmt::pmt_dict_values(pmt_t dict) + +This example does some basic manipulations of PMT dictionaries in +Python. Notice that we pass the dictionary \a a and return the results +to \a a. This still creates a new dictionary and removes the local +reference to the old dictionary. This just keeps our number of +variables small. + +\code +from gruel import pmt + +key0 = pmt.pmt_intern("int") +val0 = pmt.pmt_from_long(123) +val1 = pmt.pmt_from_long(234) + +key1 = pmt.pmt_intern("double") +val2 = pmt.pmt_from_double(5.4321) + +# Make an empty dictionary +a = pmt.pmt_make_dict() + +# Add a key:value pair to the dictionary +a = pmt.pmt_dict_add(a, key0, val0) +pmt.pmt_print(a) + +# Add a new value to the same key; +# new dict will still have one item with new value +a = pmt.pmt_dict_add(a, key0, val1) +pmt.pmt_print(a) + +# Add a new key:value pair +a = pmt.pmt_dict_add(a, key1, val2) +pmt.pmt_print(a) + +# Test if we have a key, then delete it +print pmt.pmt_dict_has_key(a, key1) +a = pmt.pmt_dict_delete(a, key1) +print pmt.pmt_dict_has_key(a, key1) + +ref = pmt.pmt_dict_ref(a, key0, pmt.PMT_NIL) +pmt.pmt_print(ref) + +# The following should never print +if(pmt.pmt_dict_has_key(a, key0) and pmt.pmt_eq(ref, pmt.PMT_NIL)): + print "Trouble! We have key0, but it returned PMT_NIL" +\endcode + +\section vectors Vectors + +PMT vectors come in two forms: vectors of PMTs and vectors of uniform +data. The standard PMT vector is a vector of PMTs, and each PMT can be +of any internal type. On the other hand, uniform PMTs are of a +specific data type which come in the form: + +- (u)int8 +- (u)int16 +- (u)int32 +- (u)int64 +- float32 +- float64 +- complex 32 (std::complex<float>) +- complex 64 (std::complex<double>) + +That is, the standard sizes of integers, floats, and complex types of +both signed and unsigned. + +Vectors have a well-defined interface that allows us to make, set, +get, and fill them. We can also get the length of a vector with +pmt::pmt_length. + +For standard vectors, these functions look like: + +- bool pmt::pmt_is_vector(pmt_t x) +- pmt_t pmt::pmt_make_vector(size_t k, pmt_t fill) +- pmt_t pmt::pmt_vector_ref(pmt_t vector, size_t k) +- void pmt::pmt_vector_set(pmt_t vector, size_t k, pmt_t obj) +- void pmt::pmt_vector_fill(pmt_t vector, pmt_t fill) + +Uniform vectors have the same types of functions, but they are data +type-dependent. The following list tries to explain them where you +substitute the specific data type prefix for \a dtype (prefixes being: +u8, u16, u32, u64, s8, s16, s32, s64, f32, f64, c32, c64). + +- bool pmt::pmt_is_(dtype)vector(pmt_t x) +- pmt_t pmt::pmt_make_(dtype)vector(size_t k, (dtype) fill) +- pmt_t pmt::pmt_init_(dtype)vector(size_t k, const (dtype*) data) +- pmt_t pmt::pmt_init_(dtype)vector(size_t k, const std::vector<dtype> data) +- pmt_t pmt::pmt_(dtype)vector_ref(pmt_t vector, size_t k) +- void pmt::pmt_(dtype)vector_set(pmt_t vector, size_t k, (dtype) x) +- const dtype* pmt::pmt_(dtype)vector_elements(pmt_t vector, size_t &len) +- dtype* pmt::pmt_(dtype)vector_writable_elements(pmt_t vector, size_t &len) + +\b Note: We break the contract with vectors. The 'set' functions +actually change the data underneath. It is important to keep track of +the implications of setting a new value as well as accessing the +'vector_writable_elements' data. Since these are mostly standard data +types, sets and gets are atomic, so it is unlikely to cause a great +deal of harm. But it's only unlikely, not impossible. Best to use +mutexes whenever manipulating data in a vector. + + +\subsection blob BLOB + +A BLOB is a 'binary large object' type. In PMT's, this is actually +just a thin wrapper around a u8vector. + +\section pairs Pairs + +Pairs are inspired by LISP 'cons' data types, so you will find the +language here comes from LISP. A pair is just a pair of PMT +objects. They are manipulated using the following functions: + +- bool pmt::pmt_is_pair (const pmt_t &obj): Return true if obj is a pair, else false +- pmt_t pmt::pmt_cons(const pmt_t &x, const pmt_t &y): construct new pair +- pmt_t pmt::pmt_car(const pmt_t &pair): get the car of the pair (first object) +- pmt_t pmt::pmt_cdr(const pmt_t &pair): get the cdr of the pair (second object) +- void pmt::pmt_set_car(pmt_t pair, pmt_t value): Stores value in the car field +- void pmt::pmt_set_cdr(pmt_t pair, pmt_t value): Stores value in the cdr field + + +\section serdes Serializing and Deserializing + +It is often important to hide the fact that we are working with PMTs +to make them easier to transmit, store, write to file, etc. The PMT +library has methods to serialize data into a string buffer or a +string and then methods to deserialize the string buffer or string +back into a PMT. We use this extensively in the metadata files (see +\ref page_metadata). + +- bool pmt::pmt_serialize(pmt_t obj, std::streambuf &sink) +- std::string pmt::pmt_serialize_str(pmt_t obj) +- pmt_t pmt::pmt_deserialize(std::streambuf &source) +- pmt_t pmt::pmt_deserialize_str(std::string str) + +For example, we will serialize the data above to make it into a string +ready to be written to a file and then deserialize it back to its +original PMT. + +\code +from gruel import pmt + +key0 = pmt.pmt_intern("int") +val0 = pmt.pmt_from_long(123) + +key1 = pmt.pmt_intern("double") +val1 = pmt.pmt_from_double(5.4321) + +# Make an empty dictionary +a = pmt.pmt_make_dict() + +# Add a key:value pair to the dictionary +a = pmt.pmt_dict_add(a, key0, val0) +a = pmt.pmt_dict_add(a, key1, val1) + +pmt.pmt_print(a) + +ser_str = pmt.pmt_serialize_str(a) +print ser_str + +b = pmt.pmt_deserialize_str(ser_str) +pmt.pmt_print(b) + +\endcode + +The line where we 'print ser_str' will print and parts will be +readable, but the point of serializing is not to make a human-readable +string. This is only done here as a test. + + +\section printing Printing + +We have used the pmt::pmt_print function in these examples to nicely +print the contents of a PMT. Another way to print the contents is +using the overloaded "<<" operator with a stream buffer object. In +C++, we can inline print the contents of a PMT like: + +\code +pmt::pmt_t a pmt::pmt_from_double(1.0); +std::cout << "The PMT a contains " << a << std::endl; +\endcode + +*/ diff --git a/gnuradio-core/CMakeLists.txt b/gnuradio-core/CMakeLists.txt index d773280e6..2f06791ca 100644 --- a/gnuradio-core/CMakeLists.txt +++ b/gnuradio-core/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright 2010-2011 Free Software Foundation, Inc. +# Copyright 2010-2012 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -45,6 +45,7 @@ GR_REGISTER_COMPONENT("gnuradio-core" ENABLE_GR_CORE include(GrMiscUtils) GR_SET_GLOBAL(GNURADIO_CORE_INCLUDE_DIRS + ${Boost_INCLUDE_DIRS} ${GRUEL_INCLUDE_DIRS} #headers depend on gruel ${CMAKE_CURRENT_SOURCE_DIR}/src/lib/runtime ${CMAKE_CURRENT_BINARY_DIR}/src/lib/general @@ -65,7 +66,7 @@ GR_SET_GLOBAL(GNURADIO_CORE_INCLUDE_DIRS GR_SET_GLOBAL(GNURADIO_CORE_SWIG_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/gruel/src/swig - ${CMAKE_BINARY_DIR}/gruel/src/swig/ + ${CMAKE_BINARY_DIR}/gruel/src/swig ${CMAKE_CURRENT_SOURCE_DIR}/src/lib/swig ${GNURADIO_CORE_INCLUDE_DIRS} ) diff --git a/gnuradio-core/src/examples/CMakeLists.txt b/gnuradio-core/src/examples/CMakeLists.txt index c2b847c91..01d9eb83e 100644 --- a/gnuradio-core/src/examples/CMakeLists.txt +++ b/gnuradio-core/src/examples/CMakeLists.txt @@ -18,6 +18,7 @@ # Boston, MA 02110-1301, USA. add_subdirectory(mp-sched) +add_subdirectory(msg_passing) add_subdirectory(network) add_subdirectory(pfb) add_subdirectory(tags) diff --git a/gnuradio-core/src/examples/msg_passing/CMakeLists.txt b/gnuradio-core/src/examples/msg_passing/CMakeLists.txt new file mode 100644 index 000000000..c4b207a1e --- /dev/null +++ b/gnuradio-core/src/examples/msg_passing/CMakeLists.txt @@ -0,0 +1,27 @@ +# Copyright 2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. + +include(GrPython) + +install( + FILES + strobe.grc + DESTINATION ${GR_PKG_DATA_DIR}/examples/msg_passing + COMPONENT "core_python" +) diff --git a/gnuradio-core/src/examples/msg_passing/hier/test_msg_hier.grc b/gnuradio-core/src/examples/msg_passing/hier/test_msg_hier.grc new file mode 100644 index 000000000..0faed49bc --- /dev/null +++ b/gnuradio-core/src/examples/msg_passing/hier/test_msg_hier.grc @@ -0,0 +1,287 @@ +<?xml version='1.0' encoding='ASCII'?> +<flow_graph> + <timestamp>Mon Dec 10 19:56:24 2012</timestamp> + <block> + <key>options</key> + <param> + <key>id</key> + <value>test_msg_hier</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>title</key> + <value></value> + </param> + <param> + <key>author</key> + <value></value> + </param> + <param> + <key>description</key> + <value></value> + </param> + <param> + <key>window_size</key> + <value>1280, 1024</value> + </param> + <param> + <key>generate_options</key> + <value>hb</value> + </param> + <param> + <key>category</key> + <value>Custom</value> + </param> + <param> + <key>run_options</key> + <value>prompt</value> + </param> + <param> + <key>run</key> + <value>True</value> + </param> + <param> + <key>max_nouts</key> + <value>0</value> + </param> + <param> + <key>realtime_scheduling</key> + <value></value> + </param> + <param> + <key>_coordinate</key> + <value>(10, 10)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>pad_source</key> + <param> + <key>id</key> + <value>pad_source_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>label</key> + <value>TEST_PORT</value> + </param> + <param> + <key>type</key> + <value>message</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + <param> + <key>optional</key> + <value>False</value> + </param> + <param> + <key>_coordinate</key> + <value>(234, 145)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>pad_source</key> + <param> + <key>id</key> + <value>pad_source_0_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>label</key> + <value>TEST_PORT2</value> + </param> + <param> + <key>type</key> + <value>message</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + <param> + <key>optional</key> + <value>False</value> + </param> + <param> + <key>_coordinate</key> + <value>(167, 54)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_message_strobe</key> + <param> + <key>id</key> + <value>gr_message_strobe_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>msg</key> + <value>pmt.pmt_cons(pmt.PMT_NIL, pmt.pmt_make_u8vector(16,0x77))</value> + </param> + <param> + <key>period</key> + <value>200</value> + </param> + <param> + <key>_coordinate</key> + <value>(362, 81)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>pad_sink</key> + <param> + <key>id</key> + <value>pad_sink_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>label</key> + <value>TEST_PORT</value> + </param> + <param> + <key>type</key> + <value>message</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + <param> + <key>optional</key> + <value>True</value> + </param> + <param> + <key>_coordinate</key> + <value>(618, 87)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_message_strobe</key> + <param> + <key>id</key> + <value>gr_message_strobe_0_1</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>msg</key> + <value>pmt.pmt_intern("OUTPUT2")</value> + </param> + <param> + <key>period</key> + <value>100</value> + </param> + <param> + <key>_coordinate</key> + <value>(400, 156)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>pad_sink</key> + <param> + <key>id</key> + <value>pad_sink_0_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>label</key> + <value>TEST_PORT3</value> + </param> + <param> + <key>type</key> + <value>message</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + <param> + <key>optional</key> + <value>True</value> + </param> + <param> + <key>_coordinate</key> + <value>(695, 172)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <connection> + <source_block_id>pad_source_0_0</source_block_id> + <sink_block_id>gr_message_strobe_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>pad_source_0</source_block_id> + <sink_block_id>gr_message_strobe_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_message_strobe_0</source_block_id> + <sink_block_id>pad_sink_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_message_strobe_0_1</source_block_id> + <sink_block_id>pad_sink_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_message_strobe_0_1</source_block_id> + <sink_block_id>pad_sink_0_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> +</flow_graph> diff --git a/gnuradio-core/src/examples/msg_passing/hier/test_msg_hier_topblock.grc b/gnuradio-core/src/examples/msg_passing/hier/test_msg_hier_topblock.grc new file mode 100644 index 000000000..f440b06b3 --- /dev/null +++ b/gnuradio-core/src/examples/msg_passing/hier/test_msg_hier_topblock.grc @@ -0,0 +1,185 @@ +<?xml version='1.0' encoding='ASCII'?> +<flow_graph> + <timestamp>Mon Dec 10 19:56:42 2012</timestamp> + <block> + <key>options</key> + <param> + <key>id</key> + <value>test_msg_hier_topblock</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>title</key> + <value></value> + </param> + <param> + <key>author</key> + <value></value> + </param> + <param> + <key>description</key> + <value></value> + </param> + <param> + <key>window_size</key> + <value>1280, 1024</value> + </param> + <param> + <key>generate_options</key> + <value>no_gui</value> + </param> + <param> + <key>category</key> + <value>Custom</value> + </param> + <param> + <key>run_options</key> + <value>prompt</value> + </param> + <param> + <key>run</key> + <value>True</value> + </param> + <param> + <key>max_nouts</key> + <value>0</value> + </param> + <param> + <key>realtime_scheduling</key> + <value></value> + </param> + <param> + <key>_coordinate</key> + <value>(10, 10)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_message_strobe</key> + <param> + <key>id</key> + <value>gr_message_strobe_0_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>msg</key> + <value>pmt.pmt_intern("UPDATED2")</value> + </param> + <param> + <key>period</key> + <value>3000</value> + </param> + <param> + <key>_coordinate</key> + <value>(51, 88)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_message_strobe</key> + <param> + <key>id</key> + <value>gr_message_strobe_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>msg</key> + <value>pmt.pmt_intern("UPDATED")</value> + </param> + <param> + <key>period</key> + <value>2000</value> + </param> + <param> + <key>_coordinate</key> + <value>(211, 168)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_message_debug</key> + <param> + <key>id</key> + <value>gr_message_debug_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>_coordinate</key> + <value>(758, 71)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>TEST_MSG_HIER</key> + <param> + <key>id</key> + <value>TEST_MSG_HIER_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>_coordinate</key> + <value>(402, 52)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <connection> + <source_block_id>TEST_MSG_HIER_0</source_block_id> + <sink_block_id>gr_message_debug_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_message_strobe_0</source_block_id> + <sink_block_id>TEST_MSG_HIER_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_message_strobe_0_0</source_block_id> + <sink_block_id>TEST_MSG_HIER_0</sink_block_id> + <source_key>0</source_key> + <sink_key>1</sink_key> + </connection> + <connection> + <source_block_id>TEST_MSG_HIER_0</source_block_id> + <sink_block_id>gr_message_debug_0</sink_block_id> + <source_key>0</source_key> + <sink_key>1</sink_key> + </connection> + <connection> + <source_block_id>TEST_MSG_HIER_0</source_block_id> + <sink_block_id>gr_message_debug_0</sink_block_id> + <source_key>1</source_key> + <sink_key>0</sink_key> + </connection> +</flow_graph> diff --git a/gnuradio-core/src/examples/msg_passing/strobe.grc b/gnuradio-core/src/examples/msg_passing/strobe.grc new file mode 100644 index 000000000..7e7e8c345 --- /dev/null +++ b/gnuradio-core/src/examples/msg_passing/strobe.grc @@ -0,0 +1,266 @@ +<?xml version='1.0' encoding='ASCII'?> +<flow_graph> + <timestamp>Thu Dec 6 11:33:08 2012</timestamp> + <block> + <key>variable</key> + <param> + <key>id</key> + <value>samp_rate</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>value</key> + <value>32000</value> + </param> + <param> + <key>_coordinate</key> + <value>(10, 170)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_pdu_to_tagged_stream</key> + <param> + <key>id</key> + <value>gr_pdu_to_tagged_stream_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>byte</value> + </param> + <param> + <key>_coordinate</key> + <value>(443, 89)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_message_debug</key> + <param> + <key>id</key> + <value>gr_message_debug_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>_coordinate</key> + <value>(1049, 176)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_tagged_stream_to_pdu</key> + <param> + <key>id</key> + <value>gr_tagged_stream_to_pdu_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>byte</value> + </param> + <param> + <key>_coordinate</key> + <value>(870, 89)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_kludge_copy</key> + <param> + <key>id</key> + <value>gr_kludge_copy_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>byte</value> + </param> + <param> + <key>num_ports</key> + <value>1</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + <param> + <key>_coordinate</key> + <value>(686, 89)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_message_strobe</key> + <param> + <key>id</key> + <value>gr_message_strobe_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>msg</key> + <value>pmt.pmt_intern("TEST")</value> + </param> + <param> + <key>period</key> + <value>1000</value> + </param> + <param> + <key>_coordinate</key> + <value>(423, 177)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_message_strobe</key> + <param> + <key>id</key> + <value>gr_message_strobe_0_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>msg</key> + <value>pmt.pmt_cons( pmt.PMT_NIL, pmt.pmt_make_u8vector(512,0) )</value> + </param> + <param> + <key>period</key> + <value>750</value> + </param> + <param> + <key>_coordinate</key> + <value>(99, 85)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>options</key> + <param> + <key>id</key> + <value>strobe</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>title</key> + <value></value> + </param> + <param> + <key>author</key> + <value></value> + </param> + <param> + <key>description</key> + <value></value> + </param> + <param> + <key>window_size</key> + <value>1280, 1024</value> + </param> + <param> + <key>generate_options</key> + <value>no_gui</value> + </param> + <param> + <key>category</key> + <value>Custom</value> + </param> + <param> + <key>run_options</key> + <value>prompt</value> + </param> + <param> + <key>run</key> + <value>True</value> + </param> + <param> + <key>max_nouts</key> + <value>0</value> + </param> + <param> + <key>realtime_scheduling</key> + <value></value> + </param> + <param> + <key>_coordinate</key> + <value>(10, 10)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <connection> + <source_block_id>gr_message_strobe_0_0</source_block_id> + <sink_block_id>gr_pdu_to_tagged_stream_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_message_strobe_0</source_block_id> + <sink_block_id>gr_message_debug_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_tagged_stream_to_pdu_0</source_block_id> + <sink_block_id>gr_message_debug_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_kludge_copy_0</source_block_id> + <sink_block_id>gr_tagged_stream_to_pdu_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_pdu_to_tagged_stream_0</source_block_id> + <sink_block_id>gr_kludge_copy_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> +</flow_graph> diff --git a/gnuradio-core/src/examples/pfb/CMakeLists.txt b/gnuradio-core/src/examples/pfb/CMakeLists.txt index 6bb25568c..090b2401d 100644 --- a/gnuradio-core/src/examples/pfb/CMakeLists.txt +++ b/gnuradio-core/src/examples/pfb/CMakeLists.txt @@ -25,7 +25,6 @@ GR_PYTHON_INSTALL(PROGRAMS decimate.py fmtest.py interpolate.py - resampler_demo.grc resampler.py synth_filter.py synth_to_chan.py @@ -34,3 +33,9 @@ GR_PYTHON_INSTALL(PROGRAMS COMPONENT "core_python" ) +install( + FILES + resampler_demo.grc + DESTINATION ${GR_PKG_DATA_DIR}/examples/pfb + COMPONENT "core_python" +) diff --git a/gnuradio-core/src/lib/filter/3dnow_float_dotprod_really_simple.S b/gnuradio-core/src/lib/filter/3dnow_float_dotprod_really_simple.S index 0cd686736..546a4a6f3 100644 --- a/gnuradio-core/src/lib/filter/3dnow_float_dotprod_really_simple.S +++ b/gnuradio-core/src/lib/filter/3dnow_float_dotprod_really_simple.S @@ -52,7 +52,7 @@ .file "3dnow_float_dotprod_really_simple.s" - .version "01.01" +// .version "01.01" .text .p2align 4 .globl sse_float_dotprod diff --git a/gnuradio-core/src/lib/filter/3dnow_float_dotprod_simple.S b/gnuradio-core/src/lib/filter/3dnow_float_dotprod_simple.S index 5af3fc5c9..c721c3601 100644 --- a/gnuradio-core/src/lib/filter/3dnow_float_dotprod_simple.S +++ b/gnuradio-core/src/lib/filter/3dnow_float_dotprod_simple.S @@ -52,7 +52,7 @@ .file "3dnow_float_dotprod_simple.s" - .version "01.01" +// .version "01.01" .text .p2align 4 .globl sse_float_dotprod diff --git a/gnuradio-core/src/lib/filter/ccomplex_dotprod_3dnow.S b/gnuradio-core/src/lib/filter/ccomplex_dotprod_3dnow.S index 8844e5108..f66356337 100644 --- a/gnuradio-core/src/lib/filter/ccomplex_dotprod_3dnow.S +++ b/gnuradio-core/src/lib/filter/ccomplex_dotprod_3dnow.S @@ -55,7 +55,7 @@ #include "assembly.h" .file "ccomplex_dotprod_3dnow.S" - .version "01.01" +// .version "01.01" .text .p2align 4 .globl GLOB_SYMB(ccomplex_dotprod_3dnow) diff --git a/gnuradio-core/src/lib/filter/ccomplex_dotprod_3dnow64.S b/gnuradio-core/src/lib/filter/ccomplex_dotprod_3dnow64.S index d92fe17a3..e81d21993 100644 --- a/gnuradio-core/src/lib/filter/ccomplex_dotprod_3dnow64.S +++ b/gnuradio-core/src/lib/filter/ccomplex_dotprod_3dnow64.S @@ -56,7 +56,7 @@ .file "ccomplex_dotprod_3dnow64.S" - .version "01.01" +// .version "01.01" .text .p2align 4 .globl GLOB_SYMB(ccomplex_dotprod_3dnow) diff --git a/gnuradio-core/src/lib/filter/ccomplex_dotprod_3dnowext.S b/gnuradio-core/src/lib/filter/ccomplex_dotprod_3dnowext.S index c4a02d7fb..22c390bdd 100644 --- a/gnuradio-core/src/lib/filter/ccomplex_dotprod_3dnowext.S +++ b/gnuradio-core/src/lib/filter/ccomplex_dotprod_3dnowext.S @@ -55,7 +55,7 @@ #include "assembly.h" .file "ccomplex_dotprod_3dnowext.S" - .version "01.01" +// .version "01.01" .text .p2align 4 .globl GLOB_SYMB(ccomplex_dotprod_3dnowext) diff --git a/gnuradio-core/src/lib/filter/ccomplex_dotprod_3dnowext64.S b/gnuradio-core/src/lib/filter/ccomplex_dotprod_3dnowext64.S index c4f9e1970..75608914b 100644 --- a/gnuradio-core/src/lib/filter/ccomplex_dotprod_3dnowext64.S +++ b/gnuradio-core/src/lib/filter/ccomplex_dotprod_3dnowext64.S @@ -55,7 +55,7 @@ #include "assembly.h" .file "ccomplex_dotprod_3dnowext64.S" - .version "01.01" +// .version "01.01" .text .p2align 4 .globl GLOB_SYMB(ccomplex_dotprod_3dnowext) diff --git a/gnuradio-core/src/lib/filter/ccomplex_dotprod_sse.S b/gnuradio-core/src/lib/filter/ccomplex_dotprod_sse.S index b50a3690d..3d16c352e 100644 --- a/gnuradio-core/src/lib/filter/ccomplex_dotprod_sse.S +++ b/gnuradio-core/src/lib/filter/ccomplex_dotprod_sse.S @@ -55,7 +55,7 @@ #include "assembly.h" .file "ccomplex_dotprod_sse.S" - .version "01.01" +// .version "01.01" .text .p2align 4 .globl GLOB_SYMB(ccomplex_dotprod_sse) diff --git a/gnuradio-core/src/lib/filter/ccomplex_dotprod_sse64.S b/gnuradio-core/src/lib/filter/ccomplex_dotprod_sse64.S index ef89ae638..95ac3dac3 100644 --- a/gnuradio-core/src/lib/filter/ccomplex_dotprod_sse64.S +++ b/gnuradio-core/src/lib/filter/ccomplex_dotprod_sse64.S @@ -56,7 +56,7 @@ .file "ccomplex_dotprod_sse64.S" - .version "01.01" +// .version "01.01" .text .p2align 4 .globl GLOB_SYMB(ccomplex_dotprod_sse) diff --git a/gnuradio-core/src/lib/filter/complex_dotprod_3dnow.S b/gnuradio-core/src/lib/filter/complex_dotprod_3dnow.S index df7761c40..be49bb863 100644 --- a/gnuradio-core/src/lib/filter/complex_dotprod_3dnow.S +++ b/gnuradio-core/src/lib/filter/complex_dotprod_3dnow.S @@ -53,7 +53,7 @@ #include "assembly.h" .file "complex_dotprod_3dnow.S" - .version "01.01" +// .version "01.01" .text .p2align 4 .globl GLOB_SYMB(complex_dotprod_3dnow) diff --git a/gnuradio-core/src/lib/filter/complex_dotprod_3dnow64.S b/gnuradio-core/src/lib/filter/complex_dotprod_3dnow64.S index ac5a7d1be..f1c813078 100644 --- a/gnuradio-core/src/lib/filter/complex_dotprod_3dnow64.S +++ b/gnuradio-core/src/lib/filter/complex_dotprod_3dnow64.S @@ -54,7 +54,7 @@ .file "complex_dotprod_3dnow64.S" - .version "01.01" +// .version "01.01" .text .p2align 4 .globl GLOB_SYMB(complex_dotprod_3dnow) diff --git a/gnuradio-core/src/lib/filter/complex_dotprod_3dnowext.S b/gnuradio-core/src/lib/filter/complex_dotprod_3dnowext.S index 1d4be32c3..52f04f10c 100644 --- a/gnuradio-core/src/lib/filter/complex_dotprod_3dnowext.S +++ b/gnuradio-core/src/lib/filter/complex_dotprod_3dnowext.S @@ -53,7 +53,7 @@ #include "assembly.h" .file "complex_dotprod_3dnowext.S" - .version "01.01" +// .version "01.01" .text .p2align 4 .globl GLOB_SYMB(complex_dotprod_3dnowext) diff --git a/gnuradio-core/src/lib/filter/complex_dotprod_3dnowext64.S b/gnuradio-core/src/lib/filter/complex_dotprod_3dnowext64.S index 018fefe28..6d7ad5ad4 100644 --- a/gnuradio-core/src/lib/filter/complex_dotprod_3dnowext64.S +++ b/gnuradio-core/src/lib/filter/complex_dotprod_3dnowext64.S @@ -54,7 +54,7 @@ .file "complex_dotprod_3dnowext64.S" - .version "01.01" +// .version "01.01" .text .p2align 4 .globl GLOB_SYMB(complex_dotprod_3dnowext) diff --git a/gnuradio-core/src/lib/filter/complex_dotprod_sse.S b/gnuradio-core/src/lib/filter/complex_dotprod_sse.S index fff1057dd..fb998cc45 100644 --- a/gnuradio-core/src/lib/filter/complex_dotprod_sse.S +++ b/gnuradio-core/src/lib/filter/complex_dotprod_sse.S @@ -56,7 +56,7 @@ .file "complex_dotprod_sse.S" - .version "01.01" +// .version "01.01" .text .p2align 4 .globl GLOB_SYMB(complex_dotprod_sse) diff --git a/gnuradio-core/src/lib/filter/complex_dotprod_sse64.S b/gnuradio-core/src/lib/filter/complex_dotprod_sse64.S index 77f0c3178..67d3519e4 100644 --- a/gnuradio-core/src/lib/filter/complex_dotprod_sse64.S +++ b/gnuradio-core/src/lib/filter/complex_dotprod_sse64.S @@ -56,7 +56,7 @@ .file "complex_dotprod_sse64.S" - .version "01.01" +// .version "01.01" .text .p2align 4 .globl GLOB_SYMB(complex_dotprod_sse) diff --git a/gnuradio-core/src/lib/filter/fcomplex_dotprod_3dnow.S b/gnuradio-core/src/lib/filter/fcomplex_dotprod_3dnow.S index a4e69461e..536e46dc1 100644 --- a/gnuradio-core/src/lib/filter/fcomplex_dotprod_3dnow.S +++ b/gnuradio-core/src/lib/filter/fcomplex_dotprod_3dnow.S @@ -53,7 +53,7 @@ .file "fcomplex_dotprod_3dnow.S" - .version "01.01" +// .version "01.01" .text .p2align 4 .globl GLOB_SYMB(fcomplex_dotprod_3dnow) diff --git a/gnuradio-core/src/lib/filter/fcomplex_dotprod_3dnow64.S b/gnuradio-core/src/lib/filter/fcomplex_dotprod_3dnow64.S index 9bbf56301..d9a695949 100644 --- a/gnuradio-core/src/lib/filter/fcomplex_dotprod_3dnow64.S +++ b/gnuradio-core/src/lib/filter/fcomplex_dotprod_3dnow64.S @@ -53,7 +53,7 @@ .file "fcomplex_dotprod_3dnow64.S" - .version "01.01" +// .version "01.01" .text .p2align 4 .globl GLOB_SYMB(fcomplex_dotprod_3dnow) diff --git a/gnuradio-core/src/lib/filter/fcomplex_dotprod_sse.S b/gnuradio-core/src/lib/filter/fcomplex_dotprod_sse.S index e516f0a61..4c5e956f2 100644 --- a/gnuradio-core/src/lib/filter/fcomplex_dotprod_sse.S +++ b/gnuradio-core/src/lib/filter/fcomplex_dotprod_sse.S @@ -56,7 +56,7 @@ .file "fcomplex_dotprod_sse.S" - .version "01.01" +// .version "01.01" .text .p2align 4 .globl GLOB_SYMB(fcomplex_dotprod_sse) diff --git a/gnuradio-core/src/lib/filter/fcomplex_dotprod_sse64.S b/gnuradio-core/src/lib/filter/fcomplex_dotprod_sse64.S index 605d87130..53a4f25e0 100644 --- a/gnuradio-core/src/lib/filter/fcomplex_dotprod_sse64.S +++ b/gnuradio-core/src/lib/filter/fcomplex_dotprod_sse64.S @@ -56,7 +56,7 @@ .file "fcomplex_dotprod_sse64.S" - .version "01.01" +// .version "01.01" .text .p2align 4 .globl GLOB_SYMB(fcomplex_dotprod_sse) diff --git a/gnuradio-core/src/lib/filter/float_dotprod_3dnow.S b/gnuradio-core/src/lib/filter/float_dotprod_3dnow.S index 914b652af..cdebe9bc3 100644 --- a/gnuradio-core/src/lib/filter/float_dotprod_3dnow.S +++ b/gnuradio-core/src/lib/filter/float_dotprod_3dnow.S @@ -54,7 +54,7 @@ .file "float_dotprod_3dnow.S" - .version "01.01" +// .version "01.01" .text .p2align 4 .globl GLOB_SYMB(float_dotprod_3dnow) diff --git a/gnuradio-core/src/lib/filter/float_dotprod_3dnow64.S b/gnuradio-core/src/lib/filter/float_dotprod_3dnow64.S index 6670553a3..1e859d75a 100644 --- a/gnuradio-core/src/lib/filter/float_dotprod_3dnow64.S +++ b/gnuradio-core/src/lib/filter/float_dotprod_3dnow64.S @@ -54,7 +54,7 @@ .file "float_dotprod_3dnow64.S" - .version "01.01" +// .version "01.01" .text .p2align 4 .globl GLOB_SYMB(float_dotprod_3dnow) diff --git a/gnuradio-core/src/lib/filter/float_dotprod_sse.S b/gnuradio-core/src/lib/filter/float_dotprod_sse.S index beddc75b0..66604526d 100644 --- a/gnuradio-core/src/lib/filter/float_dotprod_sse.S +++ b/gnuradio-core/src/lib/filter/float_dotprod_sse.S @@ -54,7 +54,7 @@ .file "float_dotprod_sse.S" - .version "01.01" +// .version "01.01" .text .p2align 4 .globl GLOB_SYMB(float_dotprod_sse) diff --git a/gnuradio-core/src/lib/filter/float_dotprod_sse64.S b/gnuradio-core/src/lib/filter/float_dotprod_sse64.S index 3d425b26b..0dd0764c5 100644 --- a/gnuradio-core/src/lib/filter/float_dotprod_sse64.S +++ b/gnuradio-core/src/lib/filter/float_dotprod_sse64.S @@ -54,7 +54,7 @@ .file "float_dotprod_sse64.S" - .version "01.01" +// .version "01.01" .text .p2align 4 .globl GLOB_SYMB(float_dotprod_sse) diff --git a/gnuradio-core/src/lib/filter/short_dotprod_mmx.S b/gnuradio-core/src/lib/filter/short_dotprod_mmx.S index 48f634a18..0f6801e4b 100644 --- a/gnuradio-core/src/lib/filter/short_dotprod_mmx.S +++ b/gnuradio-core/src/lib/filter/short_dotprod_mmx.S @@ -37,7 +37,7 @@ .file "short_dotprod_mmx.S" - .version "01.01" +// .version "01.01" .text .p2align 3 .globl GLOB_SYMB(short_dotprod_mmx) diff --git a/gnuradio-core/src/lib/filter/short_dotprod_mmx64.S b/gnuradio-core/src/lib/filter/short_dotprod_mmx64.S index c8c9da30a..bafd0e04e 100644 --- a/gnuradio-core/src/lib/filter/short_dotprod_mmx64.S +++ b/gnuradio-core/src/lib/filter/short_dotprod_mmx64.S @@ -37,7 +37,7 @@ .file "short_dotprod_mmx64.S" - .version "01.01" +// .version "01.01" .text .p2align 3 .globl GLOB_SYMB(short_dotprod_mmx) diff --git a/gnuradio-core/src/lib/general/CMakeLists.txt b/gnuradio-core/src/lib/general/CMakeLists.txt index 3cf7f74e4..4c99acfc3 100644 --- a/gnuradio-core/src/lib/general/CMakeLists.txt +++ b/gnuradio-core/src/lib/general/CMakeLists.txt @@ -187,6 +187,7 @@ set(gr_core_general_triple_threats gr_agc2_ff gr_align_on_samplenumbers_ss gr_bin_statistics_f + gr_block_gateway gr_bytes_to_syms gr_char_to_float gr_char_to_short @@ -298,6 +299,7 @@ set(gr_core_general_triple_threats gr_burst_tagger gr_correlate_access_code_tag_bb gr_tag_debug + gr_message_strobe ) foreach(file_tt ${gr_core_general_triple_threats}) diff --git a/gnuradio-core/src/lib/general/general.i b/gnuradio-core/src/lib/general/general.i index 790549c4d..1446088a2 100644 --- a/gnuradio-core/src/lib/general/general.i +++ b/gnuradio-core/src/lib/general/general.i @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc. + * Copyright 2004-2012 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -143,6 +143,7 @@ #include <gr_add_ff.h> #include <gr_vector_map.h> #include <gr_tag_debug.h> +#include <gr_message_strobe.h> %} %include "gri_control_loop.i" @@ -266,3 +267,5 @@ %include "gr_add_ff.i" %include "gr_vector_map.i" %include "gr_tag_debug.i" +%include "gr_block_gateway.i" +%include "gr_message_strobe.i" diff --git a/gnuradio-core/src/lib/general/gr_block_gateway.cc b/gnuradio-core/src/lib/general/gr_block_gateway.cc new file mode 100644 index 000000000..79b42803a --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_block_gateway.cc @@ -0,0 +1,184 @@ +/* + * Copyright 2011-2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include <gr_block_gateway.h> +#include <gr_io_signature.h> +#include <iostream> +#include <boost/bind.hpp> + +/*********************************************************************** + * Helper routines + **********************************************************************/ +template <typename OutType, typename InType> +void copy_pointers(OutType &out, const InType &in){ + out.resize(in.size()); + for (size_t i = 0; i < in.size(); i++){ + out[i] = (void *)(in[i]); + } +} + +/*********************************************************************** + * The gr_block gateway implementation class + **********************************************************************/ +class gr_block_gateway_impl : public gr_block_gateway{ +public: + gr_block_gateway_impl( + gr_feval_ll *handler, + const std::string &name, + gr_io_signature_sptr in_sig, + gr_io_signature_sptr out_sig, + const gr_block_gw_work_type work_type, + const unsigned factor + ): + gr_block(name, in_sig, out_sig), + _handler(handler), + _work_type(work_type) + { + switch(_work_type){ + case GR_BLOCK_GW_WORK_GENERAL: + _decim = 1; //not relevant, but set anyway + _interp = 1; //not relevant, but set anyway + break; + + case GR_BLOCK_GW_WORK_SYNC: + _decim = 1; + _interp = 1; + this->set_fixed_rate(true); + break; + + case GR_BLOCK_GW_WORK_DECIM: + _decim = factor; + _interp = 1; + break; + + case GR_BLOCK_GW_WORK_INTERP: + _decim = 1; + _interp = factor; + this->set_output_multiple(_interp); + break; + } + } + + /******************************************************************* + * Overloads for various scheduler-called functions + ******************************************************************/ + void forecast( + int noutput_items, + gr_vector_int &ninput_items_required + ){ + switch(_work_type){ + case GR_BLOCK_GW_WORK_GENERAL: + _message.action = gr_block_gw_message_type::ACTION_FORECAST; + _message.forecast_args_noutput_items = noutput_items; + _message.forecast_args_ninput_items_required = ninput_items_required; + _handler->calleval(0); + ninput_items_required = _message.forecast_args_ninput_items_required; + return; + + default: + unsigned ninputs = ninput_items_required.size(); + for (unsigned i = 0; i < ninputs; i++) + ninput_items_required[i] = fixed_rate_noutput_to_ninput(noutput_items); + return; + } + } + + int general_work( + int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items + ){ + switch(_work_type){ + case GR_BLOCK_GW_WORK_GENERAL: + _message.action = gr_block_gw_message_type::ACTION_GENERAL_WORK; + _message.general_work_args_noutput_items = noutput_items; + _message.general_work_args_ninput_items = ninput_items; + copy_pointers(_message.general_work_args_input_items, input_items); + _message.general_work_args_output_items = output_items; + _handler->calleval(0); + return _message.general_work_args_return_value; + + default: + int r = work (noutput_items, input_items, output_items); + if (r > 0) consume_each(r*_decim/_interp); + return r; + } + } + + int work( + int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items + ){ + _message.action = gr_block_gw_message_type::ACTION_WORK; + _message.work_args_ninput_items = fixed_rate_noutput_to_ninput(noutput_items); + if (_message.work_args_ninput_items == 0) return -1; + _message.work_args_noutput_items = noutput_items; + copy_pointers(_message.work_args_input_items, input_items); + _message.work_args_output_items = output_items; + _handler->calleval(0); + return _message.work_args_return_value; + } + + int fixed_rate_noutput_to_ninput(int noutput_items){ + return (noutput_items*_decim/_interp) + history() - 1; + } + + int fixed_rate_ninput_to_noutput(int ninput_items){ + return std::max(0, ninput_items - (int)history() + 1)*_interp/_decim; + } + + bool start(void){ + _message.action = gr_block_gw_message_type::ACTION_START; + _handler->calleval(0); + return _message.start_args_return_value; + } + + bool stop(void){ + _message.action = gr_block_gw_message_type::ACTION_STOP; + _handler->calleval(0); + return _message.stop_args_return_value; + } + + gr_block_gw_message_type &gr_block_message(void){ + return _message; + } + +private: + gr_feval_ll *_handler; + gr_block_gw_message_type _message; + const gr_block_gw_work_type _work_type; + unsigned _decim, _interp; +}; + +boost::shared_ptr<gr_block_gateway> gr_make_block_gateway( + gr_feval_ll *handler, + const std::string &name, + gr_io_signature_sptr in_sig, + gr_io_signature_sptr out_sig, + const gr_block_gw_work_type work_type, + const unsigned factor +){ + return boost::shared_ptr<gr_block_gateway>( + new gr_block_gateway_impl(handler, name, in_sig, out_sig, work_type, factor) + ); +} diff --git a/gnuradio-core/src/lib/general/gr_block_gateway.h b/gnuradio-core/src/lib/general/gr_block_gateway.h new file mode 100644 index 000000000..ae91d41b5 --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_block_gateway.h @@ -0,0 +1,212 @@ +/* + * Copyright 2011-2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GRBLOCK_GATEWAY_H +#define INCLUDED_GRBLOCK_GATEWAY_H + +#include <gr_core_api.h> +#include <gr_block.h> +#include <gr_feval.h> + +/*! + * The work type enum tells the gateway what kind of block to implement. + * The choices are familiar gnuradio block overloads (sync, decim, interp). + */ +enum gr_block_gw_work_type{ + GR_BLOCK_GW_WORK_GENERAL, + GR_BLOCK_GW_WORK_SYNC, + GR_BLOCK_GW_WORK_DECIM, + GR_BLOCK_GW_WORK_INTERP, +}; + +/*! + * Shared message structure between python and gateway. + * Each action type represents a scheduler-called function. + */ +struct gr_block_gw_message_type{ + enum action_type{ + ACTION_GENERAL_WORK, //dispatch work + ACTION_WORK, //dispatch work + ACTION_FORECAST, //dispatch forecast + ACTION_START, //dispatch start + ACTION_STOP, //dispatch stop + }; + + action_type action; + + int general_work_args_noutput_items; + std::vector<int> general_work_args_ninput_items; + std::vector<void *> general_work_args_input_items; //TODO this should be const void*, but swig cant int cast it right + std::vector<void *> general_work_args_output_items; + int general_work_args_return_value; + + int work_args_ninput_items; + int work_args_noutput_items; + std::vector<void *> work_args_input_items; //TODO this should be const void*, but swig cant int cast it right + std::vector<void *> work_args_output_items; + int work_args_return_value; + + int forecast_args_noutput_items; + std::vector<int> forecast_args_ninput_items_required; + + bool start_args_return_value; + + bool stop_args_return_value; +}; + +/*! + * The gateway block which performs all the magic. + * + * The gateway provides access to all the gr_block routines. + * The methods prefixed with gr_block__ are renamed + * to class methods without the prefix in python. + */ +class GR_CORE_API gr_block_gateway : virtual public gr_block{ +public: + //! Provide access to the shared message object + virtual gr_block_gw_message_type &gr_block_message(void) = 0; + + long gr_block__unique_id(void) const{ + return gr_block::unique_id(); + } + + std::string gr_block__name(void) const{ + return gr_block::name(); + } + + unsigned gr_block__history(void) const{ + return gr_block::history(); + } + + void gr_block__set_history(unsigned history){ + return gr_block::set_history(history); + } + + void gr_block__set_fixed_rate(bool fixed_rate){ + return gr_block::set_fixed_rate(fixed_rate); + } + + bool gr_block__fixed_rate(void) const{ + return gr_block::fixed_rate(); + } + + void gr_block__set_output_multiple(int multiple){ + return gr_block::set_output_multiple(multiple); + } + + int gr_block__output_multiple(void) const{ + return gr_block::output_multiple(); + } + + void gr_block__consume(int which_input, int how_many_items){ + return gr_block::consume(which_input, how_many_items); + } + + void gr_block__consume_each(int how_many_items){ + return gr_block::consume_each(how_many_items); + } + + void gr_block__produce(int which_output, int how_many_items){ + return gr_block::produce(which_output, how_many_items); + } + + void gr_block__set_relative_rate(double relative_rate){ + return gr_block::set_relative_rate(relative_rate); + } + + double gr_block__relative_rate(void) const{ + return gr_block::relative_rate(); + } + + uint64_t gr_block__nitems_read(unsigned int which_input){ + return gr_block::nitems_read(which_input); + } + + uint64_t gr_block__nitems_written(unsigned int which_output){ + return gr_block::nitems_written(which_output); + } + + gr_block::tag_propagation_policy_t gr_block__tag_propagation_policy(void){ + return gr_block::tag_propagation_policy(); + } + + void gr_block__set_tag_propagation_policy(gr_block::tag_propagation_policy_t p){ + return gr_block::set_tag_propagation_policy(p); + } + + void gr_block__add_item_tag( + unsigned int which_output, const gr_tag_t &tag + ){ + return gr_block::add_item_tag(which_output, tag); + } + + void gr_block__add_item_tag( + unsigned int which_output, + uint64_t abs_offset, + const pmt::pmt_t &key, + const pmt::pmt_t &value, + const pmt::pmt_t &srcid=pmt::PMT_F + ){ + return gr_block::add_item_tag(which_output, abs_offset, key, value, srcid); + } + + std::vector<gr_tag_t> gr_block__get_tags_in_range( + unsigned int which_input, + uint64_t abs_start, + uint64_t abs_end + ){ + std::vector<gr_tag_t> tags; + gr_block::get_tags_in_range(tags, which_input, abs_start, abs_end); + return tags; + } + + std::vector<gr_tag_t> gr_block__get_tags_in_range( + unsigned int which_input, + uint64_t abs_start, + uint64_t abs_end, + const pmt::pmt_t &key + ){ + std::vector<gr_tag_t> tags; + gr_block::get_tags_in_range(tags, which_input, abs_start, abs_end, key); + return tags; + } +}; + +/*! + * Make a new gateway block. + * \param handler the swig director object with callback + * \param name the name of the block (Ex: "Shirley") + * \param in_sig the input signature for this block + * \param out_sig the output signature for this block + * \param work_type the type of block overload to implement + * \param factor the decimation or interpolation factor + * \return a new gateway block + */ +GR_CORE_API boost::shared_ptr<gr_block_gateway> gr_make_block_gateway( + gr_feval_ll *handler, + const std::string &name, + gr_io_signature_sptr in_sig, + gr_io_signature_sptr out_sig, + const gr_block_gw_work_type work_type, + const unsigned factor +); + +#endif /* INCLUDED_GRBLOCK_GATEWAY_H */ diff --git a/gnuradio-core/src/lib/general/gr_block_gateway.i b/gnuradio-core/src/lib/general/gr_block_gateway.i new file mode 100644 index 000000000..8adafdfea --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_block_gateway.i @@ -0,0 +1,46 @@ +/* + * Copyright 2011-2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +//////////////////////////////////////////////////////////////////////// +// standard includes +//////////////////////////////////////////////////////////////////////// +%include <gnuradio.i> +%include <gr_tags.i> +%include <gr_feval.i> + +//////////////////////////////////////////////////////////////////////// +// block headers +//////////////////////////////////////////////////////////////////////// +%{ +#include <gr_block_gateway.h> +%} + +//////////////////////////////////////////////////////////////////////// +// data type support +//////////////////////////////////////////////////////////////////////// +%template(int_vector_t) std::vector<int>; +%template(void_star_vector_t) std::vector<void *>; + +//////////////////////////////////////////////////////////////////////// +// block magic +//////////////////////////////////////////////////////////////////////// +GR_SWIG_BLOCK_MAGIC(gr,block_gateway); +%include <gr_block_gateway.h> diff --git a/gnuradio-core/src/lib/general/gr_message_strobe.cc b/gnuradio-core/src/lib/general/gr_message_strobe.cc new file mode 100644 index 000000000..6a9f807d1 --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_message_strobe.cc @@ -0,0 +1,75 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gr_message_strobe.h> +#include <gr_io_signature.h> +#include <cstdio> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <stdexcept> +#include <string.h> +#include <iostream> + +// public constructor that returns a shared_ptr + +gr_message_strobe_sptr +gr_make_message_strobe (pmt::pmt_t msg, float period_ms) +{ + return gnuradio::get_initial_sptr(new gr_message_strobe(msg, period_ms)); +} + +gr_message_strobe::gr_message_strobe (pmt::pmt_t msg, float period_ms) + : gr_block("message_strobe", + gr_make_io_signature(0, 0, 0), + gr_make_io_signature(0, 0, 0)), + d_finished(false), + d_period_ms(period_ms), + d_msg(msg) +{ + message_port_register_out(pmt::mp("strobe")); + d_thread = boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&gr_message_strobe::run, this))); + + message_port_register_in(pmt::mp("set_msg")); + set_msg_handler(pmt::mp("set_msg"), boost::bind(&gr_message_strobe::set_msg, this, _1)); +} + +gr_message_strobe::~gr_message_strobe() +{ + d_finished = true; + d_thread->interrupt(); + d_thread->join(); +} + +void gr_message_strobe::run(){ + while(!d_finished) { + boost::this_thread::sleep(boost::posix_time::milliseconds(d_period_ms)); + if(d_finished){ return; } + + message_port_pub( pmt::mp("strobe"), d_msg ); + } +} diff --git a/gnuradio-core/src/lib/general/gr_message_strobe.h b/gnuradio-core/src/lib/general/gr_message_strobe.h new file mode 100644 index 000000000..89046ffc0 --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_message_strobe.h @@ -0,0 +1,62 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_MESSAGE_STROBE_H +#define INCLUDED_GR_MESSAGE_STROBE_H + +#include <gr_core_api.h> +#include <gr_block.h> +#include <gr_message.h> +#include <gr_msg_queue.h> + +class gr_message_strobe; +typedef boost::shared_ptr<gr_message_strobe> gr_message_strobe_sptr; + +GR_CORE_API gr_message_strobe_sptr gr_make_message_strobe (pmt::pmt_t msg, float period_ms); + +/*! + * \brief Send message at defined interval + * \ingroup msg_blk + */ +class GR_CORE_API gr_message_strobe : public gr_block +{ + private: + friend GR_CORE_API gr_message_strobe_sptr + gr_make_message_strobe(pmt::pmt_t msg, float period_ms); + + boost::shared_ptr<boost::thread> d_thread; + bool d_finished; + float d_period_ms; + pmt::pmt_t d_msg; + + void run(); + + protected: + gr_message_strobe (pmt::pmt_t msg, float period_ms); + + public: + ~gr_message_strobe (); + + void set_msg(pmt::pmt_t msg){ d_msg = msg; } +}; + +#endif /* INCLUDED_GR_MESSAGE_STROBE_H */ diff --git a/gnuradio-core/src/lib/general/gr_message_strobe.i b/gnuradio-core/src/lib/general/gr_message_strobe.i new file mode 100644 index 000000000..490aa8e8a --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_message_strobe.i @@ -0,0 +1,30 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +GR_SWIG_BLOCK_MAGIC(gr,message_strobe); + +%{ +#include <gr_message_strobe.h> +%} + +%include "gr_message_strobe.h" + diff --git a/gnuradio-core/src/lib/general/gr_nop.cc b/gnuradio-core/src/lib/general/gr_nop.cc index ca5983c39..edfe1d76d 100644 --- a/gnuradio-core/src/lib/general/gr_nop.cc +++ b/gnuradio-core/src/lib/general/gr_nop.cc @@ -40,7 +40,8 @@ gr_nop::gr_nop (size_t sizeof_stream_item) d_nmsgs_recvd(0) { // Arrange to have count_received_msgs called when messages are received. - set_msg_handler(boost::bind(&gr_nop::count_received_msgs, this, _1)); + message_port_register_in(pmt::mp("port")); + set_msg_handler(pmt::mp("port"), boost::bind(&gr_nop::count_received_msgs, this, _1)); } // Trivial message handler that just counts them. diff --git a/gnuradio-core/src/lib/general/gr_simple_correlator.cc b/gnuradio-core/src/lib/general/gr_simple_correlator.cc index 9c2ebef15..b9209e74f 100644 --- a/gnuradio-core/src/lib/general/gr_simple_correlator.cc +++ b/gnuradio-core/src/lib/general/gr_simple_correlator.cc @@ -158,11 +158,13 @@ gr_simple_correlator::general_work (int noutput_items, int decision; int hamming_dist; +#ifdef DEBUG_SIMPLE_CORRELATOR struct debug_data { float raw_data; float sampled; float enter_locked; } debug_data; +#endif while (n < nin){ @@ -212,7 +214,9 @@ gr_simple_correlator::general_work (int noutput_items, else if (d_state == ST_UNDER_THRESHOLD && hamming_dist > THRESHOLD){ // no longer seeing good PN code, compute center of goodness enter_locked (); +#ifdef DEBUG_SIMPLE_CORRELATOR debug_data.enter_locked = 1.0; +#endif } break; diff --git a/gnuradio-core/src/lib/general/gr_skiphead.cc b/gnuradio-core/src/lib/general/gr_skiphead.cc index c887376e4..7b441bea9 100644 --- a/gnuradio-core/src/lib/general/gr_skiphead.cc +++ b/gnuradio-core/src/lib/general/gr_skiphead.cc @@ -43,14 +43,14 @@ gr_make_skiphead (size_t itemsize, uint64_t nitems_to_skip) int gr_skiphead::general_work(int noutput_items, - gr_vector_int &ninput_items_ignored, + gr_vector_int &ninput_items_, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { const char *in = (const char *) input_items[0]; char *out = (char *) output_items[0]; - int ninput_items = noutput_items; // we've got at least this many input items + int ninput_items = std::min(ninput_items_[0], noutput_items); int ii = 0; // input index while (ii < ninput_items){ diff --git a/gnuradio-core/src/lib/general/gr_tag_debug.cc b/gnuradio-core/src/lib/general/gr_tag_debug.cc index c4031f438..ecf1b65e1 100644 --- a/gnuradio-core/src/lib/general/gr_tag_debug.cc +++ b/gnuradio-core/src/lib/general/gr_tag_debug.cc @@ -65,10 +65,11 @@ gr_tag_debug::work(int noutput_items, { gruel::scoped_lock l(d_mutex); + std::stringstream sout; if(d_display) { - std::cout << std::endl - << "----------------------------------------------------------------------"; - std::cout << std::endl << "Tag Debug: " << d_name << std::endl; + sout << std::endl + << "----------------------------------------------------------------------"; + sout << std::endl << "Tag Debug: " << d_name << std::endl; } uint64_t abs_N, end_N; @@ -80,20 +81,23 @@ gr_tag_debug::work(int noutput_items, get_tags_in_range(d_tags, i, abs_N, end_N); if(d_display) { - std::cout << "Input Stream: " << i << std::endl; + sout << "Input Stream: " << std::setw(2) << std::setfill('0') << i << std::setfill(' ') << std::endl; for(d_tags_itr = d_tags.begin(); d_tags_itr != d_tags.end(); d_tags_itr++) { - std::cout << std::setw(10) << "Offset: " << d_tags_itr->offset - << std::setw(10) << "Source: " << pmt::pmt_symbol_to_string(d_tags_itr->srcid) - << std::setw(10) << "Key: " << pmt::pmt_symbol_to_string(d_tags_itr->key) - << std::setw(10) << "Value: "; - pmt::pmt_print(d_tags_itr->value); + sout << std::setw(10) << "Offset: " << d_tags_itr->offset + << std::setw(10) << "Source: " << (pmt::pmt_is_symbol(d_tags_itr->srcid) ? pmt::pmt_symbol_to_string(d_tags_itr->srcid) : "n/a") + << std::setw(10) << "Key: " << pmt::pmt_symbol_to_string(d_tags_itr->key) + << std::setw(10) << "Value: "; + sout << d_tags_itr->value << std::endl; } } } if(d_display) { - std::cout << "----------------------------------------------------------------------"; - std::cout << std::endl; + sout << "----------------------------------------------------------------------"; + sout << std::endl; + + if(d_tags.size() > 0) + std::cout << sout.str(); } return noutput_items; diff --git a/gnuradio-core/src/lib/general/gri_control_loop.cc b/gnuradio-core/src/lib/general/gri_control_loop.cc index 5a93737f9..bb3c4a326 100644 --- a/gnuradio-core/src/lib/general/gri_control_loop.cc +++ b/gnuradio-core/src/lib/general/gri_control_loop.cc @@ -144,6 +144,17 @@ gri_control_loop::set_phase(float phase) d_phase += M_TWOPI; } +void +gri_control_loop::set_max_freq(float freq) +{ + d_max_freq = freq; +} + +void +gri_control_loop::set_min_freq(float freq) +{ + d_min_freq = freq; +} /******************************************************************* GET FUNCTIONS @@ -185,3 +196,15 @@ gri_control_loop::get_phase() const { return d_phase; } + +float +gri_control_loop::get_max_freq() const +{ + return d_max_freq; +} + +float +gri_control_loop::get_min_freq() const +{ + return d_min_freq; +} diff --git a/gnuradio-core/src/lib/general/gri_control_loop.h b/gnuradio-core/src/lib/general/gri_control_loop.h index df260d2cf..304857ac7 100644 --- a/gnuradio-core/src/lib/general/gri_control_loop.h +++ b/gnuradio-core/src/lib/general/gri_control_loop.h @@ -141,9 +141,9 @@ class GR_CORE_API gri_control_loop void set_beta(float beta); /*! - * \brief Set the Costas loop's frequency. + * \brief Set the control loop's frequency. * - * Set's the Costas Loop's frequency. While this is normally updated by the + * Set's the control loop's frequency. While this is normally updated by the * inner loop of the algorithm, it could be useful to manually initialize, * set, or reset this under certain circumstances. * @@ -153,9 +153,9 @@ class GR_CORE_API gri_control_loop void set_frequency(float freq); /*! - * \brief Set the Costas loop's phase. + * \brief Set the control loop's phase. * - * Set's the Costas Loop's phase. While this is normally updated by the + * Set's the control loop's phase. While this is normally updated by the * inner loop of the algorithm, it could be useful to manually initialize, * set, or reset this under certain circumstances. * @@ -164,6 +164,23 @@ class GR_CORE_API gri_control_loop */ void set_phase(float phase); + /*! + * \brief Set the control loop's maximum frequency. + * + * Set the maximum frequency the control loop can track. + * + * \param freq (float) new max frequency + */ + void set_max_freq(float freq); + + /*! + * \brief Set the control loop's minimum frequency. + * + * Set the minimum frequency the control loop can track. + * + * \param freq (float) new min frequency + */ + void set_min_freq(float freq); /******************************************************************* GET FUNCTIONS @@ -190,14 +207,24 @@ class GR_CORE_API gri_control_loop float get_beta() const; /*! - * \brief Get the Costas loop's frequency estimate + * \brief Get the control loop's frequency estimate */ float get_frequency() const; /*! - * \brief Get the Costas loop's phase estimate + * \brief Get the control loop's phase estimate */ float get_phase() const; + + /*! + * \brief Get the control loop's maximum frequency. + */ + float get_max_freq() const; + + /*! + * \brief Get the control loop's minimum frequency. + */ + float get_min_freq() const; }; #endif /* GRI_CONTROL_LOOP */ diff --git a/gnuradio-core/src/lib/gengen/gr_vector_insert_X.cc.t b/gnuradio-core/src/lib/gengen/gr_vector_insert_X.cc.t index 37963cdfe..20968afe2 100644 --- a/gnuradio-core/src/lib/gengen/gr_vector_insert_X.cc.t +++ b/gnuradio-core/src/lib/gengen/gr_vector_insert_X.cc.t @@ -44,7 +44,7 @@ // some sanity checks assert(offset < periodicity); assert(offset >= 0); - assert(periodicity > data.size()); + assert((size_t)periodicity > data.size()); } int diff --git a/gnuradio-core/src/lib/io/CMakeLists.txt b/gnuradio-core/src/lib/io/CMakeLists.txt index 3dea13396..59ca06b5a 100644 --- a/gnuradio-core/src/lib/io/CMakeLists.txt +++ b/gnuradio-core/src/lib/io/CMakeLists.txt @@ -38,6 +38,8 @@ list(APPEND gnuradio_core_sources ${CMAKE_CURRENT_SOURCE_DIR}/microtune_xxxx.cc ${CMAKE_CURRENT_SOURCE_DIR}/ppio_ppdev.cc ${CMAKE_CURRENT_SOURCE_DIR}/gri_wavfile.cc + ${CMAKE_CURRENT_SOURCE_DIR}/gr_pdu.cc + ${CMAKE_CURRENT_SOURCE_DIR}/gr_stream_pdu_base.cc ) ######################################################################## @@ -59,6 +61,8 @@ install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/microtune_xxxx.h ${CMAKE_CURRENT_SOURCE_DIR}/ppio_ppdev.h ${CMAKE_CURRENT_SOURCE_DIR}/gri_wavfile.h + ${CMAKE_CURRENT_SOURCE_DIR}/gr_pdu.h + ${CMAKE_CURRENT_SOURCE_DIR}/gr_stream_pdu_base.h DESTINATION ${GR_INCLUDE_DIR}/gnuradio COMPONENT "core_devel" ) @@ -85,9 +89,11 @@ set(gr_core_io_triple_threats gr_file_source gr_file_descriptor_sink gr_file_descriptor_source + gr_message_debug gr_message_sink gr_message_source gr_message_burst_source + gr_pdu_to_tagged_stream microtune_xxxx_eval_board microtune_4702_eval_board microtune_4937_eval_board @@ -98,6 +104,9 @@ set(gr_core_io_triple_threats gr_wavfile_source gr_wavfile_sink gr_tagged_file_sink + gr_tagged_stream_to_pdu + gr_tuntap_pdu + gr_socket_pdu ) foreach(file_tt ${gr_core_io_triple_threats}) diff --git a/gnuradio-core/src/lib/io/gr_file_sink.cc b/gnuradio-core/src/lib/io/gr_file_sink.cc index 5d147fcfe..10c8360cb 100644 --- a/gnuradio-core/src/lib/io/gr_file_sink.cc +++ b/gnuradio-core/src/lib/io/gr_file_sink.cc @@ -42,8 +42,6 @@ gr_file_sink::gr_file_sink(size_t itemsize, const char *filename) gr_file_sink_base(filename, true), d_itemsize(itemsize) { - if (!open(filename)) - throw std::runtime_error ("can't open file"); } gr_file_sink::~gr_file_sink () @@ -55,23 +53,32 @@ gr_file_sink::work (int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { - char *inbuf = (char *) input_items[0]; + char *inbuf = (char*)input_items[0]; int nwritten = 0; do_update(); // update d_fp is reqd - if (!d_fp) + if(!d_fp) return noutput_items; // drop output on the floor - while (nwritten < noutput_items){ - int count = fwrite (inbuf, d_itemsize, noutput_items - nwritten, d_fp); - if (count == 0) // FIXME add error handling - break; + while(nwritten < noutput_items) { + int count = fwrite(inbuf, d_itemsize, noutput_items - nwritten, d_fp); + if(count == 0) { + if(ferror(d_fp)) { + std::stringstream s; + s << "file_sink write failed with error " << fileno(d_fp) << std::endl; + throw std::runtime_error(s.str()); + } + else { // is EOF + break; + } + } nwritten += count; inbuf += count * d_itemsize; } - if (d_unbuffered) - fflush (d_fp); + + if(d_unbuffered) + fflush (d_fp); return nwritten; } diff --git a/gnuradio-core/src/lib/io/gr_file_sink_base.cc b/gnuradio-core/src/lib/io/gr_file_sink_base.cc index b2dcc1be5..d0aca418e 100644 --- a/gnuradio-core/src/lib/io/gr_file_sink_base.cc +++ b/gnuradio-core/src/lib/io/gr_file_sink_base.cc @@ -79,7 +79,6 @@ gr_file_sink_base::open(const char *filename) perror (filename); return false; } - if (d_new_fp){ // if we've already got a new one open, close it fclose(d_new_fp); d_new_fp = 0; @@ -122,5 +121,5 @@ gr_file_sink_base::do_update() void gr_file_sink_base::set_unbuffered(bool unbuffered) { - d_unbuffered = unbuffered; + d_unbuffered = unbuffered; } diff --git a/gnuradio-core/src/lib/io/gr_file_source.cc b/gnuradio-core/src/lib/io/gr_file_source.cc index 3f06a8244..09f3986cd 100644 --- a/gnuradio-core/src/lib/io/gr_file_source.cc +++ b/gnuradio-core/src/lib/io/gr_file_source.cc @@ -49,24 +49,14 @@ #define OUR_O_LARGEFILE 0 #endif -gr_file_source::gr_file_source (size_t itemsize, const char *filename, bool repeat) - : gr_sync_block ("file_source", - gr_make_io_signature (0, 0, 0), - gr_make_io_signature (1, 1, itemsize)), - d_itemsize (itemsize), d_fp (0), d_repeat (repeat) +gr_file_source::gr_file_source(size_t itemsize, const char *filename, bool repeat) + : gr_sync_block("file_source", + gr_make_io_signature (0, 0, 0), + gr_make_io_signature (1, 1, itemsize)), + d_itemsize(itemsize), d_fp(0), d_new_fp (0), d_repeat(repeat), + d_updated(false) { - // we use "open" to use to the O_LARGEFILE flag - - int fd; - if ((fd = open (filename, O_RDONLY | OUR_O_LARGEFILE | OUR_O_BINARY)) < 0){ - perror (filename); - throw std::runtime_error ("can't open file"); - } - - if ((d_fp = fdopen (fd, "rb")) == NULL){ - perror (filename); - throw std::runtime_error ("can't open file"); - } + open(filename, repeat); } // public constructor that returns a shared_ptr @@ -79,7 +69,11 @@ gr_make_file_source (size_t itemsize, const char *filename, bool repeat) gr_file_source::~gr_file_source () { - fclose ((FILE *) d_fp); + close(); + if(d_fp) { + fclose(d_fp); + d_fp = 0; + } } int @@ -91,6 +85,11 @@ gr_file_source::work (int noutput_items, int i; int size = noutput_items; + do_update(); // update d_fp is reqd + if(d_fp == NULL) + throw std::runtime_error("work with file not open"); + + boost::mutex::scoped_lock lock(fp_mutex); // hold for the rest of this function while (size) { i = fread(o, d_itemsize, size, (FILE *) d_fp); @@ -111,8 +110,9 @@ gr_file_source::work (int noutput_items, break; if (fseek ((FILE *) d_fp, 0, SEEK_SET) == -1) { - fprintf(stderr, "[%s] fseek failed\n", __FILE__); - exit(-1); + std::stringstream s; + s << "[" << __FILE__ << "]" << " fseek failed" << std::endl; + throw std::runtime_error(s.str()); } } @@ -128,5 +128,64 @@ gr_file_source::work (int noutput_items, bool gr_file_source::seek (long seek_point, int whence) { - return fseek ((FILE *) d_fp, seek_point * d_itemsize, whence) == 0; + // obtain exclusive access for duration of this function + boost::mutex::scoped_lock lock(fp_mutex); + return fseek((FILE *) d_fp, seek_point * d_itemsize, whence) == 0; +} + +void +gr_file_source::open(const char *filename, bool repeat) +{ + // obtain exclusive access for duration of this function + boost::mutex::scoped_lock lock(fp_mutex); + + int fd; + + // we use "open" to use to the O_LARGEFILE flag + if((fd = ::open(filename, O_RDONLY | OUR_O_LARGEFILE | OUR_O_BINARY)) < 0) { + perror(filename); + throw std::runtime_error("can't open file"); + } + + if(d_new_fp) { + fclose(d_new_fp); + d_new_fp = 0; + } + + if((d_new_fp = fdopen (fd, "rb")) == NULL) { + perror(filename); + ::close(fd); // don't leak file descriptor if fdopen fails + throw std::runtime_error("can't open file"); + } + + d_updated = true; + d_repeat = repeat; +} + +void +gr_file_source::close() +{ + // obtain exclusive access for duration of this function + boost::mutex::scoped_lock lock(fp_mutex); + + if(d_new_fp != NULL) { + fclose(d_new_fp); + d_new_fp = NULL; + } + d_updated = true; +} + +void +gr_file_source::do_update() +{ + if(d_updated) { + boost::mutex::scoped_lock lock(fp_mutex); // hold while in scope + + if(d_fp) + fclose(d_fp); + + d_fp = d_new_fp; // install new file pointer + d_new_fp = 0; + d_updated = false; + } } diff --git a/gnuradio-core/src/lib/io/gr_file_source.h b/gnuradio-core/src/lib/io/gr_file_source.h index 1cc44a3b1..0478fba04 100644 --- a/gnuradio-core/src/lib/io/gr_file_source.h +++ b/gnuradio-core/src/lib/io/gr_file_source.h @@ -25,6 +25,7 @@ #include <gr_core_api.h> #include <gr_sync_block.h> +#include <boost/thread/mutex.hpp> class gr_file_source; typedef boost::shared_ptr<gr_file_source> gr_file_source_sptr; @@ -39,31 +40,68 @@ gr_make_file_source (size_t itemsize, const char *filename, bool repeat = false) class GR_CORE_API gr_file_source : public gr_sync_block { - friend GR_CORE_API gr_file_source_sptr gr_make_file_source (size_t itemsize, - const char *filename, - bool repeat); private: - size_t d_itemsize; - void *d_fp; - bool d_repeat; + size_t d_itemsize; + FILE *d_fp; + FILE *d_new_fp; + bool d_repeat; + bool d_updated; protected: - gr_file_source (size_t itemsize, const char *filename, bool repeat); + gr_file_source(size_t itemsize, const char *filename, bool repeat); + + void do_update(); + + boost::mutex fp_mutex; public: - ~gr_file_source (); + /*! + * \brief Create a file source. + * + * Opens \p filename as a source of items into a flowgraph. The data + * is expected to be in binary format, item after item. The \p + * itemsize of the block determines the conversion from bits to + * items. + * + * If \p repeat is turned on, the file will repeat the file after + * it's reached the end. + * + * \param itemsize the size of each item in the file, in bytes + * \param filename name of the file to source from + * \param repeat repeat file from start + */ + friend GR_CORE_API gr_file_source_sptr + gr_make_file_source(size_t itemsize, + const char *filename, + bool repeat); + + ~gr_file_source(); - int work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); /*! - * \brief seek file to \p seek_point relative to \p whence + * \brief Seek file to \p seek_point relative to \p whence * * \param seek_point sample offset in file * \param whence one of SEEK_SET, SEEK_CUR, SEEK_END (man fseek) */ - bool seek (long seek_point, int whence); + bool seek(long seek_point, int whence); + + /*! + * \brief Opens a new file. + * + * \param filename name of the file to source from + * \param repeat repeat file from start + */ + void open(const char *filename, bool repeat); + + /*! + * \brief Close the file handle. + */ + void close(); + }; #endif /* INCLUDED_GR_FILE_SOURCE_H */ diff --git a/gnuradio-core/src/lib/io/gr_file_source.i b/gnuradio-core/src/lib/io/gr_file_source.i index 9bf44691d..e71cef0d1 100644 --- a/gnuradio-core/src/lib/io/gr_file_source.i +++ b/gnuradio-core/src/lib/io/gr_file_source.i @@ -40,4 +40,6 @@ class gr_file_source : public gr_sync_block ~gr_file_source (); bool seek (long seek_point, int whence); + void open (const char *filename, bool repeat); + void close(); }; diff --git a/gnuradio-core/src/lib/io/gr_message_debug.cc b/gnuradio-core/src/lib/io/gr_message_debug.cc new file mode 100644 index 000000000..27f4c65fd --- /dev/null +++ b/gnuradio-core/src/lib/io/gr_message_debug.cc @@ -0,0 +1,117 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2010,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gr_message_debug.h> +#include <gr_io_signature.h> +#include <cstdio> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <stdexcept> +#include <string.h> +#include <iostream> + +// public constructor that returns a shared_ptr + +gr_message_debug_sptr +gr_make_message_debug () +{ + return gnuradio::get_initial_sptr(new gr_message_debug()); +} + +void +gr_message_debug::print(pmt::pmt_t msg) +{ + std::cout << "******* MESSAGE DEBUG PRINT ********\n"; + pmt::pmt_print(msg); + std::cout << "************************************\n"; +} + +void +gr_message_debug::store(pmt::pmt_t msg) +{ + gruel::scoped_lock guard(d_mutex); + d_messages.push_back(msg); +} + +void +gr_message_debug::print_verbose(pmt::pmt_t msg) +{ + pmt::pmt_t meta = pmt::pmt_car(msg); + pmt::pmt_t vector = pmt::pmt_cdr(msg); + std::cout << "* MESSAGE DEBUG PRINT PDU VERBOSE *\n"; + pmt::pmt_print(meta); + size_t len = pmt::pmt_length(vector); + std::cout << "pdu_length = " << len << std::endl; + std::cout << "contents = " << std::endl; + size_t offset(0); + const uint8_t* d = (const uint8_t*) pmt_uniform_vector_elements(vector, offset); + for(size_t i=0; i<len; i+=16){ + printf("%04x: ", i); + for(size_t j=i; j<std::min(i+16,len); j++){ + printf("%02x ",d[j] ); + } + + std::cout << std::endl; + } + + std::cout << "***********************************\n"; +} + +int +gr_message_debug::num_messages() +{ + return (int)d_messages.size(); +} + +pmt::pmt_t +gr_message_debug::get_message(int i) +{ + gruel::scoped_lock guard(d_mutex); + + if((size_t)i >= d_messages.size()) { + throw std::runtime_error("gr_message_debug: index for message out of bounds.\n"); + } + + return d_messages[i]; +} + +gr_message_debug::gr_message_debug() + : gr_block("message_debug", + gr_make_io_signature(0, 0, 0), + gr_make_io_signature(0, 0, 0)) +{ + message_port_register_in(pmt::mp("print")); + set_msg_handler(pmt::mp("print"), boost::bind(&gr_message_debug::print, this, _1)); + + message_port_register_in(pmt::mp("store")); + set_msg_handler(pmt::mp("store"), boost::bind(&gr_message_debug::store, this, _1)); +} + +gr_message_debug::~gr_message_debug() +{ +} diff --git a/gnuradio-core/src/lib/io/gr_message_debug.h b/gnuradio-core/src/lib/io/gr_message_debug.h new file mode 100644 index 000000000..6e6e5103c --- /dev/null +++ b/gnuradio-core/src/lib/io/gr_message_debug.h @@ -0,0 +1,103 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_MESSAGE_DEBUG_H +#define INCLUDED_GR_MESSAGE_DEBUG_H + +#include <gr_core_api.h> +#include <gr_block.h> +#include <gr_message.h> +#include <gr_msg_queue.h> +#include <gruel/thread.h> + +class gr_message_debug; +typedef boost::shared_ptr<gr_message_debug> gr_message_debug_sptr; + +GR_CORE_API gr_message_debug_sptr gr_make_message_debug(); + +/*! + * \brief Print received messages to stdout + * \ingroup sink_blk + */ +class GR_CORE_API gr_message_debug : public gr_block +{ + private: + friend GR_CORE_API gr_message_debug_sptr + gr_make_message_debug(); + + /*! + * \brief Messages received in this port are printed to stdout. + * + * This port receives messages from the scheduler's message handling + * mechanism and prints it to stdout. This message handler function + * is only meant to be used by the scheduler to handle messages + * posted to port 'print'. + * + * \param msg A pmt message passed from the scheduler's message handling. + */ + void print(pmt::pmt_t msg); + void print_verbose(pmt::pmt_t msg); + + /*! + * \brief Messages received in this port are stored in a vector. + * + * This port receives messages from the scheduler's message handling + * mechanism and stores it in a vector. Messages can be retrieved + * later using the 'get_message' function. This message handler + * function is only meant to be used by the scheduler to handle + * messages posted to port 'store'. + * + * \param msg A pmt message passed from the scheduler's message handling. + */ + void store(pmt::pmt_t msg); + + gruel::mutex d_mutex; + std::vector<pmt::pmt_t> d_messages; + + protected: + gr_message_debug (); + + public: + ~gr_message_debug (); + + /*! + * \brief Reports the number of messages received by this block. + */ + int num_messages(); + + /*! + * \brief Get a message (as a PMT) from the message vector at index \p i. + * + * Messages passed to the 'store' port will be stored in a + * vector. This function retrieves those messages by index. They are + * index in order of when they were received (all messages are just + * pushed onto the back of a vector). This is mostly useful in + * debugging message passing graphs and in QA code. + * + * \param i The index in the vector for the message to retrieve. + * + * \return a message at index \p i as a pmt_t. + */ + pmt::pmt_t get_message(int i); +}; + +#endif /* INCLUDED_GR_MESSAGE_DEBUG_H */ diff --git a/gnuradio-core/src/lib/io/gr_message_debug.i b/gnuradio-core/src/lib/io/gr_message_debug.i new file mode 100644 index 000000000..65d3bfc4a --- /dev/null +++ b/gnuradio-core/src/lib/io/gr_message_debug.i @@ -0,0 +1,30 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +GR_SWIG_BLOCK_MAGIC(gr,message_debug); + +%{ +#include <gr_message_debug.h> +%} + +%include "gr_message_debug.h" + diff --git a/gnuradio-core/src/lib/io/gr_pdu.cc b/gnuradio-core/src/lib/io/gr_pdu.cc new file mode 100644 index 000000000..302fd7b9b --- /dev/null +++ b/gnuradio-core/src/lib/io/gr_pdu.cc @@ -0,0 +1,79 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gr_pdu.h> + +size_t +gr_pdu_itemsize(gr_pdu_vector_type type){ + switch(type){ + case pdu_byte: + return 1; + case pdu_float: + return sizeof(float); + case pdu_complex: + return sizeof(gr_complex); + default: + throw std::runtime_error("bad type!"); + } +} + +bool +gr_pdu_type_matches(gr_pdu_vector_type type, pmt::pmt_t v){ + switch(type){ + case pdu_byte: + return pmt::pmt_is_u8vector(v); + case pdu_float: + return pmt::pmt_is_f32vector(v); + case pdu_complex: + return pmt::pmt_is_c32vector(v); + default: + throw std::runtime_error("bad type!"); + } +} + +pmt::pmt_t +gr_pdu_make_vector(gr_pdu_vector_type type, const uint8_t* buf, size_t items){ + switch(type){ + case pdu_byte: + return pmt::pmt_init_u8vector(items, buf); + case pdu_float: + return pmt::pmt_init_f32vector(items, (const float*)buf); + case pdu_complex: + return pmt::pmt_init_c32vector(items, (const gr_complex*)buf); + default: + throw std::runtime_error("bad type!"); + } +} + +gr_pdu_vector_type type_from_pmt(pmt::pmt_t vector){ + if(pmt_is_u8vector(vector)) + return pdu_byte; + if(pmt_is_f32vector(vector)) + return pdu_float; + if(pmt_is_c32vector(vector)) + return pdu_complex; + throw std::runtime_error("bad type!"); +} diff --git a/gnuradio-core/src/lib/io/gr_pdu.h b/gnuradio-core/src/lib/io/gr_pdu.h new file mode 100644 index 000000000..a5ae87db7 --- /dev/null +++ b/gnuradio-core/src/lib/io/gr_pdu.h @@ -0,0 +1,39 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef GR_PDU_H +#define GR_PDU_H + +#include <gr_complex.h> +#include <gruel/pmt.h> + +#define pdu_port_id pmt::mp("pdus") +#define pdu_length_tag pmt::mp("pdu_length") + +enum gr_pdu_vector_type { pdu_byte, pdu_float, pdu_complex }; + +size_t gr_pdu_itemsize(gr_pdu_vector_type type); +bool gr_pdu_type_matches(gr_pdu_vector_type type, pmt::pmt_t v); +pmt::pmt_t gr_pdu_make_vector(gr_pdu_vector_type type, const uint8_t* buf, size_t items); +gr_pdu_vector_type type_from_pmt(pmt::pmt_t vector); + +#endif diff --git a/gnuradio-core/src/lib/io/gr_pdu.i b/gnuradio-core/src/lib/io/gr_pdu.i new file mode 100644 index 000000000..ada3a63a7 --- /dev/null +++ b/gnuradio-core/src/lib/io/gr_pdu.i @@ -0,0 +1,30 @@ +/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+%{
+#include <gr_pdu.h>
+%}
+
+enum gr_pdu_vector_type { pdu_byte, pdu_float, pdu_complex };
+
+
+
diff --git a/gnuradio-core/src/lib/io/gr_pdu_to_tagged_stream.cc b/gnuradio-core/src/lib/io/gr_pdu_to_tagged_stream.cc new file mode 100644 index 000000000..5c319dc39 --- /dev/null +++ b/gnuradio-core/src/lib/io/gr_pdu_to_tagged_stream.cc @@ -0,0 +1,132 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gr_pdu_to_tagged_stream.h> +#include <gr_io_signature.h> +#include <cstdio> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <stdexcept> +#include <string.h> + + +// public constructor that returns a shared_ptr + +gr_pdu_to_tagged_stream_sptr +gr_make_pdu_to_tagged_stream(gr_pdu_vector_type t) +{ + return gnuradio::get_initial_sptr(new gr_pdu_to_tagged_stream(t)); +} + +gr_pdu_to_tagged_stream::gr_pdu_to_tagged_stream (gr_pdu_vector_type t) + : gr_sync_block("pdu_to_tagged_stream", + gr_make_io_signature(0, 0, 0), + gr_make_io_signature(1, 1, gr_pdu_itemsize(t))), + d_vectortype(t), d_itemsize(gr_pdu_itemsize(t)) +{ + message_port_register_in(pdu_port_id); +} + +gr_pdu_to_tagged_stream::~gr_pdu_to_tagged_stream() +{ +} + +int +gr_pdu_to_tagged_stream::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + char *out = (char *) output_items[0]; + int nout = 0; + + // if we have remaining output, send it + if(d_remain.size() > 0){ + nout = std::min((size_t)d_remain.size()/d_itemsize, (size_t)noutput_items); + memcpy(out, &d_remain[0], nout*d_itemsize); + d_remain.erase( d_remain.begin(), d_remain.begin()+nout); + noutput_items -= nout; + out += nout*d_itemsize; + } + + // if we have space for at least one item output as much as we can + if(noutput_items > 0){ + + // grab a message if one exists + //pmt::pmt_t msg( delete_head_nowait( pdu_port_id ) ); + pmt::pmt_t msg( delete_head_blocking( pdu_port_id ) ); + if(msg.get() == NULL ){ + return nout; + } + + // make sure type is valid + if(!pmt::pmt_is_pair(msg)){ + throw std::runtime_error("received a malformed pdu message!"); + } + +// printf("got a msg\n"); +// pmt::pmt_print(msg); + + // grab the components of the pdu message + pmt::pmt_t meta(pmt::pmt_car(msg)); // make sure this is NIL || Dict ? + pmt::pmt_t vect(pmt::pmt_cdr(msg)); // make sure this is a vector? + + // compute offset for output tag + uint64_t offset = nitems_written(0) + nout; + + // add a tag for pdu length + add_item_tag(0, offset, pdu_length_tag, pmt::pmt_from_long( pmt::pmt_length(vect) ), pmt::mp(alias())); + + // if we recieved metadata add it as tags + if( !pmt_eq(meta, pmt::PMT_NIL) ){ + pmt::pmt_t pair(pmt::pmt_dict_keys( meta )); + while( !pmt_eq(pair, pmt::PMT_NIL) ){ + pmt::pmt_t k(pmt::pmt_cdr(pair)); + pmt::pmt_t v(pmt::pmt_dict_ref(meta, k, pmt::PMT_NIL)); + add_item_tag(0, offset, k, v, pmt::mp(alias())); + } + } + + // copy vector output + size_t ncopy = std::min((size_t)noutput_items, (size_t)pmt::pmt_length(vect)); + size_t nsave = pmt::pmt_length(vect) - ncopy; + + // copy output + size_t io(0); + nout += ncopy; + memcpy(out, pmt_uniform_vector_elements(vect,io), ncopy*d_itemsize); + + // save leftover items if needed for next work call + if(nsave > 0){ + d_remain.resize(nsave*d_itemsize, 0); + memcpy(&d_remain[0], pmt_uniform_vector_elements(vect,ncopy), nsave*d_itemsize); + } + + } + + return nout; +} diff --git a/gnuradio-core/src/lib/io/gr_pdu_to_tagged_stream.h b/gnuradio-core/src/lib/io/gr_pdu_to_tagged_stream.h new file mode 100644 index 000000000..3105a3d38 --- /dev/null +++ b/gnuradio-core/src/lib/io/gr_pdu_to_tagged_stream.h @@ -0,0 +1,63 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_PDU_TO_TAGGED_STREAM_H +#define INCLUDED_GR_PDU_TO_TAGGED_STREAM_H + +#include <gr_core_api.h> +#include <gr_sync_block.h> +#include <gr_message.h> +#include <gr_msg_queue.h> +#include <gr_pdu.h> + +class gr_pdu_to_tagged_stream; +typedef boost::shared_ptr<gr_pdu_to_tagged_stream> gr_pdu_to_tagged_stream_sptr; + +GR_CORE_API gr_pdu_to_tagged_stream_sptr gr_make_pdu_to_tagged_stream (gr_pdu_vector_type t); + +/*! + * \brief Turn received messages into a stream + * \ingroup source_blk + */ +class GR_CORE_API gr_pdu_to_tagged_stream : public gr_sync_block +{ + private: + gr_pdu_vector_type d_vectortype; + size_t d_itemsize; + std::vector<uint8_t> d_remain; + + friend GR_CORE_API gr_pdu_to_tagged_stream_sptr + gr_make_pdu_to_tagged_stream(gr_pdu_vector_type t); + + protected: + gr_pdu_to_tagged_stream (gr_pdu_vector_type t); + + public: + ~gr_pdu_to_tagged_stream (); + + int work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + +}; + +#endif /* INCLUDED_GR_PDU_TO_TAGGED_SOURCE_H */ diff --git a/gnuradio-core/src/lib/io/gr_pdu_to_tagged_stream.i b/gnuradio-core/src/lib/io/gr_pdu_to_tagged_stream.i new file mode 100644 index 000000000..ec760b309 --- /dev/null +++ b/gnuradio-core/src/lib/io/gr_pdu_to_tagged_stream.i @@ -0,0 +1,31 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +GR_SWIG_BLOCK_MAGIC(gr,pdu_to_tagged_stream); + +%{ +#include <gr_pdu_to_tagged_stream.h> +%} + +%include <gr_pdu_to_tagged_stream.h> + + diff --git a/gnuradio-core/src/lib/io/gr_socket_pdu.cc b/gnuradio-core/src/lib/io/gr_socket_pdu.cc new file mode 100644 index 000000000..bb374b300 --- /dev/null +++ b/gnuradio-core/src/lib/io/gr_socket_pdu.cc @@ -0,0 +1,157 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gr_socket_pdu.h> +#include <gr_io_signature.h> +#include <cstdio> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <stdexcept> +#include <string.h> +#include <iostream> +#include <gr_pdu.h> +#include <boost/format.hpp> + +// public constructor that returns a shared_ptr +gr_socket_pdu_sptr +gr_make_socket_pdu (std::string type, std::string addr, std::string port, int MTU) +{ + return gnuradio::get_initial_sptr(new gr_socket_pdu(type,addr,port,MTU)); +} + +gr_socket_pdu::gr_socket_pdu (std::string type, std::string addr, std::string port, int MTU) + : gr_stream_pdu_base(MTU) +{ + + if( (type == "TCP_SERVER") || (type == "TCP_CLIENT")){ + boost::asio::ip::tcp::resolver resolver(_io_service); + boost::asio::ip::tcp::resolver::query query(boost::asio::ip::tcp::v4(), addr, port); + _tcp_endpoint = *resolver.resolve(query); + } + if( (type == "UDP_SERVER") || (type == "UDP_CLIENT")){ + boost::asio::ip::udp::resolver resolver(_io_service); + boost::asio::ip::udp::resolver::query query(boost::asio::ip::udp::v4(), addr, port); + if( (type == "UDP_SERVER") ){ + _udp_endpoint = *resolver.resolve(query); + } else { + _udp_endpoint_other = *resolver.resolve(query); + } + } + + // register ports + message_port_register_out(pmt::mp("pdus")); + message_port_register_in(pmt::mp("pdus")); + + // set up socketry + if (type == "TCP_SERVER"){ + _acceptor_tcp.reset(new boost::asio::ip::tcp::acceptor(_io_service, _tcp_endpoint)); + _acceptor_tcp->set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); + start_tcp_accept(); + // bind tcp server send handler + set_msg_handler(pmt::mp("pdus"), boost::bind(&gr_socket_pdu::tcp_server_send, this, _1)); + } else if(type =="TCP_CLIENT"){ + boost::system::error_code error = boost::asio::error::host_not_found; + _tcp_socket.reset(new boost::asio::ip::tcp::socket(_io_service)); + _tcp_socket->connect(_tcp_endpoint, error); + if(error){ + throw boost::system::system_error(error); + } + set_msg_handler(pmt::mp("pdus"), boost::bind(&gr_socket_pdu::tcp_client_send, this, _1)); + _tcp_socket->async_read_some( + boost::asio::buffer(rxbuf), + boost::bind(&gr_socket_pdu::handle_tcp_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); + + } else if(type =="UDP_SERVER"){ + _udp_socket.reset(new boost::asio::ip::udp::socket(_io_service, _udp_endpoint)); + _udp_socket->async_receive_from( boost::asio::buffer(rxbuf), _udp_endpoint_other, + boost::bind(&gr_socket_pdu::handle_udp_read, this, + boost::asio::placeholders::error, + boost::asio::placeholders::bytes_transferred)); + set_msg_handler(pmt::mp("pdus"), boost::bind(&gr_socket_pdu::udp_send, this, _1)); + } else if(type =="UDP_CLIENT"){ + _udp_socket.reset(new boost::asio::ip::udp::socket(_io_service, _udp_endpoint)); + _udp_socket->async_receive_from( boost::asio::buffer(rxbuf), _udp_endpoint_other, + boost::bind(&gr_socket_pdu::handle_udp_read, this, + boost::asio::placeholders::error, + boost::asio::placeholders::bytes_transferred)); + set_msg_handler(pmt::mp("pdus"), boost::bind(&gr_socket_pdu::udp_send, this, _1)); + } else { + throw std::runtime_error("unknown socket type!"); + } + + // start thread for io_service + d_thread = boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&gr_socket_pdu::run_io_service, this))); + d_started = true; +} + +void tcp_connection::handle_read(const boost::system::error_code& error/*error*/, size_t bytes_transferred) + { + if(!error) + { + pmt::pmt_t vector = pmt::pmt_init_u8vector(bytes_transferred, (const uint8_t*)&buf[0]); + pmt::pmt_t pdu = pmt::pmt_cons( pmt::PMT_NIL, vector); + + d_block->message_port_pub( pmt::mp("pdus"), pdu ); + + socket_.async_read_some( + boost::asio::buffer(buf), + boost::bind(&tcp_connection::handle_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); + + } else { + std::cout << "error occurred\n"; + } + + } + + +void gr_socket_pdu::tcp_server_send(pmt::pmt_t msg){ + pmt::pmt_t vector = pmt::pmt_cdr(msg); + for(size_t i=0; i<d_tcp_connections.size(); i++){ + d_tcp_connections[i]->send(vector); + } +} + +void gr_socket_pdu::tcp_client_send(pmt::pmt_t msg){ + pmt::pmt_t vector = pmt::pmt_cdr(msg); + size_t len = pmt::pmt_length(vector); + size_t offset(0); + boost::array<char, 10000> txbuf; + memcpy(&txbuf[0], pmt::pmt_uniform_vector_elements(vector, offset), len); + _tcp_socket->send(boost::asio::buffer(txbuf,len)); +} + +void gr_socket_pdu::udp_send(pmt::pmt_t msg){ + pmt::pmt_t vector = pmt::pmt_cdr(msg); + size_t len = pmt::pmt_length(vector); + size_t offset(0); + boost::array<char, 10000> txbuf; + memcpy(&txbuf[0], pmt::pmt_uniform_vector_elements(vector, offset), len); + if(_udp_endpoint_other.address().to_string() != "0.0.0.0") + _udp_socket->send_to(boost::asio::buffer(txbuf,len), _udp_endpoint_other); +} diff --git a/gnuradio-core/src/lib/io/gr_socket_pdu.h b/gnuradio-core/src/lib/io/gr_socket_pdu.h new file mode 100644 index 000000000..e30a4cc6c --- /dev/null +++ b/gnuradio-core/src/lib/io/gr_socket_pdu.h @@ -0,0 +1,202 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_SOCKET_PDU_H +#define INCLUDED_GR_SOCKET_PDU_H + +#include <gr_core_api.h> +#include <gr_sync_block.h> +#include <gr_message.h> +#include <gr_msg_queue.h> +#include <gr_stream_pdu_base.h> +#include <boost/array.hpp> +#include <boost/asio.hpp> + +class gr_socket_pdu; +typedef boost::shared_ptr<gr_socket_pdu> gr_socket_pdu_sptr; + +GR_CORE_API gr_socket_pdu_sptr gr_make_socket_pdu (std::string type, std::string addr, std::string port, int MTU=10000); + +class tcp_connection + : public boost::enable_shared_from_this<tcp_connection> +{ +public: + typedef boost::shared_ptr<tcp_connection> pointer; + gr_socket_pdu *d_block; + boost::array<char, 10000> buf; + + static pointer create(boost::asio::io_service& io_service) + { + return pointer(new tcp_connection(io_service)); + } + + boost::asio::ip::tcp::socket& socket() + { + return socket_; + } + + void start(gr_socket_pdu* parent) + { + d_block = parent; +// message_ = "connected to gr_socket_pdu\n"; +// boost::asio::async_write(socket_, boost::asio::buffer(message_), +// boost::bind(&tcp_connection::handle_write, shared_from_this(), +// boost::asio::placeholders::error, +// boost::asio::placeholders::bytes_transferred)); + + socket_.async_read_some( + boost::asio::buffer(buf), + boost::bind(&tcp_connection::handle_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); + } + void send(pmt::pmt_t vector){ + size_t len = pmt::pmt_length(vector); + size_t offset(0); + boost::array<char, 10000> txbuf; + memcpy(&txbuf[0], pmt::pmt_uniform_vector_elements(vector, offset), len); + boost::asio::async_write(socket_, boost::asio::buffer(txbuf, len), + boost::bind(&tcp_connection::handle_write, shared_from_this(), + boost::asio::placeholders::error, + boost::asio::placeholders::bytes_transferred)); + } + + ~tcp_connection(){ +// std::cout << "tcp_connection destroyed\n"; + } + +private: + tcp_connection(boost::asio::io_service& io_service) + : socket_(io_service) + { + } + + void handle_read(const boost::system::error_code& error/*error*/, size_t bytes_transferred); + + void handle_write(const boost::system::error_code& /*error*/, + size_t /*bytes_transferred*/) + { + } + + boost::asio::ip::tcp::socket socket_; + std::string message_; +}; + + +/*! + * \brief Gather received items into messages and insert into msgq + * \ingroup sink_blk + */ +class GR_CORE_API gr_socket_pdu : public gr_stream_pdu_base +{ + private: + friend GR_CORE_API gr_socket_pdu_sptr + gr_make_socket_pdu(std::string type, std::string addr, std::string port, int MTU); + + boost::asio::io_service _io_service; + + boost::array<char, 10000> rxbuf; + + // tcp specific + boost::asio::ip::tcp::endpoint _tcp_endpoint; + + // specific to tcp server + boost::shared_ptr<boost::asio::ip::tcp::acceptor> _acceptor_tcp; + std::vector<tcp_connection::pointer> d_tcp_connections; + void tcp_server_send(pmt::pmt_t msg); + void tcp_client_send(pmt::pmt_t msg); + void udp_send(pmt::pmt_t msg); + + // specific to tcp client + boost::shared_ptr<boost::asio::ip::tcp::socket> _tcp_socket; + + // specific to udp client/server + boost::asio::ip::udp::endpoint _udp_endpoint; + boost::asio::ip::udp::endpoint _udp_endpoint_other; + boost::shared_ptr<boost::asio::ip::udp::socket> _udp_socket; + + void handle_receive(const boost::system::error_code& error, std::size_t ){ + } + + void start_tcp_accept(){ + tcp_connection::pointer new_connection = + tcp_connection::create(_acceptor_tcp->get_io_service()); + + _acceptor_tcp->async_accept(new_connection->socket(), + boost::bind(&gr_socket_pdu::handle_tcp_accept, this, new_connection, + boost::asio::placeholders::error)); + } + + void handle_tcp_accept(tcp_connection::pointer new_connection, const boost::system::error_code& error){ + if (!error) + { + new_connection->start(this); + d_tcp_connections.push_back(new_connection); + start_tcp_accept(); + } else { + std::cout << error << std::endl; + } + } + + void run_io_service(){ + _io_service.run(); + } + + void handle_udp_read(const boost::system::error_code& error/*error*/, size_t bytes_transferred){ + if(!error){ + pmt::pmt_t vector = pmt::pmt_init_u8vector(bytes_transferred, (const uint8_t*)&rxbuf[0]); + pmt::pmt_t pdu = pmt::pmt_cons( pmt::PMT_NIL, vector); + + message_port_pub( pmt::mp("pdus"), pdu ); + + _udp_socket->async_receive_from( boost::asio::buffer(rxbuf), _udp_endpoint_other, + boost::bind(&gr_socket_pdu::handle_udp_read, this, + boost::asio::placeholders::error, + boost::asio::placeholders::bytes_transferred)); + } else { + throw boost::system::system_error(error); +// std::cout << "error occurred\n"; + } + } + void handle_tcp_read(const boost::system::error_code& error/*error*/, size_t bytes_transferred){ + if(!error) + { + pmt::pmt_t vector = pmt::pmt_init_u8vector(bytes_transferred, (const uint8_t*)&rxbuf[0]); + pmt::pmt_t pdu = pmt::pmt_cons( pmt::PMT_NIL, vector); + + message_port_pub( pmt::mp("pdus"), pdu ); + + _tcp_socket->async_read_some( + boost::asio::buffer(rxbuf), + boost::bind(&gr_socket_pdu::handle_tcp_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); + + } else { + //std::cout << "error occurred\n"; + throw boost::system::system_error(error); + } + } + + protected: + gr_socket_pdu (std::string type, std::string addr, std::string port, int MTU=10000); + public: + ~gr_socket_pdu () {} +}; + +#endif /* INCLUDED_GR_TUNTAP_PDU_H */ diff --git a/gnuradio-core/src/lib/io/gr_socket_pdu.i b/gnuradio-core/src/lib/io/gr_socket_pdu.i new file mode 100644 index 000000000..3e20b63e2 --- /dev/null +++ b/gnuradio-core/src/lib/io/gr_socket_pdu.i @@ -0,0 +1,33 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +GR_SWIG_BLOCK_MAGIC(gr,socket_pdu); + +%ignore tcp_connection; + +%{ +#include <gr_socket_pdu.h> +%} + +%include "gr_stream_pdu_base.h" +%include "gr_socket_pdu.h" + diff --git a/gnuradio-core/src/lib/io/gr_stream_pdu_base.cc b/gnuradio-core/src/lib/io/gr_stream_pdu_base.cc new file mode 100644 index 000000000..7250c33e5 --- /dev/null +++ b/gnuradio-core/src/lib/io/gr_stream_pdu_base.cc @@ -0,0 +1,123 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <ciso646> +#include <gr_stream_pdu_base.h> +#include <gr_io_signature.h> +#include <cstdio> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <stdexcept> +#include <string.h> +#include <iostream> +#include <gr_pdu.h> +#include <boost/asio.hpp> +#include <boost/format.hpp> + +#ifdef HAVE_IO_H +#include <io.h> +#endif + +static const long timeout_us = 100*1000; //100ms + +gr_stream_pdu_base::gr_stream_pdu_base (int MTU) + : gr_sync_block("stream_pdu_base", + gr_make_io_signature(0, 0, 0), + gr_make_io_signature(0, 0, 0)), + d_finished(false), d_started(false), d_fd(-1) +{ + // reserve space for rx buffer + d_rxbuf.resize(MTU,0); +} + +gr_stream_pdu_base::~gr_stream_pdu_base() +{ + stop_rxthread(); +} + +void gr_stream_pdu_base::stop_rxthread(){ + d_finished = true; + if(d_started){ + d_thread->interrupt(); + d_thread->join(); + } + } + +void gr_stream_pdu_base::start_rxthread(pmt::pmt_t _rxport){ + rxport = _rxport; + d_thread = boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&gr_stream_pdu_base::run, this))); + d_started = true; + } + +void gr_stream_pdu_base::run(){ + while(!d_finished) { + if(not wait_ready()){ continue; } + const int result = read( d_fd, &d_rxbuf[0], d_rxbuf.size() ); + if(result <= 0){ throw std::runtime_error("gr_stream_pdu_base, bad socket read!"); } + pmt::pmt_t vector = pmt::pmt_init_u8vector(result, &d_rxbuf[0]); + pmt::pmt_t pdu = pmt::pmt_cons( pmt::PMT_NIL, vector); + message_port_pub(rxport, pdu); + } +} + +void gr_stream_pdu_base::send(pmt::pmt_t msg){ + pmt::pmt_t vector = pmt::pmt_cdr(msg); + size_t offset(0); + size_t itemsize(gr_pdu_itemsize(type_from_pmt(vector))); + int len( pmt::pmt_length(vector)*itemsize ); + + const int rv = write(d_fd, pmt::pmt_uniform_vector_elements(vector, offset), len); + if(rv != len){ + std::cerr << boost::format("WARNING: gr_stream_pdu_base::send(pdu) write failed! (d_fd=%d, len=%d, rv=%d)") + % d_fd % len % rv << std::endl; + } +} + +int +gr_stream_pdu_base::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + throw std::runtime_error("should not be called.\n"); + return 0; +} + +bool gr_stream_pdu_base::wait_ready(){ + //setup timeval for timeout + timeval tv; + tv.tv_sec = 0; + tv.tv_usec = timeout_us; + + //setup rset for timeout + fd_set rset; + FD_ZERO(&rset); + FD_SET(d_fd, &rset); + + //call select with timeout on receive socket + return ::select(d_fd+1, &rset, NULL, NULL, &tv) > 0; +} diff --git a/gnuradio-core/src/lib/io/gr_stream_pdu_base.h b/gnuradio-core/src/lib/io/gr_stream_pdu_base.h new file mode 100644 index 000000000..35bacf523 --- /dev/null +++ b/gnuradio-core/src/lib/io/gr_stream_pdu_base.h @@ -0,0 +1,59 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_STREAM_PDU_BASE_H +#define INCLUDED_GR_STREAM_PDU_BASE_H + +#include <gr_core_api.h> +#include <gr_sync_block.h> +#include <gr_message.h> +#include <gr_msg_queue.h> + +/*! + * \brief Gather received items into messages and insert into msgq + * \ingroup sink_blk + */ +class GR_CORE_API gr_stream_pdu_base : public gr_sync_block +{ + public: + boost::shared_ptr<boost::thread> d_thread; + bool d_finished; + bool d_started; + std::vector<uint8_t> d_rxbuf; + void run(); + int d_fd; + gr_stream_pdu_base (int MTU=10000); + ~gr_stream_pdu_base (); + void send(pmt::pmt_t msg); + bool wait_ready(); + int work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + void start_rxthread(pmt::pmt_t _rxport); + void stop_rxthread(); + private: + pmt::pmt_t rxport; +}; + +typedef boost::shared_ptr<gr_stream_pdu_base> gr_stream_pdu_base_sptr; + +#endif /* INCLUDED_GR_TUNTAP_PDU_H */ diff --git a/gnuradio-core/src/lib/io/gr_tagged_stream_to_pdu.cc b/gnuradio-core/src/lib/io/gr_tagged_stream_to_pdu.cc new file mode 100644 index 000000000..8211b7672 --- /dev/null +++ b/gnuradio-core/src/lib/io/gr_tagged_stream_to_pdu.cc @@ -0,0 +1,137 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gr_tagged_stream_to_pdu.h> +#include <gr_io_signature.h> +#include <cstdio> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <stdexcept> +#include <string.h> + +// public constructor that returns a shared_ptr + +gr_tagged_stream_to_pdu_sptr +gr_make_tagged_stream_to_pdu(gr_pdu_vector_type t) +{ + return gnuradio::get_initial_sptr(new gr_tagged_stream_to_pdu(t)); +} + +gr_tagged_stream_to_pdu::gr_tagged_stream_to_pdu (gr_pdu_vector_type t) + : gr_sync_block("tagged_stream_to_pdu", + gr_make_io_signature(1, 1, gr_pdu_itemsize(t)), + gr_make_io_signature(0, 0, 0)), + d_vectortype(t), d_itemsize(gr_pdu_itemsize(t)), d_inpdu(false), + d_pdu_meta(pmt::PMT_NIL), d_pdu_vector(pmt::PMT_NIL) +{ + message_port_register_out(pdu_port_id); +} + +gr_tagged_stream_to_pdu::~gr_tagged_stream_to_pdu() +{ + printf("destructor running\n"); +} + +int +gr_tagged_stream_to_pdu::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + const uint8_t *in = (const uint8_t*) input_items[0]; + uint64_t abs_N = nitems_read(0); + + // if we are not in a pdu already, start a new one + if(!d_inpdu){ + get_tags_in_range(d_tags, 0, abs_N, abs_N+1); + bool found_length_tag(false); + for(d_tags_itr = d_tags.begin(); (d_tags_itr != d_tags.end()) && (!found_length_tag); d_tags_itr++){ + if( pmt::pmt_equal( (*d_tags_itr).key, pdu_length_tag ) ){ + if( (*d_tags_itr).offset != abs_N ){ + throw std::runtime_error("expected next pdu length tag on a different item..."); + } + found_length_tag = true; + d_pdu_length = pmt::pmt_to_long( (*d_tags_itr).value ); + d_pdu_remain = d_pdu_length; + d_pdu_meta = pmt::pmt_make_dict(); + break; + } // if have length tag + } // iter over tags + if(!found_length_tag){ + throw std::runtime_error("tagged stream does not contain a pdu_length tag!"); + } + } + + size_t ncopy = std::min((size_t)noutput_items, d_pdu_remain); + + // copy any tags in this range into our meta object + get_tags_in_range(d_tags, 0, abs_N, abs_N+ncopy); + for(d_tags_itr = d_tags.begin(); d_tags_itr != d_tags.end(); d_tags_itr++){ + if( ! pmt_equal( (*d_tags_itr).key, pdu_length_tag ) ){ + d_pdu_meta = pmt_dict_add(d_pdu_meta, (*d_tags_itr).key, (*d_tags_itr).value); + } + } + + // copy samples for this vector into either a pmt or our save buffer + if(ncopy == d_pdu_remain){ // we will send this pdu + if(d_save.size() == 0){ + d_pdu_vector = gr_pdu_make_vector(d_vectortype, in, ncopy); + send_message(); + } else { + size_t oldsize = d_save.size(); + d_save.resize((oldsize + ncopy)*d_itemsize, 0); + memcpy( &d_save[oldsize*d_itemsize], in, ncopy*d_itemsize ); + d_pdu_vector = gr_pdu_make_vector(d_vectortype, &d_save[0], d_pdu_length); + send_message(); + d_save.clear(); + } + } else { + d_inpdu = true; + size_t oldsize = d_save.size(); + d_save.resize( (oldsize+ncopy)*d_itemsize ); + memcpy( &d_save[oldsize*d_itemsize], in, ncopy*d_itemsize ); + d_pdu_remain -= ncopy; + } + + return ncopy; +} + +void gr_tagged_stream_to_pdu::send_message(){ + + if(pmt::pmt_length(d_pdu_vector) != d_pdu_length){ + throw std::runtime_error("msg length not correct"); + } + + pmt::pmt_t msg = pmt::pmt_cons( d_pdu_meta, d_pdu_vector ); + message_port_pub( pdu_port_id, msg ); + + d_pdu_meta = pmt::PMT_NIL; + d_pdu_vector = pmt::PMT_NIL; + d_pdu_length = 0; + d_pdu_remain = 0; + d_inpdu = false; +} diff --git a/gnuradio-core/src/lib/io/gr_tagged_stream_to_pdu.h b/gnuradio-core/src/lib/io/gr_tagged_stream_to_pdu.h new file mode 100644 index 000000000..c3fff3581 --- /dev/null +++ b/gnuradio-core/src/lib/io/gr_tagged_stream_to_pdu.h @@ -0,0 +1,76 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_TAGGED_STREAM_TO_PDU_H +#define INCLUDED_GR_TAGGED_STREAM_TO_PDU_H + +#include <gr_core_api.h> +#include <gr_sync_block.h> +#include <gr_message.h> +#include <gr_msg_queue.h> +#include <gr_pdu.h> + +class gr_tagged_stream_to_pdu; +typedef boost::shared_ptr<gr_tagged_stream_to_pdu> gr_tagged_stream_to_pdu_sptr; + +GR_CORE_API gr_tagged_stream_to_pdu_sptr gr_make_tagged_stream_to_pdu (gr_pdu_vector_type t); + +/*! + * \brief Turn received messages into a stream + * \ingroup source_blk + */ +class GR_CORE_API gr_tagged_stream_to_pdu : public gr_sync_block +{ + private: + gr_pdu_vector_type d_vectortype; + size_t d_itemsize; + + std::vector<uint8_t> d_save; + + std::vector<gr_tag_t> d_tags; + std::vector<gr_tag_t>::iterator d_tags_itr; + + bool d_inpdu; + + size_t d_pdu_length; + size_t d_pdu_remain; + pmt::pmt_t d_pdu_meta; + pmt::pmt_t d_pdu_vector; + + friend GR_CORE_API gr_tagged_stream_to_pdu_sptr + gr_make_tagged_stream_to_pdu(gr_pdu_vector_type t); + + protected: + gr_tagged_stream_to_pdu (gr_pdu_vector_type t); + + public: + ~gr_tagged_stream_to_pdu (); + + int work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + + void send_message(); + +}; + +#endif /* INCLUDED_GR_PDU_TO_TAGGED_SOURCE_H */ diff --git a/gnuradio-core/src/lib/io/gr_tagged_stream_to_pdu.i b/gnuradio-core/src/lib/io/gr_tagged_stream_to_pdu.i new file mode 100644 index 000000000..f12987b74 --- /dev/null +++ b/gnuradio-core/src/lib/io/gr_tagged_stream_to_pdu.i @@ -0,0 +1,31 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +GR_SWIG_BLOCK_MAGIC(gr,tagged_stream_to_pdu); + +%{ +#include <gr_tagged_stream_to_pdu.h> +%} + +%include <gr_tagged_stream_to_pdu.h> + + diff --git a/gnuradio-core/src/lib/io/gr_tuntap_pdu.cc b/gnuradio-core/src/lib/io/gr_tuntap_pdu.cc new file mode 100644 index 000000000..8dd4b18a1 --- /dev/null +++ b/gnuradio-core/src/lib/io/gr_tuntap_pdu.cc @@ -0,0 +1,145 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gr_tuntap_pdu.h> +#include <gr_io_signature.h> +#include <cstdio> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <stdexcept> +#include <string.h> +#include <iostream> +#include <gr_pdu.h> +#include <boost/format.hpp> + +#if (defined(linux) || defined(__linux) || defined(__linux__)) + +#include <sys/ioctl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +#include <arpa/inet.h> +#include <linux/if.h> + + +// public constructor that returns a shared_ptr + +gr_tuntap_pdu_sptr +gr_make_tuntap_pdu (std::string dev, int MTU) +{ + return gnuradio::get_initial_sptr(new gr_tuntap_pdu(dev, MTU)); +} + +gr_tuntap_pdu::gr_tuntap_pdu (std::string dev, int MTU) + : gr_stream_pdu_base(MTU) +{ + + // make the tuntap + char dev_cstr[1024]; + memset(dev_cstr, 0x00, 1024); + strncpy(dev_cstr, dev.c_str(), std::min(sizeof(dev_cstr), dev.size())); + d_fd = tun_alloc(dev_cstr); + if(d_fd <= 0){ + throw std::runtime_error("TunTap make: tun_alloc failed (are you running as root?)"); + } + + std::cout << boost::format( + "Allocated virtual ethernet interface: %s\n" + "You must now use ifconfig to set its IP address. E.g.,\n" + " $ sudo ifconfig %s 192.168.200.1\n" + "Be sure to use a different address in the same subnet for each machine.\n" + ) % dev % dev << std::endl; + + // set up output message port + message_port_register_out(pmt::mp("pdus")); + start_rxthread(pmt::mp("pdus")); + + // set up input message port + message_port_register_in(pmt::mp("pdus")); + set_msg_handler(pmt::mp("pdus"), boost::bind(&gr_tuntap_pdu::send, this, _1)); +} + + +int gr_tuntap_pdu::tun_alloc(char *dev, int flags) { + struct ifreq ifr; + int fd, err; + const char *clonedev = "/dev/net/tun"; + + /* Arguments taken by the function: + * + * char *dev: the name of an interface (or '\0'). MUST have enough + * space to hold the interface name if '\0' is passed + * int flags: interface flags (eg, IFF_TUN etc.) + */ + + /* open the clone device */ + if( (fd = open(clonedev, O_RDWR)) < 0 ) { + return fd; + } + + /* preparation of the struct ifr, of type "struct ifreq" */ + memset(&ifr, 0, sizeof(ifr)); + + ifr.ifr_flags = flags; /* IFF_TUN or IFF_TAP, plus maybe IFF_NO_PI */ + + if (*dev) { + /* if a device name was specified, put it in the structure; otherwise, + * the kernel will try to allocate the "next" device of the + * specified type */ + strncpy(ifr.ifr_name, dev, IFNAMSIZ); + } + + /* try to create the device */ + if( (err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ) { + close(fd); + return err; + } + + /* if the operation was successful, write back the name of the + * interface to the variable "dev", so the caller can know + * it. Note that the caller MUST reserve space in *dev (see calling + * code below) */ + strcpy(dev, ifr.ifr_name); + + /* this is the special file descriptor that the caller will use to talk + * with the virtual interface */ + return fd; +} + +#else //if not linux + +gr_block_sptr +gr_make_tuntap_pdu(std::string dev, int MTU) +{ + gr_block_sptr rv; + throw std::runtime_error("tuntap only implemented on linux"); + return rv; +} + +#endif diff --git a/gnuradio-core/src/lib/io/gr_tuntap_pdu.h b/gnuradio-core/src/lib/io/gr_tuntap_pdu.h new file mode 100644 index 000000000..18c83f42b --- /dev/null +++ b/gnuradio-core/src/lib/io/gr_tuntap_pdu.h @@ -0,0 +1,74 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_TUNTAP_PDU_H +#define INCLUDED_GR_TUNTAP_PDU_H + +#include <gr_core_api.h> +#include <gr_sync_block.h> +#include <gr_message.h> +#include <gr_msg_queue.h> +#include <gr_stream_pdu_base.h> + +#if (defined(linux) || defined(__linux) || defined(__linux__)) + +#include <linux/if_tun.h> + +class gr_tuntap_pdu; +typedef boost::shared_ptr<gr_tuntap_pdu> gr_tuntap_pdu_sptr; + +GR_CORE_API gr_tuntap_pdu_sptr gr_make_tuntap_pdu (std::string dev, int MTU=10000); + +/*! + * \brief Gather received items into messages and insert into msgq + * \ingroup sink_blk + */ +class GR_CORE_API gr_tuntap_pdu : public gr_stream_pdu_base +{ + private: + friend GR_CORE_API gr_tuntap_pdu_sptr + gr_make_tuntap_pdu(std::string dev, int MTU); + int tun_alloc(char* dev, int flags = IFF_TAP | IFF_NO_PI); + std::string d_dev; + protected: + gr_tuntap_pdu (std::string dev, int MTU=10000); + + public: + ~gr_tuntap_pdu () {} + +}; + +#else // if not linux + +class gr_tuntap_pdu +{ +private: + gr_tuntap_pdu() {}; +public: + ~gr_tuntap_pdu() {}; +}; + +GR_CORE_API gr_block_sptr gr_make_tuntap_pdu (std::string dev, int MTU=0); + +#endif + +#endif /* INCLUDED_GR_TUNTAP_PDU_H */ diff --git a/gnuradio-core/src/lib/io/gr_tuntap_pdu.i b/gnuradio-core/src/lib/io/gr_tuntap_pdu.i new file mode 100644 index 000000000..589bbc385 --- /dev/null +++ b/gnuradio-core/src/lib/io/gr_tuntap_pdu.i @@ -0,0 +1,30 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +GR_SWIG_BLOCK_MAGIC(gr,tuntap_pdu); + +%{ +#include <gr_tuntap_pdu.h> +%} + +%include "gr_tuntap_pdu.h" + diff --git a/gnuradio-core/src/lib/io/gr_udp_source.cc b/gnuradio-core/src/lib/io/gr_udp_source.cc index af41159ee..eca8e89d0 100644 --- a/gnuradio-core/src/lib/io/gr_udp_source.cc +++ b/gnuradio-core/src/lib/io/gr_udp_source.cc @@ -269,8 +269,9 @@ gr_udp_source::work (int noutput_items, else if(r == 0 ) { // timed out if( d_wait ) { // Allow boost thread interrupt, then try again - boost::this_thread::interruption_point(); - continue; + //boost::this_thread::interruption_point(); + //continue; + return 0; } else return -1; @@ -294,8 +295,9 @@ gr_udp_source::work (int noutput_items, if( d_wait ) { // Allow boost thread interrupt, then try again - boost::this_thread::interruption_point(); - continue; + //boost::this_thread::interruption_point(); + //continue; + return 0; } else return -1; diff --git a/gnuradio-core/src/lib/io/io.i b/gnuradio-core/src/lib/io/io.i index 5cd352905..e2de4eb97 100644 --- a/gnuradio-core/src/lib/io/io.i +++ b/gnuradio-core/src/lib/io/io.i @@ -45,6 +45,12 @@ #include <gr_wavfile_sink.h> #include <gr_wavfile_source.h> #include <gr_tagged_file_sink.h> +#include <gr_pdu_to_tagged_stream.h> +#include <gr_tagged_stream_to_pdu.h> +#include <gr_message_debug.h> +#include <gr_pdu.h> +#include <gr_tuntap_pdu.h> +#include <gr_socket_pdu.h> %} %include "gr_file_sink_base.i" @@ -67,4 +73,11 @@ %include "gr_wavfile_sink.i" %include "gr_wavfile_source.i" %include "gr_tagged_file_sink.i" +%include "gr_pdu_to_tagged_stream.i" +%include "gr_tagged_stream_to_pdu.i" +%include "gr_message_debug.i" +%include "gr_pdu.i" +%include "gr_tuntap_pdu.i" +%include "gr_socket_pdu.i" + diff --git a/gnuradio-core/src/lib/runtime/CMakeLists.txt b/gnuradio-core/src/lib/runtime/CMakeLists.txt index 5f3672dde..70938a0f1 100644 --- a/gnuradio-core/src/lib/runtime/CMakeLists.txt +++ b/gnuradio-core/src/lib/runtime/CMakeLists.txt @@ -54,6 +54,7 @@ list(APPEND gnuradio_core_sources ${CMAKE_CURRENT_SOURCE_DIR}/gr_block.cc ${CMAKE_CURRENT_SOURCE_DIR}/gr_block_detail.cc ${CMAKE_CURRENT_SOURCE_DIR}/gr_block_executor.cc + ${CMAKE_CURRENT_SOURCE_DIR}/gr_block_registry.cc ${CMAKE_CURRENT_SOURCE_DIR}/gr_hier_block2.cc ${CMAKE_CURRENT_SOURCE_DIR}/gr_hier_block2_detail.cc ${CMAKE_CURRENT_SOURCE_DIR}/gr_buffer.cc @@ -116,6 +117,7 @@ install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/gr_block.h ${CMAKE_CURRENT_SOURCE_DIR}/gr_block_detail.h ${CMAKE_CURRENT_SOURCE_DIR}/gr_block_executor.h + ${CMAKE_CURRENT_SOURCE_DIR}/gr_block_registry.h ${CMAKE_CURRENT_SOURCE_DIR}/gr_hier_block2.h ${CMAKE_CURRENT_SOURCE_DIR}/gr_hier_block2_detail.h ${CMAKE_CURRENT_SOURCE_DIR}/gr_buffer.h diff --git a/gnuradio-core/src/lib/runtime/gr_basic_block.cc b/gnuradio-core/src/lib/runtime/gr_basic_block.cc index d7263b92d..6ff57a1d6 100644 --- a/gnuradio-core/src/lib/runtime/gr_basic_block.cc +++ b/gnuradio-core/src/lib/runtime/gr_basic_block.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2006 Free Software Foundation, Inc. + * Copyright 2006,2012 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -25,7 +25,10 @@ #endif #include <gr_basic_block.h> +#include <gr_block_registry.h> #include <stdexcept> +#include <sstream> +#include <iostream> using namespace pmt; @@ -35,7 +38,7 @@ static long s_ncurrently_allocated = 0; long gr_basic_block_ncurrently_allocated() { - return s_ncurrently_allocated; + return s_ncurrently_allocated; } gr_basic_block::gr_basic_block(const std::string &name, @@ -45,18 +48,180 @@ gr_basic_block::gr_basic_block(const std::string &name, d_input_signature(input_signature), d_output_signature(output_signature), d_unique_id(s_next_id++), - d_color(WHITE) + d_symbolic_id(global_block_registry.block_register(this)), + d_symbol_name(global_block_registry.register_symbolic_name(this)), + d_color(WHITE), + message_subscribers(pmt::pmt_make_dict()) { - s_ncurrently_allocated++; + s_ncurrently_allocated++; } gr_basic_block::~gr_basic_block() { - s_ncurrently_allocated--; + s_ncurrently_allocated--; + global_block_registry.block_unregister(this); } gr_basic_block_sptr gr_basic_block::to_basic_block() { - return shared_from_this(); + return shared_from_this(); +} + +void +gr_basic_block::set_block_alias(std::string name) +{ + global_block_registry.register_symbolic_name(this, name); +} + +// ** Message passing interface ** + +// - register a new input message port +void +gr_basic_block::message_port_register_in(pmt::pmt_t port_id) +{ + if(!pmt::pmt_is_symbol(port_id)) { + throw std::runtime_error("message_port_register_in: bad port id"); + } + msg_queue[port_id] = msg_queue_t(); + msg_queue_ready[port_id] = boost::shared_ptr<boost::condition_variable>(new boost::condition_variable()); +} + +pmt::pmt_t +gr_basic_block::message_ports_in() +{ + pmt::pmt_t port_names = pmt::pmt_make_vector(msg_queue.size(), pmt::PMT_NIL); + msg_queue_map_itr itr = msg_queue.begin(); + for(size_t i = 0; i < msg_queue.size(); i++) { + pmt::pmt_vector_set(port_names, i, (*itr).first); + itr++; + } + return port_names; +} + +// - register a new output message port +void +gr_basic_block::message_port_register_out(pmt::pmt_t port_id) +{ + if(!pmt::pmt_is_symbol(port_id)) { + throw std::runtime_error("message_port_register_out: bad port id"); + } + if(pmt::pmt_dict_has_key(message_subscribers, port_id)) { + throw std::runtime_error("message_port_register_out: port already in use"); + } + message_subscribers = pmt::pmt_dict_add(message_subscribers, port_id, pmt::PMT_NIL); +} + +pmt::pmt_t +gr_basic_block::message_ports_out() +{ + size_t len = pmt::pmt_length(message_subscribers); + pmt::pmt_t port_names = pmt::pmt_make_vector(len, pmt::PMT_NIL); + pmt::pmt_t keys = pmt::pmt_dict_keys(message_subscribers); + for(size_t i = 0; i < len; i++) { + pmt::pmt_vector_set(port_names, i, pmt::pmt_nth(i, keys)); + } + return port_names; +} + +// - publish a message on a message port +void gr_basic_block::message_port_pub(pmt::pmt_t port_id, pmt::pmt_t msg) +{ + if(!pmt::pmt_dict_has_key(message_subscribers, port_id)) { + throw std::runtime_error("port does not exist"); + } + + pmt::pmt_t currlist = pmt::pmt_dict_ref(message_subscribers, port_id, pmt::PMT_NIL); + // iterate through subscribers on port + while(pmt::pmt_is_pair(currlist)) { + pmt::pmt_t target = pmt::pmt_car(currlist); + + pmt::pmt_t block = pmt::pmt_car(target); + pmt::pmt_t port = pmt::pmt_cdr(target); + + currlist = pmt::pmt_cdr(currlist); + gr_basic_block_sptr blk = global_block_registry.block_lookup(block); + //blk->post(msg); + blk->post(port, msg); + } +} + +// - subscribe to a message port +void +gr_basic_block::message_port_sub(pmt::pmt_t port_id, pmt::pmt_t target){ + if(!pmt::pmt_dict_has_key(message_subscribers, port_id)){ + std::stringstream ss; + ss << "Port does not exist: \"" << pmt::pmt_write_string(port_id) << "\" on block: " << pmt::pmt_write_string(target) << std::endl; + throw std::runtime_error(ss.str()); + } + pmt::pmt_t currlist = pmt::pmt_dict_ref(message_subscribers,port_id,pmt::PMT_NIL); + + // ignore re-adds of the same target + if(!pmt::pmt_list_has(currlist, target)) + message_subscribers = pmt::pmt_dict_add(message_subscribers,port_id,pmt::pmt_list_add(currlist,target)); +} + +void +gr_basic_block::message_port_unsub(pmt::pmt_t port_id, pmt::pmt_t target){ + if(!pmt::pmt_dict_has_key(message_subscribers, port_id)){ + std::stringstream ss; + ss << "Port does not exist: \"" << pmt::pmt_write_string(port_id) << "\" on block: " << pmt::pmt_write_string(target) << std::endl; + throw std::runtime_error(ss.str()); + } + + // ignore unsubs of unknown targets + pmt::pmt_t currlist = pmt::pmt_dict_ref(message_subscribers,port_id,pmt::PMT_NIL); + message_subscribers = pmt::pmt_dict_add(message_subscribers,port_id,pmt::pmt_list_rm(currlist,target)); +} + +void +gr_basic_block::_post(pmt_t which_port, pmt_t msg) +{ + insert_tail(which_port, msg); +} + +void +gr_basic_block::insert_tail(pmt::pmt_t which_port, pmt::pmt_t msg) +{ + gruel::scoped_lock guard(mutex); + + if( (msg_queue.find(which_port) == msg_queue.end()) || (msg_queue_ready.find(which_port) == msg_queue_ready.end())){ + std::cout << "target port = " << pmt::pmt_symbol_to_string(which_port) << std::endl; + throw std::runtime_error("attempted to insert_tail on invalid queue!"); + } + + msg_queue[which_port].push_back(msg); + msg_queue_ready[which_port]->notify_one(); + + // wake up thread if BLKD_IN or BLKD_OUT + global_block_registry.notify_blk(alias()); +} + +pmt_t +gr_basic_block::delete_head_nowait(pmt::pmt_t which_port) +{ + gruel::scoped_lock guard(mutex); + + if (empty_p(which_port)){ + return pmt::pmt_t(); + } + + pmt_t m(msg_queue[which_port].front()); + msg_queue[which_port].pop_front(); + + return m; +} + +pmt_t +gr_basic_block::delete_head_blocking(pmt::pmt_t which_port) +{ + gruel::scoped_lock guard(mutex); + + while (empty_p(which_port)){ + msg_queue_ready[which_port]->wait(guard); + } + + pmt_t m(msg_queue[which_port].front()); + msg_queue[which_port].pop_front(); + return m; } diff --git a/gnuradio-core/src/lib/runtime/gr_basic_block.h b/gnuradio-core/src/lib/runtime/gr_basic_block.h index 4d03b878e..f3b7b835b 100644 --- a/gnuradio-core/src/lib/runtime/gr_basic_block.h +++ b/gnuradio-core/src/lib/runtime/gr_basic_block.h @@ -30,6 +30,13 @@ #include <boost/function.hpp> #include <gr_msg_accepter.h> #include <string> +#include <deque> +#include <map> +#include <gr_io_signature.h> +#include <gruel/thread.h> +#include <boost/foreach.hpp> +#include <boost/thread/condition_variable.hpp> +#include <iostream> /*! * \brief The abstract base class for all signal processing blocks. @@ -44,111 +51,215 @@ class GR_CORE_API gr_basic_block : public gr_msg_accepter, public boost::enable_shared_from_this<gr_basic_block> { - typedef boost::function<void(pmt::pmt_t)> msg_handler_t; + typedef boost::function<void(pmt::pmt_t)> msg_handler_t; + + private: + /* + * This function is called by the runtime system to dispatch messages. + * + * The thread-safety guarantees mentioned in set_msg_handler are implemented + * by the callers of this method. + */ + void dispatch_msg(pmt::pmt_t which_port, pmt::pmt_t msg) + { + // AA Update this + if (d_msg_handlers.find(which_port) != d_msg_handlers.end()) // Is there a handler? + d_msg_handlers[which_port](msg); // Yes, invoke it. + }; + + //msg_handler_t d_msg_handler; + typedef std::map<pmt::pmt_t , msg_handler_t, pmt::pmt_comperator> d_msg_handlers_t; + d_msg_handlers_t d_msg_handlers; + + typedef std::deque<pmt::pmt_t> msg_queue_t; + typedef std::map<pmt::pmt_t, msg_queue_t, pmt::pmt_comperator> msg_queue_map_t; + typedef std::map<pmt::pmt_t, msg_queue_t, pmt::pmt_comperator>::iterator msg_queue_map_itr; + std::map<pmt::pmt_t, boost::shared_ptr<boost::condition_variable>, pmt::pmt_comperator> msg_queue_ready; + + gruel::mutex mutex; //< protects all vars + + protected: + friend class gr_flowgraph; + friend class gr_flat_flowgraph; // TODO: will be redundant + friend class gr_tpb_thread_body; + + enum vcolor { WHITE, GREY, BLACK }; + + std::string d_name; + gr_io_signature_sptr d_input_signature; + gr_io_signature_sptr d_output_signature; + long d_unique_id; + long d_symbolic_id; + std::string d_symbol_name; + std::string d_symbol_alias; + vcolor d_color; + msg_queue_map_t msg_queue; + + gr_basic_block(void){} //allows pure virtual interface sub-classes + + //! Protected constructor prevents instantiation by non-derived classes + gr_basic_block(const std::string &name, + gr_io_signature_sptr input_signature, + gr_io_signature_sptr output_signature); + + //! may only be called during constructor + void set_input_signature(gr_io_signature_sptr iosig) { + d_input_signature = iosig; + } + + //! may only be called during constructor + void set_output_signature(gr_io_signature_sptr iosig) { + d_output_signature = iosig; + } + + /*! + * \brief Allow the flowgraph to set for sorting and partitioning + */ + void set_color(vcolor color) { d_color = color; } + vcolor color() const { return d_color; } + + // Message passing interface + pmt::pmt_t message_subscribers; + + public: + virtual ~gr_basic_block(); + long unique_id() const { return d_unique_id; } + long symbolic_id() const { return d_symbolic_id; } + std::string name() const { return d_name; } + std::string symbol_name() const { return d_symbol_name; } + gr_io_signature_sptr input_signature() const { return d_input_signature; } + gr_io_signature_sptr output_signature() const { return d_output_signature; } + gr_basic_block_sptr to_basic_block(); // Needed for Python type coercion + bool alias_set() { return !d_symbol_alias.empty(); } + std::string alias(){ return alias_set()?d_symbol_alias:symbol_name(); } + pmt::pmt_t alias_pmt(){ return pmt::pmt_intern(alias()); } + void set_block_alias(std::string name); + + // ** Message passing interface ** + void message_port_register_in(pmt::pmt_t port_id); + void message_port_register_out(pmt::pmt_t port_id); + void message_port_pub(pmt::pmt_t port_id, pmt::pmt_t msg); + void message_port_sub(pmt::pmt_t port_id, pmt::pmt_t target); + void message_port_unsub(pmt::pmt_t port_id, pmt::pmt_t target); + + virtual bool message_port_is_hier(pmt::pmt_t port_id) { std::cout << "is_hier\n"; return false; } + virtual bool message_port_is_hier_in(pmt::pmt_t port_id) { std::cout << "is_hier_in\n"; return false; } + virtual bool message_port_is_hier_out(pmt::pmt_t port_id) { std::cout << "is_hier_out\n"; return false; } + + /*! + * \brief Get input message port names. + * + * Returns the available input message ports for a block. The + * return object is a PMT vector that is filled with PMT symbols. + */ + pmt::pmt_t message_ports_in(); + + /*! + * \brief Get output message port names. + * + * Returns the available output message ports for a block. The + * return object is a PMT vector that is filled with PMT symbols. + */ + pmt::pmt_t message_ports_out(); + + /*! + * Accept msg, place in queue, arrange for thread to be awakened if it's not already. + */ + void _post(pmt::pmt_t which_port, pmt::pmt_t msg); + + //! is the queue empty? + //bool empty_p(const pmt::pmt_t &which_port) const { return msg_queue[which_port].empty(); } + bool empty_p(pmt::pmt_t which_port) { + if(msg_queue.find(which_port) == msg_queue.end()) + throw std::runtime_error("port does not exist!"); + return msg_queue[which_port].empty(); + } + bool empty_p() { + bool rv = true; + BOOST_FOREACH(msg_queue_map_t::value_type &i, msg_queue){ rv &= msg_queue[i.first].empty(); } + return rv; + } + + //| Acquires and release the mutex + void insert_tail( pmt::pmt_t which_port, pmt::pmt_t msg); + /*! + * \returns returns pmt at head of queue or pmt_t() if empty. + */ + pmt::pmt_t delete_head_nowait( pmt::pmt_t which_port); + + /*! + * \returns returns pmt at head of queue or pmt_t() if empty. + */ + pmt::pmt_t delete_head_blocking( pmt::pmt_t which_port); + + msg_queue_t::iterator get_iterator(pmt::pmt_t which_port){ + return msg_queue[which_port].begin(); + } -private: - /* - * This function is called by the runtime system to dispatch messages. - * - * The thread-safety guarantees mentioned in set_msg_handler are implemented - * by the callers of this method. - */ - void dispatch_msg(pmt::pmt_t msg) - { - if (d_msg_handler) // Is there a handler? - d_msg_handler(msg); // Yes, invoke it. - }; - - msg_handler_t d_msg_handler; - -protected: - friend class gr_flowgraph; - friend class gr_flat_flowgraph; // TODO: will be redundant - friend class gr_tpb_thread_body; - - enum vcolor { WHITE, GREY, BLACK }; - - std::string d_name; - gr_io_signature_sptr d_input_signature; - gr_io_signature_sptr d_output_signature; - long d_unique_id; - vcolor d_color; - - gr_basic_block(void){} //allows pure virtual interface sub-classes - - //! Protected constructor prevents instantiation by non-derived classes - gr_basic_block(const std::string &name, - gr_io_signature_sptr input_signature, - gr_io_signature_sptr output_signature); - - //! may only be called during constructor - void set_input_signature(gr_io_signature_sptr iosig) { - d_input_signature = iosig; + void erase_msg(pmt::pmt_t which_port, msg_queue_t::iterator it){ + msg_queue[which_port].erase(it); + } + + virtual bool has_msg_port(pmt::pmt_t which_port){ + if(msg_queue.find(which_port) != msg_queue.end()){ + return true; } - - //! may only be called during constructor - void set_output_signature(gr_io_signature_sptr iosig) { - d_output_signature = iosig; - } - - /*! - * \brief Allow the flowgraph to set for sorting and partitioning - */ - void set_color(vcolor color) { d_color = color; } - vcolor color() const { return d_color; } - -public: - virtual ~gr_basic_block(); - long unique_id() const { return d_unique_id; } - std::string name() const { return d_name; } - gr_io_signature_sptr input_signature() const { return d_input_signature; } - gr_io_signature_sptr output_signature() const { return d_output_signature; } - gr_basic_block_sptr to_basic_block(); // Needed for Python type coercion - - /*! - * \brief Confirm that ninputs and noutputs is an acceptable combination. - * - * \param ninputs number of input streams connected - * \param noutputs number of output streams connected - * - * \returns true if this is a valid configuration for this block. - * - * This function is called by the runtime system whenever the - * topology changes. Most classes do not need to override this. - * This check is in addition to the constraints specified by the input - * and output gr_io_signatures. - */ - virtual bool check_topology(int ninputs, int noutputs) { return true; } - - /*! - * \brief Set the callback that is fired when messages are available. - * - * \p msg_handler can be any kind of function pointer or function object - * that has the signature: - * <pre> - * void msg_handler(pmt::pmt msg); - * </pre> - * - * (You may want to use boost::bind to massage your callable into the - * correct form. See gr_nop.{h,cc} for an example that sets up a class - * method as the callback.) - * - * Blocks that desire to handle messages must call this method in their - * constructors to register the handler that will be invoked when messages - * are available. - * - * If the block inherits from gr_block, the runtime system will ensure that - * msg_handler is called in a thread-safe manner, such that work and - * msg_handler will never be called concurrently. This allows msg_handler - * to update state variables without having to worry about thread-safety - * issues with work, general_work or another invocation of msg_handler. - * - * If the block inherits from gr_hier_block2, the runtime system will - * ensure that no reentrant calls are made to msg_handler. - */ - template <typename T> void set_msg_handler(T msg_handler){ - d_msg_handler = msg_handler_t(msg_handler); + if(pmt::pmt_dict_has_key(message_subscribers, which_port)){ + return true; } + return false; + } + + + /*! + * \brief Confirm that ninputs and noutputs is an acceptable combination. + * + * \param ninputs number of input streams connected + * \param noutputs number of output streams connected + * + * \returns true if this is a valid configuration for this block. + * + * This function is called by the runtime system whenever the + * topology changes. Most classes do not need to override this. + * This check is in addition to the constraints specified by the input + * and output gr_io_signatures. + */ + virtual bool check_topology(int ninputs, int noutputs) { return true; } + + /*! + * \brief Set the callback that is fired when messages are available. + * + * \p msg_handler can be any kind of function pointer or function object + * that has the signature: + * <pre> + * void msg_handler(pmt::pmt msg); + * </pre> + * + * (You may want to use boost::bind to massage your callable into the + * correct form. See gr_nop.{h,cc} for an example that sets up a class + * method as the callback.) + * + * Blocks that desire to handle messages must call this method in their + * constructors to register the handler that will be invoked when messages + * are available. + * + * If the block inherits from gr_block, the runtime system will ensure that + * msg_handler is called in a thread-safe manner, such that work and + * msg_handler will never be called concurrently. This allows msg_handler + * to update state variables without having to worry about thread-safety + * issues with work, general_work or another invocation of msg_handler. + * + * If the block inherits from gr_hier_block2, the runtime system will + * ensure that no reentrant calls are made to msg_handler. + */ + //template <typename T> void set_msg_handler(T msg_handler){ + // d_msg_handler = msg_handler_t(msg_handler); + //} + template <typename T> void set_msg_handler(pmt::pmt_t which_port, T msg_handler){ + if(msg_queue.find(which_port) == msg_queue.end()){ + throw std::runtime_error("attempt to set_msg_handler() on bad input message port!"); } + d_msg_handlers[which_port] = msg_handler_t(msg_handler); + } }; inline bool operator<(gr_basic_block_sptr lhs, gr_basic_block_sptr rhs) @@ -163,8 +274,8 @@ GR_CORE_API long gr_basic_block_ncurrently_allocated(); inline std::ostream &operator << (std::ostream &os, gr_basic_block_sptr basic_block) { - os << basic_block->name() << "(" << basic_block->unique_id() << ")"; - return os; + os << basic_block->name() << "(" << basic_block->unique_id() << ")"; + return os; } #endif /* INCLUDED_GR_BASIC_BLOCK_H */ diff --git a/gnuradio-core/src/lib/runtime/gr_basic_block.i b/gnuradio-core/src/lib/runtime/gr_basic_block.i index e43cc114c..62f16462d 100644 --- a/gnuradio-core/src/lib/runtime/gr_basic_block.i +++ b/gnuradio-core/src/lib/runtime/gr_basic_block.i @@ -23,6 +23,8 @@ class gr_basic_block; typedef boost::shared_ptr<gr_basic_block> gr_basic_block_sptr; %template(gr_basic_block_sptr) boost::shared_ptr<gr_basic_block>; +%include "pmt_swig.i" +using namespace pmt; // support vectors of these... namespace std { @@ -37,11 +39,17 @@ protected: public: virtual ~gr_basic_block(); std::string name() const; + std::string symbol_name() const; gr_io_signature_sptr input_signature() const; gr_io_signature_sptr output_signature() const; long unique_id() const; gr_basic_block_sptr to_basic_block(); bool check_topology (int ninputs, int noutputs); + std::string alias(); + void set_block_alias(std::string name); + void _post(pmt_t which_port, pmt_t msg); + pmt_t message_ports_in(); + pmt_t message_ports_out(); }; %rename(block_ncurrently_allocated) gr_basic_block_ncurrently_allocated; diff --git a/gnuradio-core/src/lib/runtime/gr_block.cc b/gnuradio-core/src/lib/runtime/gr_block.cc index 9a5255a93..43aebf0bf 100644 --- a/gnuradio-core/src/lib/runtime/gr_block.cc +++ b/gnuradio-core/src/lib/runtime/gr_block.cc @@ -28,6 +28,7 @@ #include <gr_block_detail.h> #include <stdexcept> #include <iostream> +#include <gr_block_registry.h> gr_block::gr_block (const std::string &name, gr_io_signature_sptr input_signature, @@ -40,12 +41,18 @@ gr_block::gr_block (const std::string &name, d_relative_rate (1.0), d_history(1), d_fixed_rate(false), - d_tag_propagation_policy(TPP_ALL_TO_ALL) + d_max_noutput_items_set(false), + d_max_noutput_items(0), + d_tag_propagation_policy(TPP_ALL_TO_ALL), + d_max_output_buffer(std::max(output_signature->max_streams(),1), -1), + d_min_output_buffer(std::max(output_signature->max_streams(),1), -1) { + global_block_registry.register_primitive(alias(), this); } gr_block::~gr_block () { + global_block_registry.unregister_primitive(alias()); } // stub implementation: 1:1 @@ -208,6 +215,35 @@ gr_block::set_tag_propagation_policy(tag_propagation_policy_t p) d_tag_propagation_policy = p; } + +int +gr_block::max_noutput_items() +{ + return d_max_noutput_items; +} + +void +gr_block::set_max_noutput_items(int m) +{ + if(m <= 0) + throw std::runtime_error("gr_block::set_max_noutput_items: value for max_noutput_items must be greater than 0.\n"); + + d_max_noutput_items = m; + d_max_noutput_items_set = true; +} + +void +gr_block::unset_max_noutput_items() +{ + d_max_noutput_items_set = false; +} + +bool +gr_block::is_set_max_noutput_items() +{ + return d_max_noutput_items_set; +} + std::ostream& operator << (std::ostream& os, const gr_block *m) { @@ -215,3 +251,12 @@ operator << (std::ostream& os, const gr_block *m) return os; } +int +gr_block::general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + throw std::runtime_error("gr_block::general_work() not implemented"); + return 0; +} diff --git a/gnuradio-core/src/lib/runtime/gr_block.h b/gnuradio-core/src/lib/runtime/gr_block.h index 71ac8eee6..57e3fda90 100644 --- a/gnuradio-core/src/lib/runtime/gr_block.h +++ b/gnuradio-core/src/lib/runtime/gr_block.h @@ -124,7 +124,7 @@ class GR_CORE_API gr_block : public gr_basic_block { virtual int general_work (int noutput_items, gr_vector_int &ninput_items, gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) = 0; + gr_vector_void_star &output_items); /*! * \brief Called to enable drivers, etc for i/o devices. @@ -251,6 +251,113 @@ class GR_CORE_API gr_block : public gr_basic_block { */ void set_tag_propagation_policy(tag_propagation_policy_t p); + /*! + * \brief Return the maximum number of output items this block will + * handle during a call to work. + */ + int max_noutput_items(); + + /*! + * \brief Set the maximum number of ouput items htis block will + * handle during a call to work. + * + * \param m the maximum noutput_items this block will handle. + */ + void set_max_noutput_items(int m); + + /*! + * \brief Clear the switch for using the max_noutput_items value of this block. + * + * When is_set_max_noutput_items() returns 'true', the scheduler + * will use the value returned by max_noutput_items() to limit the + * size of the number of items possible for this block's work + * function. If is_set_max_notput_items() returns 'false', then the + * scheduler ignores the internal value and uses the value set + * globally in the top_block. + * + * Use this value to clear the 'is_set' flag so the scheduler will + * ignore this. Use the set_max_noutput_items(m) call to both set a + * new value for max_noutput_items and to reenable its use in the + * scheduler. + */ + void unset_max_noutput_items(); + + /*! + * \brief Ask the block if the flag is or is not set to use the + * internal value of max_noutput_items during a call to work. + */ + bool is_set_max_noutput_items(); + + /* + * Used to expand the vectors that hold the min/max buffer sizes. + * + * Specifically, when -1 is used, the vectors are just initialized + * with 1 value; this is used by the flat_flowgraph to expand when + * required to add a new value for new ports on these blocks. + */ + void expand_minmax_buffer(int port) { + if((size_t)port >= d_max_output_buffer.size()) + set_max_output_buffer(port, -1); + if((size_t)port >= d_min_output_buffer.size()) + set_min_output_buffer(port, -1); + } + + /*! + * \brief Returns max buffer size on output port \p i. + */ + long max_output_buffer(size_t i) { + if(i >= d_max_output_buffer.size()) + throw std::invalid_argument("gr_basic_block::max_output_buffer: port out of range."); + return d_max_output_buffer[i]; + } + + /*! + * \brief Sets max buffer size on all output ports. + */ + void set_max_output_buffer(long max_output_buffer) { + for(int i = 0; i < output_signature()->max_streams(); i++) { + set_max_output_buffer(i, max_output_buffer); + } + } + + /*! + * \brief Sets max buffer size on output port \p port. + */ + void set_max_output_buffer(int port, long max_output_buffer) { + if((size_t)port >= d_max_output_buffer.size()) + d_max_output_buffer.push_back(max_output_buffer); + else + d_max_output_buffer[port] = max_output_buffer; + } + + /*! + * \brief Returns min buffer size on output port \p i. + */ + long min_output_buffer(size_t i) { + if(i >= d_min_output_buffer.size()) + throw std::invalid_argument("gr_basic_block::min_output_buffer: port out of range."); + return d_min_output_buffer[i]; + } + + /*! + * \brief Sets min buffer size on all output ports. + */ + void set_min_output_buffer(long min_output_buffer) { + for(int i=0; i<output_signature()->max_streams(); i++) { + set_min_output_buffer(i, min_output_buffer); + } + } + + /*! + * \brief Sets min buffer size on output port \p port. + */ + void set_min_output_buffer(int port, long min_output_buffer) { + if((size_t)port >= d_min_output_buffer.size()) + d_min_output_buffer.push_back(min_output_buffer); + else + d_min_output_buffer[port] = min_output_buffer; + } + // ---------------------------------------------------------------------------- private: @@ -263,6 +370,8 @@ class GR_CORE_API gr_block : public gr_basic_block { gr_block_detail_sptr d_detail; // implementation details unsigned d_history; bool d_fixed_rate; + bool d_max_noutput_items_set; // if d_max_noutput_items is valid + int d_max_noutput_items; // value of max_noutput_items for this block tag_propagation_policy_t d_tag_propagation_policy; // policy for moving tags downstream protected: @@ -345,6 +454,10 @@ class GR_CORE_API gr_block : public gr_basic_block { uint64_t abs_end, const pmt::pmt_t &key); + std::vector<long> d_max_output_buffer; + std::vector<long> d_min_output_buffer; + + // These are really only for internal use, but leaving them public avoids // having to work up an ever-varying list of friend GR_CORE_APIs diff --git a/gnuradio-core/src/lib/runtime/gr_block.i b/gnuradio-core/src/lib/runtime/gr_block.i index 4cc260bfe..db6c1d04a 100644 --- a/gnuradio-core/src/lib/runtime/gr_block.i +++ b/gnuradio-core/src/lib/runtime/gr_block.i @@ -52,6 +52,20 @@ class gr_block : public gr_basic_block { uint64_t nitems_read(unsigned int which_input); uint64_t nitems_written(unsigned int which_output); + // Methods to manage the block's max_noutput_items size. + int max_noutput_items(); + void set_max_noutput_items(int m); + void unset_max_noutput_items(); + bool is_set_max_noutput_items(); + + // Methods to manage block's min/max buffer sizes. + long max_output_buffer(int i); + void set_max_output_buffer(long max_output_buffer); + void set_max_output_buffer(int port, long max_output_buffer); + long min_output_buffer(int i); + void set_min_output_buffer(long min_output_buffer); + void set_min_output_buffer(int port, long min_output_buffer); + // internal use gr_block_detail_sptr detail () const { return d_detail; } void set_detail (gr_block_detail_sptr detail) { d_detail = detail; } diff --git a/gnuradio-core/src/lib/runtime/gr_block_detail.cc b/gnuradio-core/src/lib/runtime/gr_block_detail.cc index 2792cd471..337c9518e 100644 --- a/gnuradio-core/src/lib/runtime/gr_block_detail.cc +++ b/gnuradio-core/src/lib/runtime/gr_block_detail.cc @@ -127,12 +127,6 @@ gr_block_detail::produce_each (int how_many_items) } -void -gr_block_detail::_post(pmt_t msg) -{ - d_tpb.insert_tail(msg); -} - uint64_t gr_block_detail::nitems_read(unsigned int which_input) { diff --git a/gnuradio-core/src/lib/runtime/gr_block_detail.h b/gnuradio-core/src/lib/runtime/gr_block_detail.h index c96f00db8..16d9f4d42 100644 --- a/gnuradio-core/src/lib/runtime/gr_block_detail.h +++ b/gnuradio-core/src/lib/runtime/gr_block_detail.h @@ -85,11 +85,6 @@ class GR_CORE_API gr_block_detail { */ void produce_each (int how_many_items); - /*! - * Accept msg, place in queue, arrange for thread to be awakened if it's not already. - */ - void _post(pmt::pmt_t msg); - // Return the number of items read on input stream which_input uint64_t nitems_read(unsigned int which_input); diff --git a/gnuradio-core/src/lib/runtime/gr_block_executor.cc b/gnuradio-core/src/lib/runtime/gr_block_executor.cc index 6fea14613..375b58f56 100644 --- a/gnuradio-core/src/lib/runtime/gr_block_executor.cc +++ b/gnuradio-core/src/lib/runtime/gr_block_executor.cc @@ -206,7 +206,7 @@ gr_block_executor::run_one_iteration() // determine the minimum available output space noutput_items = min_available_space (d, m->output_multiple ()); - noutput_items = std::min(noutput_items, d_max_noutput_items); + noutput_items = std::min(noutput_items, max_noutput_items); LOG(*d_log << " source\n noutput_items = " << noutput_items << std::endl); if (noutput_items == -1) // we're done goto were_done; @@ -251,7 +251,7 @@ gr_block_executor::run_one_iteration() // take a swag at how much output we can sink noutput_items = (int) (max_items_avail * m->relative_rate ()); noutput_items = round_down (noutput_items, m->output_multiple ()); - noutput_items = std::min(noutput_items, d_max_noutput_items); + noutput_items = std::min(noutput_items, max_noutput_items); LOG(*d_log << " max_items_avail = " << max_items_avail << std::endl); LOG(*d_log << " noutput_items = " << noutput_items << std::endl); @@ -449,6 +449,7 @@ gr_block_executor::run_one_iteration() // We didn't produce any output even though we called general_work. // We have (most likely) consumed some input. + /* // If this is a source, it's broken. if (d->source_p()){ std::cerr << "gr_block_executor: source " << m @@ -456,6 +457,7 @@ gr_block_executor::run_one_iteration() // FIXME maybe we ought to raise an exception... goto were_done; } + */ // Have the caller try again... return READY_NO_OUTPUT; diff --git a/gnuradio-core/src/lib/runtime/gr_block_registry.cc b/gnuradio-core/src/lib/runtime/gr_block_registry.cc new file mode 100644 index 000000000..ff23d97eb --- /dev/null +++ b/gnuradio-core/src/lib/runtime/gr_block_registry.cc @@ -0,0 +1,76 @@ +#include <gr_basic_block.h> +#include <gr_block_registry.h> +#include <gr_tpb_detail.h> +#include <gr_block_detail.h> +#include <gr_block.h> +#include <stdio.h> + +gr_block_registry global_block_registry; + +gr_block_registry::gr_block_registry(){ + d_ref_map = pmt::pmt_make_dict(); +} + +long gr_block_registry::block_register(gr_basic_block* block){ + if(d_map.find(block->name()) == d_map.end()){ + d_map[block->name()] = blocksubmap_t(); + d_map[block->name()][0] = block; + return 0; + } else { + for(size_t i=0; i<=d_map[block->name()].size(); i++){ + if(d_map[block->name()].find(i) == d_map[block->name()].end()){ + d_map[block->name()][i] = block; + return i; + } + } + } + throw std::runtime_error("should not reach this"); +} + +void gr_block_registry::block_unregister(gr_basic_block* block){ + d_map[block->name()].erase( d_map[block->name()].find(block->symbolic_id())); + d_ref_map = pmt::pmt_dict_delete(d_ref_map, pmt::pmt_intern(block->symbol_name())); + if(block->alias_set()){ + d_ref_map = pmt::pmt_dict_delete(d_ref_map, pmt::pmt_intern(block->alias())); + } +} + +std::string gr_block_registry::register_symbolic_name(gr_basic_block* block){ + std::stringstream ss; + ss << block->name() << block->symbolic_id(); + //std::cout << "register_symbolic_name: " << ss.str() << std::endl; + register_symbolic_name(block, ss.str()); + return ss.str(); +} + +void gr_block_registry::register_symbolic_name(gr_basic_block* block, std::string name){ + if(pmt_dict_has_key(d_ref_map, pmt::pmt_intern(name))){ + throw std::runtime_error("symbol already exists, can not re-use!"); + } + d_ref_map = pmt_dict_add(d_ref_map, pmt::pmt_intern(name), pmt::pmt_make_any(block)); +} + +gr_basic_block_sptr gr_block_registry::block_lookup(pmt::pmt_t symbol){ + pmt::pmt_t ref = pmt_dict_ref(d_ref_map, symbol, pmt::PMT_NIL); + if(pmt::pmt_eq(ref, pmt::PMT_NIL)){ + throw std::runtime_error("block lookup failed! block not found!"); + } + gr_basic_block* blk = boost::any_cast<gr_basic_block*>( pmt::pmt_any_ref(ref) ); + return blk->shared_from_this(); +} + + +void gr_block_registry::register_primitive(std::string blk, gr_block* ref){ + primitive_map[blk] = ref; +} + +void gr_block_registry::unregister_primitive(std::string blk){ + primitive_map.erase(primitive_map.find(blk)); +} + +void gr_block_registry::notify_blk(std::string blk){ + if(primitive_map.find(blk) == primitive_map.end()){ return; } + if(primitive_map[blk]->detail().get()) + primitive_map[blk]->detail()->d_tpb.notify_msg(); +} + diff --git a/gnuradio-core/src/lib/runtime/gr_block_registry.h b/gnuradio-core/src/lib/runtime/gr_block_registry.h new file mode 100644 index 000000000..6a2d939e5 --- /dev/null +++ b/gnuradio-core/src/lib/runtime/gr_block_registry.h @@ -0,0 +1,42 @@ +#ifndef GR_BLOCK_REGISTRY_H +#define GR_BLOCK_REGISTRY_H + +#include <map> + +#ifndef GR_BASIC_BLOCK_H +class gr_basic_block; +class gr_block; +#endif + +class gr_block_registry { + public: + gr_block_registry(); + + long block_register(gr_basic_block* block); + void block_unregister(gr_basic_block* block); + + std::string register_symbolic_name(gr_basic_block* block); + void register_symbolic_name(gr_basic_block* block, std::string name); + + gr_basic_block_sptr block_lookup(pmt::pmt_t symbol); + + void register_primitive(std::string blk, gr_block* ref); + void unregister_primitive(std::string blk); + void notify_blk(std::string blk); + + private: + + //typedef std::map< long, gr_basic_block_sptr > blocksubmap_t; + typedef std::map< long, gr_basic_block* > blocksubmap_t; + typedef std::map< std::string, blocksubmap_t > blockmap_t; + + blockmap_t d_map; + pmt::pmt_t d_ref_map; + std::map< std::string, gr_block*> primitive_map; + +}; + +extern gr_block_registry global_block_registry; + +#endif + diff --git a/gnuradio-core/src/lib/runtime/gr_flat_flowgraph.cc b/gnuradio-core/src/lib/runtime/gr_flat_flowgraph.cc index 9005cd339..9294a5dca 100644 --- a/gnuradio-core/src/lib/runtime/gr_flat_flowgraph.cc +++ b/gnuradio-core/src/lib/runtime/gr_flat_flowgraph.cc @@ -31,8 +31,9 @@ #include <volk/volk.h> #include <iostream> #include <map> +#include <boost/format.hpp> -#define GR_FLAT_FLOWGRAPH_DEBUG 0 +#define GR_FLAT_FLOWGRAPH_DEBUG 0 // 32Kbyte buffer size between blocks #define GR_FIXED_BUFFER_SIZE (32*(1L<<10)) @@ -71,6 +72,15 @@ gr_flat_flowgraph::setup_connections() block->set_is_unaligned(false); } + // Connect message ports connetions + for(gr_msg_edge_viter_t i = d_msg_edges.begin(); i != d_msg_edges.end(); i++){ + if(GR_FLAT_FLOWGRAPH_DEBUG) + std::cout << boost::format("flat_fg connecting msg primitives: (%s, %s)->(%s, %s)\n") % + i->src().block() % i->src().port() % + i->dst().block() % i->dst().port(); + i->src().block()->message_port_sub( i->src().port(), pmt::pmt_cons(i->dst().block()->alias_pmt(), i->dst().port()) ); + } + } gr_block_detail_sptr @@ -80,14 +90,23 @@ gr_flat_flowgraph::allocate_block_detail(gr_basic_block_sptr block) int noutputs = calc_used_ports(block, false).size(); gr_block_detail_sptr detail = gr_make_block_detail(ninputs, noutputs); + gr_block_sptr grblock = cast_to_block_sptr(block); + if(!grblock) + throw std::runtime_error("allocate_block_detail found non-gr_block"); + if (GR_FLAT_FLOWGRAPH_DEBUG) std::cout << "Creating block detail for " << block << std::endl; for (int i = 0; i < noutputs; i++) { + grblock->expand_minmax_buffer(i); + gr_buffer_sptr buffer = allocate_buffer(block, i); if (GR_FLAT_FLOWGRAPH_DEBUG) std::cout << "Allocated buffer for output " << block << ":" << i << std::endl; detail->set_output(i, buffer); + + // Update the block's max_output_buffer based on what was actually allocated. + grblock->set_max_output_buffer(i, buffer->bufsize()); } return detail; @@ -114,6 +133,21 @@ gr_flat_flowgraph::allocate_buffer(gr_basic_block_sptr block, int port) // ensure we have a buffer at least twice their decimation factor*output_multiple gr_basic_block_vector_t blocks = calc_downstream_blocks(block, port); + // limit buffer size if indicated + if(grblock->max_output_buffer(port) > 0) { +// std::cout << "constraining output items to " << block->max_output_buffer(port) << "\n"; + nitems = std::min((long)nitems, (long)grblock->max_output_buffer(port)); + nitems -= nitems%grblock->output_multiple(); + if( nitems < 1 ) + throw std::runtime_error("problems allocating a buffer with the given max output buffer constraint!"); + } + else if(grblock->min_output_buffer(port) > 0) { + nitems = std::max((long)nitems, (long)grblock->min_output_buffer(port)); + nitems -= nitems%grblock->output_multiple(); + if( nitems < 1 ) + throw std::runtime_error("problems allocating a buffer with the given min output buffer constraint!"); + } + for (gr_basic_block_viter_t p = blocks.begin(); p != blocks.end(); p++) { gr_block_sptr dgrblock = cast_to_block_sptr(*p); if (!dgrblock) @@ -125,6 +159,7 @@ gr_flat_flowgraph::allocate_buffer(gr_basic_block_sptr block, int port) nitems = std::max(nitems, static_cast<int>(2*(decimation*multiple+history))); } +// std::cout << "gr_make_buffer(" << nitems << ", " << item_size << ", " << grblock << "\n"; return gr_make_buffer(nitems, item_size, grblock); } @@ -325,3 +360,44 @@ gr_flat_flowgraph::make_block_vector(gr_basic_block_vector_t &blocks) return result; } + + +void gr_flat_flowgraph::clear_endpoint(const gr_msg_endpoint &e, bool is_src){ + for(size_t i=0; i<d_msg_edges.size(); i++){ + if(is_src){ + if(d_msg_edges[i].src() == e){ + d_msg_edges.erase(d_msg_edges.begin() + i); + i--; + } + } else { + if(d_msg_edges[i].dst() == e){ + d_msg_edges.erase(d_msg_edges.begin() + i); + i--; + } + } + } +} + +void gr_flat_flowgraph::replace_endpoint(const gr_msg_endpoint &e, const gr_msg_endpoint &r, bool is_src){ + size_t n_replr(0); + if(GR_FLAT_FLOWGRAPH_DEBUG) + std::cout << boost::format("gr_flat_flowgraph::replace_endpoint( %s, %s, %d )\n") % e.block()% r.block()% is_src; + for(size_t i=0; i<d_msg_edges.size(); i++){ + if(is_src){ + if(d_msg_edges[i].src() == e){ + if(GR_FLAT_FLOWGRAPH_DEBUG) + std::cout << boost::format("gr_flat_flowgraph::replace_endpoint() flattening to ( %s, %s )\n") % r.block()% d_msg_edges[i].dst().block(); + d_msg_edges.push_back( gr_msg_edge(r, d_msg_edges[i].dst() ) ); + n_replr++; + } + } else { + if(d_msg_edges[i].dst() == e){ + if(GR_FLAT_FLOWGRAPH_DEBUG) + std::cout << boost::format("gr_flat_flowgraph::replace_endpoint() flattening to ( %s, %s )\n") % r.block()% d_msg_edges[i].dst().block(); + d_msg_edges.push_back( gr_msg_edge(d_msg_edges[i].src(), r ) ); + n_replr++; + } + } + } +} + diff --git a/gnuradio-core/src/lib/runtime/gr_flat_flowgraph.h b/gnuradio-core/src/lib/runtime/gr_flat_flowgraph.h index 0926bcc8f..5c8268d7d 100644 --- a/gnuradio-core/src/lib/runtime/gr_flat_flowgraph.h +++ b/gnuradio-core/src/lib/runtime/gr_flat_flowgraph.h @@ -46,7 +46,7 @@ public: // Wire gr_blocks together in new flat_flowgraph void setup_connections(); - + // Merge applicable connections from existing flat flowgraph void merge_connections(gr_flat_flowgraph_sptr sfg); @@ -57,6 +57,9 @@ public: */ static gr_block_vector_t make_block_vector(gr_basic_block_vector_t &blocks); + void replace_endpoint(const gr_msg_endpoint &e, const gr_msg_endpoint &r, bool is_src); + void clear_endpoint(const gr_msg_endpoint &e, bool is_src); + private: gr_flat_flowgraph(); diff --git a/gnuradio-core/src/lib/runtime/gr_flowgraph.cc b/gnuradio-core/src/lib/runtime/gr_flowgraph.cc index 78e1bc99a..63a208480 100644 --- a/gnuradio-core/src/lib/runtime/gr_flowgraph.cc +++ b/gnuradio-core/src/lib/runtime/gr_flowgraph.cc @@ -149,6 +149,16 @@ gr_flowgraph::check_valid_port(gr_io_signature_sptr sig, int port) } } +void +gr_flowgraph::check_valid_port(const gr_msg_endpoint &e) +{ + if (GR_FLOWGRAPH_DEBUG) + std::cout << "check_valid_port( " << e.block() << ", " << e.port() << ")\n"; + + if(!e.block()->has_msg_port(e.port())) + throw std::invalid_argument("invalid msg port in connect() or disconnect()"); +} + void gr_flowgraph::check_dst_not_used(const gr_endpoint &dst) { @@ -180,6 +190,13 @@ gr_flowgraph::calc_used_blocks() { gr_basic_block_vector_t tmp; + // make sure free standing message blocks are included + for (gr_msg_edge_viter_t p = d_msg_edges.begin(); p != d_msg_edges.end(); p++) { +// for now only blocks receiving messages get a thread context - uncomment to allow senders to also obtain one +// tmp.push_back(p->src().block()); + tmp.push_back(p->dst().block()); + } + // Collect all blocks in the edge list for (gr_edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++) { tmp.push_back(p->src().block()); @@ -472,3 +489,27 @@ gr_flowgraph::topological_dfs_visit(gr_basic_block_sptr block, gr_basic_block_ve output.push_back(block); } +void gr_flowgraph::connect(const gr_msg_endpoint &src, const gr_msg_endpoint &dst){ + check_valid_port(src); + check_valid_port(dst); + for (gr_msg_edge_viter_t p = d_msg_edges.begin(); p != d_msg_edges.end(); p++) { + if(p->src() == src && p->dst() == dst){ + throw std::runtime_error("connect called on already connected edge!"); + } + } + d_msg_edges.push_back(gr_msg_edge(src,dst)); +} + +void gr_flowgraph::disconnect(const gr_msg_endpoint &src, const gr_msg_endpoint &dst){ + check_valid_port(src); + check_valid_port(dst); + for (gr_msg_edge_viter_t p = d_msg_edges.begin(); p != d_msg_edges.end(); p++) { + if(p->src() == src && p->dst() == dst){ + d_msg_edges.erase(p); + return; + } + } + throw std::runtime_error("disconnect called on non-connected edge!"); +} + + diff --git a/gnuradio-core/src/lib/runtime/gr_flowgraph.h b/gnuradio-core/src/lib/runtime/gr_flowgraph.h index a2c1580eb..bef70f626 100644 --- a/gnuradio-core/src/lib/runtime/gr_flowgraph.h +++ b/gnuradio-core/src/lib/runtime/gr_flowgraph.h @@ -52,6 +52,31 @@ inline bool gr_endpoint::operator==(const gr_endpoint &other) const d_port == other.d_port); } +class GR_CORE_API gr_msg_endpoint +{ +private: + gr_basic_block_sptr d_basic_block; + pmt::pmt_t d_port; + bool d_is_hier; +public: + gr_msg_endpoint() : d_basic_block(), d_port(pmt::PMT_NIL) { } + gr_msg_endpoint(gr_basic_block_sptr block, pmt::pmt_t port, bool is_hier=false){ d_basic_block = block; d_port = port; d_is_hier = is_hier;} + gr_basic_block_sptr block() const { return d_basic_block; } + pmt::pmt_t port() const { return d_port; } + bool is_hier() const { return d_is_hier; } + void set_hier(bool h) { d_is_hier = h; } + + bool operator==(const gr_msg_endpoint &other) const; + +}; + +inline bool gr_msg_endpoint::operator==(const gr_msg_endpoint &other) const +{ + return (d_basic_block == other.d_basic_block && + pmt::pmt_equal(d_port, other.d_port)); +} + + // Hold vectors of gr_endpoint objects typedef std::vector<gr_endpoint> gr_endpoint_vector_t; typedef std::vector<gr_endpoint>::iterator gr_endpoint_viter_t; @@ -75,11 +100,35 @@ private: gr_endpoint d_dst; }; + // Hold vectors of gr_edge objects typedef std::vector<gr_edge> gr_edge_vector_t; typedef std::vector<gr_edge>::iterator gr_edge_viter_t; +/*! + *\brief Class representing a msg connection between to graph msg endpoints + * + */ +class GR_CORE_API gr_msg_edge +{ +public: + gr_msg_edge() : d_src(), d_dst() { }; + gr_msg_edge(const gr_msg_endpoint &src, const gr_msg_endpoint &dst) : d_src(src), d_dst(dst) { } + ~gr_msg_edge() {} + + const gr_msg_endpoint &src() const { return d_src; } + const gr_msg_endpoint &dst() const { return d_dst; } + +private: + gr_msg_endpoint d_src; + gr_msg_endpoint d_dst; +}; + +// Hold vectors of gr_edge objects +typedef std::vector<gr_msg_edge> gr_msg_edge_vector_t; +typedef std::vector<gr_msg_edge>::iterator gr_msg_edge_viter_t; + // Create a shared pointer to a heap allocated flowgraph // (types defined in gr_runtime_types.h) GR_CORE_API gr_flowgraph_sptr gr_make_flowgraph(); @@ -110,6 +159,12 @@ public: void disconnect(gr_basic_block_sptr src_block, int src_port, gr_basic_block_sptr dst_block, int dst_port); + // Connect two msg endpoints + void connect(const gr_msg_endpoint &src, const gr_msg_endpoint &dst); + + // Disconnect two msg endpoints + void disconnect(const gr_msg_endpoint &src, const gr_msg_endpoint &dst); + // Validate connectivity, raise exception if invalid void validate(); @@ -118,6 +173,9 @@ public: // Return vector of edges const gr_edge_vector_t &edges() const { return d_edges; } + + // Return vector of msg edges + const gr_msg_edge_vector_t &msg_edges() const { return d_msg_edges; } // Return vector of connected blocks gr_basic_block_vector_t calc_used_blocks(); @@ -132,6 +190,7 @@ public: protected: gr_basic_block_vector_t d_blocks; gr_edge_vector_t d_edges; + gr_msg_edge_vector_t d_msg_edges; gr_flowgraph(); std::vector<int> calc_used_ports(gr_basic_block_sptr block, bool check_inputs); @@ -143,6 +202,7 @@ protected: private: void check_valid_port(gr_io_signature_sptr sig, int port); + void check_valid_port(const gr_msg_endpoint &e); void check_dst_not_used(const gr_endpoint &dst); void check_type_match(const gr_endpoint &src, const gr_endpoint &dst); gr_edge_vector_t calc_connections(gr_basic_block_sptr block, bool check_inputs); // false=use outputs diff --git a/gnuradio-core/src/lib/runtime/gr_hier_block2.cc b/gnuradio-core/src/lib/runtime/gr_hier_block2.cc index 756852df8..8c2794c63 100644 --- a/gnuradio-core/src/lib/runtime/gr_hier_block2.cc +++ b/gnuradio-core/src/lib/runtime/gr_hier_block2.cc @@ -44,7 +44,9 @@ gr_hier_block2::gr_hier_block2(const std::string &name, gr_io_signature_sptr input_signature, gr_io_signature_sptr output_signature) : gr_basic_block(name, input_signature, output_signature), - d_detail(new gr_hier_block2_detail(this)) + d_detail(new gr_hier_block2_detail(this)), + hier_message_ports_in(pmt::PMT_NIL), + hier_message_ports_out(pmt::PMT_NIL) { // This bit of magic ensures that self() works in the constructors of derived classes. gnuradio::detail::sptr_magic::create_and_stash_initial_sptr(this); @@ -81,6 +83,36 @@ gr_hier_block2::connect(gr_basic_block_sptr src, int src_port, } void +gr_hier_block2::msg_connect(gr_basic_block_sptr src, pmt::pmt_t srcport, + gr_basic_block_sptr dst, pmt::pmt_t dstport) +{ + if(!pmt::pmt_is_symbol(srcport)){throw std::runtime_error("bad port id"); } + d_detail->msg_connect(src, srcport, dst, dstport); +} + +void +gr_hier_block2::msg_connect(gr_basic_block_sptr src, std::string srcport, + gr_basic_block_sptr dst, std::string dstport) +{ + d_detail->msg_connect(src, pmt::mp(srcport), dst, pmt::mp(dstport)); +} + +void +gr_hier_block2::msg_disconnect(gr_basic_block_sptr src, pmt::pmt_t srcport, + gr_basic_block_sptr dst, pmt::pmt_t dstport) +{ + if(!pmt::pmt_is_symbol(srcport)){throw std::runtime_error("bad port id"); } + d_detail->msg_disconnect(src, srcport, dst, dstport); +} + +void +gr_hier_block2::msg_disconnect(gr_basic_block_sptr src, std::string srcport, + gr_basic_block_sptr dst, std::string dstport) +{ + d_detail->msg_disconnect(src, pmt::mp(srcport), dst, pmt::mp(dstport)); +} + +void gr_hier_block2::disconnect(gr_basic_block_sptr block) { d_detail->disconnect(block); @@ -111,6 +143,7 @@ gr_hier_block2::unlock() d_detail->unlock(); } + gr_flat_flowgraph_sptr gr_hier_block2::flatten() const { diff --git a/gnuradio-core/src/lib/runtime/gr_hier_block2.h b/gnuradio-core/src/lib/runtime/gr_hier_block2.h index 123178724..f80dd73e4 100644 --- a/gnuradio-core/src/lib/runtime/gr_hier_block2.h +++ b/gnuradio-core/src/lib/runtime/gr_hier_block2.h @@ -98,6 +98,21 @@ public: gr_basic_block_sptr dst, int dst_port); /*! + * \brief Add gr-blocks or hierarchical blocks to internal graph and wire together + * + * This adds (if not done earlier by another connect) a pair of gr-blocks or + * hierarchical blocks to the internal message port subscription + */ + void msg_connect(gr_basic_block_sptr src, pmt::pmt_t srcport, + gr_basic_block_sptr dst, pmt::pmt_t dstport); + void msg_connect(gr_basic_block_sptr src, std::string srcport, + gr_basic_block_sptr dst, std::string dstport); + void msg_disconnect(gr_basic_block_sptr src, pmt::pmt_t srcport, + gr_basic_block_sptr dst, pmt::pmt_t dstport); + void msg_disconnect(gr_basic_block_sptr src, std::string srcport, + gr_basic_block_sptr dst, std::string dstport); + + /*! * \brief Remove a gr-block or hierarchical block from the internal flowgraph. * * This removes a gr-block or hierarchical block from the internal flowgraph, @@ -151,6 +166,39 @@ public: gr_flat_flowgraph_sptr flatten() const; gr_hier_block2_sptr to_hier_block2(); // Needed for Python type coercion + + bool has_msg_port(pmt::pmt_t which_port){ + return message_port_is_hier(which_port) || gr_basic_block::has_msg_port(which_port); + } + + bool message_port_is_hier(pmt::pmt_t port_id){ + return message_port_is_hier_in(port_id) || message_port_is_hier_out(port_id); + } + bool message_port_is_hier_in(pmt::pmt_t port_id){ + return pmt::pmt_list_has(hier_message_ports_in, port_id); + } + bool message_port_is_hier_out(pmt::pmt_t port_id){ + return pmt::pmt_list_has(hier_message_ports_out, port_id); + } + + pmt::pmt_t hier_message_ports_in; + pmt::pmt_t hier_message_ports_out; + + void message_port_register_hier_in(pmt::pmt_t port_id){ + if(pmt::pmt_list_has(hier_message_ports_in, port_id)) + throw std::invalid_argument("hier msg in port by this name already registered"); + if(msg_queue.find(port_id) != msg_queue.end()) + throw std::invalid_argument("block already has a primitive input port by this name"); + hier_message_ports_in = pmt::pmt_list_add(hier_message_ports_in, port_id); + } + void message_port_register_hier_out(pmt::pmt_t port_id){ + if(pmt::pmt_list_has(hier_message_ports_out, port_id)) + throw std::invalid_argument("hier msg out port by this name already registered"); + if(pmt::pmt_dict_has_key(message_subscribers, port_id)) + throw std::invalid_argument("block already has a primitive output port by this name"); + hier_message_ports_out = pmt::pmt_list_add(hier_message_ports_out, port_id); + } + }; inline gr_hier_block2_sptr cast_to_hier_block2_sptr(gr_basic_block_sptr block) { diff --git a/gnuradio-core/src/lib/runtime/gr_hier_block2.i b/gnuradio-core/src/lib/runtime/gr_hier_block2.i index eefb965b4..a857394ca 100644 --- a/gnuradio-core/src/lib/runtime/gr_hier_block2.i +++ b/gnuradio-core/src/lib/runtime/gr_hier_block2.i @@ -38,6 +38,10 @@ gr_hier_block2_sptr gr_make_hier_block2(const std::string name, // better interface in scripting land. %rename(primitive_connect) gr_hier_block2::connect; %rename(primitive_disconnect) gr_hier_block2::disconnect; +%rename(primitive_msg_connect) gr_hier_block2::msg_connect; +%rename(primitive_msg_disconnect) gr_hier_block2::msg_disconnect; +%rename(primitive_message_port_register_hier_in) gr_hier_block2::message_port_register_hier_in; +%rename(primitive_message_port_register_hier_out) gr_hier_block2::message_port_register_hier_out; class gr_hier_block2 : public gr_basic_block { @@ -54,6 +58,19 @@ public: void connect(gr_basic_block_sptr src, int src_port, gr_basic_block_sptr dst, int dst_port) throw (std::invalid_argument); + void msg_connect(gr_basic_block_sptr src, pmt::pmt_t srcport, + gr_basic_block_sptr dst, pmt::pmt_t dstport) + throw (std::runtime_error); + void msg_connect(gr_basic_block_sptr src, std::string srcport, + gr_basic_block_sptr dst, std::string dstport) + throw (std::runtime_error); + void msg_disconnect(gr_basic_block_sptr src, pmt::pmt_t srcport, + gr_basic_block_sptr dst, pmt::pmt_t dstport) + throw (std::runtime_error); + void msg_disconnect(gr_basic_block_sptr src, std::string srcport, + gr_basic_block_sptr dst, std::string dstport) + throw (std::runtime_error); + void disconnect(gr_basic_block_sptr block) throw (std::invalid_argument); void disconnect(gr_basic_block_sptr src, int src_port, @@ -63,5 +80,9 @@ public: void lock(); void unlock(); + void message_port_register_hier_in(pmt::pmt_t port_id); + void message_port_register_hier_out(pmt::pmt_t port_id); + + gr_hier_block2_sptr to_hier_block2(); // Needed for Python type coercion }; diff --git a/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.cc b/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.cc index 76c5ce06f..add6da024 100644 --- a/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.cc +++ b/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.cc @@ -27,6 +27,7 @@ #include <gr_io_signature.h> #include <stdexcept> #include <sstream> +#include <boost/format.hpp> #define GR_HIER_BLOCK2_DETAIL_DEBUG 0 @@ -53,6 +54,7 @@ gr_hier_block2_detail::gr_hier_block2_detail(gr_hier_block2 *owner) : d_outputs = gr_endpoint_vector_t(max_outputs); } + gr_hier_block2_detail::~gr_hier_block2_detail() { d_owner = 0; // Don't use delete, we didn't allocate @@ -144,6 +146,65 @@ gr_hier_block2_detail::connect(gr_basic_block_sptr src, int src_port, } void +gr_hier_block2_detail::msg_connect(gr_basic_block_sptr src, pmt::pmt_t srcport, + gr_basic_block_sptr dst, pmt::pmt_t dstport) +{ + if (GR_HIER_BLOCK2_DETAIL_DEBUG) + std::cout << "connecting message port..." << std::endl; + + // register the subscription +// this is done later... +// src->message_port_sub(srcport, pmt::pmt_cons(dst->alias_pmt(), dstport)); + + // add block uniquely to list to internal blocks + if (std::find(d_blocks.begin(), d_blocks.end(), dst) == d_blocks.end()){ + d_blocks.push_back(src); + d_blocks.push_back(dst); + } + + bool hier_out = (d_owner == src.get()) && src->message_port_is_hier_out(srcport);; + bool hier_in = (d_owner == dst.get()) && dst->message_port_is_hier_in(dstport); + + gr_hier_block2_sptr src_block(cast_to_hier_block2_sptr(src)); + gr_hier_block2_sptr dst_block(cast_to_hier_block2_sptr(dst)); + + if (src_block && src.get() != d_owner) { + if (GR_HIER_BLOCK2_DETAIL_DEBUG) + std::cout << "connect: src is hierarchical, setting parent to " << this << std::endl; + src_block->d_detail->d_parent_detail = this; + } + + if (dst_block && dst.get() != d_owner) { + if (GR_HIER_BLOCK2_DETAIL_DEBUG) + std::cout << "connect: dst is hierarchical, setting parent to " << this << std::endl; + dst_block->d_detail->d_parent_detail = this; + } + + // add edge for this message connection + if(GR_HIER_BLOCK2_DETAIL_DEBUG) + std::cout << boost::format("connect( (%s, %s, %d), (%s, %s, %d) )\n") % + src % srcport % hier_out % + dst % dstport % hier_in; + d_fg->connect( gr_msg_endpoint(src, srcport, hier_out), gr_msg_endpoint(dst, dstport, hier_in)); +} + +void +gr_hier_block2_detail::msg_disconnect(gr_basic_block_sptr src, pmt::pmt_t srcport, + gr_basic_block_sptr dst, pmt::pmt_t dstport) +{ + if (GR_HIER_BLOCK2_DETAIL_DEBUG) + std::cout << "disconnecting message port..." << std::endl; + + // unregister the subscription - if already subscribed + src->message_port_unsub(srcport, pmt::pmt_cons(dst->alias_pmt(), dstport)); + + // remove edge for this message connection + bool hier_out = (d_owner == src.get()) && src->message_port_is_hier_out(srcport);; + bool hier_in = (d_owner == dst.get()) && dst->message_port_is_hier_in(dstport); + d_fg->disconnect( gr_msg_endpoint(src, srcport, hier_out), gr_msg_endpoint(dst, dstport, hier_in)); +} + +void gr_hier_block2_detail::disconnect(gr_basic_block_sptr block) { // Check on singleton list @@ -405,11 +466,16 @@ void gr_hier_block2_detail::flatten_aux(gr_flat_flowgraph_sptr sfg) const { if (GR_HIER_BLOCK2_DETAIL_DEBUG) - std::cout << "Flattening " << d_owner->name() << std::endl; + std::cout << " ** Flattening " << d_owner->name() << std::endl; // Add my edges to the flow graph, resolving references to actual endpoints gr_edge_vector_t edges = d_fg->edges(); + gr_msg_edge_vector_t msg_edges = d_fg->msg_edges(); gr_edge_viter_t p; + gr_msg_edge_viter_t q,u; + + if (GR_HIER_BLOCK2_DETAIL_DEBUG) + std::cout << "Flattening stream connections: " << std::endl; for (p = edges.begin(); p != edges.end(); p++) { if (GR_HIER_BLOCK2_DETAIL_DEBUG) @@ -428,6 +494,53 @@ gr_hier_block2_detail::flatten_aux(gr_flat_flowgraph_sptr sfg) const } } + // loop through flattening hierarchical connections + if (GR_HIER_BLOCK2_DETAIL_DEBUG) + std::cout << "Flattening msg connections: " << std::endl; + + + std::vector<std::pair<gr_msg_endpoint, bool> > resolved_endpoints; + for(q = msg_edges.begin(); q != msg_edges.end(); q++) { + if (GR_HIER_BLOCK2_DETAIL_DEBUG) + std::cout << boost::format(" flattening edge ( %s, %s, %d) -> ( %s, %s, %d)\n") % q->src().block() % q->src().port() % q->src().is_hier() % q->dst().block() % q->dst().port() % q->dst().is_hier(); + + bool normal_connection = true; + + // resolve existing connections to hier ports + if(q->dst().is_hier()){ + if (GR_HIER_BLOCK2_DETAIL_DEBUG) + std::cout << boost::format(" resolve hier output (%s, %s)") % q->dst().block() % q->dst().port() << std::endl; + sfg->replace_endpoint( q->dst(), q->src(), true ); + resolved_endpoints.push_back(std::pair<gr_msg_endpoint, bool>(q->dst(),true)); + normal_connection = false; + } + + if(q->src().is_hier()){ + if (GR_HIER_BLOCK2_DETAIL_DEBUG) + std::cout << boost::format(" resolve hier input (%s, %s)") % q->src().block() % q->src().port() << std::endl; + sfg->replace_endpoint( q->src(), q->dst(), false ); + resolved_endpoints.push_back(std::pair<gr_msg_endpoint, bool>(q->src(),false)); + normal_connection = false; + } + + // propogate non hier connections through + if(normal_connection){ + sfg->connect( q->src(), q->dst() ); + } + } + for(std::vector<std::pair<gr_msg_endpoint, bool> >::iterator it = resolved_endpoints.begin(); it != resolved_endpoints.end(); it++){ + sfg->clear_endpoint( (*it).first, (*it).second ); + } + +/* // connect primitive edges in the new fg + for(q = msg_edges.begin(); q != msg_edges.end(); q++) { + if( (!q->src().is_hier()) && (!q->dst().is_hier()) ){ + sfg->connect( q->src(), q->dst() ); + } else { + std::cout << "not connecting hier connection!" << std::endl; + } + }*/ + // Construct unique list of blocks used either in edges, inputs, // outputs, or by themselves. I still hate STL. gr_basic_block_vector_t blocks; // unique list of used blocks @@ -468,7 +581,7 @@ gr_hier_block2_detail::flatten_aux(gr_flat_flowgraph_sptr sfg) const // Recurse hierarchical children for (gr_basic_block_viter_t p = blocks.begin(); p != blocks.end(); p++) { gr_hier_block2_sptr hier_block2(cast_to_hier_block2_sptr(*p)); - if (hier_block2) { + if (hier_block2 && (hier_block2.get() != d_owner)) { if (GR_HIER_BLOCK2_DETAIL_DEBUG) std::cout << "flatten_aux: recursing into hierarchical block " << hier_block2 << std::endl; hier_block2->d_detail->flatten_aux(sfg); @@ -499,3 +612,4 @@ gr_hier_block2_detail::unlock() else d_owner->unlock(); } + diff --git a/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.h b/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.h index f4f950e9d..b38dae301 100644 --- a/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.h +++ b/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.h @@ -39,6 +39,10 @@ public: void connect(gr_basic_block_sptr block); void connect(gr_basic_block_sptr src, int src_port, gr_basic_block_sptr dst, int dst_port); + void msg_connect(gr_basic_block_sptr src, pmt::pmt_t srcport, + gr_basic_block_sptr dst, pmt::pmt_t dstport); + void msg_disconnect(gr_basic_block_sptr src, pmt::pmt_t srcport, + gr_basic_block_sptr dst, pmt::pmt_t dstport); void disconnect(gr_basic_block_sptr block); void disconnect(gr_basic_block_sptr, int src_port, gr_basic_block_sptr, int dst_port); @@ -57,6 +61,7 @@ private: gr_endpoint_vector_t d_outputs; // Single internal endpoint per external output gr_basic_block_vector_t d_blocks; + void connect_input(int my_port, int port, gr_basic_block_sptr block); void connect_output(int my_port, int port, gr_basic_block_sptr block); void disconnect_input(int my_port, int port, gr_basic_block_sptr block); diff --git a/gnuradio-core/src/lib/runtime/gr_msg_accepter.cc b/gnuradio-core/src/lib/runtime/gr_msg_accepter.cc index 5018ee9e6..93d5fb20e 100644 --- a/gnuradio-core/src/lib/runtime/gr_msg_accepter.cc +++ b/gnuradio-core/src/lib/runtime/gr_msg_accepter.cc @@ -41,12 +41,12 @@ gr_msg_accepter::~gr_msg_accepter() } void -gr_msg_accepter::post(pmt_t msg) +gr_msg_accepter::post(pmt_t which_port, pmt_t msg) { // Notify derived class, handled case by case gr_block *p = dynamic_cast<gr_block *>(this); if (p) { - p->detail()->_post(msg); + p->_post(which_port,msg); return; } gr_hier_block2 *p2 = dynamic_cast<gr_hier_block2 *>(this); diff --git a/gnuradio-core/src/lib/runtime/gr_msg_accepter.h b/gnuradio-core/src/lib/runtime/gr_msg_accepter.h index 3e5c97638..a497ba6e7 100644 --- a/gnuradio-core/src/lib/runtime/gr_msg_accepter.h +++ b/gnuradio-core/src/lib/runtime/gr_msg_accepter.h @@ -36,7 +36,7 @@ public: gr_msg_accepter(); ~gr_msg_accepter(); - void post(pmt::pmt_t msg); + void post(pmt::pmt_t which_port, pmt::pmt_t msg); }; diff --git a/gnuradio-core/src/lib/runtime/gr_scheduler_tpb.cc b/gnuradio-core/src/lib/runtime/gr_scheduler_tpb.cc index 131ddd19c..2824eb1b3 100644 --- a/gnuradio-core/src/lib/runtime/gr_scheduler_tpb.cc +++ b/gnuradio-core/src/lib/runtime/gr_scheduler_tpb.cc @@ -74,6 +74,11 @@ gr_scheduler_tpb::gr_scheduler_tpb(gr_flat_flowgraph_sptr ffg, int max_noutput_i for (size_t i = 0; i < blocks.size(); i++){ std::stringstream name; name << "thread-per-block[" << i << "]: " << blocks[i]; + + // If set, use internal value instead of global value + if(blocks[i]->is_set_max_noutput_items()) + max_noutput_items = blocks[i]->max_noutput_items(); + d_threads.create_thread( gruel::thread_body_wrapper<tpb_container>(tpb_container(blocks[i], max_noutput_items), name.str())); diff --git a/gnuradio-core/src/lib/runtime/gr_tpb_detail.cc b/gnuradio-core/src/lib/runtime/gr_tpb_detail.cc index 46b33d91f..46eb6bbe0 100644 --- a/gnuradio-core/src/lib/runtime/gr_tpb_detail.cc +++ b/gnuradio-core/src/lib/runtime/gr_tpb_detail.cc @@ -68,43 +68,3 @@ gr_tpb_detail::notify_neighbors(gr_block_detail *d) notify_upstream(d); } -void -gr_tpb_detail::insert_tail(pmt::pmt_t msg) -{ - gruel::scoped_lock guard(mutex); - - msg_queue.push_back(msg); - - // wake up thread if BLKD_IN or BLKD_OUT - input_cond.notify_one(); - output_cond.notify_one(); -} - -pmt_t -gr_tpb_detail::delete_head_nowait() -{ - gruel::scoped_lock guard(mutex); - - if (empty_p()) - return pmt_t(); - - pmt_t m(msg_queue.front()); - msg_queue.pop_front(); - - return m; -} - -/* - * Caller must already be holding the mutex - */ -pmt_t -gr_tpb_detail::delete_head_nowait_already_holding_mutex() -{ - if (empty_p()) - return pmt_t(); - - pmt_t m(msg_queue.front()); - msg_queue.pop_front(); - - return m; -} diff --git a/gnuradio-core/src/lib/runtime/gr_tpb_detail.h b/gnuradio-core/src/lib/runtime/gr_tpb_detail.h index b6e342dee..69feb6007 100644 --- a/gnuradio-core/src/lib/runtime/gr_tpb_detail.h +++ b/gnuradio-core/src/lib/runtime/gr_tpb_detail.h @@ -39,9 +39,6 @@ struct GR_CORE_API gr_tpb_detail { bool output_changed; gruel::condition_variable output_cond; -private: - std::deque<pmt::pmt_t> msg_queue; - public: gr_tpb_detail() : input_changed(false), output_changed(false) { } @@ -55,6 +52,12 @@ public: //! Called by us to notify both upstream and downstream void notify_neighbors(gr_block_detail *d); + //! Called by pmt msg posters + void notify_msg(){ + input_cond.notify_one(); + output_cond.notify_one(); + } + //! Called by us void clear_changed() { @@ -63,23 +66,6 @@ public: output_changed = false; } - //! is the queue empty? - bool empty_p() const { return msg_queue.empty(); } - - //| Acquires and release the mutex - void insert_tail(pmt::pmt_t msg); - - /*! - * \returns returns pmt at head of queue or pmt_t() if empty. - */ - pmt::pmt_t delete_head_nowait(); - - /*! - * \returns returns pmt at head of queue or pmt_t() if empty. - * Caller must already be holding the mutex - */ - pmt::pmt_t delete_head_nowait_already_holding_mutex(); - private: //! Used by notify_downstream diff --git a/gnuradio-core/src/lib/runtime/gr_tpb_thread_body.cc b/gnuradio-core/src/lib/runtime/gr_tpb_thread_body.cc index a5aabb379..9f17a48a8 100644 --- a/gnuradio-core/src/lib/runtime/gr_tpb_thread_body.cc +++ b/gnuradio-core/src/lib/runtime/gr_tpb_thread_body.cc @@ -25,13 +25,14 @@ #include <iostream> #include <boost/thread.hpp> #include <gruel/pmt.h> +#include <boost/foreach.hpp> using namespace pmt; gr_tpb_thread_body::gr_tpb_thread_body(gr_block_sptr block, int max_noutput_items) : d_exec(block, max_noutput_items) { - // std::cerr << "gr_tpb_thread_body: " << block << std::endl; + //std::cerr << "gr_tpb_thread_body: " << block << std::endl; gr_block_detail *d = block->detail().get(); gr_block_executor::state s; @@ -42,11 +43,22 @@ gr_tpb_thread_body::gr_tpb_thread_body(gr_block_sptr block, int max_noutput_item boost::this_thread::interruption_point(); // handle any queued up messages - while ((msg = d->d_tpb.delete_head_nowait())) - block->dispatch_msg(msg); + //BOOST_FOREACH( pmt::pmt_t port, block->msg_queue.keys() ) + + BOOST_FOREACH( gr_basic_block::msg_queue_map_t::value_type &i, block->msg_queue ) + { + while ((msg = block->delete_head_nowait(i.first))){ + block->dispatch_msg(i.first,msg); + } + } d->d_tpb.clear_changed(); - s = d_exec.run_one_iteration(); + // run one iteration if we are a connected stream block + if(d->noutputs() >0 || d->ninputs()>0){ + s = d_exec.run_one_iteration(); + } else { + s = gr_block_executor::BLKD_IN; + } switch(s){ case gr_block_executor::READY: // Tell neighbors we made progress. @@ -67,15 +79,18 @@ gr_tpb_thread_body::gr_tpb_thread_body(gr_block_sptr block, int max_noutput_item while (!d->d_tpb.input_changed){ // wait for input or message - while(!d->d_tpb.input_changed && d->d_tpb.empty_p()) + while(!d->d_tpb.input_changed && block->empty_p()) d->d_tpb.input_cond.wait(guard); // handle all pending messages - while ((msg = d->d_tpb.delete_head_nowait_already_holding_mutex())){ - guard.unlock(); // release lock while processing msg - block->dispatch_msg(msg); - guard.lock(); - } + BOOST_FOREACH( gr_basic_block::msg_queue_map_t::value_type &i, block->msg_queue ) + { + while ((msg = block->delete_head_nowait(i.first))){ + guard.unlock(); // release lock while processing msg + block->dispatch_msg(i.first, msg); + guard.lock(); + } + } } } break; @@ -87,15 +102,18 @@ gr_tpb_thread_body::gr_tpb_thread_body(gr_block_sptr block, int max_noutput_item while (!d->d_tpb.output_changed){ // wait for output room or message - while(!d->d_tpb.output_changed && d->d_tpb.empty_p()) + while(!d->d_tpb.output_changed && block->empty_p()) d->d_tpb.output_cond.wait(guard); // handle all pending messages - while ((msg = d->d_tpb.delete_head_nowait_already_holding_mutex())){ - guard.unlock(); // release lock while processing msg - block->dispatch_msg(msg); - guard.lock(); - } + BOOST_FOREACH( gr_basic_block::msg_queue_map_t::value_type &i, block->msg_queue ) + { + while ((msg = block->delete_head_nowait(i.first))){ + guard.unlock(); // release lock while processing msg + block->dispatch_msg(i.first,msg); + guard.lock(); + } + } } } break; diff --git a/gnuradio-core/src/lib/runtime/qa_gr_top_block.cc b/gnuradio-core/src/lib/runtime/qa_gr_top_block.cc index cc7b7c720..a0b4755a8 100644 --- a/gnuradio-core/src/lib/runtime/qa_gr_top_block.cc +++ b/gnuradio-core/src/lib/runtime/qa_gr_top_block.cc @@ -27,6 +27,7 @@ #include <qa_gr_top_block.h> #include <gr_top_block.h> #include <gr_head.h> +#include <gr_nop.h> #include <gr_null_source.h> #include <gr_null_sink.h> #include <iostream> @@ -119,3 +120,145 @@ void qa_gr_top_block::t4_reconfigure() // Wait for flowgraph to end on its own tb->wait(); } + + +void qa_gr_top_block::t5_max_noutputs() +{ + if (VERBOSE) std::cout << "qa_gr_top_block::t5()\n"; + + gr_top_block_sptr tb = gr_make_top_block("top"); + + gr_block_sptr src = gr_make_null_source(sizeof(int)); + gr_block_sptr head = gr_make_head(sizeof(int), 100000); + gr_block_sptr dst = gr_make_null_sink(sizeof(int)); + + // Start infinite flowgraph + tb->connect(src, 0, head, 0); + tb->connect(head, 0, dst, 0); + tb->start(100); + tb->wait(); +} + +void qa_gr_top_block::t6_reconfig_max_noutputs() +{ + if (VERBOSE) std::cout << "qa_gr_top_block::t6()\n"; + + gr_top_block_sptr tb = gr_make_top_block("top"); + + gr_block_sptr src = gr_make_null_source(sizeof(int)); + gr_block_sptr head = gr_make_head(sizeof(int), 100000); + gr_block_sptr dst = gr_make_null_sink(sizeof(int)); + + // Start infinite flowgraph + tb->connect(src, 0, dst, 0); + tb->start(100); + + // Reconfigure with gr_head in the middle + tb->lock(); + tb->disconnect(src, 0, dst, 0); + tb->connect(src, 0, head, 0); + tb->connect(head, 0, dst, 0); + tb->set_max_noutput_items(1000); + head->set_max_noutput_items(500); + tb->unlock(); + + // Wait for flowgraph to end on its own + tb->wait(); +} + +void qa_gr_top_block::t7_max_noutputs_per_block() +{ + if (VERBOSE) std::cout << "qa_gr_top_block::t7()\n"; + + gr_top_block_sptr tb = gr_make_top_block("top"); + + gr_block_sptr src = gr_make_null_source(sizeof(int)); + gr_block_sptr head = gr_make_head(sizeof(int), 100000); + gr_block_sptr dst = gr_make_null_sink(sizeof(int)); + + head->set_max_noutput_items(100); + + // Start infinite flowgraph + tb->connect(src, 0, head, 0); + tb->connect(head, 0, dst, 0); + tb->start(); + tb->wait(); +} + +void qa_gr_top_block::t8_reconfig_max_noutputs_per_block() +{ + if (VERBOSE) std::cout << "qa_gr_top_block::t8()\n"; + + gr_top_block_sptr tb = gr_make_top_block("top"); + + gr_block_sptr src = gr_make_null_source(sizeof(int)); + gr_block_sptr head = gr_make_head(sizeof(int), 100000); + gr_block_sptr dst = gr_make_null_sink(sizeof(int)); + + head->set_max_noutput_items(99); + + // Start infinite flowgraph + tb->connect(src, 0, dst, 0); + tb->start(201); + + // Reconfigure with gr_head in the middle + tb->lock(); + tb->disconnect(src, 0, dst, 0); + tb->connect(src, 0, head, 0); + tb->connect(head, 0, dst, 0); + tb->set_max_noutput_items(1023); + head->set_max_noutput_items(513); + tb->unlock(); + + // Wait for flowgraph to end on its own + tb->wait(); +} + +void qa_gr_top_block::t9_max_output_buffer() +{ + if (VERBOSE) std::cout << "qa_gr_top_block::t9()\n"; + + gr_top_block_sptr tb = gr_make_top_block("top"); + + gr_block_sptr src = gr_make_null_source(sizeof(int)); + gr_block_sptr head = gr_make_head(sizeof(int), 100000); + gr_block_sptr dst = gr_make_null_sink(sizeof(int)); + + head->set_max_output_buffer(1024); + + // Start infinite flowgraph + tb->connect(src, 0, head, 0); + tb->connect(head, 0, dst, 0); + tb->start(); + tb->wait(); +} + +void qa_gr_top_block::t10_reconfig_max_output_buffer() +{ + if (VERBOSE) std::cout << "qa_gr_top_block::t10()\n"; + + gr_top_block_sptr tb = gr_make_top_block("top"); + + gr_block_sptr src = gr_make_null_source(sizeof(int)); + gr_block_sptr head = gr_make_head(sizeof(int), 100000); + gr_block_sptr dst = gr_make_null_sink(sizeof(int)); + + head->set_max_output_buffer(1000); + + // Start infinite flowgraph + tb->connect(src, 0, dst, 0); + tb->start(201); + + // Reconfigure with gr_head in the middle + tb->lock(); + gr_block_sptr nop = gr_make_nop(sizeof(int)); + nop->set_max_output_buffer(4000); + tb->disconnect(src, 0, dst, 0); + tb->connect(src, 0, head, 0); + tb->connect(head, 0, nop, 0); + tb->connect(nop, 0, dst, 0); + tb->unlock(); + + // Wait for flowgraph to end on its own + tb->wait(); +} diff --git a/gnuradio-core/src/lib/runtime/qa_gr_top_block.h b/gnuradio-core/src/lib/runtime/qa_gr_top_block.h index b223633e5..bb891abca 100644 --- a/gnuradio-core/src/lib/runtime/qa_gr_top_block.h +++ b/gnuradio-core/src/lib/runtime/qa_gr_top_block.h @@ -36,6 +36,8 @@ class qa_gr_top_block : public CppUnit::TestCase CPPUNIT_TEST(t2_start_stop_wait); CPPUNIT_TEST(t3_lock_unlock); CPPUNIT_TEST(t4_reconfigure); // triggers 'join never returns' bug + CPPUNIT_TEST(t5_max_noutputs); + CPPUNIT_TEST(t6_reconfig_max_noutputs); CPPUNIT_TEST_SUITE_END(); @@ -46,6 +48,12 @@ private: void t2_start_stop_wait(); void t3_lock_unlock(); void t4_reconfigure(); + void t5_max_noutputs(); + void t6_reconfig_max_noutputs(); + void t7_max_noutputs_per_block(); + void t8_reconfig_max_noutputs_per_block(); + void t9_max_output_buffer(); + void t10_reconfig_max_output_buffer(); }; #endif /* INCLUDED_QA_GR_TOP_BLOCK_H */ diff --git a/gnuradio-core/src/lib/runtime/qa_set_msg_handler.cc b/gnuradio-core/src/lib/runtime/qa_set_msg_handler.cc index 25ae0b1e1..c84a219bd 100644 --- a/gnuradio-core/src/lib/runtime/qa_set_msg_handler.cc +++ b/gnuradio-core/src/lib/runtime/qa_set_msg_handler.cc @@ -65,15 +65,11 @@ void qa_set_msg_handler::t0() tb->start(); // Send them... + pmt_t port(pmt_intern("port")); for (int i = 0; i < NMSGS; i++){ - send(nop, mp(mp("example-msg"), mp(i))); + send(nop, port, mp(mp("example-msg"), mp(i))); } - // And send a message to null_source to confirm that the default - // message handling action (which should be a nop) doesn't dump - // core. - send(src, mp(mp("example-msg"), mp(0))); - // Give the messages a chance to be processed boost::this_thread::sleep(boost::posix_time::milliseconds(100)); diff --git a/gnuradio-core/src/python/build_utils.py b/gnuradio-core/src/python/build_utils.py index 77bf0607a..cf58a9763 100644 --- a/gnuradio-core/src/python/build_utils.py +++ b/gnuradio-core/src/python/build_utils.py @@ -1,5 +1,5 @@ # -# Copyright 2004,2009 Free Software Foundation, Inc. +# Copyright 2004,2009,2012 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -179,7 +179,9 @@ def is_complex (code3): def standard_dict (name, code3, package='gr'): d = {} d['NAME'] = name - d['GUARD_NAME'] = 'INCLUDED_%s_H' % name.upper () + d['NAME_IMPL'] = name+'_impl' + d['GUARD_NAME'] = 'INCLUDED_%s_%s_H' % (package.upper(), name.upper()) + d['GUARD_NAME_IMPL'] = 'INCLUDED_%s_%s_IMPL_H' % (package.upper(), name.upper()) d['BASE_NAME'] = re.sub ('^' + package + '_', '', name) d['SPTR_NAME'] = '%s_sptr' % name d['WARNING'] = 'WARNING: this file is machine generated. Edits will be overwritten' @@ -210,7 +212,7 @@ def standard_impl_dict2 (name, code3, package): d = {} d['NAME'] = name d['IMPL_NAME'] = name - d['BASE_NAME'] = name.rstrip("_impl") + d['BASE_NAME'] = name.rstrip("impl").rstrip("_") d['GUARD_NAME'] = 'INCLUDED_%s_%s_H' % (package.upper(), name.upper()) d['WARNING'] = 'WARNING: this file is machine generated. Edits will be overwritten' d['COPYRIGHT'] = copyright diff --git a/gnuradio-core/src/python/gnuradio/gr/CMakeLists.txt b/gnuradio-core/src/python/gnuradio/gr/CMakeLists.txt index 6a0555021..62f3d7e46 100644 --- a/gnuradio-core/src/python/gnuradio/gr/CMakeLists.txt +++ b/gnuradio-core/src/python/gnuradio/gr/CMakeLists.txt @@ -23,6 +23,7 @@ include(GrPython) GR_PYTHON_INSTALL(FILES __init__.py exceptions.py + gateway.py gr_threading.py gr_threading_23.py gr_threading_24.py @@ -42,6 +43,13 @@ include(GrTest) file(GLOB py_qa_test_files "qa_*.py") foreach(py_qa_test_file ${py_qa_test_files}) get_filename_component(py_qa_test_name ${py_qa_test_file} NAME_WE) + set(GR_TEST_PYTHON_DIRS + ${CMAKE_SOURCE_DIR}/gruel/src/python + ${CMAKE_BINARY_DIR}/gruel/src/swig + ${CMAKE_BINARY_DIR}/gnuradio-core/src/python + ${CMAKE_BINARY_DIR}/gnuradio-core/src/lib/swig + ) + set(GR_TEST_TARGET_DEPS volk gruel gnuradio-core) GR_ADD_TEST(${py_qa_test_name} ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B} ${py_qa_test_file}) endforeach(py_qa_test_file) endif(ENABLE_TESTING) diff --git a/gnuradio-core/src/python/gnuradio/gr/__init__.py b/gnuradio-core/src/python/gnuradio/gr/__init__.py index 602d1119f..5d01ea11b 100644 --- a/gnuradio-core/src/python/gnuradio/gr/__init__.py +++ b/gnuradio-core/src/python/gnuradio/gr/__init__.py @@ -1,5 +1,5 @@ # -# Copyright 2003,2004,2006,2008,2009,2010 Free Software Foundation, Inc. +# Copyright 2003-2012 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -24,29 +24,11 @@ # This is the main GNU Radio python module. # We pull the swig output and the other modules into the gnuradio.gr namespace -# Temporary workaround for ticket:181. -# Use leading underscores to avoid namespace pollution -import sys -_RTLD_GLOBAL = 0 -try: - from dl import RTLD_GLOBAL as _RTLD_GLOBAL -except ImportError: - try: - from DLFCN import RTLD_GLOBAL as _RTLD_GLOBAL - except ImportError: - pass - -if _RTLD_GLOBAL != 0: - _dlopenflags = sys.getdlopenflags() - sys.setdlopenflags(_dlopenflags|_RTLD_GLOBAL) - from gnuradio_core import * from exceptions import * from hier_block2 import * from top_block import * - -if _RTLD_GLOBAL != 0: - sys.setdlopenflags(_dlopenflags) # Restore original flags +from gateway import basic_block, sync_block, decim_block, interp_block # create a couple of aliases serial_to_parallel = stream_to_vector diff --git a/gnuradio-core/src/python/gnuradio/gr/gateway.py b/gnuradio-core/src/python/gnuradio/gr/gateway.py new file mode 100644 index 000000000..244b8b592 --- /dev/null +++ b/gnuradio-core/src/python/gnuradio/gr/gateway.py @@ -0,0 +1,215 @@ +# +# Copyright 2011-2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +import gnuradio_core as gr_core +from gnuradio_core import io_signature, io_signaturev +from gnuradio_core import gr_block_gw_message_type +from gnuradio_core import block_gateway +import numpy + +######################################################################## +# Magic to turn pointers into numpy arrays +# http://docs.scipy.org/doc/numpy/reference/arrays.interface.html +######################################################################## +def pointer_to_ndarray(addr, dtype, nitems): + class array_like: + __array_interface__ = { + 'data' : (int(addr), False), + 'typestr' : dtype.base.str, + 'descr' : dtype.base.descr, + 'shape' : (nitems,) + dtype.shape, + 'strides' : None, + 'version' : 3 + } + return numpy.asarray(array_like()).view(dtype.base) + +######################################################################## +# Handler that does callbacks from C++ +######################################################################## +class gateway_handler(gr_core.feval_ll): + + #dont put a constructor, it wont work + + def init(self, callback): + self._callback = callback + + def eval(self, arg): + try: self._callback() + except Exception as ex: + print("handler caught exception: %s"%ex) + import traceback; traceback.print_exc() + raise ex + return 0 + +######################################################################## +# The guts that make this into a gr block +######################################################################## +class gateway_block(object): + + def __init__(self, name, in_sig, out_sig, work_type, factor): + + #ensure that the sigs are iterable dtypes + def sig_to_dtype_sig(sig): + if sig is None: sig = () + return map(numpy.dtype, sig) + self.__in_sig = sig_to_dtype_sig(in_sig) + self.__out_sig = sig_to_dtype_sig(out_sig) + + #cache the ranges to iterate when dispatching work + self.__in_indexes = range(len(self.__in_sig)) + self.__out_indexes = range(len(self.__out_sig)) + + #convert the signatures into gr.io_signatures + def sig_to_gr_io_sigv(sig): + if not len(sig): return io_signature(0, 0, 0) + return io_signaturev(len(sig), len(sig), [s.itemsize for s in sig]) + gr_in_sig = sig_to_gr_io_sigv(self.__in_sig) + gr_out_sig = sig_to_gr_io_sigv(self.__out_sig) + + #create internal gateway block + self.__handler = gateway_handler() + self.__handler.init(self.__gr_block_handle) + self.__gateway = block_gateway( + self.__handler, name, gr_in_sig, gr_out_sig, work_type, factor) + self.__message = self.__gateway.gr_block_message() + + #register gr_block functions + prefix = 'gr_block__' + for attr in [x for x in dir(self.__gateway) if x.startswith(prefix)]: + setattr(self, attr.replace(prefix, ''), getattr(self.__gateway, attr)) + self.pop_msg_queue = lambda: gr_core.gr_block_gw_pop_msg_queue_safe(self.__gateway) + + def to_basic_block(self): + """ + Makes this block connectable by hier/top block python + """ + return self.__gateway.to_basic_block() + + def __gr_block_handle(self): + """ + Dispatch tasks according to the action type specified in the message. + """ + if self.__message.action == gr_block_gw_message_type.ACTION_GENERAL_WORK: + self.__message.general_work_args_return_value = self.general_work( + + input_items=[pointer_to_ndarray( + self.__message.general_work_args_input_items[i], + self.__in_sig[i], + self.__message.general_work_args_ninput_items[i] + ) for i in self.__in_indexes], + + output_items=[pointer_to_ndarray( + self.__message.general_work_args_output_items[i], + self.__out_sig[i], + self.__message.general_work_args_noutput_items + ) for i in self.__out_indexes], + ) + + elif self.__message.action == gr_block_gw_message_type.ACTION_WORK: + self.__message.work_args_return_value = self.work( + + input_items=[pointer_to_ndarray( + self.__message.work_args_input_items[i], + self.__in_sig[i], + self.__message.work_args_ninput_items + ) for i in self.__in_indexes], + + output_items=[pointer_to_ndarray( + self.__message.work_args_output_items[i], + self.__out_sig[i], + self.__message.work_args_noutput_items + ) for i in self.__out_indexes], + ) + + elif self.__message.action == gr_block_gw_message_type.ACTION_FORECAST: + self.forecast( + noutput_items=self.__message.forecast_args_noutput_items, + ninput_items_required=self.__message.forecast_args_ninput_items_required, + ) + + elif self.__message.action == gr_block_gw_message_type.ACTION_START: + self.__message.start_args_return_value = self.start() + + elif self.__message.action == gr_block_gw_message_type.ACTION_STOP: + self.__message.stop_args_return_value = self.stop() + + def forecast(self, noutput_items, ninput_items_required): + """ + forecast is only called from a general block + this is the default implementation + """ + for ninput_item in ninput_items_required: + ninput_item = noutput_items + self.history() - 1; + return + + def general_work(self, *args, **kwargs): + """general work to be overloaded in a derived class""" + raise NotImplementedError("general work not implemented") + + def work(self, *args, **kwargs): + """work to be overloaded in a derived class""" + raise NotImplementedError("work not implemented") + + def start(self): return True + def stop(self): return True + +######################################################################## +# Wrappers for the user to inherit from +######################################################################## +class basic_block(gateway_block): + def __init__(self, name, in_sig, out_sig): + gateway_block.__init__(self, + name=name, + in_sig=in_sig, + out_sig=out_sig, + work_type=gr_core.GR_BLOCK_GW_WORK_GENERAL, + factor=1, #not relevant factor + ) + +class sync_block(gateway_block): + def __init__(self, name, in_sig, out_sig): + gateway_block.__init__(self, + name=name, + in_sig=in_sig, + out_sig=out_sig, + work_type=gr_core.GR_BLOCK_GW_WORK_SYNC, + factor=1, + ) + +class decim_block(gateway_block): + def __init__(self, name, in_sig, out_sig, decim): + gateway_block.__init__(self, + name=name, + in_sig=in_sig, + out_sig=out_sig, + work_type=gr_core.GR_BLOCK_GW_WORK_DECIM, + factor=decim, + ) + +class interp_block(gateway_block): + def __init__(self, name, in_sig, out_sig, interp): + gateway_block.__init__(self, + name=name, + in_sig=in_sig, + out_sig=out_sig, + work_type=gr_core.GR_BLOCK_GW_WORK_INTERP, + factor=interp, + ) diff --git a/gnuradio-core/src/python/gnuradio/gr/hier_block2.py b/gnuradio-core/src/python/gnuradio/gr/hier_block2.py index 0c45f1691..b95782238 100644 --- a/gnuradio-core/src/python/gnuradio/gr/hier_block2.py +++ b/gnuradio-core/src/python/gnuradio/gr/hier_block2.py @@ -20,6 +20,10 @@ # from gnuradio_core import hier_block2_swig +try: + import pmt +except ImportError: + from gruel import pmt # # This hack forces a 'has-a' relationship to look like an 'is-a' one. @@ -111,3 +115,15 @@ class hier_block2(object): self._hb.primitive_disconnect(src_block.to_basic_block(), src_port, dst_block.to_basic_block(), dst_port) + def msg_connect(self, src, srcport, dst, dstport): + self.primitive_msg_connect(src.to_basic_block(), srcport, dst.to_basic_block(), dstport); + + def msg_disconnect(self, src, srcport, dst, dstport): + self.primitive_msg_disconnect(src.to_basic_block(), srcport, dst.to_basic_block(), dstport); + + def message_port_register_hier_in(self, portname): + self.primitive_message_port_register_hier_in(pmt.pmt_intern(portname)); + + def message_port_register_hier_out(self, portname): + self.primitive_message_port_register_hier_out(pmt.pmt_intern(portname)); + diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_block_gateway.py b/gnuradio-core/src/python/gnuradio/gr/qa_block_gateway.py new file mode 100644 index 000000000..911879f6f --- /dev/null +++ b/gnuradio-core/src/python/gnuradio/gr/qa_block_gateway.py @@ -0,0 +1,235 @@ +# +# Copyright 2011-2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, gr_unittest +import pmt +import numpy + +class add_2_f32_1_f32(gr.sync_block): + def __init__(self): + gr.sync_block.__init__( + self, + name = "add 2 f32", + in_sig = [numpy.float32, numpy.float32], + out_sig = [numpy.float32], + ) + + def work(self, input_items, output_items): + output_items[0][:] = input_items[0] + input_items[1] + return len(output_items[0]) + +class add_2_fc32_1_fc32(gr.sync_block): + def __init__(self): + gr.sync_block.__init__( + self, + name = "add 2 fc32", + in_sig = [numpy.complex64, numpy.complex64], + out_sig = [numpy.complex64], + ) + + def work(self, input_items, output_items): + output_items[0][:] = input_items[0] + input_items[1] + return len(output_items[0]) + +class convolve(gr.sync_block): + """ + A demonstration using block history to properly perform a convolution. + """ + def __init__(self): + gr.sync_block.__init__( + self, + name = "convolve", + in_sig = [numpy.float32], + out_sig = [numpy.float32] + ) + self._taps = [1, 0, 0, 0] + self.set_history(len(self._taps)) + + def work(self, input_items, output_items): + output_items[0][:] = numpy.convolve(input_items[0], self._taps, mode='valid') + return len(output_items[0]) + +class decim2x(gr.decim_block): + def __init__(self): + gr.decim_block.__init__( + self, + name = "decim2x", + in_sig = [numpy.float32], + out_sig = [numpy.float32], + decim = 2 + ) + + def work(self, input_items, output_items): + output_items[0][:] = input_items[0][::2] + return len(output_items[0]) + +class interp2x(gr.interp_block): + def __init__(self): + gr.interp_block.__init__( + self, + name = "interp2x", + in_sig = [numpy.float32], + out_sig = [numpy.float32], + interp = 2 + ) + + def work(self, input_items, output_items): + output_items[0][1::2] = input_items[0] + output_items[0][::2] = input_items[0] + return len(output_items[0]) + +class tag_source(gr.sync_block): + def __init__(self): + gr.sync_block.__init__( + self, + name = "tag source", + in_sig = None, + out_sig = [numpy.float32], + ) + + def work(self, input_items, output_items): + num_output_items = len(output_items[0]) + + #put code here to fill the output items... + + #make a new tag on the middle element every time work is called + count = self.nitems_written(0) + num_output_items/2 + key = pmt.pmt_string_to_symbol("example_key") + value = pmt.pmt_string_to_symbol("example_value") + self.add_item_tag(0, count, key, value) + + return num_output_items + +class tag_sink(gr.sync_block): + def __init__(self): + gr.sync_block.__init__( + self, + name = "tag sink", + in_sig = [numpy.float32], + out_sig = None, + ) + self.key = None + + def work(self, input_items, output_items): + num_input_items = len(input_items[0]) + + #put code here to process the input items... + + #print all the tags received in this work call + nread = self.nitems_read(0) + tags = self.get_tags_in_range(0, nread, nread+num_input_items) + for tag in tags: + #print tag.offset + #print pmt.pmt_symbol_to_string(tag.key) + #print pmt.pmt_symbol_to_string(tag.value) + self.key = pmt.pmt_symbol_to_string(tag.key) + + return num_input_items + +class fc32_to_f32_2(gr.sync_block): + def __init__(self): + gr.sync_block.__init__( + self, + name = "fc32_to_f32_2", + in_sig = [numpy.complex64], + out_sig = [(numpy.float32, 2)], + ) + + def work(self, input_items, output_items): + output_items[0][::,0] = numpy.real(input_items[0]) + output_items[0][::,1] = numpy.imag(input_items[0]) + return len(output_items[0]) + +class test_block_gateway(gr_unittest.TestCase): + + def test_add_f32(self): + tb = gr.top_block() + src0 = gr.vector_source_f([1, 3, 5, 7, 9], False) + src1 = gr.vector_source_f([0, 2, 4, 6, 8], False) + adder = add_2_f32_1_f32() + sink = gr.vector_sink_f() + tb.connect((src0, 0), (adder, 0)) + tb.connect((src1, 0), (adder, 1)) + tb.connect(adder, sink) + tb.run() + self.assertEqual(sink.data(), (1, 5, 9, 13, 17)) + + def test_add_fc32(self): + tb = gr.top_block() + src0 = gr.vector_source_c([1, 3j, 5, 7j, 9], False) + src1 = gr.vector_source_c([0, 2j, 4, 6j, 8], False) + adder = add_2_fc32_1_fc32() + sink = gr.vector_sink_c() + tb.connect((src0, 0), (adder, 0)) + tb.connect((src1, 0), (adder, 1)) + tb.connect(adder, sink) + tb.run() + self.assertEqual(sink.data(), (1, 5j, 9, 13j, 17)) + + def test_convolve(self): + tb = gr.top_block() + src = gr.vector_source_f([1, 2, 3, 4, 5, 6, 7, 8], False) + cv = convolve() + sink = gr.vector_sink_f() + tb.connect(src, cv, sink) + tb.run() + self.assertEqual(sink.data(), (1, 2, 3, 4, 5, 6, 7, 8)) + + def test_decim2x(self): + tb = gr.top_block() + src = gr.vector_source_f([1, 2, 3, 4, 5, 6, 7, 8], False) + d2x = decim2x() + sink = gr.vector_sink_f() + tb.connect(src, d2x, sink) + tb.run() + self.assertEqual(sink.data(), (1, 3, 5, 7)) + + def test_interp2x(self): + tb = gr.top_block() + src = gr.vector_source_f([1, 3, 5, 7, 9], False) + i2x = interp2x() + sink = gr.vector_sink_f() + tb.connect(src, i2x, sink) + tb.run() + self.assertEqual(sink.data(), (1, 1, 3, 3, 5, 5, 7, 7, 9, 9)) + + def test_tags(self): + src = tag_source() + sink = tag_sink() + head = gr.head(gr.sizeof_float, 50000) #should be enough items to get a tag through + tb = gr.top_block() + tb.connect(src, head, sink) + tb.run() + self.assertEqual(sink.key, "example_key") + + def test_fc32_to_f32_2(self): + tb = gr.top_block() + src = gr.vector_source_c([1+2j, 3+4j, 5+6j, 7+8j, 9+10j], False) + convert = fc32_to_f32_2() + v2s = gr.vector_to_stream(gr.sizeof_float, 2) + sink = gr.vector_sink_f() + tb.connect(src, convert, v2s, sink) + tb.run() + self.assertEqual(sink.data(), (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)) + +if __name__ == '__main__': + gr_unittest.run(test_block_gateway, "test_block_gateway.xml") + diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_pdu.py b/gnuradio-core/src/python/gnuradio/gr/qa_pdu.py new file mode 100755 index 000000000..572d8b186 --- /dev/null +++ b/gnuradio-core/src/python/gnuradio/gr/qa_pdu.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python +# +# Copyright 2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, gr_unittest +import pmt +import time + +class test_pdu(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_000(self): + # Just run some data through and make sure it doesn't puke. + src_data = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) + + src = gr.pdu_to_tagged_stream(gr.pdu_byte) + snk3 = gr.tagged_stream_to_pdu(gr.pdu_byte) + snk2 = gr.vector_sink_b() + snk = gr.tag_debug(1, "test") + + dbg = gr.message_debug() + + # Test that the right number of ports exist. + pi = dbg.message_ports_in() + po = dbg.message_ports_out() + self.assertEqual(pmt.pmt_length(pi), 2) + self.assertEqual(pmt.pmt_length(po), 0) + + pi = snk3.message_ports_in() + po = snk3.message_ports_out() + self.assertEqual(pmt.pmt_length(pi), 0) + self.assertEqual(pmt.pmt_length(po), 1) + + #print "Message Debug input ports: " + #pmt.pmt_print(pi) + #print "Message Debug output ports: " + #pmt.pmt_print(po) + + #print "Stream to PDU input ports: " + #pmt.pmt_print(pi) + #print "Stream to PDU output ports: " + #pmt.pmt_print(po) + time.sleep(0.1) + + self.tb.connect(src, snk) + self.tb.connect(src, snk2) + self.tb.connect(src, snk3) + + self.tb.msg_connect(snk3, "pdus", dbg, "store") + self.tb.start() + + # make our reference and message pmts + port = pmt.pmt_intern("pdus") + msg = pmt.pmt_cons( pmt.PMT_NIL, pmt.pmt_make_u8vector(16, 0xFF) ) + + #print "printing port & msg" + #pmt.pmt_print(port) + #pmt.pmt_print(msg) + + # post the message + src.to_basic_block()._post( port, msg ) + + while(dbg.num_messages() < 1): + time.sleep(0.5) + self.tb.stop() + self.tb.wait() + + # Get the vector of data from the vector sink + result_data = snk2.data() + + # Get the vector of data from the message sink + # Convert the message PMT as a pair into its vector + result_msg = dbg.get_message(0) + msg_vec = pmt.pmt_cdr(result_msg) + pmt.pmt_print(msg_vec) + + # Convert the PMT vector into a Python list + msg_data = [] + for i in xrange(16): + msg_data.append(pmt.pmt_u8vector_ref(msg_vec, i)) + + actual_data = 16*[0xFF,] + self.assertEqual(actual_data, list(result_data)) + self.assertEqual(actual_data, msg_data) + +if __name__ == '__main__': + gr_unittest.run(test_pdu, "test_pdu.xml") diff --git a/gnuradio-core/src/python/gnuradio/gr/top_block.py b/gnuradio-core/src/python/gnuradio/gr/top_block.py index 43af8073b..dc1f443aa 100644 --- a/gnuradio-core/src/python/gnuradio/gr/top_block.py +++ b/gnuradio-core/src/python/gnuradio/gr/top_block.py @@ -123,6 +123,12 @@ class top_block(object): for i in range (1, len (points)): self._connect(points[i-1], points[i]) + def msg_connect(self, src, srcport, dst, dstport): + self.primitive_msg_connect(src.to_basic_block(), srcport, dst.to_basic_block(), dstport); + + def msg_disconnect(self, src, srcport, dst, dstport): + self.primitive_msg_disconnect(src.to_basic_block(), srcport, dst.to_basic_block(), dstport); + def _connect(self, src, dst): (src_block, src_port) = self._coerce_endpoint(src) (dst_block, dst_port) = self._coerce_endpoint(dst) diff --git a/gr-analog/CMakeLists.txt b/gr-analog/CMakeLists.txt new file mode 100644 index 000000000..4769ce7ac --- /dev/null +++ b/gr-analog/CMakeLists.txt @@ -0,0 +1,114 @@ +# Copyright 2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. + +######################################################################## +# Setup dependencies +######################################################################## +include(GrBoost) + +######################################################################## +# Register component +######################################################################## +include(GrComponent) +GR_REGISTER_COMPONENT("gr-analog" ENABLE_GR_ANALOG + Boost_FOUND + ENABLE_VOLK + ENABLE_GR_CORE + ENABLE_GR_FFT + ENABLE_GR_FILTER +) + +GR_SET_GLOBAL(GR_ANALOG_INCLUDE_DIRS + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${CMAKE_CURRENT_BINARY_DIR}/include +) + +GR_SET_GLOBAL(GR_ANALOG_SWIG_INCLUDE_DIRS + ${CMAKE_CURRENT_SOURCE_DIR}/swig +) + +SET(GR_PKG_ANALOG_EXAMPLES_DIR ${GR_PKG_DATA_DIR}/examples/analog) + +######################################################################## +# Begin conditional configuration +######################################################################## +if(ENABLE_GR_ANALOG) + +######################################################################## +# Setup CPack components +######################################################################## +include(GrPackage) +CPACK_SET(CPACK_COMPONENT_GROUP_ANALOG_DESCRIPTION "GNU Radio Analog Blocks") + +CPACK_COMPONENT("analog_runtime" + GROUP "Analog" + DISPLAY_NAME "Runtime" + DESCRIPTION "Dynamic link libraries" + DEPENDS "core_runtime" +) + +CPACK_COMPONENT("analog_devel" + GROUP "Analog" + DISPLAY_NAME "Development" + DESCRIPTION "C++ headers, package config, import libraries" + DEPENDS "core_devel" +) + +CPACK_COMPONENT("analog_python" + GROUP "Analog" + DISPLAY_NAME "Python" + DESCRIPTION "Python modules for runtime" + DEPENDS "core_python;analog_runtime" +) + +CPACK_COMPONENT("analog_swig" + GROUP "Analog" + DISPLAY_NAME "SWIG" + DESCRIPTION "SWIG development .i files" + DEPENDS "core_swig;analog_python;analog_devel" +) + +######################################################################## +# Add subdirectories +######################################################################## +add_subdirectory(include/analog) +add_subdirectory(lib) +add_subdirectory(doc) +if(ENABLE_PYTHON) + add_subdirectory(swig) + add_subdirectory(python) + add_subdirectory(grc) + add_subdirectory(examples) +endif(ENABLE_PYTHON) + +######################################################################## +# Create Pkg Config File +######################################################################## +configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/gnuradio-analog.pc.in + ${CMAKE_CURRENT_BINARY_DIR}/gnuradio-analog.pc +@ONLY) + +install( + FILES ${CMAKE_CURRENT_BINARY_DIR}/gnuradio-analog.pc + DESTINATION ${GR_LIBRARY_DIR}/pkgconfig + COMPONENT "analog_devel" +) + +endif(ENABLE_GR_ANALOG) diff --git a/gr-analog/README b/gr-analog/README new file mode 100644 index 000000000..8c29ffde5 --- /dev/null +++ b/gr-analog/README @@ -0,0 +1,4 @@ +This GNU Radio component for implementing analog modulators, demodulators, and other related blocks. + + +FIXME: just fixme.
\ No newline at end of file diff --git a/gr-analog/doc/CMakeLists.txt b/gr-analog/doc/CMakeLists.txt new file mode 100644 index 000000000..5a02547db --- /dev/null +++ b/gr-analog/doc/CMakeLists.txt @@ -0,0 +1,23 @@ +# Copyright 2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. + +install( + FILES README.analog + DESTINATION ${GR_PKG_DOC_DIR} +) diff --git a/gr-analog/doc/README.analog b/gr-analog/doc/README.analog new file mode 100644 index 000000000..b2b763cc3 --- /dev/null +++ b/gr-analog/doc/README.analog @@ -0,0 +1,13 @@ +This is the gr-analog package. It contains all of the analog +modulation blocks, utilities, and examples. To use the analog blocks, +the Python namespaces is in gnuradio.analog, which would be normally +imported as: + + from gnuradio import analog + +See the Doxygen documentation for details about the blocks available +in this package. A quick listing of the details can be found in Python +after importing by using: + + help(analog) + diff --git a/gr-analog/doc/analog.dox b/gr-analog/doc/analog.dox new file mode 100644 index 000000000..d3af364f7 --- /dev/null +++ b/gr-analog/doc/analog.dox @@ -0,0 +1,23 @@ +/*! \page page_analog Analog Modulation + +\section Introduction +This is the gr-analog package. It contains all of the analog +modulation blocks, utilities, and examples. To use the analog blocks, +the Python namespaces is in gnuradio.analog, which would be normally +imported as: + +\code + from gnuradio import analog +\endcode + +See the Doxygen documentation for details about the blocks available +in this package. The relevant blocks are listed in the \ref analog group. + +A quick listing of the details can be found in Python after importing +by using: + +\code + help(analog) +\endcode + +*/ diff --git a/gr-analog/examples/CMakeLists.txt b/gr-analog/examples/CMakeLists.txt new file mode 100644 index 000000000..947600986 --- /dev/null +++ b/gr-analog/examples/CMakeLists.txt @@ -0,0 +1,26 @@ +# Copyright 2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. + +include(GrPython) + +# Base stuff +GR_PYTHON_INSTALL(PROGRAMS + DESTINATION ${GR_PKG_ANALOG_EXAMPLES_DIR} + COMPONENT "analog_python" +) diff --git a/gr-analog/gnuradio-analog.pc.in b/gr-analog/gnuradio-analog.pc.in new file mode 100644 index 000000000..675c7ee20 --- /dev/null +++ b/gr-analog/gnuradio-analog.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: gnuradio-analog +Description: GNU Radio blocks for analog communications +Requires: gnuradio-core +Version: @LIBVER@ +Libs: -L${libdir} -lgnuradio-analog +Cflags: -I${includedir} diff --git a/gr-analog/grc/CMakeLists.txt b/gr-analog/grc/CMakeLists.txt new file mode 100644 index 000000000..908ef0ed3 --- /dev/null +++ b/gr-analog/grc/CMakeLists.txt @@ -0,0 +1,21 @@ +# Copyright 2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. + +file(GLOB xml_files "*.xml") +install(FILES ${xml_files} DESTINATION ${GRC_BLOCKS_DIR} COMPONENT "analog_python") diff --git a/gr-analog/grc/analog_agc2_xx.xml b/gr-analog/grc/analog_agc2_xx.xml new file mode 100644 index 000000000..e57666873 --- /dev/null +++ b/gr-analog/grc/analog_agc2_xx.xml @@ -0,0 +1,70 @@ +<?xml version="1.0"?> +<!-- +################################################### +##AGC2 +################################################### + --> +<block> + <name>AGC2</name> + <key>analog_agc2_xx</key> + <import>from gnuradio import analog</import> + <make>analog.agc2_$(type.fcn)($attack_rate, $decay_rate, $reference, $gain, $max_gain)</make> + <callback>set_attack_rate($attack_rate)</callback> + <callback>set_decay_rate($decay_rate)</callback> + <callback>set_reference($reference)</callback> + <callback>set_gain($gain)</callback> + <callback>set_max_gain($max_gain)</callback> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>fcn:cc</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>fcn:ff</opt> + </option> + </param> + <param> + <name>Attack Rate</name> + <key>attack_rate</key> + <value>1e-1</value> + <type>real</type> + </param> + <param> + <name>Decay Rate</name> + <key>decay_rate</key> + <value>1e-2</value> + <type>real</type> + </param> + <param> + <name>Reference</name> + <key>reference</key> + <value>1.0</value> + <type>real</type> + </param> + <param> + <name>Gain</name> + <key>gain</key> + <value>1.0</value> + <type>real</type> + </param> + <param> + <name>Max Gain</name> + <key>max_gain</key> + <value>0.0</value> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>$type</type> + </sink> + <source> + <name>out</name> + <type>$type</type> + </source> +</block> diff --git a/gr-analog/grc/analog_agc_xx.xml b/gr-analog/grc/analog_agc_xx.xml new file mode 100644 index 000000000..46797bff9 --- /dev/null +++ b/gr-analog/grc/analog_agc_xx.xml @@ -0,0 +1,63 @@ +<?xml version="1.0"?> +<!-- +################################################### +##AGC +################################################### + --> +<block> + <name>AGC</name> + <key>analog_agc_xx</key> + <import>from gnuradio import analog</import> + <make>analog.agc_$(type.fcn)($rate, $reference, $gain, $max_gain)</make> + <callback>set_rate($rate)</callback> + <callback>set_reference($reference)</callback> + <callback>set_gain($gain)</callback> + <callback>set_max_gain($max_gain)</callback> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>fcn:cc</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>fcn:ff</opt> + </option> + </param> + <param> + <name>Rate</name> + <key>rate</key> + <value>1e-4</value> + <type>real</type> + </param> + <param> + <name>Reference</name> + <key>reference</key> + <value>1.0</value> + <type>real</type> + </param> + <param> + <name>Gain</name> + <key>gain</key> + <value>1.0</value> + <type>real</type> + </param> + <param> + <name>Max Gain</name> + <key>max_gain</key> + <value>0.0</value> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>$type</type> + </sink> + <source> + <name>out</name> + <type>$type</type> + </source> +</block> diff --git a/gr-analog/grc/analog_block_tree.xml b/gr-analog/grc/analog_block_tree.xml new file mode 100644 index 000000000..b5b2ecd56 --- /dev/null +++ b/gr-analog/grc/analog_block_tree.xml @@ -0,0 +1,64 @@ +<?xml version="1.0"?> + +<!-- + Copyright 2012 Free Software Foundation, Inc. + + This file is part of GNU Radio + + GNU Radio is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GNU Radio is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Radio; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, + Boston, MA 02110-1301, USA. +--> + +<!-- +################################################### +##Block Tree for GR Analog blocks. +################################################### + --> +<cat> + <name></name> <!-- Blank for Root Name --> + <cat> + <name>Level Controls</name> + <block>analog_agc_xx</block> + <block>analog_agc2_xx</block> + <block>analog_dpll_bb</block> + <block>analog_feedforward_agc_cc</block> + <block>analog_ctcss_squelch_ff</block> + <block>analog_pwr_squelch_xx</block> + <block>analog_simple_squelch_cc</block> + <block>analog_rail_ff</block> + </cat> + <cat> + <name>Modulators</name> + <block>analog_cpfsk_bc</block> + <block>analog_frequency_modulator_fc</block> + <block>analog_phase_modulator_fc</block> + <block>analog_quadrature_demod_cf</block> + </cat> + <cat> + <name>Sources</name> + <block>analog_sig_source_x</block> + <block>analog_noise_source_x</block> + </cat> + <cat> + <name>Synchronizers</name> + <block>analog_pll_carriertracking_cc</block> + <block>analog_pll_freqdet_cf</block> + <block>analog_pll_refout_cc</block> + </cat> + <cat> + <name>Probes</name> + <block>analog_probe_avg_mag_sqrd_x</block> + </cat> +</cat> diff --git a/gr-analog/grc/analog_cpfsk_bc.xml b/gr-analog/grc/analog_cpfsk_bc.xml new file mode 100644 index 000000000..7eb85a2ec --- /dev/null +++ b/gr-analog/grc/analog_cpfsk_bc.xml @@ -0,0 +1,37 @@ +<?xml version="1.0"?> +<!-- +################################################### +##CPFSK +################################################### + --> +<block> + <name>CPFSK</name> + <key>analog_cpfsk_bc</key> + <import>from gnuradio import analog</import> + <make>analog.cpfsk_bc($k, $amplitude, $samples_per_symbol)</make> + <callback>set_amplitude($amplitude)</callback> + <param> + <name>K</name> + <key>k</key> + <type>real</type> + </param> + <param> + <name>Amplitude</name> + <key>amplitude</key> + <type>real</type> + </param> + <param> + <name>Samples/Symbol</name> + <key>samples_per_symbol</key> + <value>2</value> + <type>int</type> + </param> + <sink> + <name>in</name> + <type>byte</type> + </sink> + <source> + <name>out</name> + <type>complex</type> + </source> +</block> diff --git a/gr-analog/grc/analog_ctcss_squelch_ff.xml b/gr-analog/grc/analog_ctcss_squelch_ff.xml new file mode 100644 index 000000000..9585835e2 --- /dev/null +++ b/gr-analog/grc/analog_ctcss_squelch_ff.xml @@ -0,0 +1,79 @@ +<?xml version="1.0"?> +<!-- +# +# Copyright 2011 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +--> + +<!-- +################################################### +##CTCSS Squelch +################################################### + --> +<block> + <name>CTCSS Squelch</name> + <key>analog_ctcss_squelch_ff</key> + <import>from gnuradio import analog</import> + <make>analog.ctcss_squelch_ff($rate, $freq, $level, $len, $ramp, $gate)</make> + <callback>set_level($level)</callback> + <param> + <name>Sampling Rate (Hz)</name> + <key>rate</key> + <value>samp_rate</value> + <type>real</type> + </param> + <param> + <name>Tone Frequency</name> + <key>freq</key> + <value>100.0</value> + <type>real</type> + </param> + <param> + <name>Level</name> + <key>level</key> + <value>0.01</value> + <type>real</type> + </param> + <param> + <name>Length</name> + <key>len</key> + <value>0</value> + <type>int</type> + </param> + <param> + <name>Ramp</name> + <key>ramp</key> + <value>0</value> + <type>int</type> + </param> + <param> + <name>Gate</name> + <key>gate</key> + <value>False</value> + <type>bool</type> + </param> + <sink> + <name>in</name> + <type>float</type> + </sink> + <source> + <name>out</name> + <type>float</type> + </source> +</block> diff --git a/gr-analog/grc/analog_dpll_bb.xml b/gr-analog/grc/analog_dpll_bb.xml new file mode 100644 index 000000000..65a489414 --- /dev/null +++ b/gr-analog/grc/analog_dpll_bb.xml @@ -0,0 +1,31 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Detect Peak +################################################### + --> +<block> + <name>Detect Peak</name> + <key>analog_dpll_bb</key> + <import>from gnuradio import analog</import> + <make>analog.dpll_bb($period, $gain)</make> + <callback>set_gain($gain)</callback> + <param> + <name>Period</name> + <key>period</key> + <type>real</type> + </param> + <param> + <name>Gain</name> + <key>gain</key> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>byte</type> + </sink> + <source> + <name>out</name> + <type>byte</type> + </source> +</block> diff --git a/gr-analog/grc/analog_feedforward_agc_cc.xml b/gr-analog/grc/analog_feedforward_agc_cc.xml new file mode 100644 index 000000000..66d200a84 --- /dev/null +++ b/gr-analog/grc/analog_feedforward_agc_cc.xml @@ -0,0 +1,32 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Feed Forward AGC +################################################### + --> +<block> + <name>Feed Forward AGC</name> + <key>analog_feedforward_agc_cc</key> + <import>from gnuradio import analog</import> + <make>analog.feedforward_agc_cc($num_samples, $reference)</make> + <param> + <name>Num Samples</name> + <key>num_samples</key> + <value>1024</value> + <type>int</type> + </param> + <param> + <name>Reference</name> + <key>reference</key> + <value>1.0</value> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>complex</type> + </sink> + <source> + <name>out</name> + <type>complex</type> + </source> +</block> diff --git a/gr-analog/grc/analog_frequency_modulator_fc.xml b/gr-analog/grc/analog_frequency_modulator_fc.xml new file mode 100644 index 000000000..3b6cd159a --- /dev/null +++ b/gr-analog/grc/analog_frequency_modulator_fc.xml @@ -0,0 +1,26 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Frequency Modulator +################################################### + --> +<block> + <name>Frequency Mod</name> + <key>analog_frequency_modulator_fc</key> + <import>from gnuradio import analog</import> + <make>analog.frequency_modulator_fc($sensitivity)</make> + <callback>set_sensitivity($sensitivity)</callback> + <param> + <name>Sensitivity</name> + <key>sensitivity</key> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>float</type> + </sink> + <source> + <name>out</name> + <type>complex</type> + </source> +</block> diff --git a/gr-analog/grc/analog_noise_source_x.xml b/gr-analog/grc/analog_noise_source_x.xml new file mode 100644 index 000000000..5404e7896 --- /dev/null +++ b/gr-analog/grc/analog_noise_source_x.xml @@ -0,0 +1,77 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Noise Source +################################################### + --> +<block> + <name>Noise Source</name> + <key>analog_noise_source_x</key> + <import>from gnuradio import analog</import> + <make>analog.noise_source_$(type.fcn)($noise_type, $amp, $seed)</make> + <callback>set_type($noise_type)</callback> + <callback>set_amplitude($amp)</callback> + <param> + <name>Output Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>fcn:c</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>fcn:f</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>fcn:i</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>fcn:s</opt> + </option> + </param> + <param> + <name>Noise Type</name> + <key>noise_type</key> + <value>analog.GR_GAUSSIAN</value> + <type>int</type> + <option> + <name>Uniform</name> + <key>analog.GR_UNIFORM</key> + </option> + <option> + <name>Gaussian</name> + <key>analog.GR_GAUSSIAN</key> + </option> + <option> + <name>Laplacian</name> + <key>analog.GR_LAPLACIAN</key> + </option> + <option> + <name>Impulse</name> + <key>analog.GR_IMPULSE</key> + </option> + </param> + <param> + <name>Amplitude</name> + <key>amp</key> + <value>1</value> + <type>real</type> + </param> + <param> + <name>Seed</name> + <key>seed</key> + <value>0</value> + <type>int</type> + </param> + <source> + <name>out</name> + <type>$type</type> + </source> +</block> diff --git a/gr-analog/grc/analog_phase_modulator_fc.xml b/gr-analog/grc/analog_phase_modulator_fc.xml new file mode 100644 index 000000000..c13af769c --- /dev/null +++ b/gr-analog/grc/analog_phase_modulator_fc.xml @@ -0,0 +1,26 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Phase Modulator +################################################### + --> +<block> + <name>Phase Mod</name> + <key>analog_phase_modulator_fc</key> + <import>from gnuradio import analog</import> + <make>analog.phase_modulator_fc($sensitivity)</make> + <callback>set_sensitivity($sensitivity)</callback> + <param> + <name>Sensitivity</name> + <key>sensitivity</key> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>float</type> + </sink> + <source> + <name>out</name> + <type>complex</type> + </source> +</block> diff --git a/gr-analog/grc/analog_pll_carriertracking_cc.xml b/gr-analog/grc/analog_pll_carriertracking_cc.xml new file mode 100644 index 000000000..95ec4b415 --- /dev/null +++ b/gr-analog/grc/analog_pll_carriertracking_cc.xml @@ -0,0 +1,38 @@ +<?xml version="1.0"?> +<!-- +################################################### +##PLL Carrier Tracking +################################################### + --> +<block> + <name>PLL Carrier Tracking</name> + <key>analog_pll_carriertracking_cc</key> + <import>from gnuradio import analog</import> + <make>analog.pll_carriertracking_cc($w, $max_freq, $min_freq)</make> + <callback>set_loop_bandwidth($w)</callback> + <callback>set_max_freq($max_freq)</callback> + <callback>set_min_freq($min_freq)</callback> + <param> + <name>Loop Bandwidth</name> + <key>w</key> + <type>real</type> + </param> + <param> + <name>Max Freq</name> + <key>max_freq</key> + <type>real</type> + </param> + <param> + <name>Min Freq</name> + <key>min_freq</key> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>complex</type> + </sink> + <source> + <name>out</name> + <type>complex</type> + </source> +</block> diff --git a/gr-analog/grc/analog_pll_freqdet_cf.xml b/gr-analog/grc/analog_pll_freqdet_cf.xml new file mode 100644 index 000000000..0d44c160b --- /dev/null +++ b/gr-analog/grc/analog_pll_freqdet_cf.xml @@ -0,0 +1,38 @@ +<?xml version="1.0"?> +<!-- +################################################### +##PLL Frequency Det +################################################### + --> +<block> + <name>PLL Freq Det</name> + <key>analog_pll_freqdet_cf</key> + <import>from gnuradio import analog</import> + <make>analog.pll_freqdet_cf($w, $max_freq, $min_freq)</make> + <callback>set_loop_bandwidth($w)</callback> + <callback>set_max_freq($max_freq)</callback> + <callback>set_min_freq($min_freq)</callback> + <param> + <name>Loop Bandwidth</name> + <key>w</key> + <type>real</type> + </param> + <param> + <name>Max Freq</name> + <key>max_freq</key> + <type>real</type> + </param> + <param> + <name>Min Freq</name> + <key>min_freq</key> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>complex</type> + </sink> + <source> + <name>out</name> + <type>float</type> + </source> +</block> diff --git a/gr-analog/grc/analog_pll_refout_cc.xml b/gr-analog/grc/analog_pll_refout_cc.xml new file mode 100644 index 000000000..eb2d752b2 --- /dev/null +++ b/gr-analog/grc/analog_pll_refout_cc.xml @@ -0,0 +1,38 @@ +<?xml version="1.0"?> +<!-- +################################################### +##PLL Reference Out +################################################### + --> +<block> + <name>PLL Ref Out</name> + <key>analog_pll_refout_cc</key> + <import>from gnuradio import analog</import> + <make>analog.pll_refout_cc($w, $max_freq, $min_freq)</make> + <callback>set_loop_bandwidth($w)</callback> + <callback>set_max_freq($max_freq)</callback> + <callback>set_min_freq($min_freq)</callback> + <param> + <name>Loop Bandwidth</name> + <key>w</key> + <type>real</type> + </param> + <param> + <name>Max Freq</name> + <key>max_freq</key> + <type>real</type> + </param> + <param> + <name>Min Freq</name> + <key>min_freq</key> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>complex</type> + </sink> + <source> + <name>out</name> + <type>complex</type> + </source> +</block> diff --git a/gr-analog/grc/analog_probe_avg_mag_sqrd_x.xml b/gr-analog/grc/analog_probe_avg_mag_sqrd_x.xml new file mode 100644 index 000000000..b05ac6d0d --- /dev/null +++ b/gr-analog/grc/analog_probe_avg_mag_sqrd_x.xml @@ -0,0 +1,50 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Probe Average Magnitude Squared +################################################### + --> +<block> + <name>Probe Avg Mag^2</name> + <key>analog_probe_avg_mag_sqrd_x</key> + <import>from gnuradio import analog</import> + <make>analog.probe_avg_mag_sqrd_$(type)($threshold, $alpha)</make> + <callback>set_alpha($alpha)</callback> + <callback>set_threshold($threshold)</callback> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>c</key> + <opt>input:complex</opt> + </option> + <option> + <name>Float</name> + <key>f</key> + <opt>input:float</opt> + </option> + </param> + <param> + <name>Threshold (dB)</name> + <key>threshold</key> + <value>0</value> + <type>real</type> + </param> + <param> + <name>Alpha</name> + <key>alpha</key> + <value>1</value> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>$type.input</type> + </sink> + <doc> +Available functions to probe: level() + +Use with the function probe block. + </doc> +</block> diff --git a/gr-analog/grc/analog_pwr_squelch_xx.xml b/gr-analog/grc/analog_pwr_squelch_xx.xml new file mode 100644 index 000000000..32d9c0e94 --- /dev/null +++ b/gr-analog/grc/analog_pwr_squelch_xx.xml @@ -0,0 +1,65 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Power Squelch +################################################### + --> +<block> + <name>Power Squelch</name> + <key>analog_pwr_squelch_xx</key> + <import>from gnuradio import analog</import> + <make>analog.pwr_squelch_$(type.fcn)($threshold, $alpha, $ramp, $gate)</make> + <callback>set_threshold($threshold)</callback> + <callback>set_alpha($alpha)</callback> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>fcn:cc</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>fcn:ff</opt> + </option> + </param> + <param> + <name>Threshold (dB)</name> + <key>threshold</key> + <type>real</type> + </param> + <param> + <name>Alpha</name> + <key>alpha</key> + <type>real</type> + </param> + <param> + <name>Ramp</name> + <key>ramp</key> + <type>int</type> + </param> + <param> + <name>Gate</name> + <key>gate</key> + <type>enum</type> + <option> + <name>Yes</name> + <key>True</key> + </option> + <option> + <name>No</name> + <key>False</key> + </option> + </param> + <sink> + <name>in</name> + <type>$type</type> + </sink> + <source> + <name>out</name> + <type>$type</type> + </source> +</block> diff --git a/gr-analog/grc/analog_quadrature_demod_cf.xml b/gr-analog/grc/analog_quadrature_demod_cf.xml new file mode 100644 index 000000000..a60653135 --- /dev/null +++ b/gr-analog/grc/analog_quadrature_demod_cf.xml @@ -0,0 +1,26 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Quadrature Demodulator +################################################### + --> +<block> + <name>Quadrature Demod</name> + <key>analog_quadrature_demod_cf</key> + <import>from gnuradio import analog</import> + <make>analog.quadrature_demod_cf($gain)</make> + <callback>set_gain($gain)</callback> + <param> + <name>Gain</name> + <key>gain</key> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>complex</type> + </sink> + <source> + <name>out</name> + <type>float</type> + </source> +</block> diff --git a/gr-analog/grc/analog_rail_ff.xml b/gr-analog/grc/analog_rail_ff.xml new file mode 100644 index 000000000..87dff0977 --- /dev/null +++ b/gr-analog/grc/analog_rail_ff.xml @@ -0,0 +1,54 @@ +<?xml version="1.0"?> +<!-- +# +# Copyright 2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +--> + +<!-- +################################################### +##Rail +################################################### + --> +<block> + <name>Rail</name> + <key>analog_rail_ff</key> + <import>from gnuradio import analog</import> + <make>analog.rail_ff($lo, $hi)</make> + <callback>set_lo($lo)</callback> + <callback>set_hi($hi)</callback> + <param> + <name>Low clipping</name> + <key>lo</key> + <type>real</type> + </param> + <param> + <name>Hi clipping</name> + <key>hi</key> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>float</type> + </sink> + <source> + <name>out</name> + <type>float</type> + </source> +</block> diff --git a/gr-analog/grc/analog_sig_source_x.xml b/gr-analog/grc/analog_sig_source_x.xml new file mode 100644 index 000000000..b2cd8ad43 --- /dev/null +++ b/gr-analog/grc/analog_sig_source_x.xml @@ -0,0 +1,104 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Signal Source +################################################### + --> +<block> + <name>Signal Source</name> + <key>analog_sig_source_x</key> + <import>from gnuradio import analog</import> + <make>analog.sig_source_$(type.fcn)($samp_rate, $waveform, $freq, $amp, $offset)</make> + <callback>set_sampling_freq($samp_rate)</callback> + <callback>set_waveform($waveform)</callback> + <callback>set_frequency($freq)</callback> + <callback>set_amplitude($amp)</callback> + <callback>set_offset($offset)</callback> + <param> + <name>Output Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>fcn:c</opt> + <opt>offset_type:complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>fcn:f</opt> + <opt>offset_type:real</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>fcn:i</opt> + <opt>offset_type:int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>fcn:s</opt> + <opt>offset_type:int</opt> + </option> + </param> + <param> + <name>Sample Rate</name> + <key>samp_rate</key> + <value>samp_rate</value> + <type>real</type> + </param> + <param> + <name>Waveform</name> + <key>waveform</key> + <value>analog.GR_COS_WAVE</value> + <type>int</type> + <option> + <name>Constant</name> + <key>analog.GR_CONST_WAVE</key> + </option> + <option> + <name>Sine</name> + <key>analog.GR_SIN_WAVE</key> + </option> + <option> + <name>Cosine</name> + <key>analog.GR_COS_WAVE</key> + </option> + <option> + <name>Square</name> + <key>analog.GR_SQR_WAVE</key> + </option> + <option> + <name>Triangle</name> + <key>analog.GR_TRI_WAVE</key> + </option> + <option> + <name>Saw Tooth</name> + <key>analog.GR_SAW_WAVE</key> + </option> + </param> + <param> + <name>Frequency</name> + <key>freq</key> + <value>1000</value> + <type>real</type> + </param> + <param> + <name>Amplitude</name> + <key>amp</key> + <value>1</value> + <type>real</type> + </param> + <param> + <name>Offset</name> + <key>offset</key> + <value>0</value> + <type>$type.offset_type</type> + </param> + <source> + <name>out</name> + <type>$type</type> + </source> +</block> diff --git a/gr-analog/grc/analog_simple_squelch_cc.xml b/gr-analog/grc/analog_simple_squelch_cc.xml new file mode 100644 index 000000000..648921a14 --- /dev/null +++ b/gr-analog/grc/analog_simple_squelch_cc.xml @@ -0,0 +1,32 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Simple Squelch +################################################### + --> +<block> + <name>Simple Squelch</name> + <key>analog_simple_squelch_cc</key> + <import>from gnuradio import analog</import> + <make>analog.simple_squelch_cc($threshold, $alpha)</make> + <callback>set_threshold($threshold)</callback> + <callback>set_alpha($alpha)</callback> + <param> + <name>Threshold (dB)</name> + <key>threshold</key> + <type>real</type> + </param> + <param> + <name>Alpha</name> + <key>alpha</key> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>complex</type> + </sink> + <source> + <name>out</name> + <type>complex</type> + </source> +</block> diff --git a/gr-analog/include/analog/CMakeLists.txt b/gr-analog/include/analog/CMakeLists.txt new file mode 100644 index 000000000..4de94a88b --- /dev/null +++ b/gr-analog/include/analog/CMakeLists.txt @@ -0,0 +1,111 @@ +# Copyright 2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. + +######################################################################## +# generate helper scripts to expand templated files +######################################################################## +include(GrPython) + +file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py " +#!${PYTHON_EXECUTABLE} + +import sys, os, re +sys.path.append('${GR_CORE_PYTHONPATH}') +os.environ['srcdir'] = '${CMAKE_CURRENT_SOURCE_DIR}' +os.chdir('${CMAKE_CURRENT_BINARY_DIR}') + +if __name__ == '__main__': + import build_utils + root, inp = sys.argv[1:3] + for sig in sys.argv[3:]: + name = re.sub ('X+', sig, root) + d = build_utils.standard_dict2(name, sig, 'analog') + build_utils.expand_template(d, inp) + +") + +macro(expand_h root) + #make a list of all the generated files + unset(expanded_files_h) + foreach(sig ${ARGN}) + string(REGEX REPLACE "X+" ${sig} name ${root}) + list(APPEND expanded_files_h ${CMAKE_CURRENT_BINARY_DIR}/${name}.h) + endforeach(sig) + + #create a command to generate the files + add_custom_command( + OUTPUT ${expanded_files_h} + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}.h.t + COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B} + ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py + ${root} ${root}.h.t ${ARGN} + ) + + #install rules for the generated h files + list(APPEND generated_includes ${expanded_files_h}) +endmacro(expand_h) + +######################################################################## +# Invoke macro to generate various sources +####################################################################### +expand_h(noise_source_X s i f c) +expand_h(sig_source_X s i f c) + +add_custom_target(analog_generated_includes DEPENDS + ${generated_includes} +) + +######################################################################## +# Install header files +######################################################################## +install(FILES + ${analog_generated_includes} + api.h + cpm.h + agc.h + agc2.h + squelch_base_ff.h + agc_cc.h + agc_ff.h + agc2_cc.h + agc2_ff.h + cpfsk_bc.h + ctcss_squelch_ff.h + dpll_bb.h + feedforward_agc_cc.h + fmdet_cf.h + frequency_modulator_fc.h + phase_modulator_fc.h + pll_carriertracking_cc.h + pll_freqdet_cf.h + pll_refout_cc.h + probe_avg_mag_sqrd_c.h + probe_avg_mag_sqrd_cf.h + probe_avg_mag_sqrd_f.h + pwr_squelch_cc.h + pwr_squelch_ff.h + quadrature_demod_cf.h + rail_ff.h + rotator.h + sig_source_waveform.h + simple_squelch_cc.h + DESTINATION ${GR_INCLUDE_DIR}/gnuradio/analog + COMPONENT "analog_devel" +) + diff --git a/gr-analog/include/analog/agc.h b/gr-analog/include/analog/agc.h new file mode 100644 index 000000000..92d777fa1 --- /dev/null +++ b/gr-analog/include/analog/agc.h @@ -0,0 +1,136 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ANALOG_AGC_H +#define INCLUDED_ANALOG_AGC_H + +#include <analog/api.h> +#include <gr_complex.h> +#include <math.h> + +namespace gr { + namespace analog { + namespace kernel { + + /*! + * \brief high performance Automatic Gain Control class for complex signals. + * + * For Power the absolute value of the complex number is used. + */ + class ANALOG_API agc_cc + { + public: + agc_cc(float rate = 1e-4, float reference = 1.0, + float gain = 1.0, float max_gain = 0.0) + : _rate(rate), _reference(reference), + _gain(gain), _max_gain(max_gain) {}; + + virtual ~agc_cc() {}; + + float rate() const { return _rate; } + float reference() const { return _reference; } + float gain() const { return _gain; } + float max_gain() const { return _max_gain; } + + void set_rate(float rate) { _rate = rate; } + void set_reference(float reference) { _reference = reference; } + void set_gain(float gain) { _gain = gain; } + void set_max_gain(float max_gain) { _max_gain = max_gain; } + + gr_complex scale(gr_complex input) + { + gr_complex output = input * _gain; + + _gain += _rate * (_reference - sqrt(output.real()*output.real() + + output.imag()*output.imag())); + if(_max_gain > 0.0 && _gain > _max_gain) { + _gain = _max_gain; + } + return output; + } + + void scaleN(gr_complex output[], const gr_complex input[], unsigned n) + { + for(unsigned i = 0; i < n; i++) { + output[i] = scale (input[i]); + } + } + + protected: + float _rate; // adjustment rate + float _reference; // reference value + float _gain; // current gain + float _max_gain; // max allowable gain + }; + + /*! + * \brief high performance Automatic Gain Control class for float signals. + * + * Power is approximated by absolute value + */ + class ANALOG_API agc_ff + { + public: + agc_ff(float rate = 1e-4, float reference = 1.0, + float gain = 1.0, float max_gain = 0.0) + : _rate(rate), _reference(reference), _gain(gain), + _max_gain(max_gain) {}; + + ~agc_ff() {}; + + float rate () const { return _rate; } + float reference () const { return _reference; } + float gain () const { return _gain; } + float max_gain () const { return _max_gain; } + + void set_rate (float rate) { _rate = rate; } + void set_reference (float reference) { _reference = reference; } + void set_gain (float gain) { _gain = gain; } + void set_max_gain (float max_gain) { _max_gain = max_gain; } + + float scale (float input) + { + float output = input * _gain; + _gain += (_reference - fabsf (output)) * _rate; + if(_max_gain > 0.0 && _gain > _max_gain) + _gain = _max_gain; + return output; + } + + void scaleN(float output[], const float input[], unsigned n) + { + for(unsigned i = 0; i < n; i++) + output[i] = scale (input[i]); + } + + protected: + float _rate; // adjustment rate + float _reference; // reference value + float _gain; // current gain + float _max_gain; // maximum gain + }; + + } /* namespace kernel */ + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_AGC_H */ diff --git a/gr-analog/include/analog/agc2.h b/gr-analog/include/analog/agc2.h new file mode 100644 index 000000000..75a203e9f --- /dev/null +++ b/gr-analog/include/analog/agc2.h @@ -0,0 +1,160 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ANALOG_AGC2_H +#define INCLUDED_ANALOG_AGC2_H + +#include <analog/api.h> +#include <gr_complex.h> +#include <math.h> + +namespace gr { + namespace analog { + namespace kernel { + + /*! + * \brief high performance Automatic Gain Control class + * + * For Power the absolute value of the complex number is used. + */ + class ANALOG_API agc2_cc + { + public: + agc2_cc(float attack_rate = 1e-1, float decay_rate = 1e-2, + float reference = 1.0, + float gain = 1.0, float max_gain = 0.0) + : _attack_rate(attack_rate), _decay_rate(decay_rate), + _reference(reference), + _gain(gain), _max_gain(max_gain) {}; + + float decay_rate() const { return _decay_rate; } + float attack_rate() const { return _attack_rate; } + float reference() const { return _reference; } + float gain() const { return _gain; } + float max_gain() const { return _max_gain; } + + void set_decay_rate(float rate) { _decay_rate = rate; } + void set_attack_rate(float rate) { _attack_rate = rate; } + void set_reference(float reference) { _reference = reference; } + void set_gain(float gain) { _gain = gain; } + void set_max_gain(float max_gain) { _max_gain = max_gain; } + + gr_complex scale(gr_complex input) + { + gr_complex output = input * _gain; + + float tmp = -_reference + sqrt(output.real()*output.real() + + output.imag()*output.imag()); + float rate = _decay_rate; + if((tmp) > _gain) { + rate = _attack_rate; + } + _gain -= tmp*rate; + + // Not sure about this; will blow up if _gain < 0 (happens + // when rates are too high), but is this the solution? + if(_gain < 0.0) + _gain = 10e-5; + + if(_max_gain > 0.0 && _gain > _max_gain) { + _gain = _max_gain; + } + return output; + } + + void scaleN(gr_complex output[], const gr_complex input[], unsigned n) + { + for(unsigned i = 0; i < n; i++) + output[i] = scale (input[i]); + } + + protected: + float _attack_rate; // attack rate for fast changing signals + float _decay_rate; // decay rate for slow changing signals + float _reference; // reference value + float _gain; // current gain + float _max_gain; // max allowable gain + }; + + + class ANALOG_API agc2_ff + { + public: + agc2_ff(float attack_rate = 1e-1, float decay_rate = 1e-2, + float reference = 1.0, + float gain = 1.0, float max_gain = 0.0) + : _attack_rate(attack_rate), _decay_rate(decay_rate), + _reference(reference), + _gain(gain), _max_gain(max_gain) {}; + + float attack_rate() const { return _attack_rate; } + float decay_rate() const { return _decay_rate; } + float reference() const { return _reference; } + float gain() const { return _gain; } + float max_gain() const { return _max_gain; } + + void set_attack_rate(float rate) { _attack_rate = rate; } + void set_decay_rate(float rate) { _decay_rate = rate; } + void set_reference(float reference) { _reference = reference; } + void set_gain(float gain) { _gain = gain; } + void set_max_gain(float max_gain) { _max_gain = max_gain; } + + float scale(float input) + { + float output = input * _gain; + + float tmp = (fabsf(output)) - _reference; + float rate = _decay_rate; + if(fabsf(tmp) > _gain) { + rate = _attack_rate; + } + _gain -= tmp*rate; + + // Not sure about this + if(_gain < 0.0) + _gain = 10e-5; + + if(_max_gain > 0.0 && _gain > _max_gain) { + _gain = _max_gain; + } + return output; + } + + void scaleN(float output[], const float input[], unsigned n) + { + for(unsigned i = 0; i < n; i++) + output[i] = scale (input[i]); + } + + protected: + float _attack_rate; // attack_rate for fast changing signals + float _decay_rate; // decay rate for slow changing signals + float _reference; // reference value + float _gain; // current gain + float _max_gain; // maximum gain + }; + + } /* namespace kernel */ + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_AGC2_H */ diff --git a/gr-analog/include/analog/agc2_cc.h b/gr-analog/include/analog/agc2_cc.h new file mode 100644 index 000000000..c922ccd4d --- /dev/null +++ b/gr-analog/include/analog/agc2_cc.h @@ -0,0 +1,65 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ANALOG_AGC2_CC_H +#define INCLUDED_ANALOG_AGC2_CC_H + +#include <analog/api.h> +#include <analog/agc2.h> +#include <gr_sync_block.h> + +namespace gr { + namespace analog { + + /*! + * \brief high performance Automatic Gain Control class + * \ingroup level_blk + * + * For Power the absolute value of the complex number is used. + */ + class ANALOG_API agc2_cc : virtual public gr_sync_block + { + public: + // gr::analog::agc2_cc::sptr + typedef boost::shared_ptr<agc2_cc> sptr; + + static sptr make(float attack_rate = 1e-1, float decay_rate = 1e-2, + float reference = 1.0, + float gain = 1.0, float max_gain = 0.0); + + virtual float attack_rate() const = 0; + virtual float decay_rate() const = 0; + virtual float reference() const = 0; + virtual float gain() const = 0; + virtual float max_gain() const = 0; + + virtual void set_attack_rate(float rate) = 0; + virtual void set_decay_rate(float rate) = 0; + virtual void set_reference(float reference) = 0; + virtual void set_gain(float gain) = 0; + virtual void set_max_gain(float max_gain) = 0; + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_AGC2_CC_H */ diff --git a/gr-analog/include/analog/agc2_ff.h b/gr-analog/include/analog/agc2_ff.h new file mode 100644 index 000000000..27dd6d92e --- /dev/null +++ b/gr-analog/include/analog/agc2_ff.h @@ -0,0 +1,65 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2006,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ANALOG_AGC2_FF_H +#define INCLUDED_ANALOG_AGC2_FF_H + +#include <analog/api.h> +#include <analog/agc2.h> +#include <gr_sync_block.h> + +namespace gr { + namespace analog { + + /*! + * \brief high performance Automatic Gain Control class + * + * \ingroup level_blk + * Power is approximated by absolute value + */ + class ANALOG_API agc2_ff : virtual public gr_sync_block + { + public: + // gr::analog::agc2_ff::sptr + typedef boost::shared_ptr<agc2_ff> sptr; + + static sptr make(float attack_rate = 1e-1, float decay_rate = 1e-2, + float reference = 1.0, + float gain = 1.0, float max_gain = 0.0); + + virtual float attack_rate() const = 0; + virtual float decay_rate() const = 0; + virtual float reference() const = 0; + virtual float gain() const = 0; + virtual float max_gain() const = 0; + + virtual void set_attack_rate(float rate) = 0; + virtual void set_decay_rate(float rate) = 0; + virtual void set_reference(float reference) = 0; + virtual void set_gain(float gain) = 0; + virtual void set_max_gain(float max_gain) = 0; + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_AGC2_FF_H */ diff --git a/gr-analog/include/analog/agc_cc.h b/gr-analog/include/analog/agc_cc.h new file mode 100644 index 000000000..b2b1a9b43 --- /dev/null +++ b/gr-analog/include/analog/agc_cc.h @@ -0,0 +1,62 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ANALOG_AGC_CC_H +#define INCLUDED_ANALOG_AGC_CC_H + +#include <analog/api.h> +#include <analog/agc.h> +#include <gr_sync_block.h> + +namespace gr { + namespace analog { + + /*! + * \brief high performance Automatic Gain Control class + * \ingroup level_blk + * + * For Power the absolute value of the complex number is used. + */ + class ANALOG_API agc_cc : virtual public gr_sync_block + { + public: + // gr::analog::agc_cc::sptr + typedef boost::shared_ptr<agc_cc> sptr; + + static sptr make(float rate = 1e-4, float reference = 1.0, + float gain = 1.0, float max_gain = 0.0); + + virtual float rate() const = 0; + virtual float reference() const = 0; + virtual float gain() const = 0; + virtual float max_gain() const = 0; + + virtual void set_rate(float rate) = 0; + virtual void set_reference(float reference) = 0; + virtual void set_gain(float gain) = 0; + virtual void set_max_gain(float max_gain) = 0; + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_AGC_CC_H */ diff --git a/gr-analog/include/analog/agc_ff.h b/gr-analog/include/analog/agc_ff.h new file mode 100644 index 000000000..30d1ae1fd --- /dev/null +++ b/gr-analog/include/analog/agc_ff.h @@ -0,0 +1,62 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2006,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ANALOG_AGC_FF_H +#define INCLUDED_ANALOG_AGC_FF_H + +#include <analog/api.h> +#include <analog/agc.h> +#include <gr_sync_block.h> + +namespace gr { + namespace analog { + + /*! + * \brief high performance Automatic Gain Control class + * \ingroup level_blk + * + * Power is approximated by absolute value + */ + class ANALOG_API agc_ff : virtual public gr_sync_block + { + public: + // gr::analog::agc_ff::sptr + typedef boost::shared_ptr<agc_ff> sptr; + + static sptr make(float rate = 1e-4, float reference = 1.0, + float gain = 1.0, float max_gain = 0.0); + + virtual float rate() const = 0; + virtual float reference() const = 0; + virtual float gain() const = 0; + virtual float max_gain() const = 0; + + virtual void set_rate(float rate) = 0; + virtual void set_reference(float reference) = 0; + virtual void set_gain(float gain) = 0; + virtual void set_max_gain(float max_gain) = 0; + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_AGC_FF_H */ diff --git a/gr-analog/include/analog/api.h b/gr-analog/include/analog/api.h new file mode 100644 index 000000000..b7dee4693 --- /dev/null +++ b/gr-analog/include/analog/api.h @@ -0,0 +1,33 @@ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ANALOG_API_H +#define INCLUDED_ANALOG_API_H + +#include <gruel/attributes.h> + +#ifdef gnuradio_analog_EXPORTS +# define ANALOG_API __GR_ATTR_EXPORT +#else +# define ANALOG_API __GR_ATTR_IMPORT +#endif + +#endif /* INCLUDED_ANALOG_API_H */ diff --git a/gr-analog/include/analog/cpfsk_bc.h b/gr-analog/include/analog/cpfsk_bc.h new file mode 100644 index 000000000..904730e2b --- /dev/null +++ b/gr-analog/include/analog/cpfsk_bc.h @@ -0,0 +1,59 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008,2012 Free Software Foundation, Inc. + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ANALOG_CPFSK_BC_H +#define INCLUDED_ANALOG_CPFSK_BC_H + +#include <analog/api.h> +#include <gr_sync_interpolator.h> + +namespace gr { + namespace analog { + + /*! + * \brief Perform continuous phase 2-level frequency shift keying modulation + * on an input stream of unpacked bits. + * \ingroup modulation_blk + */ + class ANALOG_API cpfsk_bc : virtual public gr_sync_interpolator + { + public: + // gr::analog::cpfsk_bc::sptr + typedef boost::shared_ptr<cpfsk_bc> sptr; + + /*! + * \brief Make a CPFSK block. + * + * \param k modulation index + * \param ampl output amplitude + * \param samples_per_sym number of output samples per input bit + */ + static sptr make(float k, float ampl, int samples_per_sym); + + virtual void set_amplitude(float amplitude) = 0; + virtual float amplitude() = 0; + virtual float freq() = 0; + virtual float phase() = 0; + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_CPFSK_BC_H */ diff --git a/gr-analog/include/analog/cpm.h b/gr-analog/include/analog/cpm.h new file mode 100644 index 000000000..d22e02321 --- /dev/null +++ b/gr-analog/include/analog/cpm.h @@ -0,0 +1,86 @@ +/* -*- c++ -*- */ +/* + * Copyright 2010,2012 Free Software Foundation, Inc. + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + + +#ifndef INCLUDED_ANALOG_CPM_H +#define INCLUDED_ANALOG_CPM_H + +#include <analog/api.h> +#include <vector> + +namespace gr { + namespace analog { + + class ANALOG_API cpm + { + public: + enum cpm_type { + LRC, + LSRC, + LREC, + TFM, + GAUSSIAN, + GENERIC = 999 + }; + + /*! \brief Return the taps for an interpolating FIR filter (gr_interp_fir_filter_fff). + * + * These taps represent the phase response \f$g(k)\f$ for use in a CPM modulator, + * see also gr_cpmmod_bc. + * + * \param type The CPM type (Rectangular, Raised Cosine, Spectral Raised Cosine, + * Tamed FM or Gaussian). + * \param samples_per_sym Samples per symbol. + * \param L The length of the phase response in symbols. + * \param beta For Spectral Raised Cosine, this is the rolloff factor. For Gaussian + * phase responses, this the 3dB-time-bandwidth product. For all other + * cases, it is ignored. + * + * Output: returns a vector of length \a K = \p samples_per_sym x \p L. + * This can be used directly in an interpolating FIR filter such as + * gr_interp_fir_filter_fff with interpolation factor \p samples_per_sym. + * + * All phase responses are normalised s.t. \f$ \sum_{k=0}^{K-1} g(k) = 1\f$; this will cause + * a maximum phase change of \f$ h \cdot \pi\f$ between two symbols, where \a h is the + * modulation index. + * + * The following phase responses can be generated: + * - LREC: Rectangular phase response. + * - LRC: Raised cosine phase response, looks like 1 - cos(x). + * - LSRC: Spectral raised cosine. This requires a rolloff factor beta. + * The phase response is the Fourier transform of raised cosine + * function. + * - TFM: Tamed frequency modulation. This scheme minimizes phase change for + * rapidly varying input symbols. + * - GAUSSIAN: A Gaussian phase response. For a modulation index h = 1/2, this + * results in GMSK. + * + * A short description of all these phase responses can be found in [1]. + * + * [1]: Anderson, Aulin and Sundberg; Digital Phase Modulation + */ + static std::vector<float> + phase_response(cpm_type type, unsigned samples_per_sym, unsigned L, double beta=0.3); + }; + } // namespace analog +} // namespace gr + +#endif /* INCLUDED_ANALOG_CPM_H */ + diff --git a/gr-analog/include/analog/ctcss_squelch_ff.h b/gr-analog/include/analog/ctcss_squelch_ff.h new file mode 100644 index 000000000..f88029917 --- /dev/null +++ b/gr-analog/include/analog/ctcss_squelch_ff.h @@ -0,0 +1,69 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ANALOG_CTCSS_SQUELCH_FF_H +#define INCLUDED_ANALOG_CTCSS_SQUELCH_FF_H + +#include <analog/api.h> +#include <analog/squelch_base_ff.h> +#include <gr_block.h> + +namespace gr { + namespace analog { + + /*! + * \brief gate or zero output if ctcss tone not present + * \ingroup level_blk + */ + class ANALOG_API ctcss_squelch_ff : + public squelch_base_ff, virtual public gr_block + { + protected: + virtual void update_state(const float &in) = 0; + virtual bool mute() const = 0; + + public: + // gr::analog::ctcss_squelch_ff::sptr + typedef boost::shared_ptr<ctcss_squelch_ff> sptr; + + /*! + * \brief Make CTCSS tone squelch block. + */ + static sptr make(int rate, float freq, float level, + int len, int ramp, bool gate); + + virtual std::vector<float> squelch_range() const = 0; + virtual float level() const = 0; + virtual void set_level(float level) = 0; + virtual int len() const = 0; + + virtual int ramp() const = 0; + virtual void set_ramp(int ramp) = 0; + virtual bool gate() const = 0; + virtual void set_gate(bool gate) = 0; + virtual bool unmuted() const = 0; + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_CTCSS_SQUELCH_FF_H */ diff --git a/gr-analog/include/analog/dpll_bb.h b/gr-analog/include/analog/dpll_bb.h new file mode 100644 index 000000000..78efb8fde --- /dev/null +++ b/gr-analog/include/analog/dpll_bb.h @@ -0,0 +1,59 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ANALOG_DPLL_BB_H +#define INCLUDED_ANALOG_DPLL_BB_H + +#include <analog/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace analog { + + /*! + * \brief Detect the peak of a signal + * \ingroup level_blk + * + * If a peak is detected, this block outputs a 1, + * or it outputs 0's. + */ + class ANALOG_API dpll_bb : virtual public gr_sync_block + { + public: + // gr::analog::dpll_bb::sptr + typedef boost::shared_ptr<dpll_bb> sptr; + + static sptr make(float period, float gain); + + virtual void set_gain(float gain) = 0; + virtual void set_decision_threshold(float thresh) = 0; + + virtual float gain() const = 0; + virtual float freq() const = 0; + virtual float phase() const = 0; + virtual float decision_threshold() const = 0; + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_DPLL_BB_H */ diff --git a/gr-analog/include/analog/feedforward_agc_cc.h b/gr-analog/include/analog/feedforward_agc_cc.h new file mode 100644 index 000000000..9e259a4eb --- /dev/null +++ b/gr-analog/include/analog/feedforward_agc_cc.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ANALOG_FEEDFORWARD_AGC_CC_H +#define INCLUDED_ANALOG_FEEDFORWARD_AGC_CC_H + +#include <analog/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace analog { + + /*! + * \brief Non-causal AGC which computes required gain based on max absolute value over nsamples + * \ingroup level_blk + */ + class ANALOG_API feedforward_agc_cc : virtual public gr_sync_block + { + public: + // gr::analog::feedforward_agc_cc::sptr + typedef boost::shared_ptr<feedforward_agc_cc> sptr; + + static sptr make(int nsamples, float reference); + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_GR_FEEDFORWARD_AGC_CC_H */ diff --git a/gr-analog/include/analog/fmdet_cf.h b/gr-analog/include/analog/fmdet_cf.h new file mode 100644 index 000000000..6878775e6 --- /dev/null +++ b/gr-analog/include/analog/fmdet_cf.h @@ -0,0 +1,70 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ANALOG_FMDET_CF_H +#define INCLUDED_ANALOG_FMDET_CF_H + +#include <analog/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace analog { + + /*! + * \brief Implements an IQ slope detector + * + * input: stream of complex; output: stream of floats + * + * This implements a limiting slope detector. The limiter is in + * the normalization by the magnitude of the sample + */ + class ANALOG_API fmdet_cf : virtual public gr_sync_block + { + public: + // gr::analog::fmdet_cf::sptr + typedef boost::shared_ptr<fmdet_cf> sptr; + + /*! + * \brief Make FM detector block. + * + * \param samplerate sample rate of signal (is not used; to be removed) + * \param freq_low lowest frequency of signal (Hz) + * \param freq_high highest frequency of signal (Hz) + * \param scl scale factor + */ + static sptr make(float samplerate, float freq_low, + float freq_high, float scl); + + virtual void set_scale(float scl) = 0; + virtual void set_freq_range(float freq_low, float freq_high) = 0; + + virtual float freq() const = 0; + virtual float freq_high() const = 0; + virtual float freq_low() const = 0; + virtual float scale() const = 0; + virtual float bias() const = 0; + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_FMDET_CF_H */ diff --git a/gr-analog/include/analog/frequency_modulator_fc.h b/gr-analog/include/analog/frequency_modulator_fc.h new file mode 100644 index 000000000..8706d513a --- /dev/null +++ b/gr-analog/include/analog/frequency_modulator_fc.h @@ -0,0 +1,53 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ANALOG_FREQUENCY_MODULATOR_FC_H +#define INCLUDED_ANALOG_FREQUENCY_MODULATOR_FC_H + +#include <analog/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace analog { + + /*! + * \brief Frequency modulator block + * \ingroup modulation_blk + * + * float input; complex baseband output + */ + class ANALOG_API frequency_modulator_fc : virtual public gr_sync_block + { + public: + // gr::analog::frequency_modulator_fc::sptr + typedef boost::shared_ptr<frequency_modulator_fc> sptr; + + static sptr make(double sensitivity); + + virtual void set_sensitivity(float sens) = 0; + virtual float sensitivity() const = 0; + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_FREQUENCY_MODULATOR_FC_H */ diff --git a/gr-analog/include/analog/lfsr.h b/gr-analog/include/analog/lfsr.h new file mode 100644 index 000000000..5cf2ec70d --- /dev/null +++ b/gr-analog/include/analog/lfsr.h @@ -0,0 +1,162 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008,2010,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ANALOG_LFSR_H +#define INCLUDED_ANALOG_LFSR_H + +#include <analog/api.h> +#include <stdexcept> +#include <stdint.h> + +namespace gr { + namespace analog { + + /*! + * \brief Fibonacci Linear Feedback Shift Register using specified + * polynomial mask + * \ingroup misc + * + * Generates a maximal length pseudo-random sequence of length + * 2^degree-1 + * + * Constructor: analog::lfsr(int mask, int seed, int reg_len); + * + * \param mask - polynomial coefficients representing the + * locations of feedback taps from a shift register + * which are xor'ed together to form the new high + * order bit. + * + * Some common masks might be: + * x^4 + x^3 + x^0 = 0x19 + * x^5 + x^3 + x^0 = 0x29 + * x^6 + x^5 + x^0 = 0x61 + * + * \param seed - the initialization vector placed into the + * register durring initialization. Low order bit + * corresponds to x^0 coefficient -- the first to be + * shifted as output. + * + * \param reg_len - specifies the length of the feedback shift + * register to be used. Durring each iteration, the + * register is rightshifted one and the new bit is + * placed in bit reg_len. reg_len should generally be + * at least order(mask) + 1 + * + * + * see http://en.wikipedia.org/wiki/Linear_feedback_shift_register + * for more explanation. + * + * next_bit() - Standard LFSR operation + * + * Perform one cycle of the LFSR. The output bit is taken from + * the shift register LSB. The shift register MSB is assigned from + * the modulo 2 sum of the masked shift register. + * + * next_bit_scramble(unsigned char input) - Scramble an input stream + * + * Perform one cycle of the LFSR. The output bit is taken from + * the shift register LSB. The shift register MSB is assigned from + * the modulo 2 sum of the masked shift register and the input LSB. + * + * next_bit_descramble(unsigned char input) - Descramble an input stream + * + * Perform one cycle of the LFSR. The output bit is taken from + * the modulo 2 sum of the masked shift register and the input LSB. + * The shift register MSB is assigned from the LSB of the input. + * + * See http://en.wikipedia.org/wiki/Scrambler for operation of these + * last two functions (see multiplicative scrambler.) + */ + class lfsr + { + private: + uint32_t d_shift_register; + uint32_t d_mask; + uint32_t d_seed; + uint32_t d_shift_register_length; // less than 32 + + static uint32_t + popCount(uint32_t x) + { + uint32_t r = x - ((x >> 1) & 033333333333) + - ((x >> 2) & 011111111111); + return ((r + (r >> 3)) & 030707070707) % 63; + } + + public: + lfsr(uint32_t mask, uint32_t seed, uint32_t reg_len) + : d_shift_register(seed), + d_mask(mask), + d_seed(seed), + d_shift_register_length(reg_len) + { + if(reg_len > 31) + throw std::invalid_argument("reg_len must be <= 31"); + } + + unsigned char next_bit() + { + unsigned char output = d_shift_register & 1; + unsigned char newbit = popCount( d_shift_register & d_mask )%2; + d_shift_register = ((d_shift_register>>1) | (newbit<<d_shift_register_length)); + return output; + } + + unsigned char next_bit_scramble(unsigned char input) + { + unsigned char output = d_shift_register & 1; + unsigned char newbit = (popCount( d_shift_register & d_mask )%2)^(input & 1); + d_shift_register = ((d_shift_register>>1) | (newbit<<d_shift_register_length)); + return output; + } + + unsigned char next_bit_descramble(unsigned char input) + { + unsigned char output = (popCount( d_shift_register & d_mask )%2)^(input & 1); + unsigned char newbit = input & 1; + d_shift_register = ((d_shift_register>>1) | (newbit<<d_shift_register_length)); + return output; + } + + /*! + * Reset shift register to initial seed value + */ + void reset() { d_shift_register = d_seed; } + + /*! + * Rotate the register through x number of bits + * where we are just throwing away the results to get queued up correctly + */ + void pre_shift(int num) + { + for(int i=0; i<num; i++) { + next_bit(); + } + } + + int mask() const { return d_mask; } + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_LFSR_H */ diff --git a/gr-analog/include/analog/noise_source_X.h.t b/gr-analog/include/analog/noise_source_X.h.t new file mode 100644 index 000000000..9d1be6fed --- /dev/null +++ b/gr-analog/include/analog/noise_source_X.h.t @@ -0,0 +1,68 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifndef @GUARD_NAME@ +#define @GUARD_NAME@ + +#include <analog/api.h> +#include <analog/noise_type.h> +#include <gr_sync_block.h> +#include <gr_random.h> + +namespace gr { + namespace analog { + + /*! + * \brief Random number source + * \ingroup source_blk + * + * \details + * Generate random values from different distributions. + * Currently, only Gaussian and uniform are enabled. + */ + class ANALOG_API @BASE_NAME@ : virtual public gr_sync_block + { + public: + // gr::analog::@BASE_NAME@::sptr + typedef boost::shared_ptr<@BASE_NAME@> sptr; + + /*! \brief Make a noise source + * \param type the random distribution to use (see analog/noise_type.h) + * \param ampl a scaling factor for the output + * \param seed seed for random generators. Note that for uniform and + * Gaussian distributions, this should be a negative number. + */ + static sptr make(noise_type_t type, float ampl, long seed); + + virtual void set_type(noise_type_t type) = 0; + virtual void set_amplitude(float ampl) = 0; + + virtual noise_type_t type() const = 0; + virtual float amplitude() const = 0; + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* @GUARD_NAME@ */ diff --git a/gr-analog/include/analog/noise_type.h b/gr-analog/include/analog/noise_type.h new file mode 100644 index 000000000..c3a2146b7 --- /dev/null +++ b/gr-analog/include/analog/noise_type.h @@ -0,0 +1,36 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ANALOG_NOISE_TYPE_H +#define INCLUDED_ANALOG_NOISE_TYPE_H + +namespace gr { + namespace analog { + + typedef enum { + GR_UNIFORM = 200, GR_GAUSSIAN, GR_LAPLACIAN, GR_IMPULSE + } noise_type_t; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_NOISE_TYPE_H */ diff --git a/gr-analog/include/analog/phase_modulator_fc.h b/gr-analog/include/analog/phase_modulator_fc.h new file mode 100644 index 000000000..409de7804 --- /dev/null +++ b/gr-analog/include/analog/phase_modulator_fc.h @@ -0,0 +1,63 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2006,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ANALOG_PHASE_MODULATOR_FC_H +#define INCLUDED_ANALOG_PHASE_MODULATOR_FC_H + +#include <analog/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace analog { + + /*! + * \brief Phase modulator block + * \ingroup modulation_blk + * + * output = complex(cos(in*sensitivity), sin(in*sensitivity)) + * + * Input stream 0: floats + * Ouput stream 0: complex + */ + class ANALOG_API phase_modulator_fc : virtual public gr_sync_block + { + public: + // gr::analog::phase_modulator_fc::sptr + typedef boost::shared_ptr<phase_modulator_fc> sptr; + + /* \brief Make a phase modulator block. + * + * \param sensitivity Phase change sensitivity of input amplitude. + */ + static sptr make(double sensitivity); + + virtual double sensitivity() const = 0; + virtual double phase() const = 0; + + virtual void set_sensitivity(double s) = 0; + virtual void set_phase(double p) = 0; + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_PHASE_MODULATOR_FC_H */ diff --git a/gr-analog/include/analog/pll_carriertracking_cc.h b/gr-analog/include/analog/pll_carriertracking_cc.h new file mode 100644 index 000000000..3596429d4 --- /dev/null +++ b/gr-analog/include/analog/pll_carriertracking_cc.h @@ -0,0 +1,88 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2006,2011,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ANALOG_PLL_CARRIERTRACKING_CC_H +#define INCLUDED_ANALOG_PLL_CARRIERTRACKING_CC_H + +#include <analog/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace analog { + + /*! + * \brief Implements a PLL which locks to the input frequency and outputs the + * input signal mixed with that carrier. + * \ingroup sync_blk + * + * Input stream 0: complex + * Output stream 0: complex + * + * This PLL locks onto a [possibly noisy] reference carrier on the + * input and outputs that signal, downconverted to DC + * + * All settings max_freq and min_freq are in terms of radians per + * sample, NOT HERTZ. The loop bandwidth determins the lock range + * and should be set around pi/200 -- 2pi/100. \sa + * pll_freqdet_cf, pll_carriertracking_cc + */ + class ANALOG_API pll_carriertracking_cc : virtual public gr_sync_block + { + public: + // gr::analog::pll_carriertracking_cc::sptr + typedef boost::shared_ptr<pll_carriertracking_cc> sptr; + + /* \brief Make a carrier tracking PLL block. + * + * \param loop_bw: control loop's bandwidth parameter. + * \param max_freq: maximum (normalized) frequency PLL will lock to. + * \param min_freq: minimum (normalized) frequency PLL will lock to. + */ + static sptr make(float loop_bw, float max_freq, float min_freq); + + virtual bool lock_detector(void) = 0; + virtual bool squelch_enable(bool) = 0; + virtual float set_lock_threshold(float) = 0; + + virtual void set_loop_bandwidth(float bw) = 0; + virtual void set_damping_factor(float df) = 0; + virtual void set_alpha(float alpha) = 0; + virtual void set_beta(float beta) = 0; + virtual void set_frequency(float freq) = 0; + virtual void set_phase(float phase) = 0; + virtual void set_min_freq(float freq) = 0; + virtual void set_max_freq(float freq) = 0; + + virtual float get_loop_bandwidth() const = 0; + virtual float get_damping_factor() const = 0; + virtual float get_alpha() const = 0; + virtual float get_beta() const = 0; + virtual float get_frequency() const = 0; + virtual float get_phase() const = 0; + virtual float get_min_freq() const = 0; + virtual float get_max_freq() const = 0; + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_PLL_CARRIERTRACKING_CC_H */ diff --git a/gr-analog/include/analog/pll_freqdet_cf.h b/gr-analog/include/analog/pll_freqdet_cf.h new file mode 100644 index 000000000..613e85263 --- /dev/null +++ b/gr-analog/include/analog/pll_freqdet_cf.h @@ -0,0 +1,83 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2011 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ANALOG_PLL_FREQDET_CF_H +#define INCLUDED_ANALOG_PLL_FREQDET_CF_H + +#include <analog/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace analog { + + /*! + * \brief Implements a PLL which locks to the input frequency and outputs + * an estimate of that frequency. Useful for FM Demod. + * \ingroup sync_blk + * + * Input stream 0: complex + * Output stream 0: float + * + * This PLL locks onto a [possibly noisy] reference carrier on + * the input and outputs an estimate of that frequency in radians per sample. + * All settings max_freq and min_freq are in terms of radians per sample, + * NOT HERTZ. The loop bandwidth determins the lock range and should be set + * around pi/200 -- 2pi/100. + * \sa pll_refout_cc, pll_carriertracking_cc + */ + class ANALOG_API pll_freqdet_cf : virtual public gr_sync_block + { + public: + // gr::analog::pll_freqdet_cf::sptr + typedef boost::shared_ptr<pll_freqdet_cf> sptr; + + /* \brief Make PLL block that outputs the tracked signal's frequency. + * + * \param loop_bw: control loop's bandwidth parameter. + * \param max_freq: maximum (normalized) frequency PLL will lock to. + * \param min_freq: minimum (normalized) frequency PLL will lock to. + */ + static sptr make(float loop_bw, float max_freq, float min_freq); + + virtual void set_loop_bandwidth(float bw) = 0; + virtual void set_damping_factor(float df) = 0; + virtual void set_alpha(float alpha) = 0; + virtual void set_beta(float beta) = 0; + virtual void set_frequency(float freq) = 0; + virtual void set_phase(float phase) = 0; + virtual void set_min_freq(float freq) = 0; + virtual void set_max_freq(float freq) = 0; + + virtual float get_loop_bandwidth() const = 0; + virtual float get_damping_factor() const = 0; + virtual float get_alpha() const = 0; + virtual float get_beta() const = 0; + virtual float get_frequency() const = 0; + virtual float get_phase() const = 0; + virtual float get_min_freq() const = 0; + virtual float get_max_freq() const = 0; + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_PLL_FREQDET_CF_H */ diff --git a/gr-analog/include/analog/pll_refout_cc.h b/gr-analog/include/analog/pll_refout_cc.h new file mode 100644 index 000000000..a18d177e6 --- /dev/null +++ b/gr-analog/include/analog/pll_refout_cc.h @@ -0,0 +1,66 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2011,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ANALOG_PLL_REFOUT_CC_H +#define INCLUDED_ANALOG_PLL_REFOUT_CC_H + +#include <analog/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace analog { + + /*! + * \brief Implements a PLL which locks to the input frequency and outputs a carrier + * \ingroup sync_blk + * + * Input stream 0: complex + * Output stream 0: complex + * + * This PLL locks onto a [possibly noisy] reference carrier on the + * input and outputs a clean version which is phase and frequency + * aligned to it. + * + * All settings max_freq and min_freq are in terms of radians per + * sample, NOT HERTZ. The loop bandwidth determins the lock range + * and should be set around pi/200 -- 2pi/100. \sa + * pll_freqdet_cf, pll_carriertracking_cc + */ + class ANALOG_API pll_refout_cc : virtual public gr_sync_block + { + public: + // gr::analog::pll_refout_cc::sptr + typedef boost::shared_ptr<pll_refout_cc> sptr; + + /* \brief Make PLL block that outputs the tracked carrier signal. + * + * \param loop_bw: control loop's bandwidth parameter. + * \param max_freq: maximum (normalized) frequency PLL will lock to. + * \param min_freq: minimum (normalized) frequency PLL will lock to. + */ + static sptr make(float loop_bw, float max_freq, float min_freq); + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_PLL_REFOUT_CC_H */ diff --git a/gr-analog/include/analog/probe_avg_mag_sqrd_c.h b/gr-analog/include/analog/probe_avg_mag_sqrd_c.h new file mode 100644 index 000000000..9e62732a3 --- /dev/null +++ b/gr-analog/include/analog/probe_avg_mag_sqrd_c.h @@ -0,0 +1,67 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2006,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ +#ifndef INCLUDED_ANALOG_PROBE_AVG_MAG_SQRD_C_H +#define INCLUDED_ANALOG_PROBE_AVG_MAG_SQRD_C_H + +#include <analog/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace analog { + + /*! + * \brief compute avg magnitude squared. + * \ingroup sink_blk + * + * Input stream 0: complex + * + * Compute a running average of the magnitude squared of the the + * input. The level and indication as to whether the level exceeds + * threshold can be retrieved with the level and unmuted + * accessors. + */ + class ANALOG_API probe_avg_mag_sqrd_c : virtual public gr_sync_block + { + public: + // gr::analog::probe_avg_mag_sqrd_c::sptr + typedef boost::shared_ptr<probe_avg_mag_sqrd_c> sptr; + + /*! + * \brief Make a complex sink that computes avg magnitude squared. + * + * \param threshold_db Threshold for muting. + * \param alpha Gain parameter for the running average filter. + */ + static sptr make(double threshold_db, double alpha = 0.0001); + + virtual bool unmuted() const = 0; + virtual double level() const = 0; + virtual double threshold() const = 0; + + virtual void set_alpha(double alpha) = 0; + virtual void set_threshold(double decibels) = 0; + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_PROBE_AVG_MAG_SQRD_C_H */ diff --git a/gr-analog/include/analog/probe_avg_mag_sqrd_cf.h b/gr-analog/include/analog/probe_avg_mag_sqrd_cf.h new file mode 100644 index 000000000..b18916ae9 --- /dev/null +++ b/gr-analog/include/analog/probe_avg_mag_sqrd_cf.h @@ -0,0 +1,69 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2006,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ANALOG_PROBE_AVG_MAG_SQRD_CF_H +#define INCLUDED_ANALOG_PROBE_AVG_MAG_SQRD_CF_H + +#include <analog/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace analog { + + /*! + * \brief compute avg magnitude squared. + * \ingroup sink_blk + * + * Input stream 0: complex + * Output stream 0: float + * + * Compute a running average of the magnitude squared of the the + * input. The level and indication as to whether the level exceeds + * threshold can be retrieved with the level and unmuted + * accessors. + */ + class ANALOG_API probe_avg_mag_sqrd_cf : virtual public gr_sync_block + { + public: + // gr::analog::probe_avg_mag_sqrd_cf::sptr + typedef boost::shared_ptr<probe_avg_mag_sqrd_cf> sptr; + + /*! + * \brief Make a block that computes avg magnitude squared. + * + * \param threshold_db Threshold for muting. + * \param alpha Gain parameter for the running average filter. + */ + static sptr make(double threshold_db, double alpha = 0.0001); + + virtual bool unmuted() const = 0; + virtual double level() const = 0; + virtual double threshold() const = 0; + + virtual void set_alpha(double alpha) = 0; + virtual void set_threshold(double decibels) = 0; + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_PROBE_AVG_MAG_SQRD_CF_H */ diff --git a/gr-analog/include/analog/probe_avg_mag_sqrd_f.h b/gr-analog/include/analog/probe_avg_mag_sqrd_f.h new file mode 100644 index 000000000..fe9d27793 --- /dev/null +++ b/gr-analog/include/analog/probe_avg_mag_sqrd_f.h @@ -0,0 +1,69 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ANALOG_PROBE_AVG_MAG_SQRD_F_H +#define INCLUDED_ANALOG_PROBE_AVG_MAG_SQRD_F_H + +#include <analog/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace analog { + + /*! + * \brief compute avg magnitude squared. + * \ingroup sink_blk + * + * input stream 0: float + * + * Compute a running average of the magnitude squared of the the + * input. The level and indication as to whether the level exceeds + * threshold can be retrieved with the level and unmuted + * accessors. + */ + class ANALOG_API probe_avg_mag_sqrd_f : virtual public gr_sync_block + { + public: + // gr::analog::probe_avg_mag_sqrd_f::sptr + typedef boost::shared_ptr<probe_avg_mag_sqrd_f> sptr; + + /*! + * \brief Make a float sink that computes avg magnitude squared. + * + * \param threshold_db Threshold for muting. + * \param alpha Gain parameter for the running average filter. + */ + static sptr make(double threshold_db, double alpha = 0.0001); + + virtual bool unmuted() const = 0; + virtual double level() const = 0; + + virtual double threshold() const = 0; + + virtual void set_alpha (double alpha) = 0; + virtual void set_threshold (double decibels) = 0; + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_PROBE_AVG_MAG_SQRD_F_H */ diff --git a/gr-analog/include/analog/pwr_squelch_cc.h b/gr-analog/include/analog/pwr_squelch_cc.h new file mode 100644 index 000000000..79364a86b --- /dev/null +++ b/gr-analog/include/analog/pwr_squelch_cc.h @@ -0,0 +1,75 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ANALOG_PWR_SQUELCH_CC_H +#define INCLUDED_ANALOG_PWR_SQUELCH_CC_H + +#include <analog/api.h> +#include <analog/squelch_base_cc.h> +#include <cmath> + +namespace gr { + namespace analog { + + /*! + * \brief gate or zero output when input power below threshold + * \ingroup level_blk + */ + class ANALOG_API pwr_squelch_cc : + public squelch_base_cc, virtual public gr_block + { + protected: + virtual void update_state(const gr_complex &in) = 0; + virtual bool mute() const = 0; + + public: + // gr::analog::pwr_squelch_cc::sptr + typedef boost::shared_ptr<pwr_squelch_cc> sptr; + + /*! + * \brief Make power-based squelch block. + * + * \param db threshold (in dB) for power squelch + * \param alpha Gain of averaging filter + * \param ramp + * \param gate + */ + static sptr make(double db, double alpha=0.0001, + int ramp=0, bool gate=false); + + virtual std::vector<float> squelch_range() const = 0; + + virtual double threshold() const = 0; + virtual void set_threshold(double db) = 0; + virtual void set_alpha(double alpha) = 0; + + virtual int ramp() const = 0; + virtual void set_ramp(int ramp) = 0; + virtual bool gate() const = 0; + virtual void set_gate(bool gate) = 0; + virtual bool unmuted() const = 0; + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_PWR_SQUELCH_CC_H */ diff --git a/gr-analog/include/analog/pwr_squelch_ff.h b/gr-analog/include/analog/pwr_squelch_ff.h new file mode 100644 index 000000000..6fdebec74 --- /dev/null +++ b/gr-analog/include/analog/pwr_squelch_ff.h @@ -0,0 +1,75 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ANALOG_PWR_SQUELCH_FF_H +#define INCLUDED_ANALOG_PWR_SQUELCH_FF_H + +#include <analog/api.h> +#include <analog/squelch_base_ff.h> +#include <cmath> + +namespace gr { + namespace analog { + + /*! + * \brief gate or zero output when input power below threshold + * \ingroup level_blk + */ + class ANALOG_API pwr_squelch_ff : + public squelch_base_ff, virtual public gr_block + { + protected: + virtual void update_state(const float &in) = 0; + virtual bool mute() const = 0; + + public: + // gr::analog::pwr_squelch_ff::sptr + typedef boost::shared_ptr<pwr_squelch_ff> sptr; + + /*! + * \brief Make power-based squelch block. + * + * \param db threshold (in dB) for power squelch + * \param alpha Gain of averaging filter + * \param ramp + * \param gate + */ + static sptr make(double db, double alpha=0.0001, + int ramp=0, bool gate=false); + + virtual std::vector<float> squelch_range() const = 0; + + virtual double threshold() const = 0; + virtual void set_threshold(double db) = 0; + virtual void set_alpha(double alpha) = 0; + + virtual int ramp() const = 0; + virtual void set_ramp(int ramp) = 0; + virtual bool gate() const = 0; + virtual void set_gate(bool gate) = 0; + virtual bool unmuted() const = 0; + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_PWR_SQUELCH_FF_H */ diff --git a/gr-analog/include/analog/quadrature_demod_cf.h b/gr-analog/include/analog/quadrature_demod_cf.h new file mode 100644 index 000000000..916d8b2ec --- /dev/null +++ b/gr-analog/include/analog/quadrature_demod_cf.h @@ -0,0 +1,54 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ANALOG_QUADRATURE_DEMOD_CF_H +#define INCLUDED_ANALOG_QUADRATURE_DEMOD_CF_H + +#include <analog/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace analog { + + /*! + * \brief quadrature demodulator: complex in, float out + * \ingroup demodulation_blk + * + * This can be used to demod FM, FSK, GMSK, etc. + * The input is complex baseband. + */ + class ANALOG_API quadrature_demod_cf : virtual public gr_sync_block + { + public: + // gr::analog::quadrature_demod_cf::sptr + typedef boost::shared_ptr<quadrature_demod_cf> sptr; + + static sptr make(float gain); + + virtual void set_gain(float gain) = 0; + virtual float gain() const = 0; + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_QUADRATURE_DEMOD_CF_H */ diff --git a/gr-analog/include/analog/rail_ff.h b/gr-analog/include/analog/rail_ff.h new file mode 100644 index 000000000..e51b2fc93 --- /dev/null +++ b/gr-analog/include/analog/rail_ff.h @@ -0,0 +1,54 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ANALOG_RAIL_FF_H +#define INCLUDED_ANALOG_RAIL_FF_H + +#include <analog/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace analog { + + /*! + * \brief clips input values to min, max + * \ingroup misc + */ + class ANALOG_API rail_ff : virtual public gr_sync_block + { + public: + // gr::analog::rail_ff::sptr + typedef boost::shared_ptr<rail_ff> sptr; + + static sptr make(float lo, float hi); + + virtual float lo() const = 0; + virtual float hi() const = 0; + + virtual void set_lo(float lo) = 0; + virtual void set_hi(float hi) = 0; + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_RAIL_FF_H */ diff --git a/gr-analog/include/analog/rotator.h b/gr-analog/include/analog/rotator.h new file mode 100644 index 000000000..ee3849eae --- /dev/null +++ b/gr-analog/include/analog/rotator.h @@ -0,0 +1,63 @@ +/* -*- c++ -*- */ +/* + * Copyright 2003,2008,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef _ANALOG_ROTATOR_H_ +#define _ANALOG_ROTATOR_H_ + +#include <analog/api.h> +#include <gr_complex.h> + +namespace gr { + namespace analog { + + class rotator + { + private: + gr_complex d_phase; + gr_complex d_phase_incr; + unsigned int d_counter; + + public: + rotator() : d_phase (1), d_phase_incr (1), d_counter(0) + { } + + void set_phase(gr_complex phase) { d_phase = phase / abs(phase); } + void set_phase_incr(gr_complex incr) { d_phase_incr = incr / abs(incr); } + + gr_complex rotate (gr_complex in) + { + d_counter++; + + gr_complex z = in * d_phase; // rotate in by phase + d_phase *= d_phase_incr; // incr our phase (complex mult == add phases) + + if((d_counter % 512) == 0) + d_phase /= abs(d_phase); // Normalize to ensure multiplication is rotation + + return z; + } + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* _ANALOG_ROTATOR_H_ */ diff --git a/gr-analog/include/analog/sig_source_X.h.t b/gr-analog/include/analog/sig_source_X.h.t new file mode 100644 index 000000000..2915c2abe --- /dev/null +++ b/gr-analog/include/analog/sig_source_X.h.t @@ -0,0 +1,75 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +/* @WARNING@ */ + +#ifndef @GUARD_NAME@ +#define @GUARD_NAME@ + +#include <analog/api.h> +#include <analog/sig_source_waveform.h> +#include <gr_sync_block.h> + +namespace gr { + namespace analog { + + /*! + * \brief signal generator with @TYPE@ output. + * \ingroup source_blk + */ + class ANALOG_API @BASE_NAME@ : virtual public gr_sync_block + { + public: + // gr::analog::@BASE_NAME@::sptr + typedef boost::shared_ptr<@BASE_NAME@> sptr; + + /*! + * \brief Make a signal source block. + * + * \param sampling_freq Sampling rate of signal. + * \param waveform wavetform type. + * \param wave_freq Frequency of waveform (relative to sampling_freq). + * \param ampl Signal amplitude. + * \param offset offset of signal. + */ + static sptr make(double sampling_freq, + gr::analog::gr_waveform_t waveform, + double wave_freq, + double ampl, @TYPE@ offset = 0); + + virtual double sampling_freq() const = 0; + virtual gr::analog::gr_waveform_t waveform() const = 0; + virtual double frequency() const = 0; + virtual double amplitude() const = 0; + virtual @TYPE@ offset() const = 0; + + virtual void set_sampling_freq(double sampling_freq) = 0; + virtual void set_waveform(gr::analog::gr_waveform_t waveform) = 0; + virtual void set_frequency(double frequency) = 0; + virtual void set_amplitude(double ampl) = 0; + virtual void set_offset(@TYPE@ offset) = 0; + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* @GUARD_NAME@ */ diff --git a/gr-analog/include/analog/sig_source_waveform.h b/gr-analog/include/analog/sig_source_waveform.h new file mode 100644 index 000000000..3a9edb8f3 --- /dev/null +++ b/gr-analog/include/analog/sig_source_waveform.h @@ -0,0 +1,41 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ANALOG_SIG_SOURCE_WAVEFORM_H +#define INCLUDED_ANALOG_SIG_SOURCE_WAVEFORM_H + +namespace gr { + namespace analog { + + typedef enum { + GR_CONST_WAVE = 100, + GR_SIN_WAVE, + GR_COS_WAVE, + GR_SQR_WAVE, + GR_TRI_WAVE, + GR_SAW_WAVE + } gr_waveform_t; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_SIG_SOURCE_WAVEFORM_H */ diff --git a/gr-analog/include/analog/simple_squelch_cc.h b/gr-analog/include/analog/simple_squelch_cc.h new file mode 100644 index 000000000..1e12646e4 --- /dev/null +++ b/gr-analog/include/analog/simple_squelch_cc.h @@ -0,0 +1,62 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ANALOG_SIMPLE_SQUELCH_CC_H +#define INCLUDED_ANALOG_SIMPLE_SQUELCH_CC_H + +#include <analog/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace analog { + + /*! + * \brief simple squelch block based on average signal power and threshold in dB. + * \ingroup level_blk + */ + class ANALOG_API simple_squelch_cc : virtual public gr_sync_block + { + public: + // gr::analog::simple_squelch_cc::sptr + typedef boost::shared_ptr<simple_squelch_cc> sptr; + + /*! + * \brief Make a simple squelch block. + * + * \param threshold_db Threshold for muting. + * \param alpha Gain parameter for the running average filter. + */ + static sptr make(double threshold_db, double alpha); + + virtual bool unmuted() const = 0; + + virtual void set_alpha(double alpha) = 0; + virtual void set_threshold(double decibels) = 0; + + virtual double threshold() const = 0; + virtual std::vector<float> squelch_range() const = 0; + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_SIMPLE_SQUELCH_CC_H */ diff --git a/gr-analog/include/analog/sincos.h b/gr-analog/include/analog/sincos.h new file mode 100644 index 000000000..38b9d96da --- /dev/null +++ b/gr-analog/include/analog/sincos.h @@ -0,0 +1,38 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002,2004,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ANALOG_SINCOS_H +#define INCLUDED_ANALOG_SINCOS_H + +#include <analog/api.h> + +namespace gr { + namespace analog { + + // compute sine and cosine at the same time + ANALOG_API void sincos(double x, double *sin, double *cos); + ANALOG_API void sincosf(float x, float *sin, float *cos); + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_SINCOS_H */ diff --git a/gr-analog/include/analog/squelch_base_cc.h b/gr-analog/include/analog/squelch_base_cc.h new file mode 100644 index 000000000..11476e7e8 --- /dev/null +++ b/gr-analog/include/analog/squelch_base_cc.h @@ -0,0 +1,56 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ANALOG_SQUELCH_BASE_CC_H +#define INCLUDED_ANALOG_SQUELCH_BASE_CC_H + +#include <analog/api.h> +#include <gr_block.h> + +namespace gr { + namespace analog { + + /*! + * \brief basic squelch block; to be subclassed for other squelches. + * \ingroup level_blk + */ + class ANALOG_API squelch_base_cc : virtual public gr_block + { + protected: + virtual void update_state(const gr_complex &sample) = 0; + virtual bool mute() const = 0; + + public: + squelch_base_cc() {}; + virtual int ramp() const = 0; + virtual void set_ramp(int ramp) = 0; + virtual bool gate() const = 0; + virtual void set_gate(bool gate) = 0; + virtual bool unmuted() const = 0; + + virtual std::vector<float> squelch_range() const = 0; + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_SQUELCH_BASE_CC_H */ diff --git a/gr-analog/include/analog/squelch_base_ff.h b/gr-analog/include/analog/squelch_base_ff.h new file mode 100644 index 000000000..2ce1f1a65 --- /dev/null +++ b/gr-analog/include/analog/squelch_base_ff.h @@ -0,0 +1,56 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ANALOG_SQUELCH_BASE_FF_H +#define INCLUDED_ANALOG_SQUELCH_BASE_FF_H + +#include <analog/api.h> +#include <gr_block.h> + +namespace gr { + namespace analog { + + /*! + * \brief basic squelch block; to be subclassed for other squelches. + * \ingroup level_blk + */ + class ANALOG_API squelch_base_ff : virtual public gr_block + { + protected: + virtual void update_state(const float &sample) = 0; + virtual bool mute() const = 0; + + public: + squelch_base_ff() {}; + virtual int ramp() const = 0; + virtual void set_ramp(int ramp) = 0; + virtual bool gate() const = 0; + virtual void set_gate(bool gate) = 0; + virtual bool unmuted() const = 0; + + virtual std::vector<float> squelch_range() const = 0; + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_SQUELCH_BASE_FF_H */ diff --git a/gr-analog/lib/CMakeLists.txt b/gr-analog/lib/CMakeLists.txt new file mode 100644 index 000000000..653d5be27 --- /dev/null +++ b/gr-analog/lib/CMakeLists.txt @@ -0,0 +1,187 @@ +# Copyright 2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. + +######################################################################## +# Setup the include and linker paths +######################################################################## +include_directories( + ${VOLK_INCLUDE_DIRS} + ${GNURADIO_CORE_INCLUDE_DIRS} + ${GR_ANALOG_INCLUDE_DIRS} + ${GR_FFT_INCLUDE_DIRS} + ${GR_FILTER_INCLUDE_DIRS} + ${CMAKE_CURRENT_BINARY_DIR}/../include + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} +) + +include_directories(${Boost_INCLUDE_DIRS}) +link_directories(${Boost_LIBRARY_DIRS}) + +######################################################################## +# generate helper scripts to expand templated files +######################################################################## +include(GrPython) + +file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py " +#!${PYTHON_EXECUTABLE} + +import sys, os, re +sys.path.append('${GR_CORE_PYTHONPATH}') +os.environ['srcdir'] = '${CMAKE_CURRENT_SOURCE_DIR}' +os.chdir('${CMAKE_CURRENT_BINARY_DIR}') + +if __name__ == '__main__': + import build_utils + root, inp = sys.argv[1:3] + for sig in sys.argv[3:]: + name = re.sub ('X+', sig, root) + d = build_utils.standard_impl_dict2(name, sig, 'analog') + build_utils.expand_template(d, inp) +") + +macro(expand_cc root) + #make a list of all the generated files + unset(expanded_files_cc) + unset(expanded_files_h) + foreach(sig ${ARGN}) + string(REGEX REPLACE "X+" ${sig} name ${root}) + list(APPEND expanded_files_cc ${CMAKE_CURRENT_BINARY_DIR}/${name}.cc) + list(APPEND expanded_files_h ${CMAKE_CURRENT_BINARY_DIR}/${name}.h) + endforeach(sig) + + #create a command to generate the source files + add_custom_command( + OUTPUT ${expanded_files_cc} + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}.cc.t + COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B} + ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py + ${root} ${root}.cc.t ${ARGN} + ) + + #create a command to generate the header file + add_custom_command( + OUTPUT ${expanded_files_h} + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}.h.t + COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B} + ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py + ${root} ${root}.h.t ${ARGN} + ) + + #make source files depends on headers to force generation + set_source_files_properties(${expanded_files_cc} + PROPERTIES OBJECT_DEPENDS "${expanded_files_h}" + ) + + #install rules for the generated cc files + list(APPEND generated_sources ${expanded_files_cc}) + list(APPEND generated_headers ${expanded_files_h}) +endmacro(expand_cc) + + +######################################################################## +# Invoke macro to generate various sources +######################################################################## +expand_cc(noise_source_X_impl s i f c) +expand_cc(sig_source_X_impl s i f c) + +######################################################################## +# Setup library +######################################################################## +list(APPEND analog_sources + ${generated_sources} + cpm.cc + squelch_base_cc_impl.cc + squelch_base_ff_impl.cc + agc_cc_impl.cc + agc_ff_impl.cc + agc2_cc_impl.cc + agc2_ff_impl.cc + cpfsk_bc_impl.cc + ctcss_squelch_ff_impl.cc + dpll_bb_impl.cc + feedforward_agc_cc_impl.cc + fmdet_cf_impl.cc + frequency_modulator_fc_impl.cc + phase_modulator_fc_impl.cc + pll_carriertracking_cc_impl.cc + pll_freqdet_cf_impl.cc + pll_refout_cc_impl.cc + probe_avg_mag_sqrd_c_impl.cc + probe_avg_mag_sqrd_cf_impl.cc + probe_avg_mag_sqrd_f_impl.cc + pwr_squelch_cc_impl.cc + pwr_squelch_ff_impl.cc + quadrature_demod_cf_impl.cc + rail_ff_impl.cc + simple_squelch_cc_impl.cc + sincos.cc +) + +list(APPEND analog_libs + volk + gnuradio-core + gnuradio-filter + ${Boost_LIBRARIES} +) + +add_library(gnuradio-analog SHARED ${analog_sources}) +target_link_libraries(gnuradio-analog ${analog_libs}) +GR_LIBRARY_FOO(gnuradio-analog RUNTIME_COMPONENT "analog_runtime" DEVEL_COMPONENT "analog_devel") +add_dependencies(gnuradio-analog analog_generated_includes analog_generated_swigs gnuradio-filter) + + +######################################################################## +# QA C++ Code for gr-filter +######################################################################## +if(ENABLE_TESTING) + include(GrTest) + + include_directories(${CPPUNIT_INCLUDE_DIRS}) + link_directories(${CPPUNIT_LIBRARY_DIRS}) + + list(APPEND test_gr_analog_sources + ${CMAKE_CURRENT_SOURCE_DIR}/test_gr_analog.cc + ${CMAKE_CURRENT_SOURCE_DIR}/qa_analog.cc + ${CMAKE_CURRENT_SOURCE_DIR}/qa_sincos.cc + ${CMAKE_CURRENT_SOURCE_DIR}/qa_rotator.cc + ) + + add_executable(test-gr-analog ${test_gr_analog_sources}) + + target_link_libraries( + test-gr-analog + gnuradio-core + gnuradio-analog + ${Boost_LIBRARIES} + ${CPPUNIT_LIBRARIES} + ) + + list(APPEND GR_TEST_TARGET_DEPS gnuradio-analog gnuradio-filter gnuradio-fft) + + GR_ADD_TEST(test_gr_analog test-gr-analog) +endif(ENABLE_TESTING) + +CHECK_CXX_SOURCE_COMPILES(" + #define _GNU_SOURCE + #include <math.h> + int main(){double x, sin, cos; sincos(x, &sin, &cos); return 0;} + " HAVE_SINCOS +) +GR_ADD_COND_DEF(HAVE_SINCOS) diff --git a/gr-analog/lib/agc2_cc_impl.cc b/gr-analog/lib/agc2_cc_impl.cc new file mode 100644 index 000000000..2ef18e5ab --- /dev/null +++ b/gr-analog/lib/agc2_cc_impl.cc @@ -0,0 +1,70 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2010,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "agc2_cc_impl.h" +#include <gr_io_signature.h> + +namespace gr { + namespace analog { + + agc2_cc::sptr + agc2_cc::make(float attack_rate, float decay_rate, + float reference, + float gain, float max_gain) + { + return gnuradio::get_initial_sptr + (new agc2_cc_impl(attack_rate, decay_rate, + reference, gain, max_gain)); + } + + agc2_cc_impl::agc2_cc_impl(float attack_rate, float decay_rate, + float reference, + float gain, float max_gain) + : gr_sync_block("agc2_cc", + gr_make_io_signature(1, 1, sizeof(gr_complex)), + gr_make_io_signature(1, 1, sizeof(gr_complex))), + kernel::agc2_cc(attack_rate, decay_rate, + reference, gain, max_gain) + { + } + + agc2_cc_impl::~agc2_cc_impl() + { + } + + int + agc2_cc_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const gr_complex *in = (const gr_complex*)input_items[0]; + gr_complex *out = (gr_complex*)output_items[0]; + scaleN(out, in, noutput_items); + return noutput_items; + } + + } /* namespace analog */ +} /* namespace gr */ diff --git a/gr-analog/lib/agc2_cc_impl.h b/gr-analog/lib/agc2_cc_impl.h new file mode 100644 index 000000000..98afc668a --- /dev/null +++ b/gr-analog/lib/agc2_cc_impl.h @@ -0,0 +1,59 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ANALOG_AGC2_IMPL_CC_H +#define INCLUDED_ANALOG_AGC2_IMPL_CC_H + +#include <analog/agc2_cc.h> + +namespace gr { + namespace analog { + + class agc2_cc_impl : public agc2_cc, kernel::agc2_cc + { + public: + agc2_cc_impl(float attack_rate = 1e-1, float decay_rate = 1e-2, + float reference = 1.0, + float gain = 1.0, float max_gain = 0.0); + ~agc2_cc_impl(); + + float attack_rate() const { return kernel::agc2_cc::attack_rate(); } + float decay_rate() const { return kernel::agc2_cc::decay_rate(); } + float reference() const { return kernel::agc2_cc::reference(); } + float gain() const { return kernel::agc2_cc::gain(); } + float max_gain() const { return kernel::agc2_cc::max_gain(); } + + void set_attack_rate(float rate) { kernel::agc2_cc::set_attack_rate(rate); } + void set_decay_rate(float rate) { kernel::agc2_cc::set_decay_rate(rate); } + void set_reference(float reference) { kernel::agc2_cc::set_reference(reference); } + void set_gain(float gain) { kernel::agc2_cc::set_gain(gain); } + void set_max_gain(float max_gain) { kernel::agc2_cc::set_max_gain(max_gain); } + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_AGC2_CC_IMPL_H */ diff --git a/gr-analog/lib/agc2_ff_impl.cc b/gr-analog/lib/agc2_ff_impl.cc new file mode 100644 index 000000000..e0cdd6c44 --- /dev/null +++ b/gr-analog/lib/agc2_ff_impl.cc @@ -0,0 +1,71 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2006,2010,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "agc2_ff_impl.h" +#include <gr_io_signature.h> + +namespace gr { + namespace analog { + + agc2_ff::sptr + agc2_ff::make(float attack_rate, float decay_rate, + float reference, + float gain, float max_gain) + { + return gnuradio::get_initial_sptr + (new agc2_ff_impl(attack_rate, decay_rate, + reference, + gain, max_gain)); + } + + agc2_ff_impl::~agc2_ff_impl() + { + } + + agc2_ff_impl::agc2_ff_impl(float attack_rate, float decay_rate, + float reference, + float gain, float max_gain) + : gr_sync_block("agc2_ff", + gr_make_io_signature(1, 1, sizeof(float)), + gr_make_io_signature(1, 1, sizeof(float))) + , kernel::agc2_ff(attack_rate, decay_rate, + reference, gain, max_gain) + { + } + + int + agc2_ff_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const float *in = (const float*)input_items[0]; + float *out = (float*)output_items[0]; + scaleN(out, in, noutput_items); + return noutput_items; + } + + } /* namespace analog */ +} /* namespace gr */ diff --git a/gr-analog/lib/agc2_ff_impl.h b/gr-analog/lib/agc2_ff_impl.h new file mode 100644 index 000000000..df33c8e44 --- /dev/null +++ b/gr-analog/lib/agc2_ff_impl.h @@ -0,0 +1,59 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2006,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ANALOG_AGC2_FF_IMPL_H +#define INCLUDED_ANALOG_AGC2_FF_IMPL_H + +#include <analog/agc2_ff.h> + +namespace gr { + namespace analog { + + class agc2_ff_impl : public agc2_ff, kernel::agc2_ff + { + public: + agc2_ff_impl(float attack_rate = 1e-1, float decay_rate = 1e-2, + float reference = 1.0, + float gain = 1.0, float max_gain = 0.0); + ~agc2_ff_impl(); + + float attack_rate() const { return kernel::agc2_ff::attack_rate(); } + float decay_rate() const { return kernel::agc2_ff::decay_rate(); } + float reference() const { return kernel::agc2_ff::reference(); } + float gain() const { return kernel::agc2_ff::gain(); } + float max_gain() const { return kernel::agc2_ff::max_gain(); } + + void set_attack_rate(float rate) { kernel::agc2_ff::set_attack_rate(rate); } + void set_decay_rate(float rate) { kernel::agc2_ff::set_decay_rate(rate); } + void set_reference(float reference) { kernel::agc2_ff::set_reference(reference); } + void set_gain(float gain) { kernel::agc2_ff::set_gain(gain); } + void set_max_gain(float max_gain) { kernel::agc2_ff::set_max_gain(max_gain); } + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_AGC2_IMPL_FF_H */ diff --git a/gr-analog/lib/agc_cc_impl.cc b/gr-analog/lib/agc_cc_impl.cc new file mode 100644 index 000000000..81e1f67f8 --- /dev/null +++ b/gr-analog/lib/agc_cc_impl.cc @@ -0,0 +1,66 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2010,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "agc_cc_impl.h" +#include <gr_io_signature.h> + +namespace gr { + namespace analog { + + agc_cc::sptr + agc_cc::make(float rate, float reference, + float gain, float max_gain) + { + return gnuradio::get_initial_sptr + (new agc_cc_impl(rate, reference, gain, max_gain)); + } + + agc_cc_impl::agc_cc_impl(float rate, float reference, + float gain, float max_gain) + : gr_sync_block("agc_cc", + gr_make_io_signature(1, 1, sizeof(gr_complex)), + gr_make_io_signature(1, 1, sizeof(gr_complex))), + kernel::agc_cc(rate, reference, gain, max_gain) + { + } + + agc_cc_impl::~agc_cc_impl() + { + } + + int + agc_cc_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const gr_complex *in = (const gr_complex*)input_items[0]; + gr_complex *out = (gr_complex*)output_items[0]; + scaleN(out, in, noutput_items); + return noutput_items; + } + + } /* namespace analog */ +} /* namespace gr */ diff --git a/gr-analog/lib/agc_cc_impl.h b/gr-analog/lib/agc_cc_impl.h new file mode 100644 index 000000000..822f46ef2 --- /dev/null +++ b/gr-analog/lib/agc_cc_impl.h @@ -0,0 +1,56 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ANALOG_AGC_CC_IMPL_H +#define INCLUDED_ANALOG_AGC_CC_IMPL_H + +#include <analog/agc_cc.h> + +namespace gr { + namespace analog { + + class agc_cc_impl : public agc_cc, kernel::agc_cc + { + public: + agc_cc_impl(float rate = 1e-4, float reference = 1.0, + float gain = 1.0, float max_gain = 0.0); + ~agc_cc_impl(); + + float rate() const { return kernel::agc_cc::rate(); } + float reference() const { return kernel::agc_cc::reference(); } + float gain() const { return kernel::agc_cc::gain(); } + float max_gain() const { return kernel::agc_cc::max_gain(); } + + void set_rate(float rate) { kernel::agc_cc::set_rate(rate); } + void set_reference(float reference) { kernel::agc_cc::set_reference(reference); } + void set_gain(float gain) { kernel::agc_cc::set_gain(gain); } + void set_max_gain(float max_gain) { kernel::agc_cc::set_max_gain(max_gain); } + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_AGC_CC_IMPL_H */ diff --git a/gr-analog/lib/agc_ff_impl.cc b/gr-analog/lib/agc_ff_impl.cc new file mode 100644 index 000000000..a80b90c12 --- /dev/null +++ b/gr-analog/lib/agc_ff_impl.cc @@ -0,0 +1,64 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2006,2010,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "agc_ff_impl.h" +#include <gr_io_signature.h> + +namespace gr { + namespace analog { + + agc_ff::sptr + agc_ff::make(float rate, float reference, float gain, float max_gain) + { + return gnuradio::get_initial_sptr + (new agc_ff_impl(rate, reference, gain, max_gain)); + } + + agc_ff_impl::agc_ff_impl(float rate, float reference, float gain, float max_gain) + : gr_sync_block("agc_ff", + gr_make_io_signature(1, 1, sizeof(float)), + gr_make_io_signature(1, 1, sizeof(float))), + kernel::agc_ff(rate, reference, gain, max_gain) + { + } + + agc_ff_impl::~agc_ff_impl() + { + } + + int + agc_ff_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const float *in = (const float*)input_items[0]; + float *out = (float*)output_items[0]; + scaleN(out, in, noutput_items); + return noutput_items; + } + + } /* namespace analog */ +} /* namespace gr */ diff --git a/gr-analog/lib/agc_ff_impl.h b/gr-analog/lib/agc_ff_impl.h new file mode 100644 index 000000000..e309cca1b --- /dev/null +++ b/gr-analog/lib/agc_ff_impl.h @@ -0,0 +1,56 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2006,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ANALOG_AGC_FF_IMPL_H +#define INCLUDED_ANALOG_AGC_FF_IMPL_H + +#include <analog/agc_ff.h> + +namespace gr { + namespace analog { + + class agc_ff_impl : public agc_ff, kernel::agc_ff + { + public: + agc_ff_impl(float rate = 1e-4, float reference = 1.0, + float gain = 1.0, float max_gain = 0.0); + ~agc_ff_impl(); + + float rate() const { return kernel::agc_ff::rate(); } + float reference() const { return kernel::agc_ff::reference(); } + float gain() const { return kernel::agc_ff::gain(); } + float max_gain() const { return kernel::agc_ff::max_gain(); } + + void set_rate(float rate) { kernel::agc_ff::set_rate(rate); } + void set_reference(float reference) { kernel::agc_ff::set_reference(reference); } + void set_gain(float gain) { kernel::agc_ff::set_gain(gain); } + void set_max_gain(float max_gain) { kernel::agc_ff::set_max_gain(max_gain); } + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_AGC_FF_IMPL_H */ diff --git a/gr-analog/lib/cpfsk_bc_impl.cc b/gr-analog/lib/cpfsk_bc_impl.cc new file mode 100644 index 000000000..1b7f25f6c --- /dev/null +++ b/gr-analog/lib/cpfsk_bc_impl.cc @@ -0,0 +1,86 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008,2010,2012 Free Software Foundation, Inc. + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "cpfsk_bc_impl.h" +#include <gr_io_signature.h> +#include <gr_expj.h> + +namespace gr { + namespace analog { + +#define M_TWOPI (2*M_PI) + + cpfsk_bc::sptr + cpfsk_bc::make(float k, float ampl, int samples_per_sym) + { + return gnuradio::get_initial_sptr + (new cpfsk_bc_impl(k, ampl, samples_per_sym)); + } + + cpfsk_bc_impl::cpfsk_bc_impl(float k, float ampl, int samples_per_sym) + : gr_sync_interpolator("cpfsk_bc", + gr_make_io_signature(1, 1, sizeof(char)), + gr_make_io_signature(1, 1, sizeof(gr_complex)), + samples_per_sym) + { + d_samples_per_sym = samples_per_sym; + d_freq = k*M_PI/samples_per_sym; + d_ampl = ampl; + d_phase = 0.0; + } + + cpfsk_bc_impl::~cpfsk_bc_impl() + { + } + + int + cpfsk_bc_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const char *in = (const char*)input_items[0]; + gr_complex *out = (gr_complex*)output_items[0]; + + for(int i = 0; i < noutput_items/d_samples_per_sym; i++) { + for(int j = 0; j < d_samples_per_sym; j++) { + if(in[i] == 1) + d_phase += d_freq; + else + d_phase -= d_freq; + + while(d_phase > M_TWOPI) + d_phase -= M_TWOPI; + while(d_phase < -M_TWOPI) + d_phase += M_TWOPI; + + *out++ = gr_expj(d_phase)*d_ampl; + } + } + + return noutput_items; + } + + } /* namespace analog */ +} /* namespace gr */ + diff --git a/gr-analog/lib/cpfsk_bc_impl.h b/gr-analog/lib/cpfsk_bc_impl.h new file mode 100644 index 000000000..9f6ec2c7f --- /dev/null +++ b/gr-analog/lib/cpfsk_bc_impl.h @@ -0,0 +1,54 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008,2012 Free Software Foundation, Inc. + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ANALOG_CPFSK_BC_IMPL_H +#define INCLUDED_ANALOG_CPFSK_BC_IMPL_H + +#include <analog/cpfsk_bc.h> + +namespace gr { + namespace analog { + + class cpfsk_bc_impl : public cpfsk_bc + { + private: + int d_samples_per_sym; // Samples per symbol, square pulse + float d_freq; // Modulation index*pi/samples_per_sym + float d_ampl; // Output amplitude + float d_phase; // Current phase + + public: + cpfsk_bc_impl(float k, float ampl, int samples_per_sym); + ~cpfsk_bc_impl(); + + void set_amplitude(float amplitude) { d_ampl = amplitude; } + float amplitude() { return d_ampl; } + float freq() { return d_freq; } + float phase() { return d_phase; } + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_CPFSK_BC_IMPL_H */ diff --git a/gr-analog/lib/cpm.cc b/gr-analog/lib/cpm.cc new file mode 100644 index 000000000..618475cec --- /dev/null +++ b/gr-analog/lib/cpm.cc @@ -0,0 +1,221 @@ +/* -*- c++ -*- */ +/* + * Copyright 2010,2012 Free Software Foundation, Inc. + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// Calculate the taps for the CPM phase responses + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <cmath> +#include <cfloat> +#include <analog/cpm.h> + +//gives us erf on compilers without it +#include <boost/math/special_functions/erf.hpp> +namespace bm = boost::math; + +namespace gr { + namespace analog { + +#ifndef M_TWOPI +# define M_TWOPI (2*M_PI) +#endif + + //! Normalised sinc function, sinc(x)=sin(pi*x)/pi*x + inline double + sinc(double x) + { + if(x == 0) { + return 1.0; + } + return sin(M_PI * x) / (M_PI * x); + } + + + //! Taps for L-RC CPM (Raised cosine of length L symbols) + std::vector<float> + generate_cpm_lrc_taps(unsigned samples_per_sym, unsigned L) + { + std::vector<float> taps(samples_per_sym * L, 1.0/L/samples_per_sym); + for(unsigned i = 0; i < samples_per_sym * L; i++) { + taps[i] *= 1 - cos(M_TWOPI * i / L / samples_per_sym); + } + + return taps; + } + + + /*! Taps for L-SRC CPM (Spectral raised cosine of length L symbols). + * + * L-SRC has a time-continuous phase response function of + * + * g(t) = 1/LT * sinc(2t/LT) * cos(beta * 2pi t / LT) / (1 - (4beta / LT * t)^2) + * + * which is the Fourier transform of a cos-rolloff function with rolloff + * beta, and looks like a sinc-function, multiplied with a rolloff term. + * We return the main lobe of the sinc, i.e., everything between the + * zero crossings. + * The time-discrete IR is thus + * + * g(k) = 1/Ls * sinc(2k/Ls) * cos(beta * pi k / Ls) / (1 - (4beta / Ls * k)^2) + * where k = 0...Ls-1 + * and s = samples per symbol. + */ + std::vector<float> + generate_cpm_lsrc_taps(unsigned samples_per_sym, unsigned L, double beta) + { + double Ls = (double) L * samples_per_sym; + std::vector<double> taps_d(L * samples_per_sym, 0.0); + std::vector<float> taps(L * samples_per_sym, 0.0); + + double sum = 0; + for(unsigned i = 0; i < samples_per_sym * L; i++) { + double k = i - Ls/2; // Causal to acausal + + taps_d[i] = 1.0 / Ls * sinc(2.0 * k / Ls); + + // For k = +/-Ls/4*beta, the rolloff term's cos-function becomes zero + // and the whole thing converges to PI/4 (to prove this, use de + // l'hopital's rule). + if(fabs(fabs(k) - Ls/4/beta) < 2*DBL_EPSILON) { + taps_d[i] *= M_PI_4; + } + else { + double tmp = 4.0 * beta * k / Ls; + taps_d[i] *= cos(beta * M_TWOPI * k / Ls) / (1 - tmp * tmp); + } + sum += taps_d[i]; + } + + for(unsigned i = 0; i < samples_per_sym * L; i++) { + taps[i] = (float) taps_d[i] / sum; + } + + return taps; + } + + //! Taps for L-REC CPM (Rectangular pulse shape of length L symbols) + std::vector<float> + generate_cpm_lrec_taps(unsigned samples_per_sym, unsigned L) + { + return std::vector<float>(samples_per_sym * L, 1.0/L/samples_per_sym); + } + + //! Helper function for TFM + double tfm_g0(double k, double sps) + { + if(fabs(k) < 2 * DBL_EPSILON) { + return 1.145393004159143; // 1 + pi^2/48 / sqrt(2) + } + + const double pi2_24 = 0.411233516712057; // pi^2/24 + double f = M_PI * k / sps; + return sinc(k/sps) - pi2_24 * (2 * sin(f) - 2*f*cos(f) - f*f*sin(f)) / (f*f*f); + } + + //! Taps for TFM CPM (Tamed frequency modulation) + // + // See [2, Chapter 2.7.2]. + // + // [2]: Anderson, Aulin and Sundberg; Digital Phase Modulation + std::vector<float> + generate_cpm_tfm_taps(unsigned sps, unsigned L) + { + unsigned causal_shift = sps * L / 2; + std::vector<double> taps_d(sps * L, 0.0); + std::vector<float> taps(sps * L, 0.0); + + double sum = 0; + for(unsigned i = 0; i < sps * L; i++) { + double k = (double)(((int)i) - ((int)causal_shift)); // Causal to acausal + + taps_d[i] = tfm_g0(k - sps, sps) + + 2 * tfm_g0(k, sps) + + tfm_g0(k + sps, sps); + sum += taps_d[i]; + } + + for(unsigned i = 0; i < sps * L; i++) { + taps[i] = (float) taps_d[i] / sum; + } + + return taps; + } + + //! Taps for Gaussian CPM. Phase response is truncated after \p L symbols. + // \p bt sets the 3dB-time-bandwidth product. + // + // Note: for h = 0.5, this is the phase response for GMSK. + // + // This C99-compatible formula for the taps is taken straight + // from [1, Chapter 9.2.3]. + // A version in Q-notation can be found in [2, Chapter 2.7.2]. + // + // [1]: Karl-Dirk Kammeyer; Nachrichtenübertragung, 4th Edition. + // [2]: Anderson, Aulin and Sundberg; Digital Phase Modulation + // + std::vector<float> + generate_cpm_gaussian_taps(unsigned samples_per_sym, unsigned L, double bt) + { + double Ls = (double) L * samples_per_sym; + std::vector<double> taps_d(L * samples_per_sym, 0.0); + std::vector<float> taps(L * samples_per_sym, 0.0); + + // alpha = sqrt(2/ln(2)) * pi * BT + double alpha = 5.336446256636997 * bt; + for(unsigned i = 0; i < samples_per_sym * L; i++) { + double k = i - Ls/2; // Causal to acausal + taps_d[i] = (bm::erf(alpha * (k / samples_per_sym + 0.5)) - + bm::erf(alpha * (k / samples_per_sym - 0.5))) + * 0.5 / samples_per_sym; + taps[i] = (float) taps_d[i]; + } + + return taps; + } + + std::vector<float> + cpm::phase_response(cpm_type type, unsigned samples_per_sym, unsigned L, double beta) + { + switch(type) { + case LRC: + return generate_cpm_lrc_taps(samples_per_sym, L); + + case LSRC: + return generate_cpm_lsrc_taps(samples_per_sym, L, beta); + + case LREC: + return generate_cpm_lrec_taps(samples_per_sym, L); + + case TFM: + return generate_cpm_tfm_taps(samples_per_sym, L); + + case GAUSSIAN: + return generate_cpm_gaussian_taps(samples_per_sym, L, beta); + + default: + return generate_cpm_lrec_taps(samples_per_sym, 1); + } + } + + } // namespace analog +} // namespace gr + diff --git a/gr-analog/lib/ctcss_squelch_ff_impl.cc b/gr-analog/lib/ctcss_squelch_ff_impl.cc new file mode 100644 index 000000000..db49b4f6e --- /dev/null +++ b/gr-analog/lib/ctcss_squelch_ff_impl.cc @@ -0,0 +1,130 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2006,2010,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "ctcss_squelch_ff_impl.h" + +namespace gr { + namespace analog { + + static float ctcss_tones[] = { + 67.0, 71.9, 74.4, 77.0, 79.7, 82.5, 85.4, 88.5, 91.5, 94.8, + 97.4, 100.0, 103.5, 107.2, 110.9, 114.8, 118.8, 123.0, 127.3, 131.8, + 136.5, 141.3, 146.2, 151.4, 156.7, 162.2, 167.9, 173.8, 179.9, 186.2, + 192.8, 203.5, 210.7, 218.1, 225.7, 233.6, 241.8, 250.3 + }; + + static int max_tone_index = 37; + + ctcss_squelch_ff::sptr + ctcss_squelch_ff::make(int rate, float freq, float level, + int len, int ramp, bool gate) + { + return gnuradio::get_initial_sptr(new ctcss_squelch_ff_impl + (rate, freq, level, len, ramp, gate)); + } + + int + ctcss_squelch_ff_impl::find_tone(float freq) + { + for(int i = 0; i <= max_tone_index; i++) + if(ctcss_tones[i] == freq) // FIXME: make almost equal + return i; + return -1; + } + + ctcss_squelch_ff_impl::ctcss_squelch_ff_impl(int rate, float freq, float level, + int len, int ramp, bool gate) + : gr_block("ctcss_squelch_ff", + gr_make_io_signature(1, 1, sizeof(float)), + gr_make_io_signature(1, 1, sizeof(float))), + squelch_base_ff_impl("ctcss_squelch_ff", ramp, gate) + { + d_freq = freq; + d_level = level; + + // Default is 100 ms detection time + if(len == 0) + d_len = (int)(rate/10.0); + else + d_len = len; + + int i = find_tone(freq); + + // Non-standard tones or edge tones get 2% guard band, otherwise + // guards are set at adjacent ctcss tone frequencies + float f_l, f_r; + if(i == -1 || i == 0) + f_l = freq*0.98; + else + f_l = ctcss_tones[i-1]; + + if(i == -1 || i == max_tone_index) + f_r = freq*1.02; + else + f_r = ctcss_tones[i+1]; + + d_goertzel_l = fft::goertzel(rate, d_len, f_l); + d_goertzel_c = fft::goertzel(rate, d_len, freq); + d_goertzel_r = fft::goertzel(rate, d_len, f_r); + + d_mute = true; + } + + ctcss_squelch_ff_impl::~ctcss_squelch_ff_impl() + { + } + + std::vector<float> + ctcss_squelch_ff_impl::squelch_range() const + { + std::vector<float> r(3); + r[0] = 0.0; + r[1] = 1.0; + r[2] = (r[1]-r[0])/100; // step size + + return r; + } + + void + ctcss_squelch_ff_impl::update_state(const float &in) + { + d_goertzel_l.input(in); + d_goertzel_c.input(in); + d_goertzel_r.input(in); + + float d_out_l, d_out_c, d_out_r; + if(d_goertzel_c.ready()) { + d_out_l = abs(d_goertzel_l.output()); + d_out_c = abs(d_goertzel_c.output()); + d_out_r = abs(d_goertzel_r.output()); + + //printf("d_out_l=%f d_out_c=%f d_out_r=%f\n", d_out_l, d_out_c, d_out_r); + d_mute = (d_out_c < d_level || d_out_c < d_out_l || d_out_c < d_out_r); + } + } + + } /* namespace analog */ +} /* namespace gr */ diff --git a/gr-analog/lib/ctcss_squelch_ff_impl.h b/gr-analog/lib/ctcss_squelch_ff_impl.h new file mode 100644 index 000000000..0827fbafe --- /dev/null +++ b/gr-analog/lib/ctcss_squelch_ff_impl.h @@ -0,0 +1,82 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ANALOG_CTCSS_SQUELCH_FF_IMPL_H +#define INCLUDED_ANALOG_CTCSS_SQUELCH_FF_IMPL_H + +#include <analog/ctcss_squelch_ff.h> +#include "squelch_base_ff_impl.h" +#include <fft/goertzel.h> + +namespace gr { + namespace analog { + + class ctcss_squelch_ff_impl : public ctcss_squelch_ff, squelch_base_ff_impl + { + private: + float d_freq; + float d_level; + int d_len; + bool d_mute; + + fft::goertzel d_goertzel_l; + fft::goertzel d_goertzel_c; + fft::goertzel d_goertzel_r; + + int find_tone(float freq); + + protected: + virtual void update_state(const float &in); + virtual bool mute() const { return d_mute; } + + public: + ctcss_squelch_ff_impl(int rate, float freq, float level, + int len, int ramp, bool gate); + ~ctcss_squelch_ff_impl(); + + std::vector<float> squelch_range() const; + float level() const { return d_level; } + void set_level(float level) { d_level = level; } + int len() const { return d_len; } + + int ramp() const { return squelch_base_ff_impl::ramp(); } + void set_ramp(int ramp) { squelch_base_ff_impl::set_ramp(ramp); } + bool gate() const { return squelch_base_ff_impl::gate(); } + void set_gate(bool gate) { squelch_base_ff_impl::set_gate(gate); } + bool unmuted() const { return squelch_base_ff_impl::unmuted(); } + + int general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + return squelch_base_ff_impl::general_work(noutput_items, + ninput_items, + input_items, + output_items); + } + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_CTCSS_SQUELCH_FF_IMPL_H */ diff --git a/gr-analog/lib/dpll_bb_impl.cc b/gr-analog/lib/dpll_bb_impl.cc new file mode 100644 index 000000000..a199b66b4 --- /dev/null +++ b/gr-analog/lib/dpll_bb_impl.cc @@ -0,0 +1,98 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007,2009,2010 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "dpll_bb_impl.h" +#include <gr_io_signature.h> +#include <cstdio> + +namespace gr { + namespace analog { + + dpll_bb::sptr + dpll_bb::make(float period, float gain) + { + return gnuradio::get_initial_sptr + (new dpll_bb_impl(period, gain)); + } + + dpll_bb_impl::dpll_bb_impl(float period, float gain) + : gr_sync_block("dpll_bb", + gr_make_io_signature(1, 1, sizeof(char)), + gr_make_io_signature(1, 1, sizeof(char))), + d_restart(0), d_pulse_phase(0) + { + d_pulse_frequency = 1.0/period; + d_gain = gain; + d_decision_threshold = 1.0 - 0.5*d_pulse_frequency; +#if 0 + fprintf(stderr,"frequency = %f period = %f gain = %f threshold = %f\n", + d_pulse_frequency, + period, + d_gain, + d_decision_threshold); +#endif + } + + dpll_bb_impl::~dpll_bb_impl() + { + } + + int + dpll_bb_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const char *iptr = (const char*)input_items[0]; + char *optr = (char*)output_items[0]; + + for(int i = 0; i < noutput_items; i++) { + optr[i]= 0; + if(iptr[i] == 1) { + if(d_restart == 0) { + d_pulse_phase = 1; + } + else { + if(d_pulse_phase > 0.5) + d_pulse_phase += d_gain*(1.0-d_pulse_phase); + else + d_pulse_phase -= d_gain*d_pulse_phase; + } + d_restart = 3; + } + if(d_pulse_phase > d_decision_threshold) { + d_pulse_phase -= 1.0; + if(d_restart > 0) { + d_restart -= 1; + optr[i] = 1; + } + } + d_pulse_phase += d_pulse_frequency; + } + return noutput_items; + } + + } /* namespace analog */ +} /* namespace gr */ diff --git a/gr-analog/lib/dpll_bb_impl.h b/gr-analog/lib/dpll_bb_impl.h new file mode 100644 index 000000000..a1d8b7709 --- /dev/null +++ b/gr-analog/lib/dpll_bb_impl.h @@ -0,0 +1,58 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ANALOG_DPLL_BB_IMPL_H +#define INCLUDED_ANALOG_DPLL_BB_IMPL_H + +#include <analog/dpll_bb.h> + +namespace gr { + namespace analog { + + class dpll_bb_impl : public dpll_bb + { + private: + unsigned char d_restart; + float d_pulse_phase, d_pulse_frequency; + float d_gain, d_decision_threshold; + + public: + dpll_bb_impl(float period, float gain); + ~dpll_bb_impl(); + + void set_gain(float gain) { d_gain = gain; } + void set_decision_threshold(float thresh) { d_decision_threshold = thresh; } + + float gain() const { return d_gain; } + float freq() const { return d_pulse_frequency; } + float phase() const { return d_pulse_phase; } + float decision_threshold() const { return d_decision_threshold; } + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_DPLL_BB_IMPL_H */ diff --git a/gr-analog/lib/feedforward_agc_cc_impl.cc b/gr-analog/lib/feedforward_agc_cc_impl.cc new file mode 100644 index 000000000..4796fdfc5 --- /dev/null +++ b/gr-analog/lib/feedforward_agc_cc_impl.cc @@ -0,0 +1,99 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2010,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "feedforward_agc_cc_impl.h" +#include <gr_io_signature.h> +#include <stdexcept> + +namespace gr { + namespace analog { + + feedforward_agc_cc::sptr + feedforward_agc_cc::make(int nsamples, float reference) + { + return gnuradio::get_initial_sptr + (new feedforward_agc_cc_impl(nsamples, reference)); + } + + feedforward_agc_cc_impl::feedforward_agc_cc_impl(int nsamples, float reference) + : gr_sync_block("feedforward_agc_cc", + gr_make_io_signature(1, 1, sizeof(gr_complex)), + gr_make_io_signature(1, 1, sizeof(gr_complex))), + d_nsamples(nsamples), d_reference(reference) + { + if(nsamples < 1) + throw std::invalid_argument("feedforward_agc_cc_impl: nsamples must be >= 1"); + + set_history(nsamples); + } + + feedforward_agc_cc_impl::~feedforward_agc_cc_impl() + { + } + + inline static float + mag_squared(gr_complex x) + { + return x.real() * x.real() + x.imag() * x.imag(); + } + + // approximate sqrt(x^2 + y^2) + inline static float + envelope(gr_complex x) + { + float r_abs = std::fabs(x.real()); + float i_abs = std::fabs(x.imag()); + + if(r_abs > i_abs) + return r_abs + 0.4 * i_abs; + else + return i_abs + 0.4 * r_abs; + } + + int + feedforward_agc_cc_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const gr_complex *in = (const gr_complex*)input_items[0]; + gr_complex *out = (gr_complex*)output_items[0]; + int nsamples = d_nsamples; + float gain; + + for(int i = 0; i < noutput_items; i++) { + //float max_env = 1e-12; // avoid divide by zero + float max_env = 1e-4; // avoid divide by zero, indirectly set max gain + for(int j = 0; j < nsamples; j++) { + max_env = std::max(max_env, envelope(in[i+j])); + } + gain = d_reference / max_env; + out[i] = gain * in[i]; + } + return noutput_items; + } + + } /* namespace analog */ +} /* namespace gr */ diff --git a/gr-analog/lib/feedforward_agc_cc_impl.h b/gr-analog/lib/feedforward_agc_cc_impl.h new file mode 100644 index 000000000..60c7acada --- /dev/null +++ b/gr-analog/lib/feedforward_agc_cc_impl.h @@ -0,0 +1,49 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ANALOG_FEEDFORWARD_AGC_CC_IMPL_H +#define INCLUDED_ANALOG_FEEDFORWARD_AGC_CC_IMPL_H + +#include <analog/feedforward_agc_cc.h> + +namespace gr { + namespace analog { + + class feedforward_agc_cc_impl : public feedforward_agc_cc + { + private: + int d_nsamples; + float d_reference; + + public: + feedforward_agc_cc_impl(int nsamples, float reference); + ~feedforward_agc_cc_impl(); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_FEEDFORWARD_AGC_CC_IMPL_H */ diff --git a/gr-analog/lib/fmdet_cf_impl.cc b/gr-analog/lib/fmdet_cf_impl.cc new file mode 100644 index 000000000..c92ea2889 --- /dev/null +++ b/gr-analog/lib/fmdet_cf_impl.cc @@ -0,0 +1,129 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008,2010,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "fmdet_cf_impl.h" +#include <gr_io_signature.h> +#include <gr_math.h> + +namespace gr { + namespace analog { + +#define M_TWOPI (2*M_PI) + + fmdet_cf::sptr + fmdet_cf::make(float samplerate, float freq_low, + float freq_high, float scl) + { + return gnuradio::get_initial_sptr + (new fmdet_cf_impl(samplerate, freq_low, freq_high, scl)); + } + + fmdet_cf_impl::fmdet_cf_impl(float samplerate, float freq_low, + float freq_high, float scl) + : gr_sync_block("fmdet_cf", + gr_make_io_signature(1, 1, sizeof(gr_complex)), + gr_make_io_signature(1, 1, sizeof(float))), + d_S1(0.1), d_S2(0.1), + d_S3(0.1), d_S4(0.1) + { + //const float h[] = { 0.003118678733, -0.012139843428, 0.027270898036, + // -0.051318579352, 0.090406910552, -0.162926865366, + // 0.361885392563, 0.000000000000, -0.361885392563, + // 0.162926865366, -0.090406910552, 0.051318579352, + // -0.027270898036, 0.012139843428, -0.003118678733}; + + //std::vector<float> taps(15); + + d_freq = 0; + d_freqhi = freq_high; + d_freqlo = freq_low; + set_scale(scl); + + //for(int i = 0; i < 15; i++) { + //taps[i] = h[i]; + //} + // d_filter = gr_fir_util::create_gr_fir_ccf(taps); + } + + fmdet_cf_impl::~fmdet_cf_impl() + { + } + + void + fmdet_cf_impl::set_scale(float scl) + { + float delta = d_freqhi - d_freqlo; + d_scl = scl; + d_bias = 0.5*scl*(d_freqhi + d_freqlo) / delta; + } + + void + fmdet_cf_impl::set_freq_range(float freq_low, float freq_high) + { + d_freqhi = freq_high; + d_freqlo = freq_low; + set_scale(d_scl); + } + + int + fmdet_cf_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const gr_complex *iptr = (gr_complex*)input_items[0]; + float *optr = (float*)output_items[0]; + //const gr_complex *scaleiptr = (gr_complex*)input_items[0]; + + int size = noutput_items; + + gr_complex Sdot, S0; + gr_complex S1=d_S1, S2=d_S2, S3=d_S3, S4=d_S4; + float d_8 = 8.0; + + while(size-- > 0) { + S0 = *iptr++; + + Sdot = d_scl * (-S0+d_8*S1-d_8*S1+S4); + + d_freq = (S2.real()*Sdot.imag()-S2.imag()*Sdot.real()) / + (S2.real()*S2.real()+S2.imag()*S2.imag()); + + S4 = S3; + S3 = S2; + S2 = S1; + S1 = S0; + + *optr++ = d_freq-d_bias; + } + d_S1 = S1; + d_S2 = S2; + d_S3 = S3; + d_S4 = S4; + return noutput_items; + } + + } /* namespace analog */ +} /* namespace gr */ diff --git a/gr-analog/lib/fmdet_cf_impl.h b/gr-analog/lib/fmdet_cf_impl.h new file mode 100644 index 000000000..01fce09dd --- /dev/null +++ b/gr-analog/lib/fmdet_cf_impl.h @@ -0,0 +1,62 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008, 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ANALOG_FMDET_CF_IMPL_H +#define INCLUDED_ANALOG_FMDET_CF_IMPL_H + +#include <analog/fmdet_cf.h> +//#include <filter/fir_filter.h> +#include <gr_sync_block.h> + +namespace gr { + namespace analog { + + class fmdet_cf_impl : public fmdet_cf + { + private: + gr_complex d_S1, d_S2, d_S3, d_S4; + float d_freq, d_freqlo, d_freqhi, d_scl, d_bias; + //kernel::fir_filter_ccf* d_filter; + + public: + fmdet_cf_impl(float samplerate, float freq_low, + float freq_high, float scl); + ~fmdet_cf_impl(); + + void set_scale(float scl); + void set_freq_range(float freq_low, float freq_high); + + float freq() const { return d_freq; } + float freq_high() const { return d_freqhi; } + float freq_low() const { return d_freqlo; } + float scale() const { return d_scl; } + float bias() const { return d_bias; } + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_FMDET_CF_IMPL_H */ diff --git a/gr-analog/lib/frequency_modulator_fc_impl.cc b/gr-analog/lib/frequency_modulator_fc_impl.cc new file mode 100644 index 000000000..2da7ee15f --- /dev/null +++ b/gr-analog/lib/frequency_modulator_fc_impl.cc @@ -0,0 +1,82 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2010-2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "frequency_modulator_fc_impl.h" +#include <gr_io_signature.h> +#include <gr_fxpt.h> +#include <math.h> +#include <boost/math/special_functions/trunc.hpp> + +namespace gr { + namespace analog { + + frequency_modulator_fc::sptr + frequency_modulator_fc::make(double sensitivity) + { + return gnuradio::get_initial_sptr + (new frequency_modulator_fc_impl(sensitivity)); + } + + frequency_modulator_fc_impl::frequency_modulator_fc_impl(double sensitivity) + : gr_sync_block("frequency_modulator_fc", + gr_make_io_signature(1, 1, sizeof(float)), + gr_make_io_signature(1, 1, sizeof(gr_complex))), + d_sensitivity(sensitivity), d_phase(0) + { + } + + frequency_modulator_fc_impl::~frequency_modulator_fc_impl() + { + } + + int + frequency_modulator_fc_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const float *in = (const float*)input_items[0]; + gr_complex *out = (gr_complex*)output_items[0]; + + for(int i = 0; i < noutput_items; i++) { + d_phase = d_phase + d_sensitivity * in[i]; + + while(d_phase > (float)(M_PI)) + d_phase -= (float)(2.0 * M_PI); + while(d_phase < (float)(-M_PI)) + d_phase += (float)(2.0 * M_PI); + + float oi, oq; + + gr_int32 angle = gr_fxpt::float_to_fixed (d_phase); + gr_fxpt::sincos(angle, &oq, &oi); + out[i] = gr_complex(oi, oq); + } + + return noutput_items; + } + + } /* namespace analog */ +} /* namespace gr */ diff --git a/gr-analog/lib/frequency_modulator_fc_impl.h b/gr-analog/lib/frequency_modulator_fc_impl.h new file mode 100644 index 000000000..36512f516 --- /dev/null +++ b/gr-analog/lib/frequency_modulator_fc_impl.h @@ -0,0 +1,52 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ANALOG_FREQUENCY_MODULATOR_FC_IMPL_H +#define INCLUDED_ANALOG_FREQUENCY_MODULATOR_FC_IMPL_H + +#include <analog/frequency_modulator_fc.h> + +namespace gr { + namespace analog { + + class frequency_modulator_fc_impl : public frequency_modulator_fc + { + private: + float d_sensitivity; + float d_phase; + + public: + frequency_modulator_fc_impl(double sensitivity); + ~frequency_modulator_fc_impl(); + + void set_sensitivity(float sens) { d_sensitivity = sens; } + float sensitivity() const { return d_sensitivity; } + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_FREQUENCY_MODULATOR_FC_IMPL_H */ diff --git a/gr-analog/lib/noise_source_X_impl.cc.t b/gr-analog/lib/noise_source_X_impl.cc.t new file mode 100644 index 000000000..35dda9c5d --- /dev/null +++ b/gr-analog/lib/noise_source_X_impl.cc.t @@ -0,0 +1,116 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2010,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +/* @WARNING@ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "@IMPL_NAME@.h" +#include <gr_io_signature.h> +#include <stdexcept> + +namespace gr { + namespace analog { + + @BASE_NAME@::sptr + @BASE_NAME@::make(noise_type_t type, float ampl, long seed) + { + return gnuradio::get_initial_sptr + (new @IMPL_NAME@(type, ampl, seed)); + } + + @IMPL_NAME@::@IMPL_NAME@(noise_type_t type, float ampl, long seed) + : gr_sync_block("@BASE_NAME@", + gr_make_io_signature(0, 0, 0), + gr_make_io_signature(1, 1, sizeof(@TYPE@))), + d_type(type), + d_ampl(ampl), + d_rng(seed) + { + } + + @IMPL_NAME@::~@IMPL_NAME@() + { + } + + int + @IMPL_NAME@::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + @TYPE@ *out = (@TYPE@*)output_items[0]; + + switch(d_type) { +#if @IS_COMPLEX@ // complex? + + case GR_UNIFORM: + for(int i = 0; i < noutput_items; i++) { + out[i] = gr_complex(d_ampl * ((d_rng.ran1() * 2.0) - 1.0), + d_ampl * ((d_rng.ran1() * 2.0) - 1.0)); + } + break; + + case GR_GAUSSIAN: + for(int i = 0; i < noutput_items; i++) { + out[i] = d_ampl * d_rng.rayleigh_complex(); + } + break; + +#else // nope... + + case GR_UNIFORM: + for(int i = 0; i < noutput_items; i++) { + out[i] = (@TYPE@)(d_ampl * ((d_rng.ran1() * 2.0) - 1.0)); + } + break; + + case GR_GAUSSIAN: + for(int i = 0; i < noutput_items; i++) { + out[i] = (@TYPE@)(d_ampl * d_rng.gasdev()); + } + break; + + case GR_LAPLACIAN: + for(int i = 0; i < noutput_items; i++) { + out[i] = (@TYPE@)(d_ampl * d_rng.laplacian()); + } + break; + + case GR_IMPULSE: // FIXME changeable impulse settings + for(int i = 0; i < noutput_items; i++) { + out[i] = (@TYPE@)(d_ampl * d_rng.impulse(9)); + } + break; +#endif + + default: + throw std::runtime_error("invalid type"); + } + + return noutput_items; + } + + } /* namespace analog */ +} /* namespace gr */ + diff --git a/gr-analog/lib/noise_source_X_impl.h.t b/gr-analog/lib/noise_source_X_impl.h.t new file mode 100644 index 000000000..8bcc1dfde --- /dev/null +++ b/gr-analog/lib/noise_source_X_impl.h.t @@ -0,0 +1,58 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +/* @WARNING@ */ + +#ifndef @GUARD_NAME@ +#define @GUARD_NAME@ + +#include <analog/@BASE_NAME@.h> +#include <gr_random.h> + +namespace gr { + namespace analog { + + class @IMPL_NAME@ : public @BASE_NAME@ + { + noise_type_t d_type; + float d_ampl; + gr_random d_rng; + + public: + @IMPL_NAME@(noise_type_t type, float ampl, long seed = 0); + ~@IMPL_NAME@(); + + void set_type(noise_type_t type) { d_type = type; } + void set_amplitude(float ampl) { d_ampl = ampl; } + + noise_type_t type() const { return d_type; } + float amplitude() const { return d_ampl; } + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace filter */ +} /* namespace gr */ + +#endif /* @GUARD_NAME@ */ diff --git a/gr-analog/lib/phase_modulator_fc_impl.cc b/gr-analog/lib/phase_modulator_fc_impl.cc new file mode 100644 index 000000000..9e9e73f8c --- /dev/null +++ b/gr-analog/lib/phase_modulator_fc_impl.cc @@ -0,0 +1,73 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2006,2010,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "phase_modulator_fc_impl.h" +#include <gr_io_signature.h> +#include <gr_sincos.h> +#include <math.h> + +namespace gr { + namespace analog { + + phase_modulator_fc::sptr + phase_modulator_fc::make(double sensitivity) + { + return gnuradio::get_initial_sptr + (new phase_modulator_fc_impl(sensitivity)); + } + + phase_modulator_fc_impl::phase_modulator_fc_impl(double sensitivity) + : gr_sync_block("phase_modulator_fc", + gr_make_io_signature(1, 1, sizeof(float)), + gr_make_io_signature(1, 1, sizeof(gr_complex))), + d_sensitivity(sensitivity), d_phase(0) + { + } + + phase_modulator_fc_impl::~phase_modulator_fc_impl() + { + } + + int + phase_modulator_fc_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const float *in = (const float*)input_items[0]; + gr_complex *out = (gr_complex*)output_items[0]; + + for(int i = 0; i < noutput_items; i++) { + d_phase = d_sensitivity * in[i]; + float oi, oq; + gr_sincosf(d_phase, &oq, &oi); + out[i] = gr_complex(oi, oq); + } + + return noutput_items; + } + + } /* namespace analog */ +} /* namespace gr */ diff --git a/gr-analog/lib/phase_modulator_fc_impl.h b/gr-analog/lib/phase_modulator_fc_impl.h new file mode 100644 index 000000000..ac10bc891 --- /dev/null +++ b/gr-analog/lib/phase_modulator_fc_impl.h @@ -0,0 +1,55 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2006,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ANALOG_PHASE_MODULATOR_FC_IMPL_H +#define INCLUDED_ANALOG_PHASE_MODULATOR_FC_IMPL_H + +#include <analog/phase_modulator_fc.h> + +namespace gr { + namespace analog { + + class phase_modulator_fc_impl : public phase_modulator_fc + { + private: + double d_sensitivity; + double d_phase; + + public: + phase_modulator_fc_impl(double sensitivity); + ~phase_modulator_fc_impl(); + + double sensitivity() const { return d_sensitivity; } + double phase() const { return d_phase; } + + void set_sensitivity(double s) { d_sensitivity = s; } + void set_phase(double p) { d_phase = p; } + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_PHASE_MODULATOR_FC_IMPL_H */ diff --git a/gr-analog/lib/pll_carriertracking_cc_impl.cc b/gr-analog/lib/pll_carriertracking_cc_impl.cc new file mode 100644 index 000000000..c53e0f433 --- /dev/null +++ b/gr-analog/lib/pll_carriertracking_cc_impl.cc @@ -0,0 +1,228 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2010-2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "pll_carriertracking_cc_impl.h" +#include <gr_io_signature.h> +#include <gr_sincos.h> +#include <math.h> +#include <gr_math.h> + +namespace gr { + namespace analog { + +#ifndef M_TWOPI +#define M_TWOPI (2.0f*M_PI) +#endif + + pll_carriertracking_cc::sptr + pll_carriertracking_cc::make(float loop_bw, float max_freq, float min_freq) + { + return gnuradio::get_initial_sptr + (new pll_carriertracking_cc_impl(loop_bw, max_freq, min_freq)); + } + + pll_carriertracking_cc_impl::pll_carriertracking_cc_impl(float loop_bw, + float max_freq, + float min_freq) + : gr_sync_block("pll_carriertracking_cc", + gr_make_io_signature(1, 1, sizeof(gr_complex)), + gr_make_io_signature(1, 1, sizeof(gr_complex))), + gri_control_loop(loop_bw, max_freq, min_freq), + d_locksig(0), d_lock_threshold(0), d_squelch_enable(false) + { + } + + pll_carriertracking_cc_impl::~pll_carriertracking_cc_impl() + { + } + + float + pll_carriertracking_cc_impl::mod_2pi(float in) + { + if(in>M_PI) + return in-M_TWOPI; + else if(in<-M_PI) + return in+M_TWOPI; + else + return in; + } + + float + pll_carriertracking_cc_impl::phase_detector(gr_complex sample, float ref_phase) + { + float sample_phase; + // sample_phase = atan2(sample.imag(),sample.real()); + sample_phase = gr_fast_atan2f(sample.imag(),sample.real()); + return mod_2pi(sample_phase-ref_phase); + } + + bool + pll_carriertracking_cc_impl::lock_detector(void) + { + return (fabsf(d_locksig) > d_lock_threshold); + } + + bool + pll_carriertracking_cc_impl::squelch_enable(bool set_squelch) + { + return d_squelch_enable = set_squelch; + } + + float + pll_carriertracking_cc_impl::set_lock_threshold(float threshold) + { + return d_lock_threshold = threshold; + } + + int + pll_carriertracking_cc_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const gr_complex *iptr = (gr_complex*)input_items[0]; + gr_complex *optr = (gr_complex*)output_items[0]; + + float error; + float t_imag, t_real; + + for(int i = 0; i < noutput_items; i++) { + gr_sincosf(d_phase, &t_imag, &t_real); + optr[i] = iptr[i] * gr_complex(t_real, -t_imag); + + error = phase_detector(iptr[i], d_phase); + + advance_loop(error); + phase_wrap(); + frequency_limit(); + + d_locksig = d_locksig * (1.0 - d_alpha) + \ + d_alpha*(iptr[i].real() * t_real + iptr[i].imag() * t_imag); + + if((d_squelch_enable) && !lock_detector()) + optr[i] = 0; + } + return noutput_items; + } + + void + pll_carriertracking_cc_impl::set_loop_bandwidth(float bw) + { + gri_control_loop::set_loop_bandwidth(bw); + } + + void + pll_carriertracking_cc_impl::set_damping_factor(float df) + { + gri_control_loop::set_damping_factor(df); + } + + void + pll_carriertracking_cc_impl::set_alpha(float alpha) + { + gri_control_loop::set_alpha(alpha); + } + + void + pll_carriertracking_cc_impl::set_beta(float beta) + { + gri_control_loop::set_beta(beta); + } + + void + pll_carriertracking_cc_impl::set_frequency(float freq) + { + gri_control_loop::set_frequency(freq); + } + + void + pll_carriertracking_cc_impl::set_phase(float phase) + { + gri_control_loop::set_phase(phase); + } + + void + pll_carriertracking_cc_impl::set_min_freq(float freq) + { + gri_control_loop::set_min_freq(freq); + } + + void + pll_carriertracking_cc_impl::set_max_freq(float freq) + { + gri_control_loop::set_max_freq(freq); + } + + + float + pll_carriertracking_cc_impl::get_loop_bandwidth() const + { + return gri_control_loop::get_loop_bandwidth(); + } + + float + pll_carriertracking_cc_impl::get_damping_factor() const + { + return gri_control_loop::get_damping_factor(); + } + + float + pll_carriertracking_cc_impl::get_alpha() const + { + return gri_control_loop::get_alpha(); + } + + float + pll_carriertracking_cc_impl::get_beta() const + { + return gri_control_loop::get_beta(); + } + + float + pll_carriertracking_cc_impl::get_frequency() const + { + return gri_control_loop::get_frequency(); + } + + float + pll_carriertracking_cc_impl::get_phase() const + { + return gri_control_loop::get_phase(); + } + + float + pll_carriertracking_cc_impl::get_min_freq() const + { + return gri_control_loop::get_min_freq(); + } + + float + pll_carriertracking_cc_impl::get_max_freq() const + { + return gri_control_loop::get_max_freq(); + } + + } /* namespace analog */ +} /* namespace gr */ diff --git a/gr-analog/lib/pll_carriertracking_cc_impl.h b/gr-analog/lib/pll_carriertracking_cc_impl.h new file mode 100644 index 000000000..d67223db8 --- /dev/null +++ b/gr-analog/lib/pll_carriertracking_cc_impl.h @@ -0,0 +1,76 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2006,2011,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ANALOG_PLL_CARRIERTRACKING_CC_IMPL_H +#define INCLUDED_ANALOG_PLL_CARRIERTRACKING_CC_IMPL_H + +#include <analog/pll_carriertracking_cc.h> +#include <gri_control_loop.h> + +namespace gr { + namespace analog { + + class pll_carriertracking_cc_impl + : public pll_carriertracking_cc, public gri_control_loop + { + private: + float d_locksig,d_lock_threshold; + bool d_squelch_enable; + + float mod_2pi(float in); + float phase_detector(gr_complex sample,float ref_phase); + + public: + pll_carriertracking_cc_impl(float loop_bw, float max_freq, float min_freq); + ~pll_carriertracking_cc_impl(); + + bool lock_detector(void); + bool squelch_enable(bool); + float set_lock_threshold(float); + + void set_loop_bandwidth(float bw); + void set_damping_factor(float df); + void set_alpha(float alpha); + void set_beta(float beta); + void set_frequency(float freq); + void set_phase(float phase); + void set_min_freq(float freq); + void set_max_freq(float freq); + + float get_loop_bandwidth() const; + float get_damping_factor() const; + float get_alpha() const; + float get_beta() const; + float get_frequency() const; + float get_phase() const; + float get_min_freq() const; + float get_max_freq() const; + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_PLL_CARRIERTRACKING_CC_IMPL_H */ diff --git a/gr-analog/lib/pll_freqdet_cf_impl.cc b/gr-analog/lib/pll_freqdet_cf_impl.cc new file mode 100644 index 000000000..27e8d02aa --- /dev/null +++ b/gr-analog/lib/pll_freqdet_cf_impl.cc @@ -0,0 +1,198 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2010,2011 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "pll_freqdet_cf_impl.h" +#include <gr_io_signature.h> +#include <math.h> +#include <gr_math.h> + +namespace gr { + namespace analog { + +#ifndef M_TWOPI +#define M_TWOPI (2.0f*M_PI) +#endif + + pll_freqdet_cf::sptr + pll_freqdet_cf::make(float loop_bw, float max_freq, float min_freq) + { + return gnuradio::get_initial_sptr + (new pll_freqdet_cf_impl(loop_bw, max_freq, min_freq)); + } + + pll_freqdet_cf_impl::pll_freqdet_cf_impl(float loop_bw, float max_freq, float min_freq) + : gr_sync_block("pll_freqdet_cf", + gr_make_io_signature(1, 1, sizeof(gr_complex)), + gr_make_io_signature(1, 1, sizeof(float))), + gri_control_loop(loop_bw, max_freq, min_freq) + { + } + + pll_freqdet_cf_impl::~pll_freqdet_cf_impl() + { + } + + float + pll_freqdet_cf_impl::mod_2pi(float in) + { + if(in > M_PI) + return in - M_TWOPI; + else if(in < -M_PI) + return in + M_TWOPI; + else + return in; + } + + float + pll_freqdet_cf_impl::phase_detector(gr_complex sample, float ref_phase) + { + float sample_phase; + sample_phase = gr_fast_atan2f(sample.imag(), sample.real()); + return mod_2pi(sample_phase - ref_phase); + } + + int + pll_freqdet_cf_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const gr_complex *iptr = (gr_complex*)input_items[0]; + float *optr = (float*)output_items[0]; + + float error; + int size = noutput_items; + + while(size-- > 0) { + *optr++ = d_freq; + + error = phase_detector(*iptr++, d_phase); + + advance_loop(error); + phase_wrap(); + frequency_limit(); + } + return noutput_items; + } + + void + pll_freqdet_cf_impl::set_loop_bandwidth(float bw) + { + gri_control_loop::set_loop_bandwidth(bw); + } + + void + pll_freqdet_cf_impl::set_damping_factor(float df) + { + gri_control_loop::set_damping_factor(df); + } + + void + pll_freqdet_cf_impl::set_alpha(float alpha) + { + gri_control_loop::set_alpha(alpha); + } + + void + pll_freqdet_cf_impl::set_beta(float beta) + { + gri_control_loop::set_beta(beta); + } + + void + pll_freqdet_cf_impl::set_frequency(float freq) + { + gri_control_loop::set_frequency(freq); + } + + void + pll_freqdet_cf_impl::set_phase(float phase) + { + gri_control_loop::set_phase(phase); + } + + void + pll_freqdet_cf_impl::set_min_freq(float freq) + { + gri_control_loop::set_min_freq(freq); + } + + void + pll_freqdet_cf_impl::set_max_freq(float freq) + { + gri_control_loop::set_max_freq(freq); + } + + + float + pll_freqdet_cf_impl::get_loop_bandwidth() const + { + return gri_control_loop::get_loop_bandwidth(); + } + + float + pll_freqdet_cf_impl::get_damping_factor() const + { + return gri_control_loop::get_damping_factor(); + } + + float + pll_freqdet_cf_impl::get_alpha() const + { + return gri_control_loop::get_alpha(); + } + + float + pll_freqdet_cf_impl::get_beta() const + { + return gri_control_loop::get_beta(); + } + + float + pll_freqdet_cf_impl::get_frequency() const + { + return gri_control_loop::get_frequency(); + } + + float + pll_freqdet_cf_impl::get_phase() const + { + return gri_control_loop::get_phase(); + } + + float + pll_freqdet_cf_impl::get_min_freq() const + { + return gri_control_loop::get_min_freq(); + } + + float + pll_freqdet_cf_impl::get_max_freq() const + { + return gri_control_loop::get_max_freq(); + } + + } /* namespace analog */ +} /* namespace gr */ diff --git a/gr-analog/lib/pll_freqdet_cf_impl.h b/gr-analog/lib/pll_freqdet_cf_impl.h new file mode 100644 index 000000000..7acf53ebb --- /dev/null +++ b/gr-analog/lib/pll_freqdet_cf_impl.h @@ -0,0 +1,70 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2011,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ANALOG_PLL_FREQDET_CF_IMPL_H +#define INCLUDED_ANALOG_PLL_FREQDET_CF_IMPL_H + +#include <analog/pll_freqdet_cf.h> +#include <gri_control_loop.h> + +namespace gr { + namespace analog { + + class pll_freqdet_cf_impl : + public pll_freqdet_cf, public gri_control_loop + { + private: + float phase_detector(gr_complex sample,float ref_phase); + + public: + pll_freqdet_cf_impl(float loop_bw, float max_freq, float min_freq); + ~pll_freqdet_cf_impl(); + + float mod_2pi(float in); + + void set_loop_bandwidth(float bw); + void set_damping_factor(float df); + void set_alpha(float alpha); + void set_beta(float beta); + void set_frequency(float freq); + void set_phase(float phase); + void set_min_freq(float freq); + void set_max_freq(float freq); + + float get_loop_bandwidth() const; + float get_damping_factor() const; + float get_alpha() const; + float get_beta() const; + float get_frequency() const; + float get_phase() const; + float get_min_freq() const; + float get_max_freq() const; + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_PLL_FREQDET_CF_IMPL_H */ diff --git a/gr-analog/lib/pll_refout_cc_impl.cc b/gr-analog/lib/pll_refout_cc_impl.cc new file mode 100644 index 000000000..b94e3660a --- /dev/null +++ b/gr-analog/lib/pll_refout_cc_impl.cc @@ -0,0 +1,201 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2010-2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "pll_refout_cc_impl.h" +#include <gr_io_signature.h> +#include <gr_sincos.h> +#include <math.h> +#include <gr_math.h> + +namespace gr { + namespace analog { + +#ifndef M_TWOPI +#define M_TWOPI (2.0f*M_PI) +#endif + + pll_refout_cc::sptr + pll_refout_cc::make(float loop_bw, float max_freq, float min_freq) + { + return gnuradio::get_initial_sptr + (new pll_refout_cc_impl(loop_bw, max_freq, min_freq)); + } + + pll_refout_cc_impl::pll_refout_cc_impl(float loop_bw, float max_freq, float min_freq) + : gr_sync_block("pll_refout_cc", + gr_make_io_signature(1, 1, sizeof(gr_complex)), + gr_make_io_signature(1, 1, sizeof(gr_complex))), + gri_control_loop(loop_bw, max_freq, min_freq) + { + } + + pll_refout_cc_impl::~pll_refout_cc_impl() + { + } + + float + pll_refout_cc_impl::mod_2pi(float in) + { + if(in > M_PI) + return in - M_TWOPI; + else if(in < -M_PI) + return in+ M_TWOPI; + else + return in; + } + + float + pll_refout_cc_impl::phase_detector(gr_complex sample,float ref_phase) + { + float sample_phase; + sample_phase = gr_fast_atan2f(sample.imag(),sample.real()); + return mod_2pi(sample_phase-ref_phase); + } + + int + pll_refout_cc_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const gr_complex *iptr = (gr_complex*)input_items[0]; + gr_complex *optr = (gr_complex*)output_items[0]; + + float error; + float t_imag, t_real; + int size = noutput_items; + + while(size-- > 0) { + gr_sincosf(d_phase,&t_imag,&t_real); + *optr++ = gr_complex(t_real,t_imag); + + error = phase_detector(*iptr++,d_phase); + + advance_loop(error); + phase_wrap(); + frequency_limit(); + } + return noutput_items; + } + + void + pll_refout_cc_impl::set_loop_bandwidth(float bw) + { + gri_control_loop::set_loop_bandwidth(bw); + } + + void + pll_refout_cc_impl::set_damping_factor(float df) + { + gri_control_loop::set_damping_factor(df); + } + + void + pll_refout_cc_impl::set_alpha(float alpha) + { + gri_control_loop::set_alpha(alpha); + } + + void + pll_refout_cc_impl::set_beta(float beta) + { + gri_control_loop::set_beta(beta); + } + + void + pll_refout_cc_impl::set_frequency(float freq) + { + gri_control_loop::set_frequency(freq); + } + + void + pll_refout_cc_impl::set_phase(float phase) + { + gri_control_loop::set_phase(phase); + } + + void + pll_refout_cc_impl::set_min_freq(float freq) + { + gri_control_loop::set_min_freq(freq); + } + + void + pll_refout_cc_impl::set_max_freq(float freq) + { + gri_control_loop::set_max_freq(freq); + } + + + float + pll_refout_cc_impl::get_loop_bandwidth() const + { + return gri_control_loop::get_loop_bandwidth(); + } + + float + pll_refout_cc_impl::get_damping_factor() const + { + return gri_control_loop::get_damping_factor(); + } + + float + pll_refout_cc_impl::get_alpha() const + { + return gri_control_loop::get_alpha(); + } + + float + pll_refout_cc_impl::get_beta() const + { + return gri_control_loop::get_beta(); + } + + float + pll_refout_cc_impl::get_frequency() const + { + return gri_control_loop::get_frequency(); + } + + float + pll_refout_cc_impl::get_phase() const + { + return gri_control_loop::get_phase(); + } + + float + pll_refout_cc_impl::get_min_freq() const + { + return gri_control_loop::get_min_freq(); + } + + float + pll_refout_cc_impl::get_max_freq() const + { + return gri_control_loop::get_max_freq(); + } + + } /* namespace analog */ +} /* namespace gr */ diff --git a/gr-analog/lib/pll_refout_cc_impl.h b/gr-analog/lib/pll_refout_cc_impl.h new file mode 100644 index 000000000..9e8ae286b --- /dev/null +++ b/gr-analog/lib/pll_refout_cc_impl.h @@ -0,0 +1,69 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2011,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ANALOG_PLL_REFOUT_CC_IMPL_H +#define INCLUDED_ANALOG_PLL_REFOUT_CC_IMPL_H + +#include <analog/pll_refout_cc.h> +#include <gri_control_loop.h> + +namespace gr { + namespace analog { + + class pll_refout_cc_impl + : public pll_refout_cc, public gri_control_loop + { + private: + float mod_2pi (float in); + float phase_detector(gr_complex sample, float ref_phase); + + public: + pll_refout_cc_impl(float loop_bw, float max_freq, float min_freq); + ~pll_refout_cc_impl(); + + void set_loop_bandwidth(float bw); + void set_damping_factor(float df); + void set_alpha(float alpha); + void set_beta(float beta); + void set_frequency(float freq); + void set_phase(float phase); + void set_min_freq(float freq); + void set_max_freq(float freq); + + float get_loop_bandwidth() const; + float get_damping_factor() const; + float get_alpha() const; + float get_beta() const; + float get_frequency() const; + float get_phase() const; + float get_min_freq() const; + float get_max_freq() const; + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_PLL_REFOUT_CC_IMPL_H */ diff --git a/gr-analog/lib/probe_avg_mag_sqrd_c_impl.cc b/gr-analog/lib/probe_avg_mag_sqrd_c_impl.cc new file mode 100644 index 000000000..291809bb2 --- /dev/null +++ b/gr-analog/lib/probe_avg_mag_sqrd_c_impl.cc @@ -0,0 +1,91 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2010,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "probe_avg_mag_sqrd_c_impl.h" +#include <gr_io_signature.h> +#include <cmath> + +namespace gr { + namespace analog { + + probe_avg_mag_sqrd_c::sptr + probe_avg_mag_sqrd_c::make(double threshold_db, double alpha) + { + return gnuradio::get_initial_sptr + (new probe_avg_mag_sqrd_c_impl(threshold_db, alpha)); + } + + probe_avg_mag_sqrd_c_impl::probe_avg_mag_sqrd_c_impl(double threshold_db, double alpha) + : gr_sync_block("probe_avg_mag_sqrd_c", + gr_make_io_signature(1, 1, sizeof(gr_complex)), + gr_make_io_signature(0, 0, 0)), + d_unmuted(false), d_level(0), d_iir(alpha) + { + set_threshold(threshold_db); + } + + probe_avg_mag_sqrd_c_impl::~probe_avg_mag_sqrd_c_impl() + { + } + + int + probe_avg_mag_sqrd_c_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const gr_complex *in = (const gr_complex*)input_items[0]; + + for(int i = 0; i < noutput_items; i++) { + double mag_sqrd = in[i].real()*in[i].real() + in[i].imag()*in[i].imag(); + d_iir.filter(mag_sqrd); // computed for side effect: prev_output() + } + + d_unmuted = d_iir.prev_output() >= d_threshold; + d_level = d_iir.prev_output(); + return noutput_items; + } + + double + probe_avg_mag_sqrd_c_impl::threshold() const + { + return 10 * std::log10(d_threshold); + } + + void + probe_avg_mag_sqrd_c_impl::set_threshold(double decibels) + { + // convert to absolute threshold (mag squared) + d_threshold = std::pow(10.0, decibels/10); + } + + void + probe_avg_mag_sqrd_c_impl::set_alpha(double alpha) + { + d_iir.set_taps(alpha); + } + + } /* namespace analog */ +} /* namespace gr */ diff --git a/gr-analog/lib/probe_avg_mag_sqrd_c_impl.h b/gr-analog/lib/probe_avg_mag_sqrd_c_impl.h new file mode 100644 index 000000000..0a2685357 --- /dev/null +++ b/gr-analog/lib/probe_avg_mag_sqrd_c_impl.h @@ -0,0 +1,60 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2006,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ANALOG_PROBE_AVG_MAG_SQRD_C_IMPL_H +#define INCLUDED_ANALOG_PROBE_AVG_MAG_SQRD_C_IMPL_H + +#include <analog/probe_avg_mag_sqrd_c.h> +#include <filter/single_pole_iir.h> + +namespace gr { + namespace analog { + + class probe_avg_mag_sqrd_c_impl : public probe_avg_mag_sqrd_c + { + private: + double d_threshold; + bool d_unmuted; + double d_level; + filter::single_pole_iir<double,double,double> d_iir; + + public: + probe_avg_mag_sqrd_c_impl(double threshold_db, double alpha = 0.0001); + ~probe_avg_mag_sqrd_c_impl(); + + bool unmuted() const { return d_unmuted; } + double level() const { return d_level; } + + double threshold() const; + + void set_alpha(double alpha); + void set_threshold(double decibels); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_PROBE_AVG_MAG_SQRD_C_IMPL_H */ diff --git a/gr-analog/lib/probe_avg_mag_sqrd_cf_impl.cc b/gr-analog/lib/probe_avg_mag_sqrd_cf_impl.cc new file mode 100644 index 000000000..ceaf5dbf0 --- /dev/null +++ b/gr-analog/lib/probe_avg_mag_sqrd_cf_impl.cc @@ -0,0 +1,93 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2007,2010,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "probe_avg_mag_sqrd_cf_impl.h" +#include <gr_io_signature.h> +#include <cmath> + +namespace gr { + namespace analog { + + probe_avg_mag_sqrd_cf::sptr + probe_avg_mag_sqrd_cf::make(double threshold_db, double alpha) + { + return gnuradio::get_initial_sptr + (new probe_avg_mag_sqrd_cf_impl(threshold_db, alpha)); + } + + probe_avg_mag_sqrd_cf_impl::probe_avg_mag_sqrd_cf_impl(double threshold_db, double alpha) + : gr_sync_block("probe_avg_mag_sqrd_cf", + gr_make_io_signature(1, 1, sizeof(gr_complex)), + gr_make_io_signature(1, 1, sizeof(float))), + d_unmuted(false), d_level(0), d_iir(alpha) + { + set_threshold(threshold_db); + } + + probe_avg_mag_sqrd_cf_impl::~probe_avg_mag_sqrd_cf_impl() + { + } + + int + probe_avg_mag_sqrd_cf_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const gr_complex *in = (const gr_complex*)input_items[0]; + float *out = (float*)output_items[0]; + + for(int i = 0; i < noutput_items; i++) { + out[i] = d_iir.prev_output(); + double mag_sqrd = in[i].real()*in[i].real() + in[i].imag()*in[i].imag(); + d_iir.filter(mag_sqrd); // computed for side effect: prev_output() + } + + d_unmuted = d_iir.prev_output() >= d_threshold; + d_level = d_iir.prev_output(); + return noutput_items; + } + + double + probe_avg_mag_sqrd_cf_impl::threshold() const + { + return 10 * std::log10(d_threshold); + } + + void + probe_avg_mag_sqrd_cf_impl::set_threshold(double decibels) + { + // convert to absolute threshold (mag squared) + d_threshold = std::pow(10.0, decibels/10); + } + + void + probe_avg_mag_sqrd_cf_impl::set_alpha(double alpha) + { + d_iir.set_taps(alpha); + } + + } /* namespace analog */ +} /* namespace gr */ diff --git a/gr-analog/lib/probe_avg_mag_sqrd_cf_impl.h b/gr-analog/lib/probe_avg_mag_sqrd_cf_impl.h new file mode 100644 index 000000000..9cd8f8d4c --- /dev/null +++ b/gr-analog/lib/probe_avg_mag_sqrd_cf_impl.h @@ -0,0 +1,60 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2006,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ANALOG_PROBE_AVG_MAG_SQRD_CF_IMPL_H +#define INCLUDED_ANALOG_PROBE_AVG_MAG_SQRD_CF_IMPL_H + +#include <analog/probe_avg_mag_sqrd_cf.h> +#include <filter/single_pole_iir.h> + +namespace gr { + namespace analog { + + class probe_avg_mag_sqrd_cf_impl : public probe_avg_mag_sqrd_cf + { + private: + double d_threshold; + bool d_unmuted; + double d_level; + filter::single_pole_iir<double,double,double> d_iir; + + public: + probe_avg_mag_sqrd_cf_impl(double threshold_db, double alpha); + ~probe_avg_mag_sqrd_cf_impl(); + + bool unmuted() const { return d_unmuted; } + double level() const { return d_level; } + + double threshold() const; + + void set_alpha(double alpha); + void set_threshold(double decibels); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_PROBE_AVG_MAG_SQRD_CF_IMPL_H */ diff --git a/gr-analog/lib/probe_avg_mag_sqrd_f_impl.cc b/gr-analog/lib/probe_avg_mag_sqrd_f_impl.cc new file mode 100644 index 000000000..4ac7ef06b --- /dev/null +++ b/gr-analog/lib/probe_avg_mag_sqrd_f_impl.cc @@ -0,0 +1,92 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2010,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "probe_avg_mag_sqrd_f_impl.h" +#include <gr_io_signature.h> +#include <cmath> + +namespace gr { + namespace analog { + + probe_avg_mag_sqrd_f::sptr + probe_avg_mag_sqrd_f::make(double threshold_db, double alpha) + { + return gnuradio::get_initial_sptr + (new probe_avg_mag_sqrd_f_impl(threshold_db, alpha)); + } + + probe_avg_mag_sqrd_f_impl::probe_avg_mag_sqrd_f_impl(double threshold_db, double alpha) + : gr_sync_block("probe_avg_mag_sqrd_f", + gr_make_io_signature(1, 1, sizeof(float)), + gr_make_io_signature(0, 0, 0)), + d_unmuted(false), d_level(0), d_iir(alpha) + { + set_threshold(threshold_db); + } + + probe_avg_mag_sqrd_f_impl::~probe_avg_mag_sqrd_f_impl() + { + } + + int + probe_avg_mag_sqrd_f_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const float *in = (const float*)input_items[0]; + + for(int i = 0; i < noutput_items; i++) { + double mag_sqrd = in[i]*in[i]; + d_iir.filter(mag_sqrd); // computed for side effect: prev_output() + } + + d_unmuted = d_iir.prev_output() >= d_threshold; + d_level = d_iir.prev_output(); + return noutput_items; + } + + double + probe_avg_mag_sqrd_f_impl::threshold() const + { + return 10 * std::log10(d_threshold); + } + + void + probe_avg_mag_sqrd_f_impl::set_threshold(double decibels) + { + // convert to absolute threshold (mag sqrd) + d_threshold = std::pow(10.0, decibels/10); + } + + void + probe_avg_mag_sqrd_f_impl::set_alpha(double alpha) + { + d_iir.set_taps(alpha); + } + + } /* namespace analog */ +} /* namespace gr */ + diff --git a/gr-analog/lib/probe_avg_mag_sqrd_f_impl.h b/gr-analog/lib/probe_avg_mag_sqrd_f_impl.h new file mode 100644 index 000000000..ba879763c --- /dev/null +++ b/gr-analog/lib/probe_avg_mag_sqrd_f_impl.h @@ -0,0 +1,60 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ANALOG_PROBE_AVG_MAG_SQRD_F_IMPL_H +#define INCLUDED_ANALOG_PROBE_AVG_MAG_SQRD_F_IMPL_H + +#include <analog/probe_avg_mag_sqrd_f.h> +#include <filter/single_pole_iir.h> + +namespace gr { + namespace analog { + + class probe_avg_mag_sqrd_f_impl : public probe_avg_mag_sqrd_f + { + private: + double d_threshold; + bool d_unmuted; + double d_level; + filter::single_pole_iir<double,double,double> d_iir; + + public: + probe_avg_mag_sqrd_f_impl(double threshold_db, double alpha); + ~probe_avg_mag_sqrd_f_impl(); + + bool unmuted() const { return d_unmuted; } + double level() const { return d_level; } + + double threshold() const; + + void set_alpha(double alpha); + void set_threshold(double decibels); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_PROBE_AVG_MAG_SQRD_F_IMPL_H */ diff --git a/gr-analog/lib/pwr_squelch_cc_impl.cc b/gr-analog/lib/pwr_squelch_cc_impl.cc new file mode 100644 index 000000000..1bfba6846 --- /dev/null +++ b/gr-analog/lib/pwr_squelch_cc_impl.cc @@ -0,0 +1,73 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2006,2010,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "pwr_squelch_cc_impl.h" + +namespace gr { + namespace analog { + + pwr_squelch_cc::sptr + pwr_squelch_cc::make(double threshold, double alpha, + int ramp, bool gate) + { + return gnuradio::get_initial_sptr + (new pwr_squelch_cc_impl(threshold, alpha, ramp, gate)); + } + + pwr_squelch_cc_impl::pwr_squelch_cc_impl(double threshold, double alpha, + int ramp, bool gate) + : gr_block("pwr_squelch_cc", + gr_make_io_signature(1, 1, sizeof(gr_complex)), + gr_make_io_signature(1, 1, sizeof(gr_complex))), + squelch_base_cc_impl("pwr_squelch_cc", ramp, gate), + d_iir(alpha) + { + set_threshold(threshold); + } + + pwr_squelch_cc_impl::~pwr_squelch_cc_impl() + { + } + + std::vector<float> + pwr_squelch_cc_impl::squelch_range() const + { + std::vector<float> r(3); + r[0] = -50.0; // min FIXME + r[1] = +50.0; // max FIXME + r[2] = (r[1] - r[0]) / 100; // step size + + return r; + } + + void + pwr_squelch_cc_impl::update_state(const gr_complex &in) + { + d_pwr = d_iir.filter(in.real()*in.real()+in.imag()*in.imag()); + } + + } /* namespace analog */ +} /* namespace gr */ diff --git a/gr-analog/lib/pwr_squelch_cc_impl.h b/gr-analog/lib/pwr_squelch_cc_impl.h new file mode 100644 index 000000000..72df0f3d2 --- /dev/null +++ b/gr-analog/lib/pwr_squelch_cc_impl.h @@ -0,0 +1,78 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ANALOG_PWR_SQUELCH_CC_IMPL_H +#define INCLUDED_ANALOG_PWR_SQUELCH_CC_IMPL_H + +#include <analog/pwr_squelch_cc.h> +#include "squelch_base_cc_impl.h" +#include <filter/single_pole_iir.h> +#include <cmath> + +namespace gr { + namespace analog { + + class ANALOG_API pwr_squelch_cc_impl : + public pwr_squelch_cc, squelch_base_cc_impl + { + private: + double d_threshold; + double d_pwr; + filter::single_pole_iir<double,double,double> d_iir; + + protected: + virtual void update_state(const gr_complex &in); + virtual bool mute() const { return d_pwr < d_threshold; } + + public: + pwr_squelch_cc_impl(double db, double alpha=0.0001, + int ramp=0, bool gate=false); + ~pwr_squelch_cc_impl(); + + std::vector<float> squelch_range() const; + + double threshold() const { return 10*log10(d_threshold); } + void set_threshold(double db) { d_threshold = std::pow(10.0, db/10); } + void set_alpha(double alpha) { d_iir.set_taps(alpha); } + + int ramp() const { return squelch_base_cc_impl::ramp(); } + void set_ramp(int ramp) { squelch_base_cc_impl::set_ramp(ramp); } + bool gate() const { return squelch_base_cc_impl::gate(); } + void set_gate(bool gate) { squelch_base_cc_impl::set_gate(gate); } + bool unmuted() const { return squelch_base_cc_impl::unmuted(); } + + int general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + return squelch_base_cc_impl::general_work(noutput_items, + ninput_items, + input_items, + output_items); + } + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_PWR_SQUELCH_CC_IMPL_H */ diff --git a/gr-analog/lib/pwr_squelch_ff_impl.cc b/gr-analog/lib/pwr_squelch_ff_impl.cc new file mode 100644 index 000000000..c6bb6af90 --- /dev/null +++ b/gr-analog/lib/pwr_squelch_ff_impl.cc @@ -0,0 +1,73 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2006,2010,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "pwr_squelch_ff_impl.h" + +namespace gr { + namespace analog { + + pwr_squelch_ff::sptr + pwr_squelch_ff::make(double threshold, double alpha, + int ramp, bool gate) + { + return gnuradio::get_initial_sptr + (new pwr_squelch_ff_impl(threshold, alpha, ramp, gate)); + } + + pwr_squelch_ff_impl::pwr_squelch_ff_impl(double threshold, double alpha, + int ramp, bool gate) + : gr_block("pwr_squelch_ff", + gr_make_io_signature(1, 1, sizeof(float)), + gr_make_io_signature(1, 1, sizeof(float))), + squelch_base_ff_impl("pwr_squelch_ff", ramp, gate), + d_iir(alpha) + { + set_threshold(threshold); + } + + pwr_squelch_ff_impl::~pwr_squelch_ff_impl() + { + } + + std::vector<float> + pwr_squelch_ff_impl::squelch_range() const + { + std::vector<float> r(3); + r[0] = -50.0; // min FIXME + r[1] = +50.0; // max FIXME + r[2] = (r[1] - r[0]) / 100; // step size + + return r; + } + + void + pwr_squelch_ff_impl::update_state(const float &in) + { + d_pwr = d_iir.filter(in*in); + } + + } /* namespace analog */ +} /* namespace gr */ diff --git a/gr-analog/lib/pwr_squelch_ff_impl.h b/gr-analog/lib/pwr_squelch_ff_impl.h new file mode 100644 index 000000000..96d959b4d --- /dev/null +++ b/gr-analog/lib/pwr_squelch_ff_impl.h @@ -0,0 +1,78 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ANALOG_PWR_SQUELCH_FF_IMPL_H +#define INCLUDED_ANALOG_PWR_SQUELCH_FF_IMPL_H + +#include <analog/pwr_squelch_ff.h> +#include "squelch_base_ff_impl.h" +#include <filter/single_pole_iir.h> +#include <cmath> + +namespace gr { + namespace analog { + + class ANALOG_API pwr_squelch_ff_impl : + public pwr_squelch_ff, squelch_base_ff_impl + { + private: + double d_threshold; + double d_pwr; + filter::single_pole_iir<double,double,double> d_iir; + + protected: + virtual void update_state(const float &in); + virtual bool mute() const { return d_pwr < d_threshold; } + + public: + pwr_squelch_ff_impl(double db, double alpha=0.0001, + int ramp=0, bool gate=false); + ~pwr_squelch_ff_impl(); + + std::vector<float> squelch_range() const; + + double threshold() const { return 10*log10(d_threshold); } + void set_threshold(double db) { d_threshold = std::pow(10.0, db/10); } + void set_alpha(double alpha) { d_iir.set_taps(alpha); } + + int ramp() const { return squelch_base_ff_impl::ramp(); } + void set_ramp(int ramp) { squelch_base_ff_impl::set_ramp(ramp); } + bool gate() const { return squelch_base_ff_impl::gate(); } + void set_gate(bool gate) { squelch_base_ff_impl::set_gate(gate); } + bool unmuted() const { return squelch_base_ff_impl::unmuted(); } + + int general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + return squelch_base_ff_impl::general_work(noutput_items, + ninput_items, + input_items, + output_items); + } + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_PWR_SQUELCH_FF_IMPL_H */ diff --git a/gr-analog/lib/qa_analog.cc b/gr-analog/lib/qa_analog.cc new file mode 100644 index 000000000..c3d51863b --- /dev/null +++ b/gr-analog/lib/qa_analog.cc @@ -0,0 +1,41 @@ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +/* + * This class gathers together all the test cases for the gr-analog + * directory into a single test suite. As you create new test cases, + * add them here. + */ + +#include <qa_analog.h> +#include <qa_sincos.h> +#include <qa_rotator.h> + +CppUnit::TestSuite * +qa_gr_analog::suite() +{ + CppUnit::TestSuite *s = new CppUnit::TestSuite("gr-analog"); + + s->addTest(gr::analog::qa_sincos::suite()); + s->addTest(gr::analog::qa_rotator::suite()); + + return s; +} diff --git a/gr-analog/lib/qa_analog.h b/gr-analog/lib/qa_analog.h new file mode 100644 index 000000000..458861cc9 --- /dev/null +++ b/gr-analog/lib/qa_analog.h @@ -0,0 +1,38 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef _QA_GR_ANALOG_H_ +#define _QA_GR_ANALOG_H_ + +#include <gruel/attributes.h> +#include <cppunit/TestSuite.h> + +//! collect all the tests for the gr-analog directory + +class __GR_ATTR_EXPORT qa_gr_analog { + public: + //! return suite of tests for all of gr-analog directory + static CppUnit::TestSuite *suite(); +}; + + +#endif /* _QA_GR_ANALOG_H_ */ diff --git a/gr-analog/lib/qa_rotator.cc b/gr-analog/lib/qa_rotator.cc new file mode 100644 index 000000000..b722f32c4 --- /dev/null +++ b/gr-analog/lib/qa_rotator.cc @@ -0,0 +1,81 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <gruel/attributes.h> +#include <cppunit/TestAssert.h> +#include <qa_rotator.h> +#include <analog/rotator.h> +#include <stdio.h> +#include <cmath> +#include <gr_expj.h> + +namespace gr { + namespace analog { + + // error vector magnitude + __GR_ATTR_UNUSED static float + error_vector_mag(gr_complex a, gr_complex b) + { + return abs(a-b); + } + + void + qa_rotator::t1() + { + static const unsigned int N = 100000; + + rotator r; + + double phase_incr = 2*M_PI / 1003; + double phase = 0; + + // Old code: We increment then return the rotated value, thus we + // need to start one tick back + // r.set_phase(gr_complex(1,0) * conj(gr_expj(phase_incr))); + + r.set_phase(gr_complex(1,0)); + r.set_phase_incr(gr_expj(phase_incr)); + + for(unsigned i = 0; i < N; i++) { + gr_complex expected = gr_expj(phase); + gr_complex actual = r.rotate(gr_complex(1, 0)); + +#if 0 + float evm = error_vector_mag(expected, actual); + printf("[%6d] expected: (%8.6f, %8.6f) actual: (%8.6f, %8.6f) evm: %8.6f\n", + i, expected.real(), expected.imag(), actual.real(), actual.imag(), evm); +#endif + + CPPUNIT_ASSERT_COMPLEXES_EQUAL(expected, actual, 0.0001); + + phase += phase_incr; + if(phase >= 2*M_PI) + phase -= 2*M_PI; + } + } + + } /* namespace analog */ +} /* namespace gr */ diff --git a/gr-analog/lib/qa_rotator.h b/gr-analog/lib/qa_rotator.h new file mode 100644 index 000000000..a22e41ec2 --- /dev/null +++ b/gr-analog/lib/qa_rotator.h @@ -0,0 +1,45 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef _QA_ANALOG_ROTATOR_H_ +#define _QA_ANALOG_ROTATOR_H_ + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/TestCase.h> + +namespace gr { + namespace analog { + + class qa_rotator : public CppUnit::TestCase + { + CPPUNIT_TEST_SUITE(qa_rotator); + CPPUNIT_TEST(t1); + CPPUNIT_TEST_SUITE_END(); + + private: + void t1(); + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* _QA_ANALOG_ROTATOR_H_ */ diff --git a/gr-analog/lib/qa_sincos.cc b/gr-analog/lib/qa_sincos.cc new file mode 100644 index 000000000..62642c117 --- /dev/null +++ b/gr-analog/lib/qa_sincos.cc @@ -0,0 +1,75 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <qa_sincos.h> +#include <analog/sincos.h> +#include <gruel/attributes.h> +#include <cppunit/TestAssert.h> +#include <cmath> + +namespace gr { + namespace analog { + + void + qa_sincos::t1() + { + static const unsigned int N = 1000; + double c_sin, c_cos; + double gr_sin, gr_cos; + + for(unsigned i = 0; i < N; i++) { + double x = i/100.0; + c_sin = sin(x); + c_cos = cos(x); + + analog::sincos(x, &gr_sin, &gr_cos); + + CPPUNIT_ASSERT_DOUBLES_EQUAL(c_sin, gr_sin, 0.0001); + CPPUNIT_ASSERT_DOUBLES_EQUAL(c_cos, gr_cos, 0.0001); + } + } + + void + qa_sincos::t2() + { + static const unsigned int N = 1000; + float c_sin, c_cos; + float gr_sin, gr_cos; + + for(unsigned i = 0; i < N; i++) { + float x = i/100.0; + c_sin = sinf(x); + c_cos = cosf(x); + + analog::sincosf(x, &gr_sin, &gr_cos); + + CPPUNIT_ASSERT_DOUBLES_EQUAL(c_sin, gr_sin, 0.0001); + CPPUNIT_ASSERT_DOUBLES_EQUAL(c_cos, gr_cos, 0.0001); + } + } + + } /* namespace analog */ +} /* namespace gr */ diff --git a/gr-analog/lib/qa_sincos.h b/gr-analog/lib/qa_sincos.h new file mode 100644 index 000000000..f18e879dd --- /dev/null +++ b/gr-analog/lib/qa_sincos.h @@ -0,0 +1,47 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef _QA_ANALOG_SINCOS_H_ +#define _QA_ANALOG_SINCOS_H_ + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/TestCase.h> + +namespace gr { + namespace analog { + + class qa_sincos : public CppUnit::TestCase + { + CPPUNIT_TEST_SUITE(qa_sincos); + CPPUNIT_TEST(t1); + CPPUNIT_TEST(t2); + CPPUNIT_TEST_SUITE_END(); + + private: + void t1(); + void t2(); + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* _QA_ANALOG_SINCOS_H_ */ diff --git a/gr-analog/lib/quadrature_demod_cf_impl.cc b/gr-analog/lib/quadrature_demod_cf_impl.cc new file mode 100644 index 000000000..9490ba6be --- /dev/null +++ b/gr-analog/lib/quadrature_demod_cf_impl.cc @@ -0,0 +1,72 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2005,2010,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "quadrature_demod_cf_impl.h" +#include <gr_io_signature.h> +#include <gr_math.h> + +namespace gr { + namespace analog { + + quadrature_demod_cf::sptr + quadrature_demod_cf::make(float gain) + { + return gnuradio::get_initial_sptr + (new quadrature_demod_cf_impl(gain)); + } + + quadrature_demod_cf_impl::quadrature_demod_cf_impl(float gain) + : gr_sync_block("quadrature_demod_cf", + gr_make_io_signature(1, 1, sizeof(gr_complex)), + gr_make_io_signature(1, 1, sizeof(float))), + d_gain(gain) + { + set_history(2); // we need to look at the previous value + } + + quadrature_demod_cf_impl::~quadrature_demod_cf_impl() + { + } + + int + quadrature_demod_cf_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + gr_complex *in = (gr_complex*)input_items[0]; + float *out = (float*)output_items[0]; + in++; // ensure that in[-1] is valid + + for(int i = 0; i < noutput_items; i++) { + gr_complex product = in[i] * conj(in[i-1]); + out[i] = d_gain * gr_fast_atan2f(imag(product), real(product)); + } + + return noutput_items; + } + + } /* namespace analog */ +} /* namespace gr */ diff --git a/gr-analog/lib/quadrature_demod_cf_impl.h b/gr-analog/lib/quadrature_demod_cf_impl.h new file mode 100644 index 000000000..72beb2331 --- /dev/null +++ b/gr-analog/lib/quadrature_demod_cf_impl.h @@ -0,0 +1,51 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ANALOG_QUADRATURE_DEMOD_CF_IMPL_H +#define INCLUDED_ANALOG_QUADRATURE_DEMOD_CF_IMPL_H + +#include <analog/quadrature_demod_cf.h> + +namespace gr { + namespace analog { + + class quadrature_demod_cf_impl : public quadrature_demod_cf + { + private: + float d_gain; + + public: + quadrature_demod_cf_impl(float gain); + ~quadrature_demod_cf_impl(); + + void set_gain(float gain) { d_gain = gain; } + float gain() const { return d_gain; } + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_QUADRATURE_DEMOD_CF_IMPL_H */ diff --git a/gr-analog/lib/rail_ff_impl.cc b/gr-analog/lib/rail_ff_impl.cc new file mode 100644 index 000000000..106c6353a --- /dev/null +++ b/gr-analog/lib/rail_ff_impl.cc @@ -0,0 +1,91 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2010,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "rail_ff_impl.h" +#include <gr_io_signature.h> +#include <gr_math.h> + +namespace gr { + namespace analog { + + rail_ff::sptr + rail_ff::make(float lo, float hi) + { + return gnuradio::get_initial_sptr + (new rail_ff_impl(lo, hi)); + } + + rail_ff_impl::rail_ff_impl(float lo, float hi) + : gr_sync_block("rail_ff", + gr_make_io_signature(1, 1, sizeof(float)), + gr_make_io_signature(1, 1, sizeof(float))), + d_lo(lo), d_hi(hi) + { + set_clipping(); + } + + rail_ff_impl::~rail_ff_impl() + { + } + + void + rail_ff_impl::set_lo(float lo) + { + d_lo = lo; + set_clipping(); + } + + void + rail_ff_impl::set_hi(float hi) + { + d_hi = hi; + set_clipping(); + } + + void + rail_ff_impl::set_clipping() + { + d_mid = (d_lo + d_hi)/2; + d_clip = d_hi - d_mid; + } + + int + rail_ff_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const float *in = (const float*)input_items[0]; + float *out = (float*)output_items[0]; + + for(int i = 0; i < noutput_items; i++) { + out[i] = d_mid + gr_branchless_clip(in[i] - d_mid, d_clip); + } + + return noutput_items; + } + + } /* namespace analog */ +} /* namespace gr */ diff --git a/gr-analog/lib/rail_ff_impl.h b/gr-analog/lib/rail_ff_impl.h new file mode 100644 index 000000000..436b10b41 --- /dev/null +++ b/gr-analog/lib/rail_ff_impl.h @@ -0,0 +1,57 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ANALOG_RAIL_FF_IMPL_H +#define INCLUDED_ANALOG_RAIL_FF_IMPL_H + +#include <analog/rail_ff.h> + +namespace gr { + namespace analog { + + class rail_ff_impl : public rail_ff + { + private: + float d_lo, d_hi; + float d_mid, d_clip; + + void set_clipping(); + + public: + rail_ff_impl(float lo, float hi); + ~rail_ff_impl(); + + float lo() const { return d_lo; } + float hi() const { return d_hi; } + + void set_lo(float lo); + void set_hi(float hi); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_RAIL_FF_IMPL_H */ diff --git a/gr-analog/lib/sig_source_X_impl.cc.t b/gr-analog/lib/sig_source_X_impl.cc.t new file mode 100644 index 000000000..60653dc1b --- /dev/null +++ b/gr-analog/lib/sig_source_X_impl.cc.t @@ -0,0 +1,253 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2010,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +/* @WARNING@ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "@IMPL_NAME@.h" +#include <algorithm> +#include <gr_io_signature.h> +#include <stdexcept> +#include <algorithm> +#include <gr_complex.h> + +namespace gr { + namespace analog { + + @BASE_NAME@::sptr + @BASE_NAME@::make(double sampling_freq, gr_waveform_t waveform, + double frequency, double ampl, @TYPE@ offset) + { + return gnuradio::get_initial_sptr + (new @IMPL_NAME@(sampling_freq, waveform, frequency, ampl, offset)); + } + + @IMPL_NAME@::@IMPL_NAME@(double sampling_freq, gr_waveform_t waveform, + double frequency, double ampl, @TYPE@ offset) + : gr_sync_block("@BASE_NAME@", + gr_make_io_signature(0, 0, 0), + gr_make_io_signature(1, 1, sizeof(@TYPE@))), + d_sampling_freq(sampling_freq), d_waveform(waveform), + d_frequency(frequency), d_ampl(ampl), d_offset(offset) + { + d_nco.set_freq(2 * M_PI * d_frequency / d_sampling_freq); + } + + @IMPL_NAME@::~@IMPL_NAME@() + { + } + + int + @IMPL_NAME@::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + @TYPE@ *optr = (@TYPE@*)output_items[0]; + @TYPE@ t; + + switch(d_waveform) { + +#if @IS_COMPLEX@ // complex? + + case GR_CONST_WAVE: + t = (gr_complex) d_ampl + d_offset; + std::fill_n(optr, noutput_items, t); + break; + + case GR_SIN_WAVE: + case GR_COS_WAVE: + d_nco.sincos(optr, noutput_items, d_ampl); + if(d_offset == gr_complex(0,0)) + break; + + for(int i = 0; i < noutput_items; i++) { + optr[i] += d_offset; + } + break; + + /* Implements a real square wave high from -PI to 0. + * The imaginary square wave leads by 90 deg. + */ + case GR_SQR_WAVE: + for(int i = 0; i < noutput_items; i++) { + if(d_nco.get_phase() < -1*M_PI/2) + optr[i] = gr_complex(d_ampl, 0) + d_offset; + else if(d_nco.get_phase() < 0) + optr[i] = gr_complex(d_ampl, d_ampl) + d_offset; + else if(d_nco.get_phase() < M_PI/2) + optr[i] = gr_complex(0, d_ampl) + d_offset; + else + optr[i] = d_offset; + d_nco.step(); + } + break; + + /* Implements a real triangle wave rising from -PI to 0 and + * falling from 0 to PI. The imaginary triangle wave leads by + * 90 deg. + */ + case GR_TRI_WAVE: + for(int i = 0; i < noutput_items; i++) { + if(d_nco.get_phase() < -1*M_PI/2){ + optr[i] = gr_complex(d_ampl*d_nco.get_phase()/M_PI + d_ampl, + -1*d_ampl*d_nco.get_phase()/M_PI - d_ampl/2) + d_offset; + } + else if(d_nco.get_phase() < 0) { + optr[i] = gr_complex(d_ampl*d_nco.get_phase()/M_PI + d_ampl, + d_ampl*d_nco.get_phase()/M_PI + d_ampl/2) + d_offset; + } + else if(d_nco.get_phase() < M_PI/2) { + optr[i] = gr_complex(-1*d_ampl*d_nco.get_phase()/M_PI + d_ampl, + d_ampl*d_nco.get_phase()/M_PI + d_ampl/2) + d_offset; + } + else { + optr[i] = gr_complex(-1*d_ampl*d_nco.get_phase()/M_PI + d_ampl, + -1*d_ampl*d_nco.get_phase()/M_PI + 3*d_ampl/2) + d_offset; + } + d_nco.step(); + } + break; + + /* Implements a real saw tooth wave rising from -PI to PI. + * The imaginary saw tooth wave leads by 90 deg. + */ + case GR_SAW_WAVE: + for(int i = 0; i < noutput_items; i++) { + if(d_nco.get_phase() < -1*M_PI/2) { + optr[i] = gr_complex(d_ampl*d_nco.get_phase()/(2*M_PI) + d_ampl/2, + d_ampl*d_nco.get_phase()/(2*M_PI) + 5*d_ampl/4) + d_offset; + } + else { + optr[i] = gr_complex(d_ampl*d_nco.get_phase()/(2*M_PI) + d_ampl/2, + d_ampl*d_nco.get_phase()/(2*M_PI) + d_ampl/4) + d_offset; + } + d_nco.step(); + } + break; + +#else // nope... + + case GR_CONST_WAVE: + t = (@TYPE@)d_ampl + d_offset; + std::fill_n(optr, noutput_items, t); + break; + + case GR_SIN_WAVE: + d_nco.sin(optr, noutput_items, d_ampl); + if(d_offset == 0) + break; + + for(int i = 0; i < noutput_items; i++) { + optr[i] += d_offset; + } + break; + + case GR_COS_WAVE: + d_nco.cos(optr, noutput_items, d_ampl); + if(d_offset == 0) + break; + + for(int i = 0; i < noutput_items; i++) { + optr[i] += d_offset; + } + break; + + /* The square wave is high from -PI to 0. */ + case GR_SQR_WAVE: + t = (@TYPE@)d_ampl + d_offset; + for(int i = 0; i < noutput_items; i++) { + if(d_nco.get_phase() < 0) + optr[i] = t; + else + optr[i] = d_offset; + d_nco.step(); + } + break; + + /* The triangle wave rises from -PI to 0 and falls from 0 to PI. */ + case GR_TRI_WAVE: + for(int i = 0; i < noutput_items; i++) { + double t = d_ampl*d_nco.get_phase()/M_PI; + if (d_nco.get_phase() < 0) + optr[i] = static_cast<@TYPE@>(t + d_ampl + d_offset); + else + optr[i] = static_cast<@TYPE@>(-1*t + d_ampl + d_offset); + d_nco.step(); + } + break; + + /* The saw tooth wave rises from -PI to PI. */ + case GR_SAW_WAVE: + for(int i = 0; i < noutput_items; i++) { + t = static_cast<@TYPE@>(d_ampl*d_nco.get_phase()/(2*M_PI) + + d_ampl/2 + d_offset); + optr[i] = t; + d_nco.step(); + } + break; + +#endif + + default: + throw std::runtime_error("gr_sig_source: invalid waveform"); + } + + return noutput_items; + } + + void + @NAME@::set_sampling_freq(double sampling_freq) + { + d_sampling_freq = sampling_freq; + d_nco.set_freq (2 * M_PI * d_frequency / d_sampling_freq); + } + + void + @NAME@::set_waveform(gr_waveform_t waveform) + { + d_waveform = waveform; + } + + void + @NAME@::set_frequency(double frequency) + { + d_frequency = frequency; + d_nco.set_freq(2 * M_PI * d_frequency / d_sampling_freq); + } + + void + @NAME@::set_amplitude(double ampl) + { + d_ampl = ampl; + } + + void + @NAME@::set_offset(@TYPE@ offset) + { + d_offset = offset; + } + + } /* namespace analog */ +} /* namespace gr */ diff --git a/gr-analog/lib/sig_source_X_impl.h.t b/gr-analog/lib/sig_source_X_impl.h.t new file mode 100644 index 000000000..50f179127 --- /dev/null +++ b/gr-analog/lib/sig_source_X_impl.h.t @@ -0,0 +1,70 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +/* @WARNING@ */ + +#ifndef @GUARD_NAME@ +#define @GUARD_NAME@ + +#include <analog/@BASE_NAME@.h> +#include <gr_sync_block.h> +#include <gr_fxpt_nco.h> + +namespace gr { + namespace analog { + + class @IMPL_NAME@ : public @BASE_NAME@ + { + private: + double d_sampling_freq; + gr_waveform_t d_waveform; + double d_frequency; + double d_ampl; + @TYPE@ d_offset; + gr_fxpt_nco d_nco; + + public: + @IMPL_NAME@(double sampling_freq, gr_waveform_t waveform, + double wave_freq, double ampl, @TYPE@ offset = 0); + ~@IMPL_NAME@(); + + virtual int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + + double sampling_freq() const { return d_sampling_freq; } + gr_waveform_t waveform() const { return d_waveform; } + double frequency() const { return d_frequency; } + double amplitude() const { return d_ampl; } + @TYPE@ offset() const { return d_offset; } + + void set_sampling_freq(double sampling_freq); + void set_waveform(gr_waveform_t waveform); + void set_frequency(double frequency); + void set_amplitude(double ampl); + void set_offset(@TYPE@ offset); + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* @GUARD_NAME@ */ diff --git a/gr-analog/lib/simple_squelch_cc_impl.cc b/gr-analog/lib/simple_squelch_cc_impl.cc new file mode 100644 index 000000000..02ccc535d --- /dev/null +++ b/gr-analog/lib/simple_squelch_cc_impl.cc @@ -0,0 +1,106 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2010,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "simple_squelch_cc_impl.h" +#include <gr_io_signature.h> +#include <cmath> + +namespace gr { + namespace analog { + + simple_squelch_cc::sptr + simple_squelch_cc::make(double threshold_db, double alpha) + { + return gnuradio::get_initial_sptr + (new simple_squelch_cc_impl(threshold_db, alpha)); + } + + simple_squelch_cc_impl::simple_squelch_cc_impl(double threshold_db, double alpha) + : gr_sync_block("simple_squelch_cc", + gr_make_io_signature(1, 1, sizeof(gr_complex)), + gr_make_io_signature(1, 1, sizeof(gr_complex))), + d_unmuted(false), d_iir(alpha) + { + set_threshold(threshold_db); + } + + simple_squelch_cc_impl::~simple_squelch_cc_impl() + { + } + + void + simple_squelch_cc_impl::set_threshold(double decibels) + { + // convert to absolute threshold (mag squared) + d_threshold = std::pow(10.0, decibels/10); + } + + double + simple_squelch_cc_impl::threshold() const + { + return 10 * log10(d_threshold); + } + + void + simple_squelch_cc_impl::set_alpha(double alpha) + { + d_iir.set_taps(alpha); + } + + std::vector<float> + simple_squelch_cc_impl::squelch_range() const + { + std::vector<float> r(3); + r[0] = -50.0; // min FIXME + r[1] = +50.0; // max FIXME + r[2] = (r[1] - r[0]) / 100; // step size + + return r; + } + + int + simple_squelch_cc_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const gr_complex *in = (const gr_complex*)input_items[0]; + gr_complex *out = (gr_complex*)output_items[0]; + + for(int i = 0; i < noutput_items; i++) { + double mag_sqrd = in[i].real()*in[i].real() + in[i].imag()*in[i].imag(); + double f = d_iir.filter(mag_sqrd); + if(f >= d_threshold) + out[i] = in[i]; + else + out[i] = 0; + } + + d_unmuted = d_iir.prev_output() >= d_threshold; + return noutput_items; + } + + } /* namespace analog */ +} /* namespace gr */ diff --git a/gr-analog/lib/simple_squelch_cc_impl.h b/gr-analog/lib/simple_squelch_cc_impl.h new file mode 100644 index 000000000..ba11de91e --- /dev/null +++ b/gr-analog/lib/simple_squelch_cc_impl.h @@ -0,0 +1,59 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ANALOG_SIMPLE_SQUELCH_CC_IMPL_H +#define INCLUDED_ANALOG_SIMPLE_SQUELCH_CC_IMPL_H + +#include <analog/simple_squelch_cc.h> +#include <filter/single_pole_iir.h> + +namespace gr { + namespace analog { + + class simple_squelch_cc_impl : public simple_squelch_cc + { + private: + double d_threshold; + bool d_unmuted; + filter::single_pole_iir<double,double,double> d_iir; + + public: + simple_squelch_cc_impl(double threshold_db, double alpha); + ~simple_squelch_cc_impl(); + + bool unmuted() const { return d_unmuted; } + + void set_alpha(double alpha); + void set_threshold(double decibels); + + double threshold() const; + std::vector<float> squelch_range() const; + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_SIMPLE_SQUELCH_CC_IMPL_H */ diff --git a/gr-analog/lib/sincos.cc b/gr-analog/lib/sincos.cc new file mode 100644 index 000000000..14ceeb3a2 --- /dev/null +++ b/gr-analog/lib/sincos.cc @@ -0,0 +1,89 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2010,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE // ask for GNU extensions if available +#endif + +#include <analog/sincos.h> +#include <math.h> + +namespace gr { + namespace analog { + +// ---------------------------------------------------------------- + +#if defined (HAVE_SINCOS) + + void + sincos(double x, double *sinx, double *cosx) + { + ::sincos(x, sinx, cosx); + } + +#else + + void + sincos(double x, double *sinx, double *cosx) + { + *sinx = sin(x); + *cosx = cos(x); + } + +#endif + +// ---------------------------------------------------------------- + +#if defined (HAVE_SINCOSF) + + void + sincosf(float x, float *sinx, float *cosx) + { + sincosf(x, sinx, cosx); + } + +#elif defined (HAVE_SINF) && defined (HAVE_COSF) + + void + sincosf(float x, float *sinx, float *cosx) + { + *sinx = sinf(x); + *cosx = cosf(x); + } + +#else + + void + sincosf(float x, float *sinx, float *cosx) + { + *sinx = sin(x); + *cosx = cos(x); + } + +#endif + + } /* namespace analog */ +} /* namespace gr */ diff --git a/gr-analog/lib/squelch_base_cc_impl.cc b/gr-analog/lib/squelch_base_cc_impl.cc new file mode 100644 index 000000000..cba7b30db --- /dev/null +++ b/gr-analog/lib/squelch_base_cc_impl.cc @@ -0,0 +1,140 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2006,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "squelch_base_cc_impl.h" +#include <gr_io_signature.h> + +namespace gr { + namespace analog { + + squelch_base_cc_impl::squelch_base_cc_impl(const char *name, int ramp, bool gate) + : gr_block(name, + gr_make_io_signature(1, 1, sizeof(float)), + gr_make_io_signature(1, 1, sizeof(float))) + { + set_ramp(ramp); + set_gate(gate); + d_state = ST_MUTED; + d_envelope = d_ramp ? 0.0 : 1.0; + d_ramped = 0; + } + + squelch_base_cc_impl::~squelch_base_cc_impl() + { + } + + int + squelch_base_cc_impl::ramp() const + { + return d_ramp; + } + + void + squelch_base_cc_impl::set_ramp(int ramp) + { + d_ramp = ramp; + } + + bool + squelch_base_cc_impl::gate() const + { + return d_gate; + } + + void + squelch_base_cc_impl::set_gate(bool gate) + { + d_gate = gate; + } + + bool + squelch_base_cc_impl::unmuted() const + { + return (d_state == ST_UNMUTED || d_state == ST_ATTACK); + } + + int + squelch_base_cc_impl::general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const gr_complex *in = (const gr_complex *) input_items[0]; + gr_complex *out = (gr_complex *) output_items[0]; + + int j = 0; + + for(int i = 0; i < noutput_items; i++) { + update_state(in[i]); + + // Adjust envelope based on current state + switch(d_state) { + case ST_MUTED: + if(!mute()) { + d_state = d_ramp ? ST_ATTACK : ST_UNMUTED; // If not ramping, go straight to unmuted + } + break; + + case ST_UNMUTED: + if(mute()) { + d_state = d_ramp ? ST_DECAY : ST_MUTED; // If not ramping, go straight to muted + } + break; + + case ST_ATTACK: + d_envelope = 0.5-std::cos(M_PI*(++d_ramped)/d_ramp)/2.0; // FIXME: precalculate window for speed + if(d_ramped >= d_ramp) { // use >= in case d_ramp is set to lower value elsewhere + d_state = ST_UNMUTED; + d_envelope = 1.0; + } + break; + + case ST_DECAY: + d_envelope = 0.5-std::cos(M_PI*(--d_ramped)/d_ramp)/2.0; // FIXME: precalculate window for speed + if(d_ramped == 0.0) { + d_state = ST_MUTED; + } + break; + }; + + // If unmuted, copy input times envelope to output + // Otherwise, if not gating, copy zero to output + if(d_state != ST_MUTED) { + out[j++] = in[i]*gr_complex(d_envelope, 0.0); + } + else { + if(!d_gate) { + out[j++] = 0.0; + } + } + } + + consume_each(noutput_items); // Use all the inputs + return j; // But only report outputs copied + } + + } /* namespace analog */ +} /* namespace gr */ diff --git a/gr-analog/lib/squelch_base_cc_impl.h b/gr-analog/lib/squelch_base_cc_impl.h new file mode 100644 index 000000000..19dccaa10 --- /dev/null +++ b/gr-analog/lib/squelch_base_cc_impl.h @@ -0,0 +1,65 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_SQUELCH_BASE_CC_IMPL_H +#define INCLUDED_GR_SQUELCH_BASE_CC_IMPL_H + +#include <analog/squelch_base_cc.h> + +namespace gr { + namespace analog { + + class squelch_base_cc_impl : public squelch_base_cc + { + private: + int d_ramp; + int d_ramped; + bool d_gate; + double d_envelope; + enum { ST_MUTED, ST_ATTACK, ST_UNMUTED, ST_DECAY } d_state; + + protected: + virtual void update_state(const gr_complex &sample) {}; + virtual bool mute() const { return false; }; + + public: + squelch_base_cc_impl(const char *name, int ramp, bool gate); + ~squelch_base_cc_impl(); + + int ramp() const; + void set_ramp(int ramp); + bool gate() const; + void set_gate(bool gate); + bool unmuted() const; + + virtual std::vector<float> squelch_range() const = 0; + + int general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_SQUELCH_BASE_IMPL_FF_H */ diff --git a/gr-analog/lib/squelch_base_ff_impl.cc b/gr-analog/lib/squelch_base_ff_impl.cc new file mode 100644 index 000000000..f9f07d36d --- /dev/null +++ b/gr-analog/lib/squelch_base_ff_impl.cc @@ -0,0 +1,140 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2006,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "squelch_base_ff_impl.h" +#include <gr_io_signature.h> + +namespace gr { + namespace analog { + + squelch_base_ff_impl::squelch_base_ff_impl(const char *name, int ramp, bool gate) + : gr_block(name, + gr_make_io_signature(1, 1, sizeof(float)), + gr_make_io_signature(1, 1, sizeof(float))) + { + set_ramp(ramp); + set_gate(gate); + d_state = ST_MUTED; + d_envelope = d_ramp ? 0.0 : 1.0; + d_ramped = 0; + } + + squelch_base_ff_impl::~squelch_base_ff_impl() + { + } + + int + squelch_base_ff_impl::ramp() const + { + return d_ramp; + } + + void + squelch_base_ff_impl::set_ramp(int ramp) + { + d_ramp = ramp; + } + + bool + squelch_base_ff_impl::gate() const + { + return d_gate; + } + + void + squelch_base_ff_impl::set_gate(bool gate) + { + d_gate = gate; + } + + bool + squelch_base_ff_impl::unmuted() const + { + return (d_state == ST_UNMUTED || d_state == ST_ATTACK); + } + + int + squelch_base_ff_impl::general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const float *in = (const float *) input_items[0]; + float *out = (float *) output_items[0]; + + int j = 0; + + for(int i = 0; i < noutput_items; i++) { + update_state(in[i]); + + // Adjust envelope based on current state + switch(d_state) { + case ST_MUTED: + if(!mute()) + // If not ramping, go straight to unmuted + d_state = d_ramp ? ST_ATTACK : ST_UNMUTED; + break; + + case ST_UNMUTED: + if(mute()) + // If not ramping, go straight to muted + d_state = d_ramp ? ST_DECAY : ST_MUTED; + break; + + case ST_ATTACK: + // FIXME: precalculate window for speed + d_envelope = 0.5-std::cos(M_PI*(++d_ramped)/d_ramp)/2.0; + + // use >= in case d_ramp is set to lower value elsewhere + if(d_ramped >= d_ramp) { + d_state = ST_UNMUTED; + d_envelope = 1.0; + } + break; + + case ST_DECAY: + // FIXME: precalculate window for speed + d_envelope = 0.5-std::cos(M_PI*(--d_ramped)/d_ramp)/2.0; + if(d_ramped == 0.0) + d_state = ST_MUTED; + break; + }; + + // If unmuted, copy input times envelope to output + // Otherwise, if not gating, copy zero to output + if(d_state != ST_MUTED) + out[j++] = in[i]*d_envelope; + else + if(!d_gate) + out[j++] = 0.0; + } + + consume_each(noutput_items); // Use all the inputs + return j; // But only report outputs copied + } + + } /* namespace analog */ +} /* namespace gr */ diff --git a/gr-analog/lib/squelch_base_ff_impl.h b/gr-analog/lib/squelch_base_ff_impl.h new file mode 100644 index 000000000..22659be74 --- /dev/null +++ b/gr-analog/lib/squelch_base_ff_impl.h @@ -0,0 +1,65 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_SQUELCH_BASE_FF_IMPL_H +#define INCLUDED_GR_SQUELCH_BASE_FF_IMPL_H + +#include <analog/squelch_base_ff.h> + +namespace gr { + namespace analog { + + class squelch_base_ff_impl : public squelch_base_ff + { + private: + int d_ramp; + int d_ramped; + bool d_gate; + double d_envelope; + enum { ST_MUTED, ST_ATTACK, ST_UNMUTED, ST_DECAY } d_state; + + protected: + virtual void update_state(const float &sample) {}; + virtual bool mute() const { return false; }; + + public: + squelch_base_ff_impl(const char *name, int ramp, bool gate); + ~squelch_base_ff_impl(); + + int ramp() const; + void set_ramp(int ramp); + bool gate() const; + void set_gate(bool gate); + bool unmuted() const; + + virtual std::vector<float> squelch_range() const = 0; + + int general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_SQUELCH_BASE_IMPL_FF_H */ diff --git a/gr-analog/lib/test_gr_analog.cc b/gr-analog/lib/test_gr_analog.cc new file mode 100644 index 000000000..00d624269 --- /dev/null +++ b/gr-analog/lib/test_gr_analog.cc @@ -0,0 +1,43 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include <cppunit/TextTestRunner.h> +#include <cppunit/XmlOutputter.h> + +#include <gr_unittests.h> +#include "qa_analog.h" +#include <iostream> + +int +main (int argc, char **argv) +{ + CppUnit::TextTestRunner runner; + std::ofstream xmlfile(get_unittest_path("gr_analog.xml").c_str()); + CppUnit::XmlOutputter *xmlout = new CppUnit::XmlOutputter(&runner.result(), xmlfile); + + runner.addTest(qa_gr_analog::suite()); + runner.setOutputter(xmlout); + + bool was_successful = runner.run("", false); + + return was_successful ? 0 : 1; +} diff --git a/gr-analog/python/CMakeLists.txt b/gr-analog/python/CMakeLists.txt new file mode 100644 index 000000000..1657e5bf3 --- /dev/null +++ b/gr-analog/python/CMakeLists.txt @@ -0,0 +1,51 @@ +# Copyright 212 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. + +######################################################################## +# Setup python install +######################################################################## +include(GrPython) + +GR_PYTHON_INSTALL( + FILES + __init__.py + DESTINATION ${GR_PYTHON_DIR}/gnuradio/analog + COMPONENT "analog_python" +) + +######################################################################## +# Handle the unit tests +######################################################################## +if(ENABLE_TESTING) + +list(APPEND GR_TEST_PYTHON_DIRS + ${CMAKE_BINARY_DIR}/gr-analog/python + ${CMAKE_BINARY_DIR}/gr-analog/swig + ${CMAKE_BINARY_DIR}/gr-filter/python + ${CMAKE_BINARY_DIR}/gr-filter/swig +) +list(APPEND GR_TEST_TARGET_DEPS gnuradio-analog gnuradio-filter gnuradio-fft) + +include(GrTest) +file(GLOB py_qa_test_files "qa_*.py") +foreach(py_qa_test_file ${py_qa_test_files}) + get_filename_component(py_qa_test_name ${py_qa_test_file} NAME_WE) + GR_ADD_TEST(${py_qa_test_name} ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B} ${py_qa_test_file}) +endforeach(py_qa_test_file) +endif(ENABLE_TESTING) diff --git a/gr-analog/python/__init__.py b/gr-analog/python/__init__.py new file mode 100644 index 000000000..fc345028b --- /dev/null +++ b/gr-analog/python/__init__.py @@ -0,0 +1,27 @@ +# Copyright 2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +''' +Blocks and utilities for analog modulation and demodulation. +''' + +# The presence of this file turns this directory into a Python package + +from analog_swig import * diff --git a/gr-analog/python/qa_agc.py b/gr-analog/python/qa_agc.py new file mode 100755 index 000000000..dc4922cf8 --- /dev/null +++ b/gr-analog/python/qa_agc.py @@ -0,0 +1,495 @@ +#!/usr/bin/env python +# +# Copyright 2004,2007,2010,2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, gr_unittest +import analog_swig as analog +import math + +test_output = False + +class test_agc (gr_unittest.TestCase): + + def setUp (self): + self.tb = gr.top_block () + + def tearDown (self): + self.tb = None + + + def test_001_sets(self): + agc = analog.agc_cc(1e-3, 1, 1, 1000) + + agc.set_rate(1) + agc.set_reference(1.1) + agc.set_gain(1.1) + agc.set_max_gain(100) + + self.assertAlmostEqual(agc.rate(), 1) + self.assertAlmostEqual(agc.reference(), 1.1) + self.assertAlmostEqual(agc.gain(), 1.1) + self.assertAlmostEqual(agc.max_gain(), 100) + + def test_001(self): + ''' Test the complex AGC loop (single rate input) ''' + tb = self.tb + + expected_result = ( + (100.000244140625+7.2191943445432116e-07j), + (72.892257690429688+52.959323883056641j), + (25.089065551757812+77.216217041015625j), + (-22.611061096191406+69.589706420898438j), + (-53.357715606689453+38.766635894775391j), + (-59.458671569824219+3.4792964243024471e-07j), + (-43.373462677001953-31.512666702270508j), + (-14.94139289855957-45.984889984130859j), + (13.478158950805664-41.48150634765625j), + (31.838506698608398-23.132022857666016j), + (35.519271850585938-3.1176801940091536e-07j), + (25.942903518676758+18.848621368408203j), + (8.9492912292480469+27.5430908203125j), + (-8.0852642059326172+24.883890151977539j), + (-19.131628036499023+13.899936676025391j), + (-21.383295059204102+3.1281737733479531e-07j), + (-15.650330543518066-11.370632171630859j), + (-5.4110145568847656-16.65339469909668j), + (4.9008159637451172-15.083160400390625j), + (11.628337860107422-8.4484796524047852j), + (13.036135673522949-2.288476110834381e-07j), + (9.5726661682128906+6.954948902130127j), + (3.3216962814331055+10.223132133483887j), + (-3.0204284191131592+9.2959251403808594j), + (-7.1977195739746094+5.2294478416442871j), + (-8.1072216033935547+1.8976157889483147e-07j), + (-5.9838657379150391-4.3475332260131836j), + (-2.0879747867584229-6.4261269569396973j), + (1.9100792407989502-5.8786196708679199j), + (4.5814824104309082-3.3286411762237549j), + (5.1967458724975586-1.3684227440080576e-07j), + (3.8647139072418213+2.8078789710998535j), + (1.3594740629196167+4.1840314865112305j), + (-1.2544282674789429+3.8607344627380371j), + (-3.0366206169128418+2.2062335014343262j), + (-3.4781389236450195+1.1194014604143376e-07j), + (-2.6133756637573242-1.8987287282943726j), + (-0.9293016791343689-2.8600969314575195j), + (0.86727333068847656-2.6691930294036865j), + (2.1243946552276611-1.5434627532958984j), + (2.4633183479309082-8.6486437567145913e-08j), + (1.8744727373123169+1.3618841171264648j), + (0.67528903484344482+2.0783262252807617j), + (-0.63866174221038818+1.965599536895752j), + (-1.5857341289520264+1.152103066444397j), + (-1.8640764951705933+7.6355092915036948e-08j), + (-1.4381576776504517-1.0448826551437378j), + (-0.52529704570770264-1.6166983842849731j), + (0.50366902351379395-1.5501341819763184j), + (1.26766037940979-0.92100900411605835j)) + + sampling_freq = 100 + src1 = gr.sig_source_c(sampling_freq, gr.GR_SIN_WAVE, + sampling_freq * 0.10, 100.0) + dst1 = gr.vector_sink_c() + head = gr.head(gr.sizeof_gr_complex, int (5*sampling_freq * 0.10)) + + agc = analog.agc_cc(1e-3, 1, 1, 1000) + + tb.connect(src1, head) + tb.connect(head, agc) + tb.connect(agc, dst1) + + if test_output == True: + tb.connect(agc, gr.file_sink(gr.sizeof_gr_complex, "test_agc_cc.dat")) + + tb.run() + dst_data = dst1.data() + self.assertComplexTuplesAlmostEqual(expected_result, dst_data, 4) + + def test_002_sets(self): + agc = analog.agc_ff(1e-3, 1, 1, 1000) + + agc.set_rate(1) + agc.set_reference(1.1) + agc.set_gain(1.1) + agc.set_max_gain(100) + + self.assertAlmostEqual(agc.rate(), 1) + self.assertAlmostEqual(agc.reference(), 1.1) + self.assertAlmostEqual(agc.gain(), 1.1) + self.assertAlmostEqual(agc.max_gain(), 100) + + def test_002(self): + ''' Test the floating point AGC loop (single rate input) ''' + tb = self.tb + + expected_result = ( + 7.2191943445432116e-07, + 58.837181091308594, + 89.700050354003906, + 81.264183044433594, + 45.506141662597656, + 4.269894304798072e-07, + -42.948936462402344, + -65.50335693359375, + -59.368724822998047, + -33.261005401611328, + -4.683740257860336e-07, + 31.423542022705078, + 47.950984954833984, + 43.485683441162109, + 24.378345489501953, + 5.7254135299444897e-07, + -23.062990188598633, + -35.218441009521484, + -31.964075088500977, + -17.934831619262695, + -5.0591745548445033e-07, + 16.998210906982422, + 25.982204437255859, + 23.606258392333984, + 13.260685920715332, + 4.9936483037527069e-07, + -12.59880542755127, + -19.28221321105957, + -17.54347038269043, + -9.8700437545776367, + -4.188150626305287e-07, + 9.4074573516845703, + 14.422011375427246, + 13.145503044128418, + 7.41046142578125, + 3.8512698097292741e-07, + -7.0924453735351562, + -10.896408081054688, + -9.9552040100097656, + -5.6262712478637695, + -3.1982864356905338e-07, + 5.4131259918212891, + 8.3389215469360352, + 7.6409502029418945, + 4.3320145606994629, + 2.882407841298118e-07, + -4.194943904876709, + -6.4837145805358887, + -5.9621825218200684, + -3.3931560516357422) + + sampling_freq = 100 + src1 = gr.sig_source_f (sampling_freq, gr.GR_SIN_WAVE, + sampling_freq * 0.10, 100.0) + dst1 = gr.vector_sink_f () + head = gr.head (gr.sizeof_float, int (5*sampling_freq * 0.10)) + + agc = analog.agc_ff(1e-3, 1, 1, 1000) + + tb.connect (src1, head) + tb.connect (head, agc) + tb.connect (agc, dst1) + + if test_output == True: + tb.connect (agc, gr.file_sink(gr.sizeof_float, "test_agc_ff.dat")) + + tb.run () + dst_data = dst1.data () + self.assertFloatTuplesAlmostEqual (expected_result, dst_data, 4) + + def test_003_sets(self): + agc = analog.agc2_cc(1e-3, 1e-1, 1, 1, 1000) + + agc.set_attack_rate(1) + agc.set_decay_rate(2) + agc.set_reference(1.1) + agc.set_gain(1.1) + agc.set_max_gain(100) + + self.assertAlmostEqual(agc.attack_rate(), 1) + self.assertAlmostEqual(agc.decay_rate(), 2) + self.assertAlmostEqual(agc.reference(), 1.1) + self.assertAlmostEqual(agc.gain(), 1.1) + self.assertAlmostEqual(agc.max_gain(), 100) + + def test_003(self): + ''' Test the complex AGC loop (attack and decay rate inputs) ''' + tb = self.tb + + expected_result = \ + ((100.000244140625+7.2191943445432116e-07j), + (0.80881959199905396+0.58764183521270752j), + (0.30894950032234192+0.95084899663925171j), + (-0.30895623564720154+0.95086973905563354j), + (-0.80887287855148315+0.58768033981323242j), + (-0.99984413385391235+5.850709250410091e-09j), + (-0.80889981985092163-0.58770018815994263j), + (-0.30897706747055054-0.95093393325805664j), + (0.30898112058639526-0.95094609260559082j), + (0.80893135070800781-0.58772283792495728j), + (0.99990922212600708-8.7766354184282136e-09j), + (0.80894720554351807+0.58773452043533325j), + (0.30899339914321899+0.95098406076431274j), + (-0.30899572372436523+0.95099133253097534j), + (-0.80896598100662231+0.58774799108505249j), + (-0.99994778633117676+1.4628290578855285e-08j), + (-0.80897533893585205-0.58775502443313599j), + (-0.30900305509567261-0.95101380348205566j), + (0.30900448560714722-0.95101797580718994j), + (0.80898630619049072-0.58776277303695679j), + (0.99997037649154663-1.7554345532744264e-08j), + (0.80899184942245483+0.58776694536209106j), + (0.30900871753692627+0.95103120803833008j), + (-0.30900952219963074+0.95103377103805542j), + (-0.8089984655380249+0.58777159452438354j), + (-0.99998390674591064+2.3406109050938539e-08j), + (-0.809001624584198-0.58777409791946411j), + (-0.30901208519935608-0.95104163885116577j), + (0.30901262164115906-0.95104306936264038j), + (0.80900543928146362-0.587776780128479j), + (0.99999171495437622-2.6332081404234486e-08j), + (0.80900734663009644+0.58777821063995361j), + (0.30901408195495605+0.95104765892028809j), + (-0.30901429057121277+0.95104855298995972j), + (-0.80900967121124268+0.58777981996536255j), + (-0.99999648332595825+3.2183805842578295e-08j), + (-0.80901080369949341-0.58778077363967896j), + (-0.30901527404785156-0.95105135440826416j), + (0.30901545286178589-0.95105189085006714j), + (0.80901217460632324-0.58778166770935059j), + (0.99999916553497314-3.5109700036173308e-08j), + (0.809012770652771+0.58778214454650879j), + (0.30901595950126648+0.9510534405708313j), + (-0.30901598930358887+0.95105385780334473j), + (-0.80901366472244263+0.58778274059295654j), + (-1.0000008344650269+4.0961388947380328e-08j), + (-0.8090139627456665-0.58778303861618042j), + (-0.30901634693145752-0.95105475187301636j), + (0.30901640653610229-0.95105493068695068j), + (0.80901449918746948-0.5877833366394043j)) + + sampling_freq = 100 + src1 = gr.sig_source_c(sampling_freq, gr.GR_SIN_WAVE, + sampling_freq * 0.10, 100) + dst1 = gr.vector_sink_c() + head = gr.head(gr.sizeof_gr_complex, int(5*sampling_freq * 0.10)) + + agc = analog.agc2_cc(1e-2, 1e-3, 1, 1, 1000) + + tb.connect(src1, head) + tb.connect(head, agc) + tb.connect(agc, dst1) + + if test_output == True: + tb.connect(agc, gr.file_sink(gr.sizeof_gr_complex, "test_agc2_cc.dat")) + + tb.run() + dst_data = dst1.data() + self.assertComplexTuplesAlmostEqual(expected_result, dst_data, 4) + + def test_004_sets(self): + agc = analog.agc2_ff(1e-3, 1e-1, 1, 1, 1000) + + agc.set_attack_rate(1) + agc.set_decay_rate(2) + agc.set_reference(1.1) + agc.set_gain(1.1) + agc.set_max_gain(100) + + self.assertAlmostEqual(agc.attack_rate(), 1) + self.assertAlmostEqual(agc.decay_rate(), 2) + self.assertAlmostEqual(agc.reference(), 1.1) + self.assertAlmostEqual(agc.gain(), 1.1) + self.assertAlmostEqual(agc.max_gain(), 100) + + def test_004(self): + ''' Test the floating point AGC loop (attack and decay rate inputs) ''' + tb = self.tb + + expected_result = \ + (7.2191943445432116e-07, + 58.837181091308594, + 40.194305419921875, + 2.9183335304260254, + 0.67606079578399658, + 8.6260438791896377e-09, + -1.4542514085769653, + -1.9210131168365479, + -1.0450780391693115, + -0.61939650774002075, + -1.2590258613442984e-08, + 1.4308931827545166, + 1.9054338932037354, + 1.0443156957626343, + 0.61937344074249268, + 2.0983527804219193e-08, + -1.4308838844299316, + -1.9054274559020996, + -1.0443152189254761, + -0.61937344074249268, + -2.5180233009791664e-08, + 1.4308837652206421, + 1.9054274559020996, + 1.0443154573440552, + 0.61937344074249268, + 3.3573645197293445e-08, + -1.4308838844299316, + -1.9054274559020996, + -1.0443152189254761, + -0.61937350034713745, + -3.7770352179222755e-08, + 1.4308837652206421, + 1.9054274559020996, + 1.0443154573440552, + 0.61937350034713745, + 4.6163762590367696e-08, + -1.4308838844299316, + -1.9054274559020996, + -1.0443153381347656, + -0.61937344074249268, + -5.0360466019583328e-08, + 1.4308837652206421, + 1.9054274559020996, + 1.0443155765533447, + 0.61937344074249268, + 5.8753879983441948e-08, + -1.4308837652206421, + -1.9054274559020996, + -1.0443153381347656, + -0.61937344074249268) + + sampling_freq = 100 + src1 = gr.sig_source_f(sampling_freq, gr.GR_SIN_WAVE, + sampling_freq * 0.10, 100) + dst1 = gr.vector_sink_f() + head = gr.head(gr.sizeof_float, int(5*sampling_freq * 0.10)) + + agc = analog.agc2_ff(1e-2, 1e-3, 1, 1, 1000) + + tb.connect(src1, head) + tb.connect(head, agc) + tb.connect(agc, dst1) + + if test_output == True: + tb.connect(agc, gr.file_sink(gr.sizeof_float, "test_agc2_ff.dat")) + + tb.run() + dst_data = dst1.data() + self.assertFloatTuplesAlmostEqual(expected_result, dst_data, 4) + + + def test_005(self): + ''' Test the complex AGC loop (attack and decay rate inputs) ''' + tb = self.tb + + expected_result = \ + ((100.000244140625+7.2191943445432116e-07j), + (0.80881959199905396+0.58764183521270752j), + (0.30894950032234192+0.95084899663925171j), + (-0.30895623564720154+0.95086973905563354j), + (-0.80887287855148315+0.58768033981323242j), + (-0.99984413385391235+5.850709250410091e-09j), + (-0.80889981985092163-0.58770018815994263j), + (-0.30897706747055054-0.95093393325805664j), + (0.30898112058639526-0.95094609260559082j), + (0.80893135070800781-0.58772283792495728j), + (0.99990922212600708-8.7766354184282136e-09j), + (0.80894720554351807+0.58773452043533325j), + (0.30899339914321899+0.95098406076431274j), + (-0.30899572372436523+0.95099133253097534j), + (-0.80896598100662231+0.58774799108505249j), + (-0.99994778633117676+1.4628290578855285e-08j), + (-0.80897533893585205-0.58775502443313599j), + (-0.30900305509567261-0.95101380348205566j), + (0.30900448560714722-0.95101797580718994j), + (0.80898630619049072-0.58776277303695679j), + (0.99997037649154663-1.7554345532744264e-08j), + (0.80899184942245483+0.58776694536209106j), + (0.30900871753692627+0.95103120803833008j), + (-0.30900952219963074+0.95103377103805542j), + (-0.8089984655380249+0.58777159452438354j), + (-0.99998390674591064+2.3406109050938539e-08j), + (-0.809001624584198-0.58777409791946411j), + (-0.30901208519935608-0.95104163885116577j), + (0.30901262164115906-0.95104306936264038j), + (0.80900543928146362-0.587776780128479j), + (0.99999171495437622-2.6332081404234486e-08j), + (0.80900734663009644+0.58777821063995361j), + (0.30901408195495605+0.95104765892028809j), + (-0.30901429057121277+0.95104855298995972j), + (-0.80900967121124268+0.58777981996536255j), + (-0.99999648332595825+3.2183805842578295e-08j), + (-0.80901080369949341-0.58778077363967896j), + (-0.30901527404785156-0.95105135440826416j), + (0.30901545286178589-0.95105189085006714j), + (0.80901217460632324-0.58778166770935059j), + (0.99999916553497314-3.5109700036173308e-08j), + (0.809012770652771+0.58778214454650879j), + (0.30901595950126648+0.9510534405708313j), + (-0.30901598930358887+0.95105385780334473j), + (-0.80901366472244263+0.58778274059295654j), + (-1.0000008344650269+4.0961388947380328e-08j), + (-0.8090139627456665-0.58778303861618042j), + (-0.30901634693145752-0.95105475187301636j), + (0.30901640653610229-0.95105493068695068j), + (0.80901449918746948-0.5877833366394043j)) + + sampling_freq = 100 + src1 = gr.sig_source_c(sampling_freq, gr.GR_SIN_WAVE, + sampling_freq * 0.10, 100) + dst1 = gr.vector_sink_c() + head = gr.head(gr.sizeof_gr_complex, int(5*sampling_freq * 0.10)) + + agc = analog.agc2_cc(1e-2, 1e-3, 1, 1, 1000) + + tb.connect(src1, head) + tb.connect(head, agc) + tb.connect(agc, dst1) + + if test_output == True: + tb.connect(agc, gr.file_sink(gr.sizeof_gr_complex, "test_agc2_cc.dat")) + + tb.run() + dst_data = dst1.data() + self.assertComplexTuplesAlmostEqual(expected_result, dst_data, 4) + + def test_100(self): + ''' Test complex feedforward agc with constant input ''' + + length = 8 + gain = 2 + + input_data = 8*(0.0,) + 24*(1.0,) + 24*(0.0,) + expected_result = (8+length-1)*(0.0,) + 24*(gain*1.0,) + (0,) + + src = gr.vector_source_c(input_data) + agc = analog.feedforward_agc_cc(8, 2.0) + dst = gr.vector_sink_c() + self.tb.connect(src, agc, dst) + + if test_output == True: + self.tb.connect(agc, gr.file_sink(gr.sizeof_gr_complex, + "test_feedforward_cc.dat")) + + self.tb.run() + dst_data = dst.data()[0:len(expected_result)] + + self.assertComplexTuplesAlmostEqual(expected_result, dst_data, 4) + + +if __name__ == '__main__': + gr_unittest.run(test_agc, "test_agc.xml") diff --git a/gr-analog/python/qa_cpfsk.py b/gr-analog/python/qa_cpfsk.py new file mode 100755 index 000000000..decf94ea3 --- /dev/null +++ b/gr-analog/python/qa_cpfsk.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python +# +# Copyright 2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, gr_unittest +import analog_swig as analog +import math + +class test_cpfsk_bc(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_cpfsk_bc_001(self): + # Test set/gets + + op = analog.cpfsk_bc(2, 1, 2) + + op.set_amplitude(2) + a = op.amplitude() + self.assertEqual(2, a) + + freq = 2*math.pi/2.0 + f = op.freq() + self.assertAlmostEqual(freq, f, 5) + + p = op.phase() + self.assertEqual(0, p) + + def test_cpfsk_bc_002(self): + src_data = 10*[0, 1] + expected_result = map(lambda x: complex(2*x-1,0), src_data) + + src = gr.vector_source_b(src_data) + op = analog.cpfsk_bc(2, 1, 2) + dst = gr.vector_sink_c() + + self.tb.connect(src, op) + self.tb.connect(op, dst) + self.tb.run() + + result_data = dst.data()[0:len(expected_result)] + self.assertComplexTuplesAlmostEqual(expected_result, result_data, 4) + +if __name__ == '__main__': + gr_unittest.run(test_cpfsk_bc, "test_cpfsk_bc.xml") + diff --git a/gr-analog/python/qa_ctcss_squelch.py b/gr-analog/python/qa_ctcss_squelch.py new file mode 100755 index 000000000..08d3dbfef --- /dev/null +++ b/gr-analog/python/qa_ctcss_squelch.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python +# +# Copyright 2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, gr_unittest +import analog_swig as analog + +class test_ctcss_squelch(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_ctcss_squelch_001(self): + # Test set/gets + + rate = 1 + rate2 = 2 + freq = 100 + level = 0.5 + length = 1 + ramp = 1 + ramp2 = 2 + gate = True + gate2 = False + + op = analog.ctcss_squelch_ff(rate, freq, level, + length, ramp, gate) + + op.set_ramp(ramp2) + r = op.ramp() + self.assertEqual(ramp2, r) + + op.set_gate(gate2) + g = op.gate() + self.assertEqual(gate2, g) + + def test_ctcss_squelch_002(self): + # Test runtime, gate=True + rate = 1 + freq = 100 + level = 0.0 + length = 1 + ramp = 1 + gate = True + + src_data = map(lambda x: float(x)/10.0, range(1, 40)) + expected_result = src_data + expected_result[0] = 0 + + src = gr.vector_source_f(src_data) + op = analog.ctcss_squelch_ff(rate, freq, level, + length, ramp, gate) + dst = gr.vector_sink_f() + + self.tb.connect(src, op) + self.tb.connect(op, dst) + self.tb.run() + + result_data = dst.data() + self.assertFloatTuplesAlmostEqual(expected_result, result_data, 4) + + def test_ctcss_squelch_003(self): + # Test runtime, gate=False + rate = 1 + freq = 100 + level = 0.5 + length = 1 + ramp = 1 + gate = False + + src_data = map(lambda x: float(x)/10.0, range(1, 40)) + src = gr.vector_source_f(src_data) + op = analog.ctcss_squelch_ff(rate, freq, level, + length, ramp, gate) + dst = gr.vector_sink_f() + + self.tb.connect(src, op) + self.tb.connect(op, dst) + self.tb.run() + + expected_result = src_data + expected_result[0:5] = [0, 0, 0, 0, 0] + + result_data = dst.data() + self.assertFloatTuplesAlmostEqual(expected_result, result_data, 4) + +if __name__ == '__main__': + gr_unittest.run(test_ctcss_squelch, "test_ctcss_squelch.xml") + diff --git a/gr-analog/python/qa_dpll.py b/gr-analog/python/qa_dpll.py new file mode 100755 index 000000000..3ef8a6e28 --- /dev/null +++ b/gr-analog/python/qa_dpll.py @@ -0,0 +1,76 @@ +#!/usr/bin/env python +# +# Copyright 2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, gr_unittest +import analog_swig as analog +import math + +class test_dpll_bb(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_dpll_bb_001(self): + # Test set/gets + + period = 1.0 + gain = 0.1 + op = analog.dpll_bb(period, gain) + + op.set_gain(0.2) + g = op.gain() + self.assertAlmostEqual(g, 0.2) + + f = op.freq() + self.assertEqual(1/period, f) + + d0 = 1.0 - 0.5*f; + d1 = op.decision_threshold() + self.assertAlmostEqual(d0, d1) + + p = op.phase() + self.assertEqual(0, p) + + def test_dpll_bb_002(self): + period = 4 + gain = 0.1 + + src_data = 10*((period-1)*[0,] + [1,]) + expected_result = src_data + + src = gr.vector_source_b(src_data) + op = analog.dpll_bb(period, gain) + dst = gr.vector_sink_b() + + self.tb.connect(src, op) + self.tb.connect(op, dst) + self.tb.run() + + result_data = dst.data() + self.assertComplexTuplesAlmostEqual(expected_result, result_data, 4) + +if __name__ == '__main__': + gr_unittest.run(test_dpll_bb, "test_dpll_bb.xml") + diff --git a/gr-analog/python/qa_fmdet.py b/gr-analog/python/qa_fmdet.py new file mode 100755 index 000000000..b90ef2ffa --- /dev/null +++ b/gr-analog/python/qa_fmdet.py @@ -0,0 +1,80 @@ +#!/usr/bin/env python +# +# Copyright 2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, gr_unittest +import analog_swig as analog +import math + +class test_fmdet_cf(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_fmdet_cf_001(self): + # Test set/gets + + fh1 = 10 + fh2 = 20 + fl1 = 1 + fl2 = 2 + scale1 = 3 + scale2 = 4 + op = analog.fmdet_cf(1, fl1, fh1, scale1) + + op.set_freq_range(fl2, fh2) + lo = op.freq_low() + hi = op.freq_high() + f = op.freq() + self.assertEqual(fl2, lo) + self.assertEqual(fh2, hi) + self.assertEqual(0, f) + + op.set_scale(scale2) + s = op.scale() + b = op.bias() + eb = 0.5*scale2*(hi + lo) / (hi - lo); + self.assertEqual(scale2, s) + self.assertAlmostEqual(eb, b) + + # FIXME: This passes QA, but the it's only based off what the + # block is saying, not what the values should actually be. + def est_fmdet_cf_002(self): + N = 100 + src = gr.sig_source_c(1, gr.GR_SIN_WAVE, 0.2, 1) + head = gr.head(gr.sizeof_gr_complex, N) + op = analog.fmdet_cf(1, 0.1, 0.3, 0.1) + dst = gr.vector_sink_f() + + self.tb.connect(src, head, op) + self.tb.connect(op, dst) + self.tb.run() + + result_data = dst.data()[4:N] + expected_result = (100-4)*[-0.21755,] + self.assertFloatTuplesAlmostEqual(expected_result, result_data, 4) + +if __name__ == '__main__': + gr_unittest.run(test_fmdet_cf, "test_fmdet_cf.xml") + diff --git a/gr-analog/python/qa_frequency_modulator.py b/gr-analog/python/qa_frequency_modulator.py new file mode 100755 index 000000000..b673b3275 --- /dev/null +++ b/gr-analog/python/qa_frequency_modulator.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python +# +# Copyright 2004,2007,2010,2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, gr_unittest +import analog_swig as analog +import math + +def sincos(x): + return math.cos(x) + math.sin(x) * 1j + + +class test_frequency_modulator(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_fm_001(self): + pi = math.pi + sensitivity = pi/4 + src_data = (1.0/4, 1.0/2, 1.0/4, -1.0/4, -1.0/2, -1/4.0) + running_sum = (pi/16, 3*pi/16, pi/4, 3*pi/16, pi/16, 0) + expected_result = tuple([sincos(x) for x in running_sum]) + src = gr.vector_source_f(src_data) + op = analog.frequency_modulator_fc(sensitivity) + dst = gr.vector_sink_c() + self.tb.connect(src, op) + self.tb.connect(op, dst) + self.tb.run() + result_data = dst.data() + self.assertComplexTuplesAlmostEqual(expected_result, result_data, 5) + +if __name__ == '__main__': + gr_unittest.run(test_frequency_modulator, "test_frequency_modulator.xml") + diff --git a/gr-analog/python/qa_lfsr.py b/gr-analog/python/qa_lfsr.py new file mode 100755 index 000000000..2a8167a57 --- /dev/null +++ b/gr-analog/python/qa_lfsr.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python +# +# Copyright 2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, gr_unittest +import analog_swig as analog +import math + + +class test_lfsr(gr_unittest.TestCase): + + def setUp(self): + pass + + def tearDown(self): + pass + + def test_lfsr_001(self): + reglen = 8 + l = analog.lfsr(1, 1, reglen) + + result_data = [] + for i in xrange(4*(reglen+1)): + result_data.append(l.next_bit()) + + expected_result = 4*([1,] + reglen*[0,]) + self.assertFloatTuplesAlmostEqual(expected_result, result_data, 5) + +if __name__ == '__main__': + gr_unittest.run(test_lfsr, "test_lfsr.xml") + diff --git a/gr-analog/python/qa_noise.py b/gr-analog/python/qa_noise.py new file mode 100755 index 000000000..dd94fc231 --- /dev/null +++ b/gr-analog/python/qa_noise.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python +# +# Copyright 2007,2010,2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, gr_unittest +import analog_swig as analog + +class test_noise_source(gr_unittest.TestCase): + + def setUp (self): + self.tb = gr.top_block () + + def tearDown (self): + self.tb = None + + def test_001(self): + # Just confirm that we can instantiate a noise source + op = analog.noise_source_f(analog.GR_GAUSSIAN, 10, 10) + + def test_002(self): + # Test get methods + set_type = analog.GR_GAUSSIAN + set_ampl = 10 + op = analog.noise_source_f(set_type, set_ampl, 10) + get_type = op.type() + get_ampl = op.amplitude() + + self.assertEqual(get_type, set_type) + self.assertEqual(get_ampl, set_ampl) + + +if __name__ == '__main__': + gr_unittest.run(test_noise_source, "test_noise_source.xml") + diff --git a/gr-analog/python/qa_phase_modulator.py b/gr-analog/python/qa_phase_modulator.py new file mode 100755 index 000000000..a9c8c8459 --- /dev/null +++ b/gr-analog/python/qa_phase_modulator.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python +# +# Copyright 2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, gr_unittest +import analog_swig as analog +import math + +def sincos(x): + return math.cos(x) + math.sin(x) * 1j + + +class test_phase_modulator(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_fm_001(self): + pi = math.pi + sensitivity = pi/4 + src_data = (1.0/4, 1.0/2, 1.0/4, -1.0/4, -1.0/2, -1/4.0) + expected_result = tuple([sincos(sensitivity*x) for x in src_data]) + + src = gr.vector_source_f(src_data) + op = analog.phase_modulator_fc(sensitivity) + dst = gr.vector_sink_c() + + self.tb.connect(src, op) + self.tb.connect(op, dst) + self.tb.run() + + result_data = dst.data() + self.assertComplexTuplesAlmostEqual(expected_result, result_data, 5) + +if __name__ == '__main__': + gr_unittest.run(test_phase_modulator, "test_phase_modulator.xml") + diff --git a/gr-analog/python/qa_pll_carriertracking.py b/gr-analog/python/qa_pll_carriertracking.py new file mode 100755 index 000000000..a292059d1 --- /dev/null +++ b/gr-analog/python/qa_pll_carriertracking.py @@ -0,0 +1,157 @@ +#!/usr/bin/env python +# +# Copyright 2004,2007,2010-2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, gr_unittest +import analog_swig as analog +import math + +class test_pll_carriertracking(gr_unittest.TestCase): + + def setUp (self): + self.tb = gr.top_block() + + def tearDown (self): + self.tb = None + + def test_pll_carriertracking(self): + expected_result = ((1.00000238419+7.21919457547e-09j), + (0.998025715351+0.062790453434j), + (0.992777824402+0.119947694242j), + (0.985192835331+0.171441286802j), + (0.976061582565+0.217501848936j), + (0.966034710407+0.258409559727j), + (0.95565611124+0.294477283955j), + (0.945357382298+0.326030552387j), + (0.935475051403+0.353395611048j), + (0.926258146763+0.376889169216j), + (0.917895197868+0.39681750536j), + (0.910515546799+0.413470208645j), + (0.904196679592+0.427117019892j), + (0.898972511292+0.438006043434j), + (0.894769787788+0.446523308754j), + (0.891652584076+0.452715367079j), + (0.8895829916+0.456773489714j), + (0.888502895832+0.458873122931j), + (0.888343691826+0.459175437689j), + (0.889035582542+0.457833081484j), + (0.890497922897+0.454985737801j), + (0.892645597458+0.450762689114j), + (0.895388305187+0.445282936096j), + (0.898648142815+0.438664674759j), + (0.902342617512+0.431016951799j), + (0.906392872334+0.422441422939j), + (0.910642921925+0.413191765547j), + (0.915039420128+0.403358519077j), + (0.919594764709+0.392864197493j), + (0.92425006628+0.381792247295j), + (0.928944349289+0.370217680931j), + (0.933634519577+0.358220815659j), + (0.938279032707+0.345874190331j), + (0.942840516567+0.333247303963j), + (0.947280526161+0.32040438056j), + (0.951574921608+0.307409763336j), + (0.955703914165+0.294323593378j), + (0.959648966789+0.281201630831j), + (0.963392794132+0.268095195293j), + (0.966880619526+0.255221515894j), + (0.970162451267+0.242447137833j), + (0.973235487938+0.229809194803j), + (0.97609680891+0.217341512442j), + (0.978744983673+0.20507311821j), + (0.981189727783+0.193033605814j), + (0.983436584473+0.181248426437j), + (0.985490739346+0.169738590717j), + (0.987353682518+0.158523857594j), + (0.989041447639+0.147622272372j), + (0.990563035011+0.137049794197j), + (0.991928339005+0.126818582416j), + (0.993117690086+0.117111675441j), + (0.994156062603+0.107930034399j), + (0.995076179504+0.0990980416536j), + (0.995887458324+0.0906178802252j), + (0.996591091156+0.0824909061193j), + (0.997202515602+0.0747182965279j), + (0.997730851173+0.0672992765903j), + (0.998185396194+0.0602316558361j), + (0.99856698513+0.0535135567188j), + (0.998885989189+0.0471420884132j), + (0.99915266037+0.0411129891872j), + (0.999372899532+0.0354214012623j), + (0.999548316002+0.0300626158714j), + (0.999680638313+0.0252036750317j), + (0.999784469604+0.020652115345j), + (0.999865531921+0.0163950324059j), + (0.999923825264+0.0124222636223j), + (0.999960243702+0.00872156023979j), + (0.999983668327+0.00528120994568j), + (0.999997138977+0.00209015607834j), + (1.00000119209-0.00086285173893j), + (0.999992132187-0.00358882546425j), + (0.999979138374-0.00609711557627j), + (0.999963641167-0.00839691981673j), + (0.999947249889-0.0104993218556j), + (0.999924004078-0.0122378543019j), + (0.999904811382-0.0136305987835j), + (0.999888062477-0.0148707330227j), + (0.9998742342-0.0159679055214j), + (0.999856114388-0.0169314742088j), + (0.999839782715-0.0177700817585j), + (0.999826967716-0.0184917747974j), + (0.999818325043-0.0191045701504j), + (0.999807476997-0.0196143388748j), + (0.999797284603-0.0200265944004j), + (0.999791204929-0.0203481912613j), + (0.99978852272-0.0205836892128j), + (0.99978530407-0.0207380950451j), + (0.999785065651-0.0206423997879j), + (0.999787807465-0.0204866230488j), + (0.999794304371-0.0202808082104j), + (0.999800384045-0.0200312435627j), + (0.999803245068-0.0197458267212j), + (0.9998087883-0.0194311738014j), + (0.999816894531-0.0190933048725j), + (0.999825954437-0.0187371373177j), + (0.999829888344-0.0183679759502j), + (0.999835848808-0.017987690866j), + (0.999844014645-0.0176006518304j)) + + sampling_freq = 10e3 + freq = sampling_freq / 100 + + loop_bw = math.pi/100.0 + maxf = 1 + minf = -1 + + src = gr.sig_source_c(sampling_freq, gr.GR_COS_WAVE, freq, 1.0) + pll = analog.pll_carriertracking_cc(loop_bw, maxf, minf) + head = gr.head(gr.sizeof_gr_complex, int (freq)) + dst = gr.vector_sink_c() + + self.tb.connect(src, pll, head) + self.tb.connect(head, dst) + + self.tb.run() + dst_data = dst.data() + self.assertComplexTuplesAlmostEqual(expected_result, dst_data, 5) + +if __name__ == '__main__': + gr_unittest.run(test_pll_carriertracking, "test_pll_carriertracking.xml") diff --git a/gr-analog/python/qa_pll_freqdet.py b/gr-analog/python/qa_pll_freqdet.py new file mode 100755 index 000000000..1f808afa6 --- /dev/null +++ b/gr-analog/python/qa_pll_freqdet.py @@ -0,0 +1,161 @@ +#!/usr/bin/env python +# +# Copyright 2004,2007,2010-2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, gr_unittest +import analog_swig as analog +import math + +class test_pll_freqdet(gr_unittest.TestCase): + + def setUp (self): + self.tb = gr.top_block() + + def tearDown (self): + self.tb = None + + def test_pll_freqdet(self): + expected_result = (0.0, + 4.33888922882e-08, + 0.367369994515, + 1.08135249597, + 2.10983253908, + 3.42221529438, + 4.98940390402, + 6.78379190842, + 8.77923286024, + 10.9510106794, + 13.2758363182, + 15.7317829127, + 18.2982902299, + 20.9561068599, + 23.6755271122, + 26.452952094, + 29.2731265301, + 32.1219053479, + 34.9862418188, + 37.8540971414, + 40.7144315483, + 43.5571390869, + 46.3730179743, + 49.1537231663, + 51.8917218889, + 54.58026103, + 57.2015358514, + 59.7513664199, + 62.2380533124, + 64.657612252, + 67.006640002, + 69.2822432184, + 71.4820384499, + 73.6041047056, + 75.6469478817, + 77.6094829742, + 79.4909866472, + 81.2911031615, + 83.0097850853, + 84.6355598352, + 86.1820937186, + 87.6504420946, + 89.0418441206, + 90.3577286819, + 91.5996432431, + 92.7692775646, + 93.8684162704, + 94.8989269904, + 95.8627662892, + 96.7619381633, + 97.598505899, + 98.362769679, + 99.0579904444, + 99.6992633875, + 100.288805948, + 100.828805921, + 101.321421457, + 101.76878699, + 102.17300138, + 102.536116055, + 102.860158727, + 103.147085962, + 103.398830608, + 103.617254366, + 103.792467691, + 103.939387906, + 104.060030865, + 104.15631756, + 104.230085975, + 104.283067372, + 104.316933727, + 104.333238432, + 104.333440018, + 104.318914008, + 104.290941063, + 104.250742554, + 104.187634452, + 104.103822339, + 104.013227468, + 103.916810336, + 103.815448432, + 103.709936239, + 103.600997093, + 103.489283183, + 103.375351833, + 103.259712936, + 103.142828952, + 103.025091195, + 102.90686726, + 102.776726069, + 102.648078982, + 102.521459607, + 102.397294831, + 102.275999684, + 102.157882471, + 102.043215927, + 101.93218978, + 101.824958181, + 101.72159228, + 101.622151366) + + sampling_freq = 10e3 + freq = sampling_freq / 100 + + loop_bw = math.pi/100.0 + maxf = 1 + minf = -1 + + src = gr.sig_source_c(sampling_freq, gr.GR_COS_WAVE, freq, 1.0) + pll = analog.pll_freqdet_cf(loop_bw, maxf, minf) + head = gr.head(gr.sizeof_float, int (freq)) + dst = gr.vector_sink_f() + + self.tb.connect(src, pll, head) + self.tb.connect(head, dst) + + self.tb.run() + dst_data = dst.data() + + # convert it from normalized frequency to absolute frequency (Hz) + dst_data = [i*(sampling_freq/(2*math.pi)) for i in dst_data] + + self.assertFloatTuplesAlmostEqual(expected_result, dst_data, 3) + +if __name__ == '__main__': + gr_unittest.run(test_pll_freqdet, "test_pll_freqdet.xml") diff --git a/gr-analog/python/qa_pll_refout.py b/gr-analog/python/qa_pll_refout.py new file mode 100755 index 000000000..2831b2909 --- /dev/null +++ b/gr-analog/python/qa_pll_refout.py @@ -0,0 +1,157 @@ +#!/usr/bin/env python +# +# Copyright 2004,2010,2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, gr_unittest +import analog_swig as analog +import math + +class test_pll_refout(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_pll_refout(self): + expected_result = ((1+0j), + (1+6.4087357643e-10j), + (0.999985277653+0.00542619498447j), + (0.999868750572+0.0162021834403j), + (0.99948567152+0.0320679470897j), + (0.99860727787+0.0527590736747j), + (0.996953129768+0.0780025869608j), + (0.994203746319+0.107512556016j), + (0.990011692047+0.140985429287j), + (0.984013140202+0.178095817566j), + (0.975838363171+0.218493551016j), + (0.965121984482+0.261800557375j), + (0.95151245594+0.307610183954j), + (0.934681296349+0.355486690998j), + (0.914401650429+0.404808044434j), + (0.890356600285+0.455263823271j), + (0.862329125404+0.506348133087j), + (0.830152392387+0.557536482811j), + (0.793714106083+0.608290970325j), + (0.752960026264+0.658066213131j), + (0.707896590233+0.706316053867j), + (0.658591926098+0.752500295639j), + (0.605175673962+0.796091973782j), + (0.547837555408+0.836584687233j), + (0.48682525754+0.873499393463j), + (0.42244040966+0.906390726566j), + (0.355197101831+0.934791445732j), + (0.285494059324+0.958380460739j), + (0.213591173291+0.976923108101j), + (0.139945343137+0.990159213543j), + (0.065038472414+0.997882783413j), + (-0.0106285437942+0.999943494797j), + (-0.0865436866879+0.996248066425j), + (-0.162189796567+0.986759603024j), + (-0.23705175519+0.971496999264j), + (-0.310622543097+0.950533330441j), + (-0.38240903616+0.923993110657j), + (-0.451937526464+0.89204955101j), + (-0.518758952618+0.854920566082j), + (-0.582311093807+0.812966048717j), + (-0.642372369766+0.76639264822j), + (-0.698591887951+0.715520322323j), + (-0.750654160976+0.660695314407j), + (-0.798280358315+0.602286040783j), + (-0.841228663921+0.540679454803j), + (-0.87929558754+0.476276367903j), + (-0.912315964699+0.409486919641j), + (-0.940161883831+0.340728074312j), + (-0.962742805481+0.270418733358j), + (-0.980004072189+0.198977485299j), + (-0.991925954819+0.126818284392j), + (-0.99851256609+0.0545223206282j), + (-0.999846458435-0.0175215266645j), + (-0.996021270752-0.0891158208251j), + (-0.987133920193-0.159895718098j), + (-0.973306238651-0.2295101583j), + (-0.954683184624-0.297624111176j), + (-0.931430280209-0.363919824362j), + (-0.903732538223-0.428097635508j), + (-0.871792256832-0.489875763655j), + (-0.835827112198-0.548992812634j), + (-0.796068251133-0.605206847191j), + (-0.752758979797-0.658296227455j), + (-0.706152498722-0.70805978775j), + (-0.656641483307-0.754202902317j), + (-0.604367733002-0.79670548439j), + (-0.549597978592-0.835429251194j), + (-0.492602348328-0.870254516602j), + (-0.433654457331-0.901079237461j), + (-0.373029649258-0.927819430828j), + (-0.31100410223-0.950408577919j), + (-0.247853919864-0.968797445297j), + (-0.183855071664-0.982953369617j), + (-0.119282215834-0.992860376835j), + (-0.0544078871608-0.998518764973j), + (0.0104992967099-0.999944865704j), + (0.0749994292855-0.997183561325j), + (0.138844624162-0.990314185619j), + (0.201967850327-0.979392170906j), + (0.264124274254-0.964488625526j), + (0.325075358152-0.945688128471j), + (0.3845885396-0.92308807373j), + (0.442438393831-0.89679890871j), + (0.498407125473-0.866943061352j), + (0.552284479141-0.833655714989j), + (0.603869199753-0.797083437443j), + (0.652970373631-0.757383465767j), + (0.69940674305-0.714723825455j), + (0.743007957935-0.66928255558j), + (0.78350687027-0.62138313055j), + (0.820889055729-0.571087777615j), + (0.855021059513-0.51859331131j), + (0.885780930519-0.46410369873j), + (0.913058102131-0.407829582691j), + (0.936754107475-0.349988251925j), + (0.956783294678-0.290801793337j), + (0.973072886467-0.230497643352j), + (0.985563337803-0.169307261705j), + (0.9942086339-0.1074674353j), + (0.9989772439-0.0452152714133j)) + + sampling_freq = 10e3 + freq = sampling_freq / 100 + + loop_bw = math.pi/100.0 + maxf = 1 + minf = -1 + + src = gr.sig_source_c(sampling_freq, gr.GR_COS_WAVE, freq, 1.0) + pll = analog.pll_refout_cc(loop_bw, maxf, minf) + head = gr.head(gr.sizeof_gr_complex, int (freq)) + dst = gr.vector_sink_c() + + self.tb.connect(src, pll, head) + self.tb.connect(head, dst) + + self.tb.run() + dst_data = dst.data() + self.assertComplexTuplesAlmostEqual(expected_result, dst_data, 4) + +if __name__ == '__main__': + gr_unittest.run(test_pll_refout, "test_pll_refout.xml") diff --git a/gr-analog/python/qa_probe_avg_mag_sqrd.py b/gr-analog/python/qa_probe_avg_mag_sqrd.py new file mode 100755 index 000000000..5c6c97e45 --- /dev/null +++ b/gr-analog/python/qa_probe_avg_mag_sqrd.py @@ -0,0 +1,98 @@ +#!/usr/bin/env python +# +# Copyright 2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, gr_unittest +import analog_swig as analog +import math + +def avg_mag_sqrd_c(x, alpha): + y = [0,] + for xi in x: + tmp = alpha*(xi.real*xi.real + xi.imag*xi.imag) + (1-alpha)*y[-1] + y.append(tmp) + return y + +def avg_mag_sqrd_f(x, alpha): + y = [0,] + for xi in x: + tmp = alpha*(xi*xi) + (1-alpha)*y[-1] + y.append(tmp) + return y + +class test_probe_avg_mag_sqrd(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_c_001(self): + alpha = 0.0001 + src_data = [1.0+1.0j, 2.0+2.0j, 3.0+3.0j, 4.0+4.0j, 5.0+5.0j, + 6.0+6.0j, 7.0+7.0j, 8.0+8.0j, 9.0+9.0j, 10.0+10.0j] + expected_result = avg_mag_sqrd_c(src_data, alpha)[-1] + + src = gr.vector_source_c(src_data) + op = analog.probe_avg_mag_sqrd_c(0, alpha) + + self.tb.connect(src, op) + self.tb.run() + + result_data = op.level() + self.assertAlmostEqual(expected_result, result_data, 5) + + def test_cf_002(self): + alpha = 0.0001 + src_data = [1.0+1.0j, 2.0+2.0j, 3.0+3.0j, 4.0+4.0j, 5.0+5.0j, + 6.0+6.0j, 7.0+7.0j, 8.0+8.0j, 9.0+9.0j, 10.0+10.0j] + expected_result = avg_mag_sqrd_c(src_data, alpha)[0:-1] + + src = gr.vector_source_c(src_data) + op = analog.probe_avg_mag_sqrd_cf(0, alpha) + dst = gr.vector_sink_f() + + self.tb.connect(src, op) + self.tb.connect(op, dst) + self.tb.run() + + result_data = dst.data() + self.assertComplexTuplesAlmostEqual(expected_result, result_data, 5) + + def test_f_003(self): + alpha = 0.0001 + src_data = [1.0, 2.0, 3.0, 4.0, 5.0, + 6.0, 7.0, 8.0, 9.0, 10.0] + expected_result = avg_mag_sqrd_f(src_data, alpha)[-1] + + src = gr.vector_source_f(src_data) + op = analog.probe_avg_mag_sqrd_f(0, alpha) + + self.tb.connect(src, op) + self.tb.run() + + result_data = op.level() + self.assertAlmostEqual(expected_result, result_data, 5) + +if __name__ == '__main__': + gr_unittest.run(test_probe_avg_mag_sqrd, "test_probe_avg_mag_sqrd.xml") + diff --git a/gr-analog/python/qa_pwr_squelch.py b/gr-analog/python/qa_pwr_squelch.py new file mode 100755 index 000000000..dd42c7fb9 --- /dev/null +++ b/gr-analog/python/qa_pwr_squelch.py @@ -0,0 +1,128 @@ +#!/usr/bin/env python +# +# Copyright 2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, gr_unittest +import analog_swig as analog + +class test_pwr_squelch(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_pwr_squelch_001(self): + # Test set/gets + + alpha = 0.0001 + + thr1 = 10 + thr2 = 20 + ramp = 1 + ramp2 = 2 + gate = True + gate2 = False + + op = analog.pwr_squelch_cc(thr1, alpha, ramp, gate) + + op.set_threshold(thr2) + t = op.threshold() + self.assertEqual(thr2, t) + + op.set_ramp(ramp2) + r = op.ramp() + self.assertEqual(ramp2, r) + + op.set_gate(gate2) + g = op.gate() + self.assertEqual(gate2, g) + + def test_pwr_squelch_002(self): + # Test runtime, gate=True + alpha = 0.0001 + thr = -25 + + src_data = map(lambda x: float(x)/10.0, range(1, 40)) + src = gr.vector_source_c(src_data) + op = analog.pwr_squelch_cc(thr, alpha) + dst = gr.vector_sink_c() + + self.tb.connect(src, op) + self.tb.connect(op, dst) + self.tb.run() + + expected_result = src_data + expected_result[0:20] = 20*[0,] + + result_data = dst.data() + self.assertComplexTuplesAlmostEqual(expected_result, result_data, 4) + + def test_pwr_squelch_003(self): + # Test set/gets + + alpha = 0.0001 + + thr1 = 10 + thr2 = 20 + ramp = 1 + ramp2 = 2 + gate = True + gate2 = False + + op = analog.pwr_squelch_ff(thr1, alpha, ramp, gate) + + op.set_threshold(thr2) + t = op.threshold() + self.assertEqual(thr2, t) + + op.set_ramp(ramp2) + r = op.ramp() + self.assertEqual(ramp2, r) + + op.set_gate(gate2) + g = op.gate() + self.assertEqual(gate2, g) + + + def test_pwr_squelch_004(self): + alpha = 0.0001 + thr = -25 + + src_data = map(lambda x: float(x)/10.0, range(1, 40)) + src = gr.vector_source_f(src_data) + op = analog.pwr_squelch_ff(thr, alpha) + dst = gr.vector_sink_f() + + self.tb.connect(src, op) + self.tb.connect(op, dst) + self.tb.run() + + expected_result = src_data + expected_result[0:20] = 20*[0,] + + result_data = dst.data() + self.assertFloatTuplesAlmostEqual(expected_result, result_data, 4) + +if __name__ == '__main__': + gr_unittest.run(test_pwr_squelch, "test_pwr_squelch.xml") + diff --git a/gr-analog/python/qa_quadrature_demod.py b/gr-analog/python/qa_quadrature_demod.py new file mode 100755 index 000000000..e38ea72a7 --- /dev/null +++ b/gr-analog/python/qa_quadrature_demod.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python +# +# Copyright 2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, gr_unittest +import analog_swig as analog +import cmath + +class test_quadrature_demod(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_quad_demod_001(self): + f = 1000.0 + fs = 8000.0 + + src_data = [] + for i in xrange(200): + ti = i/fs + src_data.append(cmath.exp(2j*cmath.pi*f*ti)) + + # f/fs is a quarter turn per sample. + # Set the gain based on this to get 1 out. + gain = 1.0/(cmath.pi/4) + + expected_result = [0,] + 199*[1.0] + + src = gr.vector_source_c(src_data) + op = analog.quadrature_demod_cf(gain) + dst = gr.vector_sink_f() + + self.tb.connect(src, op) + self.tb.connect(op, dst) + self.tb.run() + + result_data = dst.data() + self.assertComplexTuplesAlmostEqual(expected_result, result_data, 5) + +if __name__ == '__main__': + gr_unittest.run(test_quadrature_demod, "test_quadrature_demod.xml") + diff --git a/gr-analog/python/qa_rail_ff.py b/gr-analog/python/qa_rail_ff.py new file mode 100755 index 000000000..5bcf01c6b --- /dev/null +++ b/gr-analog/python/qa_rail_ff.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python +# +# Copyright 2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, gr_unittest +import analog_swig as analog + +def clip(x, lo, hi): + if(x < lo): + return lo + elif(x > hi): + return hi + else: + return x + +class test_rail(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_rail_001(self): + # Test set/gets + + hi1 = 1 + hi2 = 2 + lo1 = -1 + lo2 = -2 + + op = analog.rail_ff(lo1, hi1) + + op.set_hi(hi2) + h = op.hi() + self.assertEqual(hi2, h) + + op.set_lo(lo2) + l = op.lo() + self.assertEqual(lo2, l) + + def test_rail_002(self): + lo = -0.75 + hi = 0.90 + src_data = [-2, -1, -0.5, -0.25, 0, 0.25, 0.5, 1, 2] + expected_result = map(lambda x: clip(x, lo, hi), src_data) + + src = gr.vector_source_f(src_data) + op = analog.rail_ff(lo, hi) + dst = gr.vector_sink_f() + + self.tb.connect(src, op) + self.tb.connect(op, dst) + self.tb.run() + + result_data = dst.data() + self.assertFloatTuplesAlmostEqual(expected_result, result_data, 4) + +if __name__ == '__main__': + gr_unittest.run(test_rail, "test_rail.xml") + diff --git a/gr-analog/python/qa_sig_source.py b/gr-analog/python/qa_sig_source.py new file mode 100755 index 000000000..bc48333ed --- /dev/null +++ b/gr-analog/python/qa_sig_source.py @@ -0,0 +1,160 @@ +#!/usr/bin/env python +# +# Copyright 2004,2007,2010,2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, gr_unittest +import analog_swig as analog +import math + +class test_sig_source(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_const_f(self): + tb = self.tb + expected_result = (1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5) + src1 = analog.sig_source_f(1e6, analog.GR_CONST_WAVE, 0, 1.5) + op = gr.head(gr.sizeof_float, 10) + dst1 = gr.vector_sink_f() + tb.connect(src1, op) + tb.connect(op, dst1) + tb.run() + dst_data = dst1.data() + self.assertEqual(expected_result, dst_data) + + def test_const_i(self): + tb = self.tb + expected_result = (1, 1, 1, 1) + src1 = analog.sig_source_i(1e6, analog.GR_CONST_WAVE, 0, 1) + op = gr.head(gr.sizeof_int, 4) + dst1 = gr.vector_sink_i() + tb.connect(src1, op) + tb.connect(op, dst1) + tb.run() + dst_data = dst1.data() + self.assertEqual(expected_result, dst_data) + + def test_sine_f(self): + tb = self.tb + sqrt2 = math.sqrt(2) / 2 + expected_result = (0, sqrt2, 1, sqrt2, 0, -sqrt2, -1, -sqrt2, 0) + src1 = analog.sig_source_f(8, analog.GR_SIN_WAVE, 1.0, 1.0) + op = gr.head(gr.sizeof_float, 9) + dst1 = gr.vector_sink_f() + tb.connect(src1, op) + tb.connect(op, dst1) + tb.run() + dst_data = dst1.data() + self.assertFloatTuplesAlmostEqual(expected_result, dst_data, 5) + + def test_cosine_f(self): + tb = self.tb + sqrt2 = math.sqrt(2) / 2 + expected_result = (1, sqrt2, 0, -sqrt2, -1, -sqrt2, 0, sqrt2, 1) + src1 = analog.sig_source_f(8, analog.GR_COS_WAVE, 1.0, 1.0) + op = gr.head(gr.sizeof_float, 9) + dst1 = gr.vector_sink_f() + tb.connect(src1, op) + tb.connect(op, dst1) + tb.run() + dst_data = dst1.data() + self.assertFloatTuplesAlmostEqual(expected_result, dst_data, 5) + + def test_sqr_c(self): + tb = self.tb #arg6 is a bit before -PI/2 + expected_result = (1j, 1j, 0, 0, 1, 1, 1+0j, 1+1j, 1j) + src1 = analog.sig_source_c(8, analog.GR_SQR_WAVE, 1.0, 1.0) + op = gr.head(gr.sizeof_gr_complex, 9) + dst1 = gr.vector_sink_c() + tb.connect(src1, op) + tb.connect(op, dst1) + tb.run() + dst_data = dst1.data() + self.assertEqual(expected_result, dst_data) + + def test_tri_c(self): + tb = self.tb + expected_result = (1+.5j, .75+.75j, .5+1j, .25+.75j, 0+.5j, + .25+.25j, .5+0j, .75+.25j, 1+.5j) + src1 = analog.sig_source_c(8, analog.GR_TRI_WAVE, 1.0, 1.0) + op = gr.head(gr.sizeof_gr_complex, 9) + dst1 = gr.vector_sink_c() + tb.connect(src1, op) + tb.connect(op, dst1) + tb.run() + dst_data = dst1.data() + self.assertComplexTuplesAlmostEqual(expected_result, dst_data, 5) + + def test_saw_c(self): + tb = self.tb + expected_result = (.5+.25j, .625+.375j, .75+.5j, .875+.625j, + 0+.75j, .125+.875j, .25+1j, .375+.125j, .5+.25j) + src1 = analog.sig_source_c(8, analog.GR_SAW_WAVE, 1.0, 1.0) + op = gr.head(gr.sizeof_gr_complex, 9) + dst1 = gr.vector_sink_c() + tb.connect(src1, op) + tb.connect(op, dst1) + tb.run() + dst_data = dst1.data() + self.assertComplexTuplesAlmostEqual(expected_result, dst_data, 5) + + def test_sqr_f(self): + tb = self.tb + expected_result = (0, 0, 0, 0, 1, 1, 1, 1, 0) + src1 = analog.sig_source_f(8, analog.GR_SQR_WAVE, 1.0, 1.0) + op = gr.head(gr.sizeof_float, 9) + dst1 = gr.vector_sink_f() + tb.connect(src1, op) + tb.connect(op, dst1) + tb.run() + dst_data = dst1.data() + self.assertEqual(expected_result, dst_data) + + def test_tri_f(self): + tb = self.tb + expected_result = (1, .75, .5, .25, 0, .25, .5, .75, 1) + src1 = analog.sig_source_f(8, analog.GR_TRI_WAVE, 1.0, 1.0) + op = gr.head(gr.sizeof_float, 9) + dst1 = gr.vector_sink_f() + tb.connect(src1, op) + tb.connect(op, dst1) + tb.run() + dst_data = dst1.data() + self.assertFloatTuplesAlmostEqual(expected_result, dst_data, 5) + + def test_saw_f(self): + tb = self.tb + expected_result = (.5, .625, .75, .875, 0, .125, .25, .375, .5) + src1 = analog.sig_source_f(8, analog.GR_SAW_WAVE, 1.0, 1.0) + op = gr.head(gr.sizeof_float, 9) + dst1 = gr.vector_sink_f() + tb.connect(src1, op) + tb.connect(op, dst1) + tb.run() + dst_data = dst1.data() + self.assertFloatTuplesAlmostEqual(expected_result, dst_data, 5) + +if __name__ == '__main__': + gr_unittest.run(test_sig_source, "test_sig_source.xml") diff --git a/gr-analog/python/qa_simple_squelch.py b/gr-analog/python/qa_simple_squelch.py new file mode 100755 index 000000000..9fa112864 --- /dev/null +++ b/gr-analog/python/qa_simple_squelch.py @@ -0,0 +1,69 @@ +#!/usr/bin/env python +# +# Copyright 2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, gr_unittest +import analog_swig as analog + +class test_simple_squelch(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_simple_squelch_001(self): + # Test set/gets + + alpha = 0.0001 + + thr1 = 10 + thr2 = 20 + + op = analog.simple_squelch_cc(thr1, alpha) + + op.set_threshold(thr2) + t = op.threshold() + self.assertEqual(thr2, t) + + def test_simple_squelch_002(self): + alpha = 0.0001 + thr = -25 + + src_data = map(lambda x: float(x)/10.0, range(1, 40)) + src = gr.vector_source_c(src_data) + op = analog.simple_squelch_cc(thr, alpha) + dst = gr.vector_sink_c() + + self.tb.connect(src, op) + self.tb.connect(op, dst) + self.tb.run() + + expected_result = src_data + expected_result[0:20] = 20*[0,] + + result_data = dst.data() + self.assertComplexTuplesAlmostEqual(expected_result, result_data, 4) + +if __name__ == '__main__': + gr_unittest.run(test_simple_squelch, "test_simple_squelch.xml") + diff --git a/gr-analog/swig/CMakeLists.txt b/gr-analog/swig/CMakeLists.txt new file mode 100644 index 000000000..e3fbbe73f --- /dev/null +++ b/gr-analog/swig/CMakeLists.txt @@ -0,0 +1,51 @@ +# Copyright 2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. + +######################################################################## +# Setup swig generation +######################################################################## +include(GrPython) +include(GrSwig) + +set(GR_SWIG_INCLUDE_DIRS + ${GR_ANALOG_INCLUDE_DIRS} + ${GR_FILTER_INCLUDE_DIRS} + ${GNURADIO_CORE_SWIG_INCLUDE_DIRS} +) + +set(GR_SWIG_DOC_FILE ${CMAKE_CURRENT_BINARY_DIR}/analog_swig_doc.i) +set(GR_SWIG_DOC_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/../lib) + +set(GR_SWIG_LIBRARIES gnuradio-analog gnuradio-filter) + +GR_SWIG_MAKE(analog_swig analog_swig.i) + +GR_SWIG_INSTALL( + TARGETS analog_swig + DESTINATION ${GR_PYTHON_DIR}/gnuradio/analog + COMPONENT "analog_python" +) + +install( + FILES + analog_swig.i + ${CMAKE_CURRENT_BINARY_DIR}/analog_swig_doc.i + DESTINATION ${GR_INCLUDE_DIR}/gnuradio/swig + COMPONENT "analog_swig" +) diff --git a/gr-analog/swig/analog_swig.i b/gr-analog/swig/analog_swig.i new file mode 100644 index 000000000..016537c94 --- /dev/null +++ b/gr-analog/swig/analog_swig.i @@ -0,0 +1,137 @@ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#define ANALOG_API + +%include "gnuradio.i" +%include "stdint.i" + +//load generated python docstrings +%include "analog_swig_doc.i" + +%{ +#include "analog/cpm.h" +#include "analog/noise_type.h" +#include "analog/agc_cc.h" +#include "analog/agc_ff.h" +#include "analog/agc2_cc.h" +#include "analog/agc2_ff.h" +#include "analog/cpfsk_bc.h" +#include "analog/ctcss_squelch_ff.h" +#include "analog/dpll_bb.h" +#include "analog/feedforward_agc_cc.h" +#include "analog/fmdet_cf.h" +#include "analog/frequency_modulator_fc.h" +#include "analog/lfsr.h" +#include "analog/noise_source_s.h" +#include "analog/noise_source_i.h" +#include "analog/noise_source_f.h" +#include "analog/noise_source_c.h" +#include "analog/phase_modulator_fc.h" +#include "analog/pll_carriertracking_cc.h" +#include "analog/pll_freqdet_cf.h" +#include "analog/pll_refout_cc.h" +#include "analog/probe_avg_mag_sqrd_c.h" +#include "analog/probe_avg_mag_sqrd_cf.h" +#include "analog/probe_avg_mag_sqrd_f.h" +#include "analog/pwr_squelch_cc.h" +#include "analog/pwr_squelch_ff.h" +#include "analog/quadrature_demod_cf.h" +#include "analog/rail_ff.h" +#include "analog/sincos.h" +#include "analog/sig_source_s.h" +#include "analog/sig_source_i.h" +#include "analog/sig_source_f.h" +#include "analog/sig_source_c.h" +#include "analog/sig_source_waveform.h" +#include "analog/simple_squelch_cc.h" +#include "analog/squelch_base_cc.h" +#include "analog/squelch_base_ff.h" +%} + +%include "analog/cpm.h" +%include "analog/noise_type.h" +%include "analog/agc_cc.h" +%include "analog/agc_ff.h" +%include "analog/agc2_cc.h" +%include "analog/agc2_ff.h" +%include "analog/cpfsk_bc.h" +%include "analog/ctcss_squelch_ff.h" +%include "analog/dpll_bb.h" +%include "analog/feedforward_agc_cc.h" +%include "analog/fmdet_cf.h" +%include "analog/frequency_modulator_fc.h" +%include "analog/lfsr.h" +%include "analog/noise_source_s.h" +%include "analog/noise_source_i.h" +%include "analog/noise_source_f.h" +%include "analog/noise_source_c.h" +%include "analog/phase_modulator_fc.h" +%include "analog/pll_carriertracking_cc.h" +%include "analog/pll_freqdet_cf.h" +%include "analog/pll_refout_cc.h" +%include "analog/probe_avg_mag_sqrd_c.h" +%include "analog/probe_avg_mag_sqrd_cf.h" +%include "analog/probe_avg_mag_sqrd_f.h" +%include "analog/pwr_squelch_cc.h" +%include "analog/pwr_squelch_ff.h" +%include "analog/quadrature_demod_cf.h" +%include "analog/rail_ff.h" +%include "analog/sincos.h" +%include "analog/sig_source_s.h" +%include "analog/sig_source_i.h" +%include "analog/sig_source_f.h" +%include "analog/sig_source_c.h" +%include "analog/sig_source_waveform.h" +%include "analog/simple_squelch_cc.h" +%include "analog/squelch_base_cc.h" +%include "analog/squelch_base_ff.h" + +GR_SWIG_BLOCK_MAGIC2(analog, agc_cc); +GR_SWIG_BLOCK_MAGIC2(analog, agc_ff); +GR_SWIG_BLOCK_MAGIC2(analog, agc2_cc); +GR_SWIG_BLOCK_MAGIC2(analog, agc2_ff); +GR_SWIG_BLOCK_MAGIC2(analog, cpfsk_bc); +GR_SWIG_BLOCK_MAGIC2(analog, ctcss_squelch_ff); +GR_SWIG_BLOCK_MAGIC2(analog, dpll_bb); +GR_SWIG_BLOCK_MAGIC2(analog, feedforward_agc_cc); +GR_SWIG_BLOCK_MAGIC2(analog, fmdet_cf); +GR_SWIG_BLOCK_MAGIC2(analog, frequency_modulator_fc); +GR_SWIG_BLOCK_MAGIC2(analog, noise_source_s); +GR_SWIG_BLOCK_MAGIC2(analog, noise_source_i); +GR_SWIG_BLOCK_MAGIC2(analog, noise_source_f); +GR_SWIG_BLOCK_MAGIC2(analog, noise_source_c); +GR_SWIG_BLOCK_MAGIC2(analog, phase_modulator_fc); +GR_SWIG_BLOCK_MAGIC2(analog, pll_carriertracking_cc); +GR_SWIG_BLOCK_MAGIC2(analog, pll_freqdet_cf); +GR_SWIG_BLOCK_MAGIC2(analog, pll_refout_cc); +GR_SWIG_BLOCK_MAGIC2(analog, probe_avg_mag_sqrd_c); +GR_SWIG_BLOCK_MAGIC2(analog, probe_avg_mag_sqrd_cf); +GR_SWIG_BLOCK_MAGIC2(analog, probe_avg_mag_sqrd_f); +GR_SWIG_BLOCK_MAGIC2(analog, pwr_squelch_cc); +GR_SWIG_BLOCK_MAGIC2(analog, pwr_squelch_ff); +GR_SWIG_BLOCK_MAGIC2(analog, quadrature_demod_cf); +GR_SWIG_BLOCK_MAGIC2(analog, rail_ff); +GR_SWIG_BLOCK_MAGIC2(analog, sig_source_s); +GR_SWIG_BLOCK_MAGIC2(analog, sig_source_i); +GR_SWIG_BLOCK_MAGIC2(analog, sig_source_f); +GR_SWIG_BLOCK_MAGIC2(analog, sig_source_c); +GR_SWIG_BLOCK_MAGIC2(analog, simple_squelch_cc); diff --git a/gr-atsc/src/lib/qa_atsci_single_viterbi.cc b/gr-atsc/src/lib/qa_atsci_single_viterbi.cc index ca0cf7464..699dce952 100644 --- a/gr-atsc/src/lib/qa_atsci_single_viterbi.cc +++ b/gr-atsc/src/lib/qa_atsci_single_viterbi.cc @@ -236,7 +236,7 @@ qa_atsci_single_viterbi::t1 () // FIXME, should we be able to tell how many errs too? if (differs) { - const int ERRTOL = 12; /* Or relate to delay? */ + //const int ERRTOL = 12; /* Or relate to delay? */ int shouldfix = 1; //int lasti = -ERRTOL; diff --git a/gr-blocks/CMakeLists.txt b/gr-blocks/CMakeLists.txt new file mode 100644 index 000000000..7e2f43562 --- /dev/null +++ b/gr-blocks/CMakeLists.txt @@ -0,0 +1,105 @@ +# Copyright 2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. + +######################################################################## +# Setup dependencies +######################################################################## +include(GrBoost) + +######################################################################## +# Register component +######################################################################## +include(GrComponent) +GR_REGISTER_COMPONENT("gr-blocks" ENABLE_GR_BLOCKS + Boost_FOUND + ENABLE_GR_CORE +) + +GR_SET_GLOBAL(GR_BLOCKS_INCLUDE_DIRS + ${CMAKE_CURRENT_SOURCE_DIR}/lib + ${CMAKE_CURRENT_SOURCE_DIR}/include +) + +######################################################################## +# Begin conditional configuration +######################################################################## +if(ENABLE_GR_BLOCKS) + +######################################################################## +# Setup CPack components +######################################################################## +include(GrPackage) +CPACK_SET(CPACK_COMPONENT_GROUP_BLOCKS_DESCRIPTION "GNU Radio Basic Blocks") + +CPACK_COMPONENT("blocks_runtime" + GROUP "Blocks" + DISPLAY_NAME "Runtime" + DESCRIPTION "Runtime" + DEPENDS "core_runtime" +) + +CPACK_COMPONENT("blocks_devel" + GROUP "Blocks" + DISPLAY_NAME "Development" + DESCRIPTION "C++ headers, package config, import libraries" + DEPENDS "core_devel" +) + +CPACK_COMPONENT("blocks_python" + GROUP "Blocks" + DISPLAY_NAME "Python" + DESCRIPTION "Python modules for runtime; GRC xml files" + DEPENDS "core_python;blocks_runtime" +) + +CPACK_COMPONENT("blocks_swig" + GROUP "Blocks" + DISPLAY_NAME "SWIG" + DESCRIPTION "SWIG development .i files" + DEPENDS "core_swig;blocks_python;blocks_devel" +) + +######################################################################## +# Add subdirectories +######################################################################## +add_subdirectory(include/blocks) +add_subdirectory(lib) +if(ENABLE_PYTHON) + add_subdirectory(python) + add_subdirectory(swig) + add_subdirectory(grc) + add_subdirectory(doc) + add_subdirectory(examples) +endif(ENABLE_PYTHON) + +######################################################################## +# Create Pkg Config File +######################################################################## +configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/gnuradio-blocks.pc.in + ${CMAKE_CURRENT_BINARY_DIR}/gnuradio-blocks.pc +@ONLY) + +install( + FILES ${CMAKE_CURRENT_BINARY_DIR}/gnuradio-blocks.pc + DESTINATION ${GR_LIBRARY_DIR}/pkgconfig + COMPONENT "blocks_devel" +) + +endif(ENABLE_GR_BLOCKS) diff --git a/gr-blocks/doc/CMakeLists.txt b/gr-blocks/doc/CMakeLists.txt new file mode 100644 index 000000000..c1397804b --- /dev/null +++ b/gr-blocks/doc/CMakeLists.txt @@ -0,0 +1,23 @@ +# Copyright 2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. + +install( + FILES README.blocks + DESTINATION ${GR_PKG_DOC_DIR} +) diff --git a/gr-blocks/doc/README.blocks b/gr-blocks/doc/README.blocks new file mode 100644 index 000000000..418a06825 --- /dev/null +++ b/gr-blocks/doc/README.blocks @@ -0,0 +1,12 @@ +This is the gr-blocks package. It contains the basic blocks that are +widely used in many different types of flowgraphs. To use these blocks, +the Python namespace is in gnuradio.blocks, which would be normally +imported as: + + from gnuradio import blocks + +See the Doxygen documentation for details about the blocks available +in this package. A quick listing of the details can be found in Python +after importing by using: + + help(blocks) diff --git a/gr-blocks/doc/blocks.dox b/gr-blocks/doc/blocks.dox new file mode 100644 index 000000000..110dcb677 --- /dev/null +++ b/gr-blocks/doc/blocks.dox @@ -0,0 +1,23 @@ +/*! \page page_digital Digital Modulation + +\section Introduction +This is the gr-digital package. It contains all of the digital +modulation blocks, utilities, and examples. To use the digital blocks, +the Python namespaces is in gnuradio.digital, which would be normally +imported as: + +\code + from gnuradio import digital +\endcode + +See the Doxygen documentation for details about the blocks available +in this package. The relevant blocks are listed in the \ref digital group. + +A quick listing of the details can be found in Python after importing +by using: + +\code + help(digital) +\endcode + +*/ diff --git a/gr-blocks/examples/CMakeLists.txt b/gr-blocks/examples/CMakeLists.txt new file mode 100644 index 000000000..79535daa0 --- /dev/null +++ b/gr-blocks/examples/CMakeLists.txt @@ -0,0 +1,20 @@ +# Copyright 2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. + +add_subdirectory(metadata) diff --git a/gr-blocks/examples/metadata/CMakeLists.txt b/gr-blocks/examples/metadata/CMakeLists.txt new file mode 100644 index 000000000..53a54b9d5 --- /dev/null +++ b/gr-blocks/examples/metadata/CMakeLists.txt @@ -0,0 +1,30 @@ +# Copyright 2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. + +include(GrPython) + +install( + FILES + file_metadata_sink.grc + file_metadata_source.grc + file_metadata_vector_sink.grc + file_metadata_vector_source.grc + DESTINATION ${GR_PKG_DATA_DIR}/examples/metadata + COMPONENT "core_python" +) diff --git a/gr-blocks/examples/metadata/file_metadata_sink.grc b/gr-blocks/examples/metadata/file_metadata_sink.grc new file mode 100644 index 000000000..198b0725f --- /dev/null +++ b/gr-blocks/examples/metadata/file_metadata_sink.grc @@ -0,0 +1,951 @@ +<?xml version='1.0' encoding='ASCII'?> +<flow_graph> + <timestamp>Fri Dec 14 17:09:06 2012</timestamp> + <block> + <key>options</key> + <param> + <key>id</key> + <value>file_metadata_sink</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>title</key> + <value></value> + </param> + <param> + <key>author</key> + <value></value> + </param> + <param> + <key>description</key> + <value></value> + </param> + <param> + <key>window_size</key> + <value>1280, 1024</value> + </param> + <param> + <key>generate_options</key> + <value>qt_gui</value> + </param> + <param> + <key>category</key> + <value>Custom</value> + </param> + <param> + <key>run_options</key> + <value>prompt</value> + </param> + <param> + <key>run</key> + <value>True</value> + </param> + <param> + <key>max_nouts</key> + <value>0</value> + </param> + <param> + <key>realtime_scheduling</key> + <value></value> + </param> + <param> + <key>_coordinate</key> + <value>(10, 10)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_sig_source_x</key> + <param> + <key>id</key> + <value>gr_sig_source_x_0</value> + </param> + <param> + <key>_enabled</key> + <value>False</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>samp_rate</key> + <value>samp_rate</value> + </param> + <param> + <key>waveform</key> + <value>gr.GR_COS_WAVE</value> + </param> + <param> + <key>freq</key> + <value>1000</value> + </param> + <param> + <key>amp</key> + <value>1</value> + </param> + <param> + <key>offset</key> + <value>0</value> + </param> + <param> + <key>_coordinate</key> + <value>(57, 140)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable_qtgui_range</key> + <param> + <key>id</key> + <value>qt_samp_rate</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>label</key> + <value></value> + </param> + <param> + <key>value</key> + <value>samp_rate</value> + </param> + <param> + <key>start</key> + <value>200000</value> + </param> + <param> + <key>stop</key> + <value>5000000</value> + </param> + <param> + <key>step</key> + <value>200000</value> + </param> + <param> + <key>widget</key> + <value>counter_slider</value> + </param> + <param> + <key>orient</key> + <value>Qt.Horizontal</value> + </param> + <param> + <key>min_len</key> + <value>200</value> + </param> + <param> + <key>gui_hint</key> + <value></value> + </param> + <param> + <key>_coordinate</key> + <value>(330, 259)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable</key> + <param> + <key>id</key> + <value>samp_rate</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>value</key> + <value>200000</value> + </param> + <param> + <key>_coordinate</key> + <value>(208, 11)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>uhd_usrp_source</key> + <param> + <key>id</key> + <value>uhd_usrp_source_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>fc32</value> + </param> + <param> + <key>otw</key> + <value></value> + </param> + <param> + <key>stream_args</key> + <value></value> + </param> + <param> + <key>dev_addr</key> + <value>addr=192.168.11.2</value> + </param> + <param> + <key>sync</key> + <value></value> + </param> + <param> + <key>clock_rate</key> + <value>0.0</value> + </param> + <param> + <key>num_mboards</key> + <value>1</value> + </param> + <param> + <key>clock_source0</key> + <value></value> + </param> + <param> + <key>time_source0</key> + <value></value> + </param> + <param> + <key>sd_spec0</key> + <value></value> + </param> + <param> + <key>clock_source1</key> + <value></value> + </param> + <param> + <key>time_source1</key> + <value></value> + </param> + <param> + <key>sd_spec1</key> + <value></value> + </param> + <param> + <key>clock_source2</key> + <value></value> + </param> + <param> + <key>time_source2</key> + <value></value> + </param> + <param> + <key>sd_spec2</key> + <value></value> + </param> + <param> + <key>clock_source3</key> + <value></value> + </param> + <param> + <key>time_source3</key> + <value></value> + </param> + <param> + <key>sd_spec3</key> + <value></value> + </param> + <param> + <key>clock_source4</key> + <value></value> + </param> + <param> + <key>time_source4</key> + <value></value> + </param> + <param> + <key>sd_spec4</key> + <value></value> + </param> + <param> + <key>clock_source5</key> + <value></value> + </param> + <param> + <key>time_source5</key> + <value></value> + </param> + <param> + <key>sd_spec5</key> + <value></value> + </param> + <param> + <key>clock_source6</key> + <value></value> + </param> + <param> + <key>time_source6</key> + <value></value> + </param> + <param> + <key>sd_spec6</key> + <value></value> + </param> + <param> + <key>clock_source7</key> + <value></value> + </param> + <param> + <key>time_source7</key> + <value></value> + </param> + <param> + <key>sd_spec7</key> + <value></value> + </param> + <param> + <key>nchan</key> + <value>1</value> + </param> + <param> + <key>samp_rate</key> + <value>qt_samp_rate</value> + </param> + <param> + <key>center_freq0</key> + <value>98.9e6</value> + </param> + <param> + <key>gain0</key> + <value>30</value> + </param> + <param> + <key>ant0</key> + <value></value> + </param> + <param> + <key>bw0</key> + <value>0</value> + </param> + <param> + <key>center_freq1</key> + <value>0</value> + </param> + <param> + <key>gain1</key> + <value>0</value> + </param> + <param> + <key>ant1</key> + <value></value> + </param> + <param> + <key>bw1</key> + <value>0</value> + </param> + <param> + <key>center_freq2</key> + <value>0</value> + </param> + <param> + <key>gain2</key> + <value>0</value> + </param> + <param> + <key>ant2</key> + <value></value> + </param> + <param> + <key>bw2</key> + <value>0</value> + </param> + <param> + <key>center_freq3</key> + <value>0</value> + </param> + <param> + <key>gain3</key> + <value>0</value> + </param> + <param> + <key>ant3</key> + <value></value> + </param> + <param> + <key>bw3</key> + <value>0</value> + </param> + <param> + <key>center_freq4</key> + <value>0</value> + </param> + <param> + <key>gain4</key> + <value>0</value> + </param> + <param> + <key>ant4</key> + <value></value> + </param> + <param> + <key>bw4</key> + <value>0</value> + </param> + <param> + <key>center_freq5</key> + <value>0</value> + </param> + <param> + <key>gain5</key> + <value>0</value> + </param> + <param> + <key>ant5</key> + <value></value> + </param> + <param> + <key>bw5</key> + <value>0</value> + </param> + <param> + <key>center_freq6</key> + <value>0</value> + </param> + <param> + <key>gain6</key> + <value>0</value> + </param> + <param> + <key>ant6</key> + <value></value> + </param> + <param> + <key>bw6</key> + <value>0</value> + </param> + <param> + <key>center_freq7</key> + <value>0</value> + </param> + <param> + <key>gain7</key> + <value>0</value> + </param> + <param> + <key>ant7</key> + <value></value> + </param> + <param> + <key>bw7</key> + <value>0</value> + </param> + <param> + <key>center_freq8</key> + <value>0</value> + </param> + <param> + <key>gain8</key> + <value>0</value> + </param> + <param> + <key>ant8</key> + <value></value> + </param> + <param> + <key>bw8</key> + <value>0</value> + </param> + <param> + <key>center_freq9</key> + <value>0</value> + </param> + <param> + <key>gain9</key> + <value>0</value> + </param> + <param> + <key>ant9</key> + <value></value> + </param> + <param> + <key>bw9</key> + <value>0</value> + </param> + <param> + <key>center_freq10</key> + <value>0</value> + </param> + <param> + <key>gain10</key> + <value>0</value> + </param> + <param> + <key>ant10</key> + <value></value> + </param> + <param> + <key>bw10</key> + <value>0</value> + </param> + <param> + <key>center_freq11</key> + <value>0</value> + </param> + <param> + <key>gain11</key> + <value>0</value> + </param> + <param> + <key>ant11</key> + <value></value> + </param> + <param> + <key>bw11</key> + <value>0</value> + </param> + <param> + <key>center_freq12</key> + <value>0</value> + </param> + <param> + <key>gain12</key> + <value>0</value> + </param> + <param> + <key>ant12</key> + <value></value> + </param> + <param> + <key>bw12</key> + <value>0</value> + </param> + <param> + <key>center_freq13</key> + <value>0</value> + </param> + <param> + <key>gain13</key> + <value>0</value> + </param> + <param> + <key>ant13</key> + <value></value> + </param> + <param> + <key>bw13</key> + <value>0</value> + </param> + <param> + <key>center_freq14</key> + <value>0</value> + </param> + <param> + <key>gain14</key> + <value>0</value> + </param> + <param> + <key>ant14</key> + <value></value> + </param> + <param> + <key>bw14</key> + <value>0</value> + </param> + <param> + <key>center_freq15</key> + <value>0</value> + </param> + <param> + <key>gain15</key> + <value>0</value> + </param> + <param> + <key>ant15</key> + <value></value> + </param> + <param> + <key>bw15</key> + <value>0</value> + </param> + <param> + <key>center_freq16</key> + <value>0</value> + </param> + <param> + <key>gain16</key> + <value>0</value> + </param> + <param> + <key>ant16</key> + <value></value> + </param> + <param> + <key>bw16</key> + <value>0</value> + </param> + <param> + <key>center_freq17</key> + <value>0</value> + </param> + <param> + <key>gain17</key> + <value>0</value> + </param> + <param> + <key>ant17</key> + <value></value> + </param> + <param> + <key>bw17</key> + <value>0</value> + </param> + <param> + <key>center_freq18</key> + <value>0</value> + </param> + <param> + <key>gain18</key> + <value>0</value> + </param> + <param> + <key>ant18</key> + <value></value> + </param> + <param> + <key>bw18</key> + <value>0</value> + </param> + <param> + <key>center_freq19</key> + <value>0</value> + </param> + <param> + <key>gain19</key> + <value>0</value> + </param> + <param> + <key>ant19</key> + <value></value> + </param> + <param> + <key>bw19</key> + <value>0</value> + </param> + <param> + <key>center_freq20</key> + <value>0</value> + </param> + <param> + <key>gain20</key> + <value>0</value> + </param> + <param> + <key>ant20</key> + <value></value> + </param> + <param> + <key>bw20</key> + <value>0</value> + </param> + <param> + <key>center_freq21</key> + <value>0</value> + </param> + <param> + <key>gain21</key> + <value>0</value> + </param> + <param> + <key>ant21</key> + <value></value> + </param> + <param> + <key>bw21</key> + <value>0</value> + </param> + <param> + <key>center_freq22</key> + <value>0</value> + </param> + <param> + <key>gain22</key> + <value>0</value> + </param> + <param> + <key>ant22</key> + <value></value> + </param> + <param> + <key>bw22</key> + <value>0</value> + </param> + <param> + <key>center_freq23</key> + <value>0</value> + </param> + <param> + <key>gain23</key> + <value>0</value> + </param> + <param> + <key>ant23</key> + <value></value> + </param> + <param> + <key>bw23</key> + <value>0</value> + </param> + <param> + <key>center_freq24</key> + <value>0</value> + </param> + <param> + <key>gain24</key> + <value>0</value> + </param> + <param> + <key>ant24</key> + <value></value> + </param> + <param> + <key>bw24</key> + <value>0</value> + </param> + <param> + <key>center_freq25</key> + <value>0</value> + </param> + <param> + <key>gain25</key> + <value>0</value> + </param> + <param> + <key>ant25</key> + <value></value> + </param> + <param> + <key>bw25</key> + <value>0</value> + </param> + <param> + <key>center_freq26</key> + <value>0</value> + </param> + <param> + <key>gain26</key> + <value>0</value> + </param> + <param> + <key>ant26</key> + <value></value> + </param> + <param> + <key>bw26</key> + <value>0</value> + </param> + <param> + <key>center_freq27</key> + <value>0</value> + </param> + <param> + <key>gain27</key> + <value>0</value> + </param> + <param> + <key>ant27</key> + <value></value> + </param> + <param> + <key>bw27</key> + <value>0</value> + </param> + <param> + <key>center_freq28</key> + <value>0</value> + </param> + <param> + <key>gain28</key> + <value>0</value> + </param> + <param> + <key>ant28</key> + <value></value> + </param> + <param> + <key>bw28</key> + <value>0</value> + </param> + <param> + <key>center_freq29</key> + <value>0</value> + </param> + <param> + <key>gain29</key> + <value>0</value> + </param> + <param> + <key>ant29</key> + <value></value> + </param> + <param> + <key>bw29</key> + <value>0</value> + </param> + <param> + <key>center_freq30</key> + <value>0</value> + </param> + <param> + <key>gain30</key> + <value>0</value> + </param> + <param> + <key>ant30</key> + <value></value> + </param> + <param> + <key>bw30</key> + <value>0</value> + </param> + <param> + <key>center_freq31</key> + <value>0</value> + </param> + <param> + <key>gain31</key> + <value>0</value> + </param> + <param> + <key>ant31</key> + <value></value> + </param> + <param> + <key>bw31</key> + <value>0</value> + </param> + <param> + <key>_coordinate</key> + <value>(53, 269)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_head</key> + <param> + <key>id</key> + <value>gr_head_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>num_items</key> + <value>20000000</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + <param> + <key>_coordinate</key> + <value>(309, 172)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>blocks_file_meta_sink</key> + <param> + <key>id</key> + <value>blocks_file_meta_sink_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>file</key> + <value>/tmp/metadat_file.out</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>samp_rate</key> + <value>samp_rate</value> + </param> + <param> + <key>rel_rate</key> + <value>1</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + <param> + <key>max_seg_size</key> + <value>1000000</value> + </param> + <param> + <key>extra_dict</key> + <value>""</value> + </param> + <param> + <key>detached</key> + <value>True</value> + </param> + <param> + <key>unbuffered</key> + <value>False</value> + </param> + <param> + <key>_coordinate</key> + <value>(569, 124)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <connection> + <source_block_id>gr_sig_source_x_0</source_block_id> + <sink_block_id>gr_head_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>uhd_usrp_source_0</source_block_id> + <sink_block_id>gr_head_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_head_0</source_block_id> + <sink_block_id>blocks_file_meta_sink_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> +</flow_graph> diff --git a/gr-blocks/examples/metadata/file_metadata_source.grc b/gr-blocks/examples/metadata/file_metadata_source.grc new file mode 100644 index 000000000..23757881b --- /dev/null +++ b/gr-blocks/examples/metadata/file_metadata_source.grc @@ -0,0 +1,350 @@ +<?xml version='1.0' encoding='ASCII'?> +<flow_graph> + <timestamp>Fri Dec 14 17:08:09 2012</timestamp> + <block> + <key>options</key> + <param> + <key>id</key> + <value>file_metadata_source</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>title</key> + <value></value> + </param> + <param> + <key>author</key> + <value></value> + </param> + <param> + <key>description</key> + <value></value> + </param> + <param> + <key>window_size</key> + <value>1280, 1024</value> + </param> + <param> + <key>generate_options</key> + <value>qt_gui</value> + </param> + <param> + <key>category</key> + <value>Custom</value> + </param> + <param> + <key>run_options</key> + <value>prompt</value> + </param> + <param> + <key>run</key> + <value>True</value> + </param> + <param> + <key>max_nouts</key> + <value>0</value> + </param> + <param> + <key>realtime_scheduling</key> + <value></value> + </param> + <param> + <key>_coordinate</key> + <value>(10, 10)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable</key> + <param> + <key>id</key> + <value>samp_rate</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>value</key> + <value>200000</value> + </param> + <param> + <key>_coordinate</key> + <value>(208, 11)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_tag_debug</key> + <param> + <key>id</key> + <value>gr_tag_debug_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>name</key> + <value>Test</value> + </param> + <param> + <key>num_inputs</key> + <value>1</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + <param> + <key>display</key> + <value>True</value> + </param> + <param> + <key>_coordinate</key> + <value>(561, 290)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>analog_agc2_xx</key> + <param> + <key>id</key> + <value>analog_agc2_xx_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>attack_rate</key> + <value>1e-1</value> + </param> + <param> + <key>decay_rate</key> + <value>1e-2</value> + </param> + <param> + <key>reference</key> + <value>1.0</value> + </param> + <param> + <key>gain</key> + <value>1.0</value> + </param> + <param> + <key>max_gain</key> + <value>0.0</value> + </param> + <param> + <key>_coordinate</key> + <value>(561, 82)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>qtgui_time_sink_x</key> + <param> + <key>id</key> + <value>qtgui_time_sink_x_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>name</key> + <value>QT GUI Plot</value> + </param> + <param> + <key>size</key> + <value>1024</value> + </param> + <param> + <key>bw</key> + <value>samp_rate</value> + </param> + <param> + <key>nconnections</key> + <value>1</value> + </param> + <param> + <key>gui_hint</key> + <value></value> + </param> + <param> + <key>_coordinate</key> + <value>(776, 98)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_file_sink</key> + <param> + <key>id</key> + <value>gr_file_sink_1</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>file</key> + <value>/tmp/received_data.out</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + <param> + <key>unbuffered</key> + <value>False</value> + </param> + <param> + <key>_coordinate</key> + <value>(564, 215)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_throttle</key> + <param> + <key>id</key> + <value>gr_throttle_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>samples_per_second</key> + <value>samp_rate</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + <param> + <key>_coordinate</key> + <value>(322, 222)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>blocks_file_meta_source</key> + <param> + <key>id</key> + <value>blocks_file_meta_source_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>file</key> + <value>/tmp/metadat_file.out</value> + </param> + <param> + <key>repeat</key> + <value>False</value> + </param> + <param> + <key>detached</key> + <value>True</value> + </param> + <param> + <key>hdr_file</key> + <value></value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + <param> + <key>_coordinate</key> + <value>(50, 198)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <connection> + <source_block_id>gr_throttle_0</source_block_id> + <sink_block_id>gr_file_sink_1</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_throttle_0</source_block_id> + <sink_block_id>gr_tag_debug_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_throttle_0</source_block_id> + <sink_block_id>analog_agc2_xx_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>analog_agc2_xx_0</source_block_id> + <sink_block_id>qtgui_time_sink_x_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>blocks_file_meta_source_0</source_block_id> + <sink_block_id>gr_throttle_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> +</flow_graph> diff --git a/gr-blocks/examples/metadata/file_metadata_vector_sink.grc b/gr-blocks/examples/metadata/file_metadata_vector_sink.grc new file mode 100644 index 000000000..05b7cbc92 --- /dev/null +++ b/gr-blocks/examples/metadata/file_metadata_vector_sink.grc @@ -0,0 +1,219 @@ +<?xml version='1.0' encoding='ASCII'?> +<flow_graph> + <timestamp>Fri Dec 14 17:08:29 2012</timestamp> + <block> + <key>options</key> + <param> + <key>id</key> + <value>file_metadata_vector_sink</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>title</key> + <value></value> + </param> + <param> + <key>author</key> + <value></value> + </param> + <param> + <key>description</key> + <value></value> + </param> + <param> + <key>window_size</key> + <value>1280, 1024</value> + </param> + <param> + <key>generate_options</key> + <value>no_gui</value> + </param> + <param> + <key>category</key> + <value>Custom</value> + </param> + <param> + <key>run_options</key> + <value>run</value> + </param> + <param> + <key>run</key> + <value>True</value> + </param> + <param> + <key>max_nouts</key> + <value>0</value> + </param> + <param> + <key>realtime_scheduling</key> + <value></value> + </param> + <param> + <key>_coordinate</key> + <value>(10, 10)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable</key> + <param> + <key>id</key> + <value>samp_rate</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>value</key> + <value>200000</value> + </param> + <param> + <key>_coordinate</key> + <value>(208, 11)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_vector_source_x</key> + <param> + <key>id</key> + <value>gr_vector_source_x_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>vector</key> + <value>10*[0,1,2,3,4,5,6,7,8,9]</value> + </param> + <param> + <key>repeat</key> + <value>True</value> + </param> + <param> + <key>vlen</key> + <value>10</value> + </param> + <param> + <key>_coordinate</key> + <value>(67, 100)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_head</key> + <param> + <key>id</key> + <value>gr_head_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>num_items</key> + <value>10010000</value> + </param> + <param> + <key>vlen</key> + <value>10</value> + </param> + <param> + <key>_coordinate</key> + <value>(325, 108)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>blocks_file_meta_sink</key> + <param> + <key>id</key> + <value>blocks_file_meta_sink_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>file</key> + <value>/tmp/metadat_vector.out</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>samp_rate</key> + <value>samp_rate</value> + </param> + <param> + <key>rel_rate</key> + <value>1</value> + </param> + <param> + <key>vlen</key> + <value>10</value> + </param> + <param> + <key>max_seg_size</key> + <value>1000000</value> + </param> + <param> + <key>extra_dict</key> + <value>""</value> + </param> + <param> + <key>detached</key> + <value>True</value> + </param> + <param> + <key>unbuffered</key> + <value>False</value> + </param> + <param> + <key>_coordinate</key> + <value>(544, 60)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <connection> + <source_block_id>gr_vector_source_x_0</source_block_id> + <sink_block_id>gr_head_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_head_0</source_block_id> + <sink_block_id>blocks_file_meta_sink_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> +</flow_graph> diff --git a/gr-blocks/examples/metadata/file_metadata_vector_source.grc b/gr-blocks/examples/metadata/file_metadata_vector_source.grc new file mode 100644 index 000000000..d52257e06 --- /dev/null +++ b/gr-blocks/examples/metadata/file_metadata_vector_source.grc @@ -0,0 +1,338 @@ +<?xml version='1.0' encoding='ASCII'?> +<flow_graph> + <timestamp>Fri Dec 14 17:11:02 2012</timestamp> + <block> + <key>options</key> + <param> + <key>id</key> + <value>file_metadata_vector_source</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>title</key> + <value></value> + </param> + <param> + <key>author</key> + <value></value> + </param> + <param> + <key>description</key> + <value></value> + </param> + <param> + <key>window_size</key> + <value>1280, 1024</value> + </param> + <param> + <key>generate_options</key> + <value>qt_gui</value> + </param> + <param> + <key>category</key> + <value>Custom</value> + </param> + <param> + <key>run_options</key> + <value>prompt</value> + </param> + <param> + <key>run</key> + <value>True</value> + </param> + <param> + <key>max_nouts</key> + <value>0</value> + </param> + <param> + <key>realtime_scheduling</key> + <value></value> + </param> + <param> + <key>_coordinate</key> + <value>(10, 10)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable</key> + <param> + <key>id</key> + <value>samp_rate</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>value</key> + <value>200000</value> + </param> + <param> + <key>_coordinate</key> + <value>(208, 11)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_file_sink</key> + <param> + <key>id</key> + <value>gr_file_sink_1</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>file</key> + <value>/tmp/received_data.out</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>vlen</key> + <value>10</value> + </param> + <param> + <key>unbuffered</key> + <value>False</value> + </param> + <param> + <key>_coordinate</key> + <value>(564, 215)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_tag_debug</key> + <param> + <key>id</key> + <value>gr_tag_debug_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>name</key> + <value>Test</value> + </param> + <param> + <key>num_inputs</key> + <value>1</value> + </param> + <param> + <key>vlen</key> + <value>10</value> + </param> + <param> + <key>display</key> + <value>True</value> + </param> + <param> + <key>_coordinate</key> + <value>(563, 298)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>qtgui_time_sink_x</key> + <param> + <key>id</key> + <value>qtgui_time_sink_x_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>name</key> + <value>QT GUI Plot</value> + </param> + <param> + <key>size</key> + <value>1024</value> + </param> + <param> + <key>bw</key> + <value>samp_rate</value> + </param> + <param> + <key>nconnections</key> + <value>1</value> + </param> + <param> + <key>gui_hint</key> + <value></value> + </param> + <param> + <key>_coordinate</key> + <value>(746, 116)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>blocks_vector_to_stream</key> + <param> + <key>id</key> + <value>blocks_vector_to_stream_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>num_items</key> + <value>10</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + <param> + <key>_coordinate</key> + <value>(526, 132)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_throttle</key> + <param> + <key>id</key> + <value>gr_throttle_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>samples_per_second</key> + <value>samp_rate</value> + </param> + <param> + <key>vlen</key> + <value>10</value> + </param> + <param> + <key>_coordinate</key> + <value>(322, 223)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>blocks_file_meta_source</key> + <param> + <key>id</key> + <value>blocks_file_meta_source_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>file</key> + <value>/tmp/metadat_vector.out</value> + </param> + <param> + <key>repeat</key> + <value>False</value> + </param> + <param> + <key>detached</key> + <value>True</value> + </param> + <param> + <key>hdr_file</key> + <value></value> + </param> + <param> + <key>vlen</key> + <value>10</value> + </param> + <param> + <key>_coordinate</key> + <value>(42, 199)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <connection> + <source_block_id>gr_throttle_0</source_block_id> + <sink_block_id>gr_file_sink_1</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_throttle_0</source_block_id> + <sink_block_id>gr_tag_debug_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>blocks_vector_to_stream_0</source_block_id> + <sink_block_id>qtgui_time_sink_x_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_throttle_0</source_block_id> + <sink_block_id>blocks_vector_to_stream_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>blocks_file_meta_source_0</source_block_id> + <sink_block_id>gr_throttle_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> +</flow_graph> diff --git a/gr-blocks/gnuradio-blocks.pc.in b/gr-blocks/gnuradio-blocks.pc.in new file mode 100644 index 000000000..c24564157 --- /dev/null +++ b/gr-blocks/gnuradio-blocks.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: gnuradio-blocks +Description: GNU Radio basic block library +Requires: gnuradio-core +Version: @LIBVER@ +Libs: -L${libdir} -lgnuradio-blocks +Cflags: -I${includedir} diff --git a/gr-blocks/grc/CMakeLists.txt b/gr-blocks/grc/CMakeLists.txt new file mode 100644 index 000000000..ed66d9e3b --- /dev/null +++ b/gr-blocks/grc/CMakeLists.txt @@ -0,0 +1,22 @@ +# Copyright 2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. + +######################################################################## +file(GLOB xml_files "*.xml") +install(FILES ${xml_files} DESTINATION ${GRC_BLOCKS_DIR} COMPONENT "blocks_python") diff --git a/gr-blocks/grc/blocks_add_const_vxx.xml b/gr-blocks/grc/blocks_add_const_vxx.xml new file mode 100644 index 000000000..96303acef --- /dev/null +++ b/gr-blocks/grc/blocks_add_const_vxx.xml @@ -0,0 +1,67 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Add Const Block: +## all types, 1 output, 1 input & const +################################################### + --> +<block> + <name>Add Const</name> + <key>blocks_add_const_vxx</key> + <import>from gnuradio import blocks</import> + <make>blocks.add_const_v$(type.fcn)($const)</make> + <callback>set_k($const)</callback> + <param> + <name>IO Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>const_type:complex_vector</opt> + <opt>fcn:cc</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>const_type:real_vector</opt> + <opt>fcn:ff</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>const_type:int_vector</opt> + <opt>fcn:ii</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>const_type:int_vector</opt> + <opt>fcn:ss</opt> + </option> + </param> + <param> + <name>Constant</name> + <key>const</key> + <value>0</value> + <type>$type.const_type</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>len($const) == $vlen</check> + <check>$vlen > 0</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + </sink> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/gr-blocks/grc/blocks_add_xx.xml b/gr-blocks/grc/blocks_add_xx.xml new file mode 100644 index 000000000..951dff5e5 --- /dev/null +++ b/gr-blocks/grc/blocks_add_xx.xml @@ -0,0 +1,63 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Add Block: +## all types, 1 output, 2 to inf inputs +################################################### + --> +<block> + <name>Add</name> + <key>blocks_add_xx</key> + <import>from gnuradio import blocks</import> + <make>blocks.add_v$(type.fcn)($vlen)</make> + <param> + <name>IO Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>fcn:cc</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>fcn:ff</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>fcn:ii</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>fcn:ss</opt> + </option> + </param> + <param> + <name>Num Inputs</name> + <key>num_inputs</key> + <value>2</value> + <type>int</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$num_inputs > 1</check> + <check>$vlen > 0</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + <nports>$num_inputs</nports> + </sink> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/gr-blocks/grc/blocks_and_const_xx.xml b/gr-blocks/grc/blocks_and_const_xx.xml new file mode 100644 index 000000000..d0abbfe51 --- /dev/null +++ b/gr-blocks/grc/blocks_and_const_xx.xml @@ -0,0 +1,48 @@ +<?xml version="1.0"?> +<!-- +################################################### +## And Const Block: +## all types, 1 output, 1 input & const +################################################### + --> +<block> + <name>And Const</name> + <key>blocks_and_const_xx</key> + <import>from gnuradio import blocks</import> + <make>blocks.and_const_$(type.fcn)($const)</make> + <callback>set_k($const)</callback> + <param> + <name>IO Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Int</name> + <key>int</key> + <opt>fcn:ii</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>fcn:ss</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>fcn:bb</opt> + </option> + </param> + <param> + <name>Constant</name> + <key>const</key> + <value>0</value> + <type>int</type> + </param> + <sink> + <name>in</name> + <type>$type</type> + </sink> + <source> + <name>out</name> + <type>$type</type> + </source> +</block> diff --git a/gr-blocks/grc/blocks_and_xx.xml b/gr-blocks/grc/blocks_and_xx.xml new file mode 100644 index 000000000..317a0f645 --- /dev/null +++ b/gr-blocks/grc/blocks_and_xx.xml @@ -0,0 +1,48 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Logical And Block +################################################### + --> +<block> + <name>And</name> + <key>blocks_and_xx</key> + <import>from gnuradio import blocks</import> + <make>blocks.and_$(type.fcn)()</make> + <param> + <name>IO Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Int</name> + <key>int</key> + <opt>fcn:ii</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>fcn:ss</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>fcn:bb</opt> + </option> + </param> + <param> + <name>Num Inputs</name> + <key>num_inputs</key> + <value>2</value> + <type>int</type> + </param> + <check>$num_inputs >= 2</check> + <sink> + <name>in</name> + <type>$type</type> + <nports>$num_inputs</nports> + </sink> + <source> + <name>out</name> + <type>$type</type> + </source> +</block> diff --git a/gr-blocks/grc/blocks_block_tree.xml b/gr-blocks/grc/blocks_block_tree.xml new file mode 100644 index 000000000..797b3dbc5 --- /dev/null +++ b/gr-blocks/grc/blocks_block_tree.xml @@ -0,0 +1,98 @@ +<?xml version="1.0"?> + +<!-- + Copyright 2012 Free Software Foundation, Inc. + + This file is part of GNU Radio + + GNU Radio is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GNU Radio is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Radio; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, + Boston, MA 02110-1301, USA. +--> + +<!-- +################################################### +##Block Tree for gr-blocks. +################################################### + --> +<cat> + <name></name> <!-- Blank for Root Name --> + <cat> + <name>Sources (New)</name> + <block>blocks_file_source</block> + <block>blocks_file_meta_source</block> + </cat> + <cat> + <name>Sinks (New)</name> + <block>blocks_file_meta_sink</block> + </cat> + <cat> + <name>Math Operations (New) </name> + <block>blocks_add_xx</block> + <block>blocks_add_const_vxx</block> + <block>blocks_divide_xx</block> + <block>blocks_multiply_xx</block> + <block>blocks_multiply_const_vxx</block> + <block>blocks_multiply_conjugate_cc</block> + <block>blocks_sub_xx</block> + <block>blocks_conjugate_cc</block> + <block>blocks_integrate_xx</block> + <block>blocks_nlog10_ff</block> + </cat> + <cat> + <name>Boolean Operations (New) </name> + <block>blocks_and_xx</block> + <block>blocks_and_const_xx</block> + <block>blocks_not_xx</block> + <block>blocks_or_xx</block> + <block>blocks_xor_xx</block> + </cat> + <cat> + <name>Stream Type Conversions (New) </name> + <block>blocks_char_to_float</block> + <block>blocks_char_to_short</block> + <block>blocks_complex_to_interleaved_short</block> + <block>blocks_complex_to_float</block> + <block>blocks_complex_to_imag</block> + <block>blocks_complex_to_real</block> + <block>blocks_complex_to_mag</block> + <block>blocks_complex_to_mag_squared</block> + <block>blocks_complex_to_arg</block> + <block>blocks_float_to_char</block> + <block>blocks_float_to_complex</block> + <block>blocks_float_to_int</block> + <block>blocks_float_to_short</block> + <block>blocks_float_to_uchar</block> + <block>blocks_int_to_float</block> + <block>blocks_interleaved_short_to_complex</block> + <block>blocks_short_to_char</block> + <block>blocks_short_to_float</block> + <block>blocks_uchar_to_float</block> + </cat> + <cat> + <name>Stream Operations (New) </name> + <block>blocks_deinterleave</block> + <block>blocks_interleave</block> + <block>blocks_keep_m_in_n</block> + <block>blocks_keep_one_in_n</block> + <block>blocks_repeat</block> + <block>blocks_stream_mux</block> + <block>blocks_stream_to_streams</block> + <block>blocks_stream_to_vector</block> + <block>blocks_streams_to_stream</block> + <block>blocks_streams_to_vector</block> + <block>blocks_vector_to_stream</block> + <block>blocks_vector_to_streams</block> + </cat> +</cat> diff --git a/gr-blocks/grc/blocks_char_to_float.xml b/gr-blocks/grc/blocks_char_to_float.xml new file mode 100644 index 000000000..5d367d719 --- /dev/null +++ b/gr-blocks/grc/blocks_char_to_float.xml @@ -0,0 +1,35 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Char to Float: +################################################### + --> +<block> + <name>Char To Float</name> + <key>blocks_char_to_float</key> + <import>from gnuradio import blocks</import> + <make>blocks.char_to_float($vlen, $scale)</make> + <callback>set_scale($scale)</callback> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <param> + <name>Scale</name> + <key>scale</key> + <value>1</value> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>byte</type> + <vlen>$vlen</vlen> + </sink> + <source> + <name>out</name> + <type>float</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/gr-blocks/grc/blocks_char_to_short.xml b/gr-blocks/grc/blocks_char_to_short.xml new file mode 100644 index 000000000..b19fdb46a --- /dev/null +++ b/gr-blocks/grc/blocks_char_to_short.xml @@ -0,0 +1,28 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Char to Short: +################################################### + --> +<block> + <name>Char To Short</name> + <key>blocks_char_to_short</key> + <import>from gnuradio import blocks</import> + <make>blocks.char_to_short($vlen)</make> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <sink> + <name>in</name> + <type>byte</type> + <vlen>$vlen</vlen> + </sink> + <source> + <name>out</name> + <type>short</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/gr-blocks/grc/blocks_complex_to_arg.xml b/gr-blocks/grc/blocks_complex_to_arg.xml new file mode 100644 index 000000000..83140501d --- /dev/null +++ b/gr-blocks/grc/blocks_complex_to_arg.xml @@ -0,0 +1,29 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Complex to Arg +################################################### + --> +<block> + <name>Complex to Arg</name> + <key>blocks_complex_to_arg</key> + <import>from gnuradio import blocks</import> + <make>blocks.complex_to_arg($vlen)</make> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen > 0</check> + <sink> + <name>in</name> + <type>complex</type> + <vlen>$vlen</vlen> + </sink> + <source> + <name>out</name> + <type>float</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/gr-blocks/grc/blocks_complex_to_float.xml b/gr-blocks/grc/blocks_complex_to_float.xml new file mode 100644 index 000000000..7acf3fccb --- /dev/null +++ b/gr-blocks/grc/blocks_complex_to_float.xml @@ -0,0 +1,36 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Complex to Float: +## one or two output streams +################################################### + --> +<block> + <name>Complex To Float</name> + <key>blocks_complex_to_float</key> + <import>from gnuradio import blocks</import> + <make>blocks.complex_to_float($vlen)</make> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen > 0</check> + <sink> + <name>in</name> + <type>complex</type> + <vlen>$vlen</vlen> + </sink> + <source> + <name>re</name> + <type>float</type> + <vlen>$vlen</vlen> + </source> + <source> + <name>im</name> + <type>float</type> + <vlen>$vlen</vlen> + <optional>1</optional> + </source> +</block> diff --git a/gr-blocks/grc/blocks_complex_to_imag.xml b/gr-blocks/grc/blocks_complex_to_imag.xml new file mode 100644 index 000000000..cb2c2019f --- /dev/null +++ b/gr-blocks/grc/blocks_complex_to_imag.xml @@ -0,0 +1,29 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Complex to Imaginary +################################################### + --> +<block> + <name>Complex to Imag</name> + <key>blocks_complex_to_imag</key> + <import>from gnuradio import blocks</import> + <make>blocks.complex_to_imag($vlen)</make> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen > 0</check> + <sink> + <name>in</name> + <type>complex</type> + <vlen>$vlen</vlen> + </sink> + <source> + <name>out</name> + <type>float</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/gr-blocks/grc/blocks_complex_to_interleaved_short.xml b/gr-blocks/grc/blocks_complex_to_interleaved_short.xml new file mode 100644 index 000000000..43b55f32a --- /dev/null +++ b/gr-blocks/grc/blocks_complex_to_interleaved_short.xml @@ -0,0 +1,20 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Complex to Interleaved Short: +################################################### + --> +<block> + <name>Complex To IShort</name> + <key>blocks_complex_to_interleaved_short</key> + <import>from gnuradio import blocks</import> + <make>blocks.complex_to_interleaved_short()</make> + <sink> + <name>in</name> + <type>complex</type> + </sink> + <source> + <name>out</name> + <type>short</type> + </source> +</block> diff --git a/gr-blocks/grc/blocks_complex_to_mag.xml b/gr-blocks/grc/blocks_complex_to_mag.xml new file mode 100644 index 000000000..2aa4faee7 --- /dev/null +++ b/gr-blocks/grc/blocks_complex_to_mag.xml @@ -0,0 +1,29 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Complex to Magnitude +################################################### + --> +<block> + <name>Complex to Mag</name> + <key>blocks_complex_to_mag</key> + <import>from gnuradio import blocks</import> + <make>blocks.complex_to_mag($vlen)</make> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen > 0</check> + <sink> + <name>in</name> + <type>complex</type> + <vlen>$vlen</vlen> + </sink> + <source> + <name>out</name> + <type>float</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/gr-blocks/grc/blocks_complex_to_mag_squared.xml b/gr-blocks/grc/blocks_complex_to_mag_squared.xml new file mode 100644 index 000000000..ee2270fec --- /dev/null +++ b/gr-blocks/grc/blocks_complex_to_mag_squared.xml @@ -0,0 +1,29 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Complex to Magnitude Squared +################################################### + --> +<block> + <name>Complex to Mag^2</name> + <key>blocks_complex_to_mag_squared</key> + <import>from gnuradio import blocks</import> + <make>blocks.complex_to_mag_squared($vlen)</make> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen > 0</check> + <sink> + <name>in</name> + <type>complex</type> + <vlen>$vlen</vlen> + </sink> + <source> + <name>out</name> + <type>float</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/gr-blocks/grc/blocks_complex_to_real.xml b/gr-blocks/grc/blocks_complex_to_real.xml new file mode 100644 index 000000000..0fe77dc1c --- /dev/null +++ b/gr-blocks/grc/blocks_complex_to_real.xml @@ -0,0 +1,36 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Complex to Real: +## one or two output streams +################################################### + --> +<block> + <name>Complex To Real</name> + <key>blocks_complex_to_real</key> + <import>from gnuradio import blocks</import> + <make>blocks.complex_to_real($vlen)</make> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen > 0</check> + <sink> + <name>in</name> + <type>complex</type> + <vlen>$vlen</vlen> + </sink> + <source> + <name>re</name> + <type>real</type> + <vlen>$vlen</vlen> + </source> + <source> + <name>im</name> + <type>real</type> + <vlen>$vlen</vlen> + <optional>1</optional> + </source> +</block> diff --git a/gr-blocks/grc/blocks_conjugate_cc.xml b/gr-blocks/grc/blocks_conjugate_cc.xml new file mode 100644 index 000000000..152f797b2 --- /dev/null +++ b/gr-blocks/grc/blocks_conjugate_cc.xml @@ -0,0 +1,20 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Complex Conjugate +################################################### + --> +<block> + <name>Complex Conjugate</name> + <key>blocks_conjugate_cc</key> + <import>from gnuradio import blocks</import> + <make>blocks.conjugate_cc()</make> + <sink> + <name>in</name> + <type>complex</type> + </sink> + <source> + <name>out</name> + <type>complex</type> + </source> +</block> diff --git a/gr-blocks/grc/blocks_deinterleave.xml b/gr-blocks/grc/blocks_deinterleave.xml new file mode 100644 index 000000000..103091324 --- /dev/null +++ b/gr-blocks/grc/blocks_deinterleave.xml @@ -0,0 +1,67 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Deinterleave +################################################### + --> +<block> + <name>Deinterleave</name> + <key>blocks_deinterleave</key> + <import>from gnuradio import blocks</import> + <make>blocks.deinterleave($type.size*$vlen)</make> + <param> + <name>IO Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:blocks.sizeof_blocks_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:blocks.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:blocks.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:blocks.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:blocks.sizeof_char</opt> + </option> + </param> + <param> + <name>Num Streams</name> + <key>num_streams</key> + <value>2</value> + <type>int</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$num_streams > 0</check> + <check>$vlen >= 1</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + </sink> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + <nports>$num_streams</nports> + </source> +</block> diff --git a/gr-blocks/grc/blocks_divide_XX.xml b/gr-blocks/grc/blocks_divide_XX.xml new file mode 100644 index 000000000..d784d305d --- /dev/null +++ b/gr-blocks/grc/blocks_divide_XX.xml @@ -0,0 +1,63 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Divide Block: +## all types, 1 output, 2 to inf inputs +################################################### + --> +<block> + <name>Divide</name> + <key>blocks_divide_xx</key> + <import>from gnuradio import blocks</import> + <make>blocks.divide_$(type.fcn)($vlen)</make> + <param> + <name>IO Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>fcn:cc</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>fcn:ff</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>fcn:ii</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>fcn:ss</opt> + </option> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <param> + <name>Num Inputs</name> + <key>num_inputs</key> + <value>2</value> + <type>int</type> + </param> + <check>$vlen > 0</check> + <check>$num_inputs >= 2</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + <nports>$num_inputs</nports> + </sink> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/gr-blocks/grc/blocks_file_meta_sink.xml b/gr-blocks/grc/blocks_file_meta_sink.xml new file mode 100644 index 000000000..f6490d507 --- /dev/null +++ b/gr-blocks/grc/blocks_file_meta_sink.xml @@ -0,0 +1,124 @@ +<?xml version="1.0"?> +<!-- +################################################### +##File Meta Sink +################################################### + --> +<block> + <name>File Meta Sink</name> + <key>blocks_file_meta_sink</key> + <import>from gnuradio import gr, blocks</import> + <make>blocks.file_meta_sink($type.size*$vlen, $file, $samp_rate, $rel_rate, $type.dtype, $type.cplx, $max_seg_size, $extra_dict, $detached) +self.$(id).set_unbuffered($unbuffered)</make> + <callback>set_unbuffered($unbuffered)</callback> + <callback>open($file)</callback> + <param> + <name>File</name> + <key>file</key> + <value></value> + <type>file_save</type> + </param> + <param> + <name>Input Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + <opt>dtype:blocks.GR_FILE_FLOAT</opt> + <opt>cplx:True</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + <opt>dtype:blocks.GR_FILE_FLOAT</opt> + <opt>cplx:False</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + <opt>dtype:blocks.GR_FILE_INT</opt> + <opt>cplx:False</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + <opt>dtype:blocks.GR_FILE_SHORT</opt> + <opt>cplx:False</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + <opt>dtype:blocks.GR_FILE_BYTE</opt> + <opt>cplx:False</opt> + </option> + </param> + <param> + <name>Sample Rate</name> + <key>samp_rate</key> + <value>samp_rate</value> + <type>real</type> + </param> + <param> + <name>Relative Rate Change</name> + <key>rel_rate</key> + <value>1</value> + <type>real</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <param> + <name>Max Seg. Size</name> + <key>max_seg_size</key> + <value>1000000</value> + <type>int</type> + </param> + <param> + <name>Extra Dict.</name> + <key>extra_dict</key> + <value>""</value> + <type>string</type> + </param> + <param> + <name>Detached</name> + <key>detached</key> + <value>False</value> + <type>bool</type> + <option> + <name>Off</name> + <key>False</key> + </option> + <option> + <name>On</name> + <key>True</key> + </option> + </param> <param> + <name>Unbuffered</name> + <key>unbuffered</key> + <value>False</value> + <type>bool</type> + <option> + <name>Off</name> + <key>False</key> + </option> + <option> + <name>On</name> + <key>True</key> + </option> + </param> + <check>$vlen > 0</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + </sink> +</block> diff --git a/gr-blocks/grc/blocks_file_meta_source.xml b/gr-blocks/grc/blocks_file_meta_source.xml new file mode 100644 index 000000000..aa7e34955 --- /dev/null +++ b/gr-blocks/grc/blocks_file_meta_source.xml @@ -0,0 +1,94 @@ +<?xml version="1.0"?> +<!-- +################################################### +##File Source +################################################### + --> +<block> + <name>File Meta Source</name> + <key>blocks_file_meta_source</key> + <import>from gnuradio import gr, blocks</import> + <make>blocks.file_meta_source($file, $repeat, $detached, $hdr_file)</make> + <callback>open($file, $repeat)</callback> + <param> + <name>Output Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>File</name> + <key>file</key> + <value></value> + <type>file_open</type> + </param> + <param> + <name>Repeat</name> + <key>repeat</key> + <value>True</value> + <type>enum</type> + <option> + <name>Yes</name> + <key>True</key> + </option> + <option> + <name>No</name> + <key>False</key> + </option> + </param> + <param> + <name>Detached Header</name> + <key>detached</key> + <value>False</value> + <type>enum</type> + <option> + <name>Yes</name> + <key>True</key> + </option> + <option> + <name>No</name> + <key>False</key> + </option> + </param> + <param> + <name>Header File</name> + <key>hdr_file</key> + <value></value> + <type>file_open</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/gr-blocks/grc/blocks_file_source.xml b/gr-blocks/grc/blocks_file_source.xml new file mode 100644 index 000000000..7ac573f2d --- /dev/null +++ b/gr-blocks/grc/blocks_file_source.xml @@ -0,0 +1,75 @@ +<?xml version="1.0"?> +<!-- +################################################### +##File Source +################################################### + --> +<block> + <name>File Source</name> + <key>blocks_file_source</key> + <import>from gnuradio import blocks</import> + <make>blocks.file_source($type.size*$vlen, $file, $repeat)</make> + <callback>open($file, $repeat)</callback> + <param> + <name>File</name> + <key>file</key> + <value></value> + <type>file_open</type> + </param> + <param> + <name>Output Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>Repeat</name> + <key>repeat</key> + <value>True</value> + <type>enum</type> + <option> + <name>Yes</name> + <key>True</key> + </option> + <option> + <name>No</name> + <key>False</key> + </option> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen > 0</check> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/gr-blocks/grc/blocks_float_to_char.xml b/gr-blocks/grc/blocks_float_to_char.xml new file mode 100644 index 000000000..e3854fc4e --- /dev/null +++ b/gr-blocks/grc/blocks_float_to_char.xml @@ -0,0 +1,35 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Float to Char: +################################################### + --> +<block> + <name>Float To Char</name> + <key>blocks_float_to_char</key> + <import>from gnuradio import blocks</import> + <make>blocks.float_to_char($vlen, $scale)</make> + <callback>set_scale($scale)</callback> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <param> + <name>Scale</name> + <key>scale</key> + <value>1</value> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>float</type> + <vlen>$vlen</vlen> + </sink> + <source> + <name>out</name> + <type>byte</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/gr-blocks/grc/blocks_float_to_complex.xml b/gr-blocks/grc/blocks_float_to_complex.xml new file mode 100644 index 000000000..6120d5887 --- /dev/null +++ b/gr-blocks/grc/blocks_float_to_complex.xml @@ -0,0 +1,36 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Float to Complex: +## one or two input streams +################################################### + --> +<block> + <name>Float To Complex</name> + <key>blocks_float_to_complex</key> + <import>from gnuradio import blocks</import> + <make>blocks.float_to_complex($vlen)</make> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen > 0</check> + <sink> + <name>re</name> + <type>float</type> + <vlen>$vlen</vlen> + </sink> + <sink> + <name>im</name> + <type>float</type> + <vlen>$vlen</vlen> + <optional>1</optional> + </sink> + <source> + <name>out</name> + <type>complex</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/gr-blocks/grc/blocks_float_to_int.xml b/gr-blocks/grc/blocks_float_to_int.xml new file mode 100644 index 000000000..0ff5d9cdf --- /dev/null +++ b/gr-blocks/grc/blocks_float_to_int.xml @@ -0,0 +1,35 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Float to Int: +################################################### + --> +<block> + <name>Float To Int</name> + <key>blocks_float_to_int</key> + <import>from gnuradio import blocks</import> + <make>blocks.float_to_int($vlen, $scale)</make> + <callback>set_scale($scale)</callback> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <param> + <name>Scale</name> + <key>scale</key> + <value>1</value> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>float</type> + <vlen>$vlen</vlen> + </sink> + <source> + <name>out</name> + <type>int</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/gr-blocks/grc/blocks_float_to_short.xml b/gr-blocks/grc/blocks_float_to_short.xml new file mode 100644 index 000000000..986e68ec4 --- /dev/null +++ b/gr-blocks/grc/blocks_float_to_short.xml @@ -0,0 +1,35 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Float to Short: +################################################### + --> +<block> + <name>Float To Short</name> + <key>blocks_float_to_short</key> + <import>from gnuradio import blocks</import> + <make>blocks.float_to_short($vlen, $scale)</make> + <callback>set_scale($scale)</callback> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <param> + <name>Scale</name> + <key>scale</key> + <value>1</value> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>float</type> + <vlen>$vlen</vlen> + </sink> + <source> + <name>out</name> + <type>short</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/gr-blocks/grc/blocks_float_uchar.xml b/gr-blocks/grc/blocks_float_uchar.xml new file mode 100644 index 000000000..d190eafcf --- /dev/null +++ b/gr-blocks/grc/blocks_float_uchar.xml @@ -0,0 +1,20 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Float to Unsigned Char: +################################################### + --> +<block> + <name>Float To UChar</name> + <key>blocks_float_to_uchar</key> + <import>from gnuradio import blocks</import> + <make>blocks.float_to_uchar()</make> + <sink> + <name>in</name> + <type>float</type> + </sink> + <source> + <name>out</name> + <type>byte</type> + </source> +</block> diff --git a/gr-blocks/grc/blocks_int_to_float.xml b/gr-blocks/grc/blocks_int_to_float.xml new file mode 100644 index 000000000..2bb25d8be --- /dev/null +++ b/gr-blocks/grc/blocks_int_to_float.xml @@ -0,0 +1,35 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Int to Float: +################################################### + --> +<block> + <name>Int To Float</name> + <key>blocks_int_to_float</key> + <import>from gnuradio import blocks</import> + <make>blocks.int_to_float($vlen, $scale)</make> + <callback>set_scale($scale)</callback> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <param> + <name>Scale</name> + <key>scale</key> + <value>1</value> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>int</type> + <vlen>$vlen</vlen> + </sink> + <source> + <name>out</name> + <type>float</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/gr-blocks/grc/blocks_integrate_xx.xml b/gr-blocks/grc/blocks_integrate_xx.xml new file mode 100644 index 000000000..13c2ec3c8 --- /dev/null +++ b/gr-blocks/grc/blocks_integrate_xx.xml @@ -0,0 +1,50 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Integrate +################################################### + --> +<block> + <name>Integrate</name> + <key>blocks_integrate_xx</key> + <import>from gnuradio import blocks</import> + <make>blocks.integrate_$(type.fcn)($decim)</make> + <param> + <name>IO Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>fcn:cc</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>fcn:ff</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>fcn:ii</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>fcn:ss</opt> + </option> + </param> + <param> + <name>Decimation</name> + <key>decim</key> + <type>int</type> + </param> + <sink> + <name>in</name> + <type>$type</type> + </sink> + <source> + <name>out</name> + <type>$type</type> + </source> +</block> diff --git a/gr-blocks/grc/blocks_interleave.xml b/gr-blocks/grc/blocks_interleave.xml new file mode 100644 index 000000000..f01a3be6d --- /dev/null +++ b/gr-blocks/grc/blocks_interleave.xml @@ -0,0 +1,67 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Interleave +################################################### + --> +<block> + <name>Interleave</name> + <key>blocks_interleave</key> + <import>from gnuradio import blocks</import> + <make>blocks.interleave($type.size*$vlen)</make> + <param> + <name>IO Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>Num Streams</name> + <key>num_streams</key> + <value>2</value> + <type>int</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$num_streams > 0</check> + <check>$vlen >= 1</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + <nports>$num_streams</nports> + </sink> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/gr-blocks/grc/blocks_interleaved_short_to_complex.xml b/gr-blocks/grc/blocks_interleaved_short_to_complex.xml new file mode 100644 index 000000000..e44113e74 --- /dev/null +++ b/gr-blocks/grc/blocks_interleaved_short_to_complex.xml @@ -0,0 +1,20 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Interleaved Short to Complex: +################################################### + --> +<block> + <name>IShort To Complex</name> + <key>blocks_interleaved_short_to_complex</key> + <import>from gnuradio import blocks</import> + <make>blocks.interleaved_short_to_complex()</make> + <sink> + <name>in</name> + <type>short</type> + </sink> + <source> + <name>out</name> + <type>complex</type> + </source> +</block> diff --git a/gr-blocks/grc/blocks_keep_m_in_n.xml b/gr-blocks/grc/blocks_keep_m_in_n.xml new file mode 100644 index 000000000..9e861749b --- /dev/null +++ b/gr-blocks/grc/blocks_keep_m_in_n.xml @@ -0,0 +1,76 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Keep M in N +################################################### + --> +<block> + <name>Keep M in N</name> + <key>blocks_keep_m_in_n</key> + <import>from gnuradio import blocks</import> + <make>blocks.keep_m_in_n($type.size, $m, $n, $offset)</make> + <callback>set_offset($offset)</callback> + <callback>set_m($m)</callback> + <callback>set_n($n)</callback> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>M</name> + <key>m</key> + <value>1</value> + <type>int</type> + </param> + <param> + <name>N</name> + <key>n</key> + <value>2</value> + <type>int</type> + </param> + <param> + <name>initial offset</name> + <key>offset</key> + <value>0</value> + <type>int</type> + </param> + <check>$n > 0</check> + <check>$m > 0</check> + <check>$m < $n</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>1</vlen> + </sink> + <source> + <name>out</name> + <type>$type</type> + <vlen>1</vlen> + </source> +</block> diff --git a/gr-blocks/grc/blocks_keep_one_in_n.xml b/gr-blocks/grc/blocks_keep_one_in_n.xml new file mode 100644 index 000000000..4289a984f --- /dev/null +++ b/gr-blocks/grc/blocks_keep_one_in_n.xml @@ -0,0 +1,67 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Keep 1 in N +################################################### + --> +<block> + <name>Keep 1 in N</name> + <key>blocks_keep_one_in_n</key> + <import>from gnuradio import blocks</import> + <make>blocks.keep_one_in_n($type.size*$vlen, $n)</make> + <callback>set_n($n)</callback> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>N</name> + <key>n</key> + <value>1</value> + <type>int</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$n > 0</check> + <check>$vlen > 0</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + </sink> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/gr-blocks/grc/blocks_multiply_conjugate_cc.xml b/gr-blocks/grc/blocks_multiply_conjugate_cc.xml new file mode 100644 index 000000000..cf0acf4d8 --- /dev/null +++ b/gr-blocks/grc/blocks_multiply_conjugate_cc.xml @@ -0,0 +1,35 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Multiply Conjugate Block: +## 2 complex inputs, 1 complex output +################################################### + --> +<block> + <name>Multiply Conjugate</name> + <key>blocks_multiply_conjugate_cc</key> + <import>from gnuradio import blocks</import> + <make>blocks.multiply_conjugate_cc($vlen)</make> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen > 0</check> + <sink> + <name>in0</name> + <type>complex</type> + <vlen>$vlen</vlen> + </sink> + <sink> + <name>in1</name> + <type>complex</type> + <vlen>$vlen</vlen> + </sink> + <source> + <name>out</name> + <type>complex</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/gr-blocks/grc/blocks_multiply_const_vxx.xml b/gr-blocks/grc/blocks_multiply_const_vxx.xml new file mode 100644 index 000000000..6162621d3 --- /dev/null +++ b/gr-blocks/grc/blocks_multiply_const_vxx.xml @@ -0,0 +1,67 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Multiply Const Block: +## all types, 1 output, 1 input & const +################################################### + --> +<block> + <name>Multiply Const</name> + <key>blocks_multiply_const_vxx</key> + <import>from gnuradio import blocks</import> + <make>blocks.multiply_const_v$(type.fcn)($const)</make> + <callback>set_k($const)</callback> + <param> + <name>IO Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>const_type:complex_vector</opt> + <opt>fcn:cc</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>const_type:real_vector</opt> + <opt>fcn:ff</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>const_type:int_vector</opt> + <opt>fcn:ii</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>const_type:int_vector</opt> + <opt>fcn:ss</opt> + </option> + </param> + <param> + <name>Constant</name> + <key>const</key> + <value>0</value> + <type>$type.const_type</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>len($const) == $vlen</check> + <check>$vlen > 0</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + </sink> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/gr-blocks/grc/blocks_multiply_xx.xml b/gr-blocks/grc/blocks_multiply_xx.xml new file mode 100644 index 000000000..15f024142 --- /dev/null +++ b/gr-blocks/grc/blocks_multiply_xx.xml @@ -0,0 +1,63 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Multiply Block: +## all types, 1 output, 2 to inf inputs +################################################### + --> +<block> + <name>Multiply</name> + <key>blocks_multiply_xx</key> + <import>from gnuradio import blocks</import> + <make>blocks.multiply_v$(type.fcn)($vlen)</make> + <param> + <name>IO Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>fcn:cc</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>fcn:ff</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>fcn:ii</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>fcn:ss</opt> + </option> + </param> + <param> + <name>Num Inputs</name> + <key>num_inputs</key> + <value>2</value> + <type>int</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$num_inputs > 1</check> + <check>$vlen > 0</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + <nports>$num_inputs</nports> + </sink> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/gr-blocks/grc/blocks_nlog10_ff.xml b/gr-blocks/grc/blocks_nlog10_ff.xml new file mode 100644 index 000000000..884f4a444 --- /dev/null +++ b/gr-blocks/grc/blocks_nlog10_ff.xml @@ -0,0 +1,42 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Log10 Block: +## float in/ float out +################################################### + --> +<block> + <name>Log10</name> + <key>blocks_nlog10_ff</key> + <import>from gnuradio import blocks</import> + <make>blocks.nlog10_ff($n, $vlen, $k)</make> + <param> + <name>n</name> + <key>n</key> + <value>1</value> + <type>real</type> + </param> + <param> + <name>k</name> + <key>k</key> + <value>0</value> + <type>real</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen >= 1</check> + <sink> + <name>in</name> + <type>float</type> + <vlen>$vlen</vlen> + </sink> + <source> + <name>out</name> + <type>float</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/gr-blocks/grc/blocks_not_xx.xml b/gr-blocks/grc/blocks_not_xx.xml new file mode 100644 index 000000000..fe8916d8b --- /dev/null +++ b/gr-blocks/grc/blocks_not_xx.xml @@ -0,0 +1,40 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Logical Not Block +################################################### + --> +<block> + <name>Not</name> + <key>blocks_not_xx</key> + <import>from gnuradio import blocks</import> + <make>blocks.not_$(type.fcn)()</make> + <param> + <name>IO Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Int</name> + <key>int</key> + <opt>fcn:ii</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>fcn:ss</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>fcn:bb</opt> + </option> + </param> + <sink> + <name>in</name> + <type>$type</type> + </sink> + <source> + <name>out</name> + <type>$type</type> + </source> +</block> diff --git a/gr-blocks/grc/blocks_or_xx.xml b/gr-blocks/grc/blocks_or_xx.xml new file mode 100644 index 000000000..400c09389 --- /dev/null +++ b/gr-blocks/grc/blocks_or_xx.xml @@ -0,0 +1,48 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Logical Or Block +################################################### + --> +<block> + <name>Or</name> + <key>blocks_or_xx</key> + <import>from gnuradio import blocks</import> + <make>blocks.or_$(type.fcn)()</make> + <param> + <name>IO Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Int</name> + <key>int</key> + <opt>fcn:ii</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>fcn:ss</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>fcn:bb</opt> + </option> + </param> + <param> + <name>Num Inputs</name> + <key>num_inputs</key> + <value>2</value> + <type>int</type> + </param> + <check>$num_inputs >= 2</check> + <sink> + <name>in</name> + <type>$type</type> + <nports>$num_inputs</nports> + </sink> + <source> + <name>out</name> + <type>$type</type> + </source> +</block> diff --git a/gr-blocks/grc/blocks_patterned_interleaver.xml b/gr-blocks/grc/blocks_patterned_interleaver.xml new file mode 100644 index 000000000..8dd0fac41 --- /dev/null +++ b/gr-blocks/grc/blocks_patterned_interleaver.xml @@ -0,0 +1,66 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Vector to Stream +################################################### + --> +<block> + <name>Patterned Interleaver</name> + <key>blocks_patterned_interleaver</key> + <import>from gnuradio import blocks</import> + <make>blocks.patterned_interleaver($type.size*$vlen, $pattern)</make> + <param> + <name>IO Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>Pattern</name> + <key>pattern</key> + <value>[0,0,1,2]</value> + <type>int_vector</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen >= 1</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + <nports>1+max($pattern)</nports> + </sink> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/gr-blocks/grc/blocks_repeat.xml b/gr-blocks/grc/blocks_repeat.xml new file mode 100644 index 000000000..c6c17c990 --- /dev/null +++ b/gr-blocks/grc/blocks_repeat.xml @@ -0,0 +1,64 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Repeat +################################################### + --> +<block> + <name>Repeat</name> + <key>blocks_repeat</key> + <import>from gnuradio import blocks</import> + <make>blocks.repeat($type.size*$vlen, $interp)</make> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>Interpolation</name> + <key>interp</key> + <type>int</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen > 0</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + </sink> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/gr-blocks/grc/blocks_short_to_char.xml b/gr-blocks/grc/blocks_short_to_char.xml new file mode 100644 index 000000000..1951333d1 --- /dev/null +++ b/gr-blocks/grc/blocks_short_to_char.xml @@ -0,0 +1,28 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Short to char: +################################################### + --> +<block> + <name>Short To Char</name> + <key>blocks_short_to_char</key> + <import>from gnuradio import blocks</import> + <make>blocks.short_to_char($vlen)</make> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <sink> + <name>in</name> + <type>short</type> + <vlen>$vlen</vlen> + </sink> + <source> + <name>out</name> + <type>byte</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/gr-blocks/grc/blocks_short_to_float.xml b/gr-blocks/grc/blocks_short_to_float.xml new file mode 100644 index 000000000..23ea019bc --- /dev/null +++ b/gr-blocks/grc/blocks_short_to_float.xml @@ -0,0 +1,35 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Short to Float: +################################################### + --> +<block> + <name>Short To Float</name> + <key>blocks_short_to_float</key> + <import>from gnuradio import blocks</import> + <make>blocks.short_to_float($vlen, $scale)</make> + <callback>set_scale($scale)</callback> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <param> + <name>Scale</name> + <key>scale</key> + <value>1</value> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>short</type> + <vlen>$vlen</vlen> + </sink> + <source> + <name>out</name> + <type>float</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/gr-blocks/grc/blocks_stream_mux.xml b/gr-blocks/grc/blocks_stream_mux.xml new file mode 100644 index 000000000..5e56a65d9 --- /dev/null +++ b/gr-blocks/grc/blocks_stream_mux.xml @@ -0,0 +1,75 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Stream Mux: +## all types, many inputs, only one output +################################################### + --> +<block> + <name>Stream Mux</name> + <key>blocks_stream_mux</key> + <import>from gnuradio import blocks</import> + <make>blocks.stream_mux($type.size*$vlen, $lengths)</make> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>Lengths</name> + <key>lengths</key> + <value>1, 1</value> + <type>int_vector</type> + </param> + <param> + <name>Num Inputs</name> + <key>num_inputs</key> + <value>2</value> + <type>int</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$num_inputs > 0</check> + <check>$num_inputs == len($lengths)</check> + <check>$vlen > 0</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + <nports>$num_inputs</nports> + </sink> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/gr-blocks/grc/blocks_stream_to_streams.xml b/gr-blocks/grc/blocks_stream_to_streams.xml new file mode 100644 index 000000000..c164e477b --- /dev/null +++ b/gr-blocks/grc/blocks_stream_to_streams.xml @@ -0,0 +1,67 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Stream to Streams +################################################### + --> +<block> + <name>Stream to Streams</name> + <key>blocks_stream_to_streams</key> + <import>from gnuradio import blocks</import> + <make>blocks.stream_to_streams($type.size*$vlen, $num_streams)</make> + <param> + <name>IO Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>Num Streams</name> + <key>num_streams</key> + <value>2</value> + <type>int</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$num_streams > 0</check> + <check>$vlen >= 1</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + </sink> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + <nports>$num_streams</nports> + </source> +</block> diff --git a/gr-blocks/grc/blocks_stream_to_vector.xml b/gr-blocks/grc/blocks_stream_to_vector.xml new file mode 100644 index 000000000..8965dfbfe --- /dev/null +++ b/gr-blocks/grc/blocks_stream_to_vector.xml @@ -0,0 +1,66 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Stream to Vector +################################################### + --> +<block> + <name>Stream to Vector</name> + <key>blocks_stream_to_vector</key> + <import>from gnuradio import blocks</import> + <make>blocks.stream_to_vector($type.size*$vlen, $num_items)</make> + <param> + <name>IO Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>Num Items</name> + <key>num_items</key> + <value>2</value> + <type>int</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$num_items > 0</check> + <check>$vlen >= 1</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + </sink> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen*$num_items</vlen> + </source> +</block> diff --git a/gr-blocks/grc/blocks_streams_to_stream.xml b/gr-blocks/grc/blocks_streams_to_stream.xml new file mode 100644 index 000000000..2aa17dbe2 --- /dev/null +++ b/gr-blocks/grc/blocks_streams_to_stream.xml @@ -0,0 +1,67 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Streams to Stream +################################################### + --> +<block> + <name>Streams to Stream</name> + <key>blocks_streams_to_stream</key> + <import>from gnuradio import blocks</import> + <make>blocks.streams_to_stream($type.size*$vlen, $num_streams)</make> + <param> + <name>IO Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>Num Streams</name> + <key>num_streams</key> + <value>2</value> + <type>int</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$num_streams > 0</check> + <check>$vlen >= 1</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + <nports>$num_streams</nports> + </sink> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/gr-blocks/grc/blocks_streams_to_vector.xml b/gr-blocks/grc/blocks_streams_to_vector.xml new file mode 100644 index 000000000..dc371f021 --- /dev/null +++ b/gr-blocks/grc/blocks_streams_to_vector.xml @@ -0,0 +1,67 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Streams to Vector +################################################### + --> +<block> + <name>Streams to Vector</name> + <key>blocks_streams_to_vector</key> + <import>from gnuradio import blocks</import> + <make>blocks.streams_to_vector($type.size*$vlen, $num_streams)</make> + <param> + <name>IO Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>Num Streams</name> + <key>num_streams</key> + <value>2</value> + <type>int</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$num_streams > 0</check> + <check>$vlen >= 1</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + <nports>$num_streams</nports> + </sink> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen*$num_streams</vlen> + </source> +</block> diff --git a/gr-blocks/grc/blocks_sub_xx.xml b/gr-blocks/grc/blocks_sub_xx.xml new file mode 100644 index 000000000..ae01cf74a --- /dev/null +++ b/gr-blocks/grc/blocks_sub_xx.xml @@ -0,0 +1,63 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Subtract Block: +## all types, 1 output, 2 to inf inputs +################################################### + --> +<block> + <name>Subtract</name> + <key>blocks_sub_xx</key> + <import>from gnuradio import blocks</import> + <make>blocks.sub_$(type.fcn)($vlen)</make> + <param> + <name>IO Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>fcn:cc</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>fcn:ff</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>fcn:ii</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>fcn:ss</opt> + </option> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <param> + <name>Num Inputs</name> + <key>num_inputs</key> + <value>2</value> + <type>int</type> + </param> + <check>$vlen > 0</check> + <check>$num_inputs >= 2</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + <nports>$num_inputs</nports> + </sink> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/gr-blocks/grc/blocks_uchar_to_float.xml b/gr-blocks/grc/blocks_uchar_to_float.xml new file mode 100644 index 000000000..eb2b5505e --- /dev/null +++ b/gr-blocks/grc/blocks_uchar_to_float.xml @@ -0,0 +1,20 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Unsigned Char to Float: +################################################### + --> +<block> + <name>UChar To Float</name> + <key>blocks_uchar_to_float</key> + <import>from gnuradio import blocks</import> + <make>blocks.uchar_to_float()</make> + <sink> + <name>in</name> + <type>byte</type> + </sink> + <source> + <name>out</name> + <type>float</type> + </source> +</block> diff --git a/gr-blocks/grc/blocks_vector_to_stream.xml b/gr-blocks/grc/blocks_vector_to_stream.xml new file mode 100644 index 000000000..a4a77bef8 --- /dev/null +++ b/gr-blocks/grc/blocks_vector_to_stream.xml @@ -0,0 +1,66 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Vector to Stream +################################################### + --> +<block> + <name>Vector to Stream</name> + <key>blocks_vector_to_stream</key> + <import>from gnuradio import blocks</import> + <make>blocks.vector_to_stream($type.size*$vlen, $num_items)</make> + <param> + <name>IO Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>Num Items</name> + <key>num_items</key> + <value>2</value> + <type>int</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$num_items > 0</check> + <check>$vlen >= 1</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen*$num_items</vlen> + </sink> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/gr-blocks/grc/blocks_vector_to_streams.xml b/gr-blocks/grc/blocks_vector_to_streams.xml new file mode 100644 index 000000000..6a246b98d --- /dev/null +++ b/gr-blocks/grc/blocks_vector_to_streams.xml @@ -0,0 +1,67 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Vector to Streams +################################################### + --> +<block> + <name>Vector to Streams</name> + <key>blocks_vector_to_streams</key> + <import>from gnuradio import blocks</import> + <make>blocks.vector_to_streams($type.size*$vlen, $num_streams)</make> + <param> + <name>IO Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>Num Streams</name> + <key>num_streams</key> + <value>2</value> + <type>int</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$num_streams > 0</check> + <check>$vlen >= 1</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen*$num_streams</vlen> + </sink> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + <nports>$num_streams</nports> + </source> +</block> diff --git a/gr-blocks/grc/blocks_xor_xx.xml b/gr-blocks/grc/blocks_xor_xx.xml new file mode 100644 index 000000000..d2886a4e0 --- /dev/null +++ b/gr-blocks/grc/blocks_xor_xx.xml @@ -0,0 +1,48 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Logical Xor Block +################################################### + --> +<block> + <name>Xor</name> + <key>blocks_xor_xx</key> + <import>from gnuradio import blocks</import> + <make>blocks.xor_$(type.fcn)()</make> + <param> + <name>IO Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Int</name> + <key>int</key> + <opt>fcn:ii</opt> + </option> + <option> + <name>Shxort</name> + <key>short</key> + <opt>fcn:ss</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>fcn:bb</opt> + </option> + </param> + <param> + <name>Num Inputs</name> + <key>num_inputs</key> + <value>2</value> + <type>int</type> + </param> + <check>$num_inputs >= 2</check> + <sink> + <name>in</name> + <type>$type</type> + <nports>$num_inputs</nports> + </sink> + <source> + <name>out</name> + <type>$type</type> + </source> +</block> diff --git a/gr-blocks/include/blocks/CMakeLists.txt b/gr-blocks/include/blocks/CMakeLists.txt new file mode 100644 index 000000000..0459097b0 --- /dev/null +++ b/gr-blocks/include/blocks/CMakeLists.txt @@ -0,0 +1,137 @@ +# Copyright 2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. + +######################################################################## +# generate helper scripts to expand templated files +######################################################################## +include(GrPython) + +file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py " +#!${PYTHON_EXECUTABLE} + +import sys, os, re +sys.path.append('${GR_CORE_PYTHONPATH}') +os.environ['srcdir'] = '${CMAKE_CURRENT_SOURCE_DIR}' +os.chdir('${CMAKE_CURRENT_BINARY_DIR}') + +if __name__ == '__main__': + import build_utils + root, inp = sys.argv[1:3] + for sig in sys.argv[3:]: + name = re.sub ('X+', sig, root) + d = build_utils.standard_dict(name, sig, 'blocks') + build_utils.expand_template(d, inp) + +") + +macro(expand_h root) + #make a list of all the generated files + unset(expanded_files_h) + foreach(sig ${ARGN}) + string(REGEX REPLACE "X+" ${sig} name ${root}) + list(APPEND expanded_files_h ${CMAKE_CURRENT_BINARY_DIR}/${name}.h) + endforeach(sig) + + #create a command to generate the files + add_custom_command( + OUTPUT ${expanded_files_h} + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}.h.t + COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B} + ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py + ${root} ${root}.h.t ${ARGN} + ) + + #install rules for the generated h files + list(APPEND generated_includes ${expanded_files_h}) +endmacro(expand_h) + +######################################################################## +# Invoke macro to generate various sources +######################################################################## +expand_h(add_XX ss ii cc) +expand_h(add_const_XX ss ii ff cc) +expand_h(add_const_vXX ss ii ff cc) +expand_h(and_XX bb ss ii) +expand_h(and_const_XX bb ss ii) +expand_h(divide_XX ss ii ff cc) +expand_h(integrate_XX ss ii ff cc) +expand_h(multiply_XX ss ii) +expand_h(multiply_const_XX ss ii) +expand_h(multiply_const_vXX ss ii ff cc) +expand_h(not_XX bb ss ii) +expand_h(or_XX bb ss ii) +expand_h(sub_XX ss ii ff cc) +expand_h(xor_XX bb ss ii) + +add_custom_target(blocks_generated_includes DEPENDS + ${generated_includes} +) + +######################################################################## +# Install header files +######################################################################## +install(FILES + ${generated_includes} + api.h + add_ff.h + char_to_float.h + char_to_short.h + complex_to_interleaved_short.h + complex_to_float.h + complex_to_imag.h + complex_to_real.h + complex_to_mag.h + complex_to_mag_squared.h + complex_to_arg.h + conjugate_cc.h + deinterleave.h + file_source.h + file_meta_sink.h + file_meta_source.h + float_to_char.h + float_to_complex.h + float_to_int.h + float_to_short.h + float_to_uchar.h + int_to_float.h + interleave.h + interleaved_short_to_complex.h + keep_m_in_n.h + keep_one_in_n.h + multiply_cc.h + multiply_ff.h + multiply_conjugate_cc.h + multiply_const_cc.h + multiply_const_ff.h + nlog10_ff.h + patterned_interleaver.h + repeat.h + short_to_char.h + short_to_float.h + stream_mux.h + stream_to_streams.h + stream_to_vector.h + streams_to_stream.h + streams_to_vector.h + uchar_to_float.h + vector_to_stream.h + vector_to_streams.h + DESTINATION ${GR_INCLUDE_DIR}/gnuradio/blocks + COMPONENT "blocks_devel" +) diff --git a/gr-blocks/include/blocks/add_XX.h.t b/gr-blocks/include/blocks/add_XX.h.t new file mode 100644 index 000000000..607b82066 --- /dev/null +++ b/gr-blocks/include/blocks/add_XX.h.t @@ -0,0 +1,53 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2009,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifndef @GUARD_NAME@ +#define @GUARD_NAME@ + +#include <blocks/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace blocks { + + /*! + * \brief output = sum (input_0, input_1, ...) + * \ingroup math_blk + * + * Add across all input streams. + */ + class BLOCKS_API @NAME@ : virtual public gr_sync_block + { + public: + + // gr::blocks::@NAME@::sptr + typedef boost::shared_ptr<@NAME@> sptr; + + static sptr make(size_t vlen=1); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* @GUARD_NAME@ */ diff --git a/gr-blocks/include/blocks/add_const_XX.h.t b/gr-blocks/include/blocks/add_const_XX.h.t new file mode 100644 index 000000000..df968feac --- /dev/null +++ b/gr-blocks/include/blocks/add_const_XX.h.t @@ -0,0 +1,65 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifndef @GUARD_NAME@ +#define @GUARD_NAME@ + +#include <blocks/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace blocks { + + /*! + * \brief output = input + constant + * \ingroup math_blk + */ + class BLOCKS_API @NAME@ : virtual public gr_sync_block + { + public: + + // gr::blocks::@NAME@::sptr + typedef boost::shared_ptr<@NAME@> sptr; + + /*! + * \brief Create an instance of @NAME@ + * \param k additive constant + */ + static sptr make(@O_TYPE@ k); + + /*! + * \brief Return additive constant + */ + virtual @O_TYPE@ k() const = 0; + + /*! + * \brief Set additive constant + */ + virtual void set_k(@O_TYPE@ k) = 0; + }; + + } +} + +#endif /* @GUARD_NAME@ */ diff --git a/gr-blocks/include/blocks/add_const_vXX.h.t b/gr-blocks/include/blocks/add_const_vXX.h.t new file mode 100644 index 000000000..c4cd49fa4 --- /dev/null +++ b/gr-blocks/include/blocks/add_const_vXX.h.t @@ -0,0 +1,66 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2006,2010,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifndef @GUARD_NAME@ +#define @GUARD_NAME@ + +#include <blocks/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace blocks { + + /*! + * \brief output = input + constant vector + * \ingroup math_blk + */ + class BLOCKS_API @NAME@ : virtual public gr_sync_block + { + + public: + + // gr::blocks::@NAME@::sptr + typedef boost::shared_ptr<@NAME@> sptr; + + /*! + * \brief Create an instance of @NAME@ + * \param k additive constant vector + */ + static sptr make(std::vector<@O_TYPE@> k); + + /*! + * \brief Return additive constant vector + */ + virtual std::vector<@O_TYPE@> k() const = 0; + + /*! + * \brief Set additive constant vector + */ + virtual void set_k(std::vector<@O_TYPE@> k) = 0; + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* @GUARD_NAME@ */ diff --git a/gr-blocks/include/blocks/add_ff.h b/gr-blocks/include/blocks/add_ff.h new file mode 100644 index 000000000..1e7350c1b --- /dev/null +++ b/gr-blocks/include/blocks/add_ff.h @@ -0,0 +1,50 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_BLOCKS_ADD_FF_H +#define INCLUDED_BLOCKS_ADD_FF_H + +#include <blocks/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API add_ff : virtual public gr_sync_block + { + public: + + // gr::blocks::add_ff::sptr + typedef boost::shared_ptr<add_ff> sptr; + + /*! + * \brief Add streams of float values + * \param vlen Vector length + * \ingroup math_blk + */ + static sptr make(size_t vlen=1); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_BLOCKS_ADD_FF_H */ diff --git a/gr-blocks/include/blocks/and_XX.h.t b/gr-blocks/include/blocks/and_XX.h.t new file mode 100644 index 000000000..68ddcc33d --- /dev/null +++ b/gr-blocks/include/blocks/and_XX.h.t @@ -0,0 +1,53 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifndef @GUARD_NAME@ +#define @GUARD_NAME@ + +#include <blocks/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace blocks { + + /*! + * \brief output = input_0 & input_1 & , ... & input_N) + * \ingroup math_blk + * + * bitwise boolean and across all input streams. + */ + class BLOCKS_API @NAME@ : virtual public gr_sync_block + { + public: + + // gr::blocks::@NAME@::sptr + typedef boost::shared_ptr<@NAME@> sptr; + + static sptr make(size_t vlen=1); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* @GUARD_NAME@ */ diff --git a/gr-blocks/include/blocks/and_const_XX.h.t b/gr-blocks/include/blocks/and_const_XX.h.t new file mode 100644 index 000000000..945a1f48b --- /dev/null +++ b/gr-blocks/include/blocks/and_const_XX.h.t @@ -0,0 +1,68 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifndef @GUARD_NAME@ +#define @GUARD_NAME@ + +#include <blocks/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace blocks { + + /*! + * \brief output_N = input_N & value + * \ingroup math_blk + * + * bitwise boolean and of const to the data stream. + */ + class BLOCKS_API @NAME@ : virtual public gr_sync_block + { + + public: + + // gr::blocks::@NAME@::sptr + typedef boost::shared_ptr<@NAME@> sptr; + + /*! + * \brief Create an instance of @NAME@ + * \param k AND constant + */ + static sptr make(@O_TYPE@ k); + + /*! + * \brief Return AND constant + */ + virtual @O_TYPE@ k() const = 0; + + /*! + * \brief Set AND constant + */ + virtual void set_k(@O_TYPE@ k) = 0; + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* @GUARD_NAME@ */ diff --git a/gr-blocks/include/blocks/api.h b/gr-blocks/include/blocks/api.h new file mode 100644 index 000000000..45fbc0d21 --- /dev/null +++ b/gr-blocks/include/blocks/api.h @@ -0,0 +1,33 @@ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_BLOCKS_API_H +#define INCLUDED_BLOCKS_API_H + +#include <gruel/attributes.h> + +#ifdef gnuradio_blocks_EXPORTS +# define BLOCKS_API __GR_ATTR_EXPORT +#else +# define BLOCKS_API __GR_ATTR_IMPORT +#endif + +#endif /* INCLUDED_BLOCKS_API_H */ diff --git a/gr-blocks/include/blocks/char_to_float.h b/gr-blocks/include/blocks/char_to_float.h new file mode 100644 index 000000000..92a2dbf80 --- /dev/null +++ b/gr-blocks/include/blocks/char_to_float.h @@ -0,0 +1,62 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_BLOCKS_CHAR_TO_FLOAT_H +#define INCLUDED_BLOCKS_CHAR_TO_FLOAT_H + +#include <blocks/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace blocks { + + /*! + * \brief Convert stream of chars to a stream of float + * \ingroup converter_blk + * + * \param vlen vector length of data streams. + * \param scale a scalar divider to change the output signal scale. + */ + class BLOCKS_API char_to_float : virtual public gr_sync_block + { + public: + + // gr::blocks::char_to_float_ff::sptr + typedef boost::shared_ptr<char_to_float> sptr; + + static sptr make(size_t vlen=1, float scale=1.0); + + /*! + * Get the scalar divider value. + */ + virtual float scale() const = 0; + + /*! + * Set the scalar divider value. + */ + virtual void set_scale(float scale) = 0; + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_BLOCKS_CHAR_TO_FLOAT_H */ diff --git a/gr-blocks/include/blocks/char_to_short.h b/gr-blocks/include/blocks/char_to_short.h new file mode 100644 index 000000000..e2bb3a859 --- /dev/null +++ b/gr-blocks/include/blocks/char_to_short.h @@ -0,0 +1,51 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_BLOCKS_CHAR_TO_SHORT_H +#define INCLUDED_BLOCKS_CHAR_TO_SHORT_H + +#include <blocks/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace blocks { + + /*! + * \brief Convert stream of chars to a stream of short + * \ingroup converter_blk + * + * \param vlen vector length of data streams. + */ + class BLOCKS_API char_to_short : virtual public gr_sync_block + { + public: + + // gr::blocks::char_to_short_ff::sptr + typedef boost::shared_ptr<char_to_short> sptr; + + static sptr make(size_t vlen=1); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_BLOCKS_CHAR_TO_SHORT_H */ diff --git a/gr-blocks/include/blocks/complex_to_arg.h b/gr-blocks/include/blocks/complex_to_arg.h new file mode 100644 index 000000000..5d38161d4 --- /dev/null +++ b/gr-blocks/include/blocks/complex_to_arg.h @@ -0,0 +1,50 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_BLOCKS_COMPLEX_TO_ARG_H +#define INCLUDED_BLOCKS_COMPLEX_TO_ARG_H + +#include <blocks/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace blocks { + + /*! + * \brief complex in, arg out (float) + * \ingroup converter_blk + * \param vlen vector len (default 1) + */ + class BLOCKS_API complex_to_arg : virtual public gr_sync_block + { + public: + + // gr::blocks::complex_to_arg_ff::sptr + typedef boost::shared_ptr<complex_to_arg> sptr; + + static sptr make(size_t vlen=1); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_BLOCKS_COMPLEX_TO_ARG_H */ diff --git a/gr-blocks/include/blocks/complex_to_float.h b/gr-blocks/include/blocks/complex_to_float.h new file mode 100644 index 000000000..322f67b62 --- /dev/null +++ b/gr-blocks/include/blocks/complex_to_float.h @@ -0,0 +1,50 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_BLOCKS_COMPLEX_TO_FLOAT_H +#define INCLUDED_BLOCKS_COMPLEX_TO_FLOAT_H + +#include <blocks/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace blocks { + + /*! + * \brief convert a stream of gr_complex to 1 or 2 streams of float + * \ingroup converter_blk + * \param vlen vector len (default 1) + */ + class BLOCKS_API complex_to_float : virtual public gr_sync_block + { + public: + + // gr::blocks::complex_to_float_ff::sptr + typedef boost::shared_ptr<complex_to_float> sptr; + + static sptr make(size_t vlen=1); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_BLOCKS_COMPLEX_TO_FLOAT_H */ diff --git a/gr-blocks/include/blocks/complex_to_imag.h b/gr-blocks/include/blocks/complex_to_imag.h new file mode 100644 index 000000000..71353a94a --- /dev/null +++ b/gr-blocks/include/blocks/complex_to_imag.h @@ -0,0 +1,50 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_BLOCKS_COMPLEX_TO_IMAG_H +#define INCLUDED_BLOCKS_COMPLEX_TO_IMAG_H + +#include <blocks/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace blocks { + + /*! + * \brief complex in, imag out (float) + * \ingroup converter_blk + * \param vlen vector len (default 1) + */ + class BLOCKS_API complex_to_imag : virtual public gr_sync_block + { + public: + + // gr::blocks::complex_to_imag_ff::sptr + typedef boost::shared_ptr<complex_to_imag> sptr; + + static sptr make(size_t vlen=1); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_BLOCKS_COMPLEX_TO_IMAG_H */ diff --git a/gr-blocks/include/blocks/complex_to_interleaved_short.h b/gr-blocks/include/blocks/complex_to_interleaved_short.h new file mode 100644 index 000000000..f5e91123c --- /dev/null +++ b/gr-blocks/include/blocks/complex_to_interleaved_short.h @@ -0,0 +1,49 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_BLOCKS_COMPLEX_TO_INTERLEAVED_SHORT_H +#define INCLUDED_BLOCKS_COMPLEX_TO_INTERLEAVED_SHORT_H + +#include <blocks/api.h> +#include <gr_sync_interpolator.h> + +namespace gr { + namespace blocks { + + /*! + * \brief Convert stream of complex to a stream of interleaved shorts + * \ingroup converter_blk + */ + class BLOCKS_API complex_to_interleaved_short : virtual public gr_sync_interpolator + { + public: + + // gr::blocks::complex_to_interleaved_short::sptr + typedef boost::shared_ptr<complex_to_interleaved_short> sptr; + + static sptr make(); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_BLOCKS_COMPLEX_TO_INTERLEAVED_SHORT_H */ diff --git a/gr-blocks/include/blocks/complex_to_mag.h b/gr-blocks/include/blocks/complex_to_mag.h new file mode 100644 index 000000000..7e03c1cac --- /dev/null +++ b/gr-blocks/include/blocks/complex_to_mag.h @@ -0,0 +1,50 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_BLOCKS_COMPLEX_TO_MAG_H +#define INCLUDED_BLOCKS_COMPLEX_TO_MAG_H + +#include <blocks/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace blocks { + + /*! + * \brief complex in, magnitude out (float) + * \ingroup converter_blk + * \param vlen vector len (default 1) + */ + class BLOCKS_API complex_to_mag : virtual public gr_sync_block + { + public: + + // gr::blocks::complex_to_mag_ff::sptr + typedef boost::shared_ptr<complex_to_mag> sptr; + + static sptr make(size_t vlen=1); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_BLOCKS_COMPLEX_TO_MAG_H */ diff --git a/gr-blocks/include/blocks/complex_to_mag_squared.h b/gr-blocks/include/blocks/complex_to_mag_squared.h new file mode 100644 index 000000000..9e122b4b1 --- /dev/null +++ b/gr-blocks/include/blocks/complex_to_mag_squared.h @@ -0,0 +1,50 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_BLOCKS_COMPLEX_TO_MAG_SQUARED_H +#define INCLUDED_BLOCKS_COMPLEX_TO_MAG_SQUARED_H + +#include <blocks/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace blocks { + + /*! + * \brief complex in, magnitude squared out (float) + * \ingroup converter_blk + * \param vlen vector len (default 1) + */ + class BLOCKS_API complex_to_mag_squared : virtual public gr_sync_block + { + public: + + // gr::blocks::complex_to_mag_squared_ff::sptr + typedef boost::shared_ptr<complex_to_mag_squared> sptr; + + static sptr make(size_t vlen=1); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_BLOCKS_COMPLEX_TO_MAG_SQUARED_H */ diff --git a/gr-blocks/include/blocks/complex_to_real.h b/gr-blocks/include/blocks/complex_to_real.h new file mode 100644 index 000000000..a891c2e08 --- /dev/null +++ b/gr-blocks/include/blocks/complex_to_real.h @@ -0,0 +1,50 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_BLOCKS_COMPLEX_TO_REAL_H +#define INCLUDED_BLOCKS_COMPLEX_TO_REAL_H + +#include <blocks/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace blocks { + + /*! + * \brief complex in, real out (float) + * \ingroup converter_blk + * \param vlen vector len (default 1) + */ + class BLOCKS_API complex_to_real : virtual public gr_sync_block + { + public: + + // gr::blocks::complex_to_real_ff::sptr + typedef boost::shared_ptr<complex_to_real> sptr; + + static sptr make(size_t vlen=1); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_BLOCKS_COMPLEX_TO_REAL_H */ diff --git a/gr-blocks/include/blocks/conjugate_cc.h b/gr-blocks/include/blocks/conjugate_cc.h new file mode 100644 index 000000000..02297c56e --- /dev/null +++ b/gr-blocks/include/blocks/conjugate_cc.h @@ -0,0 +1,49 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_BLOCKS_CONJUGATE_CC_H +#define INCLUDED_BLOCKS_CONJUGATE_CC_H + +#include <blocks/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace blocks { + + /*! + * \brief output = complex conjugate of input + * \ingroup math_blk + */ + class BLOCKS_API conjugate_cc : virtual public gr_sync_block + { + public: + + // gr::blocks::conjugate_cc_ff::sptr + typedef boost::shared_ptr<conjugate_cc> sptr; + + static sptr make(); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_BLOCKS_CONJUGATE_CC_H */ diff --git a/gr-blocks/include/blocks/deinterleave.h b/gr-blocks/include/blocks/deinterleave.h new file mode 100644 index 000000000..24074d2fc --- /dev/null +++ b/gr-blocks/include/blocks/deinterleave.h @@ -0,0 +1,50 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_BLOCKS_DEINTERLEAVE_H +#define INCLUDED_BLOCKS_DEINTERLEAVE_H + +#include <blocks/api.h> +#include <gr_sync_decimator.h> + +namespace gr { + namespace blocks { + + /*! + * \brief deinterleave a single input into N outputs + * \ingroup slicedice_blk + * \param itemsize stream itemsize + */ + class BLOCKS_API deinterleave : virtual public gr_sync_decimator + { + public: + + // gr::blocks::deinterleave::sptr + typedef boost::shared_ptr<deinterleave> sptr; + + static sptr make(size_t itemsize); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_BLOCKS_DEINTERLEAVE_H */ diff --git a/gr-blocks/include/blocks/divide_XX.h.t b/gr-blocks/include/blocks/divide_XX.h.t new file mode 100644 index 000000000..9a382e4a0 --- /dev/null +++ b/gr-blocks/include/blocks/divide_XX.h.t @@ -0,0 +1,53 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2009,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifndef @GUARD_NAME@ +#define @GUARD_NAME@ + +#include <blocks/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace blocks { + + /*! + * \brief output = input_0 / input_1 / input_x ...) + * \ingroup math_blk + * + * Divide across all input streams. + */ + class BLOCKS_API @NAME@ : virtual public gr_sync_block + { + public: + + // gr::blocks::@NAME@::sptr + typedef boost::shared_ptr<@NAME@> sptr; + + static sptr make(size_t vlen=1); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* @GUARD_NAME@ */ diff --git a/gr-blocks/include/blocks/file_meta_sink.h b/gr-blocks/include/blocks/file_meta_sink.h new file mode 100644 index 000000000..ef64887cf --- /dev/null +++ b/gr-blocks/include/blocks/file_meta_sink.h @@ -0,0 +1,111 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_BLOCKS_FILE_META_SINK_H +#define INCLUDED_BLOCKS_FILE_META_SINK_H + +#include <blocks/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace blocks { + + const char METADATA_VERSION = 0; + const size_t METADATA_HEADER_SIZE = 149; + + enum gr_file_types { + GR_FILE_BYTE=0, + GR_FILE_CHAR=0, + GR_FILE_SHORT=1, + GR_FILE_INT, + GR_FILE_LONG, + GR_FILE_LONG_LONG, + GR_FILE_FLOAT, + GR_FILE_DOUBLE, + }; + + /*! + * \brief Write stream to file with meta-data headers. + * \ingroup sink_blk + * + * These files represent data as binary information in between + * meta-data headers. The headers contain information about the + * type of data and properties of the data in the next segment of + * samples. The information includes: + * + * rx_rate (double): sample rate of data. + * rx_time (uint64_t, double): time stamp of first sample in segment. + * size (uint32_t): item size in bytes. + * type (gr_file_types as int32_t): data type. + * cplx (bool): Is data complex? + * strt (uint64_t): Starting byte of data in this segment. + * bytes (uint64_t): Size in bytes of data in this segment. + * + * Tags can be sent to the file to update the information, which + * will create a new header. Headers are found by searching from + * the first header (at position 0 in the file) and reading where + * the data segment starts plus the data segment size. Following + * will either be a new header or EOF. + */ + class BLOCKS_API file_meta_sink : virtual public gr_sync_block + { + public: + // gr::blocks::file_meta_sink::sptr + typedef boost::shared_ptr<file_meta_sink> sptr; + + /*! + * \brief Create a meta-data file sink. + * + * \param itemsize (size_t): Size of data type. + * \param filename (string): Name of file to write data to. + * \param samp_rate (double): Sample rate of data. If sample rate will be + * set by a tag, such as rx_tag from a UHD source, this is + * basically ignored. + * \param relative_rate (double): Rate chance from source of sample + * rate tag to sink. + * \param type (gr_file_types): Data type (int, float, etc.) + * \param complex (bool): If data stream is complex + * \param max_segment_size (size_t): Length of a single segment + * before the header is repeated (in items). + * \param extra_dict (string): a serialized PMT dictionary of extra + * information. Currently not supported. + * \param detached_header (bool): Set to true to store the header + * info in a separate file (named filename.hdr) + */ + static sptr make(size_t itemsize, const std::string &filename, + double samp_rate=1, double relative_rate=1, + gr_file_types type=GR_FILE_FLOAT, bool complex=true, + size_t max_segment_size=1000000, + const std::string &extra_dict="", + bool detached_header=false); + + virtual bool open(const std::string &filename) = 0; + virtual void close() = 0; + virtual void do_update() = 0; + + virtual void set_unbuffered(bool unbuffered) = 0; + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_BLOCKS_FILE_META_SINK_H */ diff --git a/gr-blocks/include/blocks/file_meta_source.h b/gr-blocks/include/blocks/file_meta_source.h new file mode 100644 index 000000000..a992d5243 --- /dev/null +++ b/gr-blocks/include/blocks/file_meta_source.h @@ -0,0 +1,81 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_BLOCKS_FILE_META_SOURCE_H +#define INCLUDED_BLOCKS_FILE_META_SOURCE_H + +#include <blocks/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace blocks { + + /*! + * \brief Reads stream from file with meta-data headers. Headers + * are parsed into tags. + * \ingroup source_blk + * + * The information in the metadata headers includes: + * + * rx_rate (double): sample rate of data. + * rx_time (uint64_t, double): time stamp of first sample in segment. + * size (uint32_t): item size in bytes. + * type (gr_file_types as int32_t): data type. + * cplx (bool): Is data complex? + * strt (uint64_t): Starting byte of data in this segment. + * bytes (uint64_t): Size in bytes of data in this segment. + * + * Any item inside of the extra header dictionary is ready out and + * made into a stream tag. + */ + class BLOCKS_API file_meta_source : virtual public gr_sync_block + { + public: + // gr::blocks::file_meta_source::sptr + typedef boost::shared_ptr<file_meta_source> sptr; + + /*! + * \brief Create a meta-data file source. + * + * \param filename (string): Name of file to write data to. + * \param repeat (bool): Repeats file when EOF is found. + * \param detached_header (bool): Set to true if header + * info is stored in a separate file (usually named filename.hdr) + * \param hdr_filename (string): Name of detached header file if used. + * Defaults to 'filename.hdr' if detached_header is true but this + * field is an empty string. + */ + static sptr make(const std::string &filename, + bool repeat=false, + bool detached_header=false, + const std::string &hdr_filename=""); + + virtual bool open(const std::string &filename, + const std::string &hdr_filename="") = 0; + virtual void close() = 0; + virtual void do_update() = 0; + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_BLOCKS_FILE_META_SOURCE_H */ diff --git a/gr-blocks/include/blocks/file_source.h b/gr-blocks/include/blocks/file_source.h new file mode 100644 index 000000000..1a12aa905 --- /dev/null +++ b/gr-blocks/include/blocks/file_source.h @@ -0,0 +1,85 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_BLOCKS_FILE_SOURCE_H +#define INCLUDED_BLOCKS_FILE_SOURCE_H + +#include <blocks/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace blocks { + + /*! + * \brief Read stream from file + * \ingroup source_blk + */ + class BLOCKS_API file_source : virtual public gr_sync_block + { + public: + + // gr::blocks::file_source::sptr + typedef boost::shared_ptr<file_source> sptr; + + /*! + * \brief Create a file source. + * + * Opens \p filename as a source of items into a flowgraph. The + * data is expected to be in binary format, item after item. The + * \p itemsize of the block determines the conversion from bits + * to items. + * + * If \p repeat is turned on, the file will repeat the file after + * it's reached the end. + * + * \param itemsize the size of each item in the file, in bytes + * \param filename name of the file to source from + * \param repeat repeat file from start + */ + static sptr make(size_t itemsize, const char *filename, bool repeat = false); + + /*! + * \brief seek file to \p seek_point relative to \p whence + * + * \param seek_point sample offset in file + * \param whence one of SEEK_SET, SEEK_CUR, SEEK_END (man fseek) + */ + virtual bool seek(long seek_point, int whence) = 0; + + /*! + * \brief Opens a new file. + * + * \param filename name of the file to source from + * \param repeat repeat file from start + */ + virtual void open(const char *filename, bool repeat) = 0; + + /*! + * \brief Close the file handle. + */ + virtual void close() = 0; + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_BLOCKS_FILE_SOURCE_H */ diff --git a/gr-blocks/include/blocks/float_to_char.h b/gr-blocks/include/blocks/float_to_char.h new file mode 100644 index 000000000..de9ea85e3 --- /dev/null +++ b/gr-blocks/include/blocks/float_to_char.h @@ -0,0 +1,62 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_BLOCKS_FLOAT_TO_CHAR_H +#define INCLUDED_BLOCKS_FLOAT_TO_CHAR_H + +#include <blocks/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace blocks { + + /*! + * \brief Convert stream of floats to a stream of char + * \ingroup converter_blk + * + * \param vlen vector length of data streams. + * \param scale a scalar multiplier to change the output signal scale. + */ + class BLOCKS_API float_to_char : virtual public gr_sync_block + { + public: + + // gr::blocks::float_to_char_ff::sptr + typedef boost::shared_ptr<float_to_char> sptr; + + static sptr make(size_t vlen=1, float scale=1.0); + + /*! + * Get the scalar multiplier value. + */ + virtual float scale() const = 0; + + /*! + * Set the scalar multiplier value. + */ + virtual void set_scale(float scale) = 0; + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_BLOCKS_FLOAT_TO_CHAR_H */ diff --git a/gr-blocks/include/blocks/float_to_complex.h b/gr-blocks/include/blocks/float_to_complex.h new file mode 100644 index 000000000..48c5b6ead --- /dev/null +++ b/gr-blocks/include/blocks/float_to_complex.h @@ -0,0 +1,50 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_BLOCKS_FLOAT_TO_COMPLEX_H +#define INCLUDED_BLOCKS_FLOAT_TO_COMPLEX_H + +#include <blocks/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace blocks { + + /*! + * \brief one or two floats in, complex out + * \ingroup converter_blk + * \param vlen vector len (default 1) + */ + class BLOCKS_API float_to_complex : virtual public gr_sync_block + { + public: + + // gr::blocks::float_to_complex_ff::sptr + typedef boost::shared_ptr<float_to_complex> sptr; + + static sptr make(size_t vlen=1); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_BLOCKS_FLOAT_TO_COMPLEX_H */ diff --git a/gr-blocks/include/blocks/float_to_int.h b/gr-blocks/include/blocks/float_to_int.h new file mode 100644 index 000000000..95c62e516 --- /dev/null +++ b/gr-blocks/include/blocks/float_to_int.h @@ -0,0 +1,62 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_BLOCKS_FLOAT_TO_INT_H +#define INCLUDED_BLOCKS_FLOAT_TO_INT_H + +#include <blocks/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace blocks { + + /*! + * \brief Convert stream of floats to a stream of char + * \ingroup converter_blk + * + * \param vlen vector length of data streams. + * \param scale a scalar multiplier to change the output signal scale. + */ + class BLOCKS_API float_to_int : virtual public gr_sync_block + { + public: + + // gr::blocks::float_to_int_ff::sptr + typedef boost::shared_ptr<float_to_int> sptr; + + static sptr make(size_t vlen=1, float scale=1.0); + + /*! + * Get the scalar multiplier value. + */ + virtual float scale() const = 0; + + /*! + * Set the scalar multiplier value. + */ + virtual void set_scale(float scale) = 0; + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_BLOCKS_FLOAT_TO_INT_H */ diff --git a/gr-blocks/include/blocks/float_to_short.h b/gr-blocks/include/blocks/float_to_short.h new file mode 100644 index 000000000..5f1ab3f95 --- /dev/null +++ b/gr-blocks/include/blocks/float_to_short.h @@ -0,0 +1,62 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_BLOCKS_FLOAT_TO_SHORT_H +#define INCLUDED_BLOCKS_FLOAT_TO_SHORT_H + +#include <blocks/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace blocks { + + /*! + * \brief Convert stream of floats to a stream of shorts + * \ingroup converter_blk + * + * \param vlen vector length of data streams. + * \param scale a scalar multiplier to change the output signal scale. + */ + class BLOCKS_API float_to_short : virtual public gr_sync_block + { + public: + + // gr::blocks::float_to_short_ff::sptr + typedef boost::shared_ptr<float_to_short> sptr; + + static sptr make(size_t vlen=1, float scale=1.0); + + /*! + * Get the scalar multiplier value. + */ + virtual float scale() const = 0; + + /*! + * Set the scalar multiplier value. + */ + virtual void set_scale(float scale) = 0; + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_BLOCKS_FLOAT_TO_SHORT_H */ diff --git a/gr-blocks/include/blocks/float_to_uchar.h b/gr-blocks/include/blocks/float_to_uchar.h new file mode 100644 index 000000000..b5d0d08f7 --- /dev/null +++ b/gr-blocks/include/blocks/float_to_uchar.h @@ -0,0 +1,49 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_BLOCKS_FLOAT_TO_UCHAR_H +#define INCLUDED_BLOCKS_FLOAT_TO_UCHAR_H + +#include <blocks/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace blocks { + + /*! + * \brief Convert stream of floats to a stream of unsigned chars + * \ingroup converter_blk + */ + class BLOCKS_API float_to_uchar : virtual public gr_sync_block + { + public: + + // gr::blocks::float_to_uchar_ff::sptr + typedef boost::shared_ptr<float_to_uchar> sptr; + + static sptr make(); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_BLOCKS_FLOAT_TO_UCHAR_H */ diff --git a/gr-blocks/include/blocks/int_to_float.h b/gr-blocks/include/blocks/int_to_float.h new file mode 100644 index 000000000..ebee1c3c9 --- /dev/null +++ b/gr-blocks/include/blocks/int_to_float.h @@ -0,0 +1,62 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_BLOCKS_INT_TO_FLOAT_H +#define INCLUDED_BLOCKS_INT_TO_FLOAT_H + +#include <blocks/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace blocks { + + /*! + * \brief Convert stream of ints to a stream of floats + * \ingroup converter_blk + * + * \param vlen vector length of data streams. + * \param scale a scalar divider to change the output signal scale. + */ + class BLOCKS_API int_to_float : virtual public gr_sync_block + { + public: + + // gr::blocks::int_to_float_ff::sptr + typedef boost::shared_ptr<int_to_float> sptr; + + static sptr make(size_t vlen=1, float scale=1.0); + + /*! + * Get the scalar divider value. + */ + virtual float scale() const = 0; + + /*! + * Set the scalar divider value. + */ + virtual void set_scale(float scale) = 0; + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_BLOCKS_INT_TO_FLOAT_H */ diff --git a/gr-blocks/include/blocks/integrate_XX.h.t b/gr-blocks/include/blocks/integrate_XX.h.t new file mode 100644 index 000000000..8a313a0ba --- /dev/null +++ b/gr-blocks/include/blocks/integrate_XX.h.t @@ -0,0 +1,51 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2009,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifndef @GUARD_NAME@ +#define @GUARD_NAME@ + +#include <blocks/api.h> +#include <gr_sync_decimator.h> + +namespace gr { + namespace blocks { + + /*! + * \brief Integrate successive samples and decimate + * \ingroup math_blk + */ + class BLOCKS_API @NAME@ : virtual public gr_sync_decimator + { + public: + + // gr::blocks::@NAME@::sptr + typedef boost::shared_ptr<@NAME@> sptr; + + static sptr make(int decim); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* @GUARD_NAME@ */ diff --git a/gr-blocks/include/blocks/interleave.h b/gr-blocks/include/blocks/interleave.h new file mode 100644 index 000000000..e98d01df9 --- /dev/null +++ b/gr-blocks/include/blocks/interleave.h @@ -0,0 +1,50 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_BLOCKS_INTERLEAVE_H +#define INCLUDED_BLOCKS_INTERLEAVE_H + +#include <blocks/api.h> +#include <gr_sync_interpolator.h> + +namespace gr { + namespace blocks { + + /*! + * \brief interleave N inputs into a single output + * \ingroup slicedice_blk + * \param itemsize stream itemsize + */ + class BLOCKS_API interleave : virtual public gr_sync_interpolator + { + public: + + // gr::blocks::interleave::sptr + typedef boost::shared_ptr<interleave> sptr; + + static sptr make(size_t itemsize); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_BLOCKS_INTERLEAVE_H */ diff --git a/gr-blocks/include/blocks/interleaved_short_to_complex.h b/gr-blocks/include/blocks/interleaved_short_to_complex.h new file mode 100644 index 000000000..40e96fc46 --- /dev/null +++ b/gr-blocks/include/blocks/interleaved_short_to_complex.h @@ -0,0 +1,49 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_BLOCKS_INTERLEAVED_SHORT_TO_COMPLEX_H +#define INCLUDED_BLOCKS_INTERLEAVED_SHORT_TO_COMPLEX_H + +#include <blocks/api.h> +#include <gr_sync_decimator.h> + +namespace gr { + namespace blocks { + + /*! + * \brief Convert stream of interleaved shorts to a stream of complex + * \ingroup converter_blk + */ + class BLOCKS_API interleaved_short_to_complex : virtual public gr_sync_decimator + { + public: + + // gr::blocks::interleaved_short_to_complex::sptr + typedef boost::shared_ptr<interleaved_short_to_complex> sptr; + + static sptr make(); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_BLOCKS_INTERLEAVED_SHORT_TO_COMPLEX_H */ diff --git a/gr-blocks/include/blocks/keep_m_in_n.h b/gr-blocks/include/blocks/keep_m_in_n.h new file mode 100644 index 000000000..806ec3de5 --- /dev/null +++ b/gr-blocks/include/blocks/keep_m_in_n.h @@ -0,0 +1,53 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_BLOCKS_KEEP_M_IN_N_H +#define INCLUDED_BLOCKS_KEEP_M_IN_N_H + +#include <blocks/api.h> +#include <gr_block.h> + +namespace gr { + namespace blocks { + + /*! + * \brief decimate a stream, keeping one item out of every n. + * \ingroup slicedice_blk + */ + class BLOCKS_API keep_m_in_n : virtual public gr_block + { + public: + + // gr::blocks::keep_m_in_n::sptr + typedef boost::shared_ptr<keep_m_in_n> sptr; + + static sptr make(size_t itemsize, int m, int n, int offset); + + virtual void set_m(int m) = 0; + virtual void set_n(int n) = 0; + virtual void set_offset(int offset) = 0; + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_BLOCKS_KEEP_M_IN_N_H */ diff --git a/gr-blocks/include/blocks/keep_one_in_n.h b/gr-blocks/include/blocks/keep_one_in_n.h new file mode 100644 index 000000000..c48784994 --- /dev/null +++ b/gr-blocks/include/blocks/keep_one_in_n.h @@ -0,0 +1,51 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_BLOCKS_KEEP_ONE_IN_N_H +#define INCLUDED_BLOCKS_KEEP_ONE_IN_N_H + +#include <blocks/api.h> +#include <gr_block.h> + +namespace gr { + namespace blocks { + + /*! + * \brief decimate a stream, keeping one item out of every n. + * \ingroup slicedice_blk + */ + class BLOCKS_API keep_one_in_n : virtual public gr_block + { + public: + + // gr::blocks::keep_one_in_n::sptr + typedef boost::shared_ptr<keep_one_in_n> sptr; + + static sptr make(size_t itemsize, int n); + + virtual void set_n(int n) = 0; + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_BLOCKS_KEEP_ONE_IN_N_H */ diff --git a/gr-blocks/include/blocks/multiply_XX.h.t b/gr-blocks/include/blocks/multiply_XX.h.t new file mode 100644 index 000000000..47ed3746c --- /dev/null +++ b/gr-blocks/include/blocks/multiply_XX.h.t @@ -0,0 +1,53 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004, 2009, 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifndef @GUARD_NAME@ +#define @GUARD_NAME@ + +#include <blocks/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace blocks { + + /*! + * \brief output = prod (input_0, input_1, ...) + * \ingroup math_blk + * + * Multiply across all input streams. + */ + class BLOCKS_API @NAME@ : virtual public gr_sync_block + { + public: + + // gr::blocks::@NAME@::sptr + typedef boost::shared_ptr<@NAME@> sptr; + + static sptr make(size_t vlen=1); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* @GUARD_NAME@ */ diff --git a/gr-blocks/include/blocks/multiply_cc.h b/gr-blocks/include/blocks/multiply_cc.h new file mode 100644 index 000000000..559fcda57 --- /dev/null +++ b/gr-blocks/include/blocks/multiply_cc.h @@ -0,0 +1,50 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_MULTIPLY_CC_H +#define INCLUDED_GR_MULTIPLY_CC_H + +#include <blocks/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API multiply_cc : virtual public gr_sync_block + { + public: + + // gr::blocks::multiply_cc::sptr + typedef boost::shared_ptr<multiply_cc> sptr; + + /*! + * \brief Multiply streams of complex values + * \param vlen Vector length + * \ingroup math_blk + */ + static sptr make(size_t vlen=1); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_BLOCKS_MULTIPLY_CC_H */ diff --git a/gr-blocks/include/blocks/multiply_conjugate_cc.h b/gr-blocks/include/blocks/multiply_conjugate_cc.h new file mode 100644 index 000000000..fc587ae2f --- /dev/null +++ b/gr-blocks/include/blocks/multiply_conjugate_cc.h @@ -0,0 +1,50 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_MULTIPLY_CONJUGATE_CC_H +#define INCLUDED_GR_MULTIPLY_CONJUGATE_CC_H + +#include <blocks/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API multiply_conjugate_cc : virtual public gr_sync_block + { + public: + + // gr::blocks::multiply_conjugate_cc::sptr + typedef boost::shared_ptr<multiply_conjugate_cc> sptr; + + /*! + * \brief Multiplies a streams by the conjugate of a second stream + * \param vlen Vector length + * \ingroup math_blk + */ + static sptr make(size_t vlen=1); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_BLOCKS_MULTIPLY_CONJUGATE_CC_H */ diff --git a/gr-blocks/include/blocks/multiply_const_XX.h.t b/gr-blocks/include/blocks/multiply_const_XX.h.t new file mode 100644 index 000000000..a7cd3a858 --- /dev/null +++ b/gr-blocks/include/blocks/multiply_const_XX.h.t @@ -0,0 +1,66 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifndef @GUARD_NAME@ +#define @GUARD_NAME@ + +#include <blocks/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace blocks { + + /*! + * \brief output = input * constant + * \ingroup math_blk + */ + class BLOCKS_API @NAME@ : virtual public gr_sync_block + { + + public: + + // gr::blocks::@NAME@::sptr + typedef boost::shared_ptr<@NAME@> sptr; + + /*! + * \brief Create an instance of @NAME@ + * \param k multiplicative constant + */ + static sptr make(@O_TYPE@ k); + + /*! + * \brief Return multiplicative constant + */ + virtual @O_TYPE@ k() const = 0; + + /*! + * \brief Set multiplicative constant + */ + virtual void set_k(@O_TYPE@ k) = 0; + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* @GUARD_NAME */ diff --git a/gr-blocks/include/blocks/multiply_const_cc.h b/gr-blocks/include/blocks/multiply_const_cc.h new file mode 100644 index 000000000..9572eaec7 --- /dev/null +++ b/gr-blocks/include/blocks/multiply_const_cc.h @@ -0,0 +1,67 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifndef INCLUDED_MULTIPLY_CONST_CC_H +#define INCLUDED_MULTIPLY_CONST_CC_H + +#include <blocks/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace blocks { + + /*! + * \brief output = input * complex constant + * \ingroup math_blk + */ + class BLOCKS_API multiply_const_cc : virtual public gr_sync_block + { + + public: + + // gr::blocks::multiply_const_cc::sptr + typedef boost::shared_ptr<multiply_const_cc> sptr; + + /*! + * \brief Create an instance of multiply_const_cc + * \param k complex multiplicative constant + * \param vlen Vector length of incoming stream + */ + static sptr make(gr_complex k, size_t vlen=1); + + /*! + * \brief Return complex multiplicative constant + */ + virtual gr_complex k() const = 0; + + /*! + * \brief Set complex multiplicative constant + */ + virtual void set_k(gr_complex k) = 0; + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_MULTIPLY_CONST_CC_H */ diff --git a/gr-blocks/include/blocks/multiply_const_ff.h b/gr-blocks/include/blocks/multiply_const_ff.h new file mode 100644 index 000000000..d2d5e805c --- /dev/null +++ b/gr-blocks/include/blocks/multiply_const_ff.h @@ -0,0 +1,67 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifndef INCLUDED_MULTIPLY_CONST_FF_H +#define INCLUDED_MULTIPLY_CONST_FF_H + +#include <blocks/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace blocks { + + /*! + * \brief output = input * real constant + * \ingroup math_blk + */ + class BLOCKS_API multiply_const_ff : virtual public gr_sync_block + { + + public: + + // gr::blocks::multiply_const_ff::sptr + typedef boost::shared_ptr<multiply_const_ff> sptr; + + /*! + * \brief Create an instance of multiply_const_ff + * \param k real multiplicative constant + * \param vlen Vector length of incoming stream + */ + static sptr make(float k, size_t vlen=1); + + /*! + * \brief Return real multiplicative constant + */ + virtual float k() const = 0; + + /*! + * \brief Set real multiplicative constant + */ + virtual void set_k(float k) = 0; + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_MULTIPLY_CONST_FF_H */ diff --git a/gr-blocks/include/blocks/multiply_const_vXX.h.t b/gr-blocks/include/blocks/multiply_const_vXX.h.t new file mode 100644 index 000000000..4cd479f00 --- /dev/null +++ b/gr-blocks/include/blocks/multiply_const_vXX.h.t @@ -0,0 +1,66 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2006,2010,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifndef @GUARD_NAME@ +#define @GUARD_NAME@ + +#include <blocks/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace blocks { + + /*! + * \brief output = input * constant vector (element-wise) + * \ingroup math_blk + */ + class BLOCKS_API @NAME@ : virtual public gr_sync_block + { + + public: + + // gr::blocks::@NAME@::sptr + typedef boost::shared_ptr<@NAME@> sptr; + + /*! + * \brief Create an instance of @NAME@ + * \param k multiplicative constant vector + */ + static sptr make(std::vector<@O_TYPE@> k); + + /*! + * \brief Return multiplicative constant vector + */ + virtual std::vector<@O_TYPE@> k() const = 0; + + /*! + * \brief Set multiplicative constant vector + */ + virtual void set_k(std::vector<@O_TYPE@> k) = 0; + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* @GUARD_NAME@ */ diff --git a/gr-blocks/include/blocks/multiply_ff.h b/gr-blocks/include/blocks/multiply_ff.h new file mode 100644 index 000000000..683b540bb --- /dev/null +++ b/gr-blocks/include/blocks/multiply_ff.h @@ -0,0 +1,50 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_MULTIPLY_FF_H +#define INCLUDED_GR_MULTIPLY_FF_H + +#include <blocks/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API multiply_ff : virtual public gr_sync_block + { + public: + + // gr::blocks::multiply_ff::sptr + typedef boost::shared_ptr<multiply_ff> sptr; + + /*! + * \brief Multiply streams of float values + * \param vlen Vector length + * \ingroup math_blk + */ + static sptr make(size_t vlen=1); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_BLOCKS_MULTIPLY_FF_H */ diff --git a/gr-blocks/include/blocks/nlog10_ff.h b/gr-blocks/include/blocks/nlog10_ff.h new file mode 100644 index 000000000..cedd620fa --- /dev/null +++ b/gr-blocks/include/blocks/nlog10_ff.h @@ -0,0 +1,55 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_BLOCKS_NLOG10_FF_H +#define INCLUDED_BLOCKS_NLOG10_FF_H + +#include <blocks/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace blocks { + + /*! + * \brief output = n*log10(input) + k + * \ingroup math_blk + */ + class BLOCKS_API nlog10_ff : virtual public gr_sync_block + { + public: + + // gr::blocks::nlog10_ff::sptr + typedef boost::shared_ptr<nlog10_ff> sptr; + + /*! + * \brief Make an instance of an nlog10_ff block. + * \param n Scalar multiplicative constant + * \param vlen Input vector length + * \param k Scalar additive constant + */ + static sptr make(float n=1.0, size_t vlen=1, float k=0.0); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_BLOCKS_NLOG10_FF_H */ diff --git a/gr-blocks/include/blocks/not_XX.h.t b/gr-blocks/include/blocks/not_XX.h.t new file mode 100644 index 000000000..e406c82dc --- /dev/null +++ b/gr-blocks/include/blocks/not_XX.h.t @@ -0,0 +1,53 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifndef @GUARD_NAME@ +#define @GUARD_NAME@ + +#include <blocks/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace blocks { + + /*! + * \brief output = ~input + * \ingroup math_blk + * + * bitwise boolean not of input streams. + */ + class BLOCKS_API @NAME@ : virtual public gr_sync_block + { + public: + + // gr::blocks::@NAME@::sptr + typedef boost::shared_ptr<@NAME@> sptr; + + static sptr make(size_t vlen=1); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* @GUARD_NAME@ */ diff --git a/gr-blocks/include/blocks/or_XX.h.t b/gr-blocks/include/blocks/or_XX.h.t new file mode 100644 index 000000000..8bc9a080f --- /dev/null +++ b/gr-blocks/include/blocks/or_XX.h.t @@ -0,0 +1,53 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifndef @GUARD_NAME@ +#define @GUARD_NAME@ + +#include <blocks/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace blocks { + + /*! + * \brief output = input_0 | input_1 | , ... | input_N) + * \ingroup math_blk + * + * Bitwise boolean or across all input streams. + */ + class BLOCKS_API @NAME@ : virtual public gr_sync_block + { + public: + + // gr::blocks::@NAME@::sptr + typedef boost::shared_ptr<@NAME@> sptr; + + static sptr make(size_t vlen=1); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* @GUARD_NAME@ */ diff --git a/gr-blocks/include/blocks/patterned_interleaver.h b/gr-blocks/include/blocks/patterned_interleaver.h new file mode 100644 index 000000000..cfcdac6e7 --- /dev/null +++ b/gr-blocks/include/blocks/patterned_interleaver.h @@ -0,0 +1,23 @@ +#ifndef INCLUDED_BLOCKS_PATTERNED_INTERLEAVER_H +#define INCLUDED_BLOCKS_PATTERNED_INTERLEAVER_H + +#include <blocks/api.h> +#include <gr_block.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API patterned_interleaver : virtual public gr_block + { + public: + + typedef boost::shared_ptr<patterned_interleaver> sptr; + + static sptr make(size_t itemsize, std::vector<int> pattern); + }; + + } +} + +#endif + diff --git a/gr-blocks/include/blocks/repeat.h b/gr-blocks/include/blocks/repeat.h new file mode 100644 index 000000000..3f9f8e6fc --- /dev/null +++ b/gr-blocks/include/blocks/repeat.h @@ -0,0 +1,51 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_BLOCKS_REPEAT_H +#define INCLUDED_BLOCKS_REPEAT_H + +#include <blocks/api.h> +#include <gr_sync_interpolator.h> + +namespace gr { + namespace blocks { + + /*! + * \brief repeat each input 'interp' times + * \ingroup slicedice_blk + * \param itemsize stream itemsize + * \param interp number of times to repeat + */ + class BLOCKS_API repeat : virtual public gr_sync_interpolator + { + public: + + // gr::blocks::repeat::sptr + typedef boost::shared_ptr<repeat> sptr; + + static sptr make(size_t itemsize, int repeat); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_BLOCKS_REPEAT_H */ diff --git a/gr-blocks/include/blocks/short_to_char.h b/gr-blocks/include/blocks/short_to_char.h new file mode 100644 index 000000000..eeb053b0e --- /dev/null +++ b/gr-blocks/include/blocks/short_to_char.h @@ -0,0 +1,51 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_BLOCKS_SHORT_TO_CHAR_H +#define INCLUDED_BLOCKS_SHORT_TO_CHAR_H + +#include <blocks/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace blocks { + + /*! + * \brief Convert stream of shorts to a stream of chars + * \ingroup converter_blk + * + * \param vlen vector length of data streams. + */ + class BLOCKS_API short_to_char : virtual public gr_sync_block + { + public: + + // gr::blocks::short_to_char_ff::sptr + typedef boost::shared_ptr<short_to_char> sptr; + + static sptr make(size_t vlen=1); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_BLOCKS_SHORT_TO_CHAR_H */ diff --git a/gr-blocks/include/blocks/short_to_float.h b/gr-blocks/include/blocks/short_to_float.h new file mode 100644 index 000000000..c26addcd0 --- /dev/null +++ b/gr-blocks/include/blocks/short_to_float.h @@ -0,0 +1,62 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_BLOCKS_SHORT_TO_FLOAT_H +#define INCLUDED_BLOCKS_SHORT_TO_FLOAT_H + +#include <blocks/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace blocks { + + /*! + * \brief Convert stream of shorts to a stream of floats + * \ingroup converter_blk + * + * \param vlen vector length of data streams. + * \param scale a scalar divider to change the output signal scale. + */ + class BLOCKS_API short_to_float : virtual public gr_sync_block + { + public: + + // gr::blocks::short_to_float_ff::sptr + typedef boost::shared_ptr<short_to_float> sptr; + + static sptr make(size_t vlen=1, float scale=1.0); + + /*! + * Get the scalar divider value. + */ + virtual float scale() const = 0; + + /*! + * Set the scalar divider value. + */ + virtual void set_scale(float scale) = 0; + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_BLOCKS_SHORT_TO_FLOAT_H */ diff --git a/gr-blocks/include/blocks/stream_mux.h b/gr-blocks/include/blocks/stream_mux.h new file mode 100644 index 000000000..58d564f9f --- /dev/null +++ b/gr-blocks/include/blocks/stream_mux.h @@ -0,0 +1,69 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_BLOCKS_STREAM_MUX_H +#define INCLUDED_BLOCKS_STREAM_MUX_H + +#include <blocks/api.h> +#include <gr_block.h> +#include <vector> + +namespace gr { + namespace blocks { + + /*! + * \brief Stream muxing block to multiplex many streams into + * one with a specified format. + * + * Muxes N streams together producing an output stream that + * contains N0 items from the first stream, N1 items from the second, + * etc. and repeats: + * + * [N0, N1, N2, ..., Nm, N0, N1, ...] + */ + class BLOCKS_API stream_mux : virtual public gr_block + { + public: + + // gr::blocks::stream_mux::sptr + typedef boost::shared_ptr<stream_mux> sptr; + + /*! + * \brief Creates a stream muxing block to multiplex many streams into + * one with a specified format. + * \ingroup converter_blk + * + * \param itemsize the item size of the stream + * \param lengths a vector (list/tuple) specifying the number of + * items from each stream the mux together. + * Warning: this requires that at least as many items + * per stream are available or the system will wait + * indefinitely for the items. + * + */ + static sptr make(size_t itemsize, const std::vector<int> &lengths); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_BLOCKS_STREAM_MUX_H */ diff --git a/gr-blocks/include/blocks/stream_to_streams.h b/gr-blocks/include/blocks/stream_to_streams.h new file mode 100644 index 000000000..fc39f1687 --- /dev/null +++ b/gr-blocks/include/blocks/stream_to_streams.h @@ -0,0 +1,52 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_BLOCKS_STREAM_TO_STREAMS_H +#define INCLUDED_BLOCKS_STREAM_TO_STREAMS_H + +#include <blocks/api.h> +#include <gr_sync_decimator.h> + +namespace gr { + namespace blocks { + + /*! + * \brief convert a stream of items into a N streams of items + * \ingroup slicedice_blk + * + * Converts a stream of N items into N streams of 1 item. + * Repeat ad infinitum. + */ + class BLOCKS_API stream_to_streams : virtual public gr_sync_decimator + { + public: + + // gr::blocks::stream_to_streams::sptr + typedef boost::shared_ptr<stream_to_streams> sptr; + + static sptr make(size_t itemsize, size_t nstreams); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_BLOCKS_STREAM_TO_STREAMS_H */ diff --git a/gr-blocks/include/blocks/stream_to_vector.h b/gr-blocks/include/blocks/stream_to_vector.h new file mode 100644 index 000000000..8311eb350 --- /dev/null +++ b/gr-blocks/include/blocks/stream_to_vector.h @@ -0,0 +1,49 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_BLOCKS_STREAM_TO_VECTOR_H +#define INCLUDED_BLOCKS_STREAM_TO_VECTOR_H + +#include <blocks/api.h> +#include <gr_sync_decimator.h> + +namespace gr { + namespace blocks { + + /*! + * \brief convert a stream of items into a stream of blocks containing nitems_per_block + * \ingroup slicedice_blk + */ + class BLOCKS_API stream_to_vector : virtual public gr_sync_decimator + { + public: + + // gr::blocks::stream_to_vector::sptr + typedef boost::shared_ptr<stream_to_vector> sptr; + + static sptr make(size_t itemsize, size_t nitems_per_block); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_BLOCKS_STREAM_TO_VECTOR_H */ diff --git a/gr-blocks/include/blocks/streams_to_stream.h b/gr-blocks/include/blocks/streams_to_stream.h new file mode 100644 index 000000000..01dcd1be3 --- /dev/null +++ b/gr-blocks/include/blocks/streams_to_stream.h @@ -0,0 +1,52 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_BLOCKS_STREAMS_TO_STREAM_H +#define INCLUDED_BLOCKS_STREAMS_TO_STREAM_H + +#include <blocks/api.h> +#include <gr_sync_interpolator.h> + +namespace gr { + namespace blocks { + + /*! + * \brief Convert N streams of 1 item into a 1 stream of N items + * \ingroup slicedice_blk + * + * Convert N streams of 1 item into 1 stream of N items. + * Repeat ad infinitum. + */ + class BLOCKS_API streams_to_stream : virtual public gr_sync_interpolator + { + public: + + // gr::blocks::streams_to_stream::sptr + typedef boost::shared_ptr<streams_to_stream> sptr; + + static sptr make(size_t itemsize, size_t nstreams); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_BLOCKS_STREAMS_TO_STREAM_H */ diff --git a/gr-blocks/include/blocks/streams_to_vector.h b/gr-blocks/include/blocks/streams_to_vector.h new file mode 100644 index 000000000..ad55ac31f --- /dev/null +++ b/gr-blocks/include/blocks/streams_to_vector.h @@ -0,0 +1,49 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_BLOCKS_STREAMS_TO_VECTOR_H +#define INCLUDED_BLOCKS_STREAMS_TO_VECTOR_H + +#include <blocks/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace blocks { + + /*! + * \brief convert N streams of items to 1 stream of vector length N + * \ingroup slicedice_blk + */ + class BLOCKS_API streams_to_vector : virtual public gr_sync_block + { + public: + + // gr::blocks::streams_to_vector::sptr + typedef boost::shared_ptr<streams_to_vector> sptr; + + static sptr make(size_t itemsize, size_t nstreams); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_BLOCKS_STREAMS_TO_VECTOR_H */ diff --git a/gr-blocks/include/blocks/sub_XX.h.t b/gr-blocks/include/blocks/sub_XX.h.t new file mode 100644 index 000000000..8202ac54b --- /dev/null +++ b/gr-blocks/include/blocks/sub_XX.h.t @@ -0,0 +1,53 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2009,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifndef @GUARD_NAME@ +#define @GUARD_NAME@ + +#include <blocks/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace blocks { + + /*! + * \brief output = input_0 - input_1 - ...) + * \ingroup math_blk + * + * Subtract across all input streams. + */ + class BLOCKS_API @NAME@ : virtual public gr_sync_block + { + public: + + // gr::blocks::@NAME@::sptr + typedef boost::shared_ptr<@NAME@> sptr; + + static sptr make(size_t vlen=1); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* @GUARD_NAME@ */ diff --git a/gr-blocks/include/blocks/uchar_to_float.h b/gr-blocks/include/blocks/uchar_to_float.h new file mode 100644 index 000000000..033037e49 --- /dev/null +++ b/gr-blocks/include/blocks/uchar_to_float.h @@ -0,0 +1,49 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_BLOCKS_UCHAR_TO_FLOAT_H +#define INCLUDED_BLOCKS_UCHAR_TO_FLOAT_H + +#include <blocks/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace blocks { + + /*! + * \brief Convert stream of unsigned chars to a stream of floats + * \ingroup converter_blk + */ + class BLOCKS_API uchar_to_float : virtual public gr_sync_block + { + public: + + // gr::blocks::uchar_to_float_ff::sptr + typedef boost::shared_ptr<uchar_to_float> sptr; + + static sptr make(); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_BLOCKS_UCHAR_TO_FLOAT_H */ diff --git a/gr-blocks/include/blocks/vector_to_stream.h b/gr-blocks/include/blocks/vector_to_stream.h new file mode 100644 index 000000000..1e72f6d50 --- /dev/null +++ b/gr-blocks/include/blocks/vector_to_stream.h @@ -0,0 +1,49 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_BLOCKS_VECTOR_TO_STREAM_H +#define INCLUDED_BLOCKS_VECTOR_TO_STREAM_H + +#include <blocks/api.h> +#include <gr_sync_interpolator.h> + +namespace gr { + namespace blocks { + + /*! + * \brief convert a stream of blocks of nitems_per_block items into a stream of items + * \ingroup slicedice_blk + */ + class BLOCKS_API vector_to_stream : virtual public gr_sync_interpolator + { + public: + + // gr::blocks::vector_to_stream::sptr + typedef boost::shared_ptr<vector_to_stream> sptr; + + static sptr make(size_t itemsize, size_t nitems_per_block); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_BLOCKS_VECTOR_TO_STREAM_H */ diff --git a/gr-blocks/include/blocks/vector_to_streams.h b/gr-blocks/include/blocks/vector_to_streams.h new file mode 100644 index 000000000..1bc075879 --- /dev/null +++ b/gr-blocks/include/blocks/vector_to_streams.h @@ -0,0 +1,49 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_BLOCKS_VECTOR_TO_STREAMS_H +#define INCLUDED_BLOCKS_VECTOR_TO_STREAMS_H + +#include <blocks/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace blocks { + + /*! + * \brief Convert 1 stream of vectors of length N to N streams of items + * \ingroup slicedice_blk + */ + class BLOCKS_API vector_to_streams : virtual public gr_sync_block + { + public: + + // gr::blocks::vector_to_streams::sptr + typedef boost::shared_ptr<vector_to_streams> sptr; + + static sptr make(size_t itemsize, size_t nstreams); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_BLOCKS_VECTOR_TO_STREAMS_H */ diff --git a/gr-blocks/include/blocks/xor_XX.h.t b/gr-blocks/include/blocks/xor_XX.h.t new file mode 100644 index 000000000..ba0c508f6 --- /dev/null +++ b/gr-blocks/include/blocks/xor_XX.h.t @@ -0,0 +1,53 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifndef @GUARD_NAME@ +#define @GUARD_NAME@ + +#include <blocks/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace blocks { + + /*! + * \brief output = input_0 ^ input_1 ^ , ... ^ input_N) + * \ingroup math_blk + * + * Bitwise boolean xor across all input streams. + */ + class BLOCKS_API @NAME@ : virtual public gr_sync_block + { + public: + + // gr::blocks::@NAME@::sptr + typedef boost::shared_ptr<@NAME@> sptr; + + static sptr make(size_t vlen=1); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* @GUARD_NAME@ */ diff --git a/gr-blocks/lib/CMakeLists.txt b/gr-blocks/lib/CMakeLists.txt new file mode 100644 index 000000000..ab989fc78 --- /dev/null +++ b/gr-blocks/lib/CMakeLists.txt @@ -0,0 +1,191 @@ +# Copyright 2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. + +######################################################################## +# Setup compatibility checks and defines +######################################################################## +include(${CMAKE_CURRENT_SOURCE_DIR}/ConfigChecks.cmake) + +######################################################################## +# generate helper scripts to expand templated files +######################################################################## +include(GrPython) + +file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py " +#!${PYTHON_EXECUTABLE} + +import sys, os, re +sys.path.append('${GR_CORE_PYTHONPATH}') +os.environ['srcdir'] = '${CMAKE_CURRENT_SOURCE_DIR}' +os.chdir('${CMAKE_CURRENT_BINARY_DIR}') + +if __name__ == '__main__': + import build_utils + root, inp = sys.argv[1:3] + for sig in sys.argv[3:]: + name = re.sub ('X+', sig, root) + d = build_utils.standard_dict(name, sig, 'blocks') + build_utils.expand_template(d, inp, '_impl') +") + +macro(expand_cc_h_impl root) + #make a list of all the generated files + unset(expanded_files_cc_impl) + unset(expanded_files_h_impl) + foreach(sig ${ARGN}) + string(REGEX REPLACE "X+" ${sig} name ${root}) + list(APPEND expanded_files_cc_impl ${CMAKE_CURRENT_BINARY_DIR}/${name}_impl.cc) + list(APPEND expanded_files_h_impl ${CMAKE_CURRENT_BINARY_DIR}/${name}_impl.h) + list(APPEND expanded_files_h ${CMAKE_CURRENT_BINARY_DIR}/../include/${name}.h) + endforeach(sig) + + #create a command to generate the _impl.cc files + add_custom_command( + OUTPUT ${expanded_files_cc_impl} + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}_impl.cc.t + COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B} + ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py + ${root} ${root}_impl.cc.t ${ARGN} + ) + + #create a command to generate the _impl.h files + add_custom_command( + OUTPUT ${expanded_files_h_impl} + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}_impl.h.t + COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B} + ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py + ${root} ${root}_impl.h.t ${ARGN} + ) + + #make _impl.cc source files depend on headers to force generation + set_source_files_properties(${expanded_files_cc_impl} + PROPERTIES OBJECT_DEPENDS "${expanded_files_h_impl}" + ) + + #make _impl.h source files depend on headers to force generation + set_source_files_properties(${expanded_files_h_impl} + PROPERTIES OBJECT_DEPENDS "${expanded_files_h}" + ) + + #install rules for the generated cc files + list(APPEND generated_sources ${expanded_files_cc_impl}) +endmacro(expand_cc_h_impl) + +######################################################################## +# Invoke macro to generate various sources +######################################################################## +expand_cc_h_impl(add_XX ss ii cc) +expand_cc_h_impl(add_const_XX ss ii ff cc) +expand_cc_h_impl(add_const_vXX ss ii ff cc) +expand_cc_h_impl(and_XX bb ss ii) +expand_cc_h_impl(and_const_XX bb ss ii) +expand_cc_h_impl(divide_XX ss ii ff cc) +expand_cc_h_impl(integrate_XX ss ii ff cc) +expand_cc_h_impl(multiply_XX ss ii) +expand_cc_h_impl(multiply_const_XX ss ii) +expand_cc_h_impl(multiply_const_vXX ss ii ff cc) +expand_cc_h_impl(not_XX bb ss ii) +expand_cc_h_impl(or_XX bb ss ii) +expand_cc_h_impl(sub_XX ss ii ff cc) +expand_cc_h_impl(xor_XX bb ss ii) + +######################################################################## +# Setup the include and linker paths +######################################################################## +include_directories( + ${GNURADIO_CORE_INCLUDE_DIRS} + ${VOLK_INCLUDE_DIRS} + ${GR_BLOCKS_INCLUDE_DIRS} + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_CURRENT_BINARY_DIR}/../include +) + +include_directories(${BLOCKS_INCLUDE_DIRS}) +link_directories(${BLOCKS_LIBRARY_DIRS}) + +include_directories(${Boost_INCLUDE_DIRS}) +link_directories(${Boost_LIBRARY_DIRS}) + +######################################################################## +# Setup library +######################################################################## +list(APPEND gr_blocks_sources + ${generated_sources} + add_ff_impl.cc + char_to_float_impl.cc + char_to_short_impl.cc + complex_to_interleaved_short_impl.cc + complex_to_float_impl.cc + complex_to_real_impl.cc + complex_to_imag_impl.cc + complex_to_mag_impl.cc + complex_to_mag_squared_impl.cc + complex_to_arg_impl.cc + conjugate_cc_impl.cc + deinterleave_impl.cc + file_source_impl.cc + file_meta_sink_impl.cc + file_meta_source_impl.cc + float_to_char_impl.cc + float_to_complex_impl.cc + float_array_to_int.cc + float_to_int_impl.cc + float_to_short_impl.cc + float_array_to_uchar.cc + float_to_uchar_impl.cc + int_to_float_impl.cc + interleave_impl.cc + interleaved_short_array_to_complex.cc + interleaved_short_to_complex_impl.cc + keep_m_in_n_impl.cc + keep_one_in_n_impl.cc + multiply_cc_impl.cc + multiply_ff_impl.cc + multiply_conjugate_cc_impl.cc + multiply_const_cc_impl.cc + multiply_const_ff_impl.cc + nlog10_ff_impl.cc + patterned_interleaver_impl.cc + repeat_impl.cc + short_to_char_impl.cc + short_to_float_impl.cc + stream_mux_impl.cc + stream_to_streams_impl.cc + stream_to_vector_impl.cc + streams_to_stream_impl.cc + streams_to_vector_impl.cc + uchar_array_to_float.cc + uchar_to_float_impl.cc + vector_to_stream_impl.cc + vector_to_streams_impl.cc +) + +list(APPEND blocks_libs + gnuradio-core + volk + ${Boost_LIBRARIES} + ${BLOCKS_LIBRARIES} +) + +add_library(gnuradio-blocks SHARED ${gr_blocks_sources}) +add_dependencies(gnuradio-blocks blocks_generated_includes) + +target_link_libraries(gnuradio-blocks ${blocks_libs}) +GR_LIBRARY_FOO(gnuradio-blocks RUNTIME_COMPONENT "blocks_runtime" DEVEL_COMPONENT "blocks_devel") diff --git a/gr-blocks/lib/ConfigChecks.cmake b/gr-blocks/lib/ConfigChecks.cmake new file mode 100644 index 000000000..72d6d1d8a --- /dev/null +++ b/gr-blocks/lib/ConfigChecks.cmake @@ -0,0 +1,91 @@ +# Copyright 2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. + +######################################################################## +INCLUDE(GrMiscUtils) +INCLUDE(CheckCXXSourceCompiles) + +IF(MSVC) #add this directory for our provided headers +LIST(APPEND CMAKE_REQUIRED_INCLUDES ${CMAKE_SOURCE_DIR}/msvc) +ENDIF(MSVC) + +GR_CHECK_HDR_N_DEF(netdb.h HAVE_NETDB_H) +GR_CHECK_HDR_N_DEF(sys/time.h HAVE_SYS_TIME_H) +GR_CHECK_HDR_N_DEF(sys/types.h HAVE_SYS_TYPES_H) +GR_CHECK_HDR_N_DEF(sys/select.h HAVE_SYS_SELECT_H) +GR_CHECK_HDR_N_DEF(sys/socket.h HAVE_SYS_SOCKET_H) +GR_CHECK_HDR_N_DEF(io.h HAVE_IO_H) +GR_CHECK_HDR_N_DEF(sys/mman.h HAVE_SYS_MMAN_H) +GR_CHECK_HDR_N_DEF(sys/ipc.h HAVE_SYS_IPC_H) +GR_CHECK_HDR_N_DEF(sys/shm.h HAVE_SYS_SHM_H) +GR_CHECK_HDR_N_DEF(signal.h HAVE_SIGNAL_H) +GR_CHECK_HDR_N_DEF(netinet/in.h HAVE_NETINET_IN_H) +GR_CHECK_HDR_N_DEF(arpa/inet.h HAVE_ARPA_INET_H) +GR_CHECK_HDR_N_DEF(byteswap.h HAVE_BYTESWAP_H) +GR_CHECK_HDR_N_DEF(linux/ppdev.h HAVE_LINUX_PPDEV_H) +GR_CHECK_HDR_N_DEF(dev/ppbus/ppi.h HAVE_DEV_PPBUS_PPI_H) +GR_CHECK_HDR_N_DEF(unistd.h HAVE_UNISTD_H) +GR_CHECK_HDR_N_DEF(malloc.h HAVE_MALLOC_H) + +######################################################################## +CHECK_CXX_SOURCE_COMPILES(" + #include <sys/select.h> + int main(){select(0, 0, 0, 0, 0); return 0;} + " HAVE_SELECT +) +GR_ADD_COND_DEF(HAVE_SELECT) + +######################################################################## +CHECK_INCLUDE_FILE_CXX(windows.h HAVE_WINDOWS_H) +IF(HAVE_WINDOWS_H) + ADD_DEFINITIONS(-DHAVE_WINDOWS_H -DUSING_WINSOCK) + MESSAGE(STATUS "Adding windows libs to gr blocks libs...") + LIST(APPEND gnuradio_core_libs WS2_32.lib WSock32.lib) +ENDIF(HAVE_WINDOWS_H) + +######################################################################## +CHECK_CXX_SOURCE_COMPILES(" + #define _GNU_SOURCE + #include <math.h> + int main(){double x, sin, cos; sincos(x, &sin, &cos); return 0;} + " HAVE_SINCOS +) +GR_ADD_COND_DEF(HAVE_SINCOS) + +CHECK_CXX_SOURCE_COMPILES(" + #define _GNU_SOURCE + #include <math.h> + int main(){float x, sin, cos; sincosf(x, &sin, &cos); return 0;} + " HAVE_SINCOSF +) +GR_ADD_COND_DEF(HAVE_SINCOSF) + +CHECK_CXX_SOURCE_COMPILES(" + #include <math.h> + int main(){sinf(0); return 0;} + " HAVE_SINF +) +GR_ADD_COND_DEF(HAVE_SINF) + +CHECK_CXX_SOURCE_COMPILES(" + #include <math.h> + int main(){cosf(0); return 0;} + " HAVE_COSF +) +GR_ADD_COND_DEF(HAVE_COSF) diff --git a/gr-blocks/lib/add_XX_impl.cc.t b/gr-blocks/lib/add_XX_impl.cc.t new file mode 100644 index 000000000..c528e2fbf --- /dev/null +++ b/gr-blocks/lib/add_XX_impl.cc.t @@ -0,0 +1,69 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2009,2010,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <@NAME_IMPL@.h> +#include <gr_io_signature.h> + +namespace gr { + namespace blocks { + + @NAME@::sptr @NAME@::make(size_t vlen) + { + return gnuradio::get_initial_sptr(new @NAME_IMPL@(vlen)); + } + + @NAME_IMPL@::@NAME_IMPL@(size_t vlen) + : gr_sync_block ("@NAME@", + gr_make_io_signature (1, -1, sizeof (@I_TYPE@)*vlen), + gr_make_io_signature (1, 1, sizeof (@O_TYPE@)*vlen)), + d_vlen(vlen) + { + } + + int + @NAME_IMPL@::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + @O_TYPE@ *optr = (@O_TYPE@ *) output_items[0]; + + int ninputs = input_items.size (); + + for (size_t i = 0; i < noutput_items*d_vlen; i++){ + @I_TYPE@ acc = ((@I_TYPE@ *) input_items[0])[i]; + for (int j = 1; j < ninputs; j++) + acc += ((@I_TYPE@ *) input_items[j])[i]; + + *optr++ = (@O_TYPE@) acc; + } + + return noutput_items; + } + + } /* namespace blocks */ +} /* namespace gr */ diff --git a/gr-blocks/lib/add_XX_impl.h.t b/gr-blocks/lib/add_XX_impl.h.t new file mode 100644 index 000000000..a1c486b85 --- /dev/null +++ b/gr-blocks/lib/add_XX_impl.h.t @@ -0,0 +1,48 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2009,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifndef @GUARD_NAME_IMPL@ +#define @GUARD_NAME_IMPL@ + +#include <blocks/@NAME@.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API @NAME_IMPL@ : public @NAME@ + { + size_t d_vlen; + + public: + @NAME_IMPL@(size_t vlen); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* @GUARD_NAME_IMPL@ */ diff --git a/gr-blocks/lib/add_const_XX_impl.cc.t b/gr-blocks/lib/add_const_XX_impl.cc.t new file mode 100644 index 000000000..7fa883f4b --- /dev/null +++ b/gr-blocks/lib/add_const_XX_impl.cc.t @@ -0,0 +1,77 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2009,2010,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <@NAME_IMPL@.h> +#include <gr_io_signature.h> + +namespace gr { + namespace blocks { + + @NAME@::sptr @NAME@::make(@O_TYPE@ k) + { + return gnuradio::get_initial_sptr(new @NAME_IMPL@(k)); + } + + @NAME_IMPL@::@NAME_IMPL@(@O_TYPE@ k) + : gr_sync_block ("@NAME@", + gr_make_io_signature (1, 1, sizeof (@I_TYPE@)), + gr_make_io_signature (1, 1, sizeof (@O_TYPE@))), + d_k(k) + { + } + + int + @NAME_IMPL@::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + @I_TYPE@ *iptr = (@I_TYPE@ *) input_items[0]; + @O_TYPE@ *optr = (@O_TYPE@ *) output_items[0]; + + int size = noutput_items; + + while (size >= 8){ + *optr++ = *iptr++ + d_k; + *optr++ = *iptr++ + d_k; + *optr++ = *iptr++ + d_k; + *optr++ = *iptr++ + d_k; + *optr++ = *iptr++ + d_k; + *optr++ = *iptr++ + d_k; + *optr++ = *iptr++ + d_k; + *optr++ = *iptr++ + d_k; + size -= 8; + } + + while (size-- > 0) + *optr++ = *iptr++ + d_k; + + return noutput_items; + } + + } /* namespace blocks */ +} /* namespace gr */ diff --git a/gr-blocks/lib/add_const_XX_impl.h.t b/gr-blocks/lib/add_const_XX_impl.h.t new file mode 100644 index 000000000..cae5ca813 --- /dev/null +++ b/gr-blocks/lib/add_const_XX_impl.h.t @@ -0,0 +1,51 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2009,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifndef @GUARD_NAME_IMPL@ +#define @GUARD_NAME_IMPL@ + +#include <blocks/@NAME@.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API @NAME_IMPL@ : public @NAME@ + { + @O_TYPE@ d_k; + + public: + @NAME_IMPL@(@O_TYPE@ k); + + @O_TYPE@ k() const { return d_k; } + void set_k(@O_TYPE@ k) { d_k = k; } + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* @GUARD_NAME_IMPL@ */ diff --git a/gr-blocks/lib/add_const_vXX_impl.cc.t b/gr-blocks/lib/add_const_vXX_impl.cc.t new file mode 100644 index 000000000..da76cfeef --- /dev/null +++ b/gr-blocks/lib/add_const_vXX_impl.cc.t @@ -0,0 +1,66 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2009,2010,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <@NAME_IMPL@.h> +#include <gr_io_signature.h> + +namespace gr { + namespace blocks { + + @NAME@::sptr @NAME@::make(std::vector<@O_TYPE@> k) + { + return gnuradio::get_initial_sptr(new @NAME_IMPL@(k)); + } + + @NAME_IMPL@::@NAME_IMPL@(std::vector<@O_TYPE@> k) + : gr_sync_block ("@NAME@", + gr_make_io_signature (1, 1, sizeof (@I_TYPE@)*k.size()), + gr_make_io_signature (1, 1, sizeof (@O_TYPE@)*k.size())), + d_k(k) + { + } + + int + @NAME_IMPL@::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + @I_TYPE@ *iptr = (@I_TYPE@ *)input_items[0]; + @O_TYPE@ *optr = (@O_TYPE@ *)output_items[0]; + + int nitems_per_block = output_signature()->sizeof_stream_item(0)/sizeof(@I_TYPE@); + + for (int i = 0; i < noutput_items; i++) + for (int j = 0; j < nitems_per_block; j++) + *optr++ = *iptr++ + d_k[j]; + + return noutput_items; + } + + } /* namespace blocks */ +} /* namespace gr */ diff --git a/gr-blocks/lib/add_const_vXX_impl.h.t b/gr-blocks/lib/add_const_vXX_impl.h.t new file mode 100644 index 000000000..a7a619725 --- /dev/null +++ b/gr-blocks/lib/add_const_vXX_impl.h.t @@ -0,0 +1,51 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2006,2010,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifndef @GUARD_NAME_IMPL@ +#define @GUARD_NAME_IMPL@ + +#include <blocks/@NAME@.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API @NAME_IMPL@ : public @NAME@ + { + std::vector<@O_TYPE@> d_k; + + public: + @NAME_IMPL@(std::vector<@O_TYPE@> k); + + std::vector<@O_TYPE@> k() const { return d_k; } + void set_k(std::vector<@O_TYPE@> k) { d_k = k; } + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* @GUARD_NAME_IMPL@ */ diff --git a/gr-blocks/lib/add_ff_impl.cc b/gr-blocks/lib/add_ff_impl.cc new file mode 100644 index 000000000..83359ef80 --- /dev/null +++ b/gr-blocks/lib/add_ff_impl.cc @@ -0,0 +1,71 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "add_ff_impl.h" +#include <gr_io_signature.h> +#include <volk/volk.h> + +namespace gr { + namespace blocks { + + add_ff::sptr add_ff::make(size_t vlen) + { + return gnuradio::get_initial_sptr(new add_ff_impl(vlen)); + } + + add_ff_impl::add_ff_impl(size_t vlen) + : gr_sync_block("add_ff", + gr_make_io_signature (1, -1, sizeof(float)*vlen), + gr_make_io_signature (1, 1, sizeof(float)*vlen)), + d_vlen(vlen) + { + const int alignment_multiple = + volk_get_alignment() / sizeof(float); + set_alignment(std::max(1, alignment_multiple)); + } + + int + add_ff_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + float *out = (float *) output_items[0]; + int noi = d_vlen*noutput_items; + + memcpy(out, input_items[0], noi*sizeof(float)); + if(is_unaligned()) { + for(size_t i = 1; i < input_items.size(); i++) + volk_32f_x2_add_32f_u(out, out, (const float*)input_items[i], noi); + } + else { + for(size_t i = 1; i < input_items.size(); i++) + volk_32f_x2_add_32f_a(out, out, (const float*)input_items[i], noi); + } + return noutput_items; + } + + } /* namespace blocks */ +}/* namespace gr */ diff --git a/gr-blocks/lib/add_ff_impl.h b/gr-blocks/lib/add_ff_impl.h new file mode 100644 index 000000000..77b90d079 --- /dev/null +++ b/gr-blocks/lib/add_ff_impl.h @@ -0,0 +1,47 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_BLOCKS_ADD_FF_IMPL_H +#define INCLUDED_BLOCKS_ADD_FF_IMPL_H + +#include <blocks/add_ff.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API add_ff_impl : public add_ff + { + size_t d_vlen; + + public: + add_ff_impl(size_t vlen); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + + +#endif /* INCLUDED_BLOCKS_ADD_FF_IMPL_H */ diff --git a/gr-blocks/lib/and_XX_impl.cc.t b/gr-blocks/lib/and_XX_impl.cc.t new file mode 100644 index 000000000..3218a8c74 --- /dev/null +++ b/gr-blocks/lib/and_XX_impl.cc.t @@ -0,0 +1,69 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <@NAME_IMPL@.h> +#include <gr_io_signature.h> + +namespace gr { + namespace blocks { + + @NAME@::sptr @NAME@::make(size_t vlen) + { + return gnuradio::get_initial_sptr(new @NAME_IMPL@(vlen)); + } + + @NAME_IMPL@::@NAME_IMPL@(size_t vlen) + : gr_sync_block ("@NAME@", + gr_make_io_signature (1, -1, sizeof (@I_TYPE@)*vlen), + gr_make_io_signature (1, 1, sizeof (@O_TYPE@)*vlen)), + d_vlen(vlen) + { + } + + int + @NAME_IMPL@::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + @O_TYPE@ *optr = (@O_TYPE@ *) output_items[0]; + + int ninputs = input_items.size (); + + for (size_t i = 0; i < noutput_items*d_vlen; i++){ + @I_TYPE@ acc = ((@I_TYPE@ *) input_items[0])[i]; + for (int j = 1; j < ninputs; j++) + acc &= ((@I_TYPE@ *) input_items[j])[i]; + + *optr++ = (@O_TYPE@) acc; + } + + return noutput_items; + } + + } /* namespace blocks */ +} /* namespace gr */ diff --git a/gr-blocks/lib/and_XX_impl.h.t b/gr-blocks/lib/and_XX_impl.h.t new file mode 100644 index 000000000..25f0da0c8 --- /dev/null +++ b/gr-blocks/lib/and_XX_impl.h.t @@ -0,0 +1,48 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifndef @GUARD_NAME_IMPL@ +#define @GUARD_NAME_IMPL@ + +#include <blocks/@NAME@.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API @NAME_IMPL@ : public @NAME@ + { + size_t d_vlen; + + public: + @NAME_IMPL@(size_t vlen); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* @GUARD_NAME_IMPL@ */ diff --git a/gr-blocks/lib/and_const_XX_impl.cc.t b/gr-blocks/lib/and_const_XX_impl.cc.t new file mode 100644 index 000000000..8ff5ac371 --- /dev/null +++ b/gr-blocks/lib/and_const_XX_impl.cc.t @@ -0,0 +1,77 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <@NAME_IMPL@.h> +#include <gr_io_signature.h> + +namespace gr { + namespace blocks { + + @NAME@::sptr @NAME@::make(@O_TYPE@ k) + { + return gnuradio::get_initial_sptr(new @NAME_IMPL@(k)); + } + + @NAME_IMPL@::@NAME_IMPL@(@O_TYPE@ k) + : gr_sync_block ("@NAME@", + gr_make_io_signature (1, 1, sizeof (@I_TYPE@)), + gr_make_io_signature (1, 1, sizeof (@O_TYPE@))), + d_k(k) + { + } + + int + @NAME_IMPL@::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + @I_TYPE@ *iptr = (@I_TYPE@ *) input_items[0]; + @O_TYPE@ *optr = (@O_TYPE@ *) output_items[0]; + + int size = noutput_items; + + while (size >= 8){ + *optr++ = *iptr++ & d_k; + *optr++ = *iptr++ & d_k; + *optr++ = *iptr++ & d_k; + *optr++ = *iptr++ & d_k; + *optr++ = *iptr++ & d_k; + *optr++ = *iptr++ & d_k; + *optr++ = *iptr++ & d_k; + *optr++ = *iptr++ & d_k; + size -= 8; + } + + while (size-- > 0) + *optr++ = *iptr++ & d_k; + + return noutput_items; + } + + } /* namespace blocks */ +} /* namespace gr */ diff --git a/gr-blocks/lib/and_const_XX_impl.h.t b/gr-blocks/lib/and_const_XX_impl.h.t new file mode 100644 index 000000000..2c379feb8 --- /dev/null +++ b/gr-blocks/lib/and_const_XX_impl.h.t @@ -0,0 +1,51 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifndef @GUARD_NAME_IMPL@ +#define @GUARD_NAME_IMPL@ + +#include <blocks/@NAME@.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API @NAME_IMPL@ : public @NAME@ + { + @O_TYPE@ d_k; + + public: + @NAME_IMPL@(@O_TYPE@ k); + + @O_TYPE@ k() const { return d_k; } + void set_k(@O_TYPE@ k) { d_k = k; } + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* @GUARD_NAME_IMPL@ */ diff --git a/gr-blocks/lib/char_to_float_impl.cc b/gr-blocks/lib/char_to_float_impl.cc new file mode 100644 index 000000000..22c5d2e25 --- /dev/null +++ b/gr-blocks/lib/char_to_float_impl.cc @@ -0,0 +1,65 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "char_to_float_impl.h" +#include <gr_io_signature.h> +#include <volk/volk.h> + +namespace gr { + namespace blocks { + + char_to_float::sptr char_to_float::make(size_t vlen, float scale) + { + return gnuradio::get_initial_sptr(new char_to_float_impl(vlen, scale)); + } + + char_to_float_impl::char_to_float_impl(size_t vlen, float scale) + : gr_sync_block("char_to_float", + gr_make_io_signature (1, -1, sizeof(char)*vlen), + gr_make_io_signature (1, 1, sizeof(float)*vlen)), + d_vlen(vlen), d_scale(scale) + { + const int alignment_multiple = + volk_get_alignment() / sizeof(float); + set_alignment(std::max(1, alignment_multiple)); + } + + int + char_to_float_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const int8_t *in = (const int8_t *) input_items[0]; + float *out = (float *) output_items[0]; + + // Note: the unaligned benchmarked much faster than the aligned + volk_8i_s32f_convert_32f_u(out, in, d_scale, d_vlen*noutput_items); + + return noutput_items; + } + + } /* namespace blocks */ +}/* namespace gr */ diff --git a/gr-blocks/lib/char_to_float_impl.h b/gr-blocks/lib/char_to_float_impl.h new file mode 100644 index 000000000..620d7e737 --- /dev/null +++ b/gr-blocks/lib/char_to_float_impl.h @@ -0,0 +1,51 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_CHAR_TO_FLOAT_IMPL_H +#define INCLUDED_CHAR_TO_FLOAT_IMPL_H + +#include <blocks/char_to_float.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API char_to_float_impl : public char_to_float + { + size_t d_vlen; + float d_scale; + + public: + char_to_float_impl(size_t vlen, float scale); + + virtual float scale() const { return d_scale; } + virtual void set_scale(float scale) { d_scale = scale; } + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + + +#endif /* INCLUDED_CHAR_TO_FLOAT_IMPL_H */ diff --git a/gr-blocks/lib/char_to_short_impl.cc b/gr-blocks/lib/char_to_short_impl.cc new file mode 100644 index 000000000..a86a928b5 --- /dev/null +++ b/gr-blocks/lib/char_to_short_impl.cc @@ -0,0 +1,69 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "char_to_short_impl.h" +#include <gr_io_signature.h> +#include <volk/volk.h> + +namespace gr { + namespace blocks { + + char_to_short::sptr char_to_short::make(size_t vlen) + { + return gnuradio::get_initial_sptr(new char_to_short_impl(vlen)); + } + + char_to_short_impl::char_to_short_impl(size_t vlen) + : gr_sync_block("char_to_short", + gr_make_io_signature (1, -1, sizeof(char)*vlen), + gr_make_io_signature (1, 1, sizeof(short)*vlen)), + d_vlen(vlen) + { + const int alignment_multiple = + volk_get_alignment() / sizeof(short); + set_alignment(std::max(1, alignment_multiple)); + } + + int + char_to_short_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const int8_t *in = (const int8_t *) input_items[0]; + int16_t *out = (int16_t *) output_items[0]; + + if(is_unaligned()) { + volk_8i_convert_16i_u(out, in, d_vlen*noutput_items); + } + else { + volk_8i_convert_16i_a(out, in, d_vlen*noutput_items); + } + + return noutput_items; + } + + } /* namespace blocks */ +}/* namespace gr */ diff --git a/gr-blocks/lib/char_to_short_impl.h b/gr-blocks/lib/char_to_short_impl.h new file mode 100644 index 000000000..efd3ab3a8 --- /dev/null +++ b/gr-blocks/lib/char_to_short_impl.h @@ -0,0 +1,47 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_CHAR_TO_SHORT_IMPL_H +#define INCLUDED_CHAR_TO_SHORT_IMPL_H + +#include <blocks/char_to_short.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API char_to_short_impl : public char_to_short + { + size_t d_vlen; + + public: + char_to_short_impl(size_t vlen); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + + +#endif /* INCLUDED_CHAR_TO_SHORT_IMPL_H */ diff --git a/gr-blocks/lib/complex_to_arg_impl.cc b/gr-blocks/lib/complex_to_arg_impl.cc new file mode 100644 index 000000000..87ac9966f --- /dev/null +++ b/gr-blocks/lib/complex_to_arg_impl.cc @@ -0,0 +1,70 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "complex_to_arg_impl.h" +#include <gr_io_signature.h> +#include <volk/volk.h> +#include <gr_math.h> + +namespace gr { + namespace blocks { + + complex_to_arg::sptr complex_to_arg::make(size_t vlen) + { + return gnuradio::get_initial_sptr(new complex_to_arg_impl(vlen)); + } + + complex_to_arg_impl::complex_to_arg_impl(size_t vlen) + : gr_sync_block("complex_to_arg", + gr_make_io_signature (1, 1, sizeof(gr_complex)*vlen), + gr_make_io_signature (1, 1, sizeof(float)*vlen)), + d_vlen(vlen) + { + const int alignment_multiple = + volk_get_alignment() / sizeof(float); + set_alignment(std::max(1,alignment_multiple)); + } + + int + complex_to_arg_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const gr_complex *in = (const gr_complex *) input_items[0]; + float *out = (float *) output_items[0]; + int noi = noutput_items * d_vlen; + + // The fast_atan2f is faster than Volk + for (int i = 0; i < noi; i++){ + // out[i] = std::arg (in[i]); + out[i] = gr_fast_atan2f(in[i]); + } + + return noutput_items; + } + + } /* namespace blocks */ +}/* namespace gr */ diff --git a/gr-blocks/lib/complex_to_arg_impl.h b/gr-blocks/lib/complex_to_arg_impl.h new file mode 100644 index 000000000..9ccfba05a --- /dev/null +++ b/gr-blocks/lib/complex_to_arg_impl.h @@ -0,0 +1,47 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_COMPLEX_TO_ARG_IMPL_H +#define INCLUDED_COMPLEX_TO_ARG_IMPL_H + +#include <blocks/complex_to_arg.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API complex_to_arg_impl : public complex_to_arg + { + size_t d_vlen; + + public: + complex_to_arg_impl(size_t vlen); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + + +#endif /* INCLUDED_COMPLEX_TO_ARG_IMPL_H */ diff --git a/gr-blocks/lib/complex_to_float_impl.cc b/gr-blocks/lib/complex_to_float_impl.cc new file mode 100644 index 000000000..3c1109de5 --- /dev/null +++ b/gr-blocks/lib/complex_to_float_impl.cc @@ -0,0 +1,94 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "complex_to_float_impl.h" +#include <gr_io_signature.h> +#include <volk/volk.h> + +namespace gr { + namespace blocks { + + complex_to_float::sptr complex_to_float::make(size_t vlen) + { + return gnuradio::get_initial_sptr(new complex_to_float_impl(vlen)); + } + + complex_to_float_impl::complex_to_float_impl(size_t vlen) + : gr_sync_block("complex_to_float", + gr_make_io_signature (1, 1, sizeof(gr_complex)*vlen), + gr_make_io_signature (1, 2, sizeof(float)*vlen)), + d_vlen(vlen) + { + const int alignment_multiple = + volk_get_alignment() / sizeof(float); + set_alignment(std::max(1,alignment_multiple)); + } + + int + complex_to_float_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const gr_complex *in = (const gr_complex *) input_items[0]; + float *out0 = (float *) output_items[0]; + float* out1; + int noi = noutput_items * d_vlen; + + switch (output_items.size ()){ + case 1: + if(is_unaligned()) { + for (int i = 0; i < noi; i++){ + out0[i] = in[i].real (); + } + } + else { + volk_32fc_deinterleave_real_32f_a(out0, in, noi); + } + break; + + case 2: + out1 = (float *) output_items[1]; + if(is_unaligned()) { + for (int i = 0; i < noi; i++){ + out0[i] = in[i].real (); + out1[i] = in[i].imag (); + } + } + else { + volk_32fc_deinterleave_32f_x2_a(out0, out1, in, noi); + } + break; + + default: + abort (); + + } + + return noutput_items; + } + + } /* namespace blocks */ +}/* namespace gr */ diff --git a/gr-blocks/lib/complex_to_float_impl.h b/gr-blocks/lib/complex_to_float_impl.h new file mode 100644 index 000000000..d90ac28d5 --- /dev/null +++ b/gr-blocks/lib/complex_to_float_impl.h @@ -0,0 +1,47 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_COMPLEX_TO_FLOAT_IMPL_H +#define INCLUDED_COMPLEX_TO_FLOAT_IMPL_H + +#include <blocks/complex_to_float.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API complex_to_float_impl : public complex_to_float + { + size_t d_vlen; + + public: + complex_to_float_impl(size_t vlen); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + + +#endif /* INCLUDED_COMPLEX_TO_FLOAT_IMPL_H */ diff --git a/gr-blocks/lib/complex_to_imag_impl.cc b/gr-blocks/lib/complex_to_imag_impl.cc new file mode 100644 index 000000000..760440cc9 --- /dev/null +++ b/gr-blocks/lib/complex_to_imag_impl.cc @@ -0,0 +1,72 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "complex_to_imag_impl.h" +#include <gr_io_signature.h> +#include <volk/volk.h> + +namespace gr { + namespace blocks { + + complex_to_imag::sptr complex_to_imag::make(size_t vlen) + { + return gnuradio::get_initial_sptr(new complex_to_imag_impl(vlen)); + } + + complex_to_imag_impl::complex_to_imag_impl(size_t vlen) + : gr_sync_block("complex_to_imag", + gr_make_io_signature (1, 1, sizeof(gr_complex)*vlen), + gr_make_io_signature (1, 1, sizeof(float)*vlen)), + d_vlen(vlen) + { + const int alignment_multiple = + volk_get_alignment() / sizeof(float); + set_alignment(std::max(1,alignment_multiple)); + } + + int + complex_to_imag_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const gr_complex *in = (const gr_complex *) input_items[0]; + float *out = (float *) output_items[0]; + int noi = noutput_items * d_vlen; + + if(is_unaligned()) { + for (int i = 0; i < noi; i++){ + out[i] = in[i].imag (); + } + } + else { + volk_32fc_deinterleave_imag_32f_a(out, in, noi); + } + + return noutput_items; + } + + } /* namespace blocks */ +}/* namespace gr */ diff --git a/gr-blocks/lib/complex_to_imag_impl.h b/gr-blocks/lib/complex_to_imag_impl.h new file mode 100644 index 000000000..e647e6773 --- /dev/null +++ b/gr-blocks/lib/complex_to_imag_impl.h @@ -0,0 +1,47 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_COMPLEX_TO_IMAG_IMPL_H +#define INCLUDED_COMPLEX_TO_IMAG_IMPL_H + +#include <blocks/complex_to_imag.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API complex_to_imag_impl : public complex_to_imag + { + size_t d_vlen; + + public: + complex_to_imag_impl(size_t vlen); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + + +#endif /* INCLUDED_COMPLEX_TO_IMAG_IMPL_H */ diff --git a/gr-blocks/lib/complex_to_interleaved_short_impl.cc b/gr-blocks/lib/complex_to_interleaved_short_impl.cc new file mode 100644 index 000000000..2f2ea6e00 --- /dev/null +++ b/gr-blocks/lib/complex_to_interleaved_short_impl.cc @@ -0,0 +1,63 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "complex_to_interleaved_short_impl.h" +#include <gr_io_signature.h> + +namespace gr { + namespace blocks { + + complex_to_interleaved_short::sptr complex_to_interleaved_short::make() + { + return gnuradio::get_initial_sptr(new complex_to_interleaved_short_impl()); + } + + complex_to_interleaved_short_impl::complex_to_interleaved_short_impl() + : gr_sync_interpolator("complex_to_interleaved_short", + gr_make_io_signature (1, 1, sizeof(gr_complex)), + gr_make_io_signature (1, 1, sizeof(short)), + 2) + { + } + + int + complex_to_interleaved_short_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const gr_complex *in = (const gr_complex *) input_items[0]; + short *out = (short *) output_items[0]; + + for (int i = 0; i < noutput_items/2; i++){ + *out++ = (short) lrintf(in[i].real()); // FIXME saturate? + *out++ = (short) lrintf(in[i].imag()); + } + + return noutput_items; + } + + } /* namespace blocks */ +}/* namespace gr */ diff --git a/gr-blocks/lib/complex_to_interleaved_short_impl.h b/gr-blocks/lib/complex_to_interleaved_short_impl.h new file mode 100644 index 000000000..9a09d1ff9 --- /dev/null +++ b/gr-blocks/lib/complex_to_interleaved_short_impl.h @@ -0,0 +1,45 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_COMPLEX_TO_INTERLEAVED_SHORT_IMPL_H +#define INCLUDED_COMPLEX_TO_INTERLEAVED_SHORT_IMPL_H + +#include <blocks/complex_to_interleaved_short.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API complex_to_interleaved_short_impl : public complex_to_interleaved_short + { + public: + complex_to_interleaved_short_impl(); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + + +#endif /* INCLUDED_COMPLEX_TO_INTERLEAVED_SHORT_IMPL_H */ diff --git a/gr-blocks/lib/complex_to_mag_impl.cc b/gr-blocks/lib/complex_to_mag_impl.cc new file mode 100644 index 000000000..419bc53eb --- /dev/null +++ b/gr-blocks/lib/complex_to_mag_impl.cc @@ -0,0 +1,66 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "complex_to_mag_impl.h" +#include <gr_io_signature.h> +#include <volk/volk.h> + +namespace gr { + namespace blocks { + + complex_to_mag::sptr complex_to_mag::make(size_t vlen) + { + return gnuradio::get_initial_sptr(new complex_to_mag_impl(vlen)); + } + + complex_to_mag_impl::complex_to_mag_impl(size_t vlen) + : gr_sync_block("complex_to_mag", + gr_make_io_signature (1, 1, sizeof(gr_complex)*vlen), + gr_make_io_signature (1, 1, sizeof(float)*vlen)), + d_vlen(vlen) + { + const int alignment_multiple = + volk_get_alignment() / sizeof(float); + set_alignment(std::max(1,alignment_multiple)); + } + + int + complex_to_mag_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const gr_complex *in = (const gr_complex *) input_items[0]; + float *out = (float *) output_items[0]; + int noi = noutput_items * d_vlen; + + // turned out to be faster than aligned/unaligned switching + volk_32fc_magnitude_32f_u(out, in, noi); + + return noutput_items; + } + + } /* namespace blocks */ +}/* namespace gr */ diff --git a/gr-blocks/lib/complex_to_mag_impl.h b/gr-blocks/lib/complex_to_mag_impl.h new file mode 100644 index 000000000..fe6da3f15 --- /dev/null +++ b/gr-blocks/lib/complex_to_mag_impl.h @@ -0,0 +1,47 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_COMPLEX_TO_MAG_IMPL_H +#define INCLUDED_COMPLEX_TO_MAG_IMPL_H + +#include <blocks/complex_to_mag.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API complex_to_mag_impl : public complex_to_mag + { + size_t d_vlen; + + public: + complex_to_mag_impl(size_t vlen); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + + +#endif /* INCLUDED_COMPLEX_TO_MAG_IMPL_H */ diff --git a/gr-blocks/lib/complex_to_mag_squared_impl.cc b/gr-blocks/lib/complex_to_mag_squared_impl.cc new file mode 100644 index 000000000..a3b48b153 --- /dev/null +++ b/gr-blocks/lib/complex_to_mag_squared_impl.cc @@ -0,0 +1,70 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "complex_to_mag_squared_impl.h" +#include <gr_io_signature.h> +#include <volk/volk.h> + +namespace gr { + namespace blocks { + + complex_to_mag_squared::sptr complex_to_mag_squared::make(size_t vlen) + { + return gnuradio::get_initial_sptr(new complex_to_mag_squared_impl(vlen)); + } + + complex_to_mag_squared_impl::complex_to_mag_squared_impl(size_t vlen) + : gr_sync_block("complex_to_mag_squared", + gr_make_io_signature (1, 1, sizeof(gr_complex)*vlen), + gr_make_io_signature (1, 1, sizeof(float)*vlen)), + d_vlen(vlen) + { + const int alignment_multiple = + volk_get_alignment() / sizeof(float); + set_alignment(std::max(1,alignment_multiple)); + } + + int + complex_to_mag_squared_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const gr_complex *in = (const gr_complex *) input_items[0]; + float *out = (float *) output_items[0]; + int noi = noutput_items * d_vlen; + + if(is_unaligned()) { + volk_32fc_magnitude_squared_32f_u(out, in, noi); + } + else { + volk_32fc_magnitude_squared_32f_a(out, in, noi); + } + + return noutput_items; + } + + } /* namespace blocks */ +}/* namespace gr */ diff --git a/gr-blocks/lib/complex_to_mag_squared_impl.h b/gr-blocks/lib/complex_to_mag_squared_impl.h new file mode 100644 index 000000000..01851d266 --- /dev/null +++ b/gr-blocks/lib/complex_to_mag_squared_impl.h @@ -0,0 +1,47 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_COMPLEX_TO_MAG_SQUARED_IMPL_H +#define INCLUDED_COMPLEX_TO_MAG_SQUARED_IMPL_H + +#include <blocks/complex_to_mag_squared.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API complex_to_mag_squared_impl : public complex_to_mag_squared + { + size_t d_vlen; + + public: + complex_to_mag_squared_impl(size_t vlen); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + + +#endif /* INCLUDED_COMPLEX_TO_MAG_SQUARED_IMPL_H */ diff --git a/gr-blocks/lib/complex_to_real_impl.cc b/gr-blocks/lib/complex_to_real_impl.cc new file mode 100644 index 000000000..6f053b669 --- /dev/null +++ b/gr-blocks/lib/complex_to_real_impl.cc @@ -0,0 +1,72 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "complex_to_real_impl.h" +#include <gr_io_signature.h> +#include <volk/volk.h> + +namespace gr { + namespace blocks { + + complex_to_real::sptr complex_to_real::make(size_t vlen) + { + return gnuradio::get_initial_sptr(new complex_to_real_impl(vlen)); + } + + complex_to_real_impl::complex_to_real_impl(size_t vlen) + : gr_sync_block("complex_to_real", + gr_make_io_signature (1, 1, sizeof(gr_complex)*vlen), + gr_make_io_signature (1, 1, sizeof(float)*vlen)), + d_vlen(vlen) + { + const int alignment_multiple = + volk_get_alignment() / sizeof(float); + set_alignment(std::max(1,alignment_multiple)); + } + + int + complex_to_real_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const gr_complex *in = (const gr_complex *) input_items[0]; + float *out = (float *) output_items[0]; + int noi = noutput_items * d_vlen; + + if(is_unaligned()) { + for (int i = 0; i < noi; i++){ + out[i] = in[i].real (); + } + } + else { + volk_32fc_deinterleave_real_32f_a(out, in, noi); + } + + return noutput_items; + } + + } /* namespace blocks */ +}/* namespace gr */ diff --git a/gr-blocks/lib/complex_to_real_impl.h b/gr-blocks/lib/complex_to_real_impl.h new file mode 100644 index 000000000..7d4d4306f --- /dev/null +++ b/gr-blocks/lib/complex_to_real_impl.h @@ -0,0 +1,47 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_COMPLEX_TO_REAL_IMPL_H +#define INCLUDED_COMPLEX_TO_REAL_IMPL_H + +#include <blocks/complex_to_real.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API complex_to_real_impl : public complex_to_real + { + size_t d_vlen; + + public: + complex_to_real_impl(size_t vlen); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + + +#endif /* INCLUDED_COMPLEX_TO_REAL_IMPL_H */ diff --git a/gr-blocks/lib/conjugate_cc_impl.cc b/gr-blocks/lib/conjugate_cc_impl.cc new file mode 100644 index 000000000..3d46bef68 --- /dev/null +++ b/gr-blocks/lib/conjugate_cc_impl.cc @@ -0,0 +1,68 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "conjugate_cc_impl.h" +#include <gr_io_signature.h> +#include <volk/volk.h> + +namespace gr { + namespace blocks { + + conjugate_cc::sptr conjugate_cc::make() + { + return gnuradio::get_initial_sptr(new conjugate_cc_impl()); + } + + conjugate_cc_impl::conjugate_cc_impl() + : gr_sync_block("conjugate_cc", + gr_make_io_signature (1, 1, sizeof(gr_complex)), + gr_make_io_signature (1, 1, sizeof(gr_complex))) + { + const int alignment_multiple = + volk_get_alignment() / sizeof(gr_complex); + set_alignment(std::max(1, alignment_multiple)); + } + + int + conjugate_cc_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + gr_complex *iptr = (gr_complex *) input_items[0]; + gr_complex *optr = (gr_complex *) output_items[0]; + + if(is_unaligned()) { + volk_32fc_conjugate_32fc_u(optr, iptr, noutput_items); + } + else { + volk_32fc_conjugate_32fc_a(optr, iptr, noutput_items); + } + + return noutput_items; + } + + } /* namespace blocks */ +}/* namespace gr */ diff --git a/gr-blocks/lib/conjugate_cc_impl.h b/gr-blocks/lib/conjugate_cc_impl.h new file mode 100644 index 000000000..448e7b318 --- /dev/null +++ b/gr-blocks/lib/conjugate_cc_impl.h @@ -0,0 +1,44 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_CONJUGATE_CC_IMPL_H +#define INCLUDED_CONJUGATE_CC_IMPL_H + +#include <blocks/conjugate_cc.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API conjugate_cc_impl : public conjugate_cc + { + public: + conjugate_cc_impl(); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_CONJUGATE_CC_IMPL_H */ diff --git a/gr-blocks/lib/deinterleave_impl.cc b/gr-blocks/lib/deinterleave_impl.cc new file mode 100644 index 000000000..badf4973a --- /dev/null +++ b/gr-blocks/lib/deinterleave_impl.cc @@ -0,0 +1,76 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "deinterleave_impl.h" +#include <gr_io_signature.h> + +namespace gr { + namespace blocks { + + deinterleave::sptr deinterleave::make(size_t itemsize) + { + return gnuradio::get_initial_sptr(new deinterleave_impl(itemsize)); + } + + deinterleave_impl::deinterleave_impl(size_t itemsize) + : gr_sync_decimator("deinterleave", + gr_make_io_signature (1, 1, itemsize), + gr_make_io_signature (1, gr_io_signature::IO_INFINITE, itemsize), + 1), + d_itemsize(itemsize) + { + } + + bool + deinterleave_impl::check_topology(int ninputs, int noutputs) + { + set_decimation(noutputs); + return true; + } + + int + deinterleave_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + size_t nchan = output_items.size(); + size_t itemsize = d_itemsize; + const char *in = (const char *)input_items[0]; + char **out = (char **)&output_items[0]; + + for (int i = 0; i < noutput_items; i++){ + for (unsigned int n = 0; n < nchan; n++){ + memcpy(out[n], in, itemsize); + out[n] += itemsize; + in += itemsize; + } + } + + return noutput_items; + } + + } /* namespace blocks */ +} /* namespace gr */ diff --git a/gr-blocks/lib/deinterleave_impl.h b/gr-blocks/lib/deinterleave_impl.h new file mode 100644 index 000000000..762c9d5fe --- /dev/null +++ b/gr-blocks/lib/deinterleave_impl.h @@ -0,0 +1,49 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_DEINTERLEAVE_IMPL_H +#define INCLUDED_DEINTERLEAVE_IMPL_H + +#include <blocks/deinterleave.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API deinterleave_impl : public deinterleave + { + size_t d_itemsize; + + public: + deinterleave_impl(size_t itemsize); + + bool check_topology(int ninputs, int noutputs); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + + +#endif /* INCLUDED_DEINTERLEAVE_IMPL_H */ diff --git a/gr-blocks/lib/divide_XX_impl.cc.t b/gr-blocks/lib/divide_XX_impl.cc.t new file mode 100644 index 000000000..223d6ad90 --- /dev/null +++ b/gr-blocks/lib/divide_XX_impl.cc.t @@ -0,0 +1,69 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2009,2010,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <@NAME_IMPL@.h> +#include <gr_io_signature.h> + +namespace gr { + namespace blocks { + + @NAME@::sptr @NAME@::make(size_t vlen) + { + return gnuradio::get_initial_sptr(new @NAME_IMPL@(vlen)); + } + + @NAME_IMPL@::@NAME_IMPL@(size_t vlen) + : gr_sync_block ("@NAME@", + gr_make_io_signature (1, -1, sizeof (@I_TYPE@)*vlen), + gr_make_io_signature (1, 1, sizeof (@O_TYPE@)*vlen)), + d_vlen(vlen) + { + } + + int + @NAME_IMPL@::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + @O_TYPE@ *optr = (@O_TYPE@ *) output_items[0]; + + int ninputs = input_items.size (); + + for (size_t i = 0; i < noutput_items*d_vlen; i++){ + @I_TYPE@ acc = ((@I_TYPE@ *) input_items[0])[i]; + for (int j = 1; j < ninputs; j++) + acc /= ((@I_TYPE@ *) input_items[j])[i]; + + *optr++ = (@O_TYPE@) acc; + } + + return noutput_items; + } + + } /* namespace blocks */ +} /* namespace gr */ diff --git a/gr-blocks/lib/divide_XX_impl.h.t b/gr-blocks/lib/divide_XX_impl.h.t new file mode 100644 index 000000000..a1c486b85 --- /dev/null +++ b/gr-blocks/lib/divide_XX_impl.h.t @@ -0,0 +1,48 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2009,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifndef @GUARD_NAME_IMPL@ +#define @GUARD_NAME_IMPL@ + +#include <blocks/@NAME@.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API @NAME_IMPL@ : public @NAME@ + { + size_t d_vlen; + + public: + @NAME_IMPL@(size_t vlen); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* @GUARD_NAME_IMPL@ */ diff --git a/gr-blocks/lib/file_meta_sink_impl.cc b/gr-blocks/lib/file_meta_sink_impl.cc new file mode 100644 index 000000000..ad16e9fca --- /dev/null +++ b/gr-blocks/lib/file_meta_sink_impl.cc @@ -0,0 +1,464 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "file_meta_sink_impl.h" +#include <gr_io_signature.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <stdexcept> +#include <cstdio> + +namespace gr { + namespace blocks { + +// win32 (mingw/msvc) specific +#ifdef HAVE_IO_H +#include <io.h> +#endif +#ifdef O_BINARY +#define OUR_O_BINARY O_BINARY +#else +#define OUR_O_BINARY 0 +#endif + +// should be handled via configure +#ifdef O_LARGEFILE +#define OUR_O_LARGEFILE O_LARGEFILE +#else +#define OUR_O_LARGEFILE 0 +#endif + + file_meta_sink::sptr + file_meta_sink::make(size_t itemsize, const std::string &filename, + double samp_rate, double relative_rate, + gr_file_types type, bool complex, + size_t max_segment_size, + const std::string &extra_dict, + bool detached_header) + { + return gnuradio::get_initial_sptr + (new file_meta_sink_impl(itemsize, filename, + samp_rate, relative_rate, + type, complex, + max_segment_size, + extra_dict, + detached_header)); + } + + file_meta_sink_impl::file_meta_sink_impl(size_t itemsize, + const std::string &filename, + double samp_rate, double relative_rate, + gr_file_types type, bool complex, + size_t max_segment_size, + const std::string &extra_dict, + bool detached_header) + : gr_sync_block("file_meta_sink", + gr_make_io_signature(1, 1, itemsize), + gr_make_io_signature(0, 0, 0)), + d_itemsize(itemsize), + d_samp_rate(samp_rate), d_relative_rate(relative_rate), + d_max_seg_size(max_segment_size), d_total_seg_size(0), + d_updated(false), d_unbuffered(false) + { + d_fp = 0; + d_new_fp = 0; + d_hdr_fp = 0; + d_new_hdr_fp = 0; + + if(detached_header == true) + d_state = STATE_DETACHED; + else + d_state = STATE_INLINE; + + if(!open(filename)) + throw std::runtime_error("file_meta_sink: can't open file\n"); + + pmt_t timestamp = pmt_make_tuple(pmt_from_uint64(0), + pmt_from_double(0)); + + // handle extra dictionary + d_extra = pmt_make_dict(); + if(extra_dict.size() > 0) { + pmt_t extras = pmt_deserialize_str(extra_dict); + pmt_t keys = pmt_dict_keys(extras); + pmt_t vals = pmt_dict_values(extras); + size_t nitems = pmt_length(keys); + for(size_t i = 0; i < nitems; i++) { + d_extra = pmt_dict_add(d_extra, + pmt_nth(i, keys), + pmt_nth(i, vals)); + } + } + + d_extra_size = pmt_serialize_str(d_extra).size(); + + d_header = pmt_make_dict(); + d_header = pmt_dict_add(d_header, mp("version"), mp(METADATA_VERSION)); + d_header = pmt_dict_add(d_header, mp("rx_rate"), mp(samp_rate)); + d_header = pmt_dict_add(d_header, mp("rx_time"), timestamp); + d_header = pmt_dict_add(d_header, mp("size"), pmt_from_long(d_itemsize)); + d_header = pmt_dict_add(d_header, mp("type"), pmt_from_long(type)); + d_header = pmt_dict_add(d_header, mp("cplx"), complex ? PMT_T : PMT_F); + d_header = pmt_dict_add(d_header, mp("strt"), pmt_from_uint64(METADATA_HEADER_SIZE+d_extra_size)); + d_header = pmt_dict_add(d_header, mp("bytes"), pmt_from_uint64(0)); + + do_update(); + + if(d_state == STATE_DETACHED) + write_header(d_hdr_fp, d_header, d_extra); + else + write_header(d_fp, d_header, d_extra); + } + + file_meta_sink_impl::~file_meta_sink_impl() + { + close(); + + if(d_fp) { + fclose(d_fp); + d_fp = 0; + } + + if(d_state == STATE_DETACHED) { + if(d_hdr_fp) { + fclose(d_hdr_fp); + d_hdr_fp = 0; + } + } + } + + bool + file_meta_sink_impl::open(const std::string &filename) + { + bool ret = true; + if(d_state == STATE_DETACHED) { + std::string s = filename + ".hdr"; + ret = _open(&d_new_hdr_fp, s.c_str()); + } + + ret = ret && _open(&d_new_fp, filename.c_str()); + d_updated = true; + return ret; + } + + bool + file_meta_sink_impl::_open(FILE **fp, const char *filename) + { + gruel::scoped_lock guard(d_mutex); // hold mutex for duration of this function + + bool ret = true; + int fd; + + if((fd = ::open(filename, + O_WRONLY|O_CREAT|O_TRUNC|OUR_O_LARGEFILE|OUR_O_BINARY, + 0664)) < 0){ + perror(filename); + return false; + } + + if(*fp) { // if we've already got a new one open, close it + fclose(*fp); + fp = 0; + } + + if((*fp = fdopen(fd, "wb")) == NULL) { + perror(filename); + ::close(fd); // don't leak file descriptor if fdopen fails. + } + + ret = fp != 0; + + return ret; + } + + void + file_meta_sink_impl::close() + { + gruel::scoped_lock guard(d_mutex); // hold mutex for duration of this function + update_last_header(); + + if(d_state == STATE_DETACHED) { + if(d_new_hdr_fp) { + fclose(d_new_hdr_fp); + d_new_hdr_fp = 0; + } + } + + if(d_new_fp) { + fclose(d_new_fp); + d_new_fp = 0; + } + d_updated = true; + } + + void + file_meta_sink_impl::do_update() + { + if(d_updated) { + gruel::scoped_lock guard(d_mutex); // hold mutex for duration of this block + if(d_state == STATE_DETACHED) { + if(d_hdr_fp) + fclose(d_hdr_fp); + d_hdr_fp = d_new_hdr_fp; // install new file pointer + d_new_hdr_fp = 0; + } + + if(d_fp) + fclose(d_fp); + d_fp = d_new_fp; // install new file pointer + d_new_fp = 0; + + d_updated = false; + } + } + + void + file_meta_sink_impl::write_header(FILE *fp, pmt_t header, pmt_t extra) + { + std::string header_str = pmt_serialize_str(header); + std::string extra_str = pmt_serialize_str(extra); + + if((header_str.size() != METADATA_HEADER_SIZE) && (extra_str.size() != d_extra_size)) + throw std::runtime_error("file_meta_sink: header or extras is wrong size.\n"); + + size_t nwritten = 0; + while(nwritten < header_str.size()) { + std::string sub = header_str.substr(nwritten); + int count = fwrite(sub.c_str(), sizeof(char), sub.size(), fp); + nwritten += count; + if((count == 0) && (ferror(fp))) { + fclose(fp); + throw std::runtime_error("file_meta_sink: error writing header to file.\n"); + } + } + + nwritten = 0; + while(nwritten < extra_str.size()) { + std::string sub = extra_str.substr(nwritten); + int count = fwrite(sub.c_str(), sizeof(char), sub.size(), fp); + nwritten += count; + if((count == 0) && (ferror(fp))) { + fclose(fp); + throw std::runtime_error("file_meta_sink: error writing extra to file.\n"); + } + } + + fflush(fp); + } + + void + file_meta_sink_impl::update_header(pmt_t key, pmt_t value) + { + // Special handling caveat to transform rate from radio source into + // the rate at this sink. + if(pmt_eq(key, mp("rx_rate"))) { + d_samp_rate = pmt_to_double(value); + value = pmt_from_double(d_samp_rate*d_relative_rate); + } + + // If the tag is not part of the standard header, we put it into the + // extra data, which either updates the current dictionary or adds a + // new item. + if(pmt_dict_has_key(d_header, key)) { + d_header = pmt_dict_add(d_header, key, value); + } + else { + d_extra = pmt_dict_add(d_extra, key, value); + d_extra_size = pmt_serialize_str(d_extra).size(); + } + } + + void + file_meta_sink_impl::update_last_header() + { + if(d_state == STATE_DETACHED) + update_last_header_detached(); + else + update_last_header_inline(); + } + + void + file_meta_sink_impl::update_last_header_inline() + { + // Update the last header info with the number of samples this + // block represents. + + size_t hdrlen = pmt_to_uint64(pmt_dict_ref(d_header, mp("strt"), PMT_NIL)); + size_t seg_size = d_itemsize*d_total_seg_size; + pmt_t s = pmt_from_uint64(seg_size); + update_header(mp("bytes"), s); + update_header(mp("strt"), pmt_from_uint64(METADATA_HEADER_SIZE+d_extra_size)); + fseek(d_fp, -seg_size-hdrlen, SEEK_CUR); + write_header(d_fp, d_header, d_extra); + fseek(d_fp, seg_size, SEEK_CUR); + } + + void + file_meta_sink_impl::update_last_header_detached() + { + // Update the last header info with the number of samples this + // block represents. + size_t hdrlen = pmt_to_uint64(pmt_dict_ref(d_header, mp("strt"), PMT_NIL)); + size_t seg_size = d_itemsize*d_total_seg_size; + pmt_t s = pmt_from_uint64(seg_size); + update_header(mp("bytes"), s); + update_header(mp("strt"), pmt_from_uint64(METADATA_HEADER_SIZE+d_extra_size)); + fseek(d_hdr_fp, -hdrlen, SEEK_CUR); + write_header(d_hdr_fp, d_header, d_extra); + } + + void + file_meta_sink_impl::write_and_update() + { + // New header, so set current size of chunk to 0 and start of chunk + // based on current index + header size. + //uint64_t loc = get_last_header_loc(); + pmt_t s = pmt_from_uint64(0); + update_header(mp("bytes"), s); + + // If we have multiple tags on the same offset, this makes + // sure we just overwrite the same header each time instead + // of creating a new header per tag. + s = pmt_from_uint64(METADATA_HEADER_SIZE + d_extra_size); + update_header(mp("strt"), s); + + if(d_state == STATE_DETACHED) + write_header(d_hdr_fp, d_header, d_extra); + else + write_header(d_fp, d_header, d_extra); + } + + void + file_meta_sink_impl::update_rx_time() + { + pmt_t rx_time = pmt_string_to_symbol("rx_time"); + pmt_t r = pmt_dict_ref(d_header, rx_time, PMT_NIL); + uint64_t secs = pmt_to_uint64(pmt_tuple_ref(r, 0)); + double fracs = pmt_to_double(pmt_tuple_ref(r, 1)); + double diff = d_total_seg_size / (d_samp_rate*d_relative_rate); + + //std::cerr << "old secs: " << secs << std::endl; + //std::cerr << "old fracs: " << fracs << std::endl; + //std::cerr << "seg size: " << d_total_seg_size << std::endl; + //std::cerr << "diff: " << diff << std::endl; + + fracs += diff; + uint64_t new_secs = static_cast<uint64_t>(fracs); + secs += new_secs; + fracs -= new_secs; + + //std::cerr << "new secs: " << secs << std::endl; + //std::cerr << "new fracs: " << fracs << std::endl << std::endl; + + r = pmt_make_tuple(pmt_from_uint64(secs), pmt_from_double(fracs)); + d_header = pmt_dict_add(d_header, rx_time, r); + } + + int + file_meta_sink_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + char *inbuf = (char*)input_items[0]; + int nwritten = 0; + + do_update(); // update d_fp is reqd + + if(!d_fp) + return noutput_items; // drop output on the floor + + uint64_t abs_N = nitems_read(0); + uint64_t end_N = abs_N + (uint64_t)(noutput_items); + std::vector<gr_tag_t> all_tags; + get_tags_in_range(all_tags, 0, abs_N, end_N); + + std::vector<gr_tag_t>::iterator itr; + for(itr = all_tags.begin(); itr != all_tags.end(); itr++) { + int item_offset = (int)(itr->offset - abs_N); + + // Write date to file up to the next tag location + while(nwritten < item_offset) { + size_t towrite = std::min(d_max_seg_size - d_total_seg_size, + (size_t)(item_offset - nwritten)); + int count = fwrite(inbuf, d_itemsize, towrite, d_fp); + if(count == 0) // FIXME add error handling + break; + nwritten += count; + inbuf += count * d_itemsize; + + d_total_seg_size += count; + + // Only add a new header if we are not at the position of the + // next tag + if((d_total_seg_size == d_max_seg_size) && + (nwritten < item_offset)) { + update_last_header(); + update_rx_time(); + write_and_update(); + d_total_seg_size = 0; + } + } + + if(d_total_seg_size > 0) { + update_last_header(); + update_header(itr->key, itr->value); + write_and_update(); + d_total_seg_size = 0; + } + else { + update_header(itr->key, itr->value); + update_last_header(); + } + } + + // Finish up the rest of the data after tags + while(nwritten < noutput_items) { + size_t towrite = std::min(d_max_seg_size - d_total_seg_size, + (size_t)(noutput_items - nwritten)); + int count = fwrite(inbuf, d_itemsize, towrite, d_fp); + if(count == 0) // FIXME add error handling + break; + nwritten += count; + inbuf += count * d_itemsize; + + d_total_seg_size += count; + if(d_total_seg_size == d_max_seg_size) { + update_last_header(); + update_rx_time(); + write_and_update(); + d_total_seg_size = 0; + } + } + + if(d_unbuffered) + fflush(d_fp); + + return nwritten; + } + + } /* namespace blocks */ +} /* namespace gr */ diff --git a/gr-blocks/lib/file_meta_sink_impl.h b/gr-blocks/lib/file_meta_sink_impl.h new file mode 100644 index 000000000..566c997b3 --- /dev/null +++ b/gr-blocks/lib/file_meta_sink_impl.h @@ -0,0 +1,96 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_BLOCKS_FILE_META_SINK_IMPL_H +#define INCLUDED_BLOCKS_FILE_META_SINK_IMPL_H + +#include <blocks/file_meta_sink.h> +#include <gruel/pmt.h> +#include <gruel/thread.h> + +using namespace pmt; + +namespace gr { + namespace blocks { + + class file_meta_sink_impl : public file_meta_sink + { + private: + enum meta_state_t { + STATE_INLINE=0, + STATE_DETACHED + }; + + size_t d_itemsize; + double d_samp_rate; + double d_relative_rate; + size_t d_max_seg_size; + size_t d_total_seg_size; + pmt_t d_header; + pmt_t d_extra; + size_t d_extra_size; + bool d_updated; + bool d_unbuffered; + + boost::mutex d_mutex; + FILE *d_new_fp, *d_new_hdr_fp; + FILE *d_fp, *d_hdr_fp; + meta_state_t d_state; + + protected: + void write_header(FILE *fp, pmt_t header, pmt_t extra); + void update_header(pmt_t key, pmt_t value); + void update_last_header(); + void update_last_header_inline(); + void update_last_header_detached(); + void write_and_update(); + void update_rx_time(); + + bool _open(FILE **fp, const char *filename); + + public: + file_meta_sink_impl(size_t itemsize, const std::string &filename, + double samp_rate=1, double relative_rate=1, + gr_file_types type=GR_FILE_FLOAT, bool complex=true, + size_t max_segment_size=1000000, + const std::string &extra_dict="", + bool detached_header=false); + ~file_meta_sink_impl(); + + bool open(const std::string &filename); + void close(); + void do_update(); + + void set_unbuffered(bool unbuffered) + { + d_unbuffered = unbuffered; + } + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_BLOCKS_FILE_META_SINK_IMPL_H */ diff --git a/gr-blocks/lib/file_meta_source_impl.cc b/gr-blocks/lib/file_meta_source_impl.cc new file mode 100644 index 000000000..fb39b205b --- /dev/null +++ b/gr-blocks/lib/file_meta_source_impl.cc @@ -0,0 +1,433 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "file_meta_source_impl.h" +#include <gr_io_signature.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <stdexcept> +#include <cstdio> + +namespace gr { + namespace blocks { + +// win32 (mingw/msvc) specific +#ifdef HAVE_IO_H +#include <io.h> +#endif +#ifdef O_BINARY +#define OUR_O_BINARY O_BINARY +#else +#define OUR_O_BINARY 0 +#endif + +// should be handled via configure +#ifdef O_LARGEFILE +#define OUR_O_LARGEFILE O_LARGEFILE +#else +#define OUR_O_LARGEFILE 0 +#endif + + file_meta_source::sptr + file_meta_source::make(const std::string &filename, + bool repeat, + bool detached_header, + const std::string &hdr_filename) + { + return gnuradio::get_initial_sptr + (new file_meta_source_impl(filename, + repeat, + detached_header, + hdr_filename)); + } + + file_meta_source_impl::file_meta_source_impl(const std::string &filename, + bool repeat, + bool detached_header, + const std::string &hdr_filename) + : gr_sync_block("file_meta_source", + gr_make_io_signature(0, 0, 0), + gr_make_io_signature(1, 1, 1)), + d_itemsize(0), d_samp_rate(0), + d_seg_size(0), + d_updated(false), d_repeat(repeat) + { + d_fp = 0; + d_new_fp = 0; + d_hdr_fp = 0; + d_new_hdr_fp = 0; + + if(detached_header == true) { + d_state = STATE_DETACHED; + } + else + d_state = STATE_INLINE; + + if(!open(filename, hdr_filename)) + throw std::runtime_error("file_meta_source: can't open file\n"); + + do_update(); + + pmt_t hdr = PMT_NIL, extras = PMT_NIL; + if(read_header(hdr, extras)) { + parse_header(hdr, 0, d_tags); + parse_extras(extras, 0, d_tags); + } + else + throw std::runtime_error("file_meta_source: could not read header.\n"); + + // Set output signature based on itemsize info in header + set_output_signature(gr_make_io_signature(1, 1, d_itemsize)); + } + + file_meta_source_impl::~file_meta_source_impl() + { + close(); + + if(d_fp) { + fclose(d_fp); + d_fp = 0; + } + + if(d_state == STATE_DETACHED) { + if(d_hdr_fp) { + fclose(d_hdr_fp); + d_hdr_fp = 0; + } + } + } + + bool + file_meta_source_impl::read_header(pmt_t &hdr, pmt_t &extras) + { + // Select which file handle to read from. + FILE *fp; + if(d_state == STATE_DETACHED) + fp = d_hdr_fp; + else + fp = d_fp; + + size_t ret; + size_t size = 0; + std::string str; + char *hdr_buffer = new char[METADATA_HEADER_SIZE]; + while(size < METADATA_HEADER_SIZE) { + ret = fread(&hdr_buffer[size], sizeof(char), METADATA_HEADER_SIZE-size, fp); + if(ret == 0) { + delete [] hdr_buffer; + if(feof(fp)) + return false; + else { + std::stringstream s; + s << "file_meta_source: error occurred extracting header: " + << strerror(errno) << std::endl; + throw std::runtime_error(s.str()); + } + } + size += ret; + } + + // Convert to string or the char array gets confused by the \0 + str.insert(0, hdr_buffer, METADATA_HEADER_SIZE); + hdr = pmt_deserialize_str(str); + delete [] hdr_buffer; + + uint64_t seg_start, extra_len; + pmt_t r, dump; + if(pmt_dict_has_key(hdr, pmt_string_to_symbol("strt"))) { + r = pmt_dict_ref(hdr, pmt_string_to_symbol("strt"), dump); + seg_start = pmt_to_uint64(r); + extra_len = seg_start - METADATA_HEADER_SIZE; + } + + if(extra_len > 0) { + size = 0; + hdr_buffer = new char[extra_len]; + while(size < extra_len) { + ret = fread(&hdr_buffer[size], sizeof(char), extra_len-size, fp); + if(ret == 0) { + delete [] hdr_buffer; + if(feof(fp)) + return false; + else { + std::stringstream s; + s << "file_meta_source: error occurred extracting extras: " + << strerror(errno) << std::endl; + throw std::runtime_error(s.str()); + } + } + size += ret; + } + + str.clear(); + str.insert(0, hdr_buffer, extra_len); + extras = pmt_deserialize_str(str); + delete [] hdr_buffer; + } + + return true; + } + + void + file_meta_source_impl::parse_header(pmt_t hdr, uint64_t offset, + std::vector<gr_tag_t> &tags) + { + pmt_t r, key; + + // GET SAMPLE RATE + key = pmt_string_to_symbol("rx_rate"); + if(pmt_dict_has_key(hdr, key)) { + r = pmt_dict_ref(hdr, key, PMT_NIL); + d_samp_rate = pmt_to_double(r); + + gr_tag_t t; + t.offset = offset; + t.key = key; + t.value = r; + t.srcid = alias_pmt(); + tags.push_back(t); + } + else { + throw std::runtime_error("file_meta_source: Could not extract sample rate.\n"); + } + + // GET TIME STAMP + key = pmt_string_to_symbol("rx_time"); + if(pmt_dict_has_key(hdr, key)) { + d_time_stamp = pmt_dict_ref(hdr, key, PMT_NIL); + + gr_tag_t t; + t.offset = offset; + t.key = key; + t.value = d_time_stamp; + t.srcid = alias_pmt(); + tags.push_back(t); + } + else { + throw std::runtime_error("file_meta_source: Could not extract time stamp.\n"); + } + + // GET ITEM SIZE OF DATA + if(pmt_dict_has_key(hdr, pmt_string_to_symbol("size"))) { + d_itemsize = pmt_to_long(pmt_dict_ref(hdr, pmt_string_to_symbol("size"), PMT_NIL)); + } + else { + throw std::runtime_error("file_meta_source: Could not extract item size.\n"); + } + + // GET SEGMENT SIZE + if(pmt_dict_has_key(hdr, pmt_string_to_symbol("bytes"))) { + d_seg_size = pmt_to_uint64(pmt_dict_ref(hdr, pmt_string_to_symbol("bytes"), PMT_NIL)); + + // Convert from bytes to items + d_seg_size /= d_itemsize; + } + else { + throw std::runtime_error("file_meta_source: Could not extract segment size.\n"); + } + } + + void + file_meta_source_impl::parse_extras(pmt_t extras, uint64_t offset, + std::vector<gr_tag_t> &tags) + { + pmt_t item, key, val; + + size_t nitems = pmt_length(extras); + for(size_t i = 0; i < nitems; i++) { + item = pmt_nth(i, extras); + key = pmt_car(item); + val = pmt_cdr(item); + + gr_tag_t t; + t.offset = offset; + t.key = key; + t.value = val; + t.srcid = alias_pmt(); + tags.push_back(t); + } + } + + bool + file_meta_source_impl::open(const std::string &filename, + const std::string &hdr_filename) + { + bool ret = true; + if(d_state == STATE_DETACHED) { + std::string s; + if(hdr_filename == "") + s = filename + ".hdr"; + else + s = hdr_filename; + ret = _open(&d_new_hdr_fp, s.c_str()); + } + + ret = ret && _open(&d_new_fp, filename.c_str()); + d_updated = true; + return ret; + } + + bool + file_meta_source_impl::_open(FILE **fp, const char *filename) + { + gruel::scoped_lock guard(d_mutex); // hold mutex for duration of this function + + bool ret = true; + int fd; + + if((fd = ::open(filename, + O_RDONLY|OUR_O_LARGEFILE|OUR_O_BINARY)) < 0) { + perror(filename); + return false; + } + + if(*fp) { // if we've already got a new one open, close it + fclose(*fp); + fp = 0; + } + + if((*fp = fdopen(fd, "rb")) == NULL) { + perror(filename); + ::close(fd); // don't leak file descriptor if fdopen fails. + } + + ret = fp != 0; + + return ret; + } + + void + file_meta_source_impl::close() + { + gruel::scoped_lock guard(d_mutex); // hold mutex for duration of this function + if(d_state == STATE_DETACHED) { + if(d_new_hdr_fp) { + fclose(d_new_hdr_fp); + d_new_hdr_fp = 0; + } + } + + if(d_new_fp) { + fclose(d_new_fp); + d_new_fp = 0; + } + d_updated = true; + } + + void + file_meta_source_impl::do_update() + { + if(d_updated) { + gruel::scoped_lock guard(d_mutex); // hold mutex for duration of this block + if(d_state == STATE_DETACHED) { + if(d_hdr_fp) + fclose(d_hdr_fp); + d_hdr_fp = d_new_hdr_fp; // install new file pointer + d_new_hdr_fp = 0; + } + + if(d_fp) + fclose(d_fp); + d_fp = d_new_fp; // install new file pointer + d_new_fp = 0; + + d_updated = false; + } + } + + int + file_meta_source_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + // We've reached the end of a segment; parse the next header and get + // the new tags to send and set the next segment size. + if(d_seg_size == 0) { + pmt_t hdr=PMT_NIL, extras=PMT_NIL; + if(read_header(hdr, extras)) { + parse_header(hdr, nitems_written(0), d_tags); + parse_extras(extras, nitems_written(0), d_tags); + } + else { + return -1; + } + } + + char *out = (char*)output_items[0]; + int i; + int seg_size = std::min(noutput_items, (int)d_seg_size); + int size = seg_size; + + do_update(); // update d_fp is reqd + if(d_fp == NULL) + throw std::runtime_error("work with file not open"); + + // Push all tags onto the stream and remove them from the vector + while(!d_tags.empty()) { + add_item_tag(0, d_tags.back()); + d_tags.pop_back(); + } + + gruel::scoped_lock lock(d_mutex); // hold for the rest of this function + while(size) { + i = fread(out, d_itemsize, size, d_fp); + + size -= i; + d_seg_size -= i; + out += i * d_itemsize; + + if(size == 0) // done + break; + + if(i > 0) // short read, try again + continue; + + // We got a zero from fread. This is either EOF or error. In + // any event, if we're in repeat mode, seek back to the beginning + // of the file and try again, else break + + if(!d_repeat) + break; + + if(fseek(d_fp, 0, SEEK_SET) == -1) { + std::stringstream s; + s << "[" << __FILE__ << "]" << " fseek failed" << std::endl; + throw std::runtime_error(s.str()); + } + } + + if(size > 0) { // EOF or error + if(size == seg_size) // we didn't read anything; say we're done + return -1; + return seg_size - size; // else return partial result + } + + return seg_size; + } + + } /* namespace blocks */ +} /* namespace gr */ diff --git a/gr-blocks/lib/file_meta_source_impl.h b/gr-blocks/lib/file_meta_source_impl.h new file mode 100644 index 000000000..ca7ddc6e1 --- /dev/null +++ b/gr-blocks/lib/file_meta_source_impl.h @@ -0,0 +1,89 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_BLOCKS_FILE_META_SOURCE_IMPL_H +#define INCLUDED_BLOCKS_FILE_META_SOURCE_IMPL_H + +#include <blocks/file_meta_source.h> +#include <gr_tags.h> +#include <gruel/pmt.h> +#include <gruel/thread.h> + +#include <blocks/file_meta_sink.h> + +using namespace pmt; + +namespace gr { + namespace blocks { + + class file_meta_source_impl : public file_meta_source + { + private: + enum meta_state_t { + STATE_INLINE=0, + STATE_DETACHED + }; + + size_t d_itemsize; + double d_samp_rate; + pmt_t d_time_stamp; + size_t d_seg_size; + bool d_updated; + bool d_repeat; + + gruel::mutex d_mutex; + FILE *d_new_fp, *d_new_hdr_fp; + FILE *d_fp, *d_hdr_fp; + meta_state_t d_state; + + std::vector<gr_tag_t> d_tags; + + protected: + bool _open(FILE **fp, const char *filename); + bool read_header(pmt_t &hdr, pmt_t &extras); + void parse_header(pmt_t hdr, uint64_t offset, + std::vector<gr_tag_t> &tags); + void parse_extras(pmt_t extras, uint64_t offset, + std::vector<gr_tag_t> &tags); + + public: + file_meta_source_impl(const std::string &filename, + bool repeat=false, + bool detached_header=false, + const std::string &hdr_filename=""); + + ~file_meta_source_impl(); + + bool open(const std::string &filename, + const std::string &hdr_filename=""); + void close(); + void do_update(); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_BLOCKS_FILE_META_SOURCE_IMPL_H */ diff --git a/gr-blocks/lib/file_source_impl.cc b/gr-blocks/lib/file_source_impl.cc new file mode 100644 index 000000000..ed1f50c43 --- /dev/null +++ b/gr-blocks/lib/file_source_impl.cc @@ -0,0 +1,188 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "file_source_impl.h" +#include <gr_io_signature.h> +#include <cstdio> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <stdexcept> +#include <stdio.h> + +// win32 (mingw/msvc) specific +#ifdef HAVE_IO_H +#include <io.h> +#endif +#ifdef O_BINARY +#define OUR_O_BINARY O_BINARY +#else +#define OUR_O_BINARY 0 +#endif +// should be handled via configure +#ifdef O_LARGEFILE +#define OUR_O_LARGEFILE O_LARGEFILE +#else +#define OUR_O_LARGEFILE 0 +#endif + +namespace gr { + namespace blocks { + + file_source::sptr file_source::make(size_t itemsize, const char *filename, bool repeat) + { + return gnuradio::get_initial_sptr + (new file_source_impl(itemsize, filename, repeat)); + } + + file_source_impl::file_source_impl(size_t itemsize, const char *filename, bool repeat) + : gr_sync_block("file_source", + gr_make_io_signature(0, 0, 0), + gr_make_io_signature(1, 1, itemsize)), + d_itemsize(itemsize), d_fp(0), d_new_fp(0), d_repeat(repeat), + d_updated(false) + { + open(filename, repeat); + } + + file_source_impl::~file_source_impl() + { + fclose ((FILE*)d_fp); + } + + bool + file_source_impl::seek(long seek_point, int whence) + { + return fseek((FILE*)d_fp, seek_point *d_itemsize, whence) == 0; + } + + + void + file_source_impl::open(const char *filename, bool repeat) + { + // obtain exclusive access for duration of this function + boost::mutex::scoped_lock lock(fp_mutex); + + int fd; + + // we use "open" to use to the O_LARGEFILE flag + if((fd = ::open(filename, O_RDONLY | OUR_O_LARGEFILE | OUR_O_BINARY)) < 0) { + perror(filename); + throw std::runtime_error("can't open file"); + } + + if(d_new_fp) { + fclose(d_new_fp); + d_new_fp = 0; + } + + if((d_new_fp = fdopen (fd, "rb")) == NULL) { + perror(filename); + ::close(fd); // don't leak file descriptor if fdopen fails + throw std::runtime_error("can't open file"); + } + + d_updated = true; + d_repeat = repeat; + } + + void + file_source_impl::close() + { + // obtain exclusive access for duration of this function + boost::mutex::scoped_lock lock(fp_mutex); + + if(d_new_fp != NULL) { + fclose(d_new_fp); + d_new_fp = NULL; + } + d_updated = true; + } + + void + file_source_impl::do_update() + { + if(d_updated) { + boost::mutex::scoped_lock lock(fp_mutex); // hold while in scope + + if(d_fp) + fclose(d_fp); + + d_fp = d_new_fp; // install new file pointer + d_new_fp = 0; + d_updated = false; + } + } + + int + file_source_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + char *o = (char*)output_items[0]; + int i; + int size = noutput_items; + + do_update(); // update d_fp is reqd + if(d_fp == NULL) + throw std::runtime_error("work with file not open"); + + boost::mutex::scoped_lock lock(fp_mutex); // hold for the rest of this function + while(size) { + i = fread(o, d_itemsize, size, (FILE*)d_fp); + + size -= i; + o += i * d_itemsize; + + if(size == 0) // done + break; + + if(i > 0) // short read, try again + continue; + + // We got a zero from fread. This is either EOF or error. In + // any event, if we're in repeat mode, seek back to the beginning + // of the file and try again, else break + if(!d_repeat) + break; + + if(fseek ((FILE *) d_fp, 0, SEEK_SET) == -1) { + fprintf(stderr, "[%s] fseek failed\n", __FILE__); + exit(-1); + } + } + + if(size > 0) { // EOF or error + if(size == noutput_items) // we didn't read anything; say we're done + return -1; + return noutput_items - size; // else return partial result + } + + return noutput_items; + } + + } /* namespace blocks */ +} /* namespace gr */ diff --git a/gr-blocks/lib/file_source_impl.h b/gr-blocks/lib/file_source_impl.h new file mode 100644 index 000000000..600fe80ab --- /dev/null +++ b/gr-blocks/lib/file_source_impl.h @@ -0,0 +1,59 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_BLOCKS_FILE_SOURCE_IMPL_H +#define INCLUDED_BLOCKS_FILE_SOURCE_IMPL_H + +#include <blocks/file_source.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API file_source_impl : public file_source + { + private: + size_t d_itemsize; + FILE *d_fp; + FILE *d_new_fp; + bool d_repeat; + bool d_updated; + boost::mutex fp_mutex; + + void do_update(); + + public: + file_source_impl(size_t itemsize, const char *filename, bool repeat); + ~file_source_impl(); + + bool seek(long seek_point, int whence); + void open(const char *filename, bool repeat); + void close(); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_BLOCKS_FILE_SOURCE_IMPL_H */ diff --git a/gr-blocks/lib/float_array_to_int.cc b/gr-blocks/lib/float_array_to_int.cc new file mode 100644 index 000000000..66b112c06 --- /dev/null +++ b/gr-blocks/lib/float_array_to_int.cc @@ -0,0 +1,46 @@ +/* -*- c++ -*- */ +/* + * Copyright 2011-2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#define _ISOC9X_SOURCE +#include <float_array_to_int.h> +#include <math.h> +#include <stdint.h> + +static const int64_t MAX_INT = 2147483647; // (2^31)-1 +static const int64_t MIN_INT = -2147483647; // -(2^31)-1 + +void +float_array_to_int(const float *in, int *out, float scale, int nsamples) +{ + for (int i = 0; i < nsamples; i++){ + int64_t r = llrintf(scale * in[i]); + if (r < MIN_INT) + r = MIN_INT; + else if (r > MAX_INT) + r = MAX_INT; + out[i] = static_cast<int>(r); + } +} diff --git a/gr-blocks/lib/float_array_to_int.h b/gr-blocks/lib/float_array_to_int.h new file mode 100644 index 000000000..943736d7e --- /dev/null +++ b/gr-blocks/lib/float_array_to_int.h @@ -0,0 +1,33 @@ +/* -*- c++ -*- */ +/* + * Copyright 2011-2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_BLOCKS_FLOAT_ARRAY_TO_INT_H +#define INCLUDED_BLOCKS_FLOAT_ARRAY_TO_INT_H + +#include <blocks/api.h> + +/*! + * convert array of floats to int with rounding and saturation. + */ +BLOCKS_API void float_array_to_int (const float *in, int *out, float scale, int nsamples); + +#endif /* INCLUDED_BLOCKS_FLOAT_ARRAY_TO_INT_H */ diff --git a/gr-blocks/lib/float_array_to_uchar.cc b/gr-blocks/lib/float_array_to_uchar.cc new file mode 100644 index 000000000..06688e7b0 --- /dev/null +++ b/gr-blocks/lib/float_array_to_uchar.cc @@ -0,0 +1,45 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#define _ISOC9X_SOURCE +#include <float_array_to_uchar.h> +#include <math.h> + +static const int MIN_UCHAR = 0; +static const int MAX_UCHAR = 255; + +void +float_array_to_uchar(const float *in, unsigned char *out, int nsamples) +{ + for (int i = 0; i < nsamples; i++){ + long int r = (long int) rint (in[i]); + if (r < MIN_UCHAR) + r = MIN_UCHAR; + else if (r > MAX_UCHAR) + r = MAX_UCHAR; + out[i] = r; + } +} diff --git a/gr-blocks/lib/float_array_to_uchar.h b/gr-blocks/lib/float_array_to_uchar.h new file mode 100644 index 000000000..defed8e3e --- /dev/null +++ b/gr-blocks/lib/float_array_to_uchar.h @@ -0,0 +1,33 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_FLOAT_ARRAY_TO_UCHAR_H +#define INCLUDED_FLOAT_ARRAY_TO_UCHAR_H + +#include <blocks/api.h> + +/*! + * convert array of floats to unsigned chars with rounding and saturation. + */ +BLOCKS_API void float_array_to_uchar (const float *in, unsigned char *out, int nsamples); + +#endif /* INCLUDED_FLOAT_ARRAY_TO_UCHAR_H */ diff --git a/gr-blocks/lib/float_to_char_impl.cc b/gr-blocks/lib/float_to_char_impl.cc new file mode 100644 index 000000000..c37522dc9 --- /dev/null +++ b/gr-blocks/lib/float_to_char_impl.cc @@ -0,0 +1,69 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "float_to_char_impl.h" +#include <gr_io_signature.h> +#include <volk/volk.h> + +namespace gr { + namespace blocks { + + float_to_char::sptr float_to_char::make(size_t vlen, float scale) + { + return gnuradio::get_initial_sptr(new float_to_char_impl(vlen, scale)); + } + + float_to_char_impl::float_to_char_impl(size_t vlen, float scale) + : gr_sync_block("float_to_char", + gr_make_io_signature (1, 1, sizeof(float)*vlen), + gr_make_io_signature (1, 1, sizeof(char)*vlen)), + d_vlen(vlen), d_scale(scale) + { + const int alignment_multiple = + volk_get_alignment() / sizeof(char); + set_alignment(std::max(1, alignment_multiple)); + } + + int + float_to_char_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const float *in = (const float *) input_items[0]; + int8_t *out = (int8_t *) output_items[0]; + + if(is_unaligned()) { + volk_32f_s32f_convert_8i_u(out, in, d_scale, d_vlen*noutput_items); + } + else { + volk_32f_s32f_convert_8i_a(out, in, d_scale, d_vlen*noutput_items); + } + + return noutput_items; + } + + } /* namespace blocks */ +}/* namespace gr */ diff --git a/gr-blocks/lib/float_to_char_impl.h b/gr-blocks/lib/float_to_char_impl.h new file mode 100644 index 000000000..2644f3e70 --- /dev/null +++ b/gr-blocks/lib/float_to_char_impl.h @@ -0,0 +1,51 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_FLOAT_TO_CHAR_IMPL_H +#define INCLUDED_FLOAT_TO_CHAR_IMPL_H + +#include <blocks/float_to_char.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API float_to_char_impl : public float_to_char + { + size_t d_vlen; + float d_scale; + + public: + float_to_char_impl(size_t vlen, float scale); + + virtual float scale() const { return d_scale; } + virtual void set_scale(float scale) { d_scale = scale; } + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + + +#endif /* INCLUDED_FLOAT_TO_CHAR_IMPL_H */ diff --git a/gr-blocks/lib/float_to_complex_impl.cc b/gr-blocks/lib/float_to_complex_impl.cc new file mode 100644 index 000000000..709aa420c --- /dev/null +++ b/gr-blocks/lib/float_to_complex_impl.cc @@ -0,0 +1,78 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "float_to_complex_impl.h" +#include <gr_io_signature.h> +#include <volk/volk.h> + +namespace gr { + namespace blocks { + + float_to_complex::sptr float_to_complex::make(size_t vlen) + { + return gnuradio::get_initial_sptr(new float_to_complex_impl(vlen)); + } + + float_to_complex_impl::float_to_complex_impl(size_t vlen) + : gr_sync_block("float_to_complex", + gr_make_io_signature (1, 2, sizeof(float)*vlen), + gr_make_io_signature (1, 1, sizeof(gr_complex)*vlen)), + d_vlen(vlen) + { + const int alignment_multiple = + volk_get_alignment() / sizeof(float); + set_alignment(std::max(1,alignment_multiple)); + } + + int + float_to_complex_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + float *r = (float *)input_items[0]; + float *i = (float *)input_items[1]; + gr_complex *out = (gr_complex *) output_items[0]; + + switch (input_items.size ()){ + case 1: + for (size_t j = 0; j < noutput_items*d_vlen; j++) + out[j] = gr_complex (r[j], 0); + break; + + case 2: + for (size_t j = 0; j < noutput_items*d_vlen; j++) + out[j] = gr_complex (r[j], i[j]); + break; + + default: + assert (0); + } + + return noutput_items; + } + + } /* namespace blocks */ +}/* namespace gr */ diff --git a/gr-blocks/lib/float_to_complex_impl.h b/gr-blocks/lib/float_to_complex_impl.h new file mode 100644 index 000000000..859c5bf96 --- /dev/null +++ b/gr-blocks/lib/float_to_complex_impl.h @@ -0,0 +1,47 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_FLOAT_TO_COMPLEX_IMPL_H +#define INCLUDED_FLOAT_TO_COMPLEX_IMPL_H + +#include <blocks/float_to_complex.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API float_to_complex_impl : public float_to_complex + { + size_t d_vlen; + + public: + float_to_complex_impl(size_t vlen); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + + +#endif /* INCLUDED_FLOAT_TO_COMPLEX_IMPL_H */ diff --git a/gr-blocks/lib/float_to_int_impl.cc b/gr-blocks/lib/float_to_int_impl.cc new file mode 100644 index 000000000..24218ab68 --- /dev/null +++ b/gr-blocks/lib/float_to_int_impl.cc @@ -0,0 +1,83 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "float_to_int_impl.h" +#include "float_array_to_int.h" +#include <gr_io_signature.h> +#include <volk/volk.h> + +namespace gr { + namespace blocks { + + float_to_int::sptr float_to_int::make(size_t vlen, float scale) + { + return gnuradio::get_initial_sptr(new float_to_int_impl(vlen, scale)); + } + + float_to_int_impl::float_to_int_impl(size_t vlen, float scale) + : gr_sync_block("float_to_int", + gr_make_io_signature (1, 1, sizeof(float)*vlen), + gr_make_io_signature (1, 1, sizeof(int)*vlen)), + d_vlen(vlen), d_scale(scale) + { + const int alignment_multiple = + volk_get_alignment() / sizeof(int); + set_alignment(std::max(1, alignment_multiple)); + } + + int + float_to_int_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + // Disable the Volk for now. There is a problem for large 32-bit ints that + // are not properly represented by the precisions of a single float, which + // can cause wrapping from large, positive numbers to negative. + // In gri_float_to_int, the value is first promoted to a 64-bit + // value, clipped, then converted to a float. +#if 0 + const float *in = (const float *) input_items[0]; + int32_t *out = (int32_t *) output_items[0]; + + if(is_unaligned()) { + volk_32f_s32f_convert_32i_u(out, in, d_scale, d_vlen*noutput_items); + } + else { + volk_32f_s32f_convert_32i_a(out, in, d_scale, d_vlen*noutput_items); + } +#else + const float *in = (const float *) input_items[0]; + int *out = (int *) output_items[0]; + + float_array_to_int (in, out, d_scale, d_vlen*noutput_items); + +#endif + + return noutput_items; + } + + } /* namespace blocks */ +}/* namespace gr */ diff --git a/gr-blocks/lib/float_to_int_impl.h b/gr-blocks/lib/float_to_int_impl.h new file mode 100644 index 000000000..71775fcb1 --- /dev/null +++ b/gr-blocks/lib/float_to_int_impl.h @@ -0,0 +1,51 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_FLOAT_TO_INT_IMPL_H +#define INCLUDED_FLOAT_TO_INT_IMPL_H + +#include <blocks/float_to_int.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API float_to_int_impl : public float_to_int + { + size_t d_vlen; + float d_scale; + + public: + float_to_int_impl(size_t vlen, float scale); + + virtual float scale() const { return d_scale; } + virtual void set_scale(float scale) { d_scale = scale; } + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + + +#endif /* INCLUDED_FLOAT_TO_INT_IMPL_H */ diff --git a/gr-blocks/lib/float_to_short_impl.cc b/gr-blocks/lib/float_to_short_impl.cc new file mode 100644 index 000000000..2807ae192 --- /dev/null +++ b/gr-blocks/lib/float_to_short_impl.cc @@ -0,0 +1,69 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "float_to_short_impl.h" +#include <gr_io_signature.h> +#include <volk/volk.h> + +namespace gr { + namespace blocks { + + float_to_short::sptr float_to_short::make(size_t vlen, float scale) + { + return gnuradio::get_initial_sptr(new float_to_short_impl(vlen, scale)); + } + + float_to_short_impl::float_to_short_impl(size_t vlen, float scale) + : gr_sync_block("float_to_short", + gr_make_io_signature (1, 1, sizeof(float)*vlen), + gr_make_io_signature (1, 1, sizeof(short)*vlen)), + d_vlen(vlen), d_scale(scale) + { + const int alignment_multiple = + volk_get_alignment() / sizeof(short); + set_alignment(std::max(1, alignment_multiple)); + } + + int + float_to_short_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const float *in = (const float *) input_items[0]; + short *out = (short *) output_items[0]; + + if(is_unaligned()) { + volk_32f_s32f_convert_16i_u(out, in, d_scale, d_vlen*noutput_items); + } + else { + volk_32f_s32f_convert_16i_a(out, in, d_scale, d_vlen*noutput_items); + } + + return noutput_items; + } + + } /* namespace blocks */ +}/* namespace gr */ diff --git a/gr-blocks/lib/float_to_short_impl.h b/gr-blocks/lib/float_to_short_impl.h new file mode 100644 index 000000000..5427862b3 --- /dev/null +++ b/gr-blocks/lib/float_to_short_impl.h @@ -0,0 +1,51 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_FLOAT_TO_SHORT_IMPL_H +#define INCLUDED_FLOAT_TO_SHORT_IMPL_H + +#include <blocks/float_to_short.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API float_to_short_impl : public float_to_short + { + size_t d_vlen; + float d_scale; + + public: + float_to_short_impl(size_t vlen, float scale); + + virtual float scale() const { return d_scale; } + virtual void set_scale(float scale) { d_scale = scale; } + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + + +#endif /* INCLUDED_FLOAT_TO_SHORT_IMPL_H */ diff --git a/gr-blocks/lib/float_to_uchar_impl.cc b/gr-blocks/lib/float_to_uchar_impl.cc new file mode 100644 index 000000000..22d0527b1 --- /dev/null +++ b/gr-blocks/lib/float_to_uchar_impl.cc @@ -0,0 +1,60 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "float_to_uchar_impl.h" +#include "float_array_to_uchar.h" +#include <gr_io_signature.h> + +namespace gr { + namespace blocks { + + float_to_uchar::sptr float_to_uchar::make() + { + return gnuradio::get_initial_sptr(new float_to_uchar_impl()); + } + + float_to_uchar_impl::float_to_uchar_impl() + : gr_sync_block("float_to_uchar", + gr_make_io_signature (1, 1, sizeof(float)), + gr_make_io_signature (1, 1, sizeof(unsigned char))) + { + } + + int + float_to_uchar_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const float *in = (const float *)input_items[0]; + unsigned char *out = (unsigned char *)output_items[0]; + + float_array_to_uchar(in, out, noutput_items); + + return noutput_items; + } + + } /* namespace blocks */ +}/* namespace gr */ diff --git a/gr-blocks/lib/float_to_uchar_impl.h b/gr-blocks/lib/float_to_uchar_impl.h new file mode 100644 index 000000000..effd66c5c --- /dev/null +++ b/gr-blocks/lib/float_to_uchar_impl.h @@ -0,0 +1,45 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_FLOAT_TO_UCHAR_IMPL_H +#define INCLUDED_FLOAT_TO_UCHAR_IMPL_H + +#include <blocks/float_to_uchar.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API float_to_uchar_impl : public float_to_uchar + { + public: + float_to_uchar_impl(); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + + +#endif /* INCLUDED_FLOAT_TO_UCHAR_IMPL_H */ diff --git a/gr-blocks/lib/int_to_float_impl.cc b/gr-blocks/lib/int_to_float_impl.cc new file mode 100644 index 000000000..0190d7ccb --- /dev/null +++ b/gr-blocks/lib/int_to_float_impl.cc @@ -0,0 +1,68 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "int_to_float_impl.h" +#include <gr_io_signature.h> +#include <volk/volk.h> + +namespace gr { + namespace blocks { + + int_to_float::sptr int_to_float::make(size_t vlen, float scale) + { + return gnuradio::get_initial_sptr(new int_to_float_impl(vlen, scale)); + } + + int_to_float_impl::int_to_float_impl(size_t vlen, float scale) + : gr_sync_block("int_to_float", + gr_make_io_signature (1, 1, sizeof(int32_t)*vlen), + gr_make_io_signature (1, 1, sizeof(float)*vlen)), + d_vlen(vlen), d_scale(scale) + { + const int alignment_multiple = + volk_get_alignment() / sizeof(float); + set_alignment(std::max(1, alignment_multiple)); + } + + int + int_to_float_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const int32_t *in = (const int32_t *) input_items[0]; + float *out = (float *) output_items[0]; + + if(is_unaligned()) { + volk_32i_s32f_convert_32f_u(out, in, d_scale, d_vlen*noutput_items); + } + else { + volk_32i_s32f_convert_32f_a(out, in, d_scale, d_vlen*noutput_items); + } + + return noutput_items; + } + } /* namespace blocks */ +}/* namespace gr */ diff --git a/gr-blocks/lib/int_to_float_impl.h b/gr-blocks/lib/int_to_float_impl.h new file mode 100644 index 000000000..7498a0bb1 --- /dev/null +++ b/gr-blocks/lib/int_to_float_impl.h @@ -0,0 +1,51 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_INT_TO_FLOAT_IMPL_H +#define INCLUDED_INT_TO_FLOAT_IMPL_H + +#include <blocks/int_to_float.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API int_to_float_impl : public int_to_float + { + size_t d_vlen; + float d_scale; + + public: + int_to_float_impl(size_t vlen, float scale); + + virtual float scale() const { return d_scale; } + virtual void set_scale(float scale) { d_scale = scale; } + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + + +#endif /* INCLUDED_INT_TO_FLOAT_IMPL_H */ diff --git a/gr-blocks/lib/integrate_XX_impl.cc.t b/gr-blocks/lib/integrate_XX_impl.cc.t new file mode 100644 index 000000000..4c82729e3 --- /dev/null +++ b/gr-blocks/lib/integrate_XX_impl.cc.t @@ -0,0 +1,68 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2009,2010,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <@NAME_IMPL@.h> +#include <gr_io_signature.h> + +namespace gr { + namespace blocks { + + @NAME@::sptr @NAME@::make(int decim) + { + return gnuradio::get_initial_sptr(new @NAME_IMPL@(decim)); + } + + @NAME_IMPL@::@NAME_IMPL@(int decim) + : gr_sync_decimator("@NAME@", + gr_make_io_signature(1, 1, sizeof (@I_TYPE@)), + gr_make_io_signature(1, 1, sizeof (@O_TYPE@)), + decim), + d_decim(decim), + d_count(0) + { + } + + int + @NAME_IMPL@::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const @I_TYPE@ *in = (const @I_TYPE@ *)input_items[0]; + @O_TYPE@ *out = (@O_TYPE@ *)output_items[0]; + + for (int i = 0; i < noutput_items; i++) { + out[i] = (@O_TYPE@)0; + for (int j = 0; j < d_decim; j++) + out[i] += in[i*d_decim+j]; + } + + return noutput_items; + } + + } /* namespace blocks */ +} /* namespace gr */ diff --git a/gr-blocks/lib/integrate_XX_impl.h.t b/gr-blocks/lib/integrate_XX_impl.h.t new file mode 100644 index 000000000..9fc333388 --- /dev/null +++ b/gr-blocks/lib/integrate_XX_impl.h.t @@ -0,0 +1,49 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2009,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifndef @GUARD_NAME_IMPL@ +#define @GUARD_NAME_IMPL@ + +#include <blocks/@NAME@.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API @NAME_IMPL@ : public @NAME@ + { + int d_decim; + int d_count; + + public: + @NAME_IMPL@(int decim); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* @GUARD_NAME_IMPL@ */ diff --git a/gr-blocks/lib/interleave_impl.cc b/gr-blocks/lib/interleave_impl.cc new file mode 100644 index 000000000..df37ed26d --- /dev/null +++ b/gr-blocks/lib/interleave_impl.cc @@ -0,0 +1,76 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "interleave_impl.h" +#include <gr_io_signature.h> + +namespace gr { + namespace blocks { + + interleave::sptr interleave::make(size_t itemsize) + { + return gnuradio::get_initial_sptr(new interleave_impl(itemsize)); + } + + interleave_impl::interleave_impl(size_t itemsize) + : gr_sync_interpolator("interleave", + gr_make_io_signature (1, gr_io_signature::IO_INFINITE, itemsize), + gr_make_io_signature (1, 1, itemsize), + 1), + d_itemsize(itemsize) + { + } + + bool + interleave_impl::check_topology(int ninputs, int noutputs) + { + set_interpolation(ninputs); + return true; + } + + int + interleave_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + size_t nchan = input_items.size(); + size_t itemsize = d_itemsize; + const char **in = (const char **)&input_items[0]; + char *out = (char *)output_items[0]; + + for (int i = 0; i < noutput_items; i += nchan) { + for (unsigned int n = 0; n < nchan; n++) { + memcpy (out, in[n], itemsize); + out += itemsize; + in[n] += itemsize; + } + } + + return noutput_items; + } + + } /* namespace blocks */ +} /* namespace gr */ diff --git a/gr-blocks/lib/interleave_impl.h b/gr-blocks/lib/interleave_impl.h new file mode 100644 index 000000000..a02517e3e --- /dev/null +++ b/gr-blocks/lib/interleave_impl.h @@ -0,0 +1,49 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_INTERLEAVE_IMPL_H +#define INCLUDED_INTERLEAVE_IMPL_H + +#include <blocks/interleave.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API interleave_impl : public interleave + { + size_t d_itemsize; + + public: + interleave_impl(size_t itemsize); + + bool check_topology(int ninputs, int noutputs); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + + +#endif /* INCLUDED_INTERLEAVE_IMPL_H */ diff --git a/gr-blocks/lib/interleaved_short_array_to_complex.cc b/gr-blocks/lib/interleaved_short_array_to_complex.cc new file mode 100644 index 000000000..eb6431b7a --- /dev/null +++ b/gr-blocks/lib/interleaved_short_array_to_complex.cc @@ -0,0 +1,39 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "interleaved_short_array_to_complex.h" +#include <assert.h> + +void +interleaved_short_array_to_complex (const short *in, + gr_complex *out, int nsamples) +{ + assert (nsamples % 2 == 0); + + for (int i = 0; i < nsamples/2; i++){ + out[i] = gr_complex (in[i*2 + 0], in[i*2 + 1]); + } +} diff --git a/gr-blocks/lib/interleaved_short_array_to_complex.h b/gr-blocks/lib/interleaved_short_array_to_complex.h new file mode 100644 index 000000000..3f20fdb98 --- /dev/null +++ b/gr-blocks/lib/interleaved_short_array_to_complex.h @@ -0,0 +1,36 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_INTERLEAVED_SHORT_ARRAY_TO_COMPLEX_H +#define INCLUDED_INTERLEAVED_SHORT_ARRAY_TO_COMPLEX_H + +#include <blocks/api.h> +#include <gr_complex.h> + +/* + * convert array of interleaved shorts to complex. + * the shorts contains real, imaginary, real, imaginary... + * nsamples is the number of shorts; it must be even. + */ +BLOCKS_API void interleaved_short_array_to_complex (const short *in, gr_complex *out, int nsamples); + +#endif /* INCLUDED_INTERLEAVED_SHORT_ARRAY_TO_COMPLEX_H */ diff --git a/gr-blocks/lib/interleaved_short_to_complex_impl.cc b/gr-blocks/lib/interleaved_short_to_complex_impl.cc new file mode 100644 index 000000000..1be6fdc9d --- /dev/null +++ b/gr-blocks/lib/interleaved_short_to_complex_impl.cc @@ -0,0 +1,61 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "interleaved_short_to_complex_impl.h" +#include "interleaved_short_array_to_complex.h" +#include <gr_io_signature.h> + +namespace gr { + namespace blocks { + + interleaved_short_to_complex::sptr interleaved_short_to_complex::make() + { + return gnuradio::get_initial_sptr(new interleaved_short_to_complex_impl()); + } + + interleaved_short_to_complex_impl::interleaved_short_to_complex_impl() + : gr_sync_decimator("interleaved_short_to_complex", + gr_make_io_signature (1, 1, sizeof(short)), + gr_make_io_signature (1, 1, sizeof(gr_complex)), + 2) + { + } + + int + interleaved_short_to_complex_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const short *in = (const short *) input_items[0]; + gr_complex *out = (gr_complex *) output_items[0]; + + interleaved_short_array_to_complex (in, out, 2 * noutput_items); + + return noutput_items; + } + + } /* namespace blocks */ +}/* namespace gr */ diff --git a/gr-blocks/lib/interleaved_short_to_complex_impl.h b/gr-blocks/lib/interleaved_short_to_complex_impl.h new file mode 100644 index 000000000..62a1db308 --- /dev/null +++ b/gr-blocks/lib/interleaved_short_to_complex_impl.h @@ -0,0 +1,45 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_INTERLEAVED_SHORT_TO_COMPLEX_IMPL_H +#define INCLUDED_INTERLEAVED_SHORT_TO_COMPLEX_IMPL_H + +#include <blocks/interleaved_short_to_complex.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API interleaved_short_to_complex_impl : public interleaved_short_to_complex + { + public: + interleaved_short_to_complex_impl(); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + + +#endif /* INCLUDED_INTERLEAVED_SHORT_TO_COMPLEX_IMPL_H */ diff --git a/gr-blocks/lib/keep_m_in_n_impl.cc b/gr-blocks/lib/keep_m_in_n_impl.cc new file mode 100644 index 000000000..312b09c25 --- /dev/null +++ b/gr-blocks/lib/keep_m_in_n_impl.cc @@ -0,0 +1,87 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "keep_m_in_n_impl.h" +#include <gr_io_signature.h> + +namespace gr { + namespace blocks { + + keep_m_in_n::sptr keep_m_in_n::make(size_t itemsize, int m, int n, int offset) + { + return gnuradio::get_initial_sptr(new keep_m_in_n_impl(itemsize, m, n, offset)); + } + + keep_m_in_n_impl::keep_m_in_n_impl(size_t itemsize, int m, int n, int offset) + : gr_block("keep_m_in_n", + gr_make_io_signature (1, 1, itemsize), + gr_make_io_signature (1, 1, itemsize)), + d_m(m), + d_n(n), + d_offset(offset), + d_itemsize(itemsize) + { + // sanity checking + assert(d_m > 0); + assert(d_n > 0); + assert(d_m <= d_n); + assert(d_offset <= (d_n-d_m)); + + set_output_multiple(m); + } + + void + keep_m_in_n_impl::forecast(int noutput_items, gr_vector_int &ninput_items_required) + { + ninput_items_required[0] = d_n*(noutput_items/d_m); + } + + int + keep_m_in_n_impl::general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + uint8_t* out = (uint8_t*)output_items[0]; + const uint8_t* in = (const uint8_t*)input_items[0]; + + // iterate over data blocks of size {n, input : m, output} + int blks = std::min(noutput_items/d_m, ninput_items[0]/d_n); + + for(int i=0; i<blks; i++) { + // set up copy pointers + const uint8_t* iptr = &in[(i*d_n + d_offset)*d_itemsize]; + uint8_t* optr = &out[i*d_m*d_itemsize]; + // perform copy + memcpy( optr, iptr, d_m*d_itemsize ); + } + + consume_each(d_n); + return d_m; + } + + } /* namespace blocks */ +} /* namespace gr */ diff --git a/gr-blocks/lib/keep_m_in_n_impl.h b/gr-blocks/lib/keep_m_in_n_impl.h new file mode 100644 index 000000000..0b8819489 --- /dev/null +++ b/gr-blocks/lib/keep_m_in_n_impl.h @@ -0,0 +1,58 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_KEEP_M_IN_N_IMPL_H +#define INCLUDED_KEEP_M_IN_N_IMPL_H + +#include <blocks/keep_m_in_n.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API keep_m_in_n_impl : public keep_m_in_n + { + int d_m; + int d_n; + int d_count; + int d_offset; + int d_itemsize; + + void forecast(int noutput_items, gr_vector_int &ninput_items_required); + + public: + keep_m_in_n_impl(size_t itemsize, int m, int n, int offset); + + int general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + + void set_m(int m) { d_m = m; } + void set_n(int n) { d_n = n; } + void set_offset(int offset) { d_offset = offset; } + }; + + } /* namespace blocks */ +} /* namespace gr */ + + +#endif /* INCLUDED_KEEP_M_IN_N_IMPL_H */ diff --git a/gr-blocks/lib/keep_one_in_n_impl.cc b/gr-blocks/lib/keep_one_in_n_impl.cc new file mode 100644 index 000000000..7ab6dc14d --- /dev/null +++ b/gr-blocks/lib/keep_one_in_n_impl.cc @@ -0,0 +1,109 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "keep_one_in_n_impl.h" +#include <gr_io_signature.h> + +namespace gr { + namespace blocks { + + keep_one_in_n::sptr keep_one_in_n::make(size_t itemsize, int n) + { + return gnuradio::get_initial_sptr(new keep_one_in_n_impl(itemsize, n)); + } + + keep_one_in_n_impl::keep_one_in_n_impl(size_t itemsize, int n) + : gr_block("keep_one_in_n", + gr_make_io_signature (1, 1, itemsize), + gr_make_io_signature (1, 1, itemsize)), + d_count(n) + { + // To avoid bad behavior with using set_relative_rate in this block with + // VERY large values of n, we will keep track of things ourselves. Using + // this to turn off automatic tag propagation, which will be handled + // locally in general_work(). + set_tag_propagation_policy(TPP_DONT); + + set_n(n); + } + + void + keep_one_in_n_impl::set_n(int n) + { + if (n < 1) + n = 1; + + d_n = n; + d_count = n; + + // keep our internal understanding of the relative rate of this block + // don't set the relative rate, though, and we will handle our own + // tag propagation. + d_decim_rate = 1.0/(float)d_n; + } + + int + keep_one_in_n_impl::general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const char *in = (const char *) input_items[0]; + char *out = (char *) output_items[0]; + + size_t item_size = input_signature ()->sizeof_stream_item (0); + int ni = 0; + int no = 0; + + while (ni < ninput_items[0] && no < noutput_items){ + d_count--; + if (d_count <= 0){ + memcpy (out, in, item_size); // copy 1 item + out += item_size; + no++; + d_count = d_n; + } + in += item_size; + ni++; + } + + // Because we have set TPP_DONT, we have to propagate the tags here manually. + // Adjustment of the tag sample value is done using the float d_decim_rate. + std::vector<gr_tag_t> tags; + std::vector<gr_tag_t>::iterator t; + get_tags_in_range(tags, 0, nitems_read(0), nitems_read(0)+ni); + for(t = tags.begin(); t != tags.end(); t++) { + gr_tag_t new_tag = *t; + new_tag.offset *= d_decim_rate; + add_item_tag(0, new_tag); + } + + consume_each (ni); + return no; + } + + } /* namespace blocks */ +} /* namespace gr */ diff --git a/gr-blocks/lib/keep_one_in_n_impl.h b/gr-blocks/lib/keep_one_in_n_impl.h new file mode 100644 index 000000000..1588fb1a6 --- /dev/null +++ b/gr-blocks/lib/keep_one_in_n_impl.h @@ -0,0 +1,53 @@ + +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_KEEP_ONE_IN_N_IMPL_H +#define INCLUDED_KEEP_ONE_IN_N_IMPL_H + +#include <blocks/keep_one_in_n.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API keep_one_in_n_impl : public keep_one_in_n + { + int d_n; + int d_count; + float d_decim_rate; + + public: + keep_one_in_n_impl(size_t itemsize,int n); + + int general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + + void set_n(int n); + }; + + } /* namespace blocks */ +} /* namespace gr */ + + +#endif /* INCLUDED_KEEP_ONE_IN_N_IMPL_H */ diff --git a/gr-blocks/lib/multiply_XX_impl.cc.t b/gr-blocks/lib/multiply_XX_impl.cc.t new file mode 100644 index 000000000..bda4eac6a --- /dev/null +++ b/gr-blocks/lib/multiply_XX_impl.cc.t @@ -0,0 +1,69 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2009,2010,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <@NAME_IMPL@.h> +#include <gr_io_signature.h> + +namespace gr { + namespace blocks { + + @NAME@::sptr @NAME@::make(size_t vlen) + { + return gnuradio::get_initial_sptr(new @NAME_IMPL@(vlen)); + } + + @NAME_IMPL@::@NAME_IMPL@(size_t vlen) + : gr_sync_block ("@NAME@", + gr_make_io_signature (1, -1, sizeof (@I_TYPE@)*vlen), + gr_make_io_signature (1, 1, sizeof (@O_TYPE@)*vlen)), + d_vlen(vlen) + { + } + + int + @NAME_IMPL@::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + @O_TYPE@ *optr = (@O_TYPE@ *) output_items[0]; + + int ninputs = input_items.size (); + + for (size_t i = 0; i < noutput_items*d_vlen; i++){ + @I_TYPE@ acc = ((@I_TYPE@ *) input_items[0])[i]; + for (int j = 1; j < ninputs; j++) + acc *= ((@I_TYPE@ *) input_items[j])[i]; + + *optr++ = (@O_TYPE@) acc; + } + + return noutput_items; + } + + } /* namespace blocks */ +} /* namespace gr */ diff --git a/gr-blocks/lib/multiply_XX_impl.h.t b/gr-blocks/lib/multiply_XX_impl.h.t new file mode 100644 index 000000000..78c62b5e1 --- /dev/null +++ b/gr-blocks/lib/multiply_XX_impl.h.t @@ -0,0 +1,47 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2009,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifndef @GUARD_NAME_IMPL@ +#define @GUARD_NAME_IMPL@ + +#include <blocks/@NAME@.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API @NAME_IMPL@ : public @NAME@ + { + size_t d_vlen; + + public: + @NAME_IMPL@(size_t vlen); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* @GUARD_NAME_IMPL@ */ diff --git a/gr-blocks/lib/multiply_cc_impl.cc b/gr-blocks/lib/multiply_cc_impl.cc new file mode 100644 index 000000000..e5160a9d5 --- /dev/null +++ b/gr-blocks/lib/multiply_cc_impl.cc @@ -0,0 +1,71 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <multiply_cc_impl.h> +#include <gr_io_signature.h> +#include <volk/volk.h> + +namespace gr { + namespace blocks { + + multiply_cc::sptr multiply_cc::make(size_t vlen) + { + return gnuradio::get_initial_sptr(new multiply_cc_impl(vlen)); + } + + multiply_cc_impl::multiply_cc_impl(size_t vlen) + : gr_sync_block("multiply_cc", + gr_make_io_signature (1, -1, sizeof(gr_complex)*vlen), + gr_make_io_signature (1, 1, sizeof(gr_complex)*vlen)), + d_vlen(vlen) + { + const int alignment_multiple = + volk_get_alignment() / sizeof(gr_complex); + set_alignment(std::max(1, alignment_multiple)); + } + + int + multiply_cc_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + gr_complex *out = (gr_complex *) output_items[0]; + int noi = d_vlen*noutput_items; + + memcpy(out, input_items[0], noi*sizeof(gr_complex)); + if(is_unaligned()) { + for(size_t i = 1; i < input_items.size(); i++) + volk_32fc_x2_multiply_32fc_u(out, out, (gr_complex*)input_items[i], noi); + } + else { + for(size_t i = 1; i < input_items.size(); i++) + volk_32fc_x2_multiply_32fc_a(out, out, (gr_complex*)input_items[i], noi); + } + return noutput_items; + } + + } /* namespace blocks */ +}/* namespace gr */ diff --git a/gr-blocks/lib/multiply_cc_impl.h b/gr-blocks/lib/multiply_cc_impl.h new file mode 100644 index 000000000..1595dc524 --- /dev/null +++ b/gr-blocks/lib/multiply_cc_impl.h @@ -0,0 +1,47 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_BLOCKS_MULTIPLY_CC_IMPL_H +#define INCLUDED_BLOCKS_MULTIPLY_CC_IMPL_H + +#include <blocks/multiply_cc.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API multiply_cc_impl : public multiply_cc + { + size_t d_vlen; + + public: + multiply_cc_impl(size_t vlen); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + + +#endif /* INCLUDED_BLOCKS_MULTIPLY_CC_IMPL_H */ diff --git a/gr-blocks/lib/multiply_conjugate_cc_impl.cc b/gr-blocks/lib/multiply_conjugate_cc_impl.cc new file mode 100644 index 000000000..7a4356c45 --- /dev/null +++ b/gr-blocks/lib/multiply_conjugate_cc_impl.cc @@ -0,0 +1,71 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <multiply_conjugate_cc_impl.h> +#include <gr_io_signature.h> +#include <volk/volk.h> + +namespace gr { + namespace blocks { + + multiply_conjugate_cc::sptr multiply_conjugate_cc::make(size_t vlen) + { + return gnuradio::get_initial_sptr(new multiply_conjugate_cc_impl(vlen)); + } + + multiply_conjugate_cc_impl::multiply_conjugate_cc_impl(size_t vlen) + : gr_sync_block("multiply_conjugate_cc", + gr_make_io_signature (2, 2, sizeof(gr_complex)*vlen), + gr_make_io_signature (1, 1, sizeof(gr_complex)*vlen)), + d_vlen(vlen) + { + const int alignment_multiple = + volk_get_alignment() / sizeof(gr_complex); + set_alignment(std::max(1, alignment_multiple)); + } + + int + multiply_conjugate_cc_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + gr_complex *in0 = (gr_complex *) input_items[0]; + gr_complex *in1 = (gr_complex *) input_items[1]; + gr_complex *out = (gr_complex *) output_items[0]; + int noi = d_vlen*noutput_items; + + if(is_unaligned()) { + volk_32fc_x2_multiply_conjugate_32fc_u(out, in0, in1, noi); + } + else { + volk_32fc_x2_multiply_conjugate_32fc_a(out, in0, in1, noi); + } + + return noutput_items; + } + + } /* namespace blocks */ +}/* namespace gr */ diff --git a/gr-blocks/lib/multiply_conjugate_cc_impl.h b/gr-blocks/lib/multiply_conjugate_cc_impl.h new file mode 100644 index 000000000..66e7ec55b --- /dev/null +++ b/gr-blocks/lib/multiply_conjugate_cc_impl.h @@ -0,0 +1,47 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_BLOCKS_MULTIPLY_CONJUGATE_CC_IMPL_H +#define INCLUDED_BLOCKS_MULTIPLY_CONJUGATE_CC_IMPL_H + +#include <blocks/multiply_conjugate_cc.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API multiply_conjugate_cc_impl : public multiply_conjugate_cc + { + size_t d_vlen; + + public: + multiply_conjugate_cc_impl(size_t vlen); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + + +#endif /* INCLUDED_BLOCKS_MULTIPLY_CONJUGATE_CC_IMPL_H */ diff --git a/gr-blocks/lib/multiply_const_XX_impl.cc.t b/gr-blocks/lib/multiply_const_XX_impl.cc.t new file mode 100644 index 000000000..8ca79f6f3 --- /dev/null +++ b/gr-blocks/lib/multiply_const_XX_impl.cc.t @@ -0,0 +1,77 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2009,2010,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <@NAME_IMPL@.h> +#include <gr_io_signature.h> + +namespace gr { + namespace blocks { + + @NAME@::sptr @NAME@::make(@O_TYPE@ k) + { + return gnuradio::get_initial_sptr(new @NAME_IMPL@(k)); + } + + @NAME_IMPL@::@NAME_IMPL@(@O_TYPE@ k) + : gr_sync_block ("@NAME@", + gr_make_io_signature (1, 1, sizeof (@I_TYPE@)), + gr_make_io_signature (1, 1, sizeof (@O_TYPE@))), + d_k(k) + { + } + + int + @NAME_IMPL@::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + @I_TYPE@ *iptr = (@I_TYPE@ *) input_items[0]; + @O_TYPE@ *optr = (@O_TYPE@ *) output_items[0]; + + int size = noutput_items; + + while (size >= 8){ + *optr++ = *iptr++ * d_k; + *optr++ = *iptr++ * d_k; + *optr++ = *iptr++ * d_k; + *optr++ = *iptr++ * d_k; + *optr++ = *iptr++ * d_k; + *optr++ = *iptr++ * d_k; + *optr++ = *iptr++ * d_k; + *optr++ = *iptr++ * d_k; + size -= 8; + } + + while (size-- > 0) + *optr++ = *iptr++ * d_k; + + return noutput_items; + } + + } /* namespace blocks */ +} /* namespace gr */ diff --git a/gr-blocks/lib/multiply_const_XX_impl.h.t b/gr-blocks/lib/multiply_const_XX_impl.h.t new file mode 100644 index 000000000..cae5ca813 --- /dev/null +++ b/gr-blocks/lib/multiply_const_XX_impl.h.t @@ -0,0 +1,51 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2009,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifndef @GUARD_NAME_IMPL@ +#define @GUARD_NAME_IMPL@ + +#include <blocks/@NAME@.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API @NAME_IMPL@ : public @NAME@ + { + @O_TYPE@ d_k; + + public: + @NAME_IMPL@(@O_TYPE@ k); + + @O_TYPE@ k() const { return d_k; } + void set_k(@O_TYPE@ k) { d_k = k; } + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* @GUARD_NAME_IMPL@ */ diff --git a/gr-blocks/lib/multiply_const_cc_impl.cc b/gr-blocks/lib/multiply_const_cc_impl.cc new file mode 100644 index 000000000..7618150da --- /dev/null +++ b/gr-blocks/lib/multiply_const_cc_impl.cc @@ -0,0 +1,72 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2009,2010,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <multiply_const_cc_impl.h> +#include <gr_io_signature.h> +#include <volk/volk.h> + +namespace gr { + namespace blocks { + + multiply_const_cc::sptr multiply_const_cc::make(gr_complex k, size_t vlen) + { + return gnuradio::get_initial_sptr(new multiply_const_cc_impl(k, vlen)); + } + + multiply_const_cc_impl::multiply_const_cc_impl(gr_complex k, size_t vlen) + : gr_sync_block ("multiply_const_cc", + gr_make_io_signature (1, 1, sizeof (gr_complex)*vlen), + gr_make_io_signature (1, 1, sizeof (gr_complex)*vlen)), + d_k(k), d_vlen(vlen) + { + const int alignment_multiple = + volk_get_alignment() / sizeof(gr_complex); + set_alignment(std::max(1,alignment_multiple)); + } + + int + multiply_const_cc_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const gr_complex *in = (const gr_complex *) input_items[0]; + gr_complex *out = (gr_complex *) output_items[0]; + int noi = d_vlen*noutput_items; + + if(is_unaligned()) { + volk_32fc_s32fc_multiply_32fc_u(out, in, d_k, noi); + } + else { + volk_32fc_s32fc_multiply_32fc_a(out, in, d_k, noi); + } + + return noutput_items; + } + + } /* namespace blocks */ +} /* namespace gr */ diff --git a/gr-blocks/lib/multiply_const_cc_impl.h b/gr-blocks/lib/multiply_const_cc_impl.h new file mode 100644 index 000000000..81c8cc6da --- /dev/null +++ b/gr-blocks/lib/multiply_const_cc_impl.h @@ -0,0 +1,52 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2009,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifndef INCLUDED_MULTIPLY_CONST_CC_IMPL_H +#define INCLUDED_MULTIPLY_CONST_CC_IMPL_H + +#include <blocks/multiply_const_cc.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API multiply_const_cc_impl : public multiply_const_cc + { + gr_complex d_k; + size_t d_vlen; + + public: + multiply_const_cc_impl(gr_complex k, size_t vlen); + + gr_complex k() const { return d_k; } + void set_k(gr_complex k) { d_k = k; } + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_MULTIPLY_CONST_CC_IMPL_H */ diff --git a/gr-blocks/lib/multiply_const_ff_impl.cc b/gr-blocks/lib/multiply_const_ff_impl.cc new file mode 100644 index 000000000..e9cd34797 --- /dev/null +++ b/gr-blocks/lib/multiply_const_ff_impl.cc @@ -0,0 +1,72 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2009,2010,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <multiply_const_ff_impl.h> +#include <gr_io_signature.h> +#include <volk/volk.h> + +namespace gr { + namespace blocks { + + multiply_const_ff::sptr multiply_const_ff::make(float k, size_t vlen) + { + return gnuradio::get_initial_sptr(new multiply_const_ff_impl(k, vlen)); + } + + multiply_const_ff_impl::multiply_const_ff_impl(float k, size_t vlen) + : gr_sync_block ("multiply_const_ff", + gr_make_io_signature (1, 1, sizeof (float)*vlen), + gr_make_io_signature (1, 1, sizeof (float)*vlen)), + d_k(k), d_vlen(vlen) + { + const int alignment_multiple = + volk_get_alignment() / sizeof(float); + set_alignment(std::max(1,alignment_multiple)); + } + + int + multiply_const_ff_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const float *in = (const float *) input_items[0]; + float *out = (float *) output_items[0]; + int noi = d_vlen*noutput_items; + + if(is_unaligned()) { + volk_32f_s32f_multiply_32f_u(out, in, d_k, noi); + } + else { + volk_32f_s32f_multiply_32f_a(out, in, d_k, noi); + } + + return noutput_items; + } + + } /* namespace blocks */ +} /* namespace gr */ diff --git a/gr-blocks/lib/multiply_const_ff_impl.h b/gr-blocks/lib/multiply_const_ff_impl.h new file mode 100644 index 000000000..e63a3279a --- /dev/null +++ b/gr-blocks/lib/multiply_const_ff_impl.h @@ -0,0 +1,52 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2009,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifndef INCLUDED_MULTIPLY_CONST_FF_IMPL_H +#define INCLUDED_MULTIPLY_CONST_FF_IMPL_H + +#include <blocks/multiply_const_ff.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API multiply_const_ff_impl : public multiply_const_ff + { + float d_k; + size_t d_vlen; + + public: + multiply_const_ff_impl(float k, size_t vlen); + + float k() const { return d_k; } + void set_k(float k) { d_k = k; } + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_MULTIPLY_CONST_FF_IMPL_H */ diff --git a/gr-blocks/lib/multiply_const_vXX_impl.cc.t b/gr-blocks/lib/multiply_const_vXX_impl.cc.t new file mode 100644 index 000000000..dd20f2893 --- /dev/null +++ b/gr-blocks/lib/multiply_const_vXX_impl.cc.t @@ -0,0 +1,66 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2009,2010,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <@NAME_IMPL@.h> +#include <gr_io_signature.h> + +namespace gr { + namespace blocks { + + @NAME@::sptr @NAME@::make(std::vector<@O_TYPE@> k) + { + return gnuradio::get_initial_sptr(new @NAME_IMPL@(k)); + } + + @NAME_IMPL@::@NAME_IMPL@(std::vector<@O_TYPE@> k) + : gr_sync_block ("@NAME@", + gr_make_io_signature (1, 1, sizeof (@I_TYPE@)*k.size()), + gr_make_io_signature (1, 1, sizeof (@O_TYPE@)*k.size())), + d_k(k) + { + } + + int + @NAME_IMPL@::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + @I_TYPE@ *iptr = (@I_TYPE@ *)input_items[0]; + @O_TYPE@ *optr = (@O_TYPE@ *)output_items[0]; + + int nitems_per_block = output_signature()->sizeof_stream_item(0)/sizeof(@I_TYPE@); + + for (int i = 0; i < noutput_items; i++) + for (int j = 0; j < nitems_per_block; j++) + *optr++ = *iptr++ * d_k[j]; + + return noutput_items; + } + + } /* namespace blocks */ +} /* namespace gr */ diff --git a/gr-blocks/lib/multiply_const_vXX_impl.h.t b/gr-blocks/lib/multiply_const_vXX_impl.h.t new file mode 100644 index 000000000..a7a619725 --- /dev/null +++ b/gr-blocks/lib/multiply_const_vXX_impl.h.t @@ -0,0 +1,51 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2006,2010,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifndef @GUARD_NAME_IMPL@ +#define @GUARD_NAME_IMPL@ + +#include <blocks/@NAME@.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API @NAME_IMPL@ : public @NAME@ + { + std::vector<@O_TYPE@> d_k; + + public: + @NAME_IMPL@(std::vector<@O_TYPE@> k); + + std::vector<@O_TYPE@> k() const { return d_k; } + void set_k(std::vector<@O_TYPE@> k) { d_k = k; } + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* @GUARD_NAME_IMPL@ */ diff --git a/gr-blocks/lib/multiply_ff_impl.cc b/gr-blocks/lib/multiply_ff_impl.cc new file mode 100644 index 000000000..6e8f27711 --- /dev/null +++ b/gr-blocks/lib/multiply_ff_impl.cc @@ -0,0 +1,71 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <multiply_ff_impl.h> +#include <gr_io_signature.h> +#include <volk/volk.h> + +namespace gr { + namespace blocks { + + multiply_ff::sptr multiply_ff::make(size_t vlen) + { + return gnuradio::get_initial_sptr(new multiply_ff_impl(vlen)); + } + + multiply_ff_impl::multiply_ff_impl(size_t vlen) + : gr_sync_block("multiply_ff", + gr_make_io_signature (1, -1, sizeof(float)*vlen), + gr_make_io_signature (1, 1, sizeof(float)*vlen)), + d_vlen(vlen) + { + const int alignment_multiple = + volk_get_alignment() / sizeof(float); + set_alignment(std::max(1, alignment_multiple)); + } + + int + multiply_ff_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + float *out = (float *) output_items[0]; + int noi = d_vlen*noutput_items; + + memcpy(out, input_items[0], noi*sizeof(float)); + if(is_unaligned()) { + for(size_t i = 1; i < input_items.size(); i++) + volk_32f_x2_multiply_32f_u(out, out, (float*)input_items[i], noi); + } + else { + for(size_t i = 1; i < input_items.size(); i++) + volk_32f_x2_multiply_32f_a(out, out, (float*)input_items[i], noi); + } + return noutput_items; + } + + } /* namespace blocks */ +}/* namespace gr */ diff --git a/gr-blocks/lib/multiply_ff_impl.h b/gr-blocks/lib/multiply_ff_impl.h new file mode 100644 index 000000000..2c5325a98 --- /dev/null +++ b/gr-blocks/lib/multiply_ff_impl.h @@ -0,0 +1,47 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_BLOCKS_MULTIPLY_FF_IMPL_H +#define INCLUDED_BLOCKS_MULTIPLY_FF_IMPL_H + +#include <blocks/multiply_ff.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API multiply_ff_impl : public multiply_ff + { + size_t d_vlen; + + public: + multiply_ff_impl(size_t vlen); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + + +#endif /* INCLUDED_BLOCKS_MULTIPLY_FF_IMPL_H */ diff --git a/gr-blocks/lib/nlog10_ff_impl.cc b/gr-blocks/lib/nlog10_ff_impl.cc new file mode 100644 index 000000000..f662b8fd5 --- /dev/null +++ b/gr-blocks/lib/nlog10_ff_impl.cc @@ -0,0 +1,64 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "nlog10_ff_impl.h" +#include <gr_io_signature.h> + +namespace gr { + namespace blocks { + + nlog10_ff::sptr nlog10_ff::make(float n, size_t vlen, float k) + { + return gnuradio::get_initial_sptr(new nlog10_ff_impl(n, vlen, k)); + } + + nlog10_ff_impl::nlog10_ff_impl(float n, size_t vlen, float k) + : gr_sync_block("nlog10_ff", + gr_make_io_signature (1, 1, sizeof(float)*vlen), + gr_make_io_signature (1, 1, sizeof(float)*vlen)), + d_n(n), d_vlen(vlen), d_k(k) + { + } + + int + nlog10_ff_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const float *in = (const float *) input_items[0]; + float *out = (float *) output_items[0]; + int noi = noutput_items * d_vlen; + float n = d_n; + float k = d_k; + + for (int i = 0; i < noi; i++) + out[i] = n * log10(std::max(in[i], (float) 1e-18)) + k; + + return noutput_items; + } + + } /* namespace blocks */ +}/* namespace gr */ diff --git a/gr-blocks/lib/nlog10_ff_impl.h b/gr-blocks/lib/nlog10_ff_impl.h new file mode 100644 index 000000000..3789bc317 --- /dev/null +++ b/gr-blocks/lib/nlog10_ff_impl.h @@ -0,0 +1,49 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_NLOG10_FF_IMPL_H +#define INCLUDED_NLOG10_FF_IMPL_H + +#include <blocks/nlog10_ff.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API nlog10_ff_impl : public nlog10_ff + { + float d_n; + size_t d_vlen; + float d_k; + + public: + nlog10_ff_impl(float n, size_t vlen, float k); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + + +#endif /* INCLUDED_NLOG10_FF_IMPL_H */ diff --git a/gr-blocks/lib/not_XX_impl.cc.t b/gr-blocks/lib/not_XX_impl.cc.t new file mode 100644 index 000000000..b491a4ccc --- /dev/null +++ b/gr-blocks/lib/not_XX_impl.cc.t @@ -0,0 +1,65 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <@NAME_IMPL@.h> +#include <gr_io_signature.h> + +namespace gr { + namespace blocks { + + @NAME@::sptr @NAME@::make(size_t vlen) + { + return gnuradio::get_initial_sptr(new @NAME_IMPL@(vlen)); + } + + @NAME_IMPL@::@NAME_IMPL@(size_t vlen) + : gr_sync_block ("@NAME@", + gr_make_io_signature (1, 1, sizeof (@I_TYPE@)*vlen), + gr_make_io_signature (1, 1, sizeof (@O_TYPE@)*vlen)), + d_vlen(vlen) + { + } + + int + @NAME_IMPL@::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + @O_TYPE@ *optr = (@O_TYPE@ *) output_items[0]; + const @I_TYPE@ *inptr = (const @I_TYPE@ *) input_items[0]; + + int noi = noutput_items*d_vlen; + + for (int i = 0; i < noi; i++) + *optr++ = ~(inptr[i]); + + return noutput_items; + } + + } /* namespace blocks */ +} /* namespace gr */ diff --git a/gr-blocks/lib/not_XX_impl.h.t b/gr-blocks/lib/not_XX_impl.h.t new file mode 100644 index 000000000..25f0da0c8 --- /dev/null +++ b/gr-blocks/lib/not_XX_impl.h.t @@ -0,0 +1,48 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifndef @GUARD_NAME_IMPL@ +#define @GUARD_NAME_IMPL@ + +#include <blocks/@NAME@.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API @NAME_IMPL@ : public @NAME@ + { + size_t d_vlen; + + public: + @NAME_IMPL@(size_t vlen); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* @GUARD_NAME_IMPL@ */ diff --git a/gr-blocks/lib/or_XX_impl.cc.t b/gr-blocks/lib/or_XX_impl.cc.t new file mode 100644 index 000000000..15f6fa0b8 --- /dev/null +++ b/gr-blocks/lib/or_XX_impl.cc.t @@ -0,0 +1,69 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <@NAME_IMPL@.h> +#include <gr_io_signature.h> + +namespace gr { + namespace blocks { + + @NAME@::sptr @NAME@::make(size_t vlen) + { + return gnuradio::get_initial_sptr(new @NAME_IMPL@(vlen)); + } + + @NAME_IMPL@::@NAME_IMPL@(size_t vlen) + : gr_sync_block ("@NAME@", + gr_make_io_signature (1, -1, sizeof (@I_TYPE@)*vlen), + gr_make_io_signature (1, 1, sizeof (@O_TYPE@)*vlen)), + d_vlen(vlen) + { + } + + int + @NAME_IMPL@::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + @O_TYPE@ *optr = (@O_TYPE@ *) output_items[0]; + + int ninputs = input_items.size (); + + for (size_t i = 0; i < noutput_items*d_vlen; i++){ + @I_TYPE@ acc = ((@I_TYPE@ *) input_items[0])[i]; + for (int j = 1; j < ninputs; j++) + acc |= ((@I_TYPE@ *) input_items[j])[i]; + + *optr++ = (@O_TYPE@) acc; + } + + return noutput_items; + } + + } /* namespace blocks */ +} /* namespace gr */ diff --git a/gr-blocks/lib/or_XX_impl.h.t b/gr-blocks/lib/or_XX_impl.h.t new file mode 100644 index 000000000..25f0da0c8 --- /dev/null +++ b/gr-blocks/lib/or_XX_impl.h.t @@ -0,0 +1,48 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifndef @GUARD_NAME_IMPL@ +#define @GUARD_NAME_IMPL@ + +#include <blocks/@NAME@.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API @NAME_IMPL@ : public @NAME@ + { + size_t d_vlen; + + public: + @NAME_IMPL@(size_t vlen); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* @GUARD_NAME_IMPL@ */ diff --git a/gr-blocks/lib/patterned_interleaver_impl.cc b/gr-blocks/lib/patterned_interleaver_impl.cc new file mode 100644 index 000000000..437c733a1 --- /dev/null +++ b/gr-blocks/lib/patterned_interleaver_impl.cc @@ -0,0 +1,87 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "patterned_interleaver_impl.h" +#include <gr_io_signature.h> + +namespace gr { + namespace blocks { + + patterned_interleaver::sptr patterned_interleaver::make(size_t itemsize, std::vector<int> pattern) + { + return gnuradio::get_initial_sptr(new patterned_interleaver_impl(itemsize, pattern)); + } + + patterned_interleaver_impl::patterned_interleaver_impl(size_t itemsize, std::vector<int> pattern) + : gr_block ("patterned_interleaver", + gr_make_io_signature (pattern_max(pattern)+1, pattern_max(pattern)+1, itemsize), + gr_make_io_signature (1, 1, itemsize)), + d_pattern(pattern), d_counts( pattern_max(pattern)+1, 0), d_itemsize(itemsize) + { + BOOST_FOREACH( int i, d_pattern) + { d_counts[i]++; } + set_output_multiple(d_pattern.size()); + } + + int + patterned_interleaver_impl::general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + size_t nblks = noutput_items/d_pattern.size(); + + std::vector<const char*> ii; + for(size_t i=0; i<input_items.size(); i++){ + ii.push_back((const char*)input_items[i]); + } + + char *oo = (char *) output_items[0]; + + for(size_t i=0; i<nblks; i++){ + for(size_t j=0; j<d_pattern.size(); j++){ + memcpy(oo, ii[d_pattern[j]], d_itemsize); + oo += d_itemsize; + ii[d_pattern[j]] += d_itemsize; + } + } + + for(size_t i=0; i<d_counts.size(); i++){ + consume(i, d_counts[i]*nblks ); + } + return nblks*d_pattern.size(); + } + + void patterned_interleaver_impl::forecast (int noutput_items, + gr_vector_int &ninput_items_required){ + int nblks = noutput_items / d_pattern.size(); + for(size_t i=0; i<ninput_items_required.size(); i++){ + ninput_items_required[i] = d_counts[i] * nblks; + } + } + + } /* namespace blocks */ +} /* namespace gr */ diff --git a/gr-blocks/lib/patterned_interleaver_impl.h b/gr-blocks/lib/patterned_interleaver_impl.h new file mode 100644 index 000000000..4266c9636 --- /dev/null +++ b/gr-blocks/lib/patterned_interleaver_impl.h @@ -0,0 +1,61 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_PATTERNED_INTERLEAVER_IMPL_H +#define INCLUDED_PATTERNED_INTERLEAVER_IMPL_H + +#include <blocks/patterned_interleaver.h> +#include <boost/foreach.hpp> + +namespace gr { + namespace blocks { + + class BLOCKS_API patterned_interleaver_impl : public patterned_interleaver + { + public: + patterned_interleaver_impl(size_t itemsize, std::vector<int> pattern); + + int general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + + int pattern_max(std::vector<int> pattern){ + int mval(0); + BOOST_FOREACH( int i, pattern) + { mval = std::max(mval, i); } + return mval; + } + + void forecast (int noutput_items, + gr_vector_int &ninput_items_required); + + std::vector<int> d_pattern; + std::vector<int> d_counts; + size_t d_itemsize; + + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif diff --git a/gr-blocks/lib/repeat_impl.cc b/gr-blocks/lib/repeat_impl.cc new file mode 100644 index 000000000..939a33b87 --- /dev/null +++ b/gr-blocks/lib/repeat_impl.cc @@ -0,0 +1,69 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "repeat_impl.h" +#include <gr_io_signature.h> + +namespace gr { + namespace blocks { + + repeat::sptr repeat::make(size_t itemsize, int interp) + { + return gnuradio::get_initial_sptr(new repeat_impl(itemsize, interp)); + } + + repeat_impl::repeat_impl(size_t itemsize, int interp) + : gr_sync_interpolator("repeat", + gr_make_io_signature (1, 1, itemsize), + gr_make_io_signature (1, 1, itemsize), + interp), + d_itemsize(itemsize), + d_interp(interp) + { + } + + int + repeat_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const char *in = (const char *) input_items[0]; + char *out = (char *)output_items[0]; + + for (int i = 0; i < noutput_items/d_interp; i++) { + for (int j = 0; j < d_interp; j++) { + memcpy(out, in, d_itemsize); + out += d_itemsize; + } + + in += d_itemsize; + } + + return noutput_items; + } + + } /* namespace blocks */ +} /* namespace gr */ diff --git a/gr-blocks/lib/repeat_impl.h b/gr-blocks/lib/repeat_impl.h new file mode 100644 index 000000000..6451d0d98 --- /dev/null +++ b/gr-blocks/lib/repeat_impl.h @@ -0,0 +1,47 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_REPEAT_IMPL_H +#define INCLUDED_REPEAT_IMPL_H + +#include <blocks/repeat.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API repeat_impl : public repeat + { + size_t d_itemsize; + int d_interp; + + public: + repeat_impl(size_t itemsize, int d_interp); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_REPEAT_IMPL_H */ diff --git a/gr-blocks/lib/short_to_char_impl.cc b/gr-blocks/lib/short_to_char_impl.cc new file mode 100644 index 000000000..54875a2b3 --- /dev/null +++ b/gr-blocks/lib/short_to_char_impl.cc @@ -0,0 +1,69 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "short_to_char_impl.h" +#include <gr_io_signature.h> +#include <volk/volk.h> + +namespace gr { + namespace blocks { + + short_to_char::sptr short_to_char::make(size_t vlen) + { + return gnuradio::get_initial_sptr(new short_to_char_impl(vlen)); + } + + short_to_char_impl::short_to_char_impl(size_t vlen) + : gr_sync_block("short_to_char", + gr_make_io_signature (1, 1, sizeof(short)*vlen), + gr_make_io_signature (1, 1, sizeof(char)*vlen)), + d_vlen(vlen) + { + const int alignment_multiple = + volk_get_alignment() / sizeof(char); + set_alignment(std::max(1, alignment_multiple)); + } + + int + short_to_char_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const int16_t *in = (const int16_t *) input_items[0]; + int8_t *out = (int8_t *) output_items[0]; + + if(is_unaligned()) { + volk_16i_convert_8i_u(out, in, d_vlen*noutput_items); + } + else { + volk_16i_convert_8i_a(out, in, d_vlen*noutput_items); + } + + return noutput_items; + } + + } /* namespace blocks */ +}/* namespace gr */ diff --git a/gr-blocks/lib/short_to_char_impl.h b/gr-blocks/lib/short_to_char_impl.h new file mode 100644 index 000000000..37474094d --- /dev/null +++ b/gr-blocks/lib/short_to_char_impl.h @@ -0,0 +1,47 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_SHORT_TO_CHAR_IMPL_H +#define INCLUDED_SHORT_TO_CHAR_IMPL_H + +#include <blocks/short_to_char.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API short_to_char_impl : public short_to_char + { + size_t d_vlen; + + public: + short_to_char_impl(size_t vlen); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + + +#endif /* INCLUDED_SHORT_TO_CHAR_IMPL_H */ diff --git a/gr-blocks/lib/short_to_float_impl.cc b/gr-blocks/lib/short_to_float_impl.cc new file mode 100644 index 000000000..618601816 --- /dev/null +++ b/gr-blocks/lib/short_to_float_impl.cc @@ -0,0 +1,68 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "short_to_float_impl.h" +#include <gr_io_signature.h> +#include <volk/volk.h> + +namespace gr { + namespace blocks { + + short_to_float::sptr short_to_float::make(size_t vlen, float scale) + { + return gnuradio::get_initial_sptr(new short_to_float_impl(vlen, scale)); + } + + short_to_float_impl::short_to_float_impl(size_t vlen, float scale) + : gr_sync_block("short_to_float", + gr_make_io_signature (1, 1, sizeof(short)*vlen), + gr_make_io_signature (1, 1, sizeof(float)*vlen)), + d_vlen(vlen), d_scale(scale) + { + const int alignment_multiple = + volk_get_alignment() / sizeof(float); + set_alignment(std::max(1, alignment_multiple)); + } + + int + short_to_float_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const short *in = (const short *) input_items[0]; + float *out = (float *) output_items[0]; + + if(is_unaligned()) { + volk_16i_s32f_convert_32f_u(out, in, d_scale, d_vlen*noutput_items); + } + else { + volk_16i_s32f_convert_32f_a(out, in, d_scale, d_vlen*noutput_items); + } + return noutput_items; + } + + } /* namespace blocks */ +}/* namespace gr */ diff --git a/gr-blocks/lib/short_to_float_impl.h b/gr-blocks/lib/short_to_float_impl.h new file mode 100644 index 000000000..c36b42a8c --- /dev/null +++ b/gr-blocks/lib/short_to_float_impl.h @@ -0,0 +1,51 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_SHORT_TO_FLOAT_IMPL_H +#define INCLUDED_SHORT_TO_FLOAT_IMPL_H + +#include <blocks/short_to_float.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API short_to_float_impl : public short_to_float + { + size_t d_vlen; + float d_scale; + + public: + short_to_float_impl(size_t vlen, float scale); + + virtual float scale() const { return d_scale; } + virtual void set_scale(float scale) { d_scale = scale; } + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + + +#endif /* INCLUDED_SHORT_TO_FLOAT_IMPL_H */ diff --git a/gr-blocks/lib/stream_mux_impl.cc b/gr-blocks/lib/stream_mux_impl.cc new file mode 100644 index 000000000..214734c4b --- /dev/null +++ b/gr-blocks/lib/stream_mux_impl.cc @@ -0,0 +1,126 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "stream_mux_impl.h" +#include <gr_io_signature.h> +#include <string.h> +#include <cstdio> + +#define VERBOSE 0 + +namespace gr { + namespace blocks { + + stream_mux::sptr stream_mux::make(size_t itemsize, const std::vector<int> &lengths) + { + return gnuradio::get_initial_sptr(new stream_mux_impl(itemsize, lengths)); + } + + stream_mux_impl::stream_mux_impl(size_t itemsize, const std::vector<int> &lengths) + : gr_block("stream_mux", + gr_make_io_signature (1, -1, itemsize), + gr_make_io_signature (1, 1, itemsize)), + d_itemsize(itemsize), + d_stream(0), + d_residual(0), + d_lengths(lengths) + { + if(d_lengths[d_stream] == 0) { + increment_stream(); + } + d_residual = d_lengths[d_stream]; + } + + void + stream_mux_impl::forecast(int noutput_items, gr_vector_int &ninput_items_required) + { + unsigned ninputs = ninput_items_required.size (); + for (unsigned i = 0; i < ninputs; i++) + ninput_items_required[i] = (d_lengths[i] == 0 ? 0 : 1); + } + + void + stream_mux_impl::increment_stream() + { + do { + d_stream = (d_stream+1) % d_lengths.size(); + } while(d_lengths[d_stream] == 0); + + d_residual = d_lengths[d_stream]; + } + + + int + stream_mux_impl::general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + char *out = (char *) output_items[0]; + const char *in; + int out_index = 0; + std::vector<int> input_index(d_lengths.size(), 0); + + if(VERBOSE) { + printf("mux: nouput_items: %d d_stream: %d\n", noutput_items, d_stream); + for(size_t i = 0; i < d_lengths.size(); i++) + printf("\tninput_items[%zu]: %d\n", i, ninput_items[i]); + } + + while (1) { + int r = std::min(noutput_items - out_index, + std::min(d_residual, + ninput_items[d_stream] - input_index[d_stream])); + if(VERBOSE) { + printf("mux: r=%d\n", r); + printf("\tnoutput_items - out_index: %d\n", + noutput_items - out_index); + printf("\td_residual: %d\n", + d_residual); + printf("\tninput_items[d_stream] - input_index[d_stream]: %d\n", + ninput_items[d_stream] - input_index[d_stream]); + } + + if(r <= 0) { + return out_index; + } + + in = (const char *) input_items[d_stream] + input_index[d_stream]*d_itemsize; + + memcpy(&out[out_index*d_itemsize], in, r*d_itemsize); + out_index += r; + input_index[d_stream] += r; + d_residual -= r; + + consume(d_stream, r); + + if(d_residual == 0) { + increment_stream(); + } + } + } + } /* namespace blocks */ +} /* namespace gr */ diff --git a/gr-blocks/lib/stream_mux_impl.h b/gr-blocks/lib/stream_mux_impl.h new file mode 100644 index 000000000..7b2dac95c --- /dev/null +++ b/gr-blocks/lib/stream_mux_impl.h @@ -0,0 +1,55 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_STREAM_MUX_IMPL_H +#define INCLUDED_STREAM_MUX_IMPL_H + +#include <blocks/stream_mux.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API stream_mux_impl : public stream_mux + { + private: + size_t d_itemsize; + unsigned int d_stream; // index of currently selected stream + int d_residual; // number if items left to put into current stream + gr_vector_int d_lengths; // number if items to pack per stream + + void increment_stream(); + + void forecast(int noutput_items, gr_vector_int &ninput_items_required); + + public: + stream_mux_impl(size_t itemsize, const std::vector<int> &lengths); + + int general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_STREAM_MUX_IMPL_H */ diff --git a/gr-blocks/lib/stream_to_streams_impl.cc b/gr-blocks/lib/stream_to_streams_impl.cc new file mode 100644 index 000000000..9e9052e7d --- /dev/null +++ b/gr-blocks/lib/stream_to_streams_impl.cc @@ -0,0 +1,70 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "stream_to_streams_impl.h" +#include <gr_io_signature.h> +#include <string.h> + +namespace gr { + namespace blocks { + + stream_to_streams::sptr stream_to_streams::make(size_t itemsize, size_t nstreams) + { + return gnuradio::get_initial_sptr(new stream_to_streams_impl(itemsize, nstreams)); + } + + stream_to_streams_impl::stream_to_streams_impl(size_t itemsize, size_t nstreams) + : gr_sync_decimator("stream_to_streams", + gr_make_io_signature (1, 1, itemsize), + gr_make_io_signature (nstreams, nstreams, itemsize), + nstreams) + { + } + + int + stream_to_streams_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + size_t item_size = output_signature()->sizeof_stream_item(0); + + const char *in = (const char *)input_items[0]; + char **outv = (char **)&output_items[0]; + int nstreams = output_items.size(); + + for (int i = 0; i < noutput_items; i++) { + for (int j = 0; j < nstreams; j++) { + memcpy(outv[j], in, item_size); + outv[j] += item_size; + in += item_size; + } + } + + return noutput_items; + } + + } /* namespace blocks */ +} /* namespace gr */ diff --git a/gr-blocks/lib/stream_to_streams_impl.h b/gr-blocks/lib/stream_to_streams_impl.h new file mode 100644 index 000000000..9a96983ff --- /dev/null +++ b/gr-blocks/lib/stream_to_streams_impl.h @@ -0,0 +1,44 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_STREAM_TO_STREAMS_IMPL_H +#define INCLUDED_STREAM_TO_STREAMS_IMPL_H + +#include <blocks/stream_to_streams.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API stream_to_streams_impl : public stream_to_streams + { + public: + stream_to_streams_impl(size_t itemsize, size_t nstreams); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_STREAM_TO_STREAMS_IMPL_H */ diff --git a/gr-blocks/lib/stream_to_vector_impl.cc b/gr-blocks/lib/stream_to_vector_impl.cc new file mode 100644 index 000000000..80ced5a74 --- /dev/null +++ b/gr-blocks/lib/stream_to_vector_impl.cc @@ -0,0 +1,62 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "stream_to_vector_impl.h" +#include <gr_io_signature.h> + +namespace gr { + namespace blocks { + + stream_to_vector::sptr stream_to_vector::make(size_t itemsize, size_t nitems_per_block) + { + return gnuradio::get_initial_sptr(new stream_to_vector_impl(itemsize, nitems_per_block)); + } + + stream_to_vector_impl::stream_to_vector_impl(size_t itemsize, size_t nitems_per_block) + : gr_sync_decimator ("stream_to_vector", + gr_make_io_signature (1, 1, itemsize), + gr_make_io_signature (1, 1, itemsize * nitems_per_block), + nitems_per_block) + { + } + + int + stream_to_vector_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + size_t block_size = output_signature()->sizeof_stream_item (0); + + const char *in = (const char *) input_items[0]; + char *out = (char *) output_items[0]; + + memcpy (out, in, noutput_items * block_size); + + return noutput_items; + } + + } /* namespace blocks */ +} /* namespace gr */ diff --git a/gr-blocks/lib/stream_to_vector_impl.h b/gr-blocks/lib/stream_to_vector_impl.h new file mode 100644 index 000000000..f8031f005 --- /dev/null +++ b/gr-blocks/lib/stream_to_vector_impl.h @@ -0,0 +1,44 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_STREAM_TO_VECTOR_IMPL_H +#define INCLUDED_STREAM_TO_VECTOR_IMPL_H + +#include <blocks/stream_to_vector.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API stream_to_vector_impl : public stream_to_vector + { + public: + stream_to_vector_impl(size_t itemsize, size_t nitems_per_block); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_STREAM_TO_VECTOR_IMPL_H */ diff --git a/gr-blocks/lib/streams_to_stream_impl.cc b/gr-blocks/lib/streams_to_stream_impl.cc new file mode 100644 index 000000000..09c593e81 --- /dev/null +++ b/gr-blocks/lib/streams_to_stream_impl.cc @@ -0,0 +1,72 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "streams_to_stream_impl.h" +#include <gr_io_signature.h> + +namespace gr { + namespace blocks { + + streams_to_stream::sptr streams_to_stream::make(size_t itemsize, size_t nstreams) + { + return gnuradio::get_initial_sptr(new streams_to_stream_impl(itemsize, nstreams)); + } + + streams_to_stream_impl::streams_to_stream_impl(size_t itemsize, size_t nstreams) + : gr_sync_interpolator ("streams_to_stream", + gr_make_io_signature (nstreams, nstreams, itemsize), + gr_make_io_signature (1, 1, itemsize), + nstreams) + { + } + + int + streams_to_stream_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + size_t itemsize = output_signature()->sizeof_stream_item (0); + + const char **inv = (const char **) &input_items[0]; + char *out = (char *) output_items[0]; + int nstreams = input_items.size(); + + assert (noutput_items % nstreams == 0); + int ni = noutput_items / nstreams; + + for (int i = 0; i < ni; i++){ + for (int j = 0; j < nstreams; j++){ + memcpy(out, inv[j], itemsize); + out += itemsize; + inv[j] += itemsize; + } + } + + return noutput_items; + } + + } /* namespace blocks */ +} /* namespace gr */ diff --git a/gr-blocks/lib/streams_to_stream_impl.h b/gr-blocks/lib/streams_to_stream_impl.h new file mode 100644 index 000000000..6f686172c --- /dev/null +++ b/gr-blocks/lib/streams_to_stream_impl.h @@ -0,0 +1,44 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_STREAMS_TO_STREAM_IMPL_H +#define INCLUDED_STREAMS_TO_STREAM_IMPL_H + +#include <blocks/streams_to_stream.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API streams_to_stream_impl : public streams_to_stream + { + public: + streams_to_stream_impl(size_t itemsize, size_t nstreams); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_STREAMS_TO_STREAM_IMPL_H */ diff --git a/gr-blocks/lib/streams_to_vector_impl.cc b/gr-blocks/lib/streams_to_vector_impl.cc new file mode 100644 index 000000000..c524a78e4 --- /dev/null +++ b/gr-blocks/lib/streams_to_vector_impl.cc @@ -0,0 +1,68 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "streams_to_vector_impl.h" +#include <gr_io_signature.h> + +namespace gr { + namespace blocks { + + streams_to_vector::sptr streams_to_vector::make(size_t itemsize, size_t nstreams) + { + return gnuradio::get_initial_sptr(new streams_to_vector_impl(itemsize, nstreams)); + } + + streams_to_vector_impl::streams_to_vector_impl(size_t itemsize, size_t nstreams) + : gr_sync_block ("streams_to_vector", + gr_make_io_signature (nstreams, nstreams, itemsize), + gr_make_io_signature (1, 1, nstreams * itemsize)) + { + } + + int + streams_to_vector_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + size_t itemsize = input_signature()->sizeof_stream_item(0); + int nstreams = input_items.size(); + + const char **inv = (const char **) &input_items[0]; + char *out = (char *) output_items[0]; + + for (int i = 0; i < noutput_items; i++){ + for (int j = 0; j < nstreams; j++){ + memcpy(out, inv[j], itemsize); + inv[j] += itemsize; + out += itemsize; + } + } + + return noutput_items; + } + + } /* namespace blocks */ +} /* namespace gr */ diff --git a/gr-blocks/lib/streams_to_vector_impl.h b/gr-blocks/lib/streams_to_vector_impl.h new file mode 100644 index 000000000..4a14e9d4f --- /dev/null +++ b/gr-blocks/lib/streams_to_vector_impl.h @@ -0,0 +1,44 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_STREAMS_TO_VECTOR_IMPL_H +#define INCLUDED_STREAMS_TO_VECTOR_IMPL_H + +#include <blocks/streams_to_vector.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API streams_to_vector_impl : public streams_to_vector + { + public: + streams_to_vector_impl(size_t itemsize, size_t nstreams); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_STREAMS_TO_VECTOR_IMPL_H */ diff --git a/gr-blocks/lib/sub_XX_impl.cc.t b/gr-blocks/lib/sub_XX_impl.cc.t new file mode 100644 index 000000000..35ae31452 --- /dev/null +++ b/gr-blocks/lib/sub_XX_impl.cc.t @@ -0,0 +1,69 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2009,2010,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <@NAME_IMPL@.h> +#include <gr_io_signature.h> + +namespace gr { + namespace blocks { + + @NAME@::sptr @NAME@::make(size_t vlen) + { + return gnuradio::get_initial_sptr(new @NAME_IMPL@(vlen)); + } + + @NAME_IMPL@::@NAME_IMPL@(size_t vlen) + : gr_sync_block ("@NAME@", + gr_make_io_signature (1, -1, sizeof (@I_TYPE@)*vlen), + gr_make_io_signature (1, 1, sizeof (@O_TYPE@)*vlen)), + d_vlen(vlen) + { + } + + int + @NAME_IMPL@::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + @O_TYPE@ *optr = (@O_TYPE@ *) output_items[0]; + + int ninputs = input_items.size (); + + for (size_t i = 0; i < noutput_items*d_vlen; i++){ + @I_TYPE@ acc = ((@I_TYPE@ *) input_items[0])[i]; + for (int j = 1; j < ninputs; j++) + acc -= ((@I_TYPE@ *) input_items[j])[i]; + + *optr++ = (@O_TYPE@) acc; + } + + return noutput_items; + } + + } /* namespace blocks */ +} /* namespace gr */ diff --git a/gr-blocks/lib/sub_XX_impl.h.t b/gr-blocks/lib/sub_XX_impl.h.t new file mode 100644 index 000000000..a1c486b85 --- /dev/null +++ b/gr-blocks/lib/sub_XX_impl.h.t @@ -0,0 +1,48 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2009,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifndef @GUARD_NAME_IMPL@ +#define @GUARD_NAME_IMPL@ + +#include <blocks/@NAME@.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API @NAME_IMPL@ : public @NAME@ + { + size_t d_vlen; + + public: + @NAME_IMPL@(size_t vlen); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* @GUARD_NAME_IMPL@ */ diff --git a/gr-blocks/lib/uchar_array_to_float.cc b/gr-blocks/lib/uchar_array_to_float.cc new file mode 100644 index 000000000..90cc0fca3 --- /dev/null +++ b/gr-blocks/lib/uchar_array_to_float.cc @@ -0,0 +1,40 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include <uchar_array_to_float.h> + +void +uchar_array_to_float (const unsigned char *in, float *out, int nsamples) +{ + while (nsamples >= 4){ + out[0] = in[0]; + out[1] = in[1]; + out[2] = in[2]; + out[3] = in[3]; + out += 4; + in += 4; + nsamples -= 4; + } + + while (nsamples-- > 0) + *out++ = *in++; +} diff --git a/gr-blocks/lib/uchar_array_to_float.h b/gr-blocks/lib/uchar_array_to_float.h new file mode 100644 index 000000000..e6772c2a8 --- /dev/null +++ b/gr-blocks/lib/uchar_array_to_float.h @@ -0,0 +1,34 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005, 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_UCHAR_ARRAY_TO_FLOAT_H +#define INCLUDED_UCHAR_ARRAY_TO_FLOAT_H + +#include <blocks/api.h> + +/* + * convert array of unsigned chars to floats + */ +BLOCKS_API void uchar_array_to_float (const unsigned char *in, float *out, int nsamples); + + +#endif /* INCLUDED_UCHAR_ARRAY_TO_FLOAT_H */ diff --git a/gr-blocks/lib/uchar_to_float_impl.cc b/gr-blocks/lib/uchar_to_float_impl.cc new file mode 100644 index 000000000..608c05ad4 --- /dev/null +++ b/gr-blocks/lib/uchar_to_float_impl.cc @@ -0,0 +1,60 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "uchar_to_float_impl.h" +#include "uchar_array_to_float.h" +#include <gr_io_signature.h> + +namespace gr { + namespace blocks { + + uchar_to_float::sptr uchar_to_float::make() + { + return gnuradio::get_initial_sptr(new uchar_to_float_impl()); + } + + uchar_to_float_impl::uchar_to_float_impl() + : gr_sync_block("uchar_to_float", + gr_make_io_signature (1, 1, sizeof(unsigned char)), + gr_make_io_signature (1, 1, sizeof(float))) + { + } + + int + uchar_to_float_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const unsigned char *in = (const unsigned char *) input_items[0]; + float *out = (float *) output_items[0]; + + uchar_array_to_float (in, out, noutput_items); + + return noutput_items; + } + + } /* namespace blocks */ +}/* namespace gr */ diff --git a/gr-blocks/lib/uchar_to_float_impl.h b/gr-blocks/lib/uchar_to_float_impl.h new file mode 100644 index 000000000..250dc2c86 --- /dev/null +++ b/gr-blocks/lib/uchar_to_float_impl.h @@ -0,0 +1,45 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_UCHAR_TO_FLOAT_IMPL_H +#define INCLUDED_UCHAR_TO_FLOAT_IMPL_H + +#include <blocks/uchar_to_float.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API uchar_to_float_impl : public uchar_to_float + { + public: + uchar_to_float_impl(); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + + +#endif /* INCLUDED_UCHAR_TO_FLOAT_IMPL_H */ diff --git a/gr-blocks/lib/vector_to_stream_impl.cc b/gr-blocks/lib/vector_to_stream_impl.cc new file mode 100644 index 000000000..fa833a3ec --- /dev/null +++ b/gr-blocks/lib/vector_to_stream_impl.cc @@ -0,0 +1,62 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "vector_to_stream_impl.h" +#include <gr_io_signature.h> + +namespace gr { + namespace blocks { + + vector_to_stream::sptr vector_to_stream::make(size_t itemsize, size_t nitems_per_block) + { + return gnuradio::get_initial_sptr(new vector_to_stream_impl(itemsize, nitems_per_block)); + } + + vector_to_stream_impl::vector_to_stream_impl(size_t itemsize, size_t nitems_per_block) + : gr_sync_interpolator ("vector_to_stream", + gr_make_io_signature (1, 1, itemsize * nitems_per_block), + gr_make_io_signature (1, 1, itemsize), + nitems_per_block) + { + } + + int + vector_to_stream_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + size_t block_size = output_signature()->sizeof_stream_item (0); + + const char *in = (const char *) input_items[0]; + char *out = (char *) output_items[0]; + + memcpy (out, in, noutput_items * block_size); + + return noutput_items; + } + + } /* namespace blocks */ +} /* namespace gr */ diff --git a/gr-blocks/lib/vector_to_stream_impl.h b/gr-blocks/lib/vector_to_stream_impl.h new file mode 100644 index 000000000..4128f6090 --- /dev/null +++ b/gr-blocks/lib/vector_to_stream_impl.h @@ -0,0 +1,44 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_VECTOR_TO_STREAM_IMPL_H +#define INCLUDED_VECTOR_TO_STREAM_IMPL_H + +#include <blocks/vector_to_stream.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API vector_to_stream_impl : public vector_to_stream + { + public: + vector_to_stream_impl(size_t itemsize, size_t nitems_per_block); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_VECTOR_TO_STREAM_IMPL_H */ diff --git a/gr-blocks/lib/vector_to_streams_impl.cc b/gr-blocks/lib/vector_to_streams_impl.cc new file mode 100644 index 000000000..09d32c5c5 --- /dev/null +++ b/gr-blocks/lib/vector_to_streams_impl.cc @@ -0,0 +1,68 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "vector_to_streams_impl.h" +#include <gr_io_signature.h> + +namespace gr { + namespace blocks { + + vector_to_streams::sptr vector_to_streams::make(size_t itemsize, size_t nstreams) + { + return gnuradio::get_initial_sptr(new vector_to_streams_impl(itemsize, nstreams)); + } + + vector_to_streams_impl::vector_to_streams_impl(size_t itemsize, size_t nstreams) + : gr_sync_block ("vector_to_streams", + gr_make_io_signature (1, 1, nstreams * itemsize), + gr_make_io_signature (nstreams, nstreams, itemsize)) + + { + } + + int + vector_to_streams_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + size_t itemsize = output_signature()->sizeof_stream_item(0); + int nstreams = output_items.size(); + + const char *in = (const char *) input_items[0]; + char **outv = (char **) &output_items[0]; + + for (int i = 0; i < noutput_items; i++){ + for (int j = 0; j < nstreams; j++){ + memcpy(outv[j], in, itemsize); + outv[j] += itemsize; + in += itemsize; + } + } + + return noutput_items; + } + } /* namespace blocks */ +} /* namespace gr */ diff --git a/gr-blocks/lib/vector_to_streams_impl.h b/gr-blocks/lib/vector_to_streams_impl.h new file mode 100644 index 000000000..81bcfd076 --- /dev/null +++ b/gr-blocks/lib/vector_to_streams_impl.h @@ -0,0 +1,44 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_VECTOR_TO_STREAMS_IMPL_H +#define INCLUDED_VECTOR_TO_STREAMS_IMPL_H + +#include <blocks/vector_to_streams.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API vector_to_streams_impl : public vector_to_streams + { + public: + vector_to_streams_impl(size_t itemsize, size_t nstreams); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_VECTOR_TO_STREAMS_IMPL_H */ diff --git a/gr-blocks/lib/xor_XX_impl.cc.t b/gr-blocks/lib/xor_XX_impl.cc.t new file mode 100644 index 000000000..eea926512 --- /dev/null +++ b/gr-blocks/lib/xor_XX_impl.cc.t @@ -0,0 +1,69 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <@NAME_IMPL@.h> +#include <gr_io_signature.h> + +namespace gr { + namespace blocks { + + @NAME@::sptr @NAME@::make(size_t vlen) + { + return gnuradio::get_initial_sptr(new @NAME_IMPL@(vlen)); + } + + @NAME_IMPL@::@NAME_IMPL@(size_t vlen) + : gr_sync_block ("@NAME@", + gr_make_io_signature (1, -1, sizeof (@I_TYPE@)*vlen), + gr_make_io_signature (1, 1, sizeof (@O_TYPE@)*vlen)), + d_vlen(vlen) + { + } + + int + @NAME_IMPL@::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + @O_TYPE@ *optr = (@O_TYPE@ *) output_items[0]; + + int ninputs = input_items.size (); + + for (size_t i = 0; i < noutput_items*d_vlen; i++){ + @I_TYPE@ acc = ((@I_TYPE@ *) input_items[0])[i]; + for (int j = 1; j < ninputs; j++) + acc ^= ((@I_TYPE@ *) input_items[j])[i]; + + *optr++ = (@O_TYPE@) acc; + } + + return noutput_items; + } + + } /* namespace blocks */ +} /* namespace gr */ diff --git a/gr-blocks/lib/xor_XX_impl.h.t b/gr-blocks/lib/xor_XX_impl.h.t new file mode 100644 index 000000000..25f0da0c8 --- /dev/null +++ b/gr-blocks/lib/xor_XX_impl.h.t @@ -0,0 +1,48 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifndef @GUARD_NAME_IMPL@ +#define @GUARD_NAME_IMPL@ + +#include <blocks/@NAME@.h> + +namespace gr { + namespace blocks { + + class BLOCKS_API @NAME_IMPL@ : public @NAME@ + { + size_t d_vlen; + + public: + @NAME_IMPL@(size_t vlen); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* @GUARD_NAME_IMPL@ */ diff --git a/gr-blocks/python/CMakeLists.txt b/gr-blocks/python/CMakeLists.txt new file mode 100644 index 000000000..cab0b956f --- /dev/null +++ b/gr-blocks/python/CMakeLists.txt @@ -0,0 +1,48 @@ +# Copyright 2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. + +######################################################################## +include(GrPython) + +GR_PYTHON_INSTALL( + FILES + __init__.py + parse_file_metadata.py + DESTINATION ${GR_PYTHON_DIR}/gnuradio/blocks + COMPONENT "blocks_python" +) + +######################################################################## +# Handle the unit tests +######################################################################## +if(ENABLE_TESTING) + +list(APPEND GR_TEST_PYTHON_DIRS + ${CMAKE_BINARY_DIR}/gr-blocks/python + ${CMAKE_BINARY_DIR}/gr-blocks/swig +) +list(APPEND GR_TEST_TARGET_DEPS gnuradio-blocks) + +include(GrTest) +file(GLOB py_qa_test_files "qa_*.py") +foreach(py_qa_test_file ${py_qa_test_files}) + get_filename_component(py_qa_test_name ${py_qa_test_file} NAME_WE) + GR_ADD_TEST(${py_qa_test_name} ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B} ${py_qa_test_file}) +endforeach(py_qa_test_file) +endif(ENABLE_TESTING) diff --git a/gr-blocks/python/__init__.py b/gr-blocks/python/__init__.py new file mode 100644 index 000000000..6577d933e --- /dev/null +++ b/gr-blocks/python/__init__.py @@ -0,0 +1,37 @@ +# +# Copyright 2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +''' +This is the gr-blocks package. This package provides GNU Radio +processing blocks common to many flowgraphs. +''' + +from blocks_swig import * + +#alias old gr_add_vXX and gr_multiply_vXX +add_vcc = add_cc +add_vff = add_ff +add_vii = add_ii +add_vss = add_ss +multiply_vcc = multiply_cc +multiply_vff = multiply_ff +multiply_vii = multiply_ii +multiply_vss = multiply_ss diff --git a/gr-blocks/python/parse_file_metadata.py b/gr-blocks/python/parse_file_metadata.py new file mode 100644 index 000000000..c8ac2def9 --- /dev/null +++ b/gr-blocks/python/parse_file_metadata.py @@ -0,0 +1,193 @@ +#!/usr/bin/env python +# +# Copyright 2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +import sys +from gnuradio import gr + +try: + import pmt +except ImportError: + from gruel import pmt + + +try: + import blocks_swig as blocks +except ImportError: + from gnuradio import blocks + +''' +sr Sample rate (samples/second) +time Time as uint64(secs), double(fractional secs) +type Type of data (see gr_file_types enum) +cplx is complex? (True or False) +strt Start of data (or size of header) in bytes +size Size of data in bytes +''' + +HEADER_LENGTH = blocks.METADATA_HEADER_SIZE + +ftype_to_string = {blocks.GR_FILE_BYTE: "bytes", + blocks.GR_FILE_SHORT: "short", + blocks.GR_FILE_INT: "int", + blocks.GR_FILE_LONG: "long", + blocks.GR_FILE_LONG_LONG: "long long", + blocks.GR_FILE_FLOAT: "float", + blocks.GR_FILE_DOUBLE: "double" } + +ftype_to_size = {blocks.GR_FILE_BYTE: gr.sizeof_char, + blocks.GR_FILE_SHORT: gr.sizeof_short, + blocks.GR_FILE_INT: gr.sizeof_int, + blocks.GR_FILE_LONG: gr.sizeof_int, + blocks.GR_FILE_LONG_LONG: 2*gr.sizeof_int, + blocks.GR_FILE_FLOAT: gr.sizeof_float, + blocks.GR_FILE_DOUBLE: gr.sizeof_double} + +def parse_header(p, VERBOSE=False): + dump = pmt.PMT_NIL + + info = dict() + + if(pmt.pmt_is_dict(p) is False): + sys.stderr.write("Header is not a PMT dictionary: invalid or corrupt data file.\n") + sys.exit(1) + + # GET FILE FORMAT VERSION NUMBER + if(pmt.pmt_dict_has_key(p, pmt.pmt_string_to_symbol("version"))): + r = pmt.pmt_dict_ref(p, pmt.pmt_string_to_symbol("version"), dump) + version = pmt.pmt_to_long(r) + if(VERBOSE): + print "Version Number: {0}".format(version) + else: + sys.stderr.write("Could not find key 'version': invalid or corrupt data file.\n") + sys.exit(1) + + # EXTRACT SAMPLE RATE + if(pmt.pmt_dict_has_key(p, pmt.pmt_string_to_symbol("rx_rate"))): + r = pmt.pmt_dict_ref(p, pmt.pmt_string_to_symbol("rx_rate"), dump) + samp_rate = pmt.pmt_to_double(r) + info["rx_rate"] = samp_rate + if(VERBOSE): + print "Sample Rate: {0:.2f} sps".format(samp_rate) + else: + sys.stderr.write("Could not find key 'sr': invalid or corrupt data file.\n") + sys.exit(1) + + # EXTRACT TIME STAMP + if(pmt.pmt_dict_has_key(p, pmt.pmt_string_to_symbol("rx_time"))): + r = pmt.pmt_dict_ref(p, pmt.pmt_string_to_symbol("rx_time"), dump) + pmt_secs = pmt.pmt_tuple_ref(r, 0) + pmt_fracs = pmt.pmt_tuple_ref(r, 1) + secs = float(pmt.pmt_to_uint64(pmt_secs)) + fracs = pmt.pmt_to_double(pmt_fracs) + t = secs + fracs + info["rx_time"] = t + if(VERBOSE): + print "Seconds: {0:.6f}".format(t) + else: + sys.stderr.write("Could not find key 'time': invalid or corrupt data file.\n") + sys.exit(1) + + # EXTRACT ITEM SIZE + if(pmt.pmt_dict_has_key(p, pmt.pmt_string_to_symbol("size"))): + r = pmt.pmt_dict_ref(p, pmt.pmt_string_to_symbol("size"), dump) + dsize = pmt.pmt_to_long(r) + info["size"] = dsize + if(VERBOSE): + print "Item size: {0}".format(dsize) + else: + sys.stderr.write("Could not find key 'size': invalid or corrupt data file.\n") + sys.exit(1) + + # EXTRACT DATA TYPE + if(pmt.pmt_dict_has_key(p, pmt.pmt_string_to_symbol("type"))): + r = pmt.pmt_dict_ref(p, pmt.pmt_string_to_symbol("type"), dump) + dtype = pmt.pmt_to_long(r) + stype = ftype_to_string[dtype] + info["type"] = stype + if(VERBOSE): + print "Data Type: {0} ({1})".format(stype, dtype) + else: + sys.stderr.write("Could not find key 'type': invalid or corrupt data file.\n") + sys.exit(1) + + # EXTRACT COMPLEX + if(pmt.pmt_dict_has_key(p, pmt.pmt_string_to_symbol("cplx"))): + r = pmt.pmt_dict_ref(p, pmt.pmt_string_to_symbol("cplx"), dump) + cplx = pmt.pmt_to_bool(r) + info["cplx"] = cplx + if(VERBOSE): + print "Complex? {0}".format(cplx) + else: + sys.stderr.write("Could not find key 'cplx': invalid or corrupt data file.\n") + sys.exit(1) + + # EXTRACT WHERE CURRENT SEGMENT STARTS + if(pmt.pmt_dict_has_key(p, pmt.pmt_string_to_symbol("strt"))): + r = pmt.pmt_dict_ref(p, pmt.pmt_string_to_symbol("strt"), dump) + seg_start = pmt.pmt_to_uint64(r) + info["hdr_len"] = seg_start + info["extra_len"] = seg_start - HEADER_LENGTH + info["has_extra"] = info["extra_len"] > 0 + if(VERBOSE): + print "Header Length: {0} bytes".format(info["hdr_len"]) + print "Extra Length: {0}".format((info["extra_len"])) + print "Extra Header? {0}".format(info["has_extra"]) + else: + sys.stderr.write("Could not find key 'strt': invalid or corrupt data file.\n") + sys.exit(1) + + # EXTRACT SIZE OF DATA + if(pmt.pmt_dict_has_key(p, pmt.pmt_string_to_symbol("bytes"))): + r = pmt.pmt_dict_ref(p, pmt.pmt_string_to_symbol("bytes"), dump) + nbytes = pmt.pmt_to_uint64(r) + + nitems = nbytes/dsize + info["nitems"] = nitems + info["nbytes"] = nbytes + + if(VERBOSE): + print "Size of Data: {0} bytes".format(nbytes) + print " {0} items".format(nitems) + else: + sys.stderr.write("Could not find key 'size': invalid or corrupt data file.\n") + sys.exit(1) + + return info + +# IF THERE IS EXTRA DATA, PULL OUT THE DICTIONARY AND PARSE IT +def parse_extra_dict(p, info, VERBOSE=False): + if(pmt.pmt_is_dict(p) is False): + sys.stderr.write("Extra header is not a PMT dictionary: invalid or corrupt data file.\n") + sys.exit(1) + + items = pmt.pmt_dict_items(p) + nitems = pmt.pmt_length(items) + for i in xrange(nitems): + item = pmt.pmt_nth(i, items) + key = pmt.pmt_symbol_to_string(pmt.pmt_car(item)) + val = pmt.pmt_cdr(item) + info[key] = val + if(VERBOSE): + print "{0}: ".format(key) + pmt.pmt_print(val) + + return info diff --git a/gr-blocks/python/qa_add_mult_div_sub.py b/gr-blocks/python/qa_add_mult_div_sub.py new file mode 100755 index 000000000..0aca03d3f --- /dev/null +++ b/gr-blocks/python/qa_add_mult_div_sub.py @@ -0,0 +1,212 @@ +#!/usr/bin/env python +# +# Copyright 2004,2007,2010,2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, gr_unittest +import blocks_swig + +class test_add_mult_div_sub(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def help_ii(self, src_data, exp_data, op): + for s in zip(range(len(src_data)), src_data): + src = gr.vector_source_i(s[1]) + self.tb.connect(src, (op, s[0])) + dst = gr.vector_sink_i() + self.tb.connect(op, dst) + self.tb.run() + result_data = dst.data() + self.assertEqual(exp_data, result_data) + + def help_ss(self, src_data, exp_data, op): + for s in zip(range(len(src_data)), src_data): + src = gr.vector_source_s(s[1]) + self.tb.connect(src, (op, s[0])) + dst = gr.vector_sink_s() + self.tb.connect(op, dst) + self.tb.run() + result_data = dst.data() + self.assertEqual(exp_data, result_data) + + def help_ff(self, src_data, exp_data, op): + for s in zip(range(len(src_data)), src_data): + src = gr.vector_source_f(s[1]) + self.tb.connect(src, (op, s[0])) + dst = gr.vector_sink_f() + self.tb.connect(op, dst) + self.tb.run() + result_data = dst.data() + self.assertEqual(exp_data, result_data) + + def help_cc(self, src_data, exp_data, op): + for s in zip(range(len(src_data)), src_data): + src = gr.vector_source_c(s[1]) + self.tb.connect(src, (op, s[0])) + dst = gr.vector_sink_c() + self.tb.connect(op, dst) + self.tb.run() + result_data = dst.data() + self.assertEqual(exp_data, result_data) + + # add_XX + + def test_add_ss(self): + src1_data = (1, 2, 3, 4, 5) + src2_data = (8, -3, 4, 8, 2) + expected_result = (9, -1, 7, 12, 7) + op = blocks_swig.add_ss() + self.help_ss((src1_data, src2_data), expected_result, op) + + def test_add_ii(self): + src1_data = (1, 2, 3, 4, 5) + src2_data = (8, -3, 4, 8, 2) + expected_result = (9, -1, 7, 12, 7) + op = blocks_swig.add_ii() + self.help_ii((src1_data, src2_data), expected_result, op) + + def test_add_ff(self): + src1_data = (1.0, 2.0, 3.0, 4.0, 5.0) + src2_data = (8.0, -3.0, 4.0, 8.0, 2.0) + expected_result = (9.0, -1.0, 7.0, 12.0, 7.0) + op = blocks_swig.add_ff() + self.help_ff((src1_data, src2_data), expected_result, op) + + def test_add_cc(self): + src1_data = (1+1j, 2+2j, 3+3j, 4+4j, 5+5j) + src2_data = (8+8j, -3-3j, 4+4j, 8+8j, 2+2j) + expected_result = (9+9j, -1-1j, 7+7j, 12+12j, 7+7j) + op = blocks_swig.add_cc() + self.help_cc((src1_data, src2_data), expected_result, op) + + # add_const_XX + + def test_add_const_ss(self): + src_data = (1, 2, 3, 4, 5) + expected_result = (6, 7, 8, 9, 10) + op = blocks_swig.add_const_ss(5) + self.help_ss((src_data,), expected_result, op) + + def test_add_const_ii(self): + src_data = (1, 2, 3, 4, 5) + expected_result = (6, 7, 8, 9, 10) + op = blocks_swig.add_const_ii(5) + self.help_ii((src_data,), expected_result, op) + + def test_add_const_ff(self): + src_data = (1, 2, 3, 4, 5) + expected_result = (6, 7, 8, 9, 10) + op = blocks_swig.add_const_ff(5) + self.help_ff((src_data,), expected_result, op) + + def test_add_const_cc(self): + src_data = (1, 2, 3, 4, 5) + expected_result = (1+5j, 2+5j, 3+5j, 4+5j, 5+5j) + op = blocks_swig.add_const_cc(5j) + self.help_cc((src_data,), expected_result, op) + + # multiply_XX + + def test_multiply_ss(self): + src1_data = (1, 2, 3, 4, 5) + src2_data = (8, -3, 4, 8, 2) + expected_result = (8, -6, 12, 32, 10) + op = blocks_swig.multiply_ss() + self.help_ss((src1_data, src2_data), + expected_result, op) + + def test_multiply_ii(self): + src1_data = (1, 2, 3, 4, 5) + src2_data = (8, -3, 4, 8, 2) + expected_result = (8, -6, 12, 32, 10) + op = blocks_swig.multiply_ii() + self.help_ii((src1_data, src2_data), + expected_result, op) + + def test_multiply_ff(self): + src1_data = (1, 2, 3, 4, 5) + src2_data = (8, -3, 4, 8, 2) + expected_result = (8, -6, 12, 32, 10) + op = blocks_swig.multiply_ff() + self.help_ff((src1_data, src2_data), + expected_result, op) + + def test_multiply_cc(self): + src1_data = (1+1j, 2+2j, 3+3j, 4+4j, 5+5j) + src2_data = (8, -3, 4, 8, 2) + expected_result = (8+8j, -6-6j, 12+12j, 32+32j, 10+10j) + op = blocks_swig.multiply_cc() + self.help_cc((src1_data, src2_data), + expected_result, op) + + # multiply_const_XX + + def test_multiply_const_ss(self): + src_data = (-1, 0, 1, 2, 3) + expected_result = (-5, 0, 5, 10, 15) + op = blocks_swig.multiply_const_ss(5) + self.help_ss((src_data,), expected_result, op) + + def test_multiply_const_ii(self): + src_data = (-1, 0, 1, 2, 3) + expected_result = (-5, 0, 5, 10, 15) + op = blocks_swig.multiply_const_ii(5) + self.help_ii((src_data,), expected_result, op) + + def test_multiply_const_ff(self): + src_data = (-1, 0, 1, 2, 3) + expected_result = (-5, 0, 5, 10, 15) + op = blocks_swig.multiply_const_ff(5) + self.help_ff((src_data,), expected_result, op) + + def test_multiply_const_cc(self): + src_data = (-1-1j, 0+0j, 1+1j, 2+2j, 3+3j) + expected_result = (-5-5j, 0+0j, 5+5j, 10+10j, 15+15j) + op = blocks_swig.multiply_const_cc(5) + self.help_cc((src_data,), expected_result, op) + + def test_multiply_const_cc2(self): + src_data = (-1-1j, 0+0j, 1+1j, 2+2j, 3+3j) + expected_result = (-3-7j, 0+0j, 3+7j, 6+14j, 9+21j) + op = blocks_swig.multiply_const_cc(5+2j) + self.help_cc((src_data,), expected_result, op) + + def test_sub_ii(self): + src1_data = (1, 2, 3, 4, 5) + src2_data = (8, -3, 4, 8, 2) + expected_result = (-7, 5, -1, -4, 3) + op = blocks_swig.sub_ii() + self.help_ii((src1_data, src2_data), + expected_result, op) + + def test_div_ff(self): + src1_data = ( 5, 9, -15, 1024) + src2_data = (10, 3, -5, 64) + expected_result = (0.5, 3, 3, 16) + op = blocks_swig.divide_ff() + self.help_ff((src1_data, src2_data), expected_result, op) + +if __name__ == '__main__': + gr_unittest.run(test_add_mult_div_sub, "test_add_mult_div_sub.xml") diff --git a/gr-blocks/python/qa_add_mult_v.py b/gr-blocks/python/qa_add_mult_v.py new file mode 100755 index 000000000..d362cb885 --- /dev/null +++ b/gr-blocks/python/qa_add_mult_v.py @@ -0,0 +1,360 @@ +#!/usr/bin/env python +# +# Copyright 2004,2007,2010,2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, gr_unittest +import blocks_swig + +class test_add_mult_v(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def help_ss(self, size, src_data, exp_data, op): + for s in zip(range (len (src_data)), src_data): + src = gr.vector_source_s(s[1]) + srcv = gr.stream_to_vector(gr.sizeof_short, size) + self.tb.connect(src, srcv) + self.tb.connect(srcv, (op, s[0])) + rhs = gr.vector_to_stream(gr.sizeof_short, size) + dst = gr.vector_sink_s() + self.tb.connect(op, rhs, dst) + self.tb.run() + result_data = dst.data() + self.assertEqual(exp_data, result_data) + + def help_ii(self, size, src_data, exp_data, op): + for s in zip(range (len (src_data)), src_data): + src = gr.vector_source_i(s[1]) + srcv = gr.stream_to_vector(gr.sizeof_int, size) + self.tb.connect(src, srcv) + self.tb.connect(srcv, (op, s[0])) + rhs = gr.vector_to_stream(gr.sizeof_int, size) + dst = gr.vector_sink_i() + self.tb.connect(op, rhs, dst) + self.tb.run() + result_data = dst.data() + self.assertEqual(exp_data, result_data) + + def help_ff(self, size, src_data, exp_data, op): + for s in zip(range (len (src_data)), src_data): + src = gr.vector_source_f(s[1]) + srcv = gr.stream_to_vector(gr.sizeof_float, size) + self.tb.connect(src, srcv) + self.tb.connect(srcv, (op, s[0])) + rhs = gr.vector_to_stream(gr.sizeof_float, size) + dst = gr.vector_sink_f() + self.tb.connect(op, rhs, dst) + self.tb.run() + result_data = dst.data() + self.assertEqual(exp_data, result_data) + + def help_cc(self, size, src_data, exp_data, op): + for s in zip(range (len (src_data)), src_data): + src = gr.vector_source_c(s[1]) + srcv = gr.stream_to_vector(gr.sizeof_gr_complex, size) + self.tb.connect(src, srcv) + self.tb.connect(srcv, (op, s[0])) + rhs = gr.vector_to_stream(gr.sizeof_gr_complex, size) + dst = gr.vector_sink_c() + self.tb.connect(op, rhs, dst) + self.tb.run() + result_data = dst.data() + self.assertEqual(exp_data, result_data) + + def help_const_ss(self, src_data, exp_data, op): + src = gr.vector_source_s(src_data) + srcv = gr.stream_to_vector(gr.sizeof_short, len(src_data)) + rhs = gr.vector_to_stream(gr.sizeof_short, len(src_data)) + dst = gr.vector_sink_s() + self.tb.connect(src, srcv, op, rhs, dst) + self.tb.run() + result_data = dst.data() + self.assertEqual(exp_data, result_data) + + def help_const_ii(self, src_data, exp_data, op): + src = gr.vector_source_i(src_data) + srcv = gr.stream_to_vector(gr.sizeof_int, len(src_data)) + rhs = gr.vector_to_stream(gr.sizeof_int, len(src_data)) + dst = gr.vector_sink_i() + self.tb.connect(src, srcv, op, rhs, dst) + self.tb.run() + result_data = dst.data() + self.assertEqual(exp_data, result_data) + + def help_const_ff(self, src_data, exp_data, op): + src = gr.vector_source_f(src_data) + srcv = gr.stream_to_vector(gr.sizeof_float, len(src_data)) + rhs = gr.vector_to_stream(gr.sizeof_float, len(src_data)) + dst = gr.vector_sink_f() + self.tb.connect(src, srcv, op, rhs, dst) + self.tb.run() + result_data = dst.data() + self.assertEqual(exp_data, result_data) + + def help_const_cc(self, src_data, exp_data, op): + src = gr.vector_source_c(src_data) + srcv = gr.stream_to_vector(gr.sizeof_gr_complex, len(src_data)) + rhs = gr.vector_to_stream(gr.sizeof_gr_complex, len(src_data)) + dst = gr.vector_sink_c() + self.tb.connect(src, srcv, op, rhs, dst) + self.tb.run() + result_data = dst.data() + self.assertEqual(exp_data, result_data) + + # add_vXX + + def test_add_vss_one(self): + src1_data = (1,) + src2_data = (2,) + src3_data = (3,) + expected_result = (6,) + op = blocks_swig.add_ss(1) + self.help_ss(1, (src1_data, src2_data, src3_data), expected_result, op) + + def test_add_vss_five(self): + src1_data = (1, 2, 3, 4, 5) + src2_data = (6, 7, 8, 9, 10) + src3_data = (11, 12, 13, 14, 15) + expected_result = (18, 21, 24, 27, 30) + op = blocks_swig.add_ss(5) + self.help_ss(5, (src1_data, src2_data, src3_data), expected_result, op) + + def test_add_vii_one(self): + src1_data = (1,) + src2_data = (2,) + src3_data = (3,) + expected_result = (6,) + op = blocks_swig.add_ii(1) + self.help_ii(1, (src1_data, src2_data, src3_data), expected_result, op) + + def test_add_vii_five(self): + src1_data = (1, 2, 3, 4, 5) + src2_data = (6, 7, 8, 9, 10) + src3_data = (11, 12, 13, 14, 15) + expected_result = (18, 21, 24, 27, 30) + op = blocks_swig.add_ii(5) + self.help_ii(5, (src1_data, src2_data, src3_data), expected_result, op) + + def test_add_vff_one(self): + src1_data = (1.0,) + src2_data = (2.0,) + src3_data = (3.0,) + expected_result = (6.0,) + op = blocks_swig.add_ff(1) + self.help_ff(1, (src1_data, src2_data, src3_data), expected_result, op) + + def test_add_vff_five(self): + src1_data = (1.0, 2.0, 3.0, 4.0, 5.0) + src2_data = (6.0, 7.0, 8.0, 9.0, 10.0) + src3_data = (11.0, 12.0, 13.0, 14.0, 15.0) + expected_result = (18.0, 21.0, 24.0, 27.0, 30.0) + op = blocks_swig.add_ff(5) + self.help_ff(5, (src1_data, src2_data, src3_data), expected_result, op) + + def test_add_vcc_one(self): + src1_data = (1.0+2.0j,) + src2_data = (3.0+4.0j,) + src3_data = (5.0+6.0j,) + expected_result = (9.0+12j,) + op = blocks_swig.add_cc(1) + self.help_cc(1, (src1_data, src2_data, src3_data), expected_result, op) + + def test_add_vcc_five(self): + src1_data = (1.0+2.0j, 3.0+4.0j, 5.0+6.0j, 7.0+8.0j, 9.0+10.0j) + src2_data = (11.0+12.0j, 13.0+14.0j, 15.0+16.0j, 17.0+18.0j, 19.0+20.0j) + src3_data = (21.0+22.0j, 23.0+24.0j, 25.0+26.0j, 27.0+28.0j, 29.0+30.0j) + expected_result = (33.0+36.0j, 39.0+42.0j, 45.0+48.0j, 51.0+54.0j, 57.0+60.0j) + op = blocks_swig.add_cc(5) + self.help_cc(5, (src1_data, src2_data, src3_data), expected_result, op) + + # add_const_vXX + + def test_add_const_vss_one(self): + src_data = (1,) + op = blocks_swig.add_const_vss((2,)) + exp_data = (3,) + self.help_const_ss(src_data, exp_data, op) + + def test_add_const_vss_five(self): + src_data = (1, 2, 3, 4, 5) + op = blocks_swig.add_const_vss((6, 7, 8, 9, 10)) + exp_data = (7, 9, 11, 13, 15) + self.help_const_ss(src_data, exp_data, op) + + def test_add_const_vii_one(self): + src_data = (1,) + op = blocks_swig.add_const_vii((2,)) + exp_data = (3,) + self.help_const_ii(src_data, exp_data, op) + + def test_add_const_vii_five(self): + src_data = (1, 2, 3, 4, 5) + op = blocks_swig.add_const_vii((6, 7, 8, 9, 10)) + exp_data = (7, 9, 11, 13, 15) + self.help_const_ii(src_data, exp_data, op) + + def test_add_const_vff_one(self): + src_data = (1.0,) + op = blocks_swig.add_const_vff((2.0,)) + exp_data = (3.0,) + self.help_const_ff(src_data, exp_data, op) + + def test_add_const_vff_five(self): + src_data = (1.0, 2.0, 3.0, 4.0, 5.0) + op = blocks_swig.add_const_vff((6.0, 7.0, 8.0, 9.0, 10.0)) + exp_data = (7.0, 9.0, 11.0, 13.0, 15.0) + self.help_const_ff(src_data, exp_data, op) + + def test_add_const_vcc_one(self): + src_data = (1.0+2.0j,) + op = blocks_swig.add_const_vcc((2.0+3.0j,)) + exp_data = (3.0+5.0j,) + self.help_const_cc(src_data, exp_data, op) + + def test_add_const_vcc_five(self): + src_data = (1.0+2.0j, 3.0+4.0j, 5.0+6.0j, 7.0+8.0j, 9.0+10.0j) + op = blocks_swig.add_const_vcc((11.0+12.0j, 13.0+14.0j, 15.0+16.0j, 17.0+18.0j, 19.0+20.0j)) + exp_data = (12.0+14.0j, 16.0+18.0j, 20.0+22.0j, 24.0+26.0j, 28.0+30.0j) + self.help_const_cc(src_data, exp_data, op) + + # multiply_vXX + + def test_multiply_vss_one(self): + src1_data = (1,) + src2_data = (2,) + src3_data = (3,) + expected_result = (6,) + op = gr.multiply_vss(1) + self.help_ss(1, (src1_data, src2_data, src3_data), expected_result, op) + + def test_multiply_vss_five(self): + src1_data = (1, 2, 3, 4, 5) + src2_data = (6, 7, 8, 9, 10) + src3_data = (11, 12, 13, 14, 15) + expected_result = (66, 168, 312, 504, 750) + op = gr.multiply_vss(5) + self.help_ss(5, (src1_data, src2_data, src3_data), expected_result, op) + + def test_multiply_vii_one(self): + src1_data = (1,) + src2_data = (2,) + src3_data = (3,) + expected_result = (6,) + op = gr.multiply_vii(1) + self.help_ii(1, (src1_data, src2_data, src3_data), expected_result, op) + + def test_multiply_vii_five(self): + src1_data = (1, 2, 3, 4, 5) + src2_data = (6, 7, 8, 9, 10) + src3_data = (11, 12, 13, 14, 15) + expected_result = (66, 168, 312, 504, 750) + op = gr.multiply_vii(5) + self.help_ii(5, (src1_data, src2_data, src3_data), expected_result, op) + + def test_multiply_vff_one(self): + src1_data = (1.0,) + src2_data = (2.0,) + src3_data = (3.0,) + expected_result = (6.0,) + op = gr.multiply_vff(1) + self.help_ff(1, (src1_data, src2_data, src3_data), expected_result, op) + + def test_multiply_vff_five(self): + src1_data = (1.0, 2.0, 3.0, 4.0, 5.0) + src2_data = (6.0, 7.0, 8.0, 9.0, 10.0) + src3_data = (11.0, 12.0, 13.0, 14.0, 15.0) + expected_result = (66.0, 168.0, 312.0, 504.0, 750.0) + op = gr.multiply_vff(5) + self.help_ff(5, (src1_data, src2_data, src3_data), expected_result, op) + + def test_multiply_vcc_one(self): + src1_data = (1.0+2.0j,) + src2_data = (3.0+4.0j,) + src3_data = (5.0+6.0j,) + expected_result = (-85+20j,) + op = gr.multiply_vcc(1) + self.help_cc(1, (src1_data, src2_data, src3_data), expected_result, op) + + def test_multiply_vcc_five(self): + src1_data = (1.0+2.0j, 3.0+4.0j, 5.0+6.0j, 7.0+8.0j, 9.0+10.0j) + src2_data = (11.0+12.0j, 13.0+14.0j, 15.0+16.0j, 17.0+18.0j, 19.0+20.0j) + src3_data = (21.0+22.0j, 23.0+24.0j, 25.0+26.0j, 27.0+28.0j, 29.0+30.0j) + expected_result = (-1021.0+428.0j, -2647.0+1754.0j, -4945.0+3704.0j, -8011.0+6374.0j, -11941.0+9860.0j) + op = gr.multiply_vcc(5) + self.help_cc(5, (src1_data, src2_data, src3_data), expected_result, op) + + # multiply_const_vXX + + def test_multiply_const_vss_one(self): + src_data = (2,) + op = gr.multiply_const_vss((3,)) + exp_data = (6,) + self.help_const_ss(src_data, exp_data, op) + + def test_multiply_const_vss_five(self): + src_data = (1, 2, 3, 4, 5) + op = gr.multiply_const_vss((6, 7, 8, 9, 10)) + exp_data = (6, 14, 24, 36, 50) + self.help_const_ss(src_data, exp_data, op) + + def test_multiply_const_vii_one(self): + src_data = (2,) + op = gr.multiply_const_vii((3,)) + exp_data = (6,) + self.help_const_ii(src_data, exp_data, op) + + def test_multiply_const_vii_five(self): + src_data = (1, 2, 3, 4, 5) + op = gr.multiply_const_vii((6, 7, 8, 9, 10)) + exp_data = (6, 14, 24, 36, 50) + self.help_const_ii(src_data, exp_data, op) + + def test_multiply_const_vff_one(self): + src_data = (2.0,) + op = gr.multiply_const_vff((3.0,)) + exp_data = (6.0,) + self.help_const_ff(src_data, exp_data, op) + + def test_multiply_const_vff_five(self): + src_data = (1.0, 2.0, 3.0, 4.0, 5.0) + op = gr.multiply_const_vff((6.0, 7.0, 8.0, 9.0, 10.0)) + exp_data = (6.0, 14.0, 24.0, 36.0, 50.0) + self.help_const_ff(src_data, exp_data, op) + + def test_multiply_const_vcc_one(self): + src_data = (1.0+2.0j,) + op = gr.multiply_const_vcc((2.0+3.0j,)) + exp_data = (-4.0+7.0j,) + self.help_const_cc(src_data, exp_data, op) + + def test_multiply_const_vcc_five(self): + src_data = (1.0+2.0j, 3.0+4.0j, 5.0+6.0j, 7.0+8.0j, 9.0+10.0j) + op = gr.multiply_const_vcc((11.0+12.0j, 13.0+14.0j, 15.0+16.0j, 17.0+18.0j, 19.0+20.0j)) + exp_data = (-13.0+34.0j, -17.0+94.0j, -21.0+170.0j, -25.0+262.0j, -29.0+370.0j) + self.help_const_cc(src_data, exp_data, op) + + +if __name__ == '__main__': + gr_unittest.run(test_add_mult_v, "test_add_mult_v.xml") diff --git a/gr-blocks/python/qa_boolean_operators.py b/gr-blocks/python/qa_boolean_operators.py new file mode 100755 index 000000000..5572f60ac --- /dev/null +++ b/gr-blocks/python/qa_boolean_operators.py @@ -0,0 +1,195 @@ +#!/usr/bin/env python +# +# Copyright 2004,2007,2008,2010 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, gr_unittest +import blocks_swig + +class test_boolean_operators (gr_unittest.TestCase): + + def setUp (self): + self.tb = gr.top_block () + + def tearDown (self): + self.tb = None + + def help_ss (self, src_data, exp_data, op): + for s in zip (range (len (src_data)), src_data): + src = gr.vector_source_s (s[1]) + self.tb.connect (src, (op, s[0])) + dst = gr.vector_sink_s () + self.tb.connect (op, dst) + self.tb.run () + result_data = dst.data () + self.assertEqual (exp_data, result_data) + + def help_bb (self, src_data, exp_data, op): + for s in zip (range (len (src_data)), src_data): + src = gr.vector_source_b (s[1]) + self.tb.connect (src, (op, s[0])) + dst = gr.vector_sink_b () + self.tb.connect (op, dst) + self.tb.run () + result_data = dst.data () + self.assertEqual (exp_data, result_data) + + def help_ii (self, src_data, exp_data, op): + for s in zip (range (len (src_data)), src_data): + src = gr.vector_source_i (s[1]) + self.tb.connect (src, (op, s[0])) + dst = gr.vector_sink_i () + self.tb.connect (op, dst) + self.tb.run () + result_data = dst.data () + self.assertEqual (exp_data, result_data) + + def test_xor_ss (self): + src1_data = (1, 2, 3, 0x5004, 0x1150) + src2_data = (8, 2, 1 , 0x0508, 0x1105) + expected_result = (9, 0, 2, 0x550C, 0x0055) + op = blocks_swig.xor_ss () + self.help_ss ((src1_data, src2_data), + expected_result, op) + + def test_xor_bb (self): + src1_data = (1, 2, 3, 4, 0x50) + src2_data = (8, 2, 1 , 8, 0x05) + expected_result = (9, 0, 2, 0xC, 0x55) + op = blocks_swig.xor_bb () + self.help_bb ((src1_data, src2_data), + expected_result, op) + + + def test_xor_ii (self): + src1_data = (1, 2, 3, 0x5000004, 0x11000050) + src2_data = (8, 2, 1 , 0x0500008, 0x11000005) + expected_result = (9, 0, 2, 0x550000C, 0x00000055) + op = blocks_swig.xor_ii () + self.help_ii ((src1_data, src2_data), + expected_result, op) + + + def test_and_ss (self): + src1_data = (1, 2, 3, 0x5004, 0x1150) + src2_data = (8, 2, 1 , 0x0508, 0x1105) + expected_result = (0, 2, 1, 0x0000, 0x1100) + op = blocks_swig.and_ss () + self.help_ss ((src1_data, src2_data), + expected_result, op) + + def test_and_bb (self): + src1_data = (1, 2, 2, 3, 0x04, 0x50) + src2_data = (8, 2, 2, 1, 0x08, 0x05) + src3_data = (8, 2, 1, 1, 0x08, 0x05) + expected_result = (0, 2, 0, 1, 0x00, 0x00) + op = blocks_swig.and_bb () + self.help_bb ((src1_data, src2_data, src3_data), + expected_result, op) + + def test_and_ii (self): + src1_data = (1, 2, 3, 0x50005004, 0x11001150) + src2_data = (8, 2, 1 , 0x05000508, 0x11001105) + expected_result = (0, 2, 1, 0x00000000, 0x11001100) + op = blocks_swig.and_ii () + self.help_ii ((src1_data, src2_data), + expected_result, op) + + def test_and_const_ss (self): + src_data = (1, 2, 3, 0x5004, 0x1150) + expected_result = (0, 2, 2, 0x5000, 0x1100) + src = gr.vector_source_s(src_data) + op = blocks_swig.and_const_ss (0x55AA) + dst = gr.vector_sink_s() + self.tb.connect(src, op, dst) + self.tb.run() + self.assertEqual(dst.data(), expected_result) + + def test_and_const_bb (self): + src_data = (1, 2, 3, 0x50, 0x11) + expected_result = (0, 2, 2, 0x00, 0x00) + src = gr.vector_source_b(src_data) + op = blocks_swig.and_const_bb (0xAA) + dst = gr.vector_sink_b() + self.tb.connect(src, op, dst) + self.tb.run() + self.assertEqual(dst.data(), expected_result) + + + def test_and_const_ii (self): + src_data = (1, 2, 3, 0x5004, 0x1150) + expected_result = (0, 2, 2, 0x5000, 0x1100) + src = gr.vector_source_i(src_data) + op = blocks_swig.and_const_ii (0x55AA) + dst = gr.vector_sink_i() + self.tb.connect(src, op, dst) + self.tb.run() + self.assertEqual(dst.data(), expected_result) + + + def test_or_ss (self): + src1_data = (1, 2, 3, 0x5004, 0x1150) + src2_data = (8, 2, 1 , 0x0508, 0x1105) + expected_result = (9, 2, 3, 0x550C, 0x1155) + op = blocks_swig.or_ss () + self.help_ss ((src1_data, src2_data), + expected_result, op) + + def test_or_bb (self): + src1_data = (1, 2, 2, 3, 0x04, 0x50) + src2_data = (8, 2, 2, 1 , 0x08, 0x05) + src3_data = (8, 2, 1, 1 , 0x08, 0x05) + expected_result = (9, 2, 3, 3, 0x0C, 0x55) + op = blocks_swig.or_bb () + self.help_bb ((src1_data, src2_data, src3_data), + expected_result, op) + + def test_or_ii (self): + src1_data = (1, 2, 3, 0x50005004, 0x11001150) + src2_data = (8, 2, 1 , 0x05000508, 0x11001105) + expected_result = (9, 2, 3, 0x5500550C, 0x11001155) + op = blocks_swig.or_ii () + self.help_ii ((src1_data, src2_data), + expected_result, op) + + def test_not_ss (self): + src1_data = (1, 2, 3, 0x5004, 0x1150) + expected_result = (~1, ~2, ~3, ~0x5004, ~0x1150) + op = blocks_swig.not_ss () + self.help_ss ((((src1_data),)), + expected_result, op) + + def test_not_bb (self): + src1_data = (1, 2, 2, 3, 0x04, 0x50) + expected_result = (0xFE, 0xFD, 0xFD, 0xFC, 0xFB, 0xAF) + op = blocks_swig.not_bb () + self.help_bb (((src1_data), ), + expected_result, op) + + def test_not_ii (self): + src1_data = (1, 2, 3, 0x50005004, 0x11001150) + expected_result = (~1 , ~2, ~3, ~0x50005004, ~0x11001150) + op = blocks_swig.not_ii () + self.help_ii (((src1_data),), + expected_result, op) + + +if __name__ == '__main__': + gr_unittest.run(test_boolean_operators, "test_boolean_operators.xml") diff --git a/gr-blocks/python/qa_conjugate.py b/gr-blocks/python/qa_conjugate.py new file mode 100644 index 000000000..1808aa9c0 --- /dev/null +++ b/gr-blocks/python/qa_conjugate.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python +# +# Copyright 2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, gr_unittest +import blocks_swig + +class test_conjugate (gr_unittest.TestCase): + + def setUp (self): + self.tb = gr.top_block () + + def tearDown (self): + self.tb = None + + def test_000 (self): + src_data = (-2-2j, -1-1j, -2+2j, -1+1j, + 2-2j, 1-1j, 2+2j, 1+1j, + 0+0j) + + exp_data = (-2+2j, -1+1j, -2-2j, -1-1j, + 2+2j, 1+1j, 2-2j, 1-1j, + 0-0j) + + src = gr.vector_source_c(src_data) + op = blocks_swig.conjugate_cc () + dst = gr.vector_sink_c () + + self.tb.connect(src, op) + self.tb.connect(op, dst) + self.tb.run() + result_data = dst.data () + self.assertEqual (exp_data, result_data) + +if __name__ == '__main__': + gr_unittest.run(test_conjugate, "test_conjugate.xml") diff --git a/gr-blocks/python/qa_file_metadata.py b/gr-blocks/python/qa_file_metadata.py new file mode 100644 index 000000000..29ed0d1c8 --- /dev/null +++ b/gr-blocks/python/qa_file_metadata.py @@ -0,0 +1,202 @@ +#!/usr/bin/env python +# +# Copyright 2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, gr_unittest +import parse_file_metadata +import blocks_swig as blocks +import pmt +import os, math + +def sig_source_c(samp_rate, freq, amp, N): + t = map(lambda x: float(x)/samp_rate, xrange(N)) + y = map(lambda x: math.cos(2.*math.pi*freq*x) + \ + 1j*math.sin(2.*math.pi*freq*x), t) + return y + +class test_file_metadata(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_001(self): + N = 1000 + outfile = "test_out.dat" + + detached = False + samp_rate = 200000 + key = pmt.pmt_intern("samp_rate") + val = pmt.pmt_from_double(samp_rate) + extras = pmt.pmt_make_dict() + extras = pmt.pmt_dict_add(extras, key, val) + extras_str = pmt.pmt_serialize_str(extras) + + data = sig_source_c(samp_rate, 1000, 1, N) + src = gr.vector_source_c(data) + fsnk = blocks.file_meta_sink(gr.sizeof_gr_complex, outfile, + samp_rate, 1, + blocks.GR_FILE_FLOAT, True, + 1000000, extras_str, detached) + fsnk.set_unbuffered(True) + + self.tb.connect(src, fsnk) + self.tb.run() + fsnk.close() + + handle = open(outfile, "rb") + header_str = handle.read(parse_file_metadata.HEADER_LENGTH) + if(len(header_str) == 0): + self.assertFalse() + + try: + header = pmt.pmt_deserialize_str(header_str) + except RuntimeError: + self.assertFalse() + + print header + info = parse_file_metadata.parse_header(header, False) + + extra_str = handle.read(info["extra_len"]) + self.assertGreater(len(extra_str), 0) + handle.close() + + try: + extra = pmt.pmt_deserialize_str(extra_str) + except RuntimeError: + self.assertFalse() + + extra_info = parse_file_metadata.parse_extra_dict(extra, info, False) + + self.assertEqual(info['rx_rate'], samp_rate) + self.assertEqual(pmt.pmt_to_double(extra_info['samp_rate']), samp_rate) + + + # Test file metadata source + src.rewind() + fsrc = blocks.file_meta_source(outfile, False) + vsnk = gr.vector_sink_c() + tsnk = gr.tag_debug(gr.sizeof_gr_complex, "QA") + ssnk = gr.vector_sink_c() + self.tb.disconnect(src, fsnk) + self.tb.connect(fsrc, vsnk) + self.tb.connect(fsrc, tsnk) + self.tb.connect(src, ssnk) + self.tb.run() + + # Test to make sure tags with 'samp_rate' and 'rx_rate' keys + # were generated and received correctly. + tags = tsnk.current_tags() + for t in tags: + if(pmt.pmt_eq(t.key, pmt.pmt_intern("samp_rate"))): + self.assertEqual(pmt.pmt_to_double(t.value), samp_rate) + elif(pmt.pmt_eq(t.key, pmt.pmt_intern("rx_rate"))): + self.assertEqual(pmt.pmt_to_double(t.value), samp_rate) + + # Test that the data portion was extracted and received correctly. + self.assertComplexTuplesAlmostEqual(vsnk.data(), ssnk.data(), 5) + + os.remove(outfile) + + def test_002(self): + N = 1000 + outfile = "test_out.dat" + outfile_hdr = "test_out.dat.hdr" + + detached = True + samp_rate = 200000 + key = pmt.pmt_intern("samp_rate") + val = pmt.pmt_from_double(samp_rate) + extras = pmt.pmt_make_dict() + extras = pmt.pmt_dict_add(extras, key, val) + extras_str = pmt.pmt_serialize_str(extras) + + data = sig_source_c(samp_rate, 1000, 1, N) + src = gr.vector_source_c(data) + fsnk = blocks.file_meta_sink(gr.sizeof_gr_complex, outfile, + samp_rate, 1, + blocks.GR_FILE_FLOAT, True, + 1000000, extras_str, detached) + fsnk.set_unbuffered(True) + + self.tb.connect(src, fsnk) + self.tb.run() + fsnk.close() + + # Open detached header for reading + handle = open(outfile_hdr, "rb") + header_str = handle.read(parse_file_metadata.HEADER_LENGTH) + if(len(header_str) == 0): + self.assertFalse() + + try: + header = pmt.pmt_deserialize_str(header_str) + except RuntimeError: + self.assertFalse() + + info = parse_file_metadata.parse_header(header, False) + + extra_str = handle.read(info["extra_len"]) + self.assertGreater(len(extra_str), 0) + handle.close() + + try: + extra = pmt.pmt_deserialize_str(extra_str) + except RuntimeError: + self.assertFalse() + + extra_info = parse_file_metadata.parse_extra_dict(extra, info, False) + + self.assertEqual(info['rx_rate'], samp_rate) + self.assertEqual(pmt.pmt_to_double(extra_info['samp_rate']), samp_rate) + + + # Test file metadata source + src.rewind() + fsrc = blocks.file_meta_source(outfile, False, detached, outfile_hdr) + vsnk = gr.vector_sink_c() + tsnk = gr.tag_debug(gr.sizeof_gr_complex, "QA") + ssnk = gr.vector_sink_c() + self.tb.disconnect(src, fsnk) + self.tb.connect(fsrc, vsnk) + self.tb.connect(fsrc, tsnk) + self.tb.connect(src, ssnk) + self.tb.run() + + # Test to make sure tags with 'samp_rate' and 'rx_rate' keys + # were generated and received correctly. + tags = tsnk.current_tags() + for t in tags: + if(pmt.pmt_eq(t.key, pmt.pmt_intern("samp_rate"))): + self.assertEqual(pmt.pmt_to_double(t.value), samp_rate) + elif(pmt.pmt_eq(t.key, pmt.pmt_intern("rx_rate"))): + self.assertEqual(pmt.pmt_to_double(t.value), samp_rate) + + # Test that the data portion was extracted and received correctly. + self.assertComplexTuplesAlmostEqual(vsnk.data(), ssnk.data(), 5) + + os.remove(outfile) + os.remove(outfile_hdr) + +if __name__ == '__main__': + gr_unittest.run(test_file_metadata, "test_file_metadata.xml") diff --git a/gr-blocks/python/qa_integrate.py b/gr-blocks/python/qa_integrate.py new file mode 100755 index 000000000..c404f1b30 --- /dev/null +++ b/gr-blocks/python/qa_integrate.py @@ -0,0 +1,76 @@ +#!/usr/bin/env python +# +# Copyright 2008,2010 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, gr_unittest +import blocks_swig +import math + +class test_integrate (gr_unittest.TestCase): + + def setUp (self): + self.tb = gr.top_block () + + def tearDown (self): + self.tb = None + + def test_000_ss(self): + src_data = (1, 2, 3, 4, 5, 6) + dst_data = (6, 15) + src = gr.vector_source_s(src_data) + itg = blocks_swig.integrate_ss(3) + dst = gr.vector_sink_s() + self.tb.connect(src, itg, dst) + self.tb.run() + self.assertEqual(dst_data, dst.data()) + + def test_001_ii(self): + src_data = (1, 2, 3, 4, 5, 6) + dst_data = (6, 15) + src = gr.vector_source_i(src_data) + itg = blocks_swig.integrate_ii(3) + dst = gr.vector_sink_i() + self.tb.connect(src, itg, dst) + self.tb.run() + self.assertEqual(dst_data, dst.data()) + + def test_002_ff(self): + src_data = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0] + dst_data = [6.0, 15.0] + src = gr.vector_source_f(src_data) + itg = blocks_swig.integrate_ff(3) + dst = gr.vector_sink_f() + self.tb.connect(src, itg, dst) + self.tb.run() + self.assertFloatTuplesAlmostEqual(dst_data, dst.data(), 6) + + def test_003_cc(self): + src_data = [1.0+1.0j, 2.0+2.0j, 3.0+3.0j, 4.0+4.0j, 5.0+5.0j, 6.0+6.0j] + dst_data = [6.0+6.0j, 15.0+15.0j] + src = gr.vector_source_c(src_data) + itg = blocks_swig.integrate_cc(3) + dst = gr.vector_sink_c() + self.tb.connect(src, itg, dst) + self.tb.run() + self.assertComplexTuplesAlmostEqual(dst_data, dst.data(), 6) + +if __name__ == '__main__': + gr_unittest.run(test_integrate, "test_integrate.xml") diff --git a/gr-blocks/python/qa_interleave.py b/gr-blocks/python/qa_interleave.py new file mode 100755 index 000000000..376d487b1 --- /dev/null +++ b/gr-blocks/python/qa_interleave.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python +# +# Copyright 2004,2007,2010,2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, gr_unittest +import blocks_swig +import math + +class test_interleave (gr_unittest.TestCase): + + def setUp (self): + self.tb = gr.top_block () + + def tearDown (self): + self.tb = None + + def test_int_001 (self): + lenx = 64 + src0 = gr.vector_source_f (range (0, lenx, 4)) + src1 = gr.vector_source_f (range (1, lenx, 4)) + src2 = gr.vector_source_f (range (2, lenx, 4)) + src3 = gr.vector_source_f (range (3, lenx, 4)) + op = blocks_swig.interleave (gr.sizeof_float) + dst = gr.vector_sink_f () + + self.tb.connect (src0, (op, 0)) + self.tb.connect (src1, (op, 1)) + self.tb.connect (src2, (op, 2)) + self.tb.connect (src3, (op, 3)) + self.tb.connect (op, dst) + self.tb.run () + expected_result = tuple (range (lenx)) + result_data = dst.data () + self.assertFloatTuplesAlmostEqual (expected_result, result_data) + + def test_deint_001 (self): + lenx = 64 + src = gr.vector_source_f (range (lenx)) + op = blocks_swig.deinterleave (gr.sizeof_float) + dst0 = gr.vector_sink_f () + dst1 = gr.vector_sink_f () + dst2 = gr.vector_sink_f () + dst3 = gr.vector_sink_f () + + self.tb.connect (src, op) + self.tb.connect ((op, 0), dst0) + self.tb.connect ((op, 1), dst1) + self.tb.connect ((op, 2), dst2) + self.tb.connect ((op, 3), dst3) + self.tb.run () + + expected_result0 = tuple (range (0, lenx, 4)) + expected_result1 = tuple (range (1, lenx, 4)) + expected_result2 = tuple (range (2, lenx, 4)) + expected_result3 = tuple (range (3, lenx, 4)) + + self.assertFloatTuplesAlmostEqual (expected_result0, dst0.data ()) + self.assertFloatTuplesAlmostEqual (expected_result1, dst1.data ()) + self.assertFloatTuplesAlmostEqual (expected_result2, dst2.data ()) + self.assertFloatTuplesAlmostEqual (expected_result3, dst3.data ()) + +if __name__ == '__main__': + gr_unittest.run(test_interleave, "test_interleave.xml") + diff --git a/gr-blocks/python/qa_keep_m_in_n.py b/gr-blocks/python/qa_keep_m_in_n.py new file mode 100755 index 000000000..0898217ba --- /dev/null +++ b/gr-blocks/python/qa_keep_m_in_n.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python +# +# Copyright 2008,2010,2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# + +from gnuradio import gr, gr_unittest +import blocks_swig +import sys +import random + +class test_keep_m_in_n(gr_unittest.TestCase): + + def setUp(self): + pass + + def tearDown(self): + pass + + def test_001(self): + self.maxDiff = None; + tb = gr.top_block() + src = gr.vector_source_b( range(0,100) ) + + # itemsize, M, N, offset + km2 = blocks_swig.keep_m_in_n( 1, 1, 2, 0 ); + km3 = blocks_swig.keep_m_in_n( 1, 1, 3, 1 ); + km7 = blocks_swig.keep_m_in_n( 1, 1, 7, 2 ); + snk2 = gr.vector_sink_b(); + snk3 = gr.vector_sink_b(); + snk7 = gr.vector_sink_b(); + tb.connect(src,km2,snk2); + tb.connect(src,km3,snk3); + tb.connect(src,km7,snk7); + tb.run(); + + self.assertEqual(range(0,100,2), list(snk2.data())); + self.assertEqual(range(1,100,3), list(snk3.data())); + self.assertEqual(range(2,100,7), list(snk7.data())); + + +if __name__ == '__main__': + gr_unittest.run(test_keep_m_in_n, "test_keep_m_in_n.xml") + diff --git a/gr-blocks/python/qa_keep_one_in_n.py b/gr-blocks/python/qa_keep_one_in_n.py new file mode 100755 index 000000000..8c5f44b84 --- /dev/null +++ b/gr-blocks/python/qa_keep_one_in_n.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python +# +# Copyright 2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, gr_unittest +import blocks_swig + +class test_keep_one_in_n(gr_unittest.TestCase): + + def setUp (self): + self.tb = gr.top_block () + + def tearDown (self): + self.tb = None + + def test_001(self): + src_data = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) + expected_data = (5, 10) + src = gr.vector_source_b(src_data); + op = blocks_swig.keep_one_in_n(gr.sizeof_char, 5) + dst = gr.vector_sink_b() + self.tb.connect(src, op, dst) + self.tb.run() + self.assertEqual(dst.data(), expected_data) + + +if __name__ == '__main__': + gr_unittest.run(test_keep_one_in_n, "test_integrate.xml") diff --git a/gr-blocks/python/qa_multiply_conjugate.py b/gr-blocks/python/qa_multiply_conjugate.py new file mode 100644 index 000000000..f51563f85 --- /dev/null +++ b/gr-blocks/python/qa_multiply_conjugate.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python +# +# Copyright 2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, gr_unittest +import blocks_swig + +class test_multiply_conjugate (gr_unittest.TestCase): + + def setUp (self): + self.tb = gr.top_block () + + def tearDown (self): + self.tb = None + + def test_000 (self): + src_data0 = (-2-2j, -1-1j, -2+2j, -1+1j, + 2-2j, 1-1j, 2+2j, 1+1j, + 0+0j) + src_data1 = (-3-3j, -4-4j, -3+3j, -4+4j, + 3-3j, 4-4j, 3+3j, 4+4j, + 0+0j) + + exp_data = (12+0j, 8+0j, 12+0j, 8+0j, + 12+0j, 8+0j, 12+0j, 8+0j, + 0+0j) + src0 = gr.vector_source_c(src_data0) + src1 = gr.vector_source_c(src_data1) + op = blocks_swig.multiply_conjugate_cc () + dst = gr.vector_sink_c () + + self.tb.connect(src0, (op,0)) + self.tb.connect(src1, (op,1)) + self.tb.connect(op, dst) + self.tb.run() + result_data = dst.data () + self.assertEqual (exp_data, result_data) + +if __name__ == '__main__': + gr_unittest.run(test_multiply_conjugate, "test_multiply_conjugate.xml") diff --git a/gr-blocks/python/qa_nlog10.py b/gr-blocks/python/qa_nlog10.py new file mode 100755 index 000000000..cc2a3e8cc --- /dev/null +++ b/gr-blocks/python/qa_nlog10.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python +# +# Copyright 2005,2007,2010,2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, gr_unittest +import blocks_swig + +class test_nlog10(gr_unittest.TestCase): + + def setUp (self): + self.tb = gr.top_block () + + def tearDown (self): + self.tb = None + + def test_001(self): + src_data = (-10, 0, 10, 100, 1000, 10000, 100000) + expected_result = (-180, -180, 10, 20, 30, 40, 50) + src = gr.vector_source_f(src_data) + op = blocks_swig.nlog10_ff(10) + dst = gr.vector_sink_f() + self.tb.connect (src, op, dst) + self.tb.run() + result_data = dst.data() + self.assertFloatTuplesAlmostEqual (expected_result, result_data) + + +if __name__ == '__main__': + gr_unittest.run(test_nlog10, "test_nlog10.xml") + diff --git a/gr-blocks/python/qa_patterned_interleaver.py b/gr-blocks/python/qa_patterned_interleaver.py new file mode 100755 index 000000000..3cf29c917 --- /dev/null +++ b/gr-blocks/python/qa_patterned_interleaver.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python +# +# Copyright 2008,2010 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, gr_unittest +try: + import blocks_swig as blocks +except: + from gnuradio import blocks +import math + +class test_patterned_interleaver (gr_unittest.TestCase): + + def setUp (self): + self.tb = gr.top_block () + + def tearDown (self): + self.tb = None + + def test_000(self): + dst_data = [0,0,1,2,0,2,1,0]; + src0 = gr.vector_source_f(200*[0]) + src1 = gr.vector_source_f(200*[1]) + src2 = gr.vector_source_f(200*[2]) + itg = blocks.patterned_interleaver(gr.sizeof_float, dst_data) + dst = gr.vector_sink_f() + head = gr.head(gr.sizeof_float, 8); + + self.tb.connect( src0, (itg,0) ); + self.tb.connect( src1, (itg,1) ); + self.tb.connect( src2, (itg,2) ); + self.tb.connect( itg, head, dst ); + + self.tb.run() + self.assertEqual(list(dst_data), list(dst.data())) + +if __name__ == '__main__': + gr_unittest.run(test_patterned_interleaver, "test_patterned_interleaver.xml") diff --git a/gr-blocks/python/qa_pipe_fittings.py b/gr-blocks/python/qa_pipe_fittings.py new file mode 100755 index 000000000..321660d5e --- /dev/null +++ b/gr-blocks/python/qa_pipe_fittings.py @@ -0,0 +1,138 @@ +#!/usr/bin/env python +# +# Copyright 2005,2007,2010,2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, gr_unittest +import blocks_swig + +def calc_expected_result(src_data, n): + assert (len(src_data) % n) == 0 + result = [list() for x in range(n)] + #print "len(result) =", len(result) + for i in xrange(len(src_data)): + (result[i % n]).append(src_data[i]) + return [tuple(x) for x in result] + + +class test_pipe_fittings(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block () + + def tearDown(self): + self.tb = None + + def test_001(self): + """ + Test stream_to_streams. + """ + n = 8 + src_len = n * 8 + src_data = range(src_len) + + expected_results = calc_expected_result(src_data, n) + #print "expected results: ", expected_results + src = gr.vector_source_i(src_data) + op = gr.stream_to_streams(gr.sizeof_int, n) + self.tb.connect(src, op) + + dsts = [] + for i in range(n): + dst = gr.vector_sink_i() + self.tb.connect((op, i), (dst, 0)) + dsts.append(dst) + + self.tb.run() + + for d in range(n): + self.assertEqual(expected_results[d], dsts[d].data()) + + def test_002(self): + + # Test streams_to_stream (using stream_to_streams). + + n = 8 + src_len = n * 8 + src_data = tuple(range(src_len)) + expected_results = src_data + + src = gr.vector_source_i(src_data) + op1 = gr.stream_to_streams(gr.sizeof_int, n) + op2 = gr.streams_to_stream(gr.sizeof_int, n) + dst = gr.vector_sink_i() + + self.tb.connect(src, op1) + for i in range(n): + self.tb.connect((op1, i), (op2, i)) + self.tb.connect(op2, dst) + + self.tb.run() + self.assertEqual(expected_results, dst.data()) + + def test_003(self): + + #Test streams_to_vector (using stream_to_streams & vector_to_stream). + + n = 8 + src_len = n * 8 + src_data = tuple(range(src_len)) + expected_results = src_data + + src = gr.vector_source_i(src_data) + op1 = gr.stream_to_streams(gr.sizeof_int, n) + op2 = gr.streams_to_vector(gr.sizeof_int, n) + op3 = gr.vector_to_stream(gr.sizeof_int, n) + dst = gr.vector_sink_i() + + self.tb.connect(src, op1) + for i in range(n): + self.tb.connect((op1, i), (op2, i)) + self.tb.connect(op2, op3, dst) + + self.tb.run() + self.assertEqual(expected_results, dst.data()) + + def test_004(self): + + #Test vector_to_streams. + + n = 8 + src_len = n * 8 + src_data = tuple(range(src_len)) + expected_results = src_data + + src = gr.vector_source_i(src_data) + op1 = gr.stream_to_vector(gr.sizeof_int, n) + op2 = gr.vector_to_streams(gr.sizeof_int, n) + op3 = gr.streams_to_stream(gr.sizeof_int, n) + dst = gr.vector_sink_i() + + self.tb.connect(src, op1, op2) + for i in range(n): + self.tb.connect((op2, i), (op3, i)) + self.tb.connect(op3, dst) + + self.tb.run() + self.assertEqual(expected_results, dst.data()) + + +if __name__ == '__main__': + gr_unittest.run(test_pipe_fittings, "test_pipe_fittings.xml") diff --git a/gr-blocks/python/qa_repeat.py b/gr-blocks/python/qa_repeat.py new file mode 100755 index 000000000..69fb3ef72 --- /dev/null +++ b/gr-blocks/python/qa_repeat.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python +# +# Copyright 2008,2010,2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, gr_unittest +import blocks_swig +import math + +class test_repeat (gr_unittest.TestCase): + + def setUp (self): + self.tb = gr.top_block () + + def tearDown (self): + self.tb = None + + def test_001_float(self): + src_data = [n*1.0 for n in range(100)]; + dst_data = [] + for n in range(100): + dst_data += [1.0*n, 1.0*n, 1.0*n] + + src = gr.vector_source_f(src_data) + rpt = blocks_swig.repeat(gr.sizeof_float, 3) + dst = gr.vector_sink_f() + self.tb.connect(src, rpt, dst) + self.tb.run() + self.assertFloatTuplesAlmostEqual(dst_data, dst.data(), 6) + +if __name__ == '__main__': + gr_unittest.run(test_repeat, "test_repeat.xml") diff --git a/gr-blocks/python/qa_stream_mux.py b/gr-blocks/python/qa_stream_mux.py new file mode 100755 index 000000000..f21a9bbbc --- /dev/null +++ b/gr-blocks/python/qa_stream_mux.py @@ -0,0 +1,169 @@ +#!/usr/bin/env python +# +# Copyright 2004,2005,2007,2010,2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, gr_unittest +import blocks_swig + +class test_stream_mux (gr_unittest.TestCase): + + def setUp (self): + self.tb = gr.top_block () + + def tearDown (self): + self.tb = None + + def help_stream_2ff(self, N, stream_sizes): + v0 = gr.vector_source_f(N*[1,], False) + v1 = gr.vector_source_f(N*[2,], False) + + mux = blocks_swig.stream_mux(gr.sizeof_float, stream_sizes) + + dst = gr.vector_sink_f () + + self.tb.connect (v0, (mux,0)) + self.tb.connect (v1, (mux,1)) + self.tb.connect (mux, dst) + self.tb.run () + + return dst.data () + + def help_stream_ramp_2ff(self, N, stream_sizes): + r1 = range(N) + r2 = range(N) + r2.reverse() + + v0 = gr.vector_source_f(r1, False) + v1 = gr.vector_source_f(r2, False) + + mux = blocks_swig.stream_mux(gr.sizeof_float, stream_sizes) + + dst = gr.vector_sink_f () + + self.tb.connect (v0, (mux,0)) + self.tb.connect (v1, (mux,1)) + self.tb.connect (mux, dst) + self.tb.run () + + return dst.data () + + def test_stream_2NN_ff(self): + N = 40 + stream_sizes = [10, 10] + result_data = self.help_stream_2ff(N, stream_sizes) + + exp_data = (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, + 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, + 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, + 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, + 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, + 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, + 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, + 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0) + self.assertEqual (exp_data, result_data) + + def test_stream_ramp_2NN_ff(self): + N = 40 + stream_sizes = [10, 10] + result_data = self.help_stream_ramp_2ff(N, stream_sizes) + + exp_data = ( 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, + 39.0, 38.0, 37.0, 36.0, 35.0, 34.0, 33.0, 32.0, 31.0, 30.0, + 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, + 29.0, 28.0, 27.0, 26.0, 25.0, 24.0, 23.0, 22.0, 21.0, 20.0, + 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, + 19.0, 18.0, 17.0, 16.0, 15.0, 14.0, 13.0, 12.0, 11.0, 10.0, + 30.0, 31.0, 32.0, 33.0, 34.0, 35.0, 36.0, 37.0, 38.0, 39.0, + 9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0, 0.0) + self.assertEqual (exp_data, result_data) + + def test_stream_2NM_ff(self): + N = 40 + stream_sizes = [7, 9] + self.help_stream_2ff(N, stream_sizes) + + result_data = self.help_stream_2ff(N, stream_sizes) + + exp_data = (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, + 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, + 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, + 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, + 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, + 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, + 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, + 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, + 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, + 2.0, 2.0, 2.0, 2.0) + + self.assertEqual (exp_data, result_data) + + + def test_stream_2MN_ff(self): + N = 37 + stream_sizes = [7, 9] + self.help_stream_2ff(N, stream_sizes) + + result_data = self.help_stream_2ff(N, stream_sizes) + + exp_data = (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, + 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, + 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, + 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, + 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, + 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, + 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, + 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, + 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, + 2.0) + + self.assertEqual (exp_data, result_data) + + def test_stream_2N0_ff(self): + N = 30 + stream_sizes = [7, 0] + self.help_stream_2ff(N, stream_sizes) + + result_data = self.help_stream_2ff(N, stream_sizes) + + exp_data = (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, + 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, + 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, + 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, + 1.0, 1.0) + + self.assertEqual (exp_data, result_data) + + def test_stream_20N_ff(self): + N = 30 + stream_sizes = [0, 9] + self.help_stream_2ff(N, stream_sizes) + + result_data = self.help_stream_2ff(N, stream_sizes) + + exp_data = (2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, + 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, + 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, + 2.0, 2.0, 2.0) + + self.assertEqual (exp_data, result_data) + +if __name__ == '__main__': + gr_unittest.run(test_stream_mux, "test_stream_mux.xml") diff --git a/gr-blocks/python/qa_type_conversions.py b/gr-blocks/python/qa_type_conversions.py new file mode 100755 index 000000000..eb1b42b63 --- /dev/null +++ b/gr-blocks/python/qa_type_conversions.py @@ -0,0 +1,316 @@ +#!/usr/bin/env python +# +# Copyright 2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, gr_unittest +import blocks_swig +from math import sqrt, atan2 + +class test_type_conversions(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_char_to_float_identity(self): + src_data = (1, 2, 3, 4, 5) + expected_data = (1.0, 2.0, 3.0, 4.0, 5.0) + src = gr.vector_source_b(src_data) + op = blocks_swig.char_to_float() + dst = gr.vector_sink_f() + self.tb.connect(src, op, dst) + self.tb.run() + self.assertFloatTuplesAlmostEqual(expected_data, dst.data()) + + def test_char_to_float_scale(self): + src_data = (1, 2, 3, 4, 5) + expected_data = (0.5, 1.0, 1.5, 2.0, 2.5) + src = gr.vector_source_b(src_data) + op = blocks_swig.char_to_float(scale=2.0) + dst = gr.vector_sink_f() + self.tb.connect(src, op, dst) + self.tb.run() + self.assertFloatTuplesAlmostEqual(expected_data, dst.data()) + + def test_char_to_short(self): + src_data = (1, 2, 3, 4, 5) + expected_data = (256, 512, 768, 1024, 1280) + src = gr.vector_source_b(src_data) + op = blocks_swig.char_to_short() + dst = gr.vector_sink_s() + self.tb.connect(src, op, dst) + self.tb.run() + self.assertEqual(expected_data, dst.data()) + + def test_complex_to_interleaved_short(self): + src_data = (1+2j, 3+4j, 5+6j, 7+8j, 9+10j) + expected_data = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) + src = gr.vector_source_c(src_data) + op = blocks_swig.complex_to_interleaved_short() + dst = gr.vector_sink_s() + self.tb.connect(src, op, dst) + self.tb.run() + self.assertEqual(expected_data, dst.data()) + + def test_complex_to_float_1(self): + src_data = (1+2j, 3+4j, 5+6j, 7+8j, 9+10j) + expected_data = (1.0, 3.0, 5.0, 7.0, 9.0) + src = gr.vector_source_c(src_data) + op = blocks_swig.complex_to_float() + dst = gr.vector_sink_f() + self.tb.connect(src, op, dst) + self.tb.run() + self.assertFloatTuplesAlmostEqual(expected_data, dst.data()) + + def test_complex_to_float_2(self): + src_data = (1+2j, 3+4j, 5+6j, 7+8j, 9+10j) + expected_data1 = (1.0, 3.0, 5.0, 7.0, 9.0) + expected_data2 = (2.0, 4.0, 6.0, 8.0, 10.0) + src = gr.vector_source_c(src_data) + op = blocks_swig.complex_to_float() + dst1 = gr.vector_sink_f() + dst2 = gr.vector_sink_f() + self.tb.connect(src, op) + self.tb.connect((op, 0), dst1) + self.tb.connect((op, 1), dst2) + self.tb.run() + self.assertFloatTuplesAlmostEqual(expected_data1, dst1.data()) + self.assertFloatTuplesAlmostEqual(expected_data2, dst2.data()) + + def test_complex_to_real(self): + src_data = (1+2j, 3+4j, 5+6j, 7+8j, 9+10j) + expected_data = (1.0, 3.0, 5.0, 7.0, 9.0) + src = gr.vector_source_c(src_data) + op = blocks_swig.complex_to_real() + dst = gr.vector_sink_f() + self.tb.connect(src, op, dst) + self.tb.run() + self.assertFloatTuplesAlmostEqual(expected_data, dst.data()) + + def test_complex_to_imag(self): + src_data = (1+2j, 3+4j, 5+6j, 7+8j, 9+10j) + expected_data = (2.0, 4.0, 6.0, 8.0, 10.0) + src = gr.vector_source_c(src_data) + op = blocks_swig.complex_to_imag() + dst = gr.vector_sink_f() + self.tb.connect(src, op, dst) + self.tb.run() + self.assertFloatTuplesAlmostEqual(expected_data, dst.data()) + + def test_complex_to_mag(self): + src_data = (1+2j, 3-4j, 5+6j, 7-8j, -9+10j) + expected_data = (sqrt(5), sqrt(25), sqrt(61), sqrt(113), sqrt(181)) + src = gr.vector_source_c(src_data) + op = blocks_swig.complex_to_mag() + dst = gr.vector_sink_f() + self.tb.connect(src, op, dst) + self.tb.run() + self.assertFloatTuplesAlmostEqual(expected_data, dst.data(), 5) + + def test_complex_to_mag_squared(self): + src_data = (1+2j, 3-4j, 5+6j, 7-8j, -9+10j) + expected_data = (5.0, 25.0, 61.0, 113.0, 181.0) + src = gr.vector_source_c(src_data) + op = blocks_swig.complex_to_mag_squared() + dst = gr.vector_sink_f() + self.tb.connect(src, op, dst) + self.tb.run() + self.assertFloatTuplesAlmostEqual(expected_data, dst.data()) + + def test_complex_to_arg(self): + src_data = (1+2j, 3-4j, 5+6j, 7-8j, -9+10j) + expected_data = (atan2(2, 1), atan2(-4,3), atan2(6, 5), atan2(-8, 7), atan2(10,-9)) + src = gr.vector_source_c(src_data) + op = blocks_swig.complex_to_arg() + dst = gr.vector_sink_f() + self.tb.connect(src, op, dst) + self.tb.run() + self.assertFloatTuplesAlmostEqual(expected_data, dst.data(), 2) + + def test_float_to_char_identity(self): + src_data = (1.0, 2.0, 3.0, 4.0, 5.0) + expected_data = (1, 2, 3, 4, 5) + src = gr.vector_source_f(src_data) + op = blocks_swig.float_to_char() + dst = gr.vector_sink_b() + self.tb.connect(src, op, dst) + self.tb.run() + self.assertEqual(expected_data, dst.data()) + + def test_float_to_char_scale(self): + src_data = (1.0, 2.0, 3.0, 4.0, 5.0) + expected_data = (5, 10, 15, 20, 25) + src = gr.vector_source_f(src_data) + op = blocks_swig.float_to_char(1, 5) + dst = gr.vector_sink_b() + self.tb.connect(src, op, dst) + self.tb.run() + self.assertEqual(expected_data, dst.data()) + + def test_float_to_complex_1(self): + src_data = (1.0, 3.0, 5.0, 7.0, 9.0) + expected_data = (1+0j, 3+0j, 5+0j, 7+0j, 9+0j) + src = gr.vector_source_f(src_data) + op = blocks_swig.float_to_complex() + dst = gr.vector_sink_c() + self.tb.connect(src, op, dst) + self.tb.run() + self.assertFloatTuplesAlmostEqual(expected_data, dst.data()) + + def test_float_to_complex_2(self): + src1_data = (1.0, 3.0, 5.0, 7.0, 9.0) + src2_data = (2.0, 4.0, 6.0, 8.0, 10.0) + expected_data = (1+2j, 3+4j, 5+6j, 7+8j, 9+10j) + src1 = gr.vector_source_f(src1_data) + src2 = gr.vector_source_f(src2_data) + op = blocks_swig.float_to_complex() + dst = gr.vector_sink_c() + self.tb.connect(src1, (op, 0)) + self.tb.connect(src2, (op, 1)) + self.tb.connect(op, dst) + self.tb.run() + self.assertFloatTuplesAlmostEqual(expected_data, dst.data()) + + def test_float_to_int_identity(self): + src_data = (1.0, 2.0, 3.0, 4.0, 5.0) + expected_data = (1, 2, 3, 4, 5) + src = gr.vector_source_f(src_data) + op = blocks_swig.float_to_int() + dst = gr.vector_sink_i() + self.tb.connect(src, op, dst) + self.tb.run() + self.assertEqual(expected_data, dst.data()) + + def test_float_to_int_scale(self): + src_data = (1.0, 2.0, 3.0, 4.0, 5.0) + expected_data = (5, 10, 15, 20, 25) + src = gr.vector_source_f(src_data) + op = blocks_swig.float_to_int(1, 5) + dst = gr.vector_sink_i() + self.tb.connect(src, op, dst) + self.tb.run() + self.assertEqual(expected_data, dst.data()) + + def test_float_to_short_identity(self): + src_data = (1.0, 2.0, 3.0, 4.0, 5.0) + expected_data = (1, 2, 3, 4, 5) + src = gr.vector_source_f(src_data) + op = blocks_swig.float_to_short() + dst = gr.vector_sink_s() + self.tb.connect(src, op, dst) + self.tb.run() + self.assertEqual(expected_data, dst.data()) + + def test_float_to_short_scale(self): + src_data = (1.0, 2.0, 3.0, 4.0, 5.0) + expected_data = (5, 10, 15, 20, 25) + src = gr.vector_source_f(src_data) + op = blocks_swig.float_to_short(1, 5) + dst = gr.vector_sink_s() + self.tb.connect(src, op, dst) + self.tb.run() + self.assertEqual(expected_data, dst.data()) + + def test_float_to_uchar(self): + src_data = (1.0, -2.0, 3.0, -4.0, 256.0) + expected_data = (1, 0, 3, 0, 255) + src = gr.vector_source_f(src_data) + op = blocks_swig.float_to_uchar() + dst = gr.vector_sink_b() + self.tb.connect(src, op, dst) + self.tb.run() + self.assertEqual(expected_data, dst.data()) + + def test_int_to_float_identity(self): + src_data = (1, 2, 3, 4, 5) + expected_data = (1.0, 2.0, 3.0, 4.0, 5.0) + src = gr.vector_source_i(src_data) + op = blocks_swig.int_to_float() + dst = gr.vector_sink_f() + self.tb.connect(src, op, dst) + self.tb.run() + self.assertFloatTuplesAlmostEqual(expected_data, dst.data()) + + def test_int_to_float_scale(self): + src_data = (1, 2, 3, 4, 5) + expected_data = (0.2, 0.4, 0.6, 0.8, 1.0) + src = gr.vector_source_i(src_data) + op = blocks_swig.int_to_float(1, 5) + dst = gr.vector_sink_f() + self.tb.connect(src, op, dst) + self.tb.run() + self.assertFloatTuplesAlmostEqual(expected_data, dst.data()) + + def test_interleaved_short_to_complex(self): + src_data = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) + expected_data = (1+2j, 3+4j, 5+6j, 7+8j, 9+10j) + src = gr.vector_source_s(src_data) + op = blocks_swig.interleaved_short_to_complex() + dst = gr.vector_sink_c() + self.tb.connect(src, op, dst) + self.tb.run() + self.assertEqual(expected_data, dst.data()) + + def test_short_to_char(self): + src_data = (256, 512, 768, 1024, 1280) + expected_data = (1, 2, 3, 4, 5) + src = gr.vector_source_s(src_data) + op = blocks_swig.short_to_char() + dst = gr.vector_sink_b() + self.tb.connect(src, op, dst) + self.tb.run() + self.assertEqual(expected_data, dst.data()) + + def test_short_to_float_identity(self): + src_data = (1, 2, 3, 4, 5) + expected_data = (1.0, 2.0, 3.0, 4.0, 5.0) + src = gr.vector_source_s(src_data) + op = blocks_swig.short_to_float() + dst = gr.vector_sink_f() + self.tb.connect(src, op, dst) + self.tb.run() + self.assertEqual(expected_data, dst.data()) + + def test_short_to_float_scale(self): + src_data = (5, 10, 15, 20, 25) + expected_data = (1.0, 2.0, 3.0, 4.0, 5.0) + src = gr.vector_source_s(src_data) + op = blocks_swig.short_to_float(1, 5) + dst = gr.vector_sink_f() + self.tb.connect(src, op, dst) + self.tb.run() + self.assertEqual(expected_data, dst.data()) + + def test_uchar_to_float(self): + src_data = (1, 2, 3, 4, 5) + expected_data = (1.0, 2.0, 3.0, 4.0, 5.0) + src = gr.vector_source_b(src_data) + op = blocks_swig.uchar_to_float() + dst = gr.vector_sink_f() + self.tb.connect(src, op, dst) + self.tb.run() + self.assertEqual(expected_data, dst.data()) + + +if __name__ == '__main__': + gr_unittest.run(test_type_conversions, "test_type_conversions.xml") diff --git a/gr-blocks/swig/CMakeLists.txt b/gr-blocks/swig/CMakeLists.txt new file mode 100644 index 000000000..fb29789f0 --- /dev/null +++ b/gr-blocks/swig/CMakeLists.txt @@ -0,0 +1,51 @@ +# Copyright 2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. + +######################################################################## +# Setup swig generation +######################################################################## +include(GrPython) +include(GrSwig) + +set(GR_SWIG_INCLUDE_DIRS + ${GR_BLOCKS_INCLUDE_DIRS} + ${GNURADIO_CORE_SWIG_INCLUDE_DIRS} + ${CMAKE_CURRENT_BINARY_DIR}/../include +) + +set(GR_SWIG_DOC_FILE ${CMAKE_CURRENT_BINARY_DIR}/blocks_swig_doc.i) +set(GR_SWIG_DOC_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/../lib) + +set(GR_SWIG_LIBRARIES gnuradio-blocks) + +GR_SWIG_MAKE(blocks_swig blocks_swig.i) + +GR_SWIG_INSTALL( + TARGETS blocks_swig + DESTINATION ${GR_PYTHON_DIR}/gnuradio/blocks + COMPONENT "blocks_python" +) + +install( + FILES + blocks_swig.i + ${CMAKE_CURRENT_BINARY_DIR}/blocks_swig_doc.i + DESTINATION ${GR_INCLUDE_DIR}/gnuradio/swig + COMPONENT "blocks_swig" +) diff --git a/gr-blocks/swig/blocks_swig.i b/gr-blocks/swig/blocks_swig.i new file mode 100644 index 000000000..53eea818f --- /dev/null +++ b/gr-blocks/swig/blocks_swig.i @@ -0,0 +1,300 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#define BLOCKS_API + +%include "gnuradio.i" + +//load generated python docstrings +%include "blocks_swig_doc.i" + +%{ +#include "blocks/add_ff.h" +#include "blocks/add_ss.h" +#include "blocks/add_ii.h" +#include "blocks/add_cc.h" +#include "blocks/add_const_ff.h" +#include "blocks/add_const_ss.h" +#include "blocks/add_const_ii.h" +#include "blocks/add_const_cc.h" +#include "blocks/add_const_vff.h" +#include "blocks/add_const_vss.h" +#include "blocks/add_const_vii.h" +#include "blocks/add_const_vcc.h" +#include "blocks/and_bb.h" +#include "blocks/and_ss.h" +#include "blocks/and_ii.h" +#include "blocks/and_const_bb.h" +#include "blocks/and_const_ss.h" +#include "blocks/and_const_ii.h" +#include "blocks/char_to_float.h" +#include "blocks/char_to_short.h" +#include "blocks/complex_to_interleaved_short.h" +#include "blocks/complex_to_float.h" +#include "blocks/complex_to_real.h" +#include "blocks/complex_to_imag.h" +#include "blocks/complex_to_mag.h" +#include "blocks/complex_to_mag_squared.h" +#include "blocks/complex_to_arg.h" +#include "blocks/conjugate_cc.h" +#include "blocks/deinterleave.h" +#include "blocks/divide_ff.h" +#include "blocks/divide_ss.h" +#include "blocks/divide_ii.h" +#include "blocks/divide_cc.h" +#include "blocks/file_source.h" +#include "blocks/file_meta_sink.h" +#include "blocks/file_meta_source.h" +#include "blocks/float_to_char.h" +#include "blocks/float_to_complex.h" +#include "blocks/float_to_int.h" +#include "blocks/float_to_short.h" +#include "blocks/float_to_uchar.h" +#include "blocks/int_to_float.h" +#include "blocks/integrate_ss.h" +#include "blocks/integrate_ii.h" +#include "blocks/integrate_ff.h" +#include "blocks/integrate_cc.h" +#include "blocks/interleave.h" +#include "blocks/interleaved_short_to_complex.h" +#include "blocks/keep_m_in_n.h" +#include "blocks/keep_one_in_n.h" +#include "blocks/multiply_ss.h" +#include "blocks/multiply_ii.h" +#include "blocks/multiply_ff.h" +#include "blocks/multiply_cc.h" +#include "blocks/multiply_conjugate_cc.h" +#include "blocks/multiply_const_ss.h" +#include "blocks/multiply_const_ii.h" +#include "blocks/multiply_const_ff.h" +#include "blocks/multiply_const_cc.h" +#include "blocks/multiply_const_vss.h" +#include "blocks/multiply_const_vii.h" +#include "blocks/multiply_const_vff.h" +#include "blocks/multiply_const_vcc.h" +#include "blocks/nlog10_ff.h" +#include "blocks/not_bb.h" +#include "blocks/not_ss.h" +#include "blocks/not_ii.h" +#include "blocks/patterned_interleaver.h" +#include "blocks/or_bb.h" +#include "blocks/or_ss.h" +#include "blocks/or_ii.h" +#include "blocks/repeat.h" +#include "blocks/short_to_char.h" +#include "blocks/short_to_float.h" +#include "blocks/stream_mux.h" +#include "blocks/stream_to_streams.h" +#include "blocks/stream_to_vector.h" +#include "blocks/streams_to_stream.h" +#include "blocks/streams_to_vector.h" +#include "blocks/sub_ff.h" +#include "blocks/sub_ss.h" +#include "blocks/sub_ii.h" +#include "blocks/sub_cc.h" +#include "blocks/uchar_to_float.h" +#include "blocks/vector_to_stream.h" +#include "blocks/vector_to_streams.h" +#include "blocks/xor_bb.h" +#include "blocks/xor_ss.h" +#include "blocks/xor_ii.h" +%} + +%include "blocks/add_ff.h" +%include "blocks/add_ss.h" +%include "blocks/add_ii.h" +%include "blocks/add_cc.h" +%include "blocks/add_const_ff.h" +%include "blocks/add_const_ss.h" +%include "blocks/add_const_ii.h" +%include "blocks/add_const_cc.h" +%include "blocks/add_const_vff.h" +%include "blocks/add_const_vss.h" +%include "blocks/add_const_vii.h" +%include "blocks/add_const_vcc.h" +%include "blocks/and_bb.h" +%include "blocks/and_ss.h" +%include "blocks/and_ii.h" +%include "blocks/and_const_bb.h" +%include "blocks/and_const_ss.h" +%include "blocks/and_const_ii.h" +%include "blocks/char_to_float.h" +%include "blocks/char_to_short.h" +%include "blocks/complex_to_interleaved_short.h" +%include "blocks/complex_to_float.h" +%include "blocks/complex_to_real.h" +%include "blocks/complex_to_imag.h" +%include "blocks/complex_to_mag.h" +%include "blocks/complex_to_mag_squared.h" +%include "blocks/complex_to_arg.h" +%include "blocks/conjugate_cc.h" +%include "blocks/deinterleave.h" +%include "blocks/file_source.h" +%include "blocks/file_meta_sink.h" +%include "blocks/file_meta_source.h" +%include "blocks/divide_ff.h" +%include "blocks/divide_ss.h" +%include "blocks/divide_ii.h" +%include "blocks/divide_cc.h" +%include "blocks/float_to_char.h" +%include "blocks/float_to_complex.h" +%include "blocks/float_to_int.h" +%include "blocks/float_to_short.h" +%include "blocks/float_to_uchar.h" +%include "blocks/int_to_float.h" +%include "blocks/integrate_ss.h" +%include "blocks/integrate_ii.h" +%include "blocks/integrate_ff.h" +%include "blocks/integrate_cc.h" +%include "blocks/interleave.h" +%include "blocks/interleaved_short_to_complex.h" +%include "blocks/keep_m_in_n.h" +%include "blocks/keep_one_in_n.h" +%include "blocks/multiply_ss.h" +%include "blocks/multiply_ii.h" +%include "blocks/multiply_ff.h" +%include "blocks/multiply_cc.h" +%include "blocks/multiply_conjugate_cc.h" +%include "blocks/multiply_const_ss.h" +%include "blocks/multiply_const_ii.h" +%include "blocks/multiply_const_ff.h" +%include "blocks/multiply_const_cc.h" +%include "blocks/multiply_const_vss.h" +%include "blocks/multiply_const_vii.h" +%include "blocks/multiply_const_vff.h" +%include "blocks/multiply_const_vcc.h" +%include "blocks/nlog10_ff.h" +%include "blocks/not_bb.h" +%include "blocks/not_ss.h" +%include "blocks/not_ii.h" +%include "blocks/patterned_interleaver.h" +%include "blocks/or_bb.h" +%include "blocks/or_ss.h" +%include "blocks/or_ii.h" +%include "blocks/repeat.h" +%include "blocks/short_to_char.h" +%include "blocks/short_to_float.h" +%include "blocks/stream_mux.h" +%include "blocks/stream_to_streams.h" +%include "blocks/stream_to_vector.h" +%include "blocks/streams_to_stream.h" +%include "blocks/streams_to_vector.h" +%include "blocks/sub_ff.h" +%include "blocks/sub_ss.h" +%include "blocks/sub_ii.h" +%include "blocks/sub_cc.h" +%include "blocks/uchar_to_float.h" +%include "blocks/vector_to_stream.h" +%include "blocks/vector_to_streams.h" +%include "blocks/xor_bb.h" +%include "blocks/xor_ss.h" +%include "blocks/xor_ii.h" + +GR_SWIG_BLOCK_MAGIC2(blocks, add_ff); +GR_SWIG_BLOCK_MAGIC2(blocks, add_ss); +GR_SWIG_BLOCK_MAGIC2(blocks, add_ii); +GR_SWIG_BLOCK_MAGIC2(blocks, add_cc); +GR_SWIG_BLOCK_MAGIC2(blocks, add_const_ff); +GR_SWIG_BLOCK_MAGIC2(blocks, add_const_ss); +GR_SWIG_BLOCK_MAGIC2(blocks, add_const_ii); +GR_SWIG_BLOCK_MAGIC2(blocks, add_const_cc); +GR_SWIG_BLOCK_MAGIC2(blocks, add_const_vff); +GR_SWIG_BLOCK_MAGIC2(blocks, add_const_vss); +GR_SWIG_BLOCK_MAGIC2(blocks, add_const_vii); +GR_SWIG_BLOCK_MAGIC2(blocks, add_const_vcc); +GR_SWIG_BLOCK_MAGIC2(blocks, and_bb); +GR_SWIG_BLOCK_MAGIC2(blocks, and_ss); +GR_SWIG_BLOCK_MAGIC2(blocks, and_ii); +GR_SWIG_BLOCK_MAGIC2(blocks, and_const_bb); +GR_SWIG_BLOCK_MAGIC2(blocks, and_const_ss); +GR_SWIG_BLOCK_MAGIC2(blocks, and_const_ii); +GR_SWIG_BLOCK_MAGIC2(blocks, char_to_float); +GR_SWIG_BLOCK_MAGIC2(blocks, char_to_short); +GR_SWIG_BLOCK_MAGIC2(blocks, complex_to_interleaved_short); +GR_SWIG_BLOCK_MAGIC2(blocks, complex_to_float); +GR_SWIG_BLOCK_MAGIC2(blocks, complex_to_real); +GR_SWIG_BLOCK_MAGIC2(blocks, complex_to_imag); +GR_SWIG_BLOCK_MAGIC2(blocks, complex_to_mag); +GR_SWIG_BLOCK_MAGIC2(blocks, complex_to_mag_squared); +GR_SWIG_BLOCK_MAGIC2(blocks, complex_to_arg); +GR_SWIG_BLOCK_MAGIC2(blocks, conjugate_cc); +GR_SWIG_BLOCK_MAGIC2(blocks, deinterleave); +GR_SWIG_BLOCK_MAGIC2(blocks, divide_ff); +GR_SWIG_BLOCK_MAGIC2(blocks, divide_ss); +GR_SWIG_BLOCK_MAGIC2(blocks, divide_ii); +GR_SWIG_BLOCK_MAGIC2(blocks, divide_cc); +GR_SWIG_BLOCK_MAGIC2(blocks, file_source); +GR_SWIG_BLOCK_MAGIC2(blocks, file_meta_sink); +GR_SWIG_BLOCK_MAGIC2(blocks, file_meta_source); +GR_SWIG_BLOCK_MAGIC2(blocks, float_to_char); +GR_SWIG_BLOCK_MAGIC2(blocks, float_to_complex); +GR_SWIG_BLOCK_MAGIC2(blocks, float_to_int); +GR_SWIG_BLOCK_MAGIC2(blocks, float_to_short); +GR_SWIG_BLOCK_MAGIC2(blocks, float_to_uchar); +GR_SWIG_BLOCK_MAGIC2(blocks, int_to_float); +GR_SWIG_BLOCK_MAGIC2(blocks, integrate_ss); +GR_SWIG_BLOCK_MAGIC2(blocks, integrate_ii); +GR_SWIG_BLOCK_MAGIC2(blocks, integrate_ff); +GR_SWIG_BLOCK_MAGIC2(blocks, integrate_cc); +GR_SWIG_BLOCK_MAGIC2(blocks, interleave); +GR_SWIG_BLOCK_MAGIC2(blocks, interleaved_short_to_complex); +GR_SWIG_BLOCK_MAGIC2(blocks, keep_m_in_n); +GR_SWIG_BLOCK_MAGIC2(blocks, keep_one_in_n); +GR_SWIG_BLOCK_MAGIC2(blocks, multiply_ss); +GR_SWIG_BLOCK_MAGIC2(blocks, multiply_ii); +GR_SWIG_BLOCK_MAGIC2(blocks, multiply_ff); +GR_SWIG_BLOCK_MAGIC2(blocks, multiply_cc); +GR_SWIG_BLOCK_MAGIC2(blocks, multiply_conjugate_cc); +GR_SWIG_BLOCK_MAGIC2(blocks, multiply_const_ss); +GR_SWIG_BLOCK_MAGIC2(blocks, multiply_const_ii); +GR_SWIG_BLOCK_MAGIC2(blocks, multiply_const_ff); +GR_SWIG_BLOCK_MAGIC2(blocks, multiply_const_cc); +GR_SWIG_BLOCK_MAGIC2(blocks, multiply_const_vss); +GR_SWIG_BLOCK_MAGIC2(blocks, multiply_const_vii); +GR_SWIG_BLOCK_MAGIC2(blocks, multiply_const_vff); +GR_SWIG_BLOCK_MAGIC2(blocks, multiply_const_vcc); +GR_SWIG_BLOCK_MAGIC2(blocks, nlog10_ff); +GR_SWIG_BLOCK_MAGIC2(blocks, not_bb); +GR_SWIG_BLOCK_MAGIC2(blocks, not_ss); +GR_SWIG_BLOCK_MAGIC2(blocks, not_ii); +GR_SWIG_BLOCK_MAGIC2(blocks, patterned_interleaver); +GR_SWIG_BLOCK_MAGIC2(blocks, or_bb); +GR_SWIG_BLOCK_MAGIC2(blocks, or_ss); +GR_SWIG_BLOCK_MAGIC2(blocks, or_ii); +GR_SWIG_BLOCK_MAGIC2(blocks, repeat); +GR_SWIG_BLOCK_MAGIC2(blocks, short_to_char); +GR_SWIG_BLOCK_MAGIC2(blocks, short_to_float); +GR_SWIG_BLOCK_MAGIC2(blocks, stream_mux); +GR_SWIG_BLOCK_MAGIC2(blocks, stream_to_streams); +GR_SWIG_BLOCK_MAGIC2(blocks, stream_to_vector); +GR_SWIG_BLOCK_MAGIC2(blocks, streams_to_stream); +GR_SWIG_BLOCK_MAGIC2(blocks, streams_to_vector); +GR_SWIG_BLOCK_MAGIC2(blocks, sub_ff); +GR_SWIG_BLOCK_MAGIC2(blocks, sub_ss); +GR_SWIG_BLOCK_MAGIC2(blocks, sub_ii); +GR_SWIG_BLOCK_MAGIC2(blocks, sub_cc); +GR_SWIG_BLOCK_MAGIC2(blocks, uchar_to_float); +GR_SWIG_BLOCK_MAGIC2(blocks, vector_to_stream); +GR_SWIG_BLOCK_MAGIC2(blocks, vector_to_streams); +GR_SWIG_BLOCK_MAGIC2(blocks, xor_bb); +GR_SWIG_BLOCK_MAGIC2(blocks, xor_ss); +GR_SWIG_BLOCK_MAGIC2(blocks, xor_ii); diff --git a/gr-digital/CMakeLists.txt b/gr-digital/CMakeLists.txt index eb7ed67e1..864cd673a 100644 --- a/gr-digital/CMakeLists.txt +++ b/gr-digital/CMakeLists.txt @@ -29,6 +29,7 @@ include(GrComponent) GR_REGISTER_COMPONENT("gr-digital" ENABLE_GR_DIGITAL Boost_FOUND ENABLE_GR_CORE + ENABLE_GR_ANALOG ) GR_SET_GLOBAL(GR_DIGITAL_INCLUDE_DIRS diff --git a/gr-digital/examples/demod/ber_simulation.grc b/gr-digital/examples/demod/ber_simulation.grc index b7c6a624b..daf8bfde0 100644 --- a/gr-digital/examples/demod/ber_simulation.grc +++ b/gr-digital/examples/demod/ber_simulation.grc @@ -5,7 +5,7 @@ <key>options</key> <param> <key>id</key> - <value>ber_sim</value> + <value>ber_simulation</value> </param> <param> <key>_enabled</key> diff --git a/gr-digital/examples/demod/digital_freq_lock.grc b/gr-digital/examples/demod/digital_freq_lock.grc index df105dd7f..09d3085dd 100644 --- a/gr-digital/examples/demod/digital_freq_lock.grc +++ b/gr-digital/examples/demod/digital_freq_lock.grc @@ -5,7 +5,7 @@ <key>options</key> <param> <key>id</key> - <value>top_block</value> + <value>digital_freq_lock</value> </param> <param> <key>_enabled</key> diff --git a/gr-digital/examples/demod/pam_sync.grc b/gr-digital/examples/demod/pam_sync.grc index f870a0b06..dbd4befa6 100644 --- a/gr-digital/examples/demod/pam_sync.grc +++ b/gr-digital/examples/demod/pam_sync.grc @@ -5,7 +5,7 @@ <key>options</key> <param> <key>id</key> - <value>top_block</value> + <value>pam_sync</value> </param> <param> <key>_enabled</key> diff --git a/gr-digital/examples/demod/pam_timing.grc b/gr-digital/examples/demod/pam_timing.grc index 14a7d403e..c253d9a9f 100644 --- a/gr-digital/examples/demod/pam_timing.grc +++ b/gr-digital/examples/demod/pam_timing.grc @@ -5,7 +5,7 @@ <key>options</key> <param> <key>id</key> - <value>top_block</value> + <value>pam_timing</value> </param> <param> <key>_enabled</key> diff --git a/gr-digital/grc/digital_constellation_receiver_cb.xml b/gr-digital/grc/digital_constellation_receiver_cb.xml index 36c8e1b30..ffda8b85b 100644 --- a/gr-digital/grc/digital_constellation_receiver_cb.xml +++ b/gr-digital/grc/digital_constellation_receiver_cb.xml @@ -37,4 +37,24 @@ <name>out</name> <type>byte</type> </source> + <source> + <name>error</name> + <type>float</type> + <optional>1</optional> + </source> + <source> + <name>phase</name> + <type>float</type> + <optional>1</optional> + </source> + <source> + <name>frequency</name> + <type>float</type> + <optional>1</optional> + </source> + <source> + <name>symbol</name> + <type>complex</type> + <optional>1</optional> + </source> </block> diff --git a/gr-digital/include/digital_additive_scrambler_bb.h b/gr-digital/include/digital_additive_scrambler_bb.h index d4bd7d4ae..f1d0113e9 100644 --- a/gr-digital/include/digital_additive_scrambler_bb.h +++ b/gr-digital/include/digital_additive_scrambler_bb.h @@ -24,7 +24,7 @@ #include <digital_api.h> #include <gr_sync_block.h> -#include <gri_lfsr.h> +#include <analog/lfsr.h> class digital_additive_scrambler_bb; typedef boost::shared_ptr<digital_additive_scrambler_bb> digital_additive_scrambler_bb_sptr; @@ -57,7 +57,7 @@ class DIGITAL_API digital_additive_scrambler_bb : public gr_sync_block digital_make_additive_scrambler_bb(int mask, int seed, int len, int count); - gri_lfsr d_lfsr; + gr::analog::lfsr d_lfsr; int d_count; int d_bits; diff --git a/gr-digital/include/digital_constellation.h b/gr-digital/include/digital_constellation.h index a72bfb74c..76cd30b25 100644 --- a/gr-digital/include/digital_constellation.h +++ b/gr-digital/include/digital_constellation.h @@ -120,6 +120,9 @@ public: unsigned int d_rotational_symmetry; unsigned int d_dimensionality; unsigned int d_arity; + // The orignal constellation points were multiplied by this factor to get a + // constellation with average magnitude 1. + float d_scalefactor; float get_distance(unsigned int index, const gr_complex *sample); unsigned int get_closest_point(const gr_complex *sample); diff --git a/gr-digital/include/digital_descrambler_bb.h b/gr-digital/include/digital_descrambler_bb.h index b719803f3..d503102a9 100644 --- a/gr-digital/include/digital_descrambler_bb.h +++ b/gr-digital/include/digital_descrambler_bb.h @@ -24,7 +24,7 @@ #include <digital_api.h> #include <gr_sync_block.h> -#include "gri_lfsr.h" +#include <analog/lfsr.h> class digital_descrambler_bb; typedef boost::shared_ptr<digital_descrambler_bb> digital_descrambler_bb_sptr; @@ -49,7 +49,7 @@ class DIGITAL_API digital_descrambler_bb : public gr_sync_block friend DIGITAL_API digital_descrambler_bb_sptr digital_make_descrambler_bb(int mask, int seed, int len); - gri_lfsr d_lfsr; + gr::analog::lfsr d_lfsr; digital_descrambler_bb(int mask, int seed, int len); diff --git a/gr-digital/include/digital_scrambler_bb.h b/gr-digital/include/digital_scrambler_bb.h index d6f08dcc8..cafb0e5f2 100644 --- a/gr-digital/include/digital_scrambler_bb.h +++ b/gr-digital/include/digital_scrambler_bb.h @@ -24,7 +24,7 @@ #include <digital_api.h> #include <gr_sync_block.h> -#include "gri_lfsr.h" +#include <analog/lfsr.h> class digital_scrambler_bb; typedef boost::shared_ptr<digital_scrambler_bb> digital_scrambler_bb_sptr; @@ -49,7 +49,7 @@ class DIGITAL_API digital_scrambler_bb : public gr_sync_block friend DIGITAL_API digital_scrambler_bb_sptr digital_make_scrambler_bb(int mask, int seed, int len); - gri_lfsr d_lfsr; + gr::analog::lfsr d_lfsr; digital_scrambler_bb(int mask, int seed, int len); diff --git a/gr-digital/lib/CMakeLists.txt b/gr-digital/lib/CMakeLists.txt index bd4f1a500..155a10098 100644 --- a/gr-digital/lib/CMakeLists.txt +++ b/gr-digital/lib/CMakeLists.txt @@ -22,6 +22,7 @@ ######################################################################## include_directories( ${GNURADIO_CORE_INCLUDE_DIRS} + ${GR_ANALOG_INCLUDE_DIRS} ${GR_DIGITAL_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR}/../include ) @@ -146,4 +147,4 @@ add_library(gnuradio-digital SHARED ${gr_digital_sources}) target_link_libraries(gnuradio-digital ${digital_libs}) GR_LIBRARY_FOO(gnuradio-digital RUNTIME_COMPONENT "digital_runtime" DEVEL_COMPONENT "digital_devel") -add_dependencies(gnuradio-digital digital_generated_includes digital_generated_swigs) +add_dependencies(gnuradio-digital digital_generated_includes digital_generated_swigs gnuradio-analog) diff --git a/gr-digital/lib/digital_constellation.cc b/gr-digital/lib/digital_constellation.cc index d9a53c493..da79f2caa 100644 --- a/gr-digital/lib/digital_constellation.cc +++ b/gr-digital/lib/digital_constellation.cc @@ -49,6 +49,17 @@ digital_constellation::digital_constellation (std::vector<gr_complex> constellat d_rotational_symmetry(rotational_symmetry), d_dimensionality(dimensionality) { + // Scale constellation points so that average magnitude is 1. + float summed_mag = 0; + unsigned int constsize = d_constellation.size(); + for (unsigned int i=0; i<constsize; i++) { + gr_complex c = d_constellation[i]; + summed_mag += sqrt(c.real()*c.real() + c.imag()*c.imag()); + } + d_scalefactor = constsize/summed_mag; + for (unsigned int i=0; i<constsize; i++) { + d_constellation[i] = d_constellation[i]*d_scalefactor; + } if (pre_diff_code.size() == 0) d_apply_pre_diff_code = false; else if (pre_diff_code.size() != constellation.size()) @@ -293,6 +304,8 @@ digital_constellation_rect::digital_constellation_rect (std::vector<gr_complex> n_real_sectors(real_sectors), n_imag_sectors(imag_sectors), d_width_real_sectors(width_real_sectors), d_width_imag_sectors(width_imag_sectors) { + d_width_real_sectors *= d_scalefactor; + d_width_imag_sectors *= d_scalefactor; find_sector_values(); } diff --git a/gr-digital/lib/digital_constellation_receiver_cb.cc b/gr-digital/lib/digital_constellation_receiver_cb.cc index b9239962a..faaa760fd 100644 --- a/gr-digital/lib/digital_constellation_receiver_cb.cc +++ b/gr-digital/lib/digital_constellation_receiver_cb.cc @@ -47,13 +47,13 @@ digital_make_constellation_receiver_cb(digital_constellation_sptr constell, fmin, fmax)); } -static int ios[] = {sizeof(char), sizeof(float), sizeof(float), sizeof(float)}; +static int ios[] = {sizeof(char), sizeof(float), sizeof(float), sizeof(float), sizeof(gr_complex)}; static std::vector<int> iosig(ios, ios+sizeof(ios)/sizeof(int)); digital_constellation_receiver_cb::digital_constellation_receiver_cb (digital_constellation_sptr constellation, float loop_bw, float fmin, float fmax) : gr_block ("constellation_receiver_cb", gr_make_io_signature (1, 1, sizeof (gr_complex)), - gr_make_io_signaturev (1, 4, iosig)), + gr_make_io_signaturev (1, 5, iosig)), gri_control_loop(loop_bw, fmax, fmin), d_constellation(constellation), d_current_const_point(0) @@ -93,10 +93,12 @@ digital_constellation_receiver_cb::general_work (int noutput_items, gr_complex sample, nco; float *out_err = 0, *out_phase = 0, *out_freq = 0; - if(output_items.size() == 4) { + gr_complex *out_symbol; + if(output_items.size() == 5) { out_err = (float *) output_items[1]; out_phase = (float *) output_items[2]; out_freq = (float *) output_items[3]; + out_symbol = (gr_complex*)output_items[4]; } while((i < noutput_items) && (i < ninput_items[0])) { @@ -109,10 +111,11 @@ digital_constellation_receiver_cb::general_work (int noutput_items, out[i] = sym_value; - if(output_items.size() == 4) { + if(output_items.size() == 5) { out_err[i] = phase_error; out_phase[i] = d_phase; out_freq[i] = d_freq; + out_symbol[i] = sample; } i++; } diff --git a/gr-digital/python/qa_constellation.py b/gr-digital/python/qa_constellation.py index b17d2a0fc..6962ec633 100755 --- a/gr-digital/python/qa_constellation.py +++ b/gr-digital/python/qa_constellation.py @@ -69,6 +69,10 @@ tested_constellation_info = ( {'m': (2, 4, 8, 16, 32, 64), 'mod_code': tested_mod_codes, }, True, None), + (qam.qam_constellation, + {'constellation_points': (4, 16, 64), + 'mod_code': tested_mod_codes, }, + True, None), (digital_swig.constellation_bpsk, {}, True, None), (digital_swig.constellation_qpsk, {}, False, None), (digital_swig.constellation_dqpsk, {}, True, None), diff --git a/gr-digital/swig/CMakeLists.txt b/gr-digital/swig/CMakeLists.txt index 0c129e181..efbd1c2c9 100644 --- a/gr-digital/swig/CMakeLists.txt +++ b/gr-digital/swig/CMakeLists.txt @@ -105,6 +105,7 @@ execute_process( ) set(GR_SWIG_INCLUDE_DIRS + ${GR_ANALOG_INCLUDE_DIRS} ${GR_DIGITAL_INCLUDE_DIRS} ${GNURADIO_CORE_SWIG_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR} diff --git a/gr-fcd/lib/fcd_source_c_impl.cc b/gr-fcd/lib/fcd_source_c_impl.cc index 34a221827..81ccee092 100644 --- a/gr-fcd/lib/fcd_source_c_impl.cc +++ b/gr-fcd/lib/fcd_source_c_impl.cc @@ -176,7 +176,7 @@ void fcd_source_c_impl::set_lna_gain(float gain) // Set mixer gain void fcd_source_c_impl::set_mixer_gain(float gain) { - FCD_MODE_ENUM fme; + __GR_ATTR_UNUSED FCD_MODE_ENUM fme; unsigned char g; if ( gain > 4.0 ) { diff --git a/gr-howto-write-a-block/docs/doxygen/Doxyfile.in b/gr-howto-write-a-block/docs/doxygen/Doxyfile.in index cb6a913bb..6ee69ee35 100644 --- a/gr-howto-write-a-block/docs/doxygen/Doxyfile.in +++ b/gr-howto-write-a-block/docs/doxygen/Doxyfile.in @@ -455,12 +455,6 @@ MAX_INITIALIZER_LINES = 30 SHOW_USED_FILES = YES -# If the sources in your project are distributed over multiple directories -# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy -# in the documentation. The default is NO. - -SHOW_DIRECTORIES = NO - # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. @@ -807,12 +801,6 @@ HTML_FOOTER = HTML_STYLESHEET = -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to -# NO a bullet list will be used. - -HTML_ALIGN_MEMBERS = YES - # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. For this to work a browser that supports diff --git a/gr-howto-write-a-block/docs/doxygen/Doxyfile.swig_doc.in b/gr-howto-write-a-block/docs/doxygen/Doxyfile.swig_doc.in index 50b8aa81d..121c3e858 100644 --- a/gr-howto-write-a-block/docs/doxygen/Doxyfile.swig_doc.in +++ b/gr-howto-write-a-block/docs/doxygen/Doxyfile.swig_doc.in @@ -470,12 +470,6 @@ MAX_INITIALIZER_LINES = 30 SHOW_USED_FILES = YES -# If the sources in your project are distributed over multiple directories -# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy -# in the documentation. The default is NO. - -SHOW_DIRECTORIES = NO - # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. @@ -796,12 +790,6 @@ HTML_FOOTER = HTML_STYLESHEET = -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to -# NO a bullet list will be used. - -HTML_ALIGN_MEMBERS = YES - # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. For this to work a browser that supports @@ -950,11 +938,6 @@ ENUM_VALUES_PER_LINE = 4 GENERATE_TREEVIEW = NO -# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, -# and Class Hierarchy pages using a tree view instead of an ordered list. - -USE_INLINE_TREES = NO - # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. diff --git a/gr-howto-write-a-block/docs/doxygen/doxyxml/example/Doxyfile b/gr-howto-write-a-block/docs/doxygen/doxyxml/example/Doxyfile index 9780043be..dd2e5c77e 100644 --- a/gr-howto-write-a-block/docs/doxygen/doxyxml/example/Doxyfile +++ b/gr-howto-write-a-block/docs/doxygen/doxyxml/example/Doxyfile @@ -476,12 +476,6 @@ MAX_INITIALIZER_LINES = 30 SHOW_USED_FILES = YES -# If the sources in your project are distributed over multiple directories -# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy -# in the documentation. The default is NO. - -SHOW_DIRECTORIES = NO - # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. @@ -808,12 +802,6 @@ HTML_STYLESHEET = HTML_TIMESTAMP = YES -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to -# NO a bullet list will be used. - -HTML_ALIGN_MEMBERS = YES - # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. For this to work a browser that supports @@ -978,11 +966,6 @@ ENUM_VALUES_PER_LINE = 4 GENERATE_TREEVIEW = NO -# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, -# and Class Hierarchy pages using a tree view instead of an ordered list. - -USE_INLINE_TREES = NO - # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. diff --git a/gr-howto-write-a-block/python/__init__.py b/gr-howto-write-a-block/python/__init__.py index 575cbfc22..2bd27cb31 100644 --- a/gr-howto-write-a-block/python/__init__.py +++ b/gr-howto-write-a-block/python/__init__.py @@ -23,32 +23,8 @@ This is the GNU Radio HOWTO module. Place your Python package description here (python/__init__.py). ''' -# ---------------------------------------------------------------- -# Temporary workaround for ticket:181 (swig+python problem) -import sys -_RTLD_GLOBAL = 0 -try: - from dl import RTLD_GLOBAL as _RTLD_GLOBAL -except ImportError: - try: - from DLFCN import RTLD_GLOBAL as _RTLD_GLOBAL - except ImportError: - pass - -if _RTLD_GLOBAL != 0: - _dlopenflags = sys.getdlopenflags() - sys.setdlopenflags(_dlopenflags|_RTLD_GLOBAL) -# ---------------------------------------------------------------- - - # import swig generated symbols into the howto namespace from howto_swig import * # import any pure python here # - -# ---------------------------------------------------------------- -# Tail of workaround -if _RTLD_GLOBAL != 0: - sys.setdlopenflags(_dlopenflags) # Restore original flags -# ---------------------------------------------------------------- diff --git a/gr-pager/lib/pager_flex_parse.cc b/gr-pager/lib/pager_flex_parse.cc index 9418c4461..d7c308ddb 100644 --- a/gr-pager/lib/pager_flex_parse.cc +++ b/gr-pager/lib/pager_flex_parse.cc @@ -156,16 +156,16 @@ void pager_flex_parse::parse_data() void pager_flex_parse::parse_alphanumeric(int mw1, int mw2, int j) { int frag; - bool cont; + //bool cont; if (!d_laddr) { frag = (d_datawords[mw1] >> 11) & 0x03; - cont = (d_datawords[mw1] >> 10) & 0x01; + //cont = (d_datawords[mw1] >> 10) & 0x01; mw1++; } else { frag = (d_datawords[j+1] >> 11) & 0x03; - cont = (d_datawords[j+1] >> 10) & 0x01; + //cont = (d_datawords[j+1] >> 10) & 0x01; mw2--; } diff --git a/gr-qtgui/grc/qtgui_sink_x.xml b/gr-qtgui/grc/qtgui_sink_x.xml index 83d6ec287..6488ac04c 100644 --- a/gr-qtgui/grc/qtgui_sink_x.xml +++ b/gr-qtgui/grc/qtgui_sink_x.xml @@ -24,6 +24,7 @@ qtgui.$(type.fcn)( $plottime, \#plottime $plotconst, \#plotconst ) +self.$(id).set_update_time(1.0 / $rate) self._$(id)_win = sip.wrapinstance(self.$(id).pyqwidget(), Qt.QWidget) $(gui_hint()($win))</make> <callback>set_frequency_range($fc, $bw)</callback> @@ -133,6 +134,12 @@ $(gui_hint()($win))</make> <type>gui_hint</type> <hide>part</hide> </param> + <param> + <name>Update Rate</name> + <key>rate</key> + <value>10</value> + <type>real</type> + </param> <sink> <name>in</name> <type>$type</type> diff --git a/gr-uhd/examples/grc/uhd_fft.grc b/gr-uhd/examples/grc/uhd_fft.grc index 29c375065..2582b5e3b 100644 --- a/gr-uhd/examples/grc/uhd_fft.grc +++ b/gr-uhd/examples/grc/uhd_fft.grc @@ -1,6 +1,6 @@ <?xml version='1.0' encoding='ASCII'?> <flow_graph> - <timestamp>Sat Oct 8 10:26:30 2011</timestamp> + <timestamp>Mon Jun 18 14:20:11 2012</timestamp> <block> <key>options</key> <param> @@ -13,7 +13,7 @@ </param> <param> <key>title</key> - <value>UHD FFT Plotter</value> + <value>UHD FFT</value> </param> <param> <key>author</key> @@ -21,7 +21,7 @@ </param> <param> <key>description</key> - <value>FFT waveform plot</value> + <value>UHD FFT Waveform Plotter</value> </param> <param> <key>window_size</key> @@ -44,12 +44,16 @@ <value>True</value> </param> <param> + <key>max_nouts</key> + <value>0</value> + </param> + <param> <key>realtime_scheduling</key> <value></value> </param> <param> <key>_coordinate</key> - <value>(10, 10)</value> + <value>(15, 15)</value> </param> <param> <key>_rotation</key> @@ -57,34 +61,22 @@ </param> </block> <block> - <key>parameter</key> + <key>import</key> <param> <key>id</key> - <value>gain</value> + <value>import_0</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> - <key>label</key> - <value>Default Gain</value> - </param> - <param> - <key>value</key> - <value>0</value> - </param> - <param> - <key>type</key> - <value>eng_float</value> - </param> - <param> - <key>short_id</key> - <value>g</value> + <key>import</key> + <value>import numpy</value> </param> <param> <key>_coordinate</key> - <value>(633, 17)</value> + <value>(15, 121)</value> </param> <param> <key>_rotation</key> @@ -95,7 +87,7 @@ <key>parameter</key> <param> <key>id</key> - <value>freq</value> + <value>param_samp_rate</value> </param> <param> <key>_enabled</key> @@ -103,11 +95,11 @@ </param> <param> <key>label</key> - <value>Default Frequency</value> + <value>Sample Rate</value> </param> <param> <key>value</key> - <value>2.45e9</value> + <value>1e6</value> </param> <param> <key>type</key> @@ -115,11 +107,11 @@ </param> <param> <key>short_id</key> - <value>f</value> + <value>s</value> </param> <param> <key>_coordinate</key> - <value>(485, 18)</value> + <value>(358, 14)</value> </param> <param> <key>_rotation</key> @@ -130,7 +122,7 @@ <key>parameter</key> <param> <key>id</key> - <value>address</value> + <value>param_freq</value> </param> <param> <key>_enabled</key> @@ -138,23 +130,23 @@ </param> <param> <key>label</key> - <value>IP Address</value> + <value>Default Frequency</value> </param> <param> <key>value</key> - <value>addr=192.168.11.2</value> + <value>2.45e9</value> </param> <param> <key>type</key> - <value>string</value> + <value>eng_float</value> </param> <param> <key>short_id</key> - <value>a</value> + <value>f</value> </param> <param> <key>_coordinate</key> - <value>(205, 16)</value> + <value>(508, 14)</value> </param> <param> <key>_rotation</key> @@ -165,7 +157,7 @@ <key>parameter</key> <param> <key>id</key> - <value>samp_rate</value> + <value>param_gain</value> </param> <param> <key>_enabled</key> @@ -173,11 +165,11 @@ </param> <param> <key>label</key> - <value>Sample Rate</value> + <value>Default Gain</value> </param> <param> <key>value</key> - <value>1e6</value> + <value>0</value> </param> <param> <key>type</key> @@ -185,11 +177,11 @@ </param> <param> <key>short_id</key> - <value>s</value> + <value>g</value> </param> <param> <key>_coordinate</key> - <value>(359, 18)</value> + <value>(672, 13)</value> </param> <param> <key>_rotation</key> @@ -197,10 +189,10 @@ </param> </block> <block> - <key>wxgui_fftsink2</key> + <key>wxgui_scopesink2</key> <param> <key>id</key> - <value>wxgui_fftsink2_0</value> + <value>wxgui_scopesink2_0</value> </param> <param> <key>_enabled</key> @@ -212,55 +204,35 @@ </param> <param> <key>title</key> - <value>FFT Plot</value> + <value>Scope Plot</value> </param> <param> <key>samp_rate</key> <value>samp_rate</value> </param> <param> - <key>baseband_freq</key> - <value>tun_freq</value> - </param> - <param> - <key>y_per_div</key> - <value>10</value> - </param> - <param> - <key>y_divs</key> - <value>10</value> - </param> - <param> - <key>ref_level</key> - <value>10</value> - </param> - <param> - <key>ref_scale</key> - <value>2.0</value> + <key>v_scale</key> + <value>0</value> </param> <param> - <key>fft_size</key> - <value>1024</value> + <key>v_offset</key> + <value>0</value> </param> <param> - <key>fft_rate</key> - <value>30</value> + <key>t_scale</key> + <value>0</value> </param> <param> - <key>peak_hold</key> + <key>ac_couple</key> <value>False</value> </param> <param> - <key>average</key> + <key>xy_mode</key> <value>False</value> </param> <param> - <key>avg_alpha</key> - <value>0</value> - </param> - <param> - <key>win</key> - <value>None</value> + <key>num_inputs</key> + <value>1</value> </param> <param> <key>win_size</key> @@ -272,11 +244,19 @@ </param> <param> <key>notebook</key> - <value></value> + <value>nb0, 2</value> + </param> + <param> + <key>trig_mode</key> + <value>gr.gr_TRIG_MODE_AUTO</value> + </param> + <param> + <key>y_axis_label</key> + <value>Counts</value> </param> <param> <key>_coordinate</key> - <value>(479, 176)</value> + <value>(314, 250)</value> </param> <param> <key>_rotation</key> @@ -295,7 +275,15 @@ </param> <param> <key>type</key> - <value>complex</value> + <value>fc32</value> + </param> + <param> + <key>otw</key> + <value></value> + </param> + <param> + <key>stream_args</key> + <value></value> </param> <param> <key>dev_addr</key> @@ -314,7 +302,11 @@ <value>1</value> </param> <param> - <key>ref_source0</key> + <key>clock_source0</key> + <value></value> + </param> + <param> + <key>time_source0</key> <value></value> </param> <param> @@ -322,7 +314,11 @@ <value></value> </param> <param> - <key>ref_source1</key> + <key>clock_source1</key> + <value></value> + </param> + <param> + <key>time_source1</key> <value></value> </param> <param> @@ -330,7 +326,11 @@ <value></value> </param> <param> - <key>ref_source2</key> + <key>clock_source2</key> + <value></value> + </param> + <param> + <key>time_source2</key> <value></value> </param> <param> @@ -338,7 +338,11 @@ <value></value> </param> <param> - <key>ref_source3</key> + <key>clock_source3</key> + <value></value> + </param> + <param> + <key>time_source3</key> <value></value> </param> <param> @@ -346,7 +350,11 @@ <value></value> </param> <param> - <key>ref_source4</key> + <key>clock_source4</key> + <value></value> + </param> + <param> + <key>time_source4</key> <value></value> </param> <param> @@ -354,7 +362,11 @@ <value></value> </param> <param> - <key>ref_source5</key> + <key>clock_source5</key> + <value></value> + </param> + <param> + <key>time_source5</key> <value></value> </param> <param> @@ -362,7 +374,11 @@ <value></value> </param> <param> - <key>ref_source6</key> + <key>clock_source6</key> + <value></value> + </param> + <param> + <key>time_source6</key> <value></value> </param> <param> @@ -370,7 +386,11 @@ <value></value> </param> <param> - <key>ref_source7</key> + <key>clock_source7</key> + <value></value> + </param> + <param> + <key>time_source7</key> <value></value> </param> <param> @@ -387,19 +407,19 @@ </param> <param> <key>center_freq0</key> - <value>tun_freq</value> + <value>freq</value> </param> <param> <key>gain0</key> - <value>tun_gain</value> + <value>gain</value> </param> <param> <key>ant0</key> - <value></value> + <value>ant</value> </param> <param> <key>bw0</key> - <value>0</value> + <value>samp_rate</value> </param> <param> <key>center_freq1</key> @@ -899,7 +919,7 @@ </param> <param> <key>_coordinate</key> - <value>(212, 216)</value> + <value>(37, 394)</value> </param> <param> <key>_rotation</key> @@ -907,34 +927,505 @@ </param> </block> <block> - <key>variable_slider</key> + <key>variable_function_probe</key> <param> <key>id</key> - <value>tun_freq</value> + <value>chan0_lo_locked</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> + <key>value</key> + <value>uhd.sensor_value("", False, "")</value> + </param> + <param> + <key>block_id</key> + <value>uhd_usrp_source_0</value> + </param> + <param> + <key>function_name</key> + <value>get_sensor</value> + </param> + <param> + <key>function_args</key> + <value>"'lo_locked'"</value> + </param> + <param> + <key>poll_rate</key> + <value>10</value> + </param> + <param> + <key>_coordinate</key> + <value>(583, 432)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>notebook</key> + <param> + <key>id</key> + <value>nb0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>style</key> + <value>wx.NB_TOP</value> + </param> + <param> + <key>labels</key> + <value>['FFT', 'Waterfall', 'Scope']</value> + </param> + <param> + <key>grid_pos</key> + <value>0, 0, 1, 8</value> + </param> + <param> + <key>notebook</key> + <value></value> + </param> + <param> + <key>_coordinate</key> + <value>(15, 172)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable_chooser</key> + <param> + <key>id</key> + <value>ant_xcvr</value> + </param> + <param> + <key>_enabled</key> + <value>False</value> + </param> + <param> <key>label</key> - <value>UHD Freq (Hz)</value> + <value>Antenna</value> </param> <param> <key>value</key> + <value>"J2"</value> + </param> + <param> + <key>choices</key> + <value>["J2","J1"]</value> + </param> + <param> + <key>labels</key> + <value>["J2","J1"]</value> + </param> + <param> + <key>type</key> + <value>radio_buttons</value> + </param> + <param> + <key>style</key> + <value>wx.RA_HORIZONTAL</value> + </param> + <param> + <key>grid_pos</key> + <value></value> + </param> + <param> + <key>notebook</key> + <value></value> + </param> + <param> + <key>_coordinate</key> + <value>(830, 278)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable_static_text</key> + <param> + <key>id</key> + <value>lo_locked_probe</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>label</key> + <value>LO Locked</value> + </param> + <param> + <key>value</key> + <value>chan0_lo_locked.to_bool()</value> + </param> + <param> + <key>converver</key> + <value>str_converter</value> + </param> + <param> + <key>formatter</key> + <value>lambda x: x and "True" or "False"</value> + </param> + <param> + <key>grid_pos</key> + <value>1, 7, 1, 1</value> + </param> + <param> + <key>notebook</key> + <value></value> + </param> + <param> + <key>_coordinate</key> + <value>(583, 314)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable_chooser</key> + <param> + <key>id</key> + <value>ant</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>label</key> + <value>Antenna</value> + </param> + <param> + <key>value</key> + <value>"RX2"</value> + </param> + <param> + <key>choices</key> + <value>["RX2","TX/RX"]</value> + </param> + <param> + <key>labels</key> + <value>["RX2","TX/RX"]</value> + </param> + <param> + <key>type</key> + <value>radio_buttons</value> + </param> + <param> + <key>style</key> + <value>wx.RA_HORIZONTAL</value> + </param> + <param> + <key>grid_pos</key> + <value>1, 4, 1, 2</value> + </param> + <param> + <key>notebook</key> + <value></value> + </param> + <param> + <key>_coordinate</key> + <value>(830, 130)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>parameter</key> + <param> + <key>id</key> + <value>address</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>label</key> + <value>IP Address</value> + </param> + <param> + <key>value</key> + <value></value> + </param> + <param> + <key>type</key> + <value>string</value> + </param> + <param> + <key>short_id</key> + <value>a</value> + </param> + <param> + <key>_coordinate</key> + <value>(190, 15)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>wxgui_fftsink2</key> + <param> + <key>id</key> + <value>fft</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>title</key> + <value>FFT Plot</value> + </param> + <param> + <key>samp_rate</key> + <value>samp_rate</value> + </param> + <param> + <key>baseband_freq</key> + <value>freq</value> + </param> + <param> + <key>y_per_div</key> + <value>10</value> + </param> + <param> + <key>y_divs</key> + <value>15</value> + </param> + <param> + <key>ref_level</key> + <value>0</value> + </param> + <param> + <key>ref_scale</key> + <value>2.0</value> + </param> + <param> + <key>fft_size</key> + <value>1024</value> + </param> + <param> + <key>fft_rate</key> + <value>15</value> + </param> + <param> + <key>peak_hold</key> + <value>False</value> + </param> + <param> + <key>average</key> + <value>False</value> + </param> + <param> + <key>avg_alpha</key> + <value>0</value> + </param> + <param> + <key>win</key> + <value>None</value> + </param> + <param> + <key>win_size</key> + <value>(-1, 400)</value> + </param> + <param> + <key>grid_pos</key> + <value></value> + </param> + <param> + <key>notebook</key> + <value>nb0, 0</value> + </param> + <param> + <key>freqvar</key> + <value>None</value> + </param> + <param> + <key>_coordinate</key> + <value>(314, 359)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>wxgui_waterfallsink2</key> + <param> + <key>id</key> + <value>wxgui_waterfallsink2_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>title</key> + <value>Waterfall Plot</value> + </param> + <param> + <key>samp_rate</key> + <value>samp_rate</value> + </param> + <param> + <key>baseband_freq</key> + <value>0</value> + </param> + <param> + <key>dynamic_range</key> + <value>100</value> + </param> + <param> + <key>ref_level</key> + <value>0</value> + </param> + <param> + <key>ref_scale</key> + <value>2.0</value> + </param> + <param> + <key>fft_size</key> + <value>512</value> + </param> + <param> + <key>fft_rate</key> + <value>15</value> + </param> + <param> + <key>average</key> + <value>False</value> + </param> + <param> + <key>avg_alpha</key> + <value>0</value> + </param> + <param> + <key>win</key> + <value>None</value> + </param> + <param> + <key>win_size</key> + <value>(-1, 400)</value> + </param> + <param> + <key>grid_pos</key> + <value></value> + </param> + <param> + <key>notebook</key> + <value>nb0, 1</value> + </param> + <param> + <key>freqvar</key> + <value>None</value> + </param> + <param> + <key>_coordinate</key> + <value>(313, 573)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable_text_box</key> + <param> + <key>id</key> + <value>samp_rate</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>label</key> + <value>Sample Rate</value> + </param> + <param> + <key>value</key> + <value>param_samp_rate</value> + </param> + <param> + <key>converver</key> + <value>float_converter</value> + </param> + <param> + <key>formatter</key> + <value>None</value> + </param> + <param> + <key>grid_pos</key> + <value>1, 0, 1, 3</value> + </param> + <param> + <key>notebook</key> + <value></value> + </param> + <param> + <key>_coordinate</key> + <value>(358, 129)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable_slider</key> + <param> + <key>id</key> <value>freq</value> </param> <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>label</key> + <value>RX Tune Frequency</value> + </param> + <param> + <key>value</key> + <value>param_freq</value> + </param> + <param> <key>min</key> - <value>2.4e9</value> + <value>50e6</value> </param> <param> <key>max</key> - <value>2.5e9</value> + <value>6e9</value> </param> <param> <key>num_steps</key> - <value>100</value> + <value>1000</value> </param> <param> <key>style</key> @@ -946,7 +1437,7 @@ </param> <param> <key>grid_pos</key> - <value></value> + <value>3, 0, 1, 8</value> </param> <param> <key>notebook</key> @@ -954,7 +1445,7 @@ </param> <param> <key>_coordinate</key> - <value>(36, 376)</value> + <value>(510, 128)</value> </param> <param> <key>_rotation</key> @@ -965,7 +1456,7 @@ <key>variable_slider</key> <param> <key>id</key> - <value>tun_gain</value> + <value>gain</value> </param> <param> <key>_enabled</key> @@ -973,11 +1464,11 @@ </param> <param> <key>label</key> - <value>UHD Gain</value> + <value>RX Gain</value> </param> <param> <key>value</key> - <value>gain</value> + <value>param_gain</value> </param> <param> <key>min</key> @@ -985,11 +1476,11 @@ </param> <param> <key>max</key> - <value>20</value> + <value>31.5</value> </param> <param> <key>num_steps</key> - <value>100</value> + <value>63</value> </param> <param> <key>style</key> @@ -1001,7 +1492,7 @@ </param> <param> <key>grid_pos</key> - <value></value> + <value>2, 0, 1, 8</value> </param> <param> <key>notebook</key> @@ -1009,7 +1500,7 @@ </param> <param> <key>_coordinate</key> - <value>(177, 377)</value> + <value>(679, 130)</value> </param> <param> <key>_rotation</key> @@ -1018,7 +1509,19 @@ </block> <connection> <source_block_id>uhd_usrp_source_0</source_block_id> - <sink_block_id>wxgui_fftsink2_0</sink_block_id> + <sink_block_id>wxgui_scopesink2_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>uhd_usrp_source_0</source_block_id> + <sink_block_id>wxgui_waterfallsink2_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>uhd_usrp_source_0</source_block_id> + <sink_block_id>fft</sink_block_id> <source_key>0</source_key> <sink_key>0</sink_key> </connection> diff --git a/gr-uhd/include/gr_uhd_usrp_source.h b/gr-uhd/include/gr_uhd_usrp_source.h index b5acabee4..1243ddcc2 100644 --- a/gr-uhd/include/gr_uhd_usrp_source.h +++ b/gr-uhd/include/gr_uhd_usrp_source.h @@ -129,6 +129,19 @@ public: virtual void set_start_time(const uhd::time_spec_t &time) = 0; /*! + * *Advanced use only:* + * Issue a stream command to all channels in this source block. + * + * This method is intended to override the default "always on" behavior. + * After starting the flow graph, the user should call stop() on this block, + * then issue any desired arbitrary stream_cmd_t structs to the device. + * The USRP will be able to enqueue several stream commands in the FPGA. + * + * \param cmd the stream command to issue to all source channels + */ + virtual void issue_stream_cmd(const uhd::stream_cmd_t &cmd) = 0; + + /*! * Returns identifying information about this USRP's configuration. * Returns motherboard ID, name, and serial. * Returns daughterboard RX ID, subdev name and spec, serial, and antenna. diff --git a/gr-uhd/lib/gr_uhd_usrp_source.cc b/gr-uhd/lib/gr_uhd_usrp_source.cc index ad4cb4d81..3813673b4 100644 --- a/gr-uhd/lib/gr_uhd_usrp_source.cc +++ b/gr-uhd/lib/gr_uhd_usrp_source.cc @@ -338,8 +338,8 @@ public: //If receive resulted in a timeout condition: //We now receive a single packet with a large timeout. - while (_metadata.error_code == uhd::rx_metadata_t::ERROR_CODE_TIMEOUT){ - if (boost::this_thread::interruption_requested()) return WORK_DONE; + if (_metadata.error_code == uhd::rx_metadata_t::ERROR_CODE_TIMEOUT) + { num_samps = _rx_stream->recv( output_items, noutput_items, _metadata, 0.1, true/*one pkt*/ ); @@ -377,9 +377,8 @@ public: break; case uhd::rx_metadata_t::ERROR_CODE_TIMEOUT: - //Assume that the user called stop() on the flow graph. - //However, a timeout can occur under error conditions. - return WORK_DONE; + //its ok to timeout, perhaps the user is doing finite streaming + return 0; case uhd::rx_metadata_t::ERROR_CODE_OVERFLOW: _tag_now = true; @@ -402,6 +401,11 @@ public: _stream_now = false; } + void issue_stream_cmd(const uhd::stream_cmd_t &cmd) + { + _dev->issue_stream_cmd(cmd); + } + bool start(void){ #ifdef GR_UHD_USE_STREAM_API _rx_stream = _dev->get_rx_stream(_stream_args); diff --git a/gr-uhd/swig/uhd_swig.i b/gr-uhd/swig/uhd_swig.i index 513c1da7e..99258c0f5 100644 --- a/gr-uhd/swig/uhd_swig.i +++ b/gr-uhd/swig/uhd_swig.i @@ -76,6 +76,8 @@ %include <uhd/types/time_spec.hpp> +%include <uhd/types/stream_cmd.hpp> + %include <uhd/types/clock_config.hpp> %include <uhd/types/metadata.hpp> diff --git a/gr-utils/src/python/CMakeLists.txt b/gr-utils/src/python/CMakeLists.txt index 90caeb234..d2af6b952 100644 --- a/gr-utils/src/python/CMakeLists.txt +++ b/gr-utils/src/python/CMakeLists.txt @@ -50,6 +50,8 @@ GR_PYTHON_INSTALL( gr_plot_short gr_plot_qt gr_filter_design + gr_read_file_metadata + grcc DESTINATION ${GR_RUNTIME_DIR} COMPONENT "utils" ) diff --git a/gr-utils/src/python/gr_read_file_metadata b/gr-utils/src/python/gr_read_file_metadata new file mode 100644 index 000000000..cf0cd5b11 --- /dev/null +++ b/gr-utils/src/python/gr_read_file_metadata @@ -0,0 +1,87 @@ +#!/usr/bin/env python +# +# Copyright 2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +import sys +from optparse import OptionParser + +from gruel import pmt +from gnuradio.blocks import parse_file_metadata + +def main(filename, detached=False): + handle = open(filename, "rb") + + nheaders = 0 + nread = 0 + while(True): + # read out next header bytes + hdr_start = handle.tell() + header_str = handle.read(parse_file_metadata.HEADER_LENGTH) + if(len(header_str) == 0): + break + + # Convert from string to PMT (should be a dictionary) + try: + header = pmt.pmt_deserialize_str(header_str) + except RuntimeError: + sys.stderr.write("Could not deserialize header: invalid or corrupt data file.\n") + sys.exit(1) + + print "HEADER {0}".format(nheaders) + info = parse_file_metadata.parse_header(header, True) + + if(info["extra_len"] > 0): + extra_str = handle.read(info["extra_len"]) + if(len(extra_str) == 0): + break + + try: + extra = pmt.pmt_deserialize_str(extra_str) + except RuntimeError: + sys.stderr.write("Could not deserialize extras: invalid or corrupt data file.\n") + sys.exit(1) + + print "\nExtra Header:" + extra_info = parse_file_metadata.parse_extra_dict(extra, info, True) + + nheaders += 1 + nread += parse_file_metadata.HEADER_LENGTH + info["extra_len"] + if(not detached): + nread += info['nbytes'] + handle.seek(nread, 0) + print "\n\n" + +if __name__ == "__main__": + usage="%prog: [options] filename" + description = "Read in a GNU Radio file with meta data, extracts the header and prints it." + + parser = OptionParser(conflict_handler="resolve", + usage=usage, description=description) + parser.add_option("-D", "--detached", action="store_true", default=False, + help="Used if header is detached.") + (options, args) = parser.parse_args () + + if(len(args) < 1): + sys.stderr.write("No filename given\n") + sys.exit(1) + + filename = args[0] + main(filename, options.detached) diff --git a/gr-utils/src/python/grcc b/gr-utils/src/python/grcc new file mode 100755 index 000000000..7e5665dc0 --- /dev/null +++ b/gr-utils/src/python/grcc @@ -0,0 +1,66 @@ +#!/usr/bin/env python +# +# Copyright 2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +try: + from grc.python.Platform import Platform +except ImportError: + from gnuradio.grc.python.Platform import Platform + +from optparse import OptionParser +import os, sys + +class grcc: + def __init__(self, grcfile, out_dir): + self.out_dir = out_dir + self.platform = Platform() + data = self.platform.parse_flow_graph(grcfile) + + self.fg = self.platform.get_new_flow_graph() + self.fg.import_data(data) + self.fg.validate() + + self.gen = self.platform.get_generator()(self.fg, out_dir) + self.gen.write() + + def exec_program(self): + progname = self.fg.get_option('id') + os.system("{0}/{1}.py".format(self.out_dir, progname)) + +if __name__ == "__main__": + usage="%prog: [options] filename" + description = "Compiles a GRC file (.grc) into a GNU Radio Python program. The program is stored in ~/.grc_gnuradio by default, but this location can be changed with the -d option." + + parser = OptionParser(conflict_handler="resolve", usage=usage, description=description) + parser.add_option("-d", "--directory", type="string", default='{0}/.grc_gnuradio/'.format(os.environ["HOME"]), + help="Specify the directory to output the compile program [default=%default]") + parser.add_option("-e", "--execute", action="store_true", default=False, + help="Run the program after compiling [default=%default]") + (options, args) = parser.parse_args () + + if(len(args) != 1): + sys.stderr.write("Please specify a GRC file name to compile.\n") + sys.exit(1) + + g = grcc(args[0], options.directory+"/") + + if(options.execute): + g.exec_program() diff --git a/grc/base/Block.py b/grc/base/Block.py index fe7ad3c2f..a20be9db9 100644 --- a/grc/base/Block.py +++ b/grc/base/Block.py @@ -67,6 +67,7 @@ class Block(Element): self._name = n.find('name') self._key = n.find('key') self._category = n.find('category') or '' + self._grc_source = n.find('grc_source') or '' self._block_wrapper_path = n.find('block_wrapper_path') #create the param objects self._params = list() diff --git a/grc/base/Platform.py b/grc/base/Platform.py index 94d0077ea..d4b09088b 100644 --- a/grc/base/Platform.py +++ b/grc/base/Platform.py @@ -61,6 +61,10 @@ class Platform(_Element): #create a dummy flow graph for the blocks self._flow_graph = _Element(self) #search for *.xml files in the given search path + + self.loadblocks(); + + def loadblocks(self): xml_files = list() for block_path in self._block_paths: if os.path.isfile(block_path): xml_files.append(block_path) diff --git a/grc/blocks/block_tree.xml b/grc/blocks/block_tree.xml index d7ec82e4a..183883959 100644 --- a/grc/blocks/block_tree.xml +++ b/grc/blocks/block_tree.xml @@ -37,6 +37,15 @@ <block>virtual_sink</block> <block>gr_tag_debug</block> </cat> + <cat> + <name>Message Tools</name> + <block>gr_message_debug</block> + <block>gr_message_strobe</block> + <block>gr_pdu_to_tagged_stream</block> + <block>gr_tagged_stream_to_pdu</block> + <block>gr_tuntap_pdu</block> + <block>gr_socket_pdu</block> + </cat> <cat> <name>Operators</name> <block>gr_add_xx</block> diff --git a/grc/blocks/gr_file_source.xml b/grc/blocks/gr_file_source.xml index fcc7a7040..5f0e16b27 100644 --- a/grc/blocks/gr_file_source.xml +++ b/grc/blocks/gr_file_source.xml @@ -9,6 +9,7 @@ <key>gr_file_source</key> <import>from gnuradio import gr</import> <make>gr.file_source($type.size*$vlen, $file, $repeat)</make> + <callback>open($file, $repeat)</callback> <param> <name>File</name> <key>file</key> diff --git a/grc/blocks/gr_message_debug.xml b/grc/blocks/gr_message_debug.xml new file mode 100644 index 000000000..4d73fbd9c --- /dev/null +++ b/grc/blocks/gr_message_debug.xml @@ -0,0 +1,27 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Message Debug +################################################### + --> +<block> + <name>Message Debug</name> + <key>gr_message_debug</key> + <import>from gnuradio import gr</import> + <make>gr.message_debug()</make> + <sink> + <name>print</name> + <type>message</type> + <optional>1</optional> + </sink> + <sink> + <name>store</name> + <type>message</type> + <optional>1</optional> + </sink> + <sink> + <name>print_pdu_verbose</name> + <type>message</type> + <optional>1</optional> + </sink> +</block> diff --git a/grc/blocks/gr_message_strobe.xml b/grc/blocks/gr_message_strobe.xml new file mode 100644 index 000000000..60a7724df --- /dev/null +++ b/grc/blocks/gr_message_strobe.xml @@ -0,0 +1,35 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Message Strobe +################################################### + --> +<block> + <name>Message Strobe</name> + <key>gr_message_strobe</key> + <import>from gnuradio import gr</import> + <import>from gruel import pmt</import> + <make>gr.message_strobe($msg, $period)</make> + <param> + <name>Message PMT</name> + <key>msg</key> + <value>pmt.pmt_intern("TEST")</value> + <type>raw</type> + </param> + <param> + <name>Period (ms)</name> + <key>period</key> + <value>1000</value> + <type>real</type> + </param> + <sink> + <name>set_msg</name> + <type>message</type> + <optional>1</optional> + </sink> + <source> + <name>strobe</name> + <type>message</type> + <optional>1</optional> + </source> +</block> diff --git a/grc/blocks/gr_pdu_to_tagged_stream.xml b/grc/blocks/gr_pdu_to_tagged_stream.xml new file mode 100644 index 000000000..fc1c4d16a --- /dev/null +++ b/grc/blocks/gr_pdu_to_tagged_stream.xml @@ -0,0 +1,40 @@ +<?xml version="1.0"?> +<!-- +################################################### +## PDU Message to Tagged Stream +################################################### + --> +<block> + <name>PDU to Tagged Stream</name> + <key>gr_pdu_to_tagged_stream</key> + <import>from gnuradio import gr</import> + <make>gr.pdu_to_tagged_stream($type.tv)</make> + <param> + <name>Item Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Byte</name> + <key>byte</key> + <opt>tv:gr.BYTE</opt> + </option> + <option> + <name>Complex</name> + <key>complex</key> + <opt>tv:gr.COMPLEX</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>tv:gr.FLOAT</opt> + </option> + </param> + <sink> + <name>pdus</name> + <type>message</type> + </sink> + <source> + <name>out</name> + <type>$type</type> + </source> +</block> diff --git a/grc/blocks/gr_socket_pdu.xml b/grc/blocks/gr_socket_pdu.xml new file mode 100644 index 000000000..a175c3699 --- /dev/null +++ b/grc/blocks/gr_socket_pdu.xml @@ -0,0 +1,62 @@ +<?xml version="1.0"?> +<!-- +################################################### +## Socket PDU Message source/sink +################################################### + --> +<block> + <name>Socket PDU</name> + <key>gr_socket_pdu</key> + <import>from gnuradio import gr</import> + <make>gr.socket_pdu($type, $host, $port, $mtu)</make> + <param> + <name>Type</name> + <key>type</key> + <value>TCP_SERVER</value> + <type>enum</type> + <option> + <name>TCP Server</name> + <key>"TCP_SERVER"</key> + </option> + <option> + <name>TCP Client</name> + <key>"TCP_CLIENT"</key> + </option> + <option> + <name>UDP Server</name> + <key>"UDP_SERVER"</key> + </option> + <option> + <name>UDP Client</name> + <key>"UDP_CLIENT"</key> + </option> + </param> + <param> + <name>Host</name> + <key>host</key> + <value></value> + <type>string</type> + </param> + <param> + <name>Port</name> + <key>port</key> + <value>52001</value> + <type>string</type> + </param> + <param> + <name>MTU</name> + <key>mtu</key> + <value>10000</value> + <type>int</type> + </param> + <sink> + <name>pdus</name> + <type>message</type> + <optional>1</optional> + </sink> + <source> + <name>pdus</name> + <type>message</type> + <optional>1</optional> + </source> +</block> diff --git a/grc/blocks/gr_sub_xx.xml b/grc/blocks/gr_sub_xx.xml index f1f4797e0..c677747da 100644 --- a/grc/blocks/gr_sub_xx.xml +++ b/grc/blocks/gr_sub_xx.xml @@ -48,7 +48,7 @@ <type>int</type> </param> <check>$vlen > 0</check> - <check>$num_inputs >= 2</check> + <check>$num_inputs >= 1</check> <sink> <name>in</name> <type>$type</type> diff --git a/grc/blocks/gr_tagged_stream_to_pdu.xml b/grc/blocks/gr_tagged_stream_to_pdu.xml new file mode 100644 index 000000000..e70a01608 --- /dev/null +++ b/grc/blocks/gr_tagged_stream_to_pdu.xml @@ -0,0 +1,40 @@ +<?xml version="1.0"?> +<!-- +################################################### +## Tagged Stream to PDU Message +################################################### + --> +<block> + <name>Tagged Stream to PDU</name> + <key>gr_tagged_stream_to_pdu</key> + <import>from gnuradio import gr</import> + <make>gr.tagged_stream_to_pdu($type.tv)</make> + <param> + <name>Item Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Byte</name> + <key>byte</key> + <opt>tv:gr.BYTE</opt> + </option> + <option> + <name>Complex</name> + <key>complex</key> + <opt>tv:gr.COMPLEX</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>tv:gr.FLOAT</opt> + </option> + </param> + <sink> + <name>in</name> + <type>$type</type> + </sink> + <source> + <name>pdus</name> + <type>message</type> + </source> +</block> diff --git a/grc/blocks/gr_tuntap_pdu.xml b/grc/blocks/gr_tuntap_pdu.xml new file mode 100644 index 000000000..f169345af --- /dev/null +++ b/grc/blocks/gr_tuntap_pdu.xml @@ -0,0 +1,34 @@ +<?xml version="1.0"?> +<!-- +################################################### +## Tuntap PDU Message source/sink +################################################### + --> +<block> + <name>TunTap PDU</name> + <key>gr_tuntap_pdu</key> + <import>from gnuradio import gr</import> + <make>gr.tuntap_pdu($ifn, $mtu)</make> + <param> + <name>Interface Name</name> + <key>ifn</key> + <value>tun0</value> + <type>string</type> + </param> + <param> + <name>MTU</name> + <key>mtu</key> + <value>10000</value> + <type>int</type> + </param> + <sink> + <name>pdus</name> + <type>message</type> + <optional>1</optional> + </sink> + <source> + <name>pdus</name> + <type>message</type> + <optional>1</optional> + </source> +</block> diff --git a/grc/blocks/pad_sink.xml b/grc/blocks/pad_sink.xml index 2e9495260..f0e10a339 100644 --- a/grc/blocks/pad_sink.xml +++ b/grc/blocks/pad_sink.xml @@ -7,7 +7,9 @@ <block> <name>Pad Sink</name> <key>pad_sink</key> - <make></make> + <make>#if str($type) == "message" +None;self.message_port_register_hier_in($label) +#end if</make> <param> <name>Label</name> <key>label</key> @@ -43,6 +45,16 @@ <key>byte</key> <opt>size:gr.sizeof_char</opt> </option> + <option> + <name>Message</name> + <key>message</key> + <opt>size:0</opt> + </option> + <option> + <name>Wildcard</name> + <key></key> + <opt>size:0</opt> + </option> </param> <param> <name>Vec Length</name> @@ -50,6 +62,21 @@ <value>1</value> <type>int</type> </param> + <param> + <name>Optional</name> + <key>optional</key> + <value>False</value> + <type>bool</type> + <hide>part</hide> + <option> + <name>Optional</name> + <key>True</key> + </option> + <option> + <name>Required</name> + <key>False</key> + </option> + </param> <check>$vlen > 0</check> <sink> <name>in</name> diff --git a/grc/blocks/pad_source.xml b/grc/blocks/pad_source.xml index 7b2210cbb..a56a65dcc 100644 --- a/grc/blocks/pad_source.xml +++ b/grc/blocks/pad_source.xml @@ -7,7 +7,9 @@ <block> <name>Pad Source</name> <key>pad_source</key> - <make></make> + <make>#if str($type) == "message" +None;self.message_port_register_hier_out($label) +#end if</make> <param> <name>Label</name> <key>label</key> @@ -43,6 +45,16 @@ <key>byte</key> <opt>size:gr.sizeof_char</opt> </option> + <option> + <name>Message</name> + <key>message</key> + <opt>size:0</opt> + </option> + <option> + <name>Wildcard</name> + <key></key> + <opt>size:0</opt> + </option> </param> <param> <name>Vec Length</name> @@ -50,6 +62,21 @@ <value>1</value> <type>int</type> </param> + <param> + <name>Optional</name> + <key>optional</key> + <value>False</value> + <type>bool</type> + <hide>part</hide> + <option> + <name>Optional</name> + <key>True</key> + </option> + <option> + <name>Required</name> + <key>False</key> + </option> + </param> <check>$vlen > 0</check> <source> <name>out</name> diff --git a/grc/gui/ActionHandler.py b/grc/gui/ActionHandler.py index 476c82b4f..9fb5e4ebf 100644 --- a/grc/gui/ActionHandler.py +++ b/grc/gui/ActionHandler.py @@ -53,6 +53,7 @@ class ActionHandler: self.clipboard = None for action in Actions.get_all_actions(): action.connect('activate', self._handle_action) #setup the main window + self.platform = platform; self.main_window = MainWindow(platform) self.main_window.connect('delete-event', self._quit) self.main_window.connect('key-press-event', self._handle_key_press) @@ -152,6 +153,134 @@ class ActionHandler: self.get_flow_graph().update() self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data()) self.get_page().set_saved(False) + ################################################## + # Create heir block + ################################################## + elif action == Actions.BLOCK_CREATE_HIER: + + # keeping track of coordinates for pasting later + coords = self.get_flow_graph().get_selected_blocks()[0].get_coordinate() + x,y = coords + x_min = x + y_min = y + + pads = []; + params = []; + + # Save the state of the leaf blocks + for block in self.get_flow_graph().get_selected_blocks(): + + # Check for string variables within the blocks + for param in block.get_params(): + for variable in self.get_flow_graph().get_variables(): + # If a block parameter exists that is a variable, create a parameter for it + if param.get_value() == variable.get_id(): + params.append(param.get_value()) + for flow_param in self.get_flow_graph().get_parameters(): + # If a block parameter exists that is a parameter, create a parameter for it + if param.get_value() == flow_param.get_id(): + params.append(param.get_value()) + + + # keep track of x,y mins for pasting later + (x,y) = block.get_coordinate() + if x < x_min: + x_min = x + if y < y_min: + y_min = y + + for connection in block.get_connections(): + + # Get id of connected blocks + source_id = connection.get_source().get_parent().get_id() + sink_id = connection.get_sink().get_parent().get_id() + + # If connected block is not in the list of selected blocks create a pad for it + if self.get_flow_graph().get_block(source_id) not in self.get_flow_graph().get_selected_blocks(): + pads.append({'key': connection.get_sink().get_key(), 'coord': connection.get_source().get_coordinate(), 'block_id' : block.get_id(), 'direction': 'source'}) + + if self.get_flow_graph().get_block(sink_id) not in self.get_flow_graph().get_selected_blocks(): + pads.append({'key': connection.get_source().get_key(), 'coord': connection.get_sink().get_coordinate(), 'block_id' : block.get_id(), 'direction': 'sink'}) + + + # Copy the selected blocks and paste them into a new page + # then move the flowgraph to a reasonable position + Actions.BLOCK_COPY() + self.main_window.new_page() + Actions.BLOCK_PASTE() + coords = (x_min,y_min) + self.get_flow_graph().move_selected(coords) + + + # Set flow graph to heir block type + top_block = self.get_flow_graph().get_block("top_block") + top_block.get_param('generate_options').set_value('hb') + + # this needs to be a unique name + top_block.get_param('id').set_value('new_heir') + + # Remove the default samp_rate variable block that is created + remove_me = self.get_flow_graph().get_block("samp_rate") + self.get_flow_graph().remove_element(remove_me) + + + # Add the param blocks along the top of the window + x_pos = 150 + for param in params: + param_id = self.get_flow_graph().add_new_block('parameter',(x_pos,10)) + param_block = self.get_flow_graph().get_block(param_id) + param_block.get_param('id').set_value(param) + x_pos = x_pos + 100 + + for pad in pads: + # Add the pad sources and sinks within the new heir block + if pad['direction'] == 'sink': + + # Add new PAD_SINK block to the canvas + pad_id = self.get_flow_graph().add_new_block('pad_sink', pad['coord']) + + # setup the references to the sink and source + pad_block = self.get_flow_graph().get_block(pad_id) + pad_sink = pad_block.get_sinks()[0] + + source_block = self.get_flow_graph().get_block(pad['block_id']) + source = source_block.get_source(pad['key']) + + # Ensure the port types match + while pad_sink.get_type() != source.get_type(): + + # Special case for some blocks that have non-standard type names, e.g. uhd + if pad_sink.get_type() == 'complex' and source.get_type() == 'fc32': + break; + pad_block.type_controller_modify(1) + + # Connect the pad to the proper sinks + new_connection = self.get_flow_graph().connect(source,pad_sink) + + elif pad['direction'] == 'source': + pad_id = self.get_flow_graph().add_new_block('pad_source', pad['coord']) + + # setup the references to the sink and source + pad_block = self.get_flow_graph().get_block(pad_id) + pad_source = pad_block.get_sources()[0] + + sink_block = self.get_flow_graph().get_block(pad['block_id']) + sink = sink_block.get_sink(pad['key']) + + # Ensure the port types match + while sink.get_type() != pad_source.get_type(): + # Special case for some blocks that have non-standard type names, e.g. uhd + if pad_source.get_type() == 'complex' and sink.get_type() == 'fc32': + break; + pad_block.type_controller_modify(1) + + # Connect the pad to the proper sinks + new_connection = self.get_flow_graph().connect(pad_source,sink) + + # update the new heir block flow graph + self.get_flow_graph().update() + + ################################################## # Move/Rotate/Delete/Create ################################################## @@ -263,6 +392,7 @@ class ActionHandler: else: try: ParseXML.to_file(self.get_flow_graph().export_data(), self.get_page().get_file_path()) + self.get_flow_graph().grc_file_path = self.get_page().get_file_path() self.get_page().set_saved(True) except IOError: Messages.send_fail_save(self.get_page().get_file_path()) @@ -302,6 +432,15 @@ class ActionHandler: except: print "could not kill process: %d"%self.get_page().get_proc().pid elif action == Actions.PAGE_CHANGE: #pass and run the global actions pass + elif action == Actions.RELOAD_BLOCKS: + self.platform.loadblocks() + self.main_window.btwin.clear(); + self.platform.load_block_tree(self.main_window.btwin); + elif action == Actions.OPEN_HIER: + bn = []; + for b in self.get_flow_graph().get_selected_blocks(): + if b._grc_source: + self.main_window.new_page(b._grc_source, show=True); else: print '!!! Action "%s" not handled !!!'%action ################################################## # Global Actions for all States @@ -319,6 +458,9 @@ class ActionHandler: #update enable/disable Actions.BLOCK_ENABLE.set_sensitive(bool(self.get_flow_graph().get_selected_blocks())) Actions.BLOCK_DISABLE.set_sensitive(bool(self.get_flow_graph().get_selected_blocks())) + Actions.BLOCK_CREATE_HIER.set_sensitive(bool(self.get_flow_graph().get_selected_blocks())) + Actions.OPEN_HIER.set_sensitive(bool(self.get_flow_graph().get_selected_blocks())) + Actions.RELOAD_BLOCKS.set_sensitive(True) #set the exec and stop buttons self.update_exec_stop() #saved status diff --git a/grc/gui/Actions.py b/grc/gui/Actions.py index 4d196477e..8087f4955 100644 --- a/grc/gui/Actions.py +++ b/grc/gui/Actions.py @@ -198,6 +198,12 @@ BLOCK_DISABLE = Action( stock_id=gtk.STOCK_DISCONNECT, keypresses=(gtk.keysyms.d, NO_MODS_MASK), ) +BLOCK_CREATE_HIER = Action( + label='C_reate Hier', + tooltip='Create hier block from selected blocks', + stock_id=gtk.STOCK_CONNECT, + keypresses=(gtk.keysyms.c, NO_MODS_MASK), +) BLOCK_CUT = Action( label='Cu_t', tooltip='Cut', @@ -273,3 +279,13 @@ BLOCK_INC_TYPE = Action( BLOCK_DEC_TYPE = Action( keypresses=(gtk.keysyms.Up, NO_MODS_MASK), ) +RELOAD_BLOCKS = Action( + label='Reload _Blocks', + tooltip='Reload Blocks', + stock_id=gtk.STOCK_REFRESH +) +OPEN_HIER = Action( + label='Open H_ier', + tooltip='Open the source of the selected hierarchical block', + stock_id=gtk.STOCK_JUMP_TO, +) diff --git a/grc/gui/Bars.py b/grc/gui/Bars.py index 8fd167869..d95d23f1f 100644 --- a/grc/gui/Bars.py +++ b/grc/gui/Bars.py @@ -49,6 +49,9 @@ TOOLBAR_LIST = ( None, Actions.BLOCK_ENABLE, Actions.BLOCK_DISABLE, + None, + Actions.RELOAD_BLOCKS, + Actions.OPEN_HIER, ) ##The list of actions and categories for the menu bar. diff --git a/grc/gui/BlockTreeWindow.py b/grc/gui/BlockTreeWindow.py index 0175c8bec..62afb6205 100644 --- a/grc/gui/BlockTreeWindow.py +++ b/grc/gui/BlockTreeWindow.py @@ -90,6 +90,11 @@ class BlockTreeWindow(gtk.VBox): #initialize self._update_add_button() + def clear(self): + self.treestore.clear(); + self._categories = {tuple(): None} + + ############################################################ ## Block Tree Methods ############################################################ diff --git a/grc/gui/FlowGraph.py b/grc/gui/FlowGraph.py index 9f3326ada..67e5af97b 100644 --- a/grc/gui/FlowGraph.py +++ b/grc/gui/FlowGraph.py @@ -63,6 +63,8 @@ class FlowGraph(Element): Actions.BLOCK_ENABLE, Actions.BLOCK_DISABLE, Actions.BLOCK_PARAM_MODIFY, + Actions.BLOCK_CREATE_HIER, + Actions.OPEN_HIER, ]: self._context_menu.append(action.create_menu_item()) ########################################################################### @@ -97,6 +99,8 @@ class FlowGraph(Element): block.get_param('id').set_value(id) Actions.ELEMENT_CREATE() + return id + ########################################################################### # Copy Paste ########################################################################### diff --git a/grc/gui/MainWindow.py b/grc/gui/MainWindow.py index 2f761df1f..37a100c94 100644 --- a/grc/gui/MainWindow.py +++ b/grc/gui/MainWindow.py @@ -93,7 +93,8 @@ class MainWindow(gtk.Window): #flow_graph_box.pack_start(self.scrolled_window) self.flow_graph_vpaned.pack1(self.notebook) self.hpaned.pack1(self.flow_graph_vpaned) - self.hpaned.pack2(BlockTreeWindow(platform, self.get_flow_graph), False) #dont allow resize + self.btwin = BlockTreeWindow(platform, self.get_flow_graph); + self.hpaned.pack2(self.btwin, False) #dont allow resize #create the reports window self.text_display = TextDisplay() #house the reports in a scrolled window @@ -169,6 +170,8 @@ class MainWindow(gtk.Window): try: #try to load from file if file_path: Messages.send_start_load(file_path) flow_graph = self._platform.get_new_flow_graph() + flow_graph.grc_file_path = file_path; + #print flow_graph page = NotebookPage( self, flow_graph=flow_graph, diff --git a/grc/python/Connection.py b/grc/python/Connection.py index 218baf074..341dd2d82 100644 --- a/grc/python/Connection.py +++ b/grc/python/Connection.py @@ -31,6 +31,9 @@ class Connection(_Connection, _GUIConnection): def is_msg(self): return self.get_source().get_type() == self.get_sink().get_type() == 'msg' + def is_message(self): + return self.get_source().get_type() == self.get_sink().get_type() == 'message' + def validate(self): """ Validate the connections. diff --git a/grc/python/Constants.py b/grc/python/Constants.py index 1a65caf1c..b8dc9a96a 100644 --- a/grc/python/Constants.py +++ b/grc/python/Constants.py @@ -58,6 +58,7 @@ CORE_TYPES = ( #name, key, sizeof, color ('Integer 16', 's16', 2, '#FFFF66'), ('Integer 8', 's8', 1, '#FF66FF'), ('Message Queue', 'msg', 0, '#777777'), + ('Async Message', 'message', 0, '#C0C0C0'), ('Wildcard', '', 0, '#FFFFFF'), ) diff --git a/grc/python/FlowGraph.py b/grc/python/FlowGraph.py index 89a169355..376c2e337 100644 --- a/grc/python/FlowGraph.py +++ b/grc/python/FlowGraph.py @@ -58,12 +58,15 @@ class FlowGraph(_FlowGraph, _GUIFlowGraph): 'in': self.get_pad_sources(), 'out': self.get_pad_sinks(), }[direction] + # we only want stream ports + sorted_pads = filter(lambda b: b.get_param('type').get_evaluated() != 'message', sorted_pads); #load io signature return [{ 'label': str(pad.get_param('label').get_evaluated()), 'type': str(pad.get_param('type').get_evaluated()), 'vlen': str(pad.get_param('vlen').get_evaluated()), 'size': pad.get_param('type').get_opt('size'), + 'optional': bool(pad.get_param('optional').get_evaluated()), } for pad in sorted_pads] def get_pad_sources(self): @@ -82,6 +85,14 @@ class FlowGraph(_FlowGraph, _GUIFlowGraph): pads = filter(lambda b: b.get_key() == 'pad_sink', self.get_enabled_blocks()) return sorted(pads, lambda x, y: cmp(x.get_id(), y.get_id())) + def get_msg_pad_sources(self): + ps = self.get_pad_sources(); + return filter(lambda b: b.get_param('type').get_evaluated() == 'message', ps); + + def get_msg_pad_sinks(self): + ps = self.get_pad_sinks(); + return filter(lambda b: b.get_param('type').get_evaluated() == 'message', ps); + def get_imports(self): """ Get a set of all import statments in this flow graph namespace. diff --git a/grc/python/Generator.py b/grc/python/Generator.py index 2a6fe51d5..616ea00fc 100644 --- a/grc/python/Generator.py +++ b/grc/python/Generator.py @@ -116,8 +116,9 @@ Add a Misc->Throttle block to your flow graph to avoid CPU congestion.''') #list of regular blocks (all blocks minus the special ones) blocks = filter(lambda b: b not in (imports + parameters), blocks) #list of connections where each endpoint is enabled - connections = filter(lambda c: not c.is_msg(), self._flow_graph.get_enabled_connections()) + connections = filter(lambda c: not (c.is_msg() or c.is_message()), self._flow_graph.get_enabled_connections()) messages = filter(lambda c: c.is_msg(), self._flow_graph.get_enabled_connections()) + messages2 = filter(lambda c: c.is_message(), self._flow_graph.get_enabled_connections()) #list of variable names var_ids = [var.get_id() for var in parameters + variables] #prepend self. @@ -142,6 +143,7 @@ Add a Misc->Throttle block to your flow graph to avoid CPU congestion.''') 'blocks': blocks, 'connections': connections, 'messages': messages, + 'messages2': messages2, 'generate_options': self._generate_options, 'var_id2cbs': var_id2cbs, } diff --git a/grc/python/Port.py b/grc/python/Port.py index 9f8b50d05..738a33ba7 100644 --- a/grc/python/Port.py +++ b/grc/python/Port.py @@ -116,7 +116,7 @@ class Port(_Port, _GUIPort): _Port.validate(self) if not self.get_enabled_connections() and not self.get_optional(): self.add_error_message('Port is not connected.') - if not self.is_source() and len(self.get_enabled_connections()) > 1: + if not self.is_source() and (not self.get_type() == "message") and len(self.get_enabled_connections()) > 1: self.add_error_message('Port has too many connections.') #message port logic if self.get_type() == 'msg': diff --git a/grc/python/block.dtd b/grc/python/block.dtd index 41a744d07..292ea06cb 100644 --- a/grc/python/block.dtd +++ b/grc/python/block.dtd @@ -25,7 +25,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA Top level element. A block contains a name, ...parameters list, and list of IO ports. --> -<!ELEMENT block (name, key, category?, throttle?, import*, var_make?, make, callback*, param*, check*, sink*, source*, doc?)> +<!ELEMENT block (name, key, category?, throttle?, import*, var_make?, make, callback*, param*, check*, sink*, source*, doc?, grc_source?)> <!-- Sub level elements. --> @@ -40,6 +40,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA <!ELEMENT category (#PCDATA)> <!ELEMENT import (#PCDATA)> <!ELEMENT doc (#PCDATA)> +<!ELEMENT grc_source (#PCDATA)> <!ELEMENT name (#PCDATA)> <!ELEMENT key (#PCDATA)> <!ELEMENT check (#PCDATA)> diff --git a/grc/python/convert_hier.py b/grc/python/convert_hier.py index c6ca5b769..508ec63b2 100644 --- a/grc/python/convert_hier.py +++ b/grc/python/convert_hier.py @@ -25,6 +25,8 @@ def convert_hier(flow_graph, python_file): #extract info from the flow graph input_sigs = flow_graph.get_io_signaturev('in') output_sigs = flow_graph.get_io_signaturev('out') + input_msgp = flow_graph.get_msg_pad_sources(); + output_msgp = flow_graph.get_msg_pad_sinks(); parameters = flow_graph.get_parameters() block_key = flow_graph.get_option('id') block_name = flow_graph.get_option('title') or flow_graph.get_option('id').replace('_', ' ').title() @@ -55,24 +57,41 @@ def convert_hier(flow_graph, python_file): param_n['type'] = 'raw' params_n.append(param_n) block_n['param'] = params_n - #sink data + #sink data stream ports block_n['sink'] = list() for input_sig in input_sigs: sink_n = odict() sink_n['name'] = input_sig['label'] sink_n['type'] = input_sig['type'] sink_n['vlen'] = input_sig['vlen'] + if input_sig['optional']: sink_n['optional'] = '1' block_n['sink'].append(sink_n) - #source data + #sink data msg ports + for input_sig in input_msgp: + sink_n = odict() + sink_n['name'] = input_sig.get_param("label").get_value(); + sink_n['type'] = "message" + sink_n['optional'] = input_sig.get_param("optional").get_value(); + block_n['sink'].append(sink_n) + #source data stream ports block_n['source'] = list() for output_sig in output_sigs: source_n = odict() source_n['name'] = output_sig['label'] source_n['type'] = output_sig['type'] source_n['vlen'] = output_sig['vlen'] + if output_sig['optional']: source_n['optional'] = '1' + block_n['source'].append(source_n) + #source data msg ports + for output_sig in output_msgp: + source_n = odict() + source_n['name'] = output_sig.get_param("label").get_value(); + source_n['type'] = "message" + source_n['optional'] = output_sig.get_param("optional").get_value(); block_n['source'].append(source_n) #doc data block_n['doc'] = "%s\n%s\n%s"%(block_author, block_desc, python_file) + block_n['grc_source'] = "%s"%(flow_graph.grc_file_path) #write the block_n to file xml_file = python_file + '.xml' ParseXML.to_file({'block': block_n}, xml_file) diff --git a/grc/python/flow_graph.tmpl b/grc/python/flow_graph.tmpl index 17feb01f6..163e7f76a 100644 --- a/grc/python/flow_graph.tmpl +++ b/grc/python/flow_graph.tmpl @@ -191,6 +191,32 @@ gr.io_signaturev($(len($io_sigs)), $(len($io_sigs)), [$(', '.join($size_strs))]) #end for ######################################################## +##Create Asynch Message Connections +######################################################## +#if $messages2 + $DIVIDER + # Asynch Message Connections + $DIVIDER +#end if +#for $msg in $messages2 + #set $sr = $msg.get_source() + #set $source = "self.%s"%($sr.get_parent().get_id()) + #set $source_port = $sr.get_name(); + #if $sr.get_parent().get_key() == "pad_source" + #set $source = "self" + #set $source_port = $sr.get_parent().get_param("label").get_value(); + #end if + #set $sk = $msg.get_sink() + #set $sink = "self.%s"%($sk.get_parent().get_id()) + #set $sink_port = $sk.get_name(); + #if $sk.get_parent().get_key() == "pad_sink" + #set $sink = "self" + #set $sink_port = $sk.get_parent().get_param("label").get_value(); + #end if + self.msg_connect($source, "$source_port", $sink, "$sink_port") +#end for + +######################################################## ##Create Callbacks ## Write a set method for this variable that calls the callbacks ######################################################## diff --git a/gruel/src/include/gruel/msg_accepter.h b/gruel/src/include/gruel/msg_accepter.h index 2dc1a6859..45acb3c78 100644 --- a/gruel/src/include/gruel/msg_accepter.h +++ b/gruel/src/include/gruel/msg_accepter.h @@ -37,13 +37,13 @@ namespace gruel { virtual ~msg_accepter(); /*! - * \brief send \p msg to \p msg_accepter + * \brief send \p msg to \p msg_accepter on port \p which_port * * Sending a message is an asynchronous operation. The \p post * call will not wait for the message either to arrive at the * destination or to be received. */ - virtual void post(pmt::pmt_t msg) = 0; + virtual void post(pmt::pmt_t which_port, pmt::pmt_t msg) = 0; }; typedef boost::shared_ptr<msg_accepter> msg_accepter_sptr; diff --git a/gruel/src/include/gruel/msg_passing.h b/gruel/src/include/gruel/msg_passing.h index 0cc0cd111..25f30118f 100644 --- a/gruel/src/include/gruel/msg_passing.h +++ b/gruel/src/include/gruel/msg_passing.h @@ -36,6 +36,7 @@ namespace gruel { * \brief send message to msg_accepter * * \param accepter is the target of the send. + * \param which_port A pmt symbol describing the port by name. * \param msg is the message to send. It's usually a pmt tuple. * * Sending a message is an asynchronous operation. The \p send @@ -45,9 +46,9 @@ namespace gruel { * \returns msg */ static inline pmt::pmt_t - send(msg_accepter_sptr accepter, const pmt::pmt_t &msg) + send(msg_accepter_sptr accepter, const pmt::pmt_t &which_port, const pmt::pmt_t &msg) { - accepter->post(msg); + accepter->post(which_port, msg); return msg; } @@ -55,6 +56,7 @@ namespace gruel { * \brief send message to msg_accepter * * \param accepter is the target of the send. + * \param which_port A pmt symbol describing the port by name. * \param msg is the message to send. It's usually a pmt tuple. * * Sending a message is an asynchronous operation. The \p send @@ -64,9 +66,9 @@ namespace gruel { * \returns msg */ static inline pmt::pmt_t - send(msg_accepter *accepter, const pmt::pmt_t &msg) + send(msg_accepter *accepter, const pmt::pmt_t &which_port, const pmt::pmt_t &msg) { - accepter->post(msg); + accepter->post(which_port, msg); return msg; } @@ -74,6 +76,7 @@ namespace gruel { * \brief send message to msg_accepter * * \param accepter is the target of the send. + * \param which_port A pmt symbol describing the port by name. * \param msg is the message to send. It's usually a pmt tuple. * * Sending a message is an asynchronous operation. The \p send @@ -83,9 +86,9 @@ namespace gruel { * \returns msg */ static inline pmt::pmt_t - send(msg_accepter &accepter, const pmt::pmt_t &msg) + send(msg_accepter &accepter, const pmt::pmt_t &which_port, const pmt::pmt_t &msg) { - accepter.post(msg); + accepter.post(which_port, msg); return msg; } @@ -93,6 +96,7 @@ namespace gruel { * \brief send message to msg_accepter * * \param accepter is the target of the send. precond: pmt_is_msg_accepter(accepter) + * \param which_port A pmt symbol describing the port by name. * \param msg is the message to send. It's usually a pmt tuple. * * Sending a message is an asynchronous operation. The \p send @@ -102,9 +106,9 @@ namespace gruel { * \returns msg */ static inline pmt::pmt_t - send(pmt::pmt_t accepter, const pmt::pmt_t &msg) + send(pmt::pmt_t accepter, const pmt::pmt_t &which_port, const pmt::pmt_t &msg) { - return send(pmt_msg_accepter_ref(accepter), msg); + return send(pmt_msg_accepter_ref(accepter), which_port, msg); } } /* namespace gruel */ diff --git a/gruel/src/include/gruel/pmt.h b/gruel/src/include/gruel/pmt.h index 1e8b38627..383a1d44d 100644 --- a/gruel/src/include/gruel/pmt.h +++ b/gruel/src/include/gruel/pmt.h @@ -32,6 +32,7 @@ #include <stdint.h> #include <iosfwd> #include <stdexcept> +#include <vector> namespace gruel { class msg_accepter; @@ -222,6 +223,12 @@ GRUEL_API bool pmt_is_complex(pmt_t obj); //! Return a complex number constructed of the given real and imaginary parts. GRUEL_API pmt_t pmt_make_rectangular(double re, double im); +//! Return a complex number constructed of the given real and imaginary parts. +GRUEL_API pmt_t pmt_from_complex(double re, double im); + +//! Return a complex number constructed of the given a complex number. +GRUEL_API pmt_t pmt_from_complex(const std::complex<double> &z); + /*! * If \p z is complex, real or integer, return the closest complex<double>. * Otherwise, raise the wrong_type exception. @@ -412,17 +419,29 @@ GRUEL_API pmt_t pmt_make_c32vector(size_t k, std::complex<float> fill); GRUEL_API pmt_t pmt_make_c64vector(size_t k, std::complex<double> fill); GRUEL_API pmt_t pmt_init_u8vector(size_t k, const uint8_t *data); +GRUEL_API pmt_t pmt_init_u8vector(size_t k, const std::vector<uint8_t> &data); GRUEL_API pmt_t pmt_init_s8vector(size_t k, const int8_t *data); +GRUEL_API pmt_t pmt_init_s8vector(size_t k, const std::vector<int8_t> &data); GRUEL_API pmt_t pmt_init_u16vector(size_t k, const uint16_t *data); +GRUEL_API pmt_t pmt_init_u16vector(size_t k, const std::vector<uint16_t> &data); GRUEL_API pmt_t pmt_init_s16vector(size_t k, const int16_t *data); +GRUEL_API pmt_t pmt_init_s16vector(size_t k, const std::vector<int16_t> &data); GRUEL_API pmt_t pmt_init_u32vector(size_t k, const uint32_t *data); +GRUEL_API pmt_t pmt_init_u32vector(size_t k, const std::vector<uint32_t> &data); GRUEL_API pmt_t pmt_init_s32vector(size_t k, const int32_t *data); +GRUEL_API pmt_t pmt_init_s32vector(size_t k, const std::vector<int32_t> &data); GRUEL_API pmt_t pmt_init_u64vector(size_t k, const uint64_t *data); +GRUEL_API pmt_t pmt_init_u64vector(size_t k, const std::vector<uint64_t> &data); GRUEL_API pmt_t pmt_init_s64vector(size_t k, const int64_t *data); +GRUEL_API pmt_t pmt_init_s64vector(size_t k, const std::vector<int64_t> &data); GRUEL_API pmt_t pmt_init_f32vector(size_t k, const float *data); +GRUEL_API pmt_t pmt_init_f32vector(size_t k, const std::vector<float> &data); GRUEL_API pmt_t pmt_init_f64vector(size_t k, const double *data); +GRUEL_API pmt_t pmt_init_f64vector(size_t k, const std::vector<double> &data); GRUEL_API pmt_t pmt_init_c32vector(size_t k, const std::complex<float> *data); +GRUEL_API pmt_t pmt_init_c32vector(size_t k, const std::vector<std::complex<float> > &data); GRUEL_API pmt_t pmt_init_c64vector(size_t k, const std::complex<double> *data); +GRUEL_API pmt_t pmt_init_c64vector(size_t k, const std::vector<std::complex<double> > &data); GRUEL_API uint8_t pmt_u8vector_ref(pmt_t v, size_t k); GRUEL_API int8_t pmt_s8vector_ref(pmt_t v, size_t k); @@ -467,6 +486,20 @@ GRUEL_API const double *pmt_f64vector_elements(pmt_t v, size_t &len); //< len GRUEL_API const std::complex<float> *pmt_c32vector_elements(pmt_t v, size_t &len); //< len is in elements GRUEL_API const std::complex<double> *pmt_c64vector_elements(pmt_t v, size_t &len); //< len is in elements +// len is in elements +GRUEL_API const std::vector<uint8_t> pmt_u8vector_elements(pmt_t v); +GRUEL_API const std::vector<int8_t> pmt_s8vector_elements(pmt_t v); +GRUEL_API const std::vector<uint16_t> pmt_u16vector_elements(pmt_t v); +GRUEL_API const std::vector<int16_t> pmt_s16vector_elements(pmt_t v); +GRUEL_API const std::vector<uint32_t> pmt_u32vector_elements(pmt_t v); +GRUEL_API const std::vector<int32_t> pmt_s32vector_elements(pmt_t v); +GRUEL_API const std::vector<uint64_t> pmt_u64vector_elements(pmt_t v); +GRUEL_API const std::vector<int64_t> pmt_s64vector_elements(pmt_t v); +GRUEL_API const std::vector<float> pmt_f32vector_elements(pmt_t v); +GRUEL_API const std::vector<double> pmt_f64vector_elements(pmt_t v); +GRUEL_API const std::vector<std::complex<float> > pmt_c32vector_elements(pmt_t v); +GRUEL_API const std::vector<std::complex<double> > pmt_c64vector_elements(pmt_t v); + // Return non-const pointers to the elements GRUEL_API void *pmt_uniform_vector_writable_elements(pmt_t v, size_t &len); //< works with any; len is in bytes @@ -729,6 +762,16 @@ GRUEL_API pmt_t pmt_list6(const pmt_t& x1, const pmt_t& x2, const pmt_t& x3, con */ GRUEL_API pmt_t pmt_list_add(pmt_t list, const pmt_t& item); +/*! + * \brief Return \p list with \p item removed from it. + */ +GRUEL_API pmt_t pmt_list_rm(pmt_t list, const pmt_t& item); + +/*! + * \brief Return bool of \p list contains \p item + */ +GRUEL_API bool pmt_list_has(pmt_t list, const pmt_t& item); + /* * ------------------------------------------------------------------------ @@ -805,6 +848,15 @@ GRUEL_API std::string pmt_serialize_str(pmt_t obj); */ GRUEL_API pmt_t pmt_deserialize_str(std::string str); +/*! + * \brief Provide a comparator function object to allow pmt use in stl types + */ +class pmt_comperator { + public: + bool operator()(pmt::pmt_t const& p1, pmt::pmt_t const& p2) const + { return pmt::pmt_eqv(p1,p2)?false:p1.get()>p2.get(); } + }; + } /* namespace pmt */ #include <gruel/pmt_sugar.h> diff --git a/gruel/src/include/gruel/pmt_sugar.h b/gruel/src/include/gruel/pmt_sugar.h index 1d2b38ff1..bde7f716d 100644 --- a/gruel/src/include/gruel/pmt_sugar.h +++ b/gruel/src/include/gruel/pmt_sugar.h @@ -50,6 +50,12 @@ namespace pmt { //! Make pmt long static inline pmt_t + mp(long long unsigned x){ + return pmt_from_long(x); + } + + //! Make pmt long + static inline pmt_t mp(int x){ return pmt_from_long(x); } diff --git a/gruel/src/lib/pmt/pmt.cc b/gruel/src/lib/pmt/pmt.cc index 1d9125d4e..1d1e9ba7c 100644 --- a/gruel/src/lib/pmt/pmt.cc +++ b/gruel/src/lib/pmt/pmt.cc @@ -388,9 +388,19 @@ pmt_is_complex(pmt_t x) pmt_t pmt_make_rectangular(double re, double im) { + return pmt_from_complex(re, im); +} + +pmt_t pmt_from_complex(double re, double im) +{ return pmt_t(new pmt_complex(std::complex<double>(re, im))); } +pmt_t pmt_from_complex(const std::complex<double> &z) +{ + return pmt_t(new pmt_complex(z)); +} + std::complex<double> pmt_to_complex(pmt_t x) { @@ -1325,6 +1335,38 @@ pmt_list_add(pmt_t list, const pmt_t& item) } pmt_t +pmt_list_rm(pmt_t list, const pmt_t& item) +{ + if(pmt_is_pair(list)){ + pmt_t left = pmt_car(list); + pmt_t right = pmt_cdr(list); + if(!pmt_equal(left, item)){ + return pmt_cons(left, pmt_list_rm(right, item)); + } else { + return pmt_list_rm(right, item); + } + } else { + return list; + } +} + +bool +pmt_list_has(pmt_t list, const pmt_t& item) +{ + if(pmt_is_pair(list)){ + pmt_t left = pmt_car(list); + pmt_t right = pmt_cdr(list); + if(pmt_equal(left,item)) + return true; + return pmt_list_has(right, item); + } else { + if(pmt_is_null(list)) + return false; + throw std::runtime_error("list contains invalid format!"); + } +} + +pmt_t pmt_caar(pmt_t pair) { return (pmt_car(pmt_car(pair))); diff --git a/gruel/src/lib/pmt/pmt_serialize.cc b/gruel/src/lib/pmt/pmt_serialize.cc index a19809a66..24be6b772 100644 --- a/gruel/src/lib/pmt/pmt_serialize.cc +++ b/gruel/src/lib/pmt/pmt_serialize.cc @@ -309,11 +309,192 @@ pmt_serialize(pmt_t obj, std::streambuf &sb) } - if (pmt_is_vector(obj)) - throw pmt_notimplemented("pmt_serialize (vector)", obj); + if (pmt_is_vector(obj)) { + size_t vec_len = pmt::pmt_length(obj); + ok = serialize_untagged_u8(PST_VECTOR, sb); + ok &= serialize_untagged_u32(vec_len, sb); + for(size_t i=0; i<vec_len; i++) { + ok &= pmt_serialize(pmt_vector_ref(obj, i), sb); + } + return ok; + } + + if (pmt_is_uniform_vector(obj)) { + size_t npad = 1; + size_t vec_len = pmt::pmt_length(obj); + + if(pmt_is_u8vector(obj)) { + ok = serialize_untagged_u8(PST_UNIFORM_VECTOR, sb); + ok &= serialize_untagged_u8(UVI_U8, sb); + ok &= serialize_untagged_u32(vec_len, sb); + ok &= serialize_untagged_u8(npad, sb); + for(size_t i=0; i<npad; i++) { + ok &= serialize_untagged_u8(0, sb); + } + for(size_t i=0; i<vec_len; i++) { + ok &= serialize_untagged_u8(pmt_u8vector_ref(obj, i), sb); + } + return ok; + } + + if(pmt_is_s8vector(obj)) { + ok = serialize_untagged_u8(PST_UNIFORM_VECTOR, sb); + ok &= serialize_untagged_u8(UVI_S8, sb); + ok &= serialize_untagged_u32(vec_len, sb); + ok &= serialize_untagged_u8(npad, sb); + for(size_t i=0; i<npad; i++) { + ok &= serialize_untagged_u8(0, sb); + } + for(size_t i=0; i<vec_len; i++) { + ok &= serialize_untagged_u8(pmt_s8vector_ref(obj, i), sb); + } + return ok; + } + + if(pmt_is_u16vector(obj)) { + ok = serialize_untagged_u8(PST_UNIFORM_VECTOR, sb); + ok &= serialize_untagged_u8(UVI_U16, sb); + ok &= serialize_untagged_u32(vec_len, sb); + ok &= serialize_untagged_u8(npad, sb); + for(size_t i=0; i<npad; i++) { + ok &= serialize_untagged_u8(0, sb); + } + for(size_t i=0; i<vec_len; i++) { + ok &= serialize_untagged_u16(pmt_u16vector_ref(obj, i), sb); + } + return ok; + } + + if(pmt_is_s16vector(obj)) { + ok = serialize_untagged_u8(PST_UNIFORM_VECTOR, sb); + ok &= serialize_untagged_u8(UVI_S16, sb); + ok &= serialize_untagged_u32(vec_len, sb); + ok &= serialize_untagged_u8(npad, sb); + for(size_t i=0; i<npad; i++) { + ok &= serialize_untagged_u8(0, sb); + } + for(size_t i=0; i<vec_len; i++) { + ok &= serialize_untagged_u16(pmt_s16vector_ref(obj, i), sb); + } + return ok; + } - if (pmt_is_uniform_vector(obj)) - throw pmt_notimplemented("pmt_serialize (uniform-vector)", obj); + if(pmt_is_u32vector(obj)) { + ok = serialize_untagged_u8(PST_UNIFORM_VECTOR, sb); + ok &= serialize_untagged_u8(UVI_U32, sb); + ok &= serialize_untagged_u32(vec_len, sb); + ok &= serialize_untagged_u8(npad, sb); + for(size_t i=0; i<npad; i++) { + ok &= serialize_untagged_u8(0, sb); + } + for(size_t i=0; i<vec_len; i++) { + ok &= serialize_untagged_u32(pmt_u32vector_ref(obj, i), sb); + } + return ok; + } + + if(pmt_is_s32vector(obj)) { + ok = serialize_untagged_u8(PST_UNIFORM_VECTOR, sb); + ok &= serialize_untagged_u8(UVI_S32, sb); + ok &= serialize_untagged_u32(vec_len, sb); + ok &= serialize_untagged_u8(npad, sb); + for(size_t i=0; i<npad; i++) { + ok &= serialize_untagged_u8(0, sb); + } + for(size_t i=0; i<vec_len; i++) { + ok &= serialize_untagged_u32(pmt_s32vector_ref(obj, i), sb); + } + return ok; + } + + if(pmt_is_u64vector(obj)) { + ok = serialize_untagged_u8(PST_UNIFORM_VECTOR, sb); + ok &= serialize_untagged_u8(UVI_U64, sb); + ok &= serialize_untagged_u32(vec_len, sb); + ok &= serialize_untagged_u8(npad, sb); + for(size_t i=0; i<npad; i++) { + ok &= serialize_untagged_u8(0, sb); + } + for(size_t i=0; i<vec_len; i++) { + ok &= serialize_untagged_u64(pmt_u64vector_ref(obj, i), sb); + } + return ok; + } + + if(pmt_is_s64vector(obj)) { + ok = serialize_untagged_u8(PST_UNIFORM_VECTOR, sb); + ok &= serialize_untagged_u8(UVI_S64, sb); + ok &= serialize_untagged_u32(vec_len, sb); + ok &= serialize_untagged_u8(npad, sb); + for(size_t i=0; i<npad; i++) { + ok &= serialize_untagged_u8(0, sb); + } + for(size_t i=0; i<vec_len; i++) { + ok &= serialize_untagged_u64(pmt_s64vector_ref(obj, i), sb); + } + return ok; + } + + if(pmt_is_f32vector(obj)) { + ok = serialize_untagged_u8(PST_UNIFORM_VECTOR, sb); + ok &= serialize_untagged_u8(UVI_F32, sb); + ok &= serialize_untagged_u32(vec_len, sb); + ok &= serialize_untagged_u8(npad, sb); + for(size_t i=0; i<npad; i++) { + ok &= serialize_untagged_u8(0, sb); + } + for(size_t i=0; i<vec_len; i++) { + ok &= serialize_untagged_f64(pmt_f32vector_ref(obj, i), sb); + } + return ok; + } + + if(pmt_is_f64vector(obj)) { + ok = serialize_untagged_u8(PST_UNIFORM_VECTOR, sb); + ok &= serialize_untagged_u8(UVI_F64, sb); + ok &= serialize_untagged_u32(vec_len, sb); + ok &= serialize_untagged_u8(npad, sb); + for(size_t i=0; i<npad; i++) { + ok &= serialize_untagged_u8(0, sb); + } + for(size_t i=0; i<vec_len; i++) { + ok &= serialize_untagged_f64(pmt_f64vector_ref(obj, i), sb); + } + return ok; + } + + if(pmt_is_c32vector(obj)) { + ok = serialize_untagged_u8(PST_UNIFORM_VECTOR, sb); + ok &= serialize_untagged_u8(UVI_C32, sb); + ok &= serialize_untagged_u32(vec_len, sb); + ok &= serialize_untagged_u8(npad, sb); + for(size_t i=0; i<npad; i++) { + ok &= serialize_untagged_u8(0, sb); + } + for(size_t i=0; i<vec_len; i++) { + std::complex<float> c = pmt_c32vector_ref(obj, i); + ok &= serialize_untagged_f64(c.real(), sb); + ok &= serialize_untagged_f64(c.imag(), sb); + } + return ok; + } + + if(pmt_is_c64vector(obj)) { + ok = serialize_untagged_u8(PST_UNIFORM_VECTOR, sb); + ok &= serialize_untagged_u8(UVI_C64, sb); + ok &= serialize_untagged_u32(vec_len, sb); + ok &= serialize_untagged_u8(npad, sb); + for(size_t i=0; i<npad; i++) { + ok &= serialize_untagged_u8(0, sb); + } + for(size_t i=0; i<vec_len; i++) { + std::complex<double> c = pmt_c64vector_ref(obj, i); + ok &= serialize_untagged_f64(c.real(), sb); + ok &= serialize_untagged_f64(c.imag(), sb); + } + return ok; + } + } if (pmt_is_dict(obj)) throw pmt_notimplemented("pmt_serialize (dict)", obj); @@ -342,7 +523,7 @@ pmt_t pmt_deserialize(std::streambuf &sb) { uint8_t tag; - //uint8_t u8; + uint8_t u8; uint16_t u16; uint32_t u32; uint64_t u64; @@ -408,8 +589,159 @@ pmt_deserialize(std::streambuf &sb) } case PST_VECTOR: - case PST_DICT: + { + uint32_t nitems; + if(!deserialize_untagged_u32(&nitems, sb)) + goto error; + pmt_t vec = pmt_make_vector(nitems, PMT_NIL); + for(uint32_t i=0; i<nitems; i++) { + pmt_t item = pmt_deserialize(sb); + pmt_vector_set(vec, i, item); + } + return vec; + } + case PST_UNIFORM_VECTOR: + { + uint8_t utag, npad; + uint32_t nitems; + + if(!deserialize_untagged_u8(&utag, sb)) + return PMT_EOF; + + if(!deserialize_untagged_u32(&nitems, sb)) + goto error; + + deserialize_untagged_u8(&npad, sb); + for(size_t i; i < npad; i++) + deserialize_untagged_u8(&u8, sb); + + switch(utag) { + case(UVI_U8): + { + pmt_t vec = pmt_make_u8vector(nitems, 0); + for(uint32_t i=0; i<nitems; i++) { + deserialize_untagged_u8(&u8, sb); + pmt_u8vector_set(vec, i, u8); + } + return vec; + } + case(UVI_S8): + { + pmt_t vec = pmt_make_s8vector(nitems, 0); + for(uint32_t i=0; i<nitems; i++) { + deserialize_untagged_u8(&u8, sb); + pmt_s8vector_set(vec, i, u8); + } + return vec; + } + case(UVI_U16): + { + pmt_t vec = pmt_make_u16vector(nitems, 0); + for(uint32_t i=0; i<nitems; i++) { + deserialize_untagged_u16(&u16, sb); + pmt_u16vector_set(vec, i, u16); + } + return vec; + } + case(UVI_S16): + { + pmt_t vec = pmt_make_s16vector(nitems, 0); + for(uint32_t i=0; i<nitems; i++) { + deserialize_untagged_u16(&u16, sb); + pmt_s16vector_set(vec, i, u16); + } + return vec; + } + case(UVI_U32): + { + pmt_t vec = pmt_make_u32vector(nitems, 0); + for(uint32_t i=0; i<nitems; i++) { + deserialize_untagged_u32(&u32, sb); + pmt_u32vector_set(vec, i, u32); + } + return vec; + } + case(UVI_S32): + { + pmt_t vec = pmt_make_s32vector(nitems, 0); + for(uint32_t i=0; i<nitems; i++) { + deserialize_untagged_u32(&u32, sb); + pmt_s32vector_set(vec, i, u32); + } + return vec; + } + case(UVI_U64): + { + pmt_t vec = pmt_make_u64vector(nitems, 0); + for(uint32_t i=0; i<nitems; i++) { + deserialize_untagged_u64(&u64, sb); + pmt_u64vector_set(vec, i, u64); + } + return vec; + } + case(UVI_S64): + { + pmt_t vec = pmt_make_s64vector(nitems, 0); + for(uint32_t i=0; i<nitems; i++) { + deserialize_untagged_u64(&u64, sb); + pmt_s64vector_set(vec, i, u64); + } + return vec; + } + case(UVI_F32): + { + pmt_t vec = pmt_make_f32vector(nitems, 0); + for(uint32_t i=0; i<nitems; i++) { + deserialize_untagged_f64(&f64, sb); + pmt_f32vector_set(vec, i, static_cast<float>(f64)); + } + return vec; + } + case(UVI_F64): + { + pmt_t vec = pmt_make_f64vector(nitems, 0); + for(uint32_t i=0; i<nitems; i++) { + deserialize_untagged_f64(&f64, sb); + pmt_f64vector_set(vec, i, f64); + } + return vec; + } + case(UVI_C32): + { + pmt_t vec = pmt_make_c32vector(nitems, 0); + for(uint32_t i=0; i<nitems; i++) { + float re, im; + deserialize_untagged_f64(&f64, sb); + re = static_cast<float>(f64); + deserialize_untagged_f64(&f64, sb); + im = static_cast<float>(f64); + pmt_c32vector_set(vec, i, std::complex<float>(re, im)); + } + return vec; + } + + case(UVI_C64): + { + pmt_t vec = pmt_make_c64vector(nitems, 0); + for(uint32_t i=0; i<nitems; i++) { + double re, im; + deserialize_untagged_f64(&f64, sb); + re = f64; + deserialize_untagged_f64(&f64, sb); + im = f64; + pmt_c64vector_set(vec, i, std::complex<double>(re, im)); + } + return vec; + } + + default: + throw pmt_exception("pmt_deserialize: malformed input stream, tag value = ", + pmt_from_long(tag)); + } + } + + case PST_DICT: case PST_COMMENT: throw pmt_notimplemented("pmt_deserialize: tag value = ", pmt_from_long(tag)); diff --git a/gruel/src/lib/pmt/qa_pmt_prims.cc b/gruel/src/lib/pmt/qa_pmt_prims.cc index 6212b8ea4..3ae4d70b6 100644 --- a/gruel/src/lib/pmt/qa_pmt_prims.cc +++ b/gruel/src/lib/pmt/qa_pmt_prims.cc @@ -134,12 +134,24 @@ qa_pmt_prims::test_complexes() { pmt_t p1 = pmt_make_rectangular(2, -3); pmt_t m1 = pmt_make_rectangular(-3, 2); + pmt_t p2 = pmt_from_complex(2, -3); + pmt_t m2 = pmt_from_complex(-3, 2); + pmt_t p3 = pmt_from_complex(std::complex<double>(2, -3)); + pmt_t m3 = pmt_from_complex(std::complex<double>(-3, 2)); CPPUNIT_ASSERT(!pmt_is_complex(PMT_T)); CPPUNIT_ASSERT(pmt_is_complex(p1)); CPPUNIT_ASSERT(pmt_is_complex(m1)); + CPPUNIT_ASSERT(pmt_is_complex(p2)); + CPPUNIT_ASSERT(pmt_is_complex(m2)); + CPPUNIT_ASSERT(pmt_is_complex(p3)); + CPPUNIT_ASSERT(pmt_is_complex(m3)); CPPUNIT_ASSERT_THROW(pmt_to_complex(PMT_T), pmt_wrong_type); CPPUNIT_ASSERT_EQUAL(std::complex<double>(2, -3), pmt_to_complex(p1)); CPPUNIT_ASSERT_EQUAL(std::complex<double>(-3, 2), pmt_to_complex(m1)); + CPPUNIT_ASSERT_EQUAL(std::complex<double>(2, -3), pmt_to_complex(p2)); + CPPUNIT_ASSERT_EQUAL(std::complex<double>(-3, 2), pmt_to_complex(m2)); + CPPUNIT_ASSERT_EQUAL(std::complex<double>(2, -3), pmt_to_complex(p3)); + CPPUNIT_ASSERT_EQUAL(std::complex<double>(-3, 2), pmt_to_complex(m3)); CPPUNIT_ASSERT_EQUAL(std::complex<double>(1.0, 0), pmt_to_complex(pmt_from_long(1))); CPPUNIT_ASSERT_EQUAL(std::complex<double>(1.0, 0), pmt_to_complex(pmt_from_double(1.0))); } @@ -472,7 +484,7 @@ class qa_pmt_msg_accepter_nop : public gruel::msg_accepter { public: qa_pmt_msg_accepter_nop(){}; ~qa_pmt_msg_accepter_nop(); - void post(pmt_t){}; + void post(pmt_t,pmt_t){}; }; qa_pmt_msg_accepter_nop::~qa_pmt_msg_accepter_nop(){} @@ -495,9 +507,10 @@ qa_pmt_prims::test_msg_accepter() CPPUNIT_ASSERT_THROW(pmt_msg_accepter_ref(p0), pmt_wrong_type); // just confirm interfaces on send are OK - gruel::send(ma0.get(), sym); - gruel::send(ma0, sym); - gruel::send(p1, sym); + pmt_t port(pmt_intern("port")); + gruel::send(ma0.get(), port, sym); + gruel::send(ma0, port, sym); + gruel::send(p1, port, sym); } diff --git a/gruel/src/lib/pmt/unv_template.cc.t b/gruel/src/lib/pmt/unv_template.cc.t index 566168c3d..1ed505e29 100644 --- a/gruel/src/lib/pmt/unv_template.cc.t +++ b/gruel/src/lib/pmt/unv_template.cc.t @@ -87,6 +87,13 @@ pmt_init_@TAG@vector(size_t k, const @TYPE@ *data) return pmt_t(new pmt_@TAG@vector(k, data)); } +pmt_t +pmt_init_@TAG@vector(size_t k, const std::vector< @TYPE@ > &data) +{ + + return pmt_t(new pmt_@TAG@vector(k, &data[0])); +} + @TYPE@ pmt_@TAG@vector_ref(pmt_t vector, size_t k) { @@ -111,6 +118,18 @@ pmt_@TAG@vector_elements(pmt_t vector, size_t &len) return _@TAG@vector(vector)->elements(len); } +const std::vector< @TYPE@ > +pmt_@TAG@vector_elements(pmt_t vector) +{ + if (!vector->is_@TAG@vector()) + throw pmt_wrong_type("pmt_@TAG@vector_elements", vector); + size_t len; + const @TYPE@ *array = _@TAG@vector(vector)->elements(len); + const std::vector< @TYPE@ > vec(array, array+len); + return vec; +} + + @TYPE@ * pmt_@TAG@vector_writable_elements(pmt_t vector, size_t &len) { diff --git a/gruel/src/python/qa_pmt.py b/gruel/src/python/qa_pmt.py index 1ef4fed15..59a5725fc 100755 --- a/gruel/src/python/qa_pmt.py +++ b/gruel/src/python/qa_pmt.py @@ -21,22 +21,82 @@ # import unittest -import pmt_swig +import pmt_swig as pmt class test_gruel_pmt(unittest.TestCase): def test01 (self): - a = pmt_swig.pmt_intern("a") - b = pmt_swig.pmt_from_double(123765) - d1 = pmt_swig.pmt_make_dict() - d2 = pmt_swig.pmt_dict_add(d1, a, b) - pmt_swig.pmt_print(d2) + a = pmt.pmt_intern("a") + b = pmt.pmt_from_double(123765) + d1 = pmt.pmt_make_dict() + d2 = pmt.pmt_dict_add(d1, a, b) + pmt.pmt_print(d2) def test02 (self): const = 123765 - x_pmt = pmt_swig.pmt_from_double(const) - x_int = pmt_swig.pmt_to_double(x_pmt) + x_pmt = pmt.pmt_from_double(const) + x_int = pmt.pmt_to_double(x_pmt) self.assertEqual(x_int, const) + def test03(self): + v = pmt.pmt_init_f32vector(3, [11, -22, 33]) + s = pmt.pmt_serialize_str(v) + d = pmt.pmt_deserialize_str(s) + self.assertTrue(pmt.pmt_equal(v, d)) + + def test04(self): + v = pmt.pmt_init_f64vector(3, [11, -22, 33]) + s = pmt.pmt_serialize_str(v) + d = pmt.pmt_deserialize_str(s) + self.assertTrue(pmt.pmt_equal(v, d)) + + def test05(self): + v = pmt.pmt_init_u8vector(3, [11, 22, 33]) + s = pmt.pmt_serialize_str(v) + d = pmt.pmt_deserialize_str(s) + self.assertTrue(pmt.pmt_equal(v, d)) + + def test06(self): + v = pmt.pmt_init_s8vector(3, [11, -22, 33]) + s = pmt.pmt_serialize_str(v) + d = pmt.pmt_deserialize_str(s) + self.assertTrue(pmt.pmt_equal(v, d)) + + def test07(self): + v = pmt.pmt_init_u16vector(3, [11, 22, 33]) + s = pmt.pmt_serialize_str(v) + d = pmt.pmt_deserialize_str(s) + self.assertTrue(pmt.pmt_equal(v, d)) + + def test08(self): + v = pmt.pmt_init_s16vector(3, [11, -22, 33]) + s = pmt.pmt_serialize_str(v) + d = pmt.pmt_deserialize_str(s) + self.assertTrue(pmt.pmt_equal(v, d)) + + def test09(self): + v = pmt.pmt_init_u32vector(3, [11, 22, 33]) + s = pmt.pmt_serialize_str(v) + d = pmt.pmt_deserialize_str(s) + self.assertTrue(pmt.pmt_equal(v, d)) + + def test10(self): + v = pmt.pmt_init_s32vector(3, [11, -22, 33]) + s = pmt.pmt_serialize_str(v) + d = pmt.pmt_deserialize_str(s) + self.assertTrue(pmt.pmt_equal(v, d)) + + def test11(self): + v = pmt.pmt_init_c32vector(3, [11 + -101j, -22 + 202j, 33 + -303j]) + s = pmt.pmt_serialize_str(v) + d = pmt.pmt_deserialize_str(s) + self.assertTrue(pmt.pmt_equal(v, d)) + + def test12(self): + v = pmt.pmt_init_c64vector(3, [11 + -101j, -22 + 202j, 33 + -303j]) + s = pmt.pmt_serialize_str(v) + d = pmt.pmt_deserialize_str(s) + self.assertTrue(pmt.pmt_equal(v, d)) + if __name__ == '__main__': unittest.main() diff --git a/gruel/src/swig/CMakeLists.txt b/gruel/src/swig/CMakeLists.txt index 332d5866f..a5e3f9399 100644 --- a/gruel/src/swig/CMakeLists.txt +++ b/gruel/src/swig/CMakeLists.txt @@ -24,7 +24,7 @@ include(GrPython) include(GrSwig) set(GR_SWIG_TARGET_DEPS pmt_generated) -set(GR_SWIG_INCLUDE_DIRS ${GRUEL_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR}) +set(GR_SWIG_INCLUDE_DIRS ${GRUEL_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR} ${Boost_INCLUDE_DIRS}) set(GR_SWIG_LIBRARIES gruel) set(GR_SWIG_DOC_FILE ${CMAKE_CURRENT_BINARY_DIR}/pmt_swig_doc.i) diff --git a/gruel/src/swig/pmt_swig.i b/gruel/src/swig/pmt_swig.i index 45cfceadc..84f48b099 100644 --- a/gruel/src/swig/pmt_swig.i +++ b/gruel/src/swig/pmt_swig.i @@ -38,6 +38,27 @@ //load generated python docstrings %include "pmt_swig_doc.i" +%include <std_complex.i> +%include <std_vector.i> +%include <stl.i> + +namespace std { + %template() vector<unsigned char>; + %template() vector<uint8_t>; + %template() vector<char>; + %template() vector<int8_t>; + %template() vector<short>; + %template() vector<uint16_t>; + %template() vector<int16_t>; + %template() vector<int>; + %template() vector<int32_t>; + %template() vector<uint32_t>; + %template() vector<float>; + %template() vector<double>; + %template() vector< std::complex<float> >; + %template() vector< std::complex<double> >; +}; + //////////////////////////////////////////////////////////////////////// // Language independent exception handler //////////////////////////////////////////////////////////////////////// @@ -191,6 +212,8 @@ bool pmt_is_complex(pmt_t obj); //! Return a complex number constructed of the given real and imaginary parts. pmt_t pmt_make_rectangular(double re, double im); +pmt_t pmt_from_complex(const std::complex<double> &z); + /*! * If \p z is complex, real or integer, return the closest complex<double>. * Otherwise, raise the wrong_type exception. @@ -380,16 +403,17 @@ pmt_t pmt_make_f64vector(size_t k, double fill); pmt_t pmt_make_c32vector(size_t k, std::complex<float> fill); pmt_t pmt_make_c64vector(size_t k, std::complex<double> fill); -pmt_t pmt_init_u8vector(size_t k, const uint8_t *data); -pmt_t pmt_init_s8vector(size_t k, const int8_t *data); -pmt_t pmt_init_u16vector(size_t k, const uint16_t *data); -pmt_t pmt_init_s16vector(size_t k, const int16_t *data); -pmt_t pmt_init_u32vector(size_t k, const uint32_t *data); -pmt_t pmt_init_s32vector(size_t k, const int32_t *data); -pmt_t pmt_init_f32vector(size_t k, const float *data); -pmt_t pmt_init_f64vector(size_t k, const double *data); -pmt_t pmt_init_c32vector(size_t k, const std::complex<float> *data); -pmt_t pmt_init_c64vector(size_t k, const std::complex<double> *data); + +pmt_t pmt_init_u8vector(size_t k, const std::vector<uint8_t> &data); +pmt_t pmt_init_s8vector(size_t k, const std::vector<int8_t> &data); +pmt_t pmt_init_u16vector(size_t k, const std::vector<uint16_t> &data); +pmt_t pmt_init_s16vector(size_t k, const std::vector<int16_t> &data); +pmt_t pmt_init_u32vector(size_t k, const std::vector<uint32_t> &data); +pmt_t pmt_init_s32vector(size_t k, const std::vector<int32_t> &data); +pmt_t pmt_init_f32vector(size_t k, const std::vector<float> &data); +pmt_t pmt_init_f64vector(size_t k, const std::vector<double> &data); +pmt_t pmt_init_c32vector(size_t k, const std::vector<std::complex<float> > &data); +pmt_t pmt_init_c64vector(size_t k, const std::vector<std::complex<double> > &data); uint8_t pmt_u8vector_ref(pmt_t v, size_t k); int8_t pmt_s8vector_ref(pmt_t v, size_t k); @@ -419,37 +443,23 @@ void pmt_c64vector_set(pmt_t v, size_t k, std::complex<double> x); // Return const pointers to the elements -const void *pmt_uniform_vector_elements(pmt_t v, size_t &len); //< works with any; len is in bytes - -const uint8_t *pmt_u8vector_elements(pmt_t v, size_t &len); //< len is in elements -const int8_t *pmt_s8vector_elements(pmt_t v, size_t &len); //< len is in elements -const uint16_t *pmt_u16vector_elements(pmt_t v, size_t &len); //< len is in elements -const int16_t *pmt_s16vector_elements(pmt_t v, size_t &len); //< len is in elements -const uint32_t *pmt_u32vector_elements(pmt_t v, size_t &len); //< len is in elements -const int32_t *pmt_s32vector_elements(pmt_t v, size_t &len); //< len is in elements -const uint64_t *pmt_u64vector_elements(pmt_t v, size_t &len); //< len is in elements -const int64_t *pmt_s64vector_elements(pmt_t v, size_t &len); //< len is in elements -const float *pmt_f32vector_elements(pmt_t v, size_t &len); //< len is in elements -const double *pmt_f64vector_elements(pmt_t v, size_t &len); //< len is in elements -const std::complex<float> *pmt_c32vector_elements(pmt_t v, size_t &len); //< len is in elements -const std::complex<double> *pmt_c64vector_elements(pmt_t v, size_t &len); //< len is in elements - -// Return non-const pointers to the elements - -void *pmt_uniform_vector_writable_elements(pmt_t v, size_t &len); //< works with any; len is in bytes - -uint8_t *pmt_u8vector_writable_elements(pmt_t v, size_t &len); //< len is in elements -int8_t *pmt_s8vector_writable_elements(pmt_t v, size_t &len); //< len is in elements -uint16_t *pmt_u16vector_writable_elements(pmt_t v, size_t &len); //< len is in elements -int16_t *pmt_s16vector_writable_elements(pmt_t v, size_t &len); //< len is in elements -uint32_t *pmt_u32vector_writable_elements(pmt_t v, size_t &len); //< len is in elements -int32_t *pmt_s32vector_writable_elements(pmt_t v, size_t &len); //< len is in elements -uint64_t *pmt_u64vector_writable_elements(pmt_t v, size_t &len); //< len is in elements -int64_t *pmt_s64vector_writable_elements(pmt_t v, size_t &len); //< len is in elements -float *pmt_f32vector_writable_elements(pmt_t v, size_t &len); //< len is in elements -double *pmt_f64vector_writable_elements(pmt_t v, size_t &len); //< len is in elements -std::complex<float> *pmt_c32vector_writable_elements(pmt_t v, size_t &len); //< len is in elements -std::complex<double> *pmt_c64vector_writable_elements(pmt_t v, size_t &len); //< len is in elements +%apply size_t & INOUT { size_t &len }; + +// works with any; len is in bytes +// Returns an opaque Python type +const void *pmt_uniform_vector_elements(pmt_t v, size_t &len); + +// Returns a Python tuple +const std::vector<uint8_t> pmt_u8vector_elements(pmt_t v); +const std::vector<int8_t> pmt_s8vector_elements(pmt_t v); +const std::vector<uint16_t> pmt_u16vector_elements(pmt_t v); +const std::vector<int16_t> pmt_s16vector_elements(pmt_t v); +const std::vector<uint32_t> pmt_u32vector_elements(pmt_t v); +const std::vector<int32_t> pmt_s32vector_elements(pmt_t v); +const std::vector<float> pmt_f32vector_elements(pmt_t v); +const std::vector<double> pmt_f64vector_elements(pmt_t v); +const std::vector<std::complex<float> > pmt_c32vector_elements(pmt_t v); +const std::vector<std::complex<double> > pmt_c64vector_elements(pmt_t v); /* * ------------------------------------------------------------------------ @@ -696,6 +706,15 @@ pmt_t pmt_list6(const pmt_t& x1, const pmt_t& x2, const pmt_t& x3, const pmt_t& */ pmt_t pmt_list_add(pmt_t list, const pmt_t& item); +/*! + * \brief Return \p list with \p item removed + */ +pmt_t pmt_list_rm(pmt_t list, const pmt_t& item); + +/*! + * \brief Return bool of \p list contains \p item + */ +bool pmt_list_has(pmt_t list, const pmt_t& item); /* * ------------------------------------------------------------------------ diff --git a/volk/CMakeLists.txt b/volk/CMakeLists.txt index 68385f974..9519505eb 100644 --- a/volk/CMakeLists.txt +++ b/volk/CMakeLists.txt @@ -38,12 +38,8 @@ set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) #location for custom "M # Environment setup ######################################################################## IF(NOT DEFINED BOOST_ROOT) - SET(BOOST_ROOT "") + SET(BOOST_ROOT ${CMAKE_INSTALL_PREFIX}) ENDIF() -SET(BOOST_ROOT ${BOOST_ROOT} CACHE STRING "Modify search path for Boost components") - -#after caching user-defined value, make sure to add the install prefix -SET(BOOST_ROOT ${BOOST_ROOT}:${CMAKE_INSTALL_PREFIX}) IF(NOT DEFINED CROSSCOMPILE_MULTILIB) SET(CROSSCOMPILE_MULTILIB "") @@ -77,6 +73,10 @@ set(Boost_ADDITIONAL_VERSIONS ) find_package(Boost COMPONENTS unit_test_framework) +if(NOT Boost_FOUND) + message(FATAL_ERROR "VOLK Requires boost to build") +endif() + find_package(ORC) ######################################################################## diff --git a/volk/apps/CMakeLists.txt b/volk/apps/CMakeLists.txt index 175105a5a..a89a9409d 100644 --- a/volk/apps/CMakeLists.txt +++ b/volk/apps/CMakeLists.txt @@ -18,7 +18,7 @@ ######################################################################## # Setup profiler ######################################################################## -find_package(Boost) +find_package(Boost COMPONENTS unit_test_framework) if(Boost_FOUND AND UNIX) #uses mkdir and $HOME |