summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt4
-rw-r--r--cmake/Modules/GnuradioConfig.cmake4
-rw-r--r--docs/doxygen/images/gnuradio-logo.pngbin5223 -> 0 bytes
-rw-r--r--docs/doxygen/images/gnuradio-logo.svg521
-rw-r--r--docs/doxygen/other/extra_pages.dox53
-rw-r--r--docs/doxygen/other/main_page.dox2
-rw-r--r--gr-blocks/lib/add_ff_impl.cc10
-rw-r--r--gr-blocks/lib/conjugate_cc_impl.cc7
-rw-r--r--gr-blocks/lib/endian_swap_impl.cc59
-rw-r--r--gr-blocks/lib/multiply_cc_impl.cc11
-rw-r--r--gr-blocks/lib/multiply_conjugate_cc_impl.cc7
-rw-r--r--gr-blocks/lib/multiply_const_cc_impl.cc7
-rw-r--r--gr-blocks/lib/multiply_const_ff_impl.cc7
-rw-r--r--gr-blocks/lib/multiply_ff_impl.cc11
-rw-r--r--gr-fft/include/gnuradio/fft/window.h42
-rw-r--r--gr-fft/lib/window.cc19
-rw-r--r--gr-filter/doc/filter.dox10
-rw-r--r--gr-filter/grc/filter_pfb_decimator.xml3
-rw-r--r--gr-filter/include/gnuradio/filter/CMakeLists.txt3
-rw-r--r--gr-filter/include/gnuradio/filter/adaptive_fir.h88
-rw-r--r--gr-filter/include/gnuradio/filter/adaptive_fir_ccc.h87
-rw-r--r--gr-filter/include/gnuradio/filter/adaptive_fir_ccf.h82
-rw-r--r--gr-filter/include/gnuradio/filter/pfb_decimator_ccf.h2
-rw-r--r--gr-filter/lib/CMakeLists.txt3
-rw-r--r--gr-filter/lib/adaptive_fir.cc60
-rw-r--r--gr-filter/lib/adaptive_fir_ccc_impl.cc106
-rw-r--r--gr-filter/lib/adaptive_fir_ccc_impl.h62
-rw-r--r--gr-filter/lib/adaptive_fir_ccf_impl.cc106
-rw-r--r--gr-filter/lib/adaptive_fir_ccf_impl.h62
-rw-r--r--gr-filter/lib/firdes.cc25
-rw-r--r--gr-filter/lib/pfb_decimator_ccf_impl.cc7
-rw-r--r--gr-filter/lib/pfb_decimator_ccf_impl.h2
-rw-r--r--gr-filter/lib/qa_firdes.cc523
-rw-r--r--gr-filter/python/filter/pfb.py6
-rwxr-xr-xgr-filter/python/filter/qa_adaptive_fir_filter.py101
-rwxr-xr-xgr-filter/python/filter/qa_firdes.py95
-rwxr-xr-xgr-filter/python/filter/qa_freq_xlating_fir_filter.py4
-rw-r--r--gr-filter/swig/filter_swig.i6
-rw-r--r--gr-qtgui/grc/qtgui_freq_sink_x.xml4
-rw-r--r--gr-qtgui/grc/qtgui_waterfall_sink_x.xml4
-rw-r--r--gr-qtgui/include/gnuradio/qtgui/form_menus.h241
-rw-r--r--gr-qtgui/include/gnuradio/qtgui/freqdisplayform.h5
-rw-r--r--gr-qtgui/include/gnuradio/qtgui/waterfalldisplayform.h4
-rw-r--r--gr-qtgui/lib/freqdisplayform.cc21
-rw-r--r--gr-qtgui/lib/waterfalldisplayform.cc24
-rw-r--r--gr-utils/python/modtool/gr-newmod/CMakeLists.txt19
-rw-r--r--gr-utils/python/modtool/gr-newmod/lib/CMakeLists.txt2
-rw-r--r--gr-utils/python/modtool/modtool_base.py3
48 files changed, 1014 insertions, 1520 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 677ea51cec..4efa93acaa 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -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 7)
-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
diff --git a/cmake/Modules/GnuradioConfig.cmake b/cmake/Modules/GnuradioConfig.cmake
index a81211f31d..23115c484c 100644
--- a/cmake/Modules/GnuradioConfig.cmake
+++ b/cmake/Modules/GnuradioConfig.cmake
@@ -25,6 +25,10 @@ if(NOT GR_REQUIRED_COMPONENTS)
set(GR_REQUIRED_COMPONENTS RUNTIME ANALOG BLOCKS DIGITAL FFT FILTER PMT)
endif()
+# Allows us to use all .cmake files in this directory
+list(INSERT CMAKE_MODULE_PATH 0 ${CMAKE_CURRENT_LIST_DIR})
+
+# Easily access all libraries and includes of GNU Radio
set(GNURADIO_ALL_LIBRARIES "")
set(GNURADIO_ALL_INCLUDE_DIRS "")
diff --git a/docs/doxygen/images/gnuradio-logo.png b/docs/doxygen/images/gnuradio-logo.png
deleted file mode 100644
index ec4db23fc8..0000000000
--- a/docs/doxygen/images/gnuradio-logo.png
+++ /dev/null
Binary files differ
diff --git a/docs/doxygen/images/gnuradio-logo.svg b/docs/doxygen/images/gnuradio-logo.svg
new file mode 100644
index 0000000000..7143bc2a38
--- /dev/null
+++ b/docs/doxygen/images/gnuradio-logo.svg
@@ -0,0 +1,521 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="650"
+ height="164"
+ id="svg3716"
+ version="1.1"
+ inkscape:version="0.48.3.1 r9886"
+ sodipodi:docname="gnuradio-logo3.svg">
+ <defs
+ id="defs3718" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="0.7"
+ inkscape:cx="333.61853"
+ inkscape:cy="-208.88012"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:window-width="843"
+ inkscape:window-height="720"
+ inkscape:window-x="510"
+ inkscape:window-y="445"
+ inkscape:window-maximized="0"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0" />
+ <metadata
+ id="metadata3721">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0.71428519,1.0663847)">
+ <image
+ y="-1.0663847"
+ x="-0.71428519"
+ id="image3732"
+ xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAooAAACkCAYAAAAQTQ/jAAAABHNCSVQICAgIfAhkiAAAIABJREFU
+eJzs3Xd8VFXaB/DfuXUmkw4hAUKRpqAiiq5dsa6uAiomgBXLCsG2FiANvSuQhNVVd1UCuJZXXQsB
+ey9rb6soYlmkKB0SSE9m5tbz/oHsYkyZmXumJJzv55PPvq9z5zlPQjLzzLnnPAfgOI7jOI7jOI7j
+OI7jOI7jOI7jOI7jOI7jOI7jOI7jOI7jOI7jOI7jOI7jOI7jOI7jOI7jOI7jOI7jOI7jOI7jOI7j
+OI7jOI7jOI7jOI7jOI7juP0CiXcCHaG3wocmpEJWU+A4KQAAIjTC0ZsQRBN5FME4p8hxHMdxHNej
+xb1QpNegNyTpCFAcDpAxIBgDiuEAxC6eagL4DsAqUKwCoV+DWF+TRWiJftYcx3Ecx3E9X8wLRQoQ
+zJSOBxXOBeh4AKMYhrcBfAbQlwDxeVKp/8gwNsdxHMdx3H4lZoUinYlkUPlqAAUARsRgSAfAZyDk
+fljGcrIUZgzG5DiO4ziO6zGiXijSa7wDIVm3gOJKAMnRHq8DNQB5BKL0d3K/f3uccuA4juM4jutW
+olYo0pvgRVApBuitADzRGidMjQDmYre5iFTBjncyHMdxHMdxiYx5obhnDaJ8KSipAGhf1vEZWQtC
+ryeLrDfjnQjHcRzHcVyiYloo0quQCVl6GIRMZBk3ShwQ3I9d5ixSBSPeyXAcx3EcxyUaZoUinSmP
+AcUKAENchnIArAPBZgD1AOpBSQMoCEAz9nyRDBAMAzDIbd4APoEo5/G1ixzHcRzHcb/GpFCkM+XL
+QLEYgDeCp+sAfROUvAnQryFY34TaC5EWIAOCdAQcHAGQcwCcCEAIPwWyE3DySaX1YfjP5TiO4ziO
+65lcF4q0QJoDkIpwnwaQVwE8Dcl4kdyHJrd5AACdiRxQeRIILgbFsWE+3QB1JpHF9ssscuE4juM4
+juvuXBWKdKZUAkrmh/GUIAiWQhDvJfcHf3YzdlfodPkwCLgFwFQAUohPs0HJJWSx8XQUU+M4juM4
+jusWIi4U6Qz5OhD8PfQY9EXY4s1kqb4h0jEjQa9RDoJIFwM4OcSn6IAziVTar0QzL47jOI7juEQX
+UaFIC5TzAPpsaM+n20GFG8hiY0UkY7FAAYIZ8gwQLASQEsJT/AA5llQaq6OdG8dxHMdxXKIKu1Ck
+MzyDQeyvAGSEEP5l2MYlZCkaQ4qtQUKNMhzAaAAHw6GpIEjF3hNdKBpASCOoUwtCv4WtfEuWBjaH
+mftzAMaEcPk62OZRoebOcRzHcRzX04RVKO45bUX+DHsKuS4ikz9jkfFnAtBOY05Xh0N0zoWDc0Bw
+PMI/xaUOBG/DwctwzNfIUuzudLzrocKSHwRwadehySvINiYQDU6YOXEcx3Ecx3V74RWKM5XJoDSE
+jR70FlJp3d3ho3kQkaWcD0pnAfhdODl0wQbBCgB3kUXmFx2Or0HATvkuENzURbxaiPJo3mOR4ziO
+47j9Ufi3nmcqd4DSuR1fQIvIYqvDdjl0hjIFhM4HMDTcscP0LgTcSh4wv+owl5ny30BxQ7sPElTD
+IuPIUmNN1DLkOI7jOI5LYJFuZvkzQG/77QO4hyw2b273OdOVURDo/QBOiWTMCNkAFgPmXFKJ+t/k
+pEHATukZEHJhm4dqAXIq38zCcRzHcdz+LPL2OAXKXwA6a5//9DF2myeTKti/vVaaA5D5CL2fIWN0
+OwjyyCLrk988cit8aJW/wf9mOJvh0N+TJdansc2R4ziO4zgusbhsuK1ooPR2AC0QxdFtm2jTPCjI
+kv8OiumusmQjCIICssh8tO0DtEA+BsBHAJog4PTObldzHMdxHMftL9wf4TdTKQd1GkiltfBX//0a
+yBCl5QCZ4HYMpgidRRZZd7X9z3SGMh+C8w5ZZL0bj7Q4juM4juMSjetCEdiz1m/fFjK/NLh+GATT
+wgzlAPgSwFcAvgGhP4GSWkCsh0AlOE4mHCcTIhkFSg4FcDSAA8Meg2IaWWw+HubzOI7jOI7j9itM
+CsW26AzpFhDym1m7TnwPiqWQpWfJfYGt4Y2lHAKCPBA6HRTZIT7NgIPjyRLzy3DG4jiO4ziO258w
+LxTpTHkMKD4DoIZw+UrAmYtK+/WuGnN3Oe5N8CIgXwWC2wH0DuEpa+EzjyB3odXNuD1BeXl5RnNz
+4/lwnLE2xYHEoQMppb0BR6aESJRCopQSACCE2JRSSggJCERoIQKaKCXVEiFfQ5I+kGX5XU3TmuL9
+PbVn2bJl4qpVq6ZSx5xBLTrEBs0AaKd/AwIRmv1BPfe+++7TY5VnR4oLC180LeNMNzFEQdxc8Zc7
+R4R6/dy5c8dapn4btemRDqUpFI7S2fWCIG1Z+Je/DHeTo1ulpaV/0IP+Z93GUSVlwfyKinlu47x6
+9jA1K635z5mKeb5PtPrLgu2RCBXdxnXDpIIDwNEd0QTgOBR+ShHw21J10BHXBC3p882BlFfzX/rx
+565icT3bfy7p/VM/j/+Arq6jAK031C2bDe8dJz+9/aFQYpcUFj6pG/rUUK4lhDiCKK6WZOXGBQsW
+fBDKczg22O9CpvRUgHRVJAYBehuyrXuIBovFsOQeBADzfjoTy0GlJSGsjRyMVvlQwPyMxfjdiaZp
+mVYweKtFnTMd2zpwd011MqUh1+l73+BUG0j/5f8eZQKnQMfNQQLMvvWWFiIIayVRes/r8/29tLR0
+E/vvIjwlJYUzVv778zst2w7ne4UNW/X5kh4HkB+97ELMxXGybcsO5QNYh4hMeoVy3YIFxdktTeZL
+/pamo8L4cUGQhZDiRxOlNMXtzwkAHAmuv5dPp/a7frhv5529ZN11PowJv3ztfQ/w/fK/AwEcBeDS
+o+hu1F7lM+pNdUOdqb6wscF3d/5r63fFI1kufjyCraTKZiiXkjTZHDjI1/qPry/Kmv5hfdqJN7y2
+vtMP2JRS1XFCPvhMsG17jGmY7xfNmfNsWUXFhYQQVxNMXGiYF4qk0rqbFkgiQP7SwSW7QXEOWWz9
+m/XYAEAWYSdgTaQz5RtBcTf2vBi2FQShE8kia78pEjVNSzKC/lm2TS9vbmwYvHeGkDVKAcuykgEc
+YcI4IhgM3Dxn9qxdoiC+kpqefnthYWHIZ3OzyYeSoqLC14P+4JnhFIj7MnX9wsLCwsMrKiq+Zpxe
+QiotLR3Z2OD/0jLtpHjn0p19c0mfRaN8uwskoXu+lwmEIlMxlEzFGDkUzSNHp9YXrrs0c1O17q04
+Ydm2xfHOj0tMBBRj0hqO8on2mmV5ecPyq6p+0zLPHQrD0C8oLip6F8A4trG59rRXRLlGKq07AXp7
+Ow+1ADiLLDajUiT+KodF5t9AMbOdhyxQcglZZL0Z7RwSwfz58/sXz5n9dmtTY3MwqGumaRwQrSKx
+PZRSmIaRFQwGpu2q3rlpzqxZm+YWF14dqxzmFhc/bep6xEUisKfYBLWeZJhWwtI0LdkMBj7jRaI7
+n0/JmXNwckO3LRLbowo2hiU3Dzq+V03lzitSGz/J63tNvHPiEtfw5ObBh6j/ejsasSml0IOBk0sK
+C/8Wjfjcr0WlUAQAUmndAYKb8b+1hzYovZBUmis7ex69Hql0pjKZFshP0QL5O1og19ACmdICuYUW
+yOtogfwvWiDNodOVUV3msNhcAop9f5FMgOSRxcYKF99at1BRUZFWWDj7tYa62s1BXT/Ndpyo/VuH
+ilIK0zQGtvoDDxbOmb2jpKRkcjTHu620aHogGMh3UyTuZRrWQcXFxZcwSCuhBQOt/zItKzXeeXRn
+7+YNzhmV0lgm9uC7YtmeQOoxvWuXbLgsY/1beUMGxjsfLjGNSGke9/GFAyZGK75u6NctWFDcN1rx
+uT2iWjyQReY9AC365f99giy23ujoWvonpNMCpQKWvBOUPg1gCoCDAWT9cokPwDAApwCkAgL9nhbI
+n9IZ0qmdJiGbcwD8BMAGyJWk0nje7feV6EpLi2+p3bWrxgjqZzkJUCC2xzSM7EBry9OFs2Ztnju3
+6HjW8SmlRA8af2FRJP4SD7ahL1q2bFlcNyFEU0lJyQmmYR4V7zy6uyy59dFkyUrIvzuWCCiG+FqG
+HpFavf6D/NxJ8c6HSzwiKLK8rQuiFd9xHKG52frtccIcU1F/MSOV1kJQ3AhJKu3oGlqgnAdd3gDQ
+OQC8YYQ/BoS8QwuUl+hVyGx3/Pugg5IiEFxNKo0nws2/OyktLT2gcM6sDf6W1rts2+p0d2qiMExj
+gL8l8GFx4ZxHNE1j9vtYWlR0HuuZMdOyUlZ9tfJhljETiW2ZC1gV1vuzLI9+YrxziKVMxZCPyti9
+/OMp/W6Idy5c4slS9YM0LXq1BnXo76MVm9sjJp96yWLz7+31R6QAoTMVDaDPAu0XeqGh50KWvqEF
+8tj2xzeWtXd0X09SWlp0oe5v/dHQjSHxziVclFISDAanBVpbdpSWljJpreJQ5zIWcdoyDPMSTdNy
+oxE73hzbOTLeOXR3T044ILu3Etzv1nd6BBtjU+vu/SS/37XxzoVLLKmSKQ79dGSoPY7DRqkTSjs8
+zoX43h4pkGb/cla0+40NhOQCeIsWqOGe1NKtUUpJSVHhE4HWQJXtOHK883HDNM0+wYD/h9Kioj+4
+jUWBQSxyastxbCHob30lGrHjSdM0wXGs/a7AYS1HDBwk9OC1iZ1RRZuMTq//+wcXDDoi3rlwiUMg
+FL19etQ+XFNKE631VI8Tt0KRzlQuAEg547AZgPMGvTrkE1q6vZLCwreCweDFPeWWoWPbUlDXXyou
+Lp7iJg5xaNQ2ZJimOfq2kpLx0YofJ+k95FcorgRJcnFnpPvziZYwJK3hnXfHjWPfo5frthw7emvl
+99PPZTEVl0KRFiADlC5F5zOJdSC4H0SYAIqj4dDjAHIxQF8C0FmHzkGQpCVsM048lFJSVDjn30E9
+eFpPKRL3chxb0AP+J0tLZ18YcQwSneMpgT0bW4KG/jjLNZXxpiiK2NN+j7j46O/xp2f0++HReOfB
+cRwbcXqjU2YBnZ568A8Y5nCyyLyeLNJfIovNf5Ml1qek0niSVFoTQHEsKL7t8NmETKQFUo9eUF5S
+WPiWoes9docqpZQE/ebTJXPmHBfvXNpjmWaaoev3xjsPjktEw5Obpn40ZUC/eOfBcZx7MS8U6fXI
+Amgnu+NoIak0/0geQl1HV5DF5r+RbB4LkNc6jkOitiU/3ooKCx/TDb3HzSS25TiOaFjW22VlZXE/
+Fq49hh6cuXChxt8MOa6NJNEWUkW9Mt55cBznXuzXkdjyBPzvXNFfI3iYLLIWhhKG3IVWer0xBZa8
+Env6K7Z1Ar3em9vebuvurLS4+Hq/33/p//qY92y2bXmbGupXapo2RNO0kA8FjQXHccSGev9yAAk5
+68lx8dTf2/qHJWPHytNXrgzpoGBu/yMIwiMej3e3yyC1jNLhOhD7QpHSCR0sTayDYt4STihyH5po
+gXAL4LzQ3sOwrQkAFkWSZiIqKio6KBgM3LO/FIl7GYYxSJDkBwAUxDuXtgzdOLa0tPCs+fMrXo93
+LlzPsSPobdId0d0baFuUEkmgPpHAKxNbzVAMJZqnx2TKhnTIsB1/xMqe8xrMsTW/vPxlAC/HOw+u
+c3HYmUban32hWEHuRUPY4Sr1lzBD2vpLe5y2jkMPKRQ1TRMCrS0fOY4T85NBiLDPCgVKEY9b3kYw
+cE1paem98+fP/zHmg3eCUgpDtx6nlPYhhO+/49jY4U96YuwzO6Pak3BZ3rCsvtSfl+PVr871to7x
+iDbzDWCZin4FeshrMMftr2JaKNJrIKOjTSwCeSeSmASgVCBvguLK3w6IHrN+zAgGK03TjPpaPUEQ
+bFGUNhJReF+ShM8kh3yqpqRsKywsbCCEUE3TJFVVU/x+f67jGGdQC8c5oIdapjksmscFOo4jWGbw
+ZQBMGnKzZJlm79LS4jsAzI13LhwXqvyq9buwp4hb9E5ebv8+ir78oJSmYyTCboVHpqIfyiwYx3Fx
+EdsZRcHbB7A6+NTqbIk4rkM3grQTlqBHHBZeWFg4zDD0q6M5hqwoP0ui9PfDDj/8vvz8fLvt40VF
+e47s1jTNAlD/y9e3AO4GgOuvv15NT06+1rCtqy3DGBmNqTXTsIaVFhWdN7+8POHO6zaCwTmFhYV3
+V1RU1Mc7F44L12lVW7cBOPbj/H4VR2bUzlEENsViL9lQl507on/+y2u3MQnIdenuvGO9Hn+Lx3IC
+/hteW6/HO5/9yd/PHqZKgjcJACwnYN/w2vqmeOfEQuI0RaUuPsYKcNpdtkcT6PtzgTr2y9GarZMV
+pVqU5KvKyspcnTZy33336dhTNN5dVFR0ELWtZw3DGMkmyz0opTAt834ACVco2rYjixJdBuCMeOfC
+cZE6ftn2wvcvzA0e13vX7SxmFkVCkeNtnQAgKjugl4wfmzRCqb4gUzFPkkV7pCrauRKcFElAkkwc
+WSIOkQSHAIBNCbUcATYlJkBM3SEB3ZGaTUp26Lb0U5MjftNsya+OX7FxTTRyZe35iUMH9EtquSVF
+sI5Lkq1BKaKVIRFHUsSvCTL3rGS//GovNalotlpinU6lTc2W+GGNk/TA2U9v3Bjv/AHg66k5z4xM
+bcjv7BrbAdUd0Wqx5N21pvLS1mbppvEvbffHKse2Vlww7Ih+kn9yimwc5ZOsYYpAU7yC5VUEW/FK
+m4mwTzFyfYEMhxL4HdEJWlJLwBGqA5a4ttmSPt+FpMcT5d+hK7EtpJxADUSZor3dLJREPvvnkH7t
+7o8hEax5TDClpaUT/C3NzI8lJIRQ1etZsmBB+UzWa+vKy8vXABhVXFhYouvBeZRSZmufTNPsX1pU
+dO4vi6ATimnop8+dW3T8vHnlH8c7F46L1MnLt2qrL8oad2haw8ks4qXK1lgWcfZ6aVLu8P6yMTfL
+Ezyrt/J97wjWVooAPABSAPQBMBTACQBAgb/WXeWzGixla5Mlv7el0Xfv+Jd//oZl/m68evYwtVdq
+y7y+SYErctStveUuinmPAAJYSi8FOQByABxt0cZbN09La9wZ8P5zTX2f2Ze9ubo1Jsm3QyCOpAq/
+uYHV5iKQJNhyhmL0HYDWawZ6lWmfTOk387intz8UixwpQP41eeCFfeXWWzIVY0yWslkN55hOgVAk
+i5aQLFqpAFKxZ/nUOQ5tuKPmyuRAraH+u9b0/v2EZ7Y+G63vwa2Y9lEkS2EC6GArO428QbaAU9sP
+iZ8jjpkgLEO/h3VMURStFJ/3vLKyioJobsAoq6hY4POq4wWhq1eC8FiOrbGMxwqlFGbQfCbeeXCc
+W2safFNaLInJ/WeJ2EPcxtA0CO9OGnDt+ssyt56VtWvt4Rn1l+Z6A1msN+AQABmKIR2Q1DL4sNT6
+aWfnblu1eVpa/edT+z74z3MGZrAcKxyvnj1M/XpqnyeP7b+j5XeZtbMGePxdFokdkYiDAV5/2lGZ
+tTMnDFzf+PVFff65LC8v5pskI5WpGMqRabX/+PfUnLuiOc5jZ472/Xty9pKdV6T4T83csWxkStPR
+2WowrCKxMwKhyFJ170EpTScfn1m9YscVqc0rp2bd8+60wR4mAzAUh5NZ6Cft/mdCJ9Ob4A072rXS
+SaA4qINHvwg3XiKZW1R0omGYrl9k9yWKoiWrnqO1+eUvsozbkTvKFr7iUdRzBZHRoicAlmkermla
+1M5ydsMwzf6lxcVhtXniuEST/+rGnVsCSV+xiKWKTpab5787KfeSaT+n14/rs/P+ob7m/iw323RF
+JBQDvP7036XvvnpC/127v7+41+svx7hg/GRq3z8d2Xdnw5j0+qnpssH0LmCabIpj0uovOj75zZpP
+pvTrNv1gZcHBYWn1t3w0tR/ztfuaBuHfk7PvPXfghoajMuuuyfEEY1K45XgCyUekN/zpUHFXwxeT
++5bEYsxQxb5QJKSDW4akHwLSreGEonlQ4JCOP1UIwqth5ZZgTMd6gGXPREEQHFVWzikrK2PyBhCq
++RUVr8uKch1pb8NRBBzHEUxTT9hiTDeCCzRNS4p3HhznRqOpMFkLLBAa9gQAADxx9rDUHy7p/fVJ
+WTWPD0pqjfsHw2TREkalNv3+hH67az6fkh31k7+WjB0rf3dJ73ePTqu9J0vVo1qs9PP4Mw9Prfvo
+i8k5s6I5DksKcXBgUtP9r549TGUV8/38ASddvSmt7qjMuhszGBfloeqlGOqRmbvn/3x5xraXJg3u
+YBIstmJfKBrmiwCC7T5GyO10pjo+lDA0DyJ6yUsAdHTe8dfkAeP7yJKMv6Kiol6mYR7CKh4hBIrH
+Wzy/ouJNVjHDUV6+sFJV1I9YxbMt80JWsVizLVs1goEn4p0Hx7mxy6886TBYXixShP1G/v6F/Y47
+Padm+8iUxjGsbvWxkiaZ0lEZdcX/ubTXF4+Mi85twlfyBuecfej6bQenNI6L1ffvEW1yeEbdX1Zd
+lP1wTAZkoLeiq73SmopYxPryoj53/i5913v9Pf40FvHcGpzU0u/kzOrvP8jrF/fiPeaFIvkHqgFy
+XwcPi6DOs3SmfOMvPRfbRa9BX/RWngfBtA4Hot37rGdCaBHLTSCyoqwtKysL6XjEaFG83omiIDI5
+zsu2nBGapsVh6URodF0/b+7cubyHHNdtBT2/2xyw3f+JhXuj+L3JA/MOz6j/INsTaP+o1wRAAByU
+3HTkKYPqNy7LG8K0sHhj6uCDjkyp2zDA63d1yz4SIqE4LK3uilUXZT8V67EjlSlbeW6er2kQ1l2W
++dHYtPpbo9F03o0UyRKO67X7L19fnB3Xte9xeqM1ygHUdfCgBIp7Icr/oQXSbXSmdBydqQ6jM5RD
+6AxlEi2QKyHKawF6bicD6JCEmN5eZc22rKmsYgmi4Hi8SXFv26JpWp3q8dzSwRGOYbFtWzJNM2HX
+1FBKiREMroh3HhwXqfyqKttwRNcb0RxKQt5V+2H+wPFHptY8kyJZ3WJzxaAkf/axybXrl+XlRnR7
+va1X8gbnjPbUreyjBuK6dOWQ1Popn+Tn3BHPHELlk+3+kT5X0yDkr+/99TBf8/Esc2JJJBSHpdbl
+f3VRn7gtpYtLoUgqUQ/Q8wB01gx0KED+DEo+BnXWgdBvQehyADMAJHcxhArb+YROV0YxSzqGKiq0
+gZZpMTtVRpGkVzRN28wqnhvzy8ruU1X1ERaxqG139mHBNbdrKk3TGF5SUngxo3Q4LvaI+0XSDkhL
+KNf9a9LAg0en7n7OJyXWrE5Xcj3+3qPV4Kdu47w7bbBndHL9tzme+BaJwJ7i5IiMhrkfXZh7drxz
+6YpM7Ihv/09al/XhyJTG0SzziQYCYExa/dmrpvZZHo/x43brjlRaH4LixuiNQHMg0NdogYfpruFY
+aG3Up7M6T1kQBdsh4uVMgjFSvnDhlV5f0i2iILi6DU1hR3VGUZalHYLgbkbF0M0lS5Ys6XAZBccl
+KgoQmTiuF/QbDunydIpleQcrw5IbP0yVzW4xk9jWgSmNh306pd8cNzFyrJa3cz3+3qxycksVbAxJ
+aX4GBAn9b0IivEW1ckrOY4ekNiTsXam2CIBD0xomfTY557ZYjx3XNV5ksbkEBFcDMBhE2wFC5+DX
+s5QDAfs9eo061H382LEc6w+sYkmi/FEiHiu3YEH53b7UtPQkj/ceSVZ+liTRL0qSJYiiHeoXpUJU
+X1QpJUFZVf/mJoZtWb6NGzc8yConjouVqrOH9faI7lvRBGyxy02FQ6Xaxwck+ePWp5CFYUlNdyw7
+NrJb0J9M7nvjiOSmhLv92dfjT+nnCeTEOw/WPs3PufzQtPpL451HuARCMTqtUXs7v/8psRw37kfc
+kUXmQ7RAWgsIzwA00tNZPoJt5JOl2EFniD+ACCsAKL88NgCC/R6dqZ5CFunrGaUdVZZtMzn6jhAC
+QZL+xCJWNGia5gdw8y9fCUlV1Vm2aU6zLDMz0himYV5aWlo6b/78+RtY5sZx0TQg1T+FRc/CJlPt
+tNPCq5MHDB2ZstvVhoRE0FvVlcGDrXn4FGG1eXsxb9ABo1J2/TXRdnfvpbA9LyHu3srrN3BUWsM/
+ZHatfWPKK1pkVHLLc0vGjs2avnIlk82hXUmIXaOk0voQPmM4QEuAsI7dWw+Qi5FtnkyWYgcAkMX2
+yyDChdh3lpKQXDj2u3S6OnzfJ9Nb4aMF6gQ6Q5lPC5SXaIH8JS2QN+zz9R6dIS+lBfLVbZ8bLUVF
+RQc5tsOkL5QkSfVlZWWrWMTaX2ma5kiKcpmb5YqO7QiWafCNLVy34hONiW5jmI6AzbXCW51dM1AK
+/MMrWt1qXWJH+qn+q8J9zghP63Np3fSWe3c0UA2+mCqZcZ8kc6Ov6k87esSWmO1MT4hCEQDIXWgl
+lVYZiDkAhOQBeALAevxvd7QNoAbAd6D4Gxx6JmxzFKk0niTarzswkEX6S4CQh7bFomC/S69VR9Br
+5aNpgfQcWuVawHkBhJb8sot6LIAh+3ydDII/AngQgrOWFsjf0QLpZjqzy800ERPgnMdsfaIkvsMk
+0H6urKzsFUVWv3QTw9D1w+bOLc5nlRPHRdOyvFzvIJ//JLdxqnVPwxXvbWy/by6AZcfmegcktboe
+py2TCqjWPfrWgLdxc8C3baM/+aeNft/mbQHvruqgt7nRlG0WPSLbyvbo6c+dNyDkpU7/mjToD8N8
+TYcxT4Rr1/uT+l8+LLmlR/y8D0xpuuDNi3JjMoGVcFU1WYQWwFgOwNXuHlKpv0gL1DzAqcJ/b0OT
+/nCcrwEkRbj+9WCA/BVULqIzMQuLzP8jLI9OAUCdDhuIh4UQAlWUK1nE4gAiSRMEy9ziOE7En/yN
+gL5U07TlmqZ1z3se3H5jiGgtSpVM15uwag3PG0Bjh48PGGjfnCpZTCYsArZEtwS8q6t177Kf/b7/
+u/zltds6u/7Z84f2yfW0XpspG1MHJLUOVxjcZpeIg36qeQ2AkDa25PqaK8Uo3nIO2BIaLUl36J77
+rBJxxHTZVHra7eRQHZDcEpVb/BQEu3Ql0GwpPwUsYZ0NoYYQeGViD0wIvxKNAAAgAElEQVQRrVG9
+VKM361lzj2iTAaL/UQBRX9uacIUiS6RSf5Feq+TDocvwvzWLLFoP9AbFIyhQplLbmLb3tjcLDhwm
+LX0IIfbt8+a9q82fzyLcfq+srGxHcXHxg0F/64xIY5iWlSbq+r0AbmCYGscx9erEgeNHptS47pRg
+U4LdptppL74MxWQyy76uNXXdNttz6in/3LY11Odc8NyGGgC3A7j9zfMGjxme2vjqYF9LpOvk/ytZ
+to4M5bp38weePtS3c6Db8dpqMGV7sz/5/UZD/ftOkvpaftX3v9os+si4wZ5h2eb4VNG4NNsTPCNb
+jc1ZxvH2QX7upNykml4sYzZbkl0d9HxQZ3puP/rpHR92dN0LEw5MGZTccM/ApJZLMmSD2ZGDB3j9
+x76YN+iACVWbfmYVsz0Jc+s5WsgDxgsA/hmd6PRMiMpKep3C7AQO23aY9E8UJbGGkARdHd1NKYpy
+rSRJ4ayh/Q1DD85csGCB6zcjjouGD/Nyzzomq/bZJAa9DLcFvDWnV23+obNrMpXggW7H+U9z2tcj
+HqsdEU6R2NaZz29c9eb3Qwb92JK61m0+HsE+IJTrchT/XwSGN6SCtkhXN6SveKsxM+WwJ2tOO2n5
+lhfaFokAcMV7G4MnPrOt6rAnd01YPLDZ92Vtr4UNlmwxSyRB9fUEKhi0BQUAGI5Iv21Kf+2dXdm9
+hz9ef2pnRSIATHzxx+YxT1Zf/bI+tNea5tSvKINDJwBAFW0yRGmNeleNHl8o0pnyjQCuiOIIfWHT
+9+l0mcm6B+pQJsdWCUT8jkUc7n80TXMUWfmjm5NlHMcRW5sa49I0leM68sKEA7K/vTjrjaMydr+W
+IRtM7jTtCHoLO3v8kfMGp6dLpqvZlRpdDW6sTT/WTYy9pq9caf7YmHpSqy25ugctEqfL1/AXJhyQ
+PTCpdYybcfa1W1eNz+p7/+Gwp3ZdmF+1NRDq8zQNzlHLdhZ+W5s18Gd/8k+s8kk07+Tl9h/obRnG
+IlaDKZuf1mdOHP3PXX84//mNYU0cXPb46taRT9SO/bIh8xFWa2QHJLWesmT82Kg2ae/Rt57pDCUf
+lN4dg6EyIJDX6XWe48j9wYingO+++27vti2b2ex+E/Atkzjcr8wvL19eVDhrtR40Iu7mrxvGccXF
+xb8vKyt7g2VuHBcqbdw4aXTG1qP6eVrOz1aCeTmeHYM9DNetbfT7thzzzM5OT2CSdclZ1ZAx0804
+fhNf/uG19Z2d8BWWiS/+XL3+soyfh/paIu69Kwn/XebUoQHJgdIkRmvWdutq8JvmzLFdzd525qRn
+N+2gwLD/XNrr45HJTUwK70SSJplzFAbtcHRHpN80pU8at2z7S27i/O6pnVd+c1F28ui0OtdtoVIl
+SzjCt+02AJ1+MHOjxxaKtEA9EHAeQsxmTWkOLHs5nYbjyaPocJdfZ3bt2jWI1Y5nVRK/YBKI+w1f
+ctoE06j9yXGciH63KKWwLfNxSmk2Xx7AtSfX13LF5mlpk1jHlQg8AnHUVOlzNVotaYK2SDf4lcld
+XXfJa+ubACTchjvdEbcDiLhQFEjXtxwyJf38SOPvK2BLdHVz2jluisS9CEC1obUnXLSh14/Dk5uY
+zL4lil6ycQGLOKsb0he7LRL3OuzJ6vx1l/VaP8zX5PpAkCxVvwy8UAwP1SCg2nkUXZ8JvQfBl3Dw
+fxDFl9AarCaPIkivQW8QaTiIcB6IcwlAul47SHAEvMptgFEcSd6yLByoh3zToHN+3fqGTSSurdLS
+0k0lhYWPBYKBaZHGMA0ja25JyZ8BxPw4Ji7x9VF1L4CITvmIJwpgXUvaX06vqnZ99nG8UApX6/Wc
+Lj76LcsblpXt3drfzRh7fdOUfu9pVdv+xSIWsOdW9Ki8jON6q8FtGbLRI44efej4A1OyPZtd/7x3
+6En1r47ceR2LnPba0JJ8Yi8luMntzzpHDfR9YcIB2RNf/LmaVW776plrFKvlSwEcE8KVNSBkChaZ
+vyOLzfvJA8FNe2cDyVLsJkusT8liYw581giAlAGhvIDQWyJtzu04Vm4kz2uLEIKsrKzNLGJx7ZM9
+nj9KktzsJoauBwo1TUtnlRPHxdsPjWkfjX6yOmozG91Ep6XiIKFlGovb/FsDSTXHPL3jFteB2siv
+Wr9rQ3PSA6zjxsuBuc2TvaL7vTqb/Mk3a216Nrt11rObdqxpSnX9s1ZFG/2T/DeyyKk9PW5Gcc9s
+IopCuPQ7UHE8qQxu7OpCchdaAaOEFogf7TlqECmdXK6AOMWIYAON4xBGjbwJnTVrViubWKGZPetW
+v23bMZ0BEQRi33nX3XH5HdY0zdLmFl/T3GI9FelyAdt2ZD0QeAbA79lmx3Gx5VCC1Y0Zyw5/qrrL
+W877uxTZOsdtDIcS/NSaesMANEZl6cor1QfPGpz8ZUFvRWfWyiVe0iXT9W3nat3beOzT2x51n81v
+baWZc3bqLQU5atDVzzpFMc8GENHdzK70vBnFaulUAF20XKDbYJtnksVdF4n7IpX2a6D0PHQ1s0hw
+ES1A2Afci5Qw2bkkELafekJBHSpQx0FMv1j1GIiQNq/saVmR17iJYRj6mSWzZ4cy+81xCUm3RXzV
+2OsxXiTu0dUHx2TRjHgj3F7bAt66k6u2POM2Tke0996ztgR8r0crfiylyMZYtzG2B7xVLHJpT37V
+98bOQNKzbuOki4brVlMd6XmFIkhXu4goKCZH2iSbLLb+BdDbu7hMAeTzwo1tU5tJaxwQgW+QiBUi
+jnezIYVSChs0ai9CHBctFARrW1I2fVCTc/hRT+1w3aA7URCXzfY6O61rWV6e2Es1XC83qTE8UeoN
+/D+bzFTNjGy/XkJJk0xXTbZtSrDFkheyyqc92/3ev7l9085UTe9jl45mU0O00f1/C37rjE4fpXQF
+WWx97GoE27oTQOc9pwjOCjsuEbtsqxBanNjPKO6vKioq1ise1dUne8MwcktKim5mlRPHRZMDgo1+
+365PanvPGvF43QFnPr9xVbxzSiS0k/54vc3Px7hti2M6AnY0p0W1cAGA86vWrarWPfXRHiealk0Y
+OixVtly1nKvRvc0Tq7auZ5VTe855YePndabiqs2TRBwMCdQxPzcd6GFrFOkM9AHQVVd81wtHyVKY
+dAZ9EISUd5wMjg47Lhw2e54p7YkfABKWqnovty1zgmXaES8dMIJ6maZpizVN87PMjeNYCtoiPq/v
+VXly1bZrD0BDwt+5eGTcYE+fTJLtdezeikz7eyXT41CaTClRZclSHSqkE0AQCTyUIg0AfJJxkKtB
+Scf3nr2KcZqr2AB2657m8V2cY81KgymvzPXi9FiMFQ0DvIGz3Z7G0mjK6xil06kGXV3XSzYOcRND
+lcwTALzGKKX/6lGFIiB1tdu4ATnWR2yGEl6BTTsuFIEB9Hqo5D6E/CmBUsqoSGDU8p0LiaZpRnFx
+4Y22FXww8o0ttmoEg48BuJBtdhzHjke0cVLvmoJtV6Rf8nHAe8vxT++I+vFhHVkydqx80LCaU5KI
+eWqSZB/qIdZgWaAZquCkKoLl8UiO6BFiUk+FzCM6rk9jabalmHW0aLHFz4DuWyiqgu16PajfEb9k
+kUtXGmx5NQB3haLoHM4onV/pYTNPQle9kr4nmrseWf91v/Ed0GkRKMD0hHemrwAmhSJ1qEA7u//B
+MVdWVvEPSZY3uImh68EL5s6dy+zccI6LBgKgv6c15Zj02qXrLsv87q28IWmxGFcbN076dHK/q1df
+nPX+pmlp9ZeO/UE/KXPnG0dm1M4ZldLwhyHJLaMGJLX27eMJ+NIVU2R50kx4Ol6zrIrOALfRg5a4
+2m2MULXYYrc+PUomziC3MQK29BWLXLqiO+7/Xb3Ejkqj9J41o0i6OCeZ0BpmQwGUAtUABnZ4keR0
+1kbnNyglLW7zAgAKkIULF6YCaGQRjwuNrKjjLdP8PtIinVJKTF1fji537XNc/AmEYpiv+eB02dz2
+yaR+Jx63YvvX0Rjng0kDzuulBm7rl/Tv0emyyeaI0ziRieNqYwUAtJgSm7tiIfh414jPjs+op9E6
+xSfaVMnu+qCMLjQG5ZiswdV15zO3MRTJTmWRS1s9a0axq8UIrNupdLUW0ApvcYTsYKObdPailKKp
+qamrtZocY/Pnz/+P4lFfcBPDMPQRRUVFV7HKieOirbcS9I1Ib/rsjckDXN022xcFyIeTcm+ovjK1
+7sQ+O58bldZ4eLcpEjt5H5IF6nrH8y5T/NZtjFBp771ntVoMulXHiQL3P++Njb5NLHLpyo+tff5j
+u7wRKAJR6XvZswpFSrpoMk16MxsKICAkq/OrhLBmCJWUlO/c5PSrkQUa9mYazj1V9U6VJCmis773
+skzjb0uWLOkRx2dx+4deiq4c5mv87PW83Ey3sd46f9DI9Zdlbjouq+ZvfdRA2P1o44120nNCIo7r
+Qwla7eSdbmOEw4JgxnI8lgTiuOokQkGQhNYGVvl0JpDmazYcd5+FJIGy6ZzSRs8qFB1naxdXjKJ5
+YPOpdLo8Gp1X7zZqg9vDCTlixIjtgsBm0tOx6JFMAnFh0TQtKMtKESGR/zvaluXbvHHjEoZpcVzU
+ZasB3zCv/303Mb6cml14TFbNd8N8zQOEyNuTxlVnfRhFgbp6/7EpQX2A1rmJES7LJkYsx2NJINTV
+8jpKgU3jNsbk+7+p6tOg5fJXXiJOVJYT9qxCUbLWovNzNjORJR3LZCxCz+7iip9IFcL6BcvPz7eJ
+IDCZ5ncc52AWcbjwLSgvv1eRZVe3K3Q9eHlpaelQVjlxXCwM8TUf8kl+v2sjee6nU/o9OyatvjxZ
+tLr1+1Jnb0AE7iYqTEeA3OBrchMjXA7g6g5JPAmEuCsUAYz6/uCY7OUgAHUocdUDWSIupyQ7ihuN
+oPFCHkAtLcD36GyLOcVNAFwtBqa3wodW4YZOXxIIPowkNiGkCYDr2zeU2u56gXGuSKpnkmGaX0S6
+scVxHME2jOUAotLugEtsXzX0WlbXqlawiOVVnQGqaOVQ2NkekQxOEo2TMmTjgAzFEFnvUCAABie3
+VlBgUWcnlLS1ckrOY4dn7D7fbc+7REBpx9+EQNwddUIIoPdpjHUh3S03sgCADXeHT1AQbGoUZSC8
+SZ84isq/VY8qFPcgrwG0k0XV5Dw6XT6SLDEj743UIt0KQjtvfeOQiNoKCIK4CbBcF4qWZWfcdNNN
+3nvuuYdNE28uLPPmzVtZPGfO60E92NXMc4cM0xhTWlR04fzy8uUsc4umBGnL1K1npAAADnaf8eIm
+VruIfxNH0yCc/P2AvIHelgWDk1qHsrzN21f1J380ue8NeGbH30K5/sup2YVj0uou7QlFYlccx90P
+WiIOVElIQeet2ZgSSHQ2SMSEA1frKyXiIDfJyALQxf4H97Rx4yRZ+NzVa5fbGcmOdP8X1LYIfbKL
+KwQIWEFnIieS8LRAPBuE3NbFZU3wGi9FEl8g5PtIntcWpRTJXu9kFrFCIcvS56pHWRPOl9BdFyGF
+KKN37zxRFCN+QaeUwjTNBzVN6zZ/pyQBPnwS4v6DVk+naXBOqdryzNDH6od9XJs1s8GUmTYd7K8E
+bwrlupfGDxk43Nc8vye9FHT2nVAQVz9nkVColhOTvpX/HRPothvrbBDXG3FSxKao9CZsq7e4M012
+WedFq1CM+4s6a2SRuYoWyO8BGNfJZQNB5XfodeK55P7gz6HGpjOU8wH6BLoqsClZTO5BRDN5okDe
+B3BJJM9ty7TtGQAeZRGrK2UVC08O53pN0zINvb42WvkkglmzZrUWFxfebvsDEd9CNC0zXQwG7gbw
+J4ap/YZhGJQQgkhPltmLkvi/pjgOYVIoCi5vW3UXJ1Vtq3xz0oAvjsqo+yRdNpgUBX29wYFPnD0s
+9ZLX1ne6nm5YeuOK1O7S9iZ0Hf4RuS0UASBFQhYAV839wyEITrctFB3qfiOOjwiDGaTSpZRU9JIF
+dy85FnX/+9WebjNTER6qoev1MaNg25/RAvlqqnX+5kYLkEEL5HtA6HIAXZ3n2wAYfw0j2V+xIbzi
+Zsfsr2JZ1phEnY0yjODlLmuSbqGsrGKhIsmuzhEzDOO64uLibFY5dTQMiyDUiX+hCAdMWqpQ0lW7
+rZ7jzBVbvlzTnDHRsEUmf5Ue0SKDfP5OP/C+cf6AQ4b4Wnpcd4bO1mZa1P3fWXZSa0w3uflEy/Xf
+tCC6rIAiZFLR9Q5xVXA6PlSDoVzB7/qgBZOSqCw1i/+LehSQSut9WiD/E13PzPUB8CCq5VI6Ey+A
+kH8BdAscsQGOnQlChkCgvwfF+UCIbz4EJaQSEZ8AU1ZWtmPOrbc0mZblusO6bVuqZRjXArjPbSzW
+HMvZb840FlX1QmJbn0Y6W+c4jkgdc0WU15QzWqztbrE+CzZ1XDfZBQBC2JyU1F0c+8zW1769pNfb
+h6Q0ncEiXpJsnw5gUUeP90sK3qVE504ZbErQaotO0JaDQUdo1B2xwXbQaFGh1qLiLtOmjU4HBZ0q
+4rAxaXWnRDp2Z6t0DUdoAtBF/93OeQV6HIB/uokRqucnDh3gk7a4/ptuJU4zi3zCFXTINrjcEOiT
+rZjcek6TjaPcxjCpGJUd8T2yUAQAELMAVD4KoR2HNggUN4DSG/b8v/Yvc600jH17AChdTiqtDl8Y
+QyWK4irTsk5yGwcALMuchQQrFJcsWSKvX/ej6z+K7mLBggWfFRUWvq8HA2Hdnt+XoZvHy4q7mcmu
+hthTiLqbULJtR9A0LUfTtJg2Bd4XoRjBJpK9XxWKALBTT7t6mK91E4tzkn2i1eGmQgqQnWpwnOtB
+fmE4Aqp1747dQfWDFlt6vdaUnz//+Y0NiGAF0Cd5/a4DEHGhCNrxgkubCrUAXM0IqqI12s3zw5Ei
+Bsex2GTUHPDFpGl1WwYVN7qN4RVi00FEJPQwtzEMW4hKj824f/qPFrIILXAwGbE773g1PNYfWQQS
+ROF5FnEAwDTNAVpp6ams4rGwZdPPN9uW3W3XvURC9XguEMTIj8KilMI0zP4sc9qXpmlOZ42Cw+GY
+wRNZxIkUpZTJ8ZUEiMssSDydUfXT5u2BpLUsYiXLVp+OHnvrgn7HZau66920zZbkrGrM+OebdYNy
+Bz7a0O+Ip6unnFS17dE9RWKcdPJ3ZFBS7Ta8KjgxO541WbF/5zaGQwn8fsTlQ5duCz+6jeEVrcEM
+UumSKlrD3cYIUjEqxw322EIRAMgS8xsQUhmDodZClM8m94LJi5Np04cJYbMNkFIKv64/yiIWK6Zl
+3RjvHGJN07Q6VVHL3Kw/dbvRpCtEYHNUl23jBBZxIuU4tqtbe3tJkhjNGdyEVWsqT7OIIxHH09Fj
+GYo9xe3nku16Uv37db0OOvzJmkvGV63tFv9WuiW5LlwyZT3a65X/K0UyXd/50R0Ru8Z972eRT7g2
++5Pfdlx27EoWzXRt3Lio333NkE3XayH9lvRvFrm0FfNCkc5EMp0unUELpGJaID9FC+RVtEDe0Obr
+KzpTepYWKHfSGcrF9Fo1oltJdKZ8GSidxfp7aOMbEPNkcr8/rOP6OrNw4cJGSVbWsYpnmcaAuSWF
+17CK58ZtJYV5lml13oOyh1pQXn67JMuuZxSiRSCR7dRvy4EdtybhJSUl/R2HzS7NoEm3sIjT3VQH
+vc+y+EgioOPj03yi5WqmqtUSnfV+32HjV2xl9jq5lyO4O/ats/rX78gfu4oNIEMxpFcuGMBkaVJX
+0iT3t7mDjmBpWnw6CEx9ae2PTZbkauw0xSKHZ/50NKuc2vPIeQcNzlR0n9s4LQHxbRb5tBWTQpFe
+iRRaIF9BC+R3QeV6CORNgCwAMAXAYQCGtPk6HJScD9BbQegTcJwfaYG8jhYod9JrlZCOpqMF8uWg
+eAQuj0zqfBA8Cts8jiwC8/VYokRcr3XcVzBoPjB/fskgljHDpWmaRzfNh6M9M5bIFFWanAgdqdtD
+ITBZCG1ZzhEs4kTCcaybWfx+EUIwePDgkFtn9STnPvfz6mZTdv3GLgkd/zt4JSfXTeytQd+XJz+9
+PSqFvEyoyz6FHd8N2knpB7bLGS4CYKAneIOrICF4cfyQo7I9Aa/bOLojxq17AAFosynXu4tBkasY
+U1jl1J7hStO1isuN4S2mRD9pGrqKUUq/EtVCkV6LXrRA+TNUeROAh7Gnt2Gkn9aGAfRWOPQ7WiB/
+QK+VTutw3AL5il/Ga/v91YHSIgAbI8xhr9UQ6OlksXkFWYqoTKkrirdSEERmPZFs25Jam4x343ly
+hh4MPmwaVnK8xk8E8+aVvy+rqqsjJKNFFEnEu/X3ZVuWb+7cuVH9BN4Rajl5LOIIgmBNnz6dya34
+7oYA1G9Lrl/XBNLxa41HdFx1dag31CfcPL8zEtw1tO7sc0p+1da6WkNx3WEgy6Of5TZGV/ont94s
+MlgBFbSis8EiVC2W5LrnZIaqn8sil470UYIXuI1Ra3h2au+9F/E6+M5ErVCkM+XL4Mg/AvQ2hNpa
+JnQnwiFv0wLljba3pekM+UoA/0C7RSJOJ4utCuw2DwTBFQB5Awj5iB8bhLwKIkxApTmGPGC9w+D7
+6JCmaYasSEwLCt0wDigqKnyTZcxQ3VZSOFnXg1PjMXai8XiTJoqiEJU/aDcEInzHKpZlGOWsYoXq
+jrlzjzItcwCLWERgM7vaXVkOCUYzvojIN7MFbRFbNgv/YJnPvhSBumqH0lWvjEZTcT1Tna0GfF9c
+lHOd2zgd0TQIud7WCSxitdjuCzU3Gm35Vbcx+nsCg16/YFBUlky9eVHu8EHJrUPcxmmw5U9Z5NMe
+5oXinubU0oug+D8AvVjHbzPamXCc1XSmfBMFCJ0pXwWCB9FhkWh+DQCkCgZZZD5KKo2zYJtZAD0D
+oIUAHgKlLwB4+5f//QdAbweEiRDMbLLIOIcs0l8K57B7V98dhKtZbWrZy9T104uL5sSkB9deWsmc
+EwJB44lOP2rvRzRNq1Mk5d5459EWJWD2wcQwjXHz58+P6VIHv2E8xmpZg0CE/XJ94l4WotO4dy9J
+oBEvCfLbkpH/6dao5aeIjqtCkZDOfwn9tvyJm/h79ZEDf6ZRaq562g/9ZvVR9a4OlwiJ35Zcr8t0
+Y7ed9IhF3ZU6imCTPp7gXYxS+pVcIbCURT/ROt0btfd1poUivU45FJC/BMh4lnG7oILibhTIn4Fi
+KX77PdXuWyS2RZaikVRab5NKayGpNK8mi63zSKV5xi//+0dSad1BKvUXyQOI+XFzFRUV6xVF+YJl
+TEop9KB+UdGc2Z9rmqawjN2e0tLSCa1B813btntuz84IzK+omC3LckIdYUiI+Bar9x3qOKS5qek1
+JsFCUDpnzo2moTPrd0ZErGYVqztyKIn4jPIQ40dc0dtR/KBOAdJL1V3N7tAu/oaqLeXRrq4JxcAk
+f+aXU7IjPgWsI6+ePUwdkdyssYrXaipVrGJFYnzVT5t36R7X6yQP8DXnPzThwBQWOe31QX6f44f4
+Wsa5jVNnqMYHh2xi1lavLWaFIp0unQGbfoI9m1Hi4Xf4zfdDdsAmJ3RUJHYHqjfpj6w/MlJKoev6
+7/ytzdW33XZbh2s93dA0TSguLqwMtLY8z4vE3yKEUFUQL2V0WiMTCxYs2CRJIrNbjpZpjCwumsN0
+U1Z7bisuPi1oGnez3CRFCHF9u6qbi+pvpuWQiJdeeARbidZM2vv5A6b0kt31dyS080L2zGVbPtyl
+q0z+zkamNt347vn9mLajys1sfLOPGuywtVE4ag3VOHXF5u9ZxHKj3pRd1wDpkikdk1rLrBhblndw
+8nBf8HWVwemGO3XP59HcWc6kUKQzpeMgkOcAJNJGhVoQ+gey1FgT70Tc0DRtteJR349GbMu00lub
+m94uLpzz4ezZs12fM7nXbSWFkwOtLTVBf2BGPDfPJLo7Fi58TVY8TGeM3RJFkdk6xV9mrwuKCwsf
+ZBWzrcLCwqmtwcAbjsPu6EAiEKoo3mdZxeuOCIluoWg6QsSFUrJkk/fy+h3PMp+9+qt+zW2Mrl7x
+CEBrDeVzt+MAgE+0hIMzmt56O2/gKBbxPp+c/eDBKY3MWu/U6J4fWMVyY5vfeyeLj5EHJjed+unk
+fte7jaNpEA717PwsxxNwXTM5lKBG95S5jdMZ1zM99Fp1BBznRQCuewCxRc8ni6yobBWPNYeSiaIk
+1diWxfxWMaUUwWDwBBCypnDWrDWSLC4dMOiA+8Pd8VleXp7R0tJyq2XqV7f6g3325xY44fB4vRMs
+09jqOE702jiFQRDEFQCOZBVvz+x18Oo5s2ad7ABn33nnnUwWtmualhwMBp4w9eBE1r9rkiRv0zSN
+0dnX3RSLe6OdCDpiNSLc5EhAkaUYGoDTWeb0xZSciiG+OvfHPzpd3xrfHvTddVBK88ksDkPKUnXP
+GFL71XtTB44f99TmtyKJQQGyamqfFaPT688XGN7ZbzaVh5gFc+HMZ7e8uOOKlECOJ+iq3Y9IKMak
+1f3twyn9Wk98evvDkcTQxo2T8tZ/9+VBKY0htfrryvagt+6Uqq2vs4jVEVeFIr0SKXCclxH1TSsR
+uZVq+JjEqdEnSwsXLmwsKSqaE7Tte6JWgFEKwzQOMkzcvXbNf/46e9attYIg/iAQ8gMlZLUsCFtB
+aQsAWEBfAehLbbufQ5xjHYseXLurJtVxuv2POuY0TdtZVFT4gB4IRL0vWihS09MfCOrBMuo4zAoF
+SilM0xhOBGFd0exZn8mSXHJHWdm7kcSaPXv2SJGQ+a3NTeNtOzrHQBKBvByNuN1KlGcUg464AUDE
+a0qH+FpPfefCfsedtny7640hFCCrLsp56OCU+isEFnsHQ6i0Tl+++eUt09Iac71+lz0b9+ilGOrR
+Ys0bqy7OXrbWkK/Irwp9s8/HF/U9aYvsf2ZMUn0Oi1z2ajAVy189YjHA7CwKV2p075s5nuBEt3E8
+ok2OSdv90HcX975orV+dfMFz20Jea/523sBRw5JWvT0oqZXZDmYwSK8AACAASURBVOrtQe+D0T6p
+2N2MoiovAuD6fMJfGABaAaSAwUwnQCZgp1QCWPPcx4q/BeXl9xbOmTXd0I2oH1BOKSWWafYGzJMA
+nAQAUV3Zvp9TVc9NjmVdapom6zZSYZszZ05zUeGsb/Wg4fpEhrao4xDdMI7VDeNfs2+9JUiIsFEQ
+hO8E4FsiC18Si+7Y93pbEPpRSg8TQEfZjn24Y9kH2KbhtaI4W00IoR5P0u1RG6C7cKJbKDZY8qsA
+zon0+V7RIqNTm955fWLfM896YceHkcTQxo2Tzuqz5sbtSYGSMd5aZn97of521hjqg7le/62sxvWI
+NjkstW7yYFOe9P0lvT+tCyqPfNbUe9msN1f/ZiPHUxOHDhjs9V+TrQYvG+CpHdhZc/RI/ez3vXNK
+lPr6RWJr0Hfj0KTmCT7Zcv27LQkUB6c2njbIK1V/e1HW29up70+/f2pjh8vcnjtvwNDhvsDdg327
+zvWJFrNlMrt0NbhqXf+5YH/mx69EXJDRGcr5AL0k4pEJ1oCSZ+HQ52CaP5KH0QwAVIOA3Uk5MPUx
+EITJACYCiOxTFyFz6Uz5JbLI7BG3oHv17nPkrurqbZZlMvkUyiUGTdOcoqKiK2Faz8Wo81KnZMV7
+hx40lkdzDMuyPNgzo3QQgAsT5ZOIrKj/0TSNSePxbk2IbqG4w/H8U3fEB1Qh8jMFequ65+Rs6/01
+l/b+utpQl66pzXl6+tsrO5xauf+0g3qNSNOPT1X0E9Nk/awc9YuR6bIRtyUfTUrS3Dqj9cZMxWA6
+M54mm1Ka3HgiUnDikb3qHr7iKp8edKSg7cCRBSp6RTspWdoqSQxasnREt0Xa7Eh/jNoAETjn2Z83
+fXNxnzdGy/XMmpUny5Z4SFrD70fSxv9svyKttd6QfrSotIGC1tuO4FUk+4AU0RyZre7q5WF3fsZ/
+bWxNfmD6ypVRPxggokKRXoMkEHpPhGP+BEKKschY1l4/wj23iv3bAWwH7FfpNUiCIM0CIbMQ/jpI
+GcAiAMdFmGtCmTVrVqtWXHxSi2N/lShr2jg2ysvLny+aM3uVrutj4p3LHXfcsWLOrFnVpmlkxzuX
+WJMIuSneOSQCtt1bfyu/6qfGny7P2HJAUourBuke0SYHJjcecSCw+Ki0usXnXZWsBy3xv6fKiAKR
+CKjkFSwlRf5ZjGZxtFdXu573OuXRjcHPJ+fc87vM2tnRysUj2PAotgoYrnZyh2tDq+/NaB2x6MYG
+f8rlg5Oad6RK7Gb1gD1rF/t6/L6+HhwBICZHmG4PJDW9Wn1QYbRnE4FIdz1L0nUAImmm+w/sNkeS
+RcYzoTatJkvhJ4utP4NKBwIIf10TxbG0QGXSYT4RaGVlq1WvOpMkUl8VjgnVmzRREMWEWOgpq+qV
++9vvmKIqa+ZXVMTl5KJEQ6O8RhEAduvqoyzjeUULfRRdHZjkz9j71d/TmtLP4/dmKEZMikQAe3bb
+hOi1kTuLdgSTmqOZTqzVGqrx/e6ci+KdR3sueG5DzTeNmX+L8l6tqDMdAT+0pF4WrSP72gq7UKR5
+UEBxY7hPA6GlpNL8I6lCRLsJyeLANuw2zwLwWPjPdoojGTNRLVhQsdTj8Vbsb2/kPZ2maZsVVX40
+3nkAwPz581+VFTkhWlvEBCFUVjzT4p3G/mSjfeKfaww2/QQTCQ1xRhEANA3Omqa0q0123Z3iyqEE
+G1p9M/Pf+D6u5zt35sRl225Z15L8U7zzcOOH5rQ3z1i+5YVYjRf+b2eWMgkg/cJ6DiVlZJG1IOyx
+2iBVMFBpTgPweJhPPZpeKx/tdvxEsqC8vMjj8d7Oi8WeZcyYsdfIkpQQ5wynpMqniqK0X7SJ8XjV
+/5s3bx6T3nY9ghP9bhH5VVX2lkDyo9EeJ9bCvWt/6orNy75rSn8pKsnE2OqmjOePfro6IVridIQA
+dEtj2nENhtItX9s2+n1bnh9Rc3Ysxwy/UKS4NMxnVGGxMTfscTpAAArbvAoUH4T1RAfTWOWQKBaU
+l9/h8aj3dudiUZSkBNnGkBjy8/NtxatOT4R/05KSsmpPkloQ/0yiS1GUrYrivSreeSQSyrKZXide
+HrHz2i2BpISdfYpQ2D+7L9bmTtoSSKqPRjKxsq419bPDn6w+P955hOL0F3+uXtnU69wmU2a/wySK
+qnVvy4/NaUdH8xSW9oRVKNIrkQLQcI58a4ZkXhvqesRQkaUwIQp/BBD6/XlKz43WsU/xtKB84U2q
+N+kKQXCxfTBOVNWzRBDEbn1yTjTMm1f2dKLc9p03r+xhRVVuT4C6NSpESWrwJPkO1TQtIdaGJgqC
+2LwRaRqcta1pU4K2GP/t/nE0feVK89umzMNrGB3tF0sUwJrm1PdHPFZ7bLxzCcfpVZv/v71zj4+q
+uvb4b+1zZiYTwjtBRER8XCvWJ9bqVajvJ+1ttQJerbSoH4d5JNS2+NY7VyEB8YqdmTNDrK+KWgnW
+R4veXh/VimKLL0TxiS8EhCQIhIQkM3POun/MTDIJk2TOzJlkgP39fPL5sM/stffai7PP2Wftvdd+
+4e3m8vN27CGDxcaoo231ziHHn//k19/2ndtazHkUberJAEycDkKLKIgGcyplWbLW/inMTEETjYXH
+XvAYhANBdXX1Q05HyWRVte3qO3dx4ChxLq9ZsGDWQOtRrKg2x4+FKI6NLTULFt7ucA5aWAxeTiux
+qWrT0GHDj/H7/dsHWpdig7n/PBZnL1v/wpqmoTXGXnPaZ257xqc8+eXXaxpHnrItZi+a2IN90aqr
+xuodw+ZOeGTr6QOtSy6c+fj6l95qGn7OtiKfht7c5mx+r3nosecv27BuIOo3N1BUhJnzNVuhRv/H
+nDomIWHufEPmkwukyYBzR03NG6VlZQc6HI7VxfxCJwKcTmeoZv78nwy0LsXM3Llzv3Q47H8aaD1S
+VFdXX1dS6pxBe6DnOhM2u+1dZ9ng/W+55ZaiC+FRDPS3e++kx7fcvHr7sEXxvWNTR87mO+cvX7/7
+fsPwid+2lxb2qI08YQBftpR983bDiIkTH2uwbGnZQHB23caXP20bduiGXc5+99Rlw+ctZRvf2Fhx
+6NlLN346UDqY7JU8IeusRC9TEAVdlE/h9nVgvJ+9AAY8Rl0h8fv939UsuPP4ktJBM2w2pei8i0JR
+Yg6n86p5NfPzPlR9X2Dc+INnKqq626kKA8W8eTVLSgeVHW+z2TYW88dIbwgh9JJS58IFd9410e/3
+F10f2Zc54fH636zeMXxB254eIjbPUfZpz2x4/8XYQQd80jz0vWL0sm5pd7a80VDhPeThbeMmP7Xx
+vYHWxwpOfnTjhrF/bDrgg6ZhS4tlGUSUBdbsHLbskUO2jbv4+c8H9BAAcwNFxqHZ5+XnzCqTE4Ke
+zTov8/jCKVI8zJs3b4lz0JCRTmfpnxRFLYppDLvD/rHdUXJQdfX8nA5S3xdxuVwxm2qrKqZB2R13
+3PH+goV3jbWXOG9UFHWPWU9FRHDY7a/bS5wHVFfPL1iAY0l+nPj45hve3DFyasOeHTYn74HGjCVr
+Wo5Y0njcqm2jfr6pSDa5fLOrdOsb35XPGv1AU9mpT2wKD7Q+VkMAH/1ow6Vvt40Yv65l8MqBDFm0
+qc25+b3tI0899pGGaf29cSUTJi1BB2SflfvnS8OAiXoor1MA9iT8fn/bvJqay9qi0TKHs/QeRVGz
+PiTeSlRV3eYc5Jw2f8HCCdXV1UXp2i9mqufPf0C12T8baD26U1NTM3/Q4MGDHY6SuapqK4oXWSYU
+VY2XlDj/anOUHFpz58JJ1dXVWwZaJ0nv/OjxjU/8LXpI+fs7hj23K64WhXfHDGzhzP2/L93w5B++
+On7Ue00jApvbnDv62xituoJ1zUPWrWwc5TnwjzsqTln6bW0/q9DvTHp40/p/e/i7U1+vHzn5k51D
+3mmJ9c89yAA2tDq3/3Nb+W/GPNg05oePb1rZH/Vmg8kj/Lgs+7zKZjObknOGjG9NbGY2of/eQTAY
+bAdwbV1d3e9Wv/POL3XDcBt6/Dhd13M+57svSBDbVNtaVVEDqsNxv9xRmh82u/2n8XhsLRtG8bgW
+Afj9/jiAWwHcesstt5wej0avNwzjR7oeL2UemPc7EUERol1R1PdsqvqwsNvv9/v9e7J3ap9kxpI1
+LQCmvDD1kHGj7U33H+BsPX24LVqwZxYARA2Bze0lW5vjti1HDt5xZCHrMoP/lVfifmA2gNkrph/w
+41G21ptH2qMTRzraTWwszZ6oIbCprXRzfbvj6S9aB1X/5zOf75PreM94atNrAE54dMq44YcNilaP
+Lm2dNtrRNsIurHudMYDvovb2xnbHqg0tZXee/dT65Sjsir2cMNvxnFnnbG/vn9hYQjTCyPKlxJy9
+/nsZ06ZN0wE8AOCBuro6ZfXqt6cbOi5hwzhR1+P753N2NBFBUZUWAfEhqWK5w+G82+/3N1un/b7N
+3LlzP7rphhv+2tbWWrRHUc6dO/cVAK8AgP+mm45qZ/1ysHGGHje+ZxjGEGYWVg8eiQhEZCiq0iRI
+fA7QSqGqD8+bN+8tSyuSDBjnLPtiPYBz6qZOVcaK164ebm+fMcIWPW6EPVaaz5F8Bgg7orbYTl3d
+uktXvmiO2VZs2mUP/PQv32xaOXWMD4MRzLlwKtxJ2ZOXblwOYDkAvHzZuLMrROs1ZUrsB0PU2Nhh
+9pjNxOmBHeyMq0ZTzL6jOa580KTbnmuIOx+asuyrwh8gvIdw+bPrtwFwA3A/edGho8bYW2aNcMR+
+NlSJHT7YFh3kVLLf3xdlgW1RR3NTTP28Wbev2NrseOCcv3z9LtACoHjDiZodKLYDKM0qZ0nJYKCt
+8C2PG0MgsnS0EEnPAjoGjY8l/8DMdNtttx1jGMZJrOvHMnA4sz6GGTYwO0FkAwAy2GAhWojQLoAN
+IPGhIsQ7jtLSf+S6e1QI8YHNbh+diywR9bjRQxHK88Juz2uXO6m0Kh95K7GXlEw3DONlApfkUw4p
+ouA75/zV1R8AuLHLNb9/jBFrm6wbNNFg3h8wKsA80mAMA6AApIK582OFiAGOElGMGC0g7ABoK4g2
+qURfq0TvtTGvrqmp2Vro9pghDvHJRzuH/CPfclqhvmSFPrmyvd3+xEfGkLzi4sVY7ASs2S80bdky
+HUBt8g91FxxWceCQ1kvs0I9ShH6QIrjCToZdJBdTRQ2KEdDSZijtAFoMpo26Qd+0wv5Va1z55IOd
+gz+f8/yajM+Ptrjx/gdNQ3Pu+ztjdnOHQeTIGY+tfxHAi6n0C1MPGTcIbZOcavxYmzCOEMRDFcIg
+QawCQMyguM4iFjdosw58GTPUj75FyasXL/3iU2BAViahxVCf+2jnkJH5lBEz1Hqgf/wSFz/1eT2A
+25N/8J9+ujp52LqJQ5yxc0qEcTSDnIKMMubU7CVtixrKRt3A11ESn2zShz87bdnaPc6JYmoqi922
+egAVWWU2cCLVxgr+Zc9u+88AfirL7O9SJDaxoApJJBKJRCKR7CWY3dbTmHVO6q+NI2Z2MlNBgn9L
+JBKJRCKR7I2YjaOY/e5L4nNN6pIbhAuzz2xCf4lEIpFIJJJ9HHMDRSIzA62CDxTZgzIwJmctQJAD
+RYlEIpFIJJIsMTtQXGEi9yHsVi4wp45JWK0EYGZxf96LzCUSiUQikUj2FUxOPUdfA8xECRe3mSs/
+e/hKDAboNyZEtqEhlv1xfxKJRCKRSCT7OKYGiqRhK8x55U7mWbYrzKmUJQ7bnQDKTUg8TcuQfcAj
+iUQikUgkkn0c84cZMh4xlZ9Qy27bCabr6U2FWTYXgFkmpR6zUgeJRCKRSCSSvR3zA0URqwNgJsit
+E8xP8zX2I0zXlQF226eCTEfN/wj7xf9uRf0SiUQikUgk+wqmB4oURjOIF5kTorFQ+E32OH5itr50
+2GP3A7wUgM2cIM0jv5m1lRKJRCKRSCQSUyezpOBfYxiito/B2M+kaAzAfVBscym0a1PW9XnsEwDc
+BWYTMRNTwngfo2MTyY+4aVmJRCKRSCSSfZicBooAwG77ZQA/mqN4Kwh/gkHPwYi+SPdix27l/xrD
+0GY/F8Q/BTAN5s+lBgAG82RaHH89Rz0lEolEIpFI9llyHigCAHvUJ8F0UZ46xAGuB9NmEL4DMATg
+AwDaD7kNDtO5myKx3+ZZhkQikUgkEsk+SZ4DsfgMwLYKwIT8dKAxIIzpvJTX+DXF39EYu86KgvoT
+TQttJmQ/pV/f0Gjz+/3xhKz2KwI/mPyp3eP1dQlGHggExqqK+CaVZtBkr9f7Wje5jDDwqNfr+0X2
+7TBfZi8yrQA2gvAKMy3wer3rClhXjzJmYGZarGm/YGIPQN8DUAJGAwTWMNPdXq/35VzKra2tLTVi
+satZ4CIwjgIwFIydIHwMwvL29ljk2muv3d5drpf2xgjYwqDXSeh3u91Vq7KU62xrH7Yl4CG31zcz
+XSashRoBjEzIJ+7DbNofDoeHE/MNDP4JgPGJ4rEVwAYQ3hEGnprl873Qk3wB7JfRDrn243A4eBmY
+kjM19JnH6z28o3xmimhaIwgjkhXWeHy+m1K/RyLBM9mgl5LJrW6Pt4KIOL2ecDg8BWwsT1M6CiFG
+ezyebZn0yrVP9iGbVr1lz5U+9Ulh1gY91GsAiDKwgxhfM+GfQih/cLvdH/Qhu9tzOdd7si/ysb/f
+7xcVFRUXA3yZAE5koCLZ5q8A+gcDD3i93jczlZlPe8z279raWpsRj73NwNHJS2/WNzSe7Pf7O/Yk
+BAKBITZFrGVgbLLVz3q8lT/Op14L39MZyeJ9FdcNPqiysrLLEr5wOOQFI9S1LBrs9Xqbs9U1E+Z3
+PadBYTRD0FSY2wXdH3wFxXaFjJu41+AEcBgYVxP4zWAwePBAK9QXi8PhO5jwMEAnAxgOwAnCODB+
+LICTcipzceBIXY+tYcLvwTgdiTiituTA4RQwqh129cNwOHyyiWJtiQcoT2dDvBEJhS7NRbfeYOAK
+TdPy+ZgEACxatGgY2FjF4OuQ+Dh1InEy0wEATgLDrRN+2ZN8gexnKcwi7fQr/rdIJDIqldI07ciO
+QSIAEE3qImyIzuNMGa93HyQmK+hqH4KdDCOX//Ni65PZ62ONDQSAEgL2A+GHBFSxoa8Jh0Lz/X5/
+1u/VYrwna2tr9x81qvxVAi8j4KLkAMuBhI0nADwL4L9a3Z5c+rfL5YqRwVcCHe/6EysqRlam57Ep
+VNM5SMQOEqor33qLAFWIriECmZmY4StIZfkWQFp0Lbts50PgJQBDLNApXxqh0wUUyX6zTDFBhDBz
+px0FcG7H1xJjPROWdROxeje3zsA9GTR7u5/LjIMxB4ANRCcAPD15fZgQuAbAjRbWZXmbGexJS1zL
+RMuZeYxCdK4BmL4377vv7hHRNvG/IIxLlhkF8CgTf0xE48GYAWAQQPuDjeW1tb+f6HLNXt9DcSnb
+AsCBIFwFYCgAwYRwIBB4qqqqqj2DXK52UgCeB+DiPhvaCyV2eyWDD0smtzGwBOCNBFEB4DCAz+pJ
+1mL79WmHXPux1+v9JhwKre/QMx6fDODPAKAQTWKkj/34xLo6v33aNH80mU4/9343D+2iRYuGIeEx
+6QITzwAQ6aGt6eTaJ4HCPFdM62OBDYBkW4hhB2E8gLMAlAIgEK4fVV5uA9DnkieL78msdN79clf7
+33333U49HvsbgGPSLq8E40UmbiGIg8F8IQgOq9uTa/+eVVn5VjgUuguE6wGAQHNra3//lMs1e72m
+aacw2N2RmfE7t9u9MV0+l3otfE/n0S/omro6/9xU/6/VtLOJYEkYwu7kPVAEAKqNvcVe+ynQjb+B
+aGzfEgVjHaCcR/e2fTGAOuSFx+O7PT0d1rT7AD4aAIjwmcfr+12BVYh7ra8jlzJ1j8/X0YHC4dBY
+ME5NpOhAi+uyvM0MRDsWUAjjA6+nah2AdQBezaW8aNT+244HMMDEfJ67svKV1O/BYDCiEL0Fgh3A
+SD2u3gbg6h6K62JbTQuuItDjyeRwuxATAbyRQS5nOxFwUSQS+GH3qW0zMDCxs0D+rddT2WX6JhAI
+OFRVHZ9J1mL79WmHfPoxE1YQcDkAsEKTkBwoMpDyIK5B4kVe0tBQ8QMAK/1+v8pAp5dGpHsmE5TY
+7dMZnJz25GcBOglAOUAnh0Khw30+36e9tQm590mgMM8V0/pYYAOgW1sikcgoNownOgbqhGuDweBD
+lZWVvR4Za/E9aUrnnigpsVeBOweJxJjt9vkC6Xn8fr8oLy/fbbCdb3vy6d/OQYP8rbtafgbgewDK
+9LgI19X5L26s5z+AEmvZCHjJ7fPd1102l3otfE/n0i+aAAwhYL/GxpHTgMQhKIZAVfI7sgkWO+3y
+mnpOh7ToWgjlDBA+tqpMk7wHUs+kyJ47SJT0goE0Dxd/03PGYoHv7finIe4PBoNjesmcRXGY1vFv
+wrPpD2AASL6UHkoTuDjbKTAh+Mv0tCGMQbkr2h36DKmlKYaozrOwjiUuzHTJ4sWBI9N/rKqqavd4
+PJ9klCyg/axGgDoHeYw0LyFPSlziJQCSXhFjEgBUVFQcDyD1/9aqKMpuHgkGz+j8t3iIwHWptEI0
+o3v+Pim2PpmFPpbbAIDb7a4nIS5BYp0kAJAqRN/rLovxnjTQaQPG37sPEgHA7/cbPp/vmd1k829P
+zv175syZbQy6Eh2eO5rS2DDyeRBSZbRAKD0NsnN/rgwMnwFYCQBg8gFAOBw+BIwLAYBAva5/zAVL
+PIopKNy+jn+F41FqWwBGlZVl914xAlBi11Ewlmm6bF/FEdZCu69RylWO+CKPp/JpS3XpvUyhadol
+AGwAnwDgjOT1JiLlDxbXZWmbNU07g8Cd60cI4xSiFyORyOlut7seACKadiuDfwoABuM8n8/X4zrf
+Bx98sKR1V0tqagTMvJu3CAAgeAWYrkmmhpeXlx8I4OvedA0EAmPZELekX2NWenoo5mAnbmLwvQRa
+yMBZ4XDgbI+n6sXedOoRMv4MpqsAgIALDV1cGNZC2wG8y+BXFcV4dNas2Z91FyuA/QrRRzrQmV8T
+nfv5jtM0rUwIMZQNfTwAECmvAcYJYFxKoEkA7kSntxEAr3K5XLH0MjVNOwzgU5LJptLS0uVtzc3f
+QsADAMx8BTPfmnFdYye59kmgMDYzpY9FNsiI2+2uD2va6wCfDQAG+Pje8heyT/dAn/YPBAKOtIEV
+mGj5bvl7wJL25Ni/U3i93pXhcCgAxq+TjTstrZ03ut3urzIK5llvnuTULxgUosS9fJKmaSfCMC4F
+QQBoIV1/kBUx20olLf86oYfQRuHYbDBNB+hbq8vvxhcg8R8Ujs2mIOQgce/CllhMzY9RYr0PEfCq
+bvAkj8dTtF7jxYHAsQRejsQuwa3cOYU7gQ39hfvuu3sEADD4fAAnADjc6/V+11uZ8R07hqaniWhL
+5py8OT0lhBiaOV/i4RTWQpzcBd8xjUTAE16v11LvUGlpWQgpDxjn7lX0eCr/F4zrAOxKuzwMwBkE
++i9DVz6OaNoN3eUKYL+C4vV6PwQjdU8oCvO/G0Y8NRBsVRTlbeYOr+MpzExd1icSZXhJGx2eIgKe
+nDlzZtssn28lgK+SF8eFw+HT+1Ct2PqkSX0ssUHPMNenlT+st6zFeE86DaOLzkRGQ7ayVrQn1/6d
+jqLYbgbh8y4XCa/X12/VepKxot7+RlXVJwD+FgAIxg0gXJn4hZawzbZbXOp8KZgbmxZH66BHJwA0
+F0CPYQdypAHEc9Aa+z6F2zPuvpJAB2NB+h+Bw7nIgbFACM5m7U5By2TgByrRYX1ky6Uuy9qsK+K/
+kFjYDoNxFUDnAvzP5M/HtLfb/0/TtElIrScjPN+XB0MdOrRLx2fmHsIy0Oj0lGEYZh4YBgOPNu9q
+/VUveXKy08yZM9tASK3pOTESDP7chF5d8Ph8C9ujsQMI9AuAFiOxXi9lP8HgeZqmHZcuUwD7FaKP
+dGpBxCB0HBJgJLyFiYEi4V8ulysmhEitdR1ZWxucQEitzQNI5y4bWZiZCHRFx++Mx9Lqeazzerfd
+wFmQZZ8ECmyzvvQppA06IOrYoc5Ar+Fs+qlPp9On/VuF6KIzs6jItnCr2pNL/07H5XLtYqYuYfEM
+A1Xp4XIykW+9eZBTv3C5XDGCqE2k6GIkP0wM5lAvYjlj6dRzdxInrkRv5StxJxy2ywFMBXAaACWH
+4nQAK8Cog4gtoTDyigu0DxD3+HxdvoIScRTJ05NAT3KF0CUL2j1eX4mmaaMJCAA8FUApEx4JhUJH
++ny+nqZfcqnLsjYnY44BABRFecvtdjeHw+ELwcYrAI4h4AcAv4zkRxozZdjx1pWZM2e2hbXQOgCH
+AQAxnZoxI4tTO59t2N7Y2NiTZ7Bz17NAjJm2CCHe8HTbDZhJLlc71dc3PjCqonwOgMMMQXMpt2cA
+ACAZg+3R5B9qg8EjdEErkAjFIYiMyQBWp/IXwn4F6CPddMEKUNLTS5hMoOHJX14DgFmzZq2NaNp3
+IIww4uIqEFKDFD3G3GUjUiQS+RESseEAAAbh+bAWStXTCeHnCxcu9M6ZM6elB61y7ZNAYWyWtT4W
+2iAjiQ0tesd9JUDv9pa/APdkX/Rp/6qqqvZwKPRhavpZgKcAWJRN4Va2x2z/zkB9esIwjPqeMlpc
+by7k3C8MoJaAmwHYAACMv/t8vrWRSGS8hfoBKKBHMR16ADspEltMkdhZiMZGgekSABqAlwF8g65d
+NQlvAuNVAIvBNB16bDRFYmfQ4lhEDhL3Hbxe7+aWXbtmojOkTKkgvr03mYGEgWjHv1mfAgAej2cb
+CeUcAKmvRDWZWcs20DQ4LdwC4SeRYLDLgzgRp5BndmbHk718Resen+8ej893j8fj07xe7xPdQ0ZY
+jd/vjxPjVgAg4Aj0MTWXiUgw+PNwOHxM9+uuysqPQejQn1jYdxO21n6Fp+uu5ZORDL2R8hZ28ToS
+runMSmuqqqqaupRlGNl6ycrKnM4+QxgVW5/MSh+LbZBO1NsHNwAABE5JREFUKBQayawvRSL+HgBw
+3DAe6VOwGO9JgQ69GThL07TdHAvMTOFweMpusnm2J6/+nQcDVW++eL3ezV1sLjhYqLoK6lHMBN2P
+74Don5EM+ZCCf4dBaIEdKnQKoqkHcUnhUcOh0PwM1zenh6LoT+bMmdMSDoUWglJft3RZMBj0V1ZW
+fpkhey76W9ZmAj/DoGsBAIxAOBw6SBh43WD9YKS+/JIwZT9YMoD/UYArkoFjiQW9qGmhPwL0CcDj
+KfEATsU228aMQry487LTLK93aSSsXQ8gpykcFuICsPFEWAutJfA/mOkrCAgwnwnGsal8BvCv7rJF
+Yr+sURTlbT1utCIx+EgNQHR7aenKjkydXseyzmtdp51ra2tL9XjskjSZ2yG469pxFqcjGYOQEzt/
+l/Sln8k+CRT4udKbPgWwQaotNhCPB3AuOP3/AIv6Co0D9Ps9mZX9FcX2ez0evQygowCAwFpYC05j
+4AUiamXmgyNhbQonltd0nUbOsz359O98GKh6k+TVL5hoLmB8Rkzx8or9CrYMr98Hij1Bd6EFgCl3
+v6QgKKnApd1Yi4yBQfsHxWa7V4/HbkZiGkBVBW4E0j0pnVlz0N+yNgvV/t96PPYjJDaqOMC4ySB0
+95kbAAQBl4dDoY89Pt/cvsr1+XxbI5HIBTD0vwA4GIlTIVzdC2ZgC0AX+3zeXHZG9kVediIiXhwK
+3WwQns1Tj+8z6PvosGvakZ+EP3s9u3tpi8R+WeNyuWLhcOhfSJxukYTWXHXVVTs7kkKsAHd1MFG3
+QNtGPH4RgMHJ5Ob6xsb/7u6VCoVCKwQhGayazwwEAmOrqqo29KWjiT4J9MNzpSd9CmCDtLZ0OW6W
+CbRwS2NDb4HHO+jnezIr+7tcrl2RSOR8NuJPIHGqFAA6jYDTwEiFJASA3TarWNge0/3bIgai3rz6
+hdfr/QiA32qlujMgccIkErO4XK5d4M71Msz0y0AgMJDB3TPicrl2xHXjVAbPAfA2EjvpYgC+AWgp
+gy4AcedxYYTbw+Hg1GzKdrvdH7Tsaj0ajGspEbh7K4A4gO0A/xOMm4nEBK/Xu7KPogaMWT7fc8hw
+akg2KKp6K4OvBmgZEg/SrUisXd4G0AoQu8vLR03vSX5Ps99uIUa6eQuTsRLTd2oi3i0Pp+30ZeCZ
+TFOXPp9vLTqXRQibomR19nKx9cme9CmQDRhAOwNbwFgFwj1CMY5ye73Xm5keLsZ70u12byyv2G8S
+gy8F6GkAG5E4ZWU7Ae+DEVR04zyr25Nv/86VgapXIpFIJBKJRCKRSCQSiUQikUgkEolEIpFIJBKJ
+RCKRSCQSiUQikUgkEolEIpFIJBKJRCKRSCQSiUQikUgkEolEIpFIJBKJRCKRSCQSiUQikUgkEolE
+IpFIJBKJRCKRSCQSiUQikUgkEolEIpFIJBKJRCKRSCQSiUQikUgkEolEIpFIJBKJRCKRSCQSiUSy
+7/L/7tLt1enPwIwAAAAASUVORK5CYII=
+"
+ height="164"
+ width="650" />
+ </g>
+</svg>
diff --git a/docs/doxygen/other/extra_pages.dox b/docs/doxygen/other/extra_pages.dox
index 617e00d553..88aee72ffe 100644
--- a/docs/doxygen/other/extra_pages.dox
+++ b/docs/doxygen/other/extra_pages.dox
@@ -119,7 +119,7 @@ built or installed.
The -DENABLE_DEFAULT=False can be used to disable all
components. Individual components can then be selectively turned back
-on. For example, just buidling the Volk library can be
+on. For example, just buidling the VOLK library can be
done with this:
\code
@@ -160,27 +160,27 @@ cmake -DCMAKE_CXX_FLAGS:STRING="-mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp -g
-/*! \page volk_guide Instructions for using Volk in GNU Radio
+/*! \page volk_guide Instructions for using VOLK in GNU Radio
\section volk_intro Introduction
-Volk is the Vector-Optimized Library of Kernels. It is a library that
+VOLK is the Vector-Optimized Library of Kernels. It is a library that
contains kernels of hand-written SIMD code for different mathematical
operations. Since each SIMD architecture can be greatly different and
no compiler has yet come along to handle vectorization properly or
-highly efficiently, Volk approaches the problem differently. For each
+highly efficiently, VOLK approaches the problem differently. For each
architecture or platform that a developer wishes to vectorize for, a
-new proto-kernel is added to Volk. At runtime, Volk will select the
-correct proto-kernel. In this way, the users of Volk call a kernel for
+new proto-kernel is added to VOLK. At runtime, VOLK will select the
+correct proto-kernel. In this way, the users of VOLK call a kernel for
performing the operation that is platform/architecture agnostic. This
allows us to write portable SIMD code.
-Volk kernels are always defined with a 'generic' proto-kernel, which
+VOLK kernels are always defined with a 'generic' proto-kernel, which
is written in plain C. With the generic kernel, the kernel becomes
portable to any platform. Kernels are then extended by adding
proto-kernels for new platforms in which they are desired.
-A good example of a Volk kernel with multiple proto-kernels defined is
+A good example of a VOLK kernel with multiple proto-kernels defined is
the volk_32f_s32f_multiply_32f_a. This kernel implements a scalar
multiplication of a vector of floating point numbers (each item in the
vector is multiplied by the same value). This kernel has the following
@@ -193,10 +193,10 @@ proto-kernels that are defined for 'generic,' 'avx,' 'sse,' and 'orc.'
void volk_32f_s32f_multiply_32f_a_orc
\endcode
-These proto-kernels means that on platforms with AVX support, Volk can
+These proto-kernels means that on platforms with AVX support, VOLK can
select this option or the SSE option, depending on which is faster. On
other platforms, the ORC SIMD compiler might provide a solution. If
-all else fails, Volk can fall back on the generic proto-kernel, which
+all else fails, VOLK can fall back on the generic proto-kernel, which
will always work.
Just a note on ORC. ORC is a SIMD compiler library that uses a generic
@@ -210,13 +210,13 @@ step to performance improvements until a specific hand-tuned
proto-kernel can be made for a given platform.
See <a
-href="http://gnuradio.org/redmine/projects/gnuradio/wiki/Volk">Volk on
-gnuradio.org</a> for details on the Volk naming scheme.
+href="http://gnuradio.org/redmine/projects/gnuradio/wiki/Volk">VOLK on
+gnuradio.org</a> for details on the VOLK naming scheme.
\section volk_alignment Setting and Using Memory Alignment Information
-For Volk to work as best as possible, we want to use memory-aligned
+For VOLK to work as best as possible, we want to use memory-aligned
SIMD calls, which means we have to have some way of knowing and
controlling the alignment of the buffers passed to gr_block's work
function. We set the alignment requirement for SIMD aligned memory
@@ -228,7 +228,7 @@ calls with:
set_alignment(std::max(1,alignment_multiple));
\endcode
-The Volk function 'volk_get_alignment' provides the alignment of the
+The VOLK function 'volk_get_alignment' provides the alignment of the
the machine architecture. We then base the alignment on the number of
output items required to maintain the alignment, so we divide the
number of alignment bytes by the number of bytes in an output items
@@ -249,13 +249,16 @@ do. The next section discusses the use of the aligned/unaligned
information in a gr_block's work function.
-\section volk_work Using Alignment Properties in Work()
+\section volk_work Calling VOLK kernels in Work()
The buffers passed to work/general_work in a gr_block are not
guaranteed to be aligned, but they will mostly be aligned whenever
-possible. When not aligned, the 'is_unaligned()' flag will be set. So
-a block can know if its buffers are aligned and make the right
-decisions. This looks like:
+possible. When not aligned, the 'is_unaligned()' flag will be set so
+the scheduler knows to try to realign the buffers. We actually make
+calls to the VOLK dispatcher, which is mainly designed to check the
+buffer alignments and call the correct version of the kernel for
+us. From the user-level view of VOLK, calling the dispatcher allows us
+to ignore the concept of aligned versus unaligned. This looks like:
\code
int
@@ -266,15 +269,9 @@ gr_some_block::work (int noutput_items,
const float *in = (const float *) input_items[0];
float *out = (float *) output_items[0];
- if(is_unaligned()) {
- // do something with unaligned data. This can either be a manual
- // handling of the items or a call to an unaligned Volk function.
- volk_32f_something_32f_u(out, in, noutput_items);
- }
- else {
- // Buffers are aligned; can call the aligned Volk function.
- volk_32f_something_32f_a(out, in, noutput_items);
- }
+ // Call the dispatcher to check alignment and call the _a or _u
+ // version of the kernel.
+ volk_32f_something_32f(out, in, noutput_items);
return noutput_items;
}
@@ -282,7 +279,7 @@ gr_some_block::work (int noutput_items,
-\section volk_tuning Tuning Volk Performance
+\section volk_tuning Tuning VOLK Performance
VOLK comes with a profiler that will build a config file for the best
SIMD architecture for your processor. Run volk_profile that is
diff --git a/docs/doxygen/other/main_page.dox b/docs/doxygen/other/main_page.dox
index f96492c5cc..d47b739057 100644
--- a/docs/doxygen/other/main_page.dox
+++ b/docs/doxygen/other/main_page.dox
@@ -1,6 +1,6 @@
/*! \mainpage
-\image html gnuradio-logo.png
+\image html gnuradio-logo.svg
Welcome to GNU Radio!
diff --git a/gr-blocks/lib/add_ff_impl.cc b/gr-blocks/lib/add_ff_impl.cc
index e12e86c061..ca2fbe659c 100644
--- a/gr-blocks/lib/add_ff_impl.cc
+++ b/gr-blocks/lib/add_ff_impl.cc
@@ -56,14 +56,8 @@ namespace gr {
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);
- }
+ for(size_t i = 1; i < input_items.size(); i++)
+ volk_32f_x2_add_32f(out, out, (const float*)input_items[i], noi);
return noutput_items;
}
diff --git a/gr-blocks/lib/conjugate_cc_impl.cc b/gr-blocks/lib/conjugate_cc_impl.cc
index 14fbbf172c..55ff30aa5d 100644
--- a/gr-blocks/lib/conjugate_cc_impl.cc
+++ b/gr-blocks/lib/conjugate_cc_impl.cc
@@ -54,12 +54,7 @@ namespace gr {
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);
- }
+ volk_32fc_conjugate_32fc(optr, iptr, noutput_items);
return noutput_items;
}
diff --git a/gr-blocks/lib/endian_swap_impl.cc b/gr-blocks/lib/endian_swap_impl.cc
index 3c263e40a3..604e8b9ad8 100644
--- a/gr-blocks/lib/endian_swap_impl.cc
+++ b/gr-blocks/lib/endian_swap_impl.cc
@@ -60,47 +60,24 @@ namespace gr {
char *out = (char*)output_items[0];
int nbytes(output_signature()->sizeof_stream_item(0));
- if(is_unaligned()) {
- switch(nbytes){
- case 1:
- memcpy(out,in,noutput_items);
- break;
- case 2:
- memcpy(out,in,2*noutput_items);
- volk_16u_byteswap_u((uint16_t*)out,noutput_items);
- break;
- case 4:
- memcpy(out,in,4*noutput_items);
- volk_32u_byteswap_u((uint32_t*)out,noutput_items);
- break;
- case 8:
- memcpy(out,in,8*noutput_items);
- volk_64u_byteswap_u((uint64_t*)out,noutput_items);
- break;
- default:
- throw std::runtime_error("itemsize is not valid for endian_swap!");
- }
- }
- else {
- switch(nbytes) {
- case 1:
- memcpy(out,in,noutput_items);
- break;
- case 2:
- memcpy(out,in,2*noutput_items);
- volk_16u_byteswap_a((uint16_t*)out,noutput_items);
- break;
- case 4:
- memcpy(out,in,4*noutput_items);
- volk_32u_byteswap_a((uint32_t*)out,noutput_items);
- break;
- case 8:
- memcpy(out,in,8*noutput_items);
- volk_64u_byteswap_a((uint64_t*)out,noutput_items);
- break;
- default:
- throw std::runtime_error("itemsize is not valid for endian_swap!");
- }
+ switch(nbytes){
+ case 1:
+ memcpy(out,in,noutput_items);
+ break;
+ case 2:
+ memcpy(out,in,2*noutput_items);
+ volk_16u_byteswap((uint16_t*)out,noutput_items);
+ break;
+ case 4:
+ memcpy(out,in,4*noutput_items);
+ volk_32u_byteswap((uint32_t*)out,noutput_items);
+ break;
+ case 8:
+ memcpy(out,in,8*noutput_items);
+ volk_64u_byteswap((uint64_t*)out,noutput_items);
+ break;
+ default:
+ throw std::runtime_error("itemsize is not valid for endian_swap!");
}
return noutput_items;
diff --git a/gr-blocks/lib/multiply_cc_impl.cc b/gr-blocks/lib/multiply_cc_impl.cc
index b54296c112..2e1ce93b37 100644
--- a/gr-blocks/lib/multiply_cc_impl.cc
+++ b/gr-blocks/lib/multiply_cc_impl.cc
@@ -56,14 +56,9 @@ namespace gr {
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);
- }
+ for(size_t i = 1; i < input_items.size(); i++)
+ volk_32fc_x2_multiply_32fc(out, out, (gr_complex*)input_items[i], noi);
+
return noutput_items;
}
diff --git a/gr-blocks/lib/multiply_conjugate_cc_impl.cc b/gr-blocks/lib/multiply_conjugate_cc_impl.cc
index 671e1160f6..7f9652152b 100644
--- a/gr-blocks/lib/multiply_conjugate_cc_impl.cc
+++ b/gr-blocks/lib/multiply_conjugate_cc_impl.cc
@@ -57,12 +57,7 @@ namespace gr {
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);
- }
+ volk_32fc_x2_multiply_conjugate_32fc(out, in0, in1, noi);
return noutput_items;
}
diff --git a/gr-blocks/lib/multiply_const_cc_impl.cc b/gr-blocks/lib/multiply_const_cc_impl.cc
index d0393907b0..f6b8dc3d63 100644
--- a/gr-blocks/lib/multiply_const_cc_impl.cc
+++ b/gr-blocks/lib/multiply_const_cc_impl.cc
@@ -58,12 +58,7 @@ namespace gr {
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);
- }
+ volk_32fc_s32fc_multiply_32fc(out, in, d_k, noi);
return noutput_items;
}
diff --git a/gr-blocks/lib/multiply_const_ff_impl.cc b/gr-blocks/lib/multiply_const_ff_impl.cc
index 67205c06c0..366c06181f 100644
--- a/gr-blocks/lib/multiply_const_ff_impl.cc
+++ b/gr-blocks/lib/multiply_const_ff_impl.cc
@@ -58,12 +58,7 @@ namespace gr {
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);
- }
+ volk_32f_s32f_multiply_32f(out, in, d_k, noi);
return noutput_items;
}
diff --git a/gr-blocks/lib/multiply_ff_impl.cc b/gr-blocks/lib/multiply_ff_impl.cc
index 912c1bb926..22100497c5 100644
--- a/gr-blocks/lib/multiply_ff_impl.cc
+++ b/gr-blocks/lib/multiply_ff_impl.cc
@@ -56,14 +56,9 @@ namespace gr {
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);
- }
+ for(size_t i = 1; i < input_items.size(); i++)
+ volk_32f_x2_multiply_32f(out, out, (float*)input_items[i], noi);
+
return noutput_items;
}
diff --git a/gr-fft/include/gnuradio/fft/window.h b/gr-fft/include/gnuradio/fft/window.h
index 4a7fb44ff9..92f62c64cb 100644
--- a/gr-fft/include/gnuradio/fft/window.h
+++ b/gr-fft/include/gnuradio/fft/window.h
@@ -35,19 +35,41 @@ namespace gr {
public:
enum win_type {
- WIN_NONE = -1, //!< don't use a window
- WIN_HAMMING = 0, //!< Hamming window; max attenuation 53 dB
- WIN_HANN = 1, //!< Hann window; max attenuation 44 dB
- WIN_BLACKMAN = 2, //!< Blackman window; max attenuation 74 dB
- WIN_RECTANGULAR = 3, //!< Basic rectangular window
- WIN_KAISER = 4, //!< Kaiser window; max attenuation a function of beta, google it
- WIN_BLACKMAN_hARRIS = 5, //!< Blackman-harris window
- WIN_BLACKMAN_HARRIS = 5, //!< alias to WIN_BLACKMAN_hARRIS for capitalization consistency
- WIN_BARTLETT = 6, //!< Barlett (triangular) window
- WIN_FLATTOP = 7, //!< flat top window; useful in FFTs
+ WIN_HAMMING = 0, //!< Hamming window; max attenuation 53 dB
+ WIN_HANN = 1, //!< Hann window; max attenuation 44 dB
+ WIN_BLACKMAN = 2, //!< Blackman window; max attenuation 74 dB
+ WIN_RECTANGULAR = 3, //!< Basic rectangular window; max attenuation 21 dB
+ WIN_KAISER = 4, //!< Kaiser window; max attenuation see window::max_attenuation
+ WIN_BLACKMAN_hARRIS = 5, //!< Blackman-harris window; max attenuation 92 dB
+ WIN_BLACKMAN_HARRIS = 5, //!< alias to WIN_BLACKMAN_hARRIS for capitalization consistency
+ WIN_BARTLETT = 6, //!< Barlett (triangular) window; max attenuation 26 dB
+ WIN_FLATTOP = 7, //!< flat top window; useful in FFTs; max attenuation 93 dB
};
/*!
+ * \brief Given a window::win_type, this tells you the maximum
+ * attenuation you can expect.
+ *
+ * \details
+ * For most windows, this is a set value. For the Kaiser window,
+ * the attenuation is based on the value of beta. The actual
+ * relationship is a piece-wise exponential relationship to
+ * calculate beta from the desired attenuation and can be found
+ * on page 542 of Oppenheim and Schafer (Discrete-Time Signal
+ * Processing, 3rd edition). To simplify this function to solve
+ * for A given beta, we use a linear form that is exact for
+ * attenuation >= 50 dB.
+ *
+ * For an attenuation of 50 dB, beta = 4.55.
+ *
+ * For an attenuation of 70 dB, beta = 6.76.
+ *
+ * \param type The window::win_type enumeration of the window type.
+ * \param beta Beta value only used for the Kaiser window.
+ */
+ static double max_attenuation(win_type type, double beta=6.76);
+
+ /*!
* \brief Helper function to build cosine-based windows. 3-coefficient version.
*/
static std::vector<float> coswindow(int ntaps, float c0, float c1, float c2);
diff --git a/gr-fft/lib/window.cc b/gr-fft/lib/window.cc
index 1610b46f5d..015e2d9943 100644
--- a/gr-fft/lib/window.cc
+++ b/gr-fft/lib/window.cc
@@ -74,7 +74,24 @@ namespace gr {
return 1.0/(ntaps >> 1);
}
- std::vector<float>
+ double
+ window::max_attenuation(win_type type, double beta)
+ {
+ switch(type) {
+ case(WIN_HAMMING): return 53; break;
+ case(WIN_HANN): return 44; break;
+ case(WIN_BLACKMAN): return 74; break;
+ case(WIN_RECTANGULAR): return 21; break;
+ case(WIN_KAISER): return (beta/0.1102 + 8.7); break;
+ case(WIN_BLACKMAN_hARRIS): return 92; break;
+ case(WIN_BARTLETT): return 27; break;
+ case(WIN_FLATTOP): return 93; break;
+ default:
+ throw std::out_of_range("window::max_attenuation: unknown window type provided.");
+ }
+ }
+
+ std::vector<float>
window::coswindow(int ntaps, float c0, float c1, float c2)
{
std::vector<float> taps(ntaps);
diff --git a/gr-filter/doc/filter.dox b/gr-filter/doc/filter.dox
index ad0cfcb6c5..a9b329836c 100644
--- a/gr-filter/doc/filter.dox
+++ b/gr-filter/doc/filter.dox
@@ -54,11 +54,6 @@ impulse response (IIR) filtering.
an IIR filter with a single pole (also known as a moving average
filter).
-\li Adaptive FIR filters (see adaptive_fir.h): FIR filters that define
-an \b error and \b update_tap virtual interface to create filters that
-update the taps based on some criteria. \sa
-gr::digital::lms_dd_equalizer_cc, gr::digital::cma_equalizer_cc
-
\li PFB arbitrary resampler (see pfb_arb_resampler.h): performs
arbitrary resampling (i.e., using any real number) using the polyphase
filterbank method. \sa \ref pfb_arb_resampl
@@ -94,11 +89,6 @@ blocks.
<li>gr::filter::single_pole_iir_filter_cc</li>
<li>gr::filter::single_pole_iir_filter_ff</li>
</ul>
-<li>Adaptive FIR Filters</li>
- <ul>
- <li>gr::filter::adaptive_fir_ccc</li>
- <li>gr::filter::adaptive_fir_ccf</li>
- </ul>
<li>Polyphase Filterbanks</li>
<ul>
<li>gr::filter::pfb_arb_resampler_ccf</li>
diff --git a/gr-filter/grc/filter_pfb_decimator.xml b/gr-filter/grc/filter_pfb_decimator.xml
index 8ecf9b2d95..d57119636c 100644
--- a/gr-filter/grc/filter_pfb_decimator.xml
+++ b/gr-filter/grc/filter_pfb_decimator.xml
@@ -15,7 +15,8 @@
$channel,
$atten)
</make>
- <callback>set_taps($taps)</callback>
+ <callback>set_taps($taps)</callback>
+ <callback>set_channel(int($channel))</callback>
<param>
<name>Decimation</name>
<key>decim</key>
diff --git a/gr-filter/include/gnuradio/filter/CMakeLists.txt b/gr-filter/include/gnuradio/filter/CMakeLists.txt
index 7871c8c003..3135688eb4 100644
--- a/gr-filter/include/gnuradio/filter/CMakeLists.txt
+++ b/gr-filter/include/gnuradio/filter/CMakeLists.txt
@@ -79,7 +79,6 @@ add_custom_target(filter_generated_includes DEPENDS
install(FILES
${generated_includes}
api.h
- adaptive_fir.h
firdes.h
fir_filter.h
fir_filter_with_buffer.h
@@ -91,8 +90,6 @@ install(FILES
pm_remez.h
polyphase_filterbank.h
single_pole_iir.h
- adaptive_fir_ccc.h
- adaptive_fir_ccf.h
dc_blocker_cc.h
dc_blocker_ff.h
filter_delay_fc.h
diff --git a/gr-filter/include/gnuradio/filter/adaptive_fir.h b/gr-filter/include/gnuradio/filter/adaptive_fir.h
deleted file mode 100644
index be2060537f..0000000000
--- a/gr-filter/include/gnuradio/filter/adaptive_fir.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/* -*- 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_FILTER_ADAPTIVE_FIR_H
-#define INCLUDED_FILTER_ADAPTIVE_FIR_H
-
-#include <gnuradio/filter/api.h>
-#include <gnuradio/filter/fir_filter.h>
-
-namespace gr {
- namespace filter {
- namespace kernel {
-
- /*!
- * \brief Adaptive FIR filter kernel with gr_complex input,
- * gr_complex output and gr_complex taps
- *
- * This class implements an adaptive FIR filter. Any class
- * actually wanting to use adaptive FIRs will contain an object of
- * this class.
- */
- class FILTER_API adaptive_fir_ccc : public fir_filter_ccc
- {
- public:
- adaptive_fir_ccc(int decimation,
- const std::vector<gr_complex> &taps);
- ~adaptive_fir_ccc();
-
- protected:
- // Override to calculate error signal per output
- virtual gr_complex error(const gr_complex &out) = 0;
-
- // Override to calculate new weight from old, corresponding input
- virtual void update_tap(gr_complex &tap, const gr_complex &in) = 0;
-
- gr_complex d_error;
- };
-
-
- /*!
- * \brief Adaptive FIR filter kernel with gr_complex input,
- * gr_complex output and float taps
- *
- * This class implements an adaptive FIR filter. Any class
- * actually wanting to use adaptive FIRs will contain an object of
- * this class.
- */
- class FILTER_API adaptive_fir_ccf : public fir_filter_ccf
- {
- public:
- adaptive_fir_ccf(int decimation,
- const std::vector<float> &taps);
- ~adaptive_fir_ccf();
-
- protected:
- // Override to calculate error signal per output
- virtual float error(const gr_complex &out) = 0;
-
- // Override to calculate new weight from old, corresponding input
- virtual void update_tap(float &tap, const gr_complex &in) = 0;
-
- float d_error;
- };
-
- } /* namespace kernel */
- } /* namespace filter */
-} /* namespace gr */
-
-#endif /* INCLUDED_FILTER_ADAPTIVE_FIR_H */
diff --git a/gr-filter/include/gnuradio/filter/adaptive_fir_ccc.h b/gr-filter/include/gnuradio/filter/adaptive_fir_ccc.h
deleted file mode 100644
index 13e05a477b..0000000000
--- a/gr-filter/include/gnuradio/filter/adaptive_fir_ccc.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/* -*- 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_FILTER_ADAPTIVE_FIR_CCC_H
-#define INCLUDED_FILTER_ADAPTIVE_FIR_CCC_H
-
-#include <gnuradio/filter/api.h>
-#include <gnuradio/sync_decimator.h>
-
-namespace gr {
- namespace filter {
-
- /*!
- * \brief Adaptive FIR filter with gr_complex input, gr_complex output and gr_complex taps
- * \ingroup filter_blk
- *
- * \details
- * This is a base class to implement an adaptive FIR
- * filter. Generally, another block will inherit from this one to
- * build a new type of adaptive filter such as an equalizer.
- *
- * This class implements two functions that are designed to be
- * overloaded by the child class: error(gr_complex out) and
- * update_tap(gr_complex tap, gr_complex in).
- *
- * The error() function calculates the error value that will be
- * used to adjust the taps. The update_tap function then uses the
- * error and the input signal value to update a particular
- * tap. Typically, the error is calculated for a given output and
- * then this is used in a loop to update all of the filter taps in
- * a loop:
- *
- * \code
- * d_error = error(sum);
- * for(k = 0; k < l; k++) {
- * update_tap(d_taps[ntaps-k-1], in[i+k]);
- * }
- * \endcode
- *
- * See digital::cma_equalizer_cc and digital::lms_dd_equalizer_cc
- * for example usage.
- */
- class FILTER_API adaptive_fir_ccc : virtual public sync_decimator
- {
- protected:
-
- public:
- // gr::filter::adaptive_fir_ccc::sptr
- typedef boost::shared_ptr<adaptive_fir_ccc> sptr;
-
- /*!
- * \brief Adaptive FIR filter with gr_complex input, gr_complex output and gr_complex taps
- *
- * \param name Provides a name to identify this type of algorithm
- * \param decimation (interger) decimation rate of the filter
- * \param taps (complex) filter taps
- */
- static sptr make(const char *name, int decimation,
- const std::vector<gr_complex> &taps);
-
- virtual void set_taps(const std::vector<gr_complex> &taps) = 0;
- virtual std::vector<gr_complex> taps() const = 0;
- };
-
- } /* namespace filter */
-} /* namespace gr */
-
-#endif /* INCLUDED_FILTER_ADAPTIVE_FIR_CCC_H */
diff --git a/gr-filter/include/gnuradio/filter/adaptive_fir_ccf.h b/gr-filter/include/gnuradio/filter/adaptive_fir_ccf.h
deleted file mode 100644
index 81d11d6fd6..0000000000
--- a/gr-filter/include/gnuradio/filter/adaptive_fir_ccf.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/* -*- 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_FILTER_ADAPTIVE_FIR_CCF_H
-#define INCLUDED_FILTER_ADAPTIVE_FIR_CCF_H
-
-#include <gnuradio/filter/api.h>
-#include <gnuradio/sync_decimator.h>
-
-namespace gr {
- namespace filter {
-
- /*!
- * \brief Adaptive FIR filter with gr_complex input, gr_complex output and float taps
- * \ingroup filter_blk
- *
- * \details
- * This is a base class to implement an adaptive FIR
- * filter. Generally, another block will inherit from this one to
- * build a new type of adaptive filter such as an equalizer.
- *
- * This class implements two functions that are designed to be
- * overloaded by the child class: error(gr_complex out) and
- * update_tap(float tap, gr_complex in).
- *
- * The error() function calculates the error value that will be
- * used to adjust the taps. The update_tap function then uses the
- * error and the input signal value to update a particular
- * tap. Typically, the error is calculated for a given output and
- * then this is used in a loop to update all of the filter taps in
- * a loop:
- *
- * \code
- * d_error = error(sum);
- * for(k = 0; k < l; k++) {
- * update_tap(d_taps[ntaps-k-1], in[i+k]);
- * }
- * \endcode
- */
- class FILTER_API adaptive_fir_ccf : virtual public sync_decimator
- {
- public:
- // gr::filter::adaptive_fir_ccf::sptr
- typedef boost::shared_ptr<adaptive_fir_ccf> sptr;
-
- /*!
- * \brief Adaptive FIR filter with gr_complex input, gr_complex output and float taps
- *
- * \param name Provides a name to identify this type of algorithm
- * \param decimation (interger) decimation rate of the filter
- * \param taps (real) filter taps
- */
- static sptr make(const char *name, int decimation,
- const std::vector<float> &taps);
-
- virtual void set_taps(const std::vector<float> &taps) = 0;
- virtual std::vector<float> taps() = 0;
- };
-
- } /* namespace filter */
-} /* namespace gr */
-
-#endif /* INCLUDED_FILTER_ADAPTIVE_FIR_CCF_H */
diff --git a/gr-filter/include/gnuradio/filter/pfb_decimator_ccf.h b/gr-filter/include/gnuradio/filter/pfb_decimator_ccf.h
index 822206889f..da4eb2bd34 100644
--- a/gr-filter/include/gnuradio/filter/pfb_decimator_ccf.h
+++ b/gr-filter/include/gnuradio/filter/pfb_decimator_ccf.h
@@ -120,7 +120,7 @@ namespace gr {
*/
virtual void print_taps() = 0;
- //virtual void set_channel(unsigned int channel) = 0;
+ virtual void set_channel(const unsigned int channel) = 0;
};
} /* namespace filter */
diff --git a/gr-filter/lib/CMakeLists.txt b/gr-filter/lib/CMakeLists.txt
index db9b0cfcb9..58000bbfcd 100644
--- a/gr-filter/lib/CMakeLists.txt
+++ b/gr-filter/lib/CMakeLists.txt
@@ -115,7 +115,6 @@ endif(ENABLE_GR_CTRLPORT)
# Setup library
########################################################################
list(APPEND filter_sources
- adaptive_fir.cc
fir_filter.cc
fir_filter_with_buffer.cc
fft_filter.cc
@@ -125,8 +124,6 @@ list(APPEND filter_sources
pm_remez.cc
polyphase_filterbank.cc
${generated_sources}
- adaptive_fir_ccc_impl.cc
- adaptive_fir_ccf_impl.cc
dc_blocker_cc_impl.cc
dc_blocker_ff_impl.cc
filter_delay_fc_impl.cc
diff --git a/gr-filter/lib/adaptive_fir.cc b/gr-filter/lib/adaptive_fir.cc
deleted file mode 100644
index a7ee8228a0..0000000000
--- a/gr-filter/lib/adaptive_fir.cc
+++ /dev/null
@@ -1,60 +0,0 @@
-/* -*- 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
-
-#include <gnuradio/filter/adaptive_fir.h>
-#include <gnuradio/io_signature.h>
-
-namespace gr {
- namespace filter {
- namespace kernel {
-
- adaptive_fir_ccc::adaptive_fir_ccc(int decimation,
- const std::vector<gr_complex> &taps)
- : fir_filter_ccc(decimation, taps)
- {
- }
-
- adaptive_fir_ccc::~adaptive_fir_ccc()
- {
- }
-
-
- /**************************************************************/
-
-
- adaptive_fir_ccf::adaptive_fir_ccf(int decimation,
- const std::vector<float> &taps)
- : fir_filter_ccf(decimation, taps)
- {
- }
-
- adaptive_fir_ccf::~adaptive_fir_ccf()
- {
- }
-
- } /* namespace kernel */
- } /* namespace filter */
-} /* namespace gr */
diff --git a/gr-filter/lib/adaptive_fir_ccc_impl.cc b/gr-filter/lib/adaptive_fir_ccc_impl.cc
deleted file mode 100644
index 93c7dea443..0000000000
--- a/gr-filter/lib/adaptive_fir_ccc_impl.cc
+++ /dev/null
@@ -1,106 +0,0 @@
-/* -*- 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
-
-#include "adaptive_fir_ccc_impl.h"
-#include <gnuradio/io_signature.h>
-
-namespace gr {
- namespace filter {
-
- adaptive_fir_ccc::sptr adaptive_fir_ccc::make(const char *name, int decimation,
- const std::vector<gr_complex> &taps)
- {
- return gnuradio::get_initial_sptr(new adaptive_fir_ccc_impl
- (name, decimation, taps));
- }
-
- adaptive_fir_ccc_impl::adaptive_fir_ccc_impl(const char *name, int decimation,
- const std::vector<gr_complex> &taps)
- : sync_decimator(name,
- io_signature::make(1, 1, sizeof(gr_complex)),
- io_signature::make(1, 1, sizeof(gr_complex)),
- decimation),
- kernel::adaptive_fir_ccc(decimation, taps),
- d_updated(false)
- {
- set_history(d_ntaps);
- }
-
- void
- adaptive_fir_ccc_impl::set_taps(const std::vector<gr_complex> &taps)
- {
- d_new_taps = taps;
- d_updated = true;
- }
-
- std::vector<gr_complex>
- adaptive_fir_ccc_impl::taps() const
- {
- return kernel::fir_filter_ccc::taps();
- }
-
- gr_complex
- adaptive_fir_ccc_impl::error(const gr_complex &out)
- {
- return 0;
- }
-
- void
- adaptive_fir_ccc_impl::update_tap(gr_complex &tap, const gr_complex &in)
- {
- tap = tap;
- }
-
- int
- adaptive_fir_ccc_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];
- gr_complex *out = (gr_complex *)output_items[0];
-
- if (d_updated) {
- kernel::fir_filter_ccc::set_taps(d_new_taps);
- set_history(d_ntaps);
- d_updated = false;
- return 0; // history requirements may have changed.
- }
-
- // Call base class filtering function that uses
- // overloaded error and update_tap functions.
- if (decimation() == 1) {
- filterN(out, in, noutput_items);
- }
- else {
- filterNdec(out, in, noutput_items,
- decimation());
- }
-
- return noutput_items;
- }
-
- } /* namespace filter */
-} /* namespace gr */
diff --git a/gr-filter/lib/adaptive_fir_ccc_impl.h b/gr-filter/lib/adaptive_fir_ccc_impl.h
deleted file mode 100644
index 66b8fe5a49..0000000000
--- a/gr-filter/lib/adaptive_fir_ccc_impl.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/* -*- 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_FILTER_ADAPTIVE_FIR_CCC_IMPL_H
-#define INCLUDED_FILTER_ADAPTIVE_FIR_CCC_IMPL_H
-
-#include <gnuradio/filter/adaptive_fir_ccc.h>
-#include <gnuradio/filter/adaptive_fir.h>
-#include <gnuradio/types.h>
-
-namespace gr {
- namespace filter {
-
- class FILTER_API adaptive_fir_ccc_impl :
- public adaptive_fir_ccc, public kernel::adaptive_fir_ccc
- {
- private:
- std::vector<gr_complex> d_new_taps;
- bool d_updated;
-
- protected:
- // Override to calculate error signal per output
- gr_complex error(const gr_complex &out);
-
- // Override to calculate new weight from old, corresponding input
- void update_tap(gr_complex &tap, const gr_complex &in);
-
- public:
- void set_taps(const std::vector<gr_complex> &taps);
- std::vector<gr_complex> taps() const;
-
- adaptive_fir_ccc_impl(const char *name, int decimation,
- const std::vector<gr_complex> &taps);
-
- int work(int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items);
- };
-
- } /* namespace filter */
-} /* namespace gr */
-
-#endif /* INCLUDED_FILTER_ADAPTIVE_FIR_CCC_IMPL_H */
diff --git a/gr-filter/lib/adaptive_fir_ccf_impl.cc b/gr-filter/lib/adaptive_fir_ccf_impl.cc
deleted file mode 100644
index 16d59f36f3..0000000000
--- a/gr-filter/lib/adaptive_fir_ccf_impl.cc
+++ /dev/null
@@ -1,106 +0,0 @@
-/* -*- 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
-
-#include "adaptive_fir_ccf_impl.h"
-#include <gnuradio/io_signature.h>
-
-namespace gr {
- namespace filter {
-
- adaptive_fir_ccf::sptr adaptive_fir_ccf::make(const char *name, int decimation,
- const std::vector<float> &taps)
- {
- return gnuradio::get_initial_sptr(new adaptive_fir_ccf_impl
- (name, decimation, taps));
- }
-
- adaptive_fir_ccf_impl::adaptive_fir_ccf_impl(const char *name, int decimation,
- const std::vector<float> &taps)
- : sync_decimator(name,
- io_signature::make(1, 1, sizeof(gr_complex)),
- io_signature::make(1, 1, sizeof(gr_complex)),
- decimation),
- kernel::adaptive_fir_ccf(decimation, taps),
- d_updated(false)
- {
- set_history(d_ntaps);
- }
-
- void
- adaptive_fir_ccf_impl::set_taps(const std::vector<float> &taps)
- {
- d_new_taps = taps;
- d_updated = true;
- }
-
- std::vector<float>
- adaptive_fir_ccf_impl::taps()
- {
- return kernel::fir_filter_ccf::taps();
- }
-
- float
- adaptive_fir_ccf_impl::error(const gr_complex &out)
- {
- return 0;
- }
-
- void
- adaptive_fir_ccf_impl::update_tap(float &tap, const gr_complex &in)
- {
- tap = tap;
- }
-
- int
- adaptive_fir_ccf_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];
- gr_complex *out = (gr_complex *)output_items[0];
-
- if (d_updated) {
- kernel::fir_filter_ccf::set_taps(d_new_taps);
- set_history(d_ntaps);
- d_updated = false;
- return 0; // history requirements may have changed.
- }
-
- // Call base class filtering function that uses
- // overloaded error and update_tap functions.
- if (decimation() == 1) {
- filterN(out, in, noutput_items);
- }
- else {
- filterNdec(out, in, noutput_items,
- decimation());
- }
-
- return noutput_items;
- }
-
- } /* namespace filter */
-} /* namespace gr */
diff --git a/gr-filter/lib/adaptive_fir_ccf_impl.h b/gr-filter/lib/adaptive_fir_ccf_impl.h
deleted file mode 100644
index 188587ee56..0000000000
--- a/gr-filter/lib/adaptive_fir_ccf_impl.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/* -*- 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_FILTER_ADAPTIVE_FIR_CCF_IMPL_H
-#define INCLUDED_FILTER_ADAPTIVE_FIR_CCF_IMPL_H
-
-#include <gnuradio/filter/adaptive_fir_ccf.h>
-#include <gnuradio/filter/adaptive_fir.h>
-#include <gnuradio/types.h>
-
-namespace gr {
- namespace filter {
-
- class FILTER_API adaptive_fir_ccf_impl :
- public adaptive_fir_ccf, public kernel::adaptive_fir_ccf
- {
- private:
- std::vector<float> d_new_taps;
- bool d_updated;
-
- protected:
- // Override to calculate error signal per output
- float error(const gr_complex &out);
-
- // Override to calculate new weight from old, corresponding input
- void update_tap(float &tap, const gr_complex &in);
-
- public:
- void set_taps(const std::vector<float> &taps);
- std::vector<float> taps();
-
- adaptive_fir_ccf_impl(const char *name, int decimation,
- const std::vector<float> &taps);
-
- int work(int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items);
- };
-
- } /* namespace filter */
-} /* namespace gr */
-
-#endif /* INCLUDED_FILTER_ADAPTIVE_FIR_CCF_IMPL_H */
diff --git a/gr-filter/lib/firdes.cc b/gr-filter/lib/firdes.cc
index a52a2ddf63..cb6bffd18a 100644
--- a/gr-filter/lib/firdes.cc
+++ b/gr-filter/lib/firdes.cc
@@ -658,21 +658,6 @@ namespace gr {
// === Utilities ===
//
- // delta_f / width_factor gives number of taps required.
- const int MAX_WIDTH_FACTOR = 8;
- static const float width_factor[8] = { // indexed by win_type
- 3.3, // WIN_HAMMING
- 3.1, // WIN_HANN
- 5.5, // WIN_BLACKMAN
- 2.0, // WIN_RECTANGULAR
- //5.0 // WIN_KAISER (guesstimate compromise)
- //2.0 // WIN_KAISER (guesstimate compromise)
- 10.0, // WIN_KAISER
- 6.0, // WIN_BLACKMAN_HARRIS (est.)
- 3.0, // WIN_BARTLETT (est.)
- 5.5, // WIN_FLATTOP (est.)
- };
-
int
firdes::compute_ntaps_windes(double sampling_freq,
double transition_width, // this is frequency, not relative frequency
@@ -692,14 +677,8 @@ namespace gr {
win_type window_type,
double beta)
{
- // normalized transition width
- double delta_f = transition_width / sampling_freq;
-
- // compute number of taps required for given transition width
- if(window_type >= MAX_WIDTH_FACTOR)
- throw std::runtime_error("firdes::compute_ntaps: window_type out of range.");
-
- int ntaps = (int)(width_factor[window_type] / delta_f + 0.5);
+ double a = fft::window::max_attenuation(static_cast<fft::window::win_type>(window_type), beta);
+ int ntaps = (int)(a*sampling_freq/(22.0*transition_width));
if((ntaps & 1) == 0) // if even...
ntaps++; // ...make odd
diff --git a/gr-filter/lib/pfb_decimator_ccf_impl.cc b/gr-filter/lib/pfb_decimator_ccf_impl.cc
index a9e5138d18..feb36a5999 100644
--- a/gr-filter/lib/pfb_decimator_ccf_impl.cc
+++ b/gr-filter/lib/pfb_decimator_ccf_impl.cc
@@ -82,6 +82,13 @@ namespace gr {
return polyphase_filterbank::taps();
}
+ void
+ pfb_decimator_ccf_impl::set_channel(const unsigned int chan)
+ {
+ gr::thread::scoped_lock guard(d_mutex);
+ d_chan = chan;
+ }
+
#define ROTATEFFT
int
diff --git a/gr-filter/lib/pfb_decimator_ccf_impl.h b/gr-filter/lib/pfb_decimator_ccf_impl.h
index eeebc2c3a7..2df8a506f0 100644
--- a/gr-filter/lib/pfb_decimator_ccf_impl.h
+++ b/gr-filter/lib/pfb_decimator_ccf_impl.h
@@ -52,7 +52,7 @@ namespace gr {
void set_taps(const std::vector<float> &taps);
void print_taps();
std::vector<std::vector<float> > taps() const;
- //void set_channel(unsigned int channel);
+ void set_channel(const unsigned int channel);
int work(int noutput_items,
gr_vector_const_void_star &input_items,
diff --git a/gr-filter/lib/qa_firdes.cc b/gr-filter/lib/qa_firdes.cc
index dfc5e00f35..ef61dffae7 100644
--- a/gr-filter/lib/qa_firdes.cc
+++ b/gr-filter/lib/qa_firdes.cc
@@ -36,14 +36,15 @@ namespace gr {
using std::vector;
-#if 0
+#if 1
static void
print_taps(std::ostream &s, vector<float> &v)
{
-
+ s << std::setprecision(9);
for(unsigned int i = 0; i < v.size(); i++) {
- printf("tap[%2d] = %16.7e\n", i, v[i]);
+ s << v[i] << ", ";
}
+ s << std::endl;
}
#endif
@@ -57,430 +58,94 @@ namespace gr {
CPPUNIT_ASSERT_DOUBLES_EQUAL(v[i], v[n - i - 1], 1e-9);
}
- const static float t1_exp[53] = {
- -9.0525491e-04,
- 2.0713841e-04,
- 1.2388536e-03,
- 2.9683491e-04,
- -1.7744775e-03,
- -1.3599906e-03,
- 2.2031884e-03,
- 3.2744040e-03,
- -1.8868084e-03,
- -5.9935520e-03,
- 6.4301129e-18,
- 8.9516686e-03,
- 4.2178580e-03,
- -1.0998557e-02,
- -1.1173409e-02,
- 1.0455756e-02,
- 2.0686293e-02,
- -5.2032238e-03,
- -3.1896964e-02,
- -7.4998410e-03,
- 4.3362070e-02,
- 3.2502845e-02,
- -5.3328082e-02,
- -8.5621715e-02,
- 6.0117975e-02,
- 3.1128189e-01,
- 4.3769023e-01,
- 3.1128189e-01,
- 6.0117975e-02,
- -8.5621715e-02,
- -5.3328082e-02,
- 3.2502845e-02,
- 4.3362070e-02,
- -7.4998410e-03,
- -3.1896964e-02,
- -5.2032238e-03,
- 2.0686293e-02,
- 1.0455756e-02,
- -1.1173409e-02,
- -1.0998557e-02,
- 4.2178580e-03,
- 8.9516686e-03,
- 6.4301129e-18,
- -5.9935520e-03,
- -1.8868084e-03,
- 3.2744040e-03,
- 2.2031884e-03,
- -1.3599906e-03,
- -1.7744775e-03,
- 2.9683491e-04,
- 1.2388536e-03,
- 2.0713841e-04,
- -9.0525491e-04
+ const static float t1_exp[39] = {
+ 0.00111410965, -0.000583702058, -0.00192639488, 2.30933896e-18, 0.00368289859,
+ 0.00198723329, -0.0058701504, -0.00666110823, 0.0068643163, 0.0147596458,
+ -0.00398709066, -0.0259727165, -0.0064281947, 0.0387893915, 0.0301109217,
+ -0.0507995859, -0.0833103433, 0.0593735874, 0.310160041, 0.437394291,
+ 0.310160041, 0.0593735874, -0.0833103433, -0.0507995859, 0.0301109217,
+ 0.0387893915, -0.0064281947, -0.0259727165, -0.00398709066, 0.0147596458,
+ 0.0068643163, -0.00666110823, -0.0058701504, 0.00198723329, 0.00368289859,
+ 2.30933896e-18, -0.00192639488, -0.000583702058, 0.00111410965
};
- const static float t2_exp[53] = {
- 9.0380036e-04,
- -2.0680559e-04,
- -1.2368630e-03,
- -2.9635796e-04,
- 1.7716263e-03,
- 1.3578053e-03,
- -2.1996482e-03,
- -3.2691427e-03,
- 1.8837767e-03,
- 5.9839217e-03,
- -6.4197810e-18,
- -8.9372853e-03,
- -4.2110807e-03,
- 1.0980885e-02,
- 1.1155456e-02,
- -1.0438956e-02,
- -2.0653054e-02,
- 5.1948633e-03,
- 3.1845711e-02,
- 7.4877902e-03,
- -4.3292396e-02,
- -3.2450620e-02,
- 5.3242393e-02,
- 8.5484132e-02,
- -6.0021374e-02,
- -3.1078172e-01,
- 5.6184036e-01,
- -3.1078172e-01,
- -6.0021374e-02,
- 8.5484132e-02,
- 5.3242393e-02,
- -3.2450620e-02,
- -4.3292396e-02,
- 7.4877902e-03,
- 3.1845711e-02,
- 5.1948633e-03,
- -2.0653054e-02,
- -1.0438956e-02,
- 1.1155456e-02,
- 1.0980885e-02,
- -4.2110807e-03,
- -8.9372853e-03,
- -6.4197810e-18,
- 5.9839217e-03,
- 1.8837767e-03,
- -3.2691427e-03,
- -2.1996482e-03,
- 1.3578053e-03,
- 1.7716263e-03,
- -2.9635796e-04,
- -1.2368630e-03,
- -2.0680559e-04,
- 9.0380036e-04
+ const static float t2_exp[39] = {
+ -0.00111255341, 0.000582886743, 0.00192370394, -2.30611317e-18, -0.0036777542,
+ -0.00198445749, 0.00586195057, 0.00665180339, -0.00685472786, -0.0147390282,
+ 0.00398152089, 0.0259364359, 0.00641921535, -0.0387352072, -0.0300688613,
+ 0.0507286265, 0.0831939653, -0.0592906512, -0.309726775, 0.561578512,
+ -0.309726775, -0.0592906512, 0.0831939653, 0.0507286265, -0.0300688613,
+ -0.0387352072, 0.00641921535, 0.0259364359, 0.00398152089, -0.0147390282,
+ -0.00685472786, 0.00665180339, 0.00586195057, -0.00198445749, -0.0036777542,
+ -2.30611317e-18, 0.00192370394, 0.000582886743, -0.00111255341
};
- const static float t3_exp[107] = {
- -1.8970841e-06,
- -7.1057165e-04,
- 5.4005696e-04,
- 4.6233178e-04,
- 2.0572044e-04,
- 3.5209916e-04,
- -1.4098573e-03,
- 1.1279077e-04,
- -6.2994129e-04,
- 1.1450432e-03,
- 1.3637283e-03,
- -6.4360141e-04,
- 3.6509900e-04,
- -3.2864159e-03,
- 7.0192874e-04,
- 3.7524730e-04,
- 2.0256115e-03,
- 3.0641893e-03,
- -3.6618244e-03,
- 7.5592739e-05,
- -5.5586505e-03,
- 2.3849572e-03,
- 4.0114378e-03,
- 1.6636450e-03,
- 4.7835698e-03,
- -1.0191196e-02,
- -3.8158931e-04,
- -5.5551580e-03,
- 5.3901658e-03,
- 1.1366769e-02,
- -3.0000482e-03,
- 4.9341680e-03,
- -2.0093076e-02,
- 5.5752542e-17,
- 1.2093617e-03,
- 8.6089745e-03,
- 2.2382140e-02,
- -1.6854567e-02,
- 1.6913920e-03,
- -3.1222520e-02,
- 3.2711059e-03,
- 2.2604836e-02,
- 8.1451107e-03,
- 3.7583180e-02,
- -5.2293688e-02,
- -8.0551542e-03,
- -4.0092729e-02,
- 1.5582236e-02,
- 9.7452506e-02,
- -1.6183170e-02,
- 8.3281815e-02,
- -2.8196752e-01,
- -1.0965768e-01,
- 5.2867508e-01,
- -1.0965768e-01,
- -2.8196752e-01,
- 8.3281815e-02,
- -1.6183170e-02,
- 9.7452506e-02,
- 1.5582236e-02,
- -4.0092729e-02,
- -8.0551542e-03,
- -5.2293688e-02,
- 3.7583180e-02,
- 8.1451107e-03,
- 2.2604836e-02,
- 3.2711059e-03,
- -3.1222520e-02,
- 1.6913920e-03,
- -1.6854567e-02,
- 2.2382140e-02,
- 8.6089745e-03,
- 1.2093617e-03,
- 5.5752542e-17,
- -2.0093076e-02,
- 4.9341680e-03,
- -3.0000482e-03,
- 1.1366769e-02,
- 5.3901658e-03,
- -5.5551580e-03,
- -3.8158931e-04,
- -1.0191196e-02,
- 4.7835698e-03,
- 1.6636450e-03,
- 4.0114378e-03,
- 2.3849572e-03,
- -5.5586505e-03,
- 7.5592739e-05,
- -3.6618244e-03,
- 3.0641893e-03,
- 2.0256115e-03,
- 3.7524730e-04,
- 7.0192874e-04,
- -3.2864159e-03,
- 3.6509900e-04,
- -6.4360141e-04,
- 1.3637283e-03,
- 1.1450432e-03,
- -6.2994129e-04,
- 1.1279077e-04,
- -1.4098573e-03,
- 3.5209916e-04,
- 2.0572044e-04,
- 4.6233178e-04,
- 5.4005696e-04,
- -7.1057165e-04,
- -1.8970841e-06
+ const static float t3_exp[77] = {
+ 0.000119983582, 0.000607753696, 0.000897691818, -0.0010834164, 2.31763315e-05,
+ -0.00179765455, 0.000822491478, 0.0014836716, 0.000661226455, 0.00204213755,
+ -0.00466352375, -0.000186616904, -0.00289339852, 0.00297895772, 0.00664081471,
+ -0.00184599939, 0.00318629085, -0.0135707017, 3.90737225e-17, 0.000884963025,
+ 0.00652826019, 0.0175401419, -0.013614703, 0.00140484457, -0.0266032815,
+ 0.00285289111, 0.0201372877, 0.00739659835, 0.0347237773, -0.0490655154,
+ -0.00766157778, -0.0385900773, 0.0151521852, 0.0955788717, -0.0159830209,
+ 0.0826964602, -0.281061709, -0.109556615, 0.528591633, -0.109556615,
+ -0.281061709, 0.0826964602, -0.0159830209, 0.0955788717, 0.0151521852,
+ -0.0385900773, -0.00766157778, -0.0490655154, 0.0347237773, 0.00739659835,
+ 0.0201372877, 0.00285289111, -0.0266032815, 0.00140484457, -0.013614703,
+ 0.0175401419, 0.00652826019, 0.000884963025, 3.90737225e-17, -0.0135707017,
+ 0.00318629085, -0.00184599939, 0.00664081471, 0.00297895772, -0.00289339852,
+ -0.000186616904, -0.00466352375, 0.00204213755, 0.000661226455, 0.0014836716,
+ 0.000822491478, -0.00179765455, 2.31763315e-05, -0.0010834164, 0.000897691818,
+ 0.000607753696, 0.000119983582
};
- const static float t4_exp[] = { // low pass
- 0.001059958362,
- 0.0002263929928,
- -0.001277606934,
- -0.0009675776237,
- 0.001592264394,
- 0.00243603508,
- -0.001451682881,
- -0.004769335967,
- 5.281541594e-18,
- 0.007567512803,
- 0.003658855334,
- -0.009761494584,
- -0.01011830103,
- 0.009636915289,
- 0.0193619132,
- -0.004935568199,
- -0.03060629964,
- -0.007267376408,
- 0.04236677289,
- 0.03197422624,
- -0.05274848267,
- -0.0850463286,
- 0.05989059806,
- 0.31065014,
- 0.4370569289,
- 0.31065014,
- 0.05989059806,
- -0.0850463286,
- -0.05274848267,
- 0.03197422624,
- 0.04236677289,
- -0.007267376408,
- -0.03060629964,
- -0.004935568199,
- 0.0193619132,
- 0.009636915289,
- -0.01011830103,
- -0.009761494584,
- 0.003658855334,
- 0.007567512803,
- 5.281541594e-18,
- -0.004769335967,
- -0.001451682881,
- 0.00243603508,
- 0.001592264394,
- -0.0009675776237,
- -0.001277606934,
- 0.0002263929928,
- 0.001059958362,
+ const static float t4_exp[49] = { // low pass
+ 0.00105995836, 0.000226392993, -0.00127760693, -0.000967577624, 0.00159226439,
+ 0.00243603508, -0.00145168288, -0.00476933597, 5.28154159e-18, 0.0075675128,
+ 0.00365885533, -0.00976149458, -0.010118301, 0.00963691529, 0.0193619132,
+ -0.0049355682, -0.0306062996, -0.00726737641, 0.0423667729, 0.0319742262,
+ -0.0527484827, -0.0850463286, 0.0598905981, 0.31065014, 0.437056929,
+ 0.31065014, 0.0598905981, -0.0850463286, -0.0527484827, 0.0319742262,
+ 0.0423667729, -0.00726737641, -0.0306062996, -0.0049355682, 0.0193619132,
+ 0.00963691529, -0.010118301, -0.00976149458, 0.00365885533, 0.0075675128,
+ 5.28154159e-18, -0.00476933597, -0.00145168288, 0.00243603508, 0.00159226439,
+ -0.000967577624, -0.00127760693, 0.000226392993, 0.00105995836
};
- const static float t5_exp[] = { //high pass
- -0.001062123571,
- -0.0002268554381,
- 0.001280216733,
- 0.000969554123,
- -0.001595516922,
- -0.002441011136,
- 0.001454648213,
- 0.004779078532,
- -5.292330097e-18,
- -0.007582970895,
- -0.00366632943,
- 0.009781434201,
- 0.01013896987,
- -0.009656600654,
- -0.01940146461,
- 0.004945650231,
- 0.03066881932,
- 0.00728222169,
- -0.04245331511,
- -0.03203954175,
- 0.05285623297,
- 0.08522006124,
- -0.06001294032,
- -0.3112847209,
- 0.5630782247,
- -0.3112847209,
- -0.06001294032,
- 0.08522006124,
- 0.05285623297,
- -0.03203954175,
- -0.04245331511,
- 0.00728222169,
- 0.03066881932,
- 0.004945650231,
- -0.01940146461,
- -0.009656600654,
- 0.01013896987,
- 0.009781434201,
- -0.00366632943,
- -0.007582970895,
- -5.292330097e-18,
- 0.004779078532,
- 0.001454648213,
- -0.002441011136,
- -0.001595516922,
- 0.000969554123,
- 0.001280216733,
- -0.0002268554381,
- -0.001062123571,
+ const static float t5_exp[49] = { //high pass
+ -0.00106212357, -0.000226855438, 0.00128021673, 0.000969554123, -0.00159551692,
+ -0.00244101114, 0.00145464821, 0.00477907853, -5.2923301e-18, -0.00758297089,
+ -0.00366632943, 0.0097814342, 0.0101389699, -0.00965660065, -0.0194014646,
+ 0.00494565023, 0.0306688193, 0.00728222169, -0.0424533151, -0.0320395418,
+ 0.052856233, 0.0852200612, -0.0600129403, -0.311284721, 0.563078225,
+ -0.311284721, -0.0600129403, 0.0852200612, 0.052856233, -0.0320395418,
+ -0.0424533151, 0.00728222169, 0.0306688193, 0.00494565023, -0.0194014646,
+ -0.00965660065, 0.0101389699, 0.0097814342, -0.00366632943, -0.00758297089,
+ -5.2923301e-18, 0.00477907853, 0.00145464821, -0.00244101114, -0.00159551692,
+ 0.000969554123, 0.00128021673, -0.000226855438, -0.00106212357
};
const static float t6_exp[] = { // bandpass
- 0.0002809273137,
- -0.001047327649,
- 7.936541806e-05,
- -0.0004270860809,
- 0.0007595835486,
- 0.0008966081077,
- -0.0004236323002,
- 0.0002423936094,
- -0.002212299034,
- 0.0004807534278,
- 0.0002620361629,
- 0.001443728455,
- 0.002229931997,
- -0.002720607212,
- 5.731141573e-05,
- -0.004297634587,
- 0.001878833398,
- 0.003217151389,
- 0.001357055153,
- 0.003965090029,
- -0.008576190099,
- -0.0003257228818,
- -0.004805727862,
- 0.004721920472,
- 0.01007549558,
- -0.002688719891,
- 0.004467967432,
- -0.01837076992,
- 5.119658377e-17,
- 0.001125075156,
- 0.008071650751,
- 0.02113764361,
- -0.01602453552,
- 0.001618095324,
- -0.03004053794,
- 0.003163811285,
- 0.0219683405,
- 0.007950295694,
- 0.03682873398,
- -0.05142467469,
- -0.00794606097,
- -0.03965795785,
- 0.01544955093,
- 0.09681399167,
- -0.01610304788,
- 0.08297294378,
- -0.2811714709,
- -0.1094062924,
- 0.5275565982,
- -0.1094062924,
- -0.2811714709,
- 0.08297294378,
- -0.01610304788,
- 0.09681399167,
- 0.01544955093,
- -0.03965795785,
- -0.00794606097,
- -0.05142467469,
- 0.03682873398,
- 0.007950295694,
- 0.0219683405,
- 0.003163811285,
- -0.03004053794,
- 0.001618095324,
- -0.01602453552,
- 0.02113764361,
- 0.008071650751,
- 0.001125075156,
- 5.119658377e-17,
- -0.01837076992,
- 0.004467967432,
- -0.002688719891,
- 0.01007549558,
- 0.004721920472,
- -0.004805727862,
- -0.0003257228818,
- -0.008576190099,
- 0.003965090029,
- 0.001357055153,
- 0.003217151389,
- 0.001878833398,
- -0.004297634587,
- 5.731141573e-05,
- -0.002720607212,
- 0.002229931997,
- 0.001443728455,
- 0.0002620361629,
- 0.0004807534278,
- -0.002212299034,
- 0.0002423936094,
- -0.0004236323002,
- 0.0008966081077,
- 0.0007595835486,
- -0.0004270860809,
- 7.936541806e-05,
- -0.001047327649,
- 0.0002809273137,
+ 0.000280927314, -0.00104732765, 7.93654181e-05, -0.000427086081, 0.000759583549,
+ 0.000896608108, -0.0004236323, 0.000242393609, -0.00221229903, 0.000480753428,
+ 0.000262036163, 0.00144372846, 0.002229932, -0.00272060721, 5.73114157e-05,
+ -0.00429763459, 0.0018788334, 0.00321715139, 0.00135705515, 0.00396509003,
+ -0.0085761901, -0.000325722882, -0.00480572786, 0.00472192047, 0.0100754956,
+ -0.00268871989, 0.00446796743, -0.0183707699, 5.11965838e-17, 0.00112507516,
+ 0.00807165075, 0.0211376436, -0.0160245355, 0.00161809532, -0.0300405379,
+ 0.00316381129, 0.0219683405, 0.00795029569, 0.036828734, -0.0514246747,
+ -0.00794606097, -0.0396579579, 0.0154495509, 0.0968139917, -0.0161030479,
+ 0.0829729438, -0.281171471, -0.109406292, 0.527556598, -0.109406292,
+ -0.281171471, 0.0829729438, -0.0161030479, 0.0968139917, 0.0154495509,
+ -0.0396579579, -0.00794606097, -0.0514246747, 0.036828734, 0.00795029569,
+ 0.0219683405, 0.00316381129, -0.0300405379, 0.00161809532, -0.0160245355,
+ 0.0211376436, 0.00807165075, 0.00112507516, 5.11965838e-17, -0.0183707699,
+ 0.00446796743, -0.00268871989, 0.0100754956, 0.00472192047, -0.00480572786,
+ -0.000325722882, -0.0085761901, 0.00396509003, 0.00135705515, 0.00321715139,
+ 0.0018788334, -0.00429763459, 5.73114157e-05, -0.00272060721, 0.002229932,
+ 0.00144372846, 0.000262036163, 0.000480753428, -0.00221229903, 0.000242393609,
+ -0.0004236323, 0.000896608108, 0.000759583549, -0.000427086081, 7.93654181e-05,
+ -0.00104732765, 0.000280927314
};
void
@@ -493,15 +158,15 @@ namespace gr {
500,
firdes::WIN_HAMMING);
- // cout << "ntaps: " << taps.size() << endl;
- // print_taps(cout, taps);
+ // std::cout << "ntaps: " << taps.size() << std::endl;
+ // print_taps(std::cout, taps);
CPPUNIT_ASSERT_EQUAL(NELEM(t1_exp), taps.size());
for(unsigned int i = 0; i < taps.size(); i++)
CPPUNIT_ASSERT_DOUBLES_EQUAL(t1_exp[i], taps[i], 1e-9);
check_symmetry(taps);
-}
+ }
void
qa_firdes::t2()
@@ -513,8 +178,8 @@ namespace gr {
500,
firdes::WIN_HAMMING);
- // cout << "ntaps: " << taps.size() << endl;
- // print_taps(cout, taps);
+ // std::cout << "ntaps: " << taps.size() << std::endl;
+ // print_taps(std::cout, taps);
CPPUNIT_ASSERT_EQUAL(NELEM(t2_exp), taps.size());
@@ -535,8 +200,8 @@ namespace gr {
0.62e6,
firdes::WIN_HAMMING);
- // cout << "ntaps: " << taps.size() << endl;
- // print_taps(cout, taps);
+ // std::cout << "ntaps: " << taps.size() << std::endl;
+ // print_taps(std::cout, taps);
CPPUNIT_ASSERT_EQUAL(NELEM(t3_exp), taps.size());
@@ -557,8 +222,8 @@ namespace gr {
66,
firdes::WIN_HAMMING);
- // std::cout << "ntaps: " << taps.size() << std::endl;
- // print_taps(std::cout, taps);
+ // std::cout << "ntaps: " << taps.size() << std::endl;
+ // print_taps(std::cout, taps);
CPPUNIT_ASSERT_EQUAL(NELEM(t4_exp), taps.size());
for(unsigned int i = 0; i < taps.size(); i++)
@@ -578,8 +243,8 @@ namespace gr {
66,
firdes::WIN_HAMMING);
- // std::cout << "ntaps: " << taps.size() << std::endl;
- // print_taps(std::cout, taps);
+ // std::cout << "ntaps: " << taps.size() << std::endl;
+ // print_taps(std::cout, taps);
CPPUNIT_ASSERT_EQUAL(NELEM(t5_exp), taps.size());
@@ -601,8 +266,8 @@ namespace gr {
66,
firdes::WIN_HAMMING);
- // std::cout << "ntaps: " << taps.size() << std::endl;
- // print_taps(std::cout, taps);
+ // std::cout << "ntaps: " << taps.size() << std::endl;
+ // print_taps(std::cout, taps);
CPPUNIT_ASSERT_EQUAL(NELEM(t6_exp), taps.size());
diff --git a/gr-filter/python/filter/pfb.py b/gr-filter/python/filter/pfb.py
index 52f598cc40..2ddf65962c 100644
--- a/gr-filter/python/filter/pfb.py
+++ b/gr-filter/python/filter/pfb.py
@@ -169,6 +169,12 @@ class decimator_ccf(gr.hier_block2):
self.connect(self.pfb, self)
+ def set_taps(self, taps):
+ self.pfb.set_taps(taps)
+
+ def set_channel(self, chan):
+ self.pfb.set_channel(chan)
+
class arb_resampler_ccf(gr.hier_block2):
'''
diff --git a/gr-filter/python/filter/qa_adaptive_fir_filter.py b/gr-filter/python/filter/qa_adaptive_fir_filter.py
deleted file mode 100755
index cb82c7e969..0000000000
--- a/gr-filter/python/filter/qa_adaptive_fir_filter.py
+++ /dev/null
@@ -1,101 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2008,2010,2012,2013 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3, or (at your option)
-# any later version.
-#
-# GNU Radio is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR 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, filter, blocks
-
-def fir_filter(x, taps, decim=1):
- y = []
- x2 = (len(taps)-1)*[0,] + x
- for i in range(0, len(x), decim):
- yi = 0
- for j in range(len(taps)):
- yi += taps[len(taps)-1-j] * x2[i+j]
- y.append(yi)
- return y
-
-class test_adaptive_filter(gr_unittest.TestCase):
-
- def setUp(self):
- self.tb = gr.top_block ()
-
- def tearDown(self):
- self.tb = None
-
- def test_adaptive_fir_filter_ccf_001(self):
- decim = 1
- taps = 20*[0.5, 0.5]
- src_data = 40*[1+1j, 2+2j, 3+3j, 4+4j]
- expected_data = fir_filter(src_data, taps, decim)
-
- src = blocks.vector_source_c(src_data)
- op = filter.adaptive_fir_ccf("test", decim, taps)
- dst = blocks.vector_sink_c()
- self.tb.connect(src, op, dst)
- self.tb.run()
- result_data = dst.data()
- self.assertComplexTuplesAlmostEqual(expected_data, result_data, 5)
-
- def test_adaptive_fir_filter_ccf_002(self):
- decim = 4
- taps = 20*[0.5, 0.5]
- src_data = 40*[1+1j, 2+2j, 3+3j, 4+4j]
- expected_data = fir_filter(src_data, taps, decim)
-
- src = blocks.vector_source_c(src_data)
- op = filter.adaptive_fir_ccf("test", decim, taps)
- dst = blocks.vector_sink_c()
- self.tb.connect(src, op, dst)
- self.tb.run()
- result_data = dst.data()
- self.assertComplexTuplesAlmostEqual(expected_data, result_data, 5)
-
- def test_adaptive_fir_filter_ccc_001(self):
- decim = 1
- taps = 20*[0.5+1j, 0.5+1j]
- src_data = 40*[1+1j, 2+2j, 3+3j, 4+4j]
- expected_data = fir_filter(src_data, taps, decim)
-
- src = blocks.vector_source_c(src_data)
- op = filter.adaptive_fir_ccc("test", decim, taps)
- dst = blocks.vector_sink_c()
- self.tb.connect(src, op, dst)
- self.tb.run()
- result_data = dst.data()
- self.assertComplexTuplesAlmostEqual(expected_data, result_data, 5)
-
-
- def test_adaptive_fir_filter_ccc_002(self):
- decim = 4
- taps = 20*[0.5+1j, 0.5+1j]
- src_data = 40*[1+1j, 2+2j, 3+3j, 4+4j]
- expected_data = fir_filter(src_data, taps, decim)
-
- src = blocks.vector_source_c(src_data)
- op = filter.adaptive_fir_ccc("test", decim, taps)
- dst = blocks.vector_sink_c()
- self.tb.connect(src, op, dst)
- self.tb.run()
- result_data = dst.data()
- self.assertComplexTuplesAlmostEqual(expected_data, result_data, 5)
-
-if __name__ == '__main__':
- gr_unittest.run(test_adaptive_filter, "test_adaptive_filter.xml")
-
diff --git a/gr-filter/python/filter/qa_firdes.py b/gr-filter/python/filter/qa_firdes.py
index d38af31822..b32e5b2f91 100755
--- a/gr-filter/python/filter/qa_firdes.py
+++ b/gr-filter/python/filter/qa_firdes.py
@@ -32,15 +32,14 @@ class test_firdes(gr_unittest.TestCase):
pass
def test_low_pass(self):
- known_taps = (0.0030193300917744637, -0.004960992839187384,
- 0.006678304169327021, -1.132049690556083e-17,
- -0.0251916591078043, 0.07206480950117111,
- -0.13062666356563568, 0.18007083237171173,
- 0.7978920936584473, 0.18007083237171173,
- -0.13062666356563568, 0.07206480950117111,
- -0.0251916591078043, -1.132049690556083e-17,
- 0.006678304169327021, -0.004960992839187384,
- 0.0030193300917744637)
+ known_taps = (0.0024871660862118006, -4.403502608370943e-18,
+ -0.014456653036177158, 0.0543283149600029,
+ -0.116202212870121, 0.17504146695137024,
+ 0.7976038455963135, 0.17504146695137024,
+ -0.116202212870121, 0.0543283149600029,
+ -0.014456653036177158, -4.403502608370943e-18,
+ 0.0024871660862118006)
+
new_taps = filter.firdes.low_pass(1, 1, 0.4, 0.2)
self.assertFloatTuplesAlmostEqual(known_taps, new_taps, 5)
@@ -56,15 +55,13 @@ class test_firdes(gr_unittest.TestCase):
self.assertFloatTuplesAlmostEqual(known_taps, new_taps, 5)
def test_high_pass(self):
- known_taps = (-0.003062003292143345, 0.005031108390539885,
- -0.0067726909182965755, 1.1480492661182674e-17,
- 0.025547700002789497, -0.0730833187699318,
- 0.13247284293174744, -0.18261581659317017,
- 0.20229223370552063, -0.18261581659317017,
- 0.13247284293174744, -0.0730833187699318,
- 0.025547700002789497, 1.1480492661182674e-17,
- -0.0067726909182965755, 0.005031108390539885,
- -0.003062003292143345)
+ known_taps = (-0.0027197482995688915, 4.815287179370254e-18,
+ 0.01580853760242462, -0.05940871313214302,
+ 0.1270686239004135, -0.1914101094007492,
+ 0.21804752945899963, -0.1914101094007492,
+ 0.1270686239004135, -0.05940871313214302,
+ 0.01580853760242462, 4.815287179370254e-18,
+ -0.0027197482995688915)
new_taps = filter.firdes.high_pass(1, 1, 0.4, 0.2)
self.assertFloatTuplesAlmostEqual(known_taps, new_taps, 5)
@@ -80,15 +77,13 @@ class test_firdes(gr_unittest.TestCase):
self.assertFloatTuplesAlmostEqual(known_taps, new_taps, 5)
def test_band_pass(self):
- known_taps = (0.004961997736245394, -0.008152946829795837,
- -0.004192151129245758, -5.749020235348687e-18,
- 0.01581347920000553, 0.11843203753232956,
- -0.21467317640781403, -0.11303528398275375,
- 0.40520283579826355, -0.11303528398275375,
- -0.21467317640781403, 0.11843203753232956,
- 0.01581347920000553, -5.749020235348687e-18,
- -0.004192151129245758, -0.008152946829795837,
- 0.004961997736245394)
+ known_taps = (-0.001676854444667697, -2.4018533253972557e-18,
+ 0.009746716357767582, 0.09589414298534393,
+ -0.20510689914226532, -0.11801345646381378,
+ 0.4350462853908539, -0.11801345646381378,
+ -0.20510689914226532, 0.09589414298534393,
+ 0.009746716357767582, -2.4018533253972557e-18,
+ -0.001676854444667697)
new_taps = filter.firdes.band_pass(1, 1, 0.2, 0.4, 0.2)
self.assertFloatTuplesAlmostEqual(known_taps, new_taps, 5)
@@ -104,23 +99,19 @@ class test_firdes(gr_unittest.TestCase):
self.assertFloatTuplesAlmostEqual(known_taps, new_taps, 5)
def test_complex_band_pass(self):
- known_taps = ((0.0024772135075181723+0.0017997993854805827j),
- (-0.004070250317454338+0.002957213670015335j),
- (-0.0020928815938532352-0.006441210396587849j),
- (-2.8701231652956686e-18+2.805614574993832e-24j),
- (0.007894645445048809-0.024297315627336502j),
- (0.05912570655345917+0.04295721650123596j),
- (-0.10717268288135529+0.07786571979522705j),
- (-0.0564316064119339-0.17367789149284363j),
- (0.20229223370552063-2.4115112751132983e-07j),
- (-0.05643119290471077+0.17367802560329437j),
- (-0.10717286914587021-0.07786546647548676j),
- (0.05912560224533081-0.0429573580622673j),
- (0.007894691079854965+0.024297300726175308j),
- (-2.8701231652956686e-18+2.6687109203363464e-24j),
- (-0.0020928694866597652+0.006441214121878147j),
- (-0.004070255905389786-0.0029572059866040945j),
- (0.0024772100150585175-0.0017998040420934558j))
+ known_taps = ((-0.0008404505206272006-0.0025866336654871702j),
+ (-1.2038217948425635e-18+1.1767648157397848e-24j),
+ (0.0048850891180336475-0.015034818090498447j),
+ (0.048062704503536224+0.03491950035095215j),
+ (-0.10280057787895203+0.07468919456005096j),
+ (-0.05914920195937157-0.18204176425933838j),
+ (0.21804752945899963-2.5993290364567656e-07j),
+ (-0.059148769825696945+0.18204189836978912j),
+ (-0.10280075669288635-0.07468894869089127j),
+ (0.04806262254714966-0.0349196158349514j),
+ (0.004885117989033461+0.015034808777272701j),
+ (-1.2038217948425635e-18+1.1193430388030685e-24j),
+ (-0.000840445572976023+0.002586635295301676j))
new_taps = filter.firdes.complex_band_pass(1, 1, 0.2, 0.4, 0.2)
self.assertComplexTuplesAlmostEqual(known_taps, new_taps, 5)
@@ -142,15 +133,13 @@ class test_firdes(gr_unittest.TestCase):
self.assertComplexTuplesAlmostEqual(known_taps, new_taps, 5)
def test_band_reject(self):
- known_taps = (-0.004915320314466953, 0.008076251484453678,
- 0.00415271520614624, 5.694938753309664e-18,
- -0.01566472090780735, -0.11731793731451035,
- 0.2126537412405014, 0.11197195947170258,
- 0.6020866632461548, 0.11197195947170258,
- 0.2126537412405014, -0.11731793731451035,
- -0.01566472090780735, 5.694938753309664e-18,
- 0.00415271520614624, 0.008076251484453678,
- -0.004915320314466953)
+ known_taps = (0.0015371545450761914, 2.201753372137003e-18,
+ -0.00893471110612154, -0.08790513873100281,
+ 0.1880193054676056, 0.1081816703081131,
+ 0.5982034206390381, 0.1081816703081131,
+ 0.1880193054676056, -0.08790513873100281,
+ -0.00893471110612154, 2.201753372137003e-18,
+ 0.0015371545450761914)
new_taps = filter.firdes.band_reject(1, 1, 0.2, 0.4, 0.2)
self.assertFloatTuplesAlmostEqual(known_taps, new_taps, 5)
diff --git a/gr-filter/python/filter/qa_freq_xlating_fir_filter.py b/gr-filter/python/filter/qa_freq_xlating_fir_filter.py
index 39a803715e..ca5245db64 100755
--- a/gr-filter/python/filter/qa_freq_xlating_fir_filter.py
+++ b/gr-filter/python/filter/qa_freq_xlating_fir_filter.py
@@ -91,7 +91,7 @@ class test_freq_xlating_filter(gr_unittest.TestCase):
def generate_scf_source(self):
self.fs = fs = 1
self.fc = fc = 0.3
- self.bw = bw = 0.1
+ self.bw = bw = 0.12
self.taps = filter.firdes.low_pass(1, fs, bw, bw/4)
times = xrange(100)
self.src_data = map(lambda t: int(100*math.sin(2*cmath.pi*fc/fs*(t/100.0))), times)
@@ -99,7 +99,7 @@ class test_freq_xlating_filter(gr_unittest.TestCase):
def generate_scc_source(self):
self.fs = fs = 1
self.fc = fc = 0.3
- self.bw = bw = 0.1
+ self.bw = bw = 0.12
self.taps = filter.firdes.complex_band_pass(1, fs, -bw/2, bw/2, bw/4)
times = xrange(100)
self.src_data = map(lambda t: int(100*math.sin(2*cmath.pi*fc/fs*(t/100.0))), times)
diff --git a/gr-filter/swig/filter_swig.i b/gr-filter/swig/filter_swig.i
index b7d3656bcf..aad96e5c86 100644
--- a/gr-filter/swig/filter_swig.i
+++ b/gr-filter/swig/filter_swig.i
@@ -30,8 +30,6 @@
%{
#include "gnuradio/filter/firdes.h"
#include "gnuradio/filter/pm_remez.h"
-#include "gnuradio/filter/adaptive_fir_ccc.h"
-#include "gnuradio/filter/adaptive_fir_ccf.h"
#include "gnuradio/filter/dc_blocker_cc.h"
#include "gnuradio/filter/dc_blocker_ff.h"
#include "gnuradio/filter/filter_delay_fc.h"
@@ -79,8 +77,6 @@
%include "gnuradio/filter/firdes.h"
%include "gnuradio/filter/pm_remez.h"
-%include "gnuradio/filter/adaptive_fir_ccc.h"
-%include "gnuradio/filter/adaptive_fir_ccf.h"
%include "gnuradio/filter/dc_blocker_cc.h"
%include "gnuradio/filter/dc_blocker_ff.h"
%include "gnuradio/filter/filter_delay_fc.h"
@@ -125,8 +121,6 @@
%include "gnuradio/filter/single_pole_iir_filter_cc.h"
%include "gnuradio/filter/single_pole_iir_filter_ff.h"
-GR_SWIG_BLOCK_MAGIC2(filter, adaptive_fir_ccc);
-GR_SWIG_BLOCK_MAGIC2(filter, adaptive_fir_ccf);
GR_SWIG_BLOCK_MAGIC2(filter, dc_blocker_cc);
GR_SWIG_BLOCK_MAGIC2(filter, dc_blocker_ff);
GR_SWIG_BLOCK_MAGIC2(filter, filter_delay_fc);
diff --git a/gr-qtgui/grc/qtgui_freq_sink_x.xml b/gr-qtgui/grc/qtgui_freq_sink_x.xml
index 35edf61ed8..6a61a05e0f 100644
--- a/gr-qtgui/grc/qtgui_freq_sink_x.xml
+++ b/gr-qtgui/grc/qtgui_freq_sink_x.xml
@@ -78,6 +78,10 @@ $(gui_hint()($win))</make>
<name>Kaiser</name>
<key>firdes.WIN_KAISER</key>
</option>
+ <option>
+ <name>Flat-top</name>
+ <key>firdes.WIN_FLATTOP</key>
+ </option>
</param>
<param>
<name>Center Frequency (Hz)</name>
diff --git a/gr-qtgui/grc/qtgui_waterfall_sink_x.xml b/gr-qtgui/grc/qtgui_waterfall_sink_x.xml
index 176a907e9e..ac08450730 100644
--- a/gr-qtgui/grc/qtgui_waterfall_sink_x.xml
+++ b/gr-qtgui/grc/qtgui_waterfall_sink_x.xml
@@ -77,6 +77,10 @@ $(gui_hint()($win))</make>
<name>Kaiser</name>
<key>firdes.WIN_KAISER</key>
</option>
+ <option>
+ <name>Flat-top</name>
+ <key>firdes.WIN_FLATTOP</key>
+ </option>
</param>
<param>
<name>Center Frequency (Hz)</name>
diff --git a/gr-qtgui/include/gnuradio/qtgui/form_menus.h b/gr-qtgui/include/gnuradio/qtgui/form_menus.h
index d6499572c3..e7ebc3a797 100644
--- a/gr-qtgui/include/gnuradio/qtgui/form_menus.h
+++ b/gr-qtgui/include/gnuradio/qtgui/form_menus.h
@@ -26,6 +26,8 @@
#include <stdexcept>
#include <vector>
#include <QtGui/QtGui>
+#include <QtGui/QIntValidator>
+#include <QtGui/QDoubleValidator>
#include <qwt_symbol.h>
#include <gnuradio/filter/firdes.h>
#include <gnuradio/qtgui/qtgui_types.h>
@@ -498,6 +500,16 @@ public:
~OtherAction()
{}
+ void setValidator(QValidator *v)
+ {
+ d_text->setValidator(v);
+ }
+
+ void setDiagText(QString text)
+ {
+ d_text->setText(text);
+ }
+
signals:
void whichTrigger(const QString &text);
@@ -603,11 +615,20 @@ public:
d_act.push_back(new QAction("1024", this));
d_act.push_back(new QAction("2048", this));
d_act.push_back(new QAction("4096", this));
- d_act.push_back(new QAction("8192", this));
- d_act.push_back(new QAction("16384", this));
- d_act.push_back(new QAction("32768", this));
+ //d_act.push_back(new QAction("8192", this));
+ //d_act.push_back(new QAction("16384", this));
+ //d_act.push_back(new QAction("32768", this));
d_act.push_back(new OtherAction(this));
+ d_grp = new QActionGroup(this);
+ for(int t = 0; t < d_act.size(); t++) {
+ d_act[t]->setCheckable(true);
+ d_act[t]->setActionGroup(d_grp);
+ }
+
+ QIntValidator *valid = new QIntValidator(32, 4096, this);
+ ((OtherAction*)d_act[d_act.size()-1])->setValidator(valid);
+
connect(d_act[0], SIGNAL(triggered()), this, SLOT(get05()));
connect(d_act[1], SIGNAL(triggered()), this, SLOT(get06()));
connect(d_act[2], SIGNAL(triggered()), this, SLOT(get07()));
@@ -616,59 +637,78 @@ public:
connect(d_act[5], SIGNAL(triggered()), this, SLOT(get10()));
connect(d_act[6], SIGNAL(triggered()), this, SLOT(get11()));
connect(d_act[7], SIGNAL(triggered()), this, SLOT(get12()));
- connect(d_act[8], SIGNAL(triggered()), this, SLOT(get13()));
- connect(d_act[9], SIGNAL(triggered()), this, SLOT(get14()));
- connect(d_act[10], SIGNAL(triggered()), this, SLOT(get15()));
- connect(d_act[11], SIGNAL(whichTrigger(const QString&)),
- this, SLOT(getOther(const QString&)));
+ //connect(d_act[8], SIGNAL(triggered()), this, SLOT(get13()));
+ //connect(d_act[9], SIGNAL(triggered()), this, SLOT(get14()));
+ //connect(d_act[10], SIGNAL(triggered()), this, SLOT(get15()));
+ connect(d_act[8], SIGNAL(whichTrigger(const QString&)),
+ this, SLOT(getOther(const QString&)));
- QListIterator<QAction*> i(d_act);
- while(i.hasNext()) {
- QAction *a = i.next();
- addAction(a);
- }
- }
+ QListIterator<QAction*> i(d_act);
+ while(i.hasNext()) {
+ QAction *a = i.next();
+ addAction(a);
+ }
+ }
- ~FFTSizeMenu()
- {}
+ ~FFTSizeMenu()
+ {}
- int getNumActions() const
- {
- return d_act.size();
- }
+ int getNumActions() const
+ {
+ return d_act.size();
+ }
- QAction * getAction(int which)
- {
- if(which < d_act.size())
- return d_act[which];
- else
- throw std::runtime_error("FFTSizeMenu::getAction: which out of range.\n");
- }
+ QAction * getAction(int which)
+ {
+ if(which < d_act.size())
+ return d_act[which];
+ else
+ throw std::runtime_error("FFTSizeMenu::getAction: which out of range.\n");
+ }
- signals:
- void whichTrigger(int size);
+ QAction * getActionFromSize(int size)
+ {
+ float ipt;
+ float which = logf(static_cast<float>(size))/logf(2.0) - 5;
+ // If we're a predefined value
+ if(modff(which,&ipt) == 0) {
+ if(which < d_act.size()-1)
+ return d_act[static_cast<int>(which)];
+ else
+ throw std::runtime_error("FFTSizeMenu::getActionFromString: which out of range.\n");
+ }
+ // Or a non-predefined value, return Other
+ else {
+ ((OtherAction*)d_act[d_act.size()-1])->setDiagText(QString().setNum(size));
+ return d_act[d_act.size()-1];
+ }
+ }
- public slots:
- void get05() { emit whichTrigger(32); }
- void get06() { emit whichTrigger(64); }
- void get07() { emit whichTrigger(128); }
- void get08() { emit whichTrigger(256); }
- void get09() { emit whichTrigger(512); }
- void get10() { emit whichTrigger(1024); }
- void get11() { emit whichTrigger(2048); }
- void get12() { emit whichTrigger(4096); }
- void get13() { emit whichTrigger(8192); }
- void get14() { emit whichTrigger(16384); }
- void get15() { emit whichTrigger(32768); }
- void getOther(const QString &str)
- {
- int value = str.toInt();
- emit whichTrigger(value);
- }
+signals:
+ void whichTrigger(int size);
+
+public slots:
+ void get05() { emit whichTrigger(32); }
+ void get06() { emit whichTrigger(64); }
+ void get07() { emit whichTrigger(128); }
+ void get08() { emit whichTrigger(256); }
+ void get09() { emit whichTrigger(512); }
+ void get10() { emit whichTrigger(1024); }
+ void get11() { emit whichTrigger(2048); }
+ void get12() { emit whichTrigger(4096); }
+ //void get13() { emit whichTrigger(8192); }
+ //void get14() { emit whichTrigger(16384); }
+ //void get15() { emit whichTrigger(32768); }
+ void getOther(const QString &str)
+ {
+ int value = str.toInt();
+ emit whichTrigger(value);
+ }
private:
QList<QAction *> d_act;
OtherAction *d_other;
+ QActionGroup *d_grp;
};
@@ -683,50 +723,83 @@ public:
FFTAverageMenu(QWidget *parent)
: QMenu("FFT Average", parent)
{
+ d_off = 1.0;
+ d_high = 0.05;
+ d_medium = 0.1;
+ d_low = 0.2;
+
d_act.push_back(new QAction("Off", this));
d_act.push_back(new QAction("High", this));
d_act.push_back(new QAction("Medium", this));
d_act.push_back(new QAction("Low", this));
d_act.push_back(new OtherAction(this));
+ d_grp = new QActionGroup(this);
+ for(int t = 0; t < d_act.size(); t++) {
+ d_act[t]->setCheckable(true);
+ d_act[t]->setActionGroup(d_grp);
+ }
+ d_act[0]->setChecked(true);
+
+ QDoubleValidator *valid = new QDoubleValidator(0.0, 1.0, 2, this);
+ ((OtherAction*)d_act[d_act.size()-1])->setValidator(valid);
+
connect(d_act[0], SIGNAL(triggered()), this, SLOT(getOff()));
connect(d_act[1], SIGNAL(triggered()), this, SLOT(getHigh()));
connect(d_act[2], SIGNAL(triggered()), this, SLOT(getMedium()));
connect(d_act[3], SIGNAL(triggered()), this, SLOT(getLow()));
connect(d_act[4], SIGNAL(whichTrigger(const QString&)),
- this, SLOT(getOther(const QString&)));
+ this, SLOT(getOther(const QString&)));
- QListIterator<QAction*> i(d_act);
- while(i.hasNext()) {
- QAction *a = i.next();
- addAction(a);
- }
- }
+ QListIterator<QAction*> i(d_act);
+ while(i.hasNext()) {
+ QAction *a = i.next();
+ addAction(a);
+ }
+ }
- ~FFTAverageMenu()
- {}
+ ~FFTAverageMenu()
+ {}
- int getNumActions() const
- {
- return d_act.size();
- }
+ int getNumActions() const
+ {
+ return d_act.size();
+ }
- QAction * getAction(int which)
- {
- if(which < d_act.size())
- return d_act[which];
- else
- throw std::runtime_error("FFTSizeMenu::getAction: which out of range.\n");
- }
+ QAction * getAction(int which)
+ {
+ if(which < d_act.size())
+ return d_act[which];
+ else
+ throw std::runtime_error("FFTSizeMenu::getAction: which out of range.\n");
+ }
+
+ QAction * getActionFromAvg(float avg)
+ {
+ int which = 0;
+ if(avg == d_off)
+ which = 0;
+ else if(avg == d_high)
+ which = 1;
+ else if(avg == d_medium)
+ which = 2;
+ else if(avg == d_low)
+ which = 3;
+ else {
+ ((OtherAction*)d_act[d_act.size()-1])->setDiagText(QString().setNum(avg));
+ which = 4;
+ }
+ return d_act[static_cast<int>(which)];
+ }
signals:
void whichTrigger(float alpha);
public slots:
- void getOff() { emit whichTrigger(1.0); }
- void getHigh() { emit whichTrigger(0.05); }
- void getMedium() { emit whichTrigger(0.1); }
- void getLow() { emit whichTrigger(0.2); }
+ void getOff() { emit whichTrigger(d_off); }
+ void getHigh() { emit whichTrigger(d_high); }
+ void getMedium() { emit whichTrigger(d_medium); }
+ void getLow() { emit whichTrigger(d_low); }
void getOther(const QString &str)
{
float value = str.toFloat();
@@ -736,6 +809,8 @@ public:
private:
QList<QAction *> d_act;
OtherAction *d_other;
+ QActionGroup *d_grp;
+ float d_off, d_high, d_medium, d_low;
};
@@ -757,6 +832,13 @@ public:
d_act.push_back(new QAction("Blackman-harris", this));
d_act.push_back(new QAction("Rectangular", this));
d_act.push_back(new QAction("Kaiser", this));
+ d_act.push_back(new QAction("Flat-top", this));
+
+ d_grp = new QActionGroup(this);
+ for(int t = 0; t < d_act.size(); t++) {
+ d_act[t]->setCheckable(true);
+ d_act[t]->setActionGroup(d_grp);
+ }
connect(d_act[0], SIGNAL(triggered()), this, SLOT(getNone()));
connect(d_act[1], SIGNAL(triggered()), this, SLOT(getHamming()));
@@ -765,6 +847,7 @@ public:
connect(d_act[4], SIGNAL(triggered()), this, SLOT(getBlackmanharris()));
connect(d_act[5], SIGNAL(triggered()), this, SLOT(getRectangular()));
connect(d_act[6], SIGNAL(triggered()), this, SLOT(getKaiser()));
+ connect(d_act[7], SIGNAL(triggered()), this, SLOT(getFlattop()));
QListIterator<QAction*> i(d_act);
while(i.hasNext()) {
@@ -789,6 +872,22 @@ public:
throw std::runtime_error("FFTWindowMenu::getAction: which out of range.\n");
}
+ QAction * getActionFromWindow(gr::filter::firdes::win_type type)
+ {
+ int which = 0;
+ switch(static_cast<int>(type)) {
+ case((gr::filter::firdes::WIN_NONE)): which = 0; break;
+ case((gr::filter::firdes::WIN_HAMMING)): which = 1; break;
+ case((gr::filter::firdes::WIN_HANN)): which = 2; break;
+ case((gr::filter::firdes::WIN_BLACKMAN)): which = 3; break;
+ case((gr::filter::firdes::WIN_BLACKMAN_hARRIS)): which = 4; break;
+ case((gr::filter::firdes::WIN_RECTANGULAR)): which = 5; break;
+ case((gr::filter::firdes::WIN_KAISER)): which = 6; break;
+ case((gr::filter::firdes::WIN_FLATTOP)): which = 7; break;
+ }
+ return d_act[which];
+ }
+
signals:
void whichTrigger(const gr::filter::firdes::win_type type);
@@ -800,9 +899,11 @@ public slots:
void getBlackmanharris() { emit whichTrigger(gr::filter::firdes::WIN_BLACKMAN_hARRIS); }
void getRectangular() { emit whichTrigger(gr::filter::firdes::WIN_RECTANGULAR); }
void getKaiser() { emit whichTrigger(gr::filter::firdes::WIN_KAISER); }
+ void getFlattop() { emit whichTrigger(gr::filter::firdes::WIN_FLATTOP); }
private:
QList<QAction *> d_act;
+ QActionGroup *d_grp;
int d_which;
};
diff --git a/gr-qtgui/include/gnuradio/qtgui/freqdisplayform.h b/gr-qtgui/include/gnuradio/qtgui/freqdisplayform.h
index 9a69810276..95e6337f04 100644
--- a/gr-qtgui/include/gnuradio/qtgui/freqdisplayform.h
+++ b/gr-qtgui/include/gnuradio/qtgui/freqdisplayform.h
@@ -73,6 +73,11 @@ private:
int d_fftsize;
float d_fftavg;
gr::filter::firdes::win_type d_fftwintype;
+
+ FFTSizeMenu *d_sizemenu;
+ FFTAverageMenu *d_avgmenu;
+ FFTWindowMenu *d_winmenu;
+
};
#endif /* FREQ_DISPLAY_FORM_H */
diff --git a/gr-qtgui/include/gnuradio/qtgui/waterfalldisplayform.h b/gr-qtgui/include/gnuradio/qtgui/waterfalldisplayform.h
index 926d1cec12..1ac1cf428f 100644
--- a/gr-qtgui/include/gnuradio/qtgui/waterfalldisplayform.h
+++ b/gr-qtgui/include/gnuradio/qtgui/waterfalldisplayform.h
@@ -92,6 +92,10 @@ private:
double d_min_val;
double d_max_val;
+
+ FFTSizeMenu *d_sizemenu;
+ FFTAverageMenu *d_avgmenu;
+ FFTWindowMenu *d_winmenu;
};
#endif /* WATERFALL_DISPLAY_FORM_H */
diff --git a/gr-qtgui/lib/freqdisplayform.cc b/gr-qtgui/lib/freqdisplayform.cc
index 46050d8149..32d82b9a8d 100644
--- a/gr-qtgui/lib/freqdisplayform.cc
+++ b/gr-qtgui/lib/freqdisplayform.cc
@@ -40,17 +40,17 @@ FreqDisplayForm::FreqDisplayForm(int nplots, QWidget* parent)
d_fftsize = 1024;
d_fftavg = 1.0;
- FFTSizeMenu *sizemenu = new FFTSizeMenu(this);
- FFTAverageMenu *avgmenu = new FFTAverageMenu(this);
- FFTWindowMenu *winmenu = new FFTWindowMenu(this);
- d_menu->addMenu(sizemenu);
- d_menu->addMenu(avgmenu);
- d_menu->addMenu(winmenu);
- connect(sizemenu, SIGNAL(whichTrigger(int)),
+ d_sizemenu = new FFTSizeMenu(this);
+ d_avgmenu = new FFTAverageMenu(this);
+ d_winmenu = new FFTWindowMenu(this);
+ d_menu->addMenu(d_sizemenu);
+ d_menu->addMenu(d_avgmenu);
+ d_menu->addMenu(d_winmenu);
+ connect(d_sizemenu, SIGNAL(whichTrigger(int)),
this, SLOT(setFFTSize(const int)));
- connect(avgmenu, SIGNAL(whichTrigger(float)),
+ connect(d_avgmenu, SIGNAL(whichTrigger(float)),
this, SLOT(setFFTAverage(const float)));
- connect(winmenu, SIGNAL(whichTrigger(gr::filter::firdes::win_type)),
+ connect(d_winmenu, SIGNAL(whichTrigger(gr::filter::firdes::win_type)),
this, SLOT(setFFTWindowType(const gr::filter::firdes::win_type)));
Reset();
@@ -120,6 +120,7 @@ void
FreqDisplayForm::setFFTSize(const int newsize)
{
d_fftsize = newsize;
+ d_sizemenu->getActionFromSize(newsize)->setChecked(true);
getPlot()->replot();
}
@@ -127,6 +128,7 @@ void
FreqDisplayForm::setFFTAverage(const float newavg)
{
d_fftavg = newavg;
+ d_avgmenu->getActionFromAvg(newavg)->setChecked(true);
getPlot()->replot();
}
@@ -134,6 +136,7 @@ void
FreqDisplayForm::setFFTWindowType(const gr::filter::firdes::win_type newwin)
{
d_fftwintype = newwin;
+ d_winmenu->getActionFromWindow(newwin)->setChecked(true);
getPlot()->replot();
}
diff --git a/gr-qtgui/lib/waterfalldisplayform.cc b/gr-qtgui/lib/waterfalldisplayform.cc
index 4b8e042658..f4dd2fd338 100644
--- a/gr-qtgui/lib/waterfalldisplayform.cc
+++ b/gr-qtgui/lib/waterfalldisplayform.cc
@@ -75,17 +75,17 @@ WaterfallDisplayForm::WaterfallDisplayForm(int nplots, QWidget* parent)
d_autoscale_act->setText(tr("Auto Scale"));
d_autoscale_act->setCheckable(false);
- FFTSizeMenu *sizemenu = new FFTSizeMenu(this);
- FFTAverageMenu *avgmenu = new FFTAverageMenu(this);
- FFTWindowMenu *winmenu = new FFTWindowMenu(this);
- d_menu->addMenu(sizemenu);
- d_menu->addMenu(avgmenu);
- d_menu->addMenu(winmenu);
- connect(sizemenu, SIGNAL(whichTrigger(int)),
+ d_sizemenu = new FFTSizeMenu(this);
+ d_avgmenu = new FFTAverageMenu(this);
+ d_winmenu = new FFTWindowMenu(this);
+ d_menu->addMenu(d_sizemenu);
+ d_menu->addMenu(d_avgmenu);
+ d_menu->addMenu(d_winmenu);
+ connect(d_sizemenu, SIGNAL(whichTrigger(int)),
this, SLOT(setFFTSize(const int)));
- connect(avgmenu, SIGNAL(whichTrigger(float)),
+ connect(d_avgmenu, SIGNAL(whichTrigger(float)),
this, SLOT(setFFTAverage(const float)));
- connect(winmenu, SIGNAL(whichTrigger(gr::filter::firdes::win_type)),
+ connect(d_winmenu, SIGNAL(whichTrigger(gr::filter::firdes::win_type)),
this, SLOT(setFFTWindowType(const gr::filter::firdes::win_type)));
Reset();
@@ -190,18 +190,24 @@ void
WaterfallDisplayForm::setFFTSize(const int newsize)
{
d_fftsize = newsize;
+ d_sizemenu->getActionFromSize(newsize)->setChecked(true);
+ getPlot()->replot();
}
void
WaterfallDisplayForm::setFFTAverage(const float newavg)
{
d_fftavg = newavg;
+ d_avgmenu->getActionFromAvg(newavg)->setChecked(true);
+ getPlot()->replot();
}
void
WaterfallDisplayForm::setFFTWindowType(const gr::filter::firdes::win_type newwin)
{
d_fftwintype = newwin;
+ d_winmenu->getActionFromWindow(newwin)->setChecked(true);
+ getPlot()->replot();
}
void
diff --git a/gr-utils/python/modtool/gr-newmod/CMakeLists.txt b/gr-utils/python/modtool/gr-newmod/CMakeLists.txt
index 2dac3461a8..1d2e37b6a6 100644
--- a/gr-utils/python/modtool/gr-newmod/CMakeLists.txt
+++ b/gr-utils/python/modtool/gr-newmod/CMakeLists.txt
@@ -83,20 +83,15 @@ set(GRC_BLOCKS_DIR ${GR_PKG_DATA_DIR}/grc/blocks)
########################################################################
# Find gnuradio build dependencies
########################################################################
-find_package(GnuradioRuntime)
find_package(CppUnit)
-# To run a more advanced search for GNU Radio and it's components and
-# versions, use the following. Add any components required to the list
-# of GR_REQUIRED_COMPONENTS (in all caps) and change "version" to the
-# minimum API compatible version required.
-#
-# set(GR_REQUIRED_COMPONENTS RUNTIME BLOCKS FILTER ...)
-# find_package(Gnuradio "version")
+# Search for GNU Radio and its components and versions. Add any
+# components required to the list of GR_REQUIRED_COMPONENTS (in all
+# caps such as FILTER or FFT) and change the version to the minimum
+# API compatible version required.
+set(GR_REQUIRED_COMPONENTS RUNTIME)
+find_package(Gnuradio "3.7.2" REQUIRED)
-if(NOT GNURADIO_RUNTIME_FOUND)
- message(FATAL_ERROR "GnuRadio Runtime required to compile howto")
-endif()
if(NOT CPPUNIT_FOUND)
message(FATAL_ERROR "CppUnit required to compile howto")
endif()
@@ -111,7 +106,7 @@ include_directories(
${CMAKE_BINARY_DIR}/include
${Boost_INCLUDE_DIRS}
${CPPUNIT_INCLUDE_DIRS}
- ${GNURADIO_RUNTIME_INCLUDE_DIRS}
+ ${GNURADIO_ALL_INCLUDE_DIRS}
)
link_directories(
diff --git a/gr-utils/python/modtool/gr-newmod/lib/CMakeLists.txt b/gr-utils/python/modtool/gr-newmod/lib/CMakeLists.txt
index 312594149c..de53723de2 100644
--- a/gr-utils/python/modtool/gr-newmod/lib/CMakeLists.txt
+++ b/gr-utils/python/modtool/gr-newmod/lib/CMakeLists.txt
@@ -29,7 +29,7 @@ list(APPEND howto_sources
)
add_library(gnuradio-howto SHARED ${howto_sources})
-target_link_libraries(gnuradio-howto ${Boost_LIBRARIES} ${GNURADIO_RUNTIME_LIBRARIES})
+target_link_libraries(gnuradio-howto ${Boost_LIBRARIES} ${GNURADIO_ALL_LIBRARIES})
set_target_properties(gnuradio-howto PROPERTIES DEFINE_SYMBOL "gnuradio_howto_EXPORTS")
########################################################################
diff --git a/gr-utils/python/modtool/modtool_base.py b/gr-utils/python/modtool/modtool_base.py
index f8fc8639c4..86cbd8f420 100644
--- a/gr-utils/python/modtool/modtool_base.py
+++ b/gr-utils/python/modtool/modtool_base.py
@@ -141,8 +141,7 @@ class ModTool(object):
self._info['is_component'] = False
for f in files:
if os.path.isfile(f) and f == 'CMakeLists.txt':
- if re.search('find_package\(GnuradioRuntime\)', open(f).read()) is not None or \
- re.search('find_package\(Gnuradio(\s+[0-9".]+)?\)', open(f).read()) is not None:
+ if re.search('find_package\(Gnuradio', open(f).read()) is not None:
self._info['version'] = '36' # Might be 37, check that later
has_makefile = True
elif re.search('GR_REGISTER_COMPONENT', open(f).read()) is not None: